move many tests into their modules with qtest

This commit is contained in:
Simon Cruanes 2015-09-16 16:18:50 +02:00
parent ada364ae3a
commit eb1c9bc0be
20 changed files with 640 additions and 765 deletions

View file

@ -36,6 +36,55 @@ module type PARTIAL_ORD = sig
(** [leq x y] shall return [true] iff [x] is lower or equal to [y] *)
end
(*$inject
module H = CCHeap.Make(struct
type t = int
let leq x y = x<=y
end)
let rec is_sorted l = match l with
| [_]
| [] -> true
| x::((y::_) as l') -> x <= y && is_sorted l'
let extract_list heap =
let rec recurse acc h =
if H.is_empty h
then List.rev acc
else
let h', x = H.take_exn h in
recurse (x::acc) h'
in
recurse [] heap
*)
(*$R
let h = H.of_list [5;3;4;1;42;0] in
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 0 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 1 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 3 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 4 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 5 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 42 x;
OUnit.assert_raises H.Empty (fun () -> H.take_exn h);
*)
(*$QR
Q.(list_of_size Gen.(return 10_000) int) (fun l ->
(* put elements into a heap *)
let h = H.of_seq H.empty (Sequence.of_list l) in
OUnit.assert_equal 10_000 (H.size h);
let l' = extract_list h in
is_sorted l'
)
*)
module type S = sig
type elt
type t

View file

@ -124,6 +124,14 @@ let ensure v size =
let clear v =
v.size <- 0
(*$R
let v = of_seq Sequence.(1 -- 10) in
OUnit.assert_equal 10 (size v);
clear v;
OUnit.assert_equal 0 (size v);
OUnit.assert_bool "empty_after_clear" (Sequence.is_empty (to_seq v));
*)
let is_empty v = v.size = 0
let push_unsafe v x =
@ -156,6 +164,15 @@ let append a b =
append v1 v2; to_list v1 = CCList.(0--9)
*)
(*$R
let a = of_seq Sequence.(1 -- 5) in
let b = of_seq Sequence.(6 -- 10) in
append a b;
OUnit.assert_equal 10 (size a);
OUnit.assert_equal (Sequence.to_array Sequence.(1 -- 10)) (to_array a);
OUnit.assert_equal (Sequence.to_array Sequence.(6 -- 10)) (to_array b);
*)
let get v i =
if i < 0 || i >= v.size then invalid_arg "Vector.get";
Array.unsafe_get v.vec i
@ -186,6 +203,22 @@ let append_array a b =
append_array v1 v2; to_list v1 = CCList.(0--9)
*)
(*$inject
let gen x =
let small = length in
let print = CCOpt.map (fun p x -> Q.Print.list p (CCVector.to_list x)) x.Q.print in
Q.make ?print ~small Q.Gen.(list x.Q.gen >|= of_list)
*)
(*$QR
(Q.pair (gen Q.int) (gen Q.int)) (fun (v1,v2) ->
let l1 = to_list v1 in
append v1 v2;
Sequence.to_list (to_seq v1) =
Sequence.(to_list (append (of_list l1) (to_seq v2)))
)
*)
let equal eq v1 v2 =
let n = min v1.size v2.size in
let rec check i =
@ -240,9 +273,36 @@ let copy v = {
create () |> copy |> is_empty
*)
(*$R
let v = of_seq Sequence.(1 -- 100) in
OUnit.assert_equal 100 (size v);
let v' = copy v in
OUnit.assert_equal 100 (size v');
clear v';
OUnit.assert_bool "empty" (is_empty v');
OUnit.assert_bool "not_empty" (not (is_empty v));
*)
let shrink v n =
if n < v.size then v.size <- n
(*$R
let v = of_seq Sequence.(1 -- 10) in
shrink v 5;
OUnit.assert_equal [1;2;3;4;5] (to_list v);
*)
(*$QR
(gen Q.small_int) (fun v ->
let n = size v / 2 in
let l = to_list v in
let h = Sequence.(to_list (take n (of_list l))) in
let v' = copy v in
shrink v' n;
h = to_list v'
)
*)
let sort' cmp v =
(* possibly copy array (to avoid junk at its end), then sort the array *)
let a =
@ -260,6 +320,15 @@ let sort cmp v =
Array.sort cmp v'.vec;
v'
(*$QR
(gen Q.small_int) (fun v ->
let v' = copy v in
sort' Pervasives.compare v';
let l = to_list v' in
List.sort Pervasives.compare l = l
)
*)
let uniq_sort cmp v =
sort' cmp v;
let n = v.size in

View file

@ -98,6 +98,15 @@ let cardinal bv =
done;
!n
(*$R
let bv1 = CCBV.create ~size:87 true in
assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1);
*)
(*$Q
Q.small_int (fun n -> CCBV.cardinal (CCBV.create ~size:n true) = n)
*)
let is_empty bv =
try
for i = 0 to Array.length bv.a - 1 do
@ -115,6 +124,22 @@ let get bv i =
bv.a.(n) land (1 lsl i) <> 0
else false
(*$R
let bv = CCBV.create ~size:99 false in
assert_bool "32 must be false" (not (CCBV.get bv 32));
assert_bool "88 must be false" (not (CCBV.get bv 88));
assert_bool "5 must be false" (not (CCBV.get bv 5));
CCBV.set bv 32;
CCBV.set bv 88;
CCBV.set bv 5;
assert_bool "32 must be true" (CCBV.get bv 32);
assert_bool "88 must be true" (CCBV.get bv 88);
assert_bool "5 must be true" (CCBV.get bv 5);
assert_bool "33 must be false" (not (CCBV.get bv 33));
assert_bool "44 must be false" (not (CCBV.get bv 44));
assert_bool "1 must be false" (not (CCBV.get bv 1));
*)
let set bv i =
let n = i / __width in
if n >= Array.length bv.a
@ -152,6 +177,14 @@ let clear bv =
let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0)
*)
(*$R
let bv = CCBV.of_list [1; 5; 200] in
assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv);
CCBV.clear bv;
assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv);
assert_bool "must be empty" (CCBV.is_empty bv);
*)
let iter bv f =
let len = Array.length bv.a in
for n = 0 to len - 1 do
@ -175,11 +208,37 @@ let iter_true bv f =
of_list [1;5;7] |> iter_true |> Sequence.to_list |> List.sort CCOrd.compare = [1;5;7]
*)
(*$inject
let _gen = Q.Gen.(map of_list (list nat))
let _pp bv = Q.Print.(list string) (List.map string_of_int (to_list bv))
let _small bv = length bv
let gen_bv = Q.make ~small:_small ~print:_pp _gen
*)
(*$QR
gen_bv (fun bv ->
let l' = Sequence.to_rev_list (CCBV.iter_true bv) in
let bv' = CCBV.of_list l' in
CCBV.cardinal bv = CCBV.cardinal bv'
)
*)
let to_list bv =
let l = ref [] in
iter_true bv (fun i -> l := i :: !l);
!l
(*$R
let bv = CCBV.of_list [1; 5; 156; 0; 222] in
assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv);
CCBV.set bv 201;
assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv);
let l = CCBV.to_list bv in
let l = List.sort compare l in
assert_equal [0;1;5;156;201;222] l;
*)
let to_sorted_list bv =
List.rev (to_list bv)
@ -230,6 +289,15 @@ let union bv1 bv2 =
union_into ~into:bv bv2;
bv
(*$R
let bv1 = CCBV.of_list [1;2;3;4] in
let bv2 = CCBV.of_list [4;200;3] in
let bv = CCBV.union bv1 bv2 in
let l = List.sort compare (CCBV.to_list bv) in
assert_equal [1;2;3;4;200] l;
()
*)
(*$T
union (of_list [1;2;3;4;5]) (of_list [7;3;5;6]) |> to_sorted_list = CCList.range 1 7
*)
@ -255,6 +323,14 @@ let inter bv1 bv2 =
inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4]
*)
(*$R
let bv1 = CCBV.of_list [1;2;3;4] in
let bv2 = CCBV.of_list [4;200;3] in
CCBV.inter_into ~into:bv1 bv2;
let l = List.sort compare (CCBV.to_list bv1) in
assert_equal [3;4] l;
*)
let select bv arr =
let l = ref [] in
begin try
@ -267,6 +343,13 @@ let select bv arr =
end;
!l
(*$R
let bv = CCBV.of_list [1;2;5;400] in
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
let l = List.sort compare (CCBV.selecti bv arr) in
assert_equal [("b",1); ("c",2); ("f",5)] l;
*)
let selecti bv arr =
let l = ref [] in
begin try

View file

@ -45,6 +45,11 @@ type 'a t = {
}
(** The deque, a double linked list of cells *)
(*$inject
let plist l = CCPrint.to_string (CCList.pp CCInt.pp) l
let pint i = string_of_int i
*)
(*$R
let q = create () in
add_seq_back q Sequence.(3 -- 5);
@ -119,6 +124,19 @@ let peek_front d = match d.cur.cell with
try (ignore (of_list [] |> peek_front); false) with Empty -> true
*)
(*$R
let d = of_seq Sequence.(1 -- 10) in
let printer = pint in
OUnit.assert_equal ~printer 1 (peek_front d);
push_front d 42;
OUnit.assert_equal ~printer 42 (peek_front d);
OUnit.assert_equal ~printer 42 (take_front d);
OUnit.assert_equal ~printer 1 (take_front d);
OUnit.assert_equal ~printer 2 (take_front d);
OUnit.assert_equal ~printer 3 (take_front d);
OUnit.assert_equal ~printer 10 (peek_back d);
*)
let peek_back d =
if is_empty d then raise Empty
else match d.cur.prev.cell with
@ -132,6 +150,19 @@ let peek_back d =
try (ignore (of_list [] |> peek_back); false) with Empty -> true
*)
(*$R
let d = of_seq Sequence.(1 -- 10) in
let printer = pint in
OUnit.assert_equal ~printer 1 (peek_front d);
push_back d 42;
OUnit.assert_equal ~printer 42 (peek_back d);
OUnit.assert_equal ~printer 42 (take_back d);
OUnit.assert_equal ~printer 10 (take_back d);
OUnit.assert_equal ~printer 9 (take_back d);
OUnit.assert_equal ~printer 8 (take_back d);
OUnit.assert_equal ~printer 1 (peek_front d);
*)
let take_back_node_ n = match n.cell with
| Zero -> assert false
| One x -> n.cell <- Zero; x
@ -205,6 +236,13 @@ let iter f d =
let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3
*)
(*$R
let d = of_seq Sequence.(1 -- 5) in
let s = Sequence.from_iter (fun k -> iter k d) in
let l = Sequence.to_list s in
OUnit.assert_equal ~printer:plist [1;2;3;4;5] l;
*)
let append_front ~into q = iter (push_front into) q
let append_back ~into q = iter (push_back into) q
@ -244,6 +282,11 @@ let length d = d.size
length q = 3 * List.length l)
*)
(*$R
let d = of_seq Sequence.(1 -- 10) in
OUnit.assert_equal ~printer:pint 10 (length d)
*)
type 'a sequence = ('a -> unit) -> unit
type 'a gen = unit -> 'a option

View file

@ -30,6 +30,10 @@ type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
type 'a equal = 'a -> 'a -> bool
type 'a printer = Format.formatter -> 'a -> unit
(*$inject
let pp_ilist = CCPrint.(to_string (list int))
*)
(** {2 Basics} *)
type 'a digit =
@ -45,6 +49,11 @@ type 'a t =
let empty = Shallow Zero
(*$R
let q = empty in
OUnit.assert_bool "is_empty" (is_empty q)
*)
exception Empty
let _single x = Shallow (One x)
@ -98,6 +107,14 @@ let rec snoc : 'a. 'a t -> 'a -> 'a t
snoc (of_list l) x |> to_list = l @ [x])
*)
(*$R
let q = List.fold_left snoc empty [1;2;3;4;5] in
let q = tail q in
let q = List.fold_left snoc q [6;7;8] in
let l = Sequence.to_list (to_seq q) in
OUnit.assert_equal ~printer:pp_ilist [2;3;4;5;6;7;8] l
*)
let rec take_front_exn : 'a. 'a t -> ('a *'a t)
= fun q -> match q with
| Shallow Zero -> raise Empty
@ -122,6 +139,16 @@ let rec take_front_exn : 'a. 'a t -> ('a *'a t)
x'=x && to_list q = l)
*)
(*$R
let q = of_list [1;2;3;4] in
let x, q = take_front_exn q in
OUnit.assert_equal 1 x;
let q = List.fold_left snoc q [5;6;7] in
OUnit.assert_equal 2 (first_exn q);
let x, q = take_front_exn q in
OUnit.assert_equal 2 x;
*)
let take_front q =
try Some (take_front_exn q)
with Empty -> None
@ -336,6 +363,14 @@ let append q1 q2 =
append (of_list l1) (of_list l2) |> to_list = l1 @ l2)
*)
(*$R
let q1 = of_seq (Sequence.of_list [1;2;3;4]) in
let q2 = of_seq (Sequence.of_list [5;6;7;8]) in
let q = append q1 q2 in
let l = Sequence.to_list (to_seq q) in
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5;6;7;8] l
*)
let _map_digit f d = match d with
| Zero -> Zero
| One x -> One (f x)
@ -375,6 +410,12 @@ let rec fold : 'a 'b. ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
of_list l |> fold (fun acc x->x::acc) [] = List.rev l)
*)
(*$R
let q = of_seq (Sequence.of_list [1;2;3;4]) in
let n = fold (+) 0 q in
OUnit.assert_equal 10 n;
*)
let iter f q = to_seq q f
let of_list l = List.fold_left snoc empty l

View file

@ -82,6 +82,10 @@ let empty = E
let is_prefix_ ~prefix y ~bit = prefix = Bit.mask y ~mask:bit
(*$inject
let _list_uniq = CCList.sort_uniq ~cmp:(fun a b-> Pervasives.compare (fst a)(fst b))
*)
(*$Q
Q.int (fun i -> \
let b = Bit.highest i in \
@ -162,7 +166,7 @@ let find k t =
(*$Q
Q.(list (pair int int)) (fun l -> \
let l = CCList.Set.uniq ~eq:(CCFun.compose_binop fst (=)) l in \
let l = _list_uniq l in \
let m = of_list l in \
List.for_all (fun (k,v) -> find k m = Some v) l)
*)
@ -215,7 +219,7 @@ let add k v t = insert_ (fun ~old:_ v -> v) k v t
(*$Q & ~count:20
Q.(list (pair int int)) (fun l -> \
let l = CCList.Set.uniq l in let m = of_list l in \
let l = _list_uniq l in let m = of_list l in \
List.for_all (fun (k,v) -> find_exn k m = v) l)
*)
@ -231,7 +235,7 @@ let rec remove k t = match t with
(*$Q & ~count:20
Q.(list (pair int int)) (fun l -> \
let l = CCList.Set.uniq l in let m = of_list l in \
let l = _list_uniq l in let m = of_list l in \
List.for_all (fun (k,_) -> mem k m && not (mem k (remove k m))) l)
*)
@ -472,17 +476,24 @@ let compare ~cmp a b =
Q.(list (pair int bool)) ( fun l -> \
let m1 = of_list l and m2 = of_list (List.rev l) in \
compare ~cmp:Pervasives.compare m1 m2 = 0)
Q.(pair (list (pair int bool)) (list (pair int bool))) (fun (l1, l2) -> \
let l1 = List.map (fun (k,v) -> abs k,v) l1 in \
let l2 = List.map (fun (k,v) -> abs k,v) l2 in \
let m1 = of_list l1 and m2 = of_list l2 in \
let c = compare ~cmp:Pervasives.compare m1 m2 \
and c' = compare ~cmp:Pervasives.compare m2 m1 in \
*)
(*$QR
Q.(pair (list (pair int bool)) (list (pair int bool))) (fun (l1, l2) ->
let l1 = List.map (fun (k,v) -> abs k,v) l1 in
let l2 = List.map (fun (k,v) -> abs k,v) l2 in
let m1 = of_list l1 and m2 = of_list l2 in
let c = compare ~cmp:Pervasives.compare m1 m2
and c' = compare ~cmp:Pervasives.compare m2 m1 in
(c = 0) = (c' = 0) && (c < 0) = (c' > 0) && (c > 0) = (c' < 0))
Q.(pair (list (pair int bool)) (list (pair int bool))) (fun (l1, l2) -> \
let l1 = List.map (fun (k,v) -> abs k,v) l1 in \
let l2 = List.map (fun (k,v) -> abs k,v) l2 in \
let m1 = of_list l1 and m2 = of_list l2 in \
*)
(*$QR
Q.(pair (list (pair int bool)) (list (pair int bool))) (fun (l1, l2) ->
let l1 = List.map (fun (k,v) -> abs k,v) l1 in
let l2 = List.map (fun (k,v) -> abs k,v) l2 in
let m1 = of_list l1 and m2 = of_list l2 in
(compare ~cmp:Pervasives.compare m1 m2 = 0) = equal ~eq:(=) m1 m2)
*)

View file

@ -26,11 +26,32 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Hash Table with Heterogeneous Keys} *)
(*$inject
open CCFun
*)
type 'b injection = {
get : (unit -> unit) -> 'b option;
set : 'b -> (unit -> unit);
}
(*$R
let inj_int = create_inj () in
let tbl = create 10 in
OUnit.assert_equal None (get ~inj:inj_int tbl "a");
set ~inj:inj_int tbl "a" 1;
OUnit.assert_equal (Some 1) (get ~inj:inj_int tbl "a");
let inj_string = create_inj () in
set ~inj:inj_string tbl "b" "Hello";
OUnit.assert_equal (Some "Hello") (get ~inj:inj_string tbl "b");
OUnit.assert_equal None (get ~inj:inj_string tbl "a");
OUnit.assert_equal (Some 1) (get ~inj:inj_int tbl "a");
set ~inj:inj_string tbl "a" "Bye";
OUnit.assert_equal None (get ~inj:inj_int tbl "a");
OUnit.assert_equal (Some "Bye") (get ~inj:inj_string tbl "a");
*)
type 'a t = ('a, unit -> unit) Hashtbl.t
let create n = Hashtbl.create n
@ -55,8 +76,33 @@ let set ~inj tbl x y =
let length tbl = Hashtbl.length tbl
(*$R
let inj_int = create_inj () in
let tbl = create 5 in
set ~inj:inj_int tbl "foo" 1;
set ~inj:inj_int tbl "bar" 2;
OUnit.assert_equal 2 (length tbl);
OUnit.assert_equal 2 (find ~inj:inj_int tbl "bar");
set ~inj:inj_int tbl "foo" 42;
OUnit.assert_equal 2 (length tbl);
remove tbl "bar";
OUnit.assert_equal 1 (length tbl);
*)
let clear tbl = Hashtbl.clear tbl
(*$R
let inj_int = create_inj () in
let inj_str = create_inj () in
let tbl = create 5 in
set ~inj:inj_int tbl "foo" 1;
set ~inj:inj_int tbl "bar" 2;
set ~inj:inj_str tbl "baaz" "hello";
OUnit.assert_equal 3 (length tbl);
clear tbl;
OUnit.assert_equal 0 (length tbl);
*)
let remove tbl x = Hashtbl.remove tbl x
let copy tbl = Hashtbl.copy tbl
@ -66,6 +112,21 @@ let mem ~inj tbl x =
inj.get (Hashtbl.find tbl x) <> None
with Not_found -> false
(*$R
let inj_int = create_inj () in
let inj_str = create_inj () in
let tbl = create 5 in
set ~inj:inj_int tbl "foo" 1;
set ~inj:inj_int tbl "bar" 2;
set ~inj:inj_str tbl "baaz" "hello";
OUnit.assert_bool "mem foo int" (mem ~inj:inj_int tbl "foo");
OUnit.assert_bool "mem bar int" (mem ~inj:inj_int tbl "bar");
OUnit.assert_bool "not mem baaz int" (not (mem ~inj:inj_int tbl "baaz"));
OUnit.assert_bool "not mem foo str" (not (mem ~inj:inj_str tbl "foo"));
OUnit.assert_bool "not mem bar str" (not (mem ~inj:inj_str tbl "bar"));
OUnit.assert_bool "mem baaz str" (mem ~inj:inj_str tbl "baaz");
*)
let find ~inj tbl x =
match inj.get (Hashtbl.find tbl x) with
| None -> raise Not_found
@ -86,6 +147,17 @@ let keys_seq tbl yield =
(fun x _ -> yield x)
tbl
(*$R
let inj_int = create_inj () in
let inj_str = create_inj () in
let tbl = create 5 in
set ~inj:inj_int tbl "foo" 1;
set ~inj:inj_int tbl "bar" 2;
set ~inj:inj_str tbl "baaz" "hello";
let l = keys_seq tbl |> Sequence.to_list in
OUnit.assert_equal ["baaz"; "bar"; "foo"] (List.sort compare l);
*)
let bindings_of ~inj tbl yield =
Hashtbl.iter
(fun k value ->
@ -101,3 +173,17 @@ let bindings tbl yield =
Hashtbl.iter
(fun x y -> yield (x, Value (fun inj -> inj.get y)))
tbl
(*$R
let inj_int = create_inj () in
let inj_str = create_inj () in
let tbl = create 5 in
set ~inj:inj_int tbl "foo" 1;
set ~inj:inj_int tbl "bar" 2;
set ~inj:inj_str tbl "baaz" "hello";
set ~inj:inj_str tbl "str" "rts";
let l_int = bindings_of tbl ~inj:inj_int |> Sequence.to_list in
OUnit.assert_equal ["bar", 2; "foo", 1] (List.sort compare l_int);
let l_str = bindings_of tbl ~inj:inj_str |> Sequence.to_list in
OUnit.assert_equal ["baaz", "hello"; "str", "rts"] (List.sort compare l_str);
*)

View file

@ -131,6 +131,27 @@ module type S = sig
val print : key formatter -> 'a formatter -> 'a t formatter
end
(*$inject
module H = Make(CCInt)
let my_list =
[ 1, "a";
2, "b";
3, "c";
4, "d";
]
let my_seq = Sequence.of_list my_list
let _list_uniq = CCList.sort_uniq
~cmp:(fun a b -> Pervasives.compare (fst a) (fst b))
let _list_int_int = Q.(
map_same_type _list_uniq
(list_of_size Gen.(0 -- 40) (pair small_int small_int))
)
*)
(** {2 Implementation} *)
module Make(H : HashedType) : S with type key = H.t = struct
@ -187,6 +208,41 @@ module Make(H : HashedType) : S with type key = H.t = struct
let find t k = Table.find (reroot t) k
(*$R
let h = H.of_seq my_seq in
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 5);
let h' = H.replace h 5 "e" in
OUnit.assert_equal "a" (H.find h' 1);
OUnit.assert_equal "e" (H.find h' 5);
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 5);
*)
(*$R
let n = 10000 in
let seq = Sequence.map (fun i -> i, string_of_int i) Sequence.(0--n) in
let h = H.of_seq seq in
Sequence.iter
(fun (k,v) ->
OUnit.assert_equal ~printer:(fun x -> x) v (H.find h k))
seq;
OUnit.assert_raises Not_found (fun () -> H.find h (n+1));
*)
(*$QR
_list_int_int
(fun l ->
let h = H.of_list l in
List.for_all
(fun (k,v) ->
try
H.find h k = v
with Not_found -> false)
l
)
*)
let get_exn k t = find t k
let get k t =
@ -197,6 +253,20 @@ module Make(H : HashedType) : S with type key = H.t = struct
let length t = Table.length (reroot t)
(*$R
let h = H.of_seq
Sequence.(map (fun i -> i, string_of_int i)
(0 -- 200)) in
OUnit.assert_equal 201 (H.length h);
*)
(*$QR
_list_int_int (fun l ->
let h = H.of_list l in
H.length h = List.length l
)
*)
let replace t k v =
let tbl = reroot t in
(* create the new hashtable *)
@ -225,6 +295,36 @@ module Make(H : HashedType) : S with type key = H.t = struct
(* not member, nothing to do *)
t
(*$R
let h = H.of_seq my_seq in
OUnit.assert_equal (H.find h 2) "b";
OUnit.assert_equal (H.find h 3) "c";
OUnit.assert_equal (H.find h 4) "d";
OUnit.assert_equal (H.length h) 4;
let h = H.remove h 2 in
OUnit.assert_equal (H.find h 3) "c";
OUnit.assert_equal (H.length h) 3;
OUnit.assert_raises Not_found (fun () -> H.find h 2)
*)
(*$R
let open Sequence.Infix in
let n = 10000 in
let seq = Sequence.map (fun i -> i, string_of_int i) (0 -- n) in
let h = H.of_seq seq in
OUnit.assert_equal (n+1) (H.length h);
let h = Sequence.fold (fun h i -> H.remove h i) h (0 -- 500) in
OUnit.assert_equal (n-500) (H.length h);
OUnit.assert_bool "is_empty" (H.is_empty (H.create 16));
*)
(*$QR
_list_int_int (fun l ->
let h = H.of_list l in
let h = List.fold_left (fun h (k,_) -> H.remove h k) h l in
H.is_empty h)
*)
let update t k f =
let v = get k t in
match v, f v with
@ -297,6 +397,22 @@ module Make(H : HashedType) : S with type key = H.t = struct
| Some _ -> Table.replace tbl k v2);
ref (Table tbl)
(*$R
let t1 = H.of_list [1, "a"; 2, "b1"] in
let t2 = H.of_list [2, "b2"; 3, "c"] in
let t = H.merge
(fun _ v1 v2 -> match v1, v2 with
| None, _ -> v2
| _ , None -> v1
| Some s1, Some s2 -> if s1 < s2 then Some s1 else Some s2)
t1 t2
in
OUnit.assert_equal ~printer:string_of_int 3 (H.length t);
OUnit.assert_equal "a" (H.find t 1);
OUnit.assert_equal "b1" (H.find t 2);
OUnit.assert_equal "c" (H.find t 3);
*)
let add_seq init seq =
let tbl = ref init in
seq (fun (k,v) -> tbl := replace !tbl k v);
@ -307,6 +423,25 @@ module Make(H : HashedType) : S with type key = H.t = struct
let add_list init l =
add_seq init (fun k -> List.iter k l)
(*$QR
_list_int_int (fun l ->
let l1, l2 = List.partition (fun (x,_) -> x mod 2 = 0) l in
let h1 = H.of_list l1 in
let h2 = H.add_list h1 l2 in
List.for_all
(fun (k,v) -> H.find h2 k = v)
l
&&
List.for_all
(fun (k,v) -> H.find h1 k = v)
l1
&&
List.length l1 = H.length h1
&&
List.length l = H.length h2
)
*)
let of_list l = add_list (empty ()) l
let to_list t =
@ -314,11 +449,24 @@ module Make(H : HashedType) : S with type key = H.t = struct
let bindings = Table.fold (fun k v acc -> (k,v)::acc) tbl [] in
bindings
(*$R
let h = H.of_seq my_seq in
let l = Sequence.to_list (H.to_seq h) in
OUnit.assert_equal my_list (List.sort compare l)
*)
let to_seq t =
fun k ->
let tbl = reroot t in
Table.iter (fun x y -> k (x,y)) tbl
(*$R
let h = H.of_seq my_seq in
OUnit.assert_equal "b" (H.find h 2);
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 42);
*)
let equal eq t1 t2 =
length t1 = length t2
&&

View file

@ -429,14 +429,14 @@ module Make(W : WORD) = struct
in
_mk_node v map'
(*$Q & ~small:(fun (a,b) -> List.length a + List.length b) ~count:30
Q.(let p = list (pair printable_string small_int) in pair p p) \
(fun (l1,l2) -> \
let t1 = S.of_list l1 and t2 = S.of_list l2 in \
let t = S.merge (fun a _ -> Some a) t1 t2 in \
S.to_seq t |> Sequence.for_all \
(fun (k,v) -> S.find k t1 = Some v || S.find k t2 = Some v) && \
S.to_seq t1 |> Sequence.for_all (fun (k,v) -> S.find k t <> None) && \
(*$QR & ~count:30
Q.(let p = list_of_size Gen.(0--100) (pair printable_string small_int) in pair p p)
(fun (l1,l2) ->
let t1 = S.of_list l1 and t2 = S.of_list l2 in
let t = S.merge (fun a _ -> Some a) t1 t2 in
S.to_seq t |> Sequence.for_all
(fun (k,v) -> S.find k t1 = Some v || S.find k t2 = Some v) &&
S.to_seq t1 |> Sequence.for_all (fun (k,v) -> S.find k t <> None) &&
S.to_seq t2 |> Sequence.for_all (fun (k,v) -> S.find k t <> None))
*)
@ -554,13 +554,13 @@ module Make(W : WORD) = struct
(T.below [1;1] t1 |> Sequence.sort |> Sequence.to_list)
*)
(*$Q & ~small:List.length
Q.(list (pair printable_string small_int)) (fun l -> \
(*$Q & ~count:30
Q.(list_of_size Gen.(0--100) (pair printable_string small_int)) (fun l -> \
let t = S.of_list l in \
S.check_invariants t)
*)
(*$Q & ~small:List.length ~count:30
(*$Q & ~count:20
Q.(list_of_size Gen.(1 -- 20) (pair printable_string small_int)) \
(fun l -> let t = String.of_list l in \
List.for_all (fun (k,_) -> \

View file

@ -34,11 +34,11 @@
let op = Q.make ~print:pp_op gen_op
let _list_uniq = CCList.sort_uniq ~cmp:(CCFun.compose_binop fst Pervasives.compare)
*)
(*$Q & ~small:List.length ~count:200
Q.(list op) (fun l -> \
let m = apply_ops l M.empty in M.balanced m)
(*$Q & ~count:200
Q.(list op) (fun l -> let m = apply_ops l M.empty in M.balanced m)
*)
type 'a sequence = ('a -> unit) -> unit
@ -272,17 +272,15 @@ module MakeFull(K : KEY) : S with type key = K.t = struct
| n when n<0 -> balance_r k' v' (add k v l) r
| _ -> balance_l k' v' l (add k v r)
(*$Q & ~small:List.length
(*$Q
Q.(list (pair small_int bool)) (fun l -> \
let m = M.of_list l in \
M.balanced m)
Q.(list (pair small_int small_int)) (fun l -> \
let l = CCList.Set.uniq ~eq:(CCFun.compose_binop fst (=)) l in \
let m = M.of_list l in \
let l = _list_uniq l in let m = M.of_list l in \
List.for_all (fun (k,v) -> M.get_exn k m = v) l)
Q.(list (pair small_int small_int)) (fun l -> \
let l = CCList.Set.uniq ~eq:(CCFun.compose_binop fst (=)) l in \
let m = M.of_list l in \
let l = _list_uniq l in let m = M.of_list l in \
M.cardinal m = List.length l)
*)
@ -326,12 +324,12 @@ module MakeFull(K : KEY) : S with type key = K.t = struct
| n when n<0 -> balance_l k' v' (remove k l) r
| _ -> balance_r k' v' l (remove k r)
(*$Q & ~small:List.length
Q.(list (pair small_int small_int)) (fun l -> \
(*$Q
Q.(list_of_size Gen.(0 -- 30) (pair small_int small_int)) (fun l -> \
let m = M.of_list l in \
List.for_all (fun (k,_) -> \
M.mem k m && (let m' = M.remove k m in not (M.mem k m'))) l)
Q.(list (pair small_int small_int)) (fun l -> \
Q.(list_of_size Gen.(0 -- 30) (pair small_int small_int)) (fun l -> \
let m = M.of_list l in \
List.for_all (fun (k,_) -> let m' = M.remove k m in M.balanced m') l)
*)
@ -447,9 +445,9 @@ module MakeFull(K : KEY) : S with type key = K.t = struct
let rl, o, rr = split k r in
node_ k' v' l rl, o, rr
(*$QR & ~small:List.length ~count:20
Q.(list (pair small_int small_int)) ( fun lst ->
let lst = CCList.sort_uniq ~cmp:(CCFun.compose_binop fst CCInt.compare) lst in
(*$QR & ~count:20
Q.(list_of_size Gen.(1 -- 100) (pair small_int small_int)) ( fun lst ->
let lst = _list_uniq lst in
let m = M.of_list lst in
List.for_all (fun (k,v) ->
let l, v', r = M.split k m in
@ -496,14 +494,13 @@ module MakeFull(K : KEY) : S with type key = K.t = struct
(M.to_list m |> List.sort Pervasives.compare)
*)
(*$Q & ~small:(fun (l1,l2) -> List.length l1 + List.length l2)
Q.(let p = list (pair small_int small_int) in pair p p) (fun (l1, l2) -> \
let eq x y = fst x = fst y in \
let l1 = CCList.Set.uniq ~eq l1 and l2 = CCList.Set.uniq ~eq l2 in \
let m1 = M.of_list l1 and m2 = M.of_list l2 in \
let m = M.merge (fun _ v1 v2 -> match v1 with \
| None -> v2 | Some _ as r -> r) m1 m2 in \
List.for_all (fun (k,v) -> M.get_exn k m = v) l1 && \
(*$QR
Q.(let p = list (pair small_int small_int) in pair p p) (fun (l1, l2) ->
let l1 = _list_uniq l1 and l2 = _list_uniq l2 in
let m1 = M.of_list l1 and m2 = M.of_list l2 in
let m = M.merge (fun _ v1 v2 -> match v1 with
| None -> v2 | Some _ as r -> r) m1 m2 in
List.for_all (fun (k,v) -> M.get_exn k m = v) l1 &&
List.for_all (fun (k,v) -> M.mem k m1 || M.get_exn k m = v) l2)
*)

View file

@ -47,6 +47,71 @@ let rec klist_to_list l = match l () with
| `Nil -> []
| `Cons (x,k) -> x :: klist_to_list k
(*$inject
open CCFun
*)
(*$Q
Q.(string_of_size Gen.(0 -- 30)) (fun s -> \
let a = of_string ~limit:1 s in \
match_with a s)
*)
(* test that building a from s, and mutating one char of s, yields
a string s' that is accepted by a.
--> generate triples (s, i, c) where c is a char, s a non empty string
and i a valid index in s
*)
(*$QR
(
let gen = Q.Gen.(
3 -- 10 >>= fun len ->
0 -- (len-1) >>= fun i ->
string_size (return len) >>= fun s ->
char >|= fun c -> (s,i,c)
) in
let small (s,_,_) = String.length s in
Q.make ~small gen
)
(fun (s,i,c) ->
let s' = Bytes.of_string s in
Bytes.set s' i c;
let a = of_string ~limit:1 s in
match_with a (Bytes.to_string s')
)
*)
(* test that, for an index, all retrieved strings are at a distance to
the key that is not too high *)
(*$QR & ~count:30
(
let mklist l =
let l' = List.map (fun s->s,s) l in
l, Index.of_list l'
in
let gen = Q.Gen.(
list_size (3 -- 15) (string_size (0 -- 10)) >|= mklist
) in
let small (l,_) = List.length l in
let print (l,_) = Q.Print.(list string) l in
let shrink (l,_) = Sequence.map mklist (Q.Shrink.list l) in
Q.make ~small ~print ~shrink gen
)
(fun (l,idx) ->
List.for_all
(fun s ->
let retrieved = Index.retrieve ~limit:2 idx s
|> klist_to_list in
List.for_all
(fun s' -> edit_distance s s' <= 2) retrieved
) l
)
*)
module type S = sig
type char_
type string_

View file

@ -3,27 +3,11 @@ open OUnit
let suite =
"all_tests" >:::
[ Test_pHashtbl.suite;
Test_PersistentHashtbl.suite;
Test_bv.suite;
Test_CCHeap.suite;
Test_puf.suite;
Test_vector.suite;
Test_deque.suite;
Test_fQueue.suite;
Test_univ.suite;
Test_mixtbl.suite;
Test_RoseTree.suite;
]
let props =
QCheck.flatten
[ Test_PersistentHashtbl.props
; Test_bv.props
; Test_vector.props
; Test_levenshtein.props
]
let _ =
ignore (QCheck.run_tests props);
let () =
ignore (run_test_tt_main suite);
()

View file

@ -1,59 +0,0 @@
(* test leftistheap *)
open OUnit
module H = CCHeap.Make(struct type t = int let leq x y =x<=y end)
let empty = H.empty
let test1 () =
let h = H.of_list [5;3;4;1;42;0] in
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 0 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 1 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 3 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 4 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 5 x;
let h, x = H.take_exn h in
OUnit.assert_equal ~printer:string_of_int 42 x;
OUnit.assert_raises H.Empty (fun () -> H.take_exn h);
()
let rec is_sorted l = match l with
| [_]
| [] -> true
| x::((y::_) as l') -> x <= y && is_sorted l'
(* extract the content of the heap into a list *)
let extract_list heap =
let rec recurse acc h =
if H.is_empty h
then List.rev acc
else
let h', x = H.take_exn h in
recurse (x::acc) h'
in
recurse [] heap
(* heap sort on a random list *)
let test_sort () =
let n = 100_000 in
let l = Sequence.to_rev_list (Sequence.take n (Sequence.random_int n)) in
(* put elements into a heap *)
let h = H.of_seq empty (Sequence.of_list l) in
OUnit.assert_equal n (H.size h);
let l' = extract_list h in
OUnit.assert_bool "sorted" (is_sorted l');
()
let suite =
"test_leftistheap" >:::
[ "test1" >:: test1;
"test_sort" >:: test_sort;
"test_sort2" >:: test_sort; (* random! *)
]

View file

@ -1,187 +0,0 @@
open OUnit
module H = CCPersistentHashtbl.Make(CCInt)
let test_add () =
let h = H.create 32 in
let h = H.replace h 42 "foo" in
OUnit.assert_equal (H.find h 42) "foo"
let my_list =
[ 1, "a";
2, "b";
3, "c";
4, "d";
]
let my_seq = Sequence.of_list my_list
let test_of_seq () =
let h = H.of_seq my_seq in
OUnit.assert_equal "b" (H.find h 2);
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 42);
()
let test_to_seq () =
let h = H.of_seq my_seq in
let l = Sequence.to_list (H.to_seq h) in
OUnit.assert_equal my_list (List.sort compare l)
let test_resize () =
let h = H.of_seq
Sequence.(map (fun i -> i, string_of_int i)
(0 -- 200)) in
OUnit.assert_equal 201 (H.length h);
()
let test_persistent () =
let h = H.of_seq my_seq in
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 5);
let h' = H.replace h 5 "e" in
OUnit.assert_equal "a" (H.find h' 1);
OUnit.assert_equal "e" (H.find h' 5);
OUnit.assert_equal "a" (H.find h 1);
OUnit.assert_raises Not_found (fun () -> H.find h 5);
()
let test_big () =
let n = 10000 in
let seq = Sequence.map (fun i -> i, string_of_int i) Sequence.(0--n) in
let h = H.of_seq seq in
(*
Format.printf "@[<v2>table:%a@]@." (Sequence.pp_seq
(fun formatter (k,v) -> Format.fprintf formatter "%d -> \"%s\"" k v))
(H.to_seq h);
*)
Sequence.iter
(fun (k,v) ->
(*
Format.printf "lookup %d@." k;
*)
OUnit.assert_equal ~printer:(fun x -> x) v (H.find h k))
seq;
OUnit.assert_raises Not_found (fun () -> H.find h (n+1));
()
let test_remove () =
let h = H.of_seq my_seq in
OUnit.assert_equal (H.find h 2) "b";
OUnit.assert_equal (H.find h 3) "c";
OUnit.assert_equal (H.find h 4) "d";
OUnit.assert_equal (H.length h) 4;
let h = H.remove h 2 in
OUnit.assert_equal (H.find h 3) "c";
OUnit.assert_equal (H.length h) 3;
(* test that 2 has been removed *)
OUnit.assert_raises Not_found (fun () -> H.find h 2)
let test_size () =
let open Sequence.Infix in
let n = 10000 in
let seq = Sequence.map (fun i -> i, string_of_int i) (0 -- n) in
let h = H.of_seq seq in
OUnit.assert_equal (n+1) (H.length h);
let h = Sequence.fold (fun h i -> H.remove h i) h (0 -- 500) in
OUnit.assert_equal (n-500) (H.length h);
OUnit.assert_bool "is_empty" (H.is_empty (H.create 16));
()
let test_merge () =
let t1 = H.of_list [1, "a"; 2, "b1"] in
let t2 = H.of_list [2, "b2"; 3, "c"] in
let t = H.merge
(fun _ v1 v2 -> match v1, v2 with
| None, _ -> v2
| _ , None -> v1
| Some s1, Some s2 -> if s1 < s2 then Some s1 else Some s2)
t1 t2
in
OUnit.assert_equal ~printer:string_of_int 3 (H.length t);
OUnit.assert_equal "a" (H.find t 1);
OUnit.assert_equal "b1" (H.find t 2);
OUnit.assert_equal "c" (H.find t 3);
()
let suite =
"test_H" >:::
[ "test_add" >:: test_add;
"test_of_seq" >:: test_of_seq;
"test_to_seq" >:: test_to_seq;
"test_resize" >:: test_resize;
"test_persistent" >:: test_persistent;
"test_big" >:: test_big;
"test_remove" >:: test_remove;
"test_size" >:: test_size;
"test_merge" >:: test_merge;
]
open QCheck
let rec _list_uniq l = match l with
| [] -> []
| (x,_)::l' when List.mem_assoc x l' -> _list_uniq l'
| (x,y)::l' -> (x,y) :: _list_uniq l'
let check_add_mem =
let gen = Arbitrary.(lift _list_uniq (list (pair small_int small_int))) in
let prop l =
let h = H.of_list l in
List.for_all
(fun (k,v) ->
try
H.find h k = v
with Not_found -> false)
l
in
let name = "persistent_hashtbl_add_mem" in
mk_test ~name ~pp:PP.(list (pair int int)) ~size:List.length gen prop
let check_len =
let gen = Arbitrary.(lift _list_uniq (list (pair small_int small_int))) in
let prop l =
let h = H.of_list l in
H.length h = List.length l
in
let name = "persistent_hashtbl_len" in
mk_test ~name ~pp:PP.(list (pair int int)) ~size:List.length gen prop
let check_old_new =
let gen = Arbitrary.(lift _list_uniq (list (pair small_int small_int))) in
let prop l =
let l1, l2 = List.partition (fun (x,_) -> x mod 2 = 0) l in
let h1 = H.of_list l1 in
let h2 = H.add_list h1 l2 in
List.for_all
(fun (k,v) -> H.find h2 k = v)
l
&&
List.for_all
(fun (k,v) -> H.find h1 k = v)
l1
&&
List.length l1 = H.length h1
&&
List.length l = H.length h2
in
let name = "persistent_hashtbl_old_new" in
mk_test ~name ~pp:PP.(list (pair int int)) ~size:List.length gen prop
let check_add_remove_empty =
let gen = Arbitrary.(lift _list_uniq (list (pair small_int small_int))) in
let prop l =
let h = H.of_list l in
let h = List.fold_left (fun h (k,_) -> H.remove h k) h l in
H.is_empty h
in
let name = "persistent_hashtbl_add_remove_empty" in
mk_test ~name ~pp:PP.(list (pair int int)) ~size:List.length gen prop
let props =
[ check_add_mem
; check_len
; check_old_new
; check_add_remove_empty
]

View file

@ -1,100 +0,0 @@
open OUnit
let test_cardinal () =
let bv1 = CCBV.create ~size:87 true in
assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1);
()
let test_get () =
let bv = CCBV.create ~size:99 false in
assert_bool "32 must be false" (not (CCBV.get bv 32));
assert_bool "88 must be false" (not (CCBV.get bv 88));
assert_bool "5 must be false" (not (CCBV.get bv 5));
CCBV.set bv 32;
CCBV.set bv 88;
CCBV.set bv 5;
assert_bool "32 must be true" (CCBV.get bv 32);
assert_bool "88 must be true" (CCBV.get bv 88);
assert_bool "5 must be true" (CCBV.get bv 5);
assert_bool "33 must be false" (not (CCBV.get bv 33));
assert_bool "44 must be false" (not (CCBV.get bv 44));
assert_bool "1 must be false" (not (CCBV.get bv 1));
()
let test_list () =
let bv = CCBV.of_list [1; 5; 156; 0; 222] in
assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv);
CCBV.set bv 201;
assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv);
let l = CCBV.to_list bv in
let l = List.sort compare l in
assert_equal [0;1;5;156;201;222] l;
()
let test_clear () =
let bv = CCBV.of_list [1; 5; 200] in
assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv);
CCBV.clear bv;
assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv);
assert_bool "must be empty" (CCBV.is_empty bv);
()
let test_union () =
let bv1 = CCBV.of_list [1;2;3;4] in
let bv2 = CCBV.of_list [4;200;3] in
let bv = CCBV.union bv1 bv2 in
let l = List.sort compare (CCBV.to_list bv) in
assert_equal [1;2;3;4;200] l;
()
let test_inter () =
let bv1 = CCBV.of_list [1;2;3;4] in
let bv2 = CCBV.of_list [4;200;3] in
CCBV.inter_into ~into:bv1 bv2;
let l = List.sort compare (CCBV.to_list bv1) in
assert_equal [3;4] l;
()
let test_select () =
let bv = CCBV.of_list [1;2;5;400] in
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
let l = List.sort compare (CCBV.selecti bv arr) in
assert_equal [("b",1); ("c",2); ("f",5)] l;
()
let suite = "test_bv" >:::
[ "test_cardinal" >:: test_cardinal
; "test_get" >:: test_get
; "test_list" >:: test_list
; "test_clear" >:: test_clear
; "test_union" >:: test_union
; "test_inter" >:: test_inter
; "test_select" >:: test_select
]
open QCheck
let check_create_cardinal =
let gen = Arbitrary.small_int in
let prop n = CCBV.cardinal (CCBV.create ~size:n true) = n in
let name = "bv_create_cardinal" in
mk_test ~name ~pp:string_of_int gen prop
let pp bv = PP.(list string) (List.map string_of_int (CCBV.to_list bv))
let check_iter_true =
let gen = Arbitrary.(lift CCBV.of_list (list small_int)) in
let prop bv =
let l' = Sequence.to_rev_list (CCBV.iter_true bv) in
let bv' = CCBV.of_list l' in
CCBV.cardinal bv = CCBV.cardinal bv'
in
let name = "bv_iter_true" in
mk_test ~pp ~size:CCBV.cardinal ~name gen prop
let props =
[ check_create_cardinal
; check_iter_true
]

View file

@ -1,53 +0,0 @@
open OUnit
module Deque = CCDeque
let plist l = CCPrint.to_string (CCList.pp CCInt.pp) l
let pint i = string_of_int i
let test_length () =
let d = Deque.of_seq Sequence.(1 -- 10) in
OUnit.assert_equal ~printer:pint 10 (Deque.length d)
let test_front () =
let d = Deque.of_seq Sequence.(1 -- 10) in
let printer = pint in
OUnit.assert_equal ~printer 1 (Deque.peek_front d);
Deque.push_front d 42;
OUnit.assert_equal ~printer 42 (Deque.peek_front d);
OUnit.assert_equal ~printer 42 (Deque.take_front d);
OUnit.assert_equal ~printer 1 (Deque.take_front d);
OUnit.assert_equal ~printer 2 (Deque.take_front d);
OUnit.assert_equal ~printer 3 (Deque.take_front d);
OUnit.assert_equal ~printer 10 (Deque.peek_back d);
()
let test_back () =
let d = Deque.of_seq Sequence.(1 -- 10) in
let printer = pint in
OUnit.assert_equal ~printer 1 (Deque.peek_front d);
Deque.push_back d 42;
OUnit.assert_equal ~printer 42 (Deque.peek_back d);
OUnit.assert_equal ~printer 42 (Deque.take_back d);
OUnit.assert_equal ~printer 10 (Deque.take_back d);
OUnit.assert_equal ~printer 9 (Deque.take_back d);
OUnit.assert_equal ~printer 8 (Deque.take_back d);
OUnit.assert_equal ~printer 1 (Deque.peek_front d);
()
let test_iter () =
let d = Deque.of_seq Sequence.(1 -- 5) in
let s = Sequence.from_iter (fun k -> Deque.iter k d) in
let l = Sequence.to_list s in
OUnit.assert_equal ~printer:plist [1;2;3;4;5] l;
()
let suite =
"test_deque" >:::
[ "test_length" >:: test_length;
"test_front" >:: test_front;
"test_back" >:: test_back;
"test_iter" >:: test_iter;
]

View file

@ -1,50 +0,0 @@
open OUnit
module FQueue = CCFQueue
let test_empty () =
let q = FQueue.empty in
OUnit.assert_bool "is_empty" (FQueue.is_empty q)
let pp_ilist = CCPrint.(to_string (list int))
let test_push () =
let q = List.fold_left FQueue.snoc FQueue.empty [1;2;3;4;5] in
let q = FQueue.tail q in
let q = List.fold_left FQueue.snoc q [6;7;8] in
let l = Sequence.to_list (FQueue.to_seq q) in
OUnit.assert_equal ~printer:pp_ilist [2;3;4;5;6;7;8] l
let test_pop () =
let q = FQueue.of_list [1;2;3;4] in
let x, q = FQueue.take_front_exn q in
OUnit.assert_equal 1 x;
let q = List.fold_left FQueue.snoc q [5;6;7] in
OUnit.assert_equal 2 (FQueue.first_exn q);
let x, q = FQueue.take_front_exn q in
OUnit.assert_equal 2 x;
()
let test_append () =
let q1 = FQueue.of_seq (Sequence.of_list [1;2;3;4]) in
let q2 = FQueue.of_seq (Sequence.of_list [5;6;7;8]) in
let q = FQueue.append q1 q2 in
let l = Sequence.to_list (FQueue.to_seq q) in
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5;6;7;8] l
let test_fold () =
let q = FQueue.of_seq (Sequence.of_list [1;2;3;4]) in
let n = FQueue.fold (+) 0 q in
OUnit.assert_equal 10 n;
()
let suite =
"test_FQueue" >:::
[ "test_empty" >:: test_empty;
"test_push" >:: test_push;
"test_pop" >:: test_pop;
"test_fold" >:: test_fold;
"test_append" >:: test_append;
]

View file

@ -1,61 +0,0 @@
(* quickcheck for Levenshtein *)
module Levenshtein = Containers_string.Levenshtein
open CCFun
(* test that automaton accepts its string *)
let test_automaton =
let gen = QCheck.Arbitrary.(map string (fun s -> s, Levenshtein.of_string ~limit:1 s)) in
let test (s,a) =
Levenshtein.match_with a s
in
let pp (s,_) = s in
let name = "string accepted by its own automaton" in
QCheck.mk_test ~name ~pp ~size:(fun (s,_)->String.length s) gen test
(* test that building a from s, and mutating one char of s, yields
a string s' that is accepted by a *)
let test_mutation =
(* generate triples (s, i, c) where c is a char, s a non empty string
and i a valid index in s *)
let gen = QCheck.Arbitrary.(
int_range ~start:3 ~stop:10 >>= fun len ->
int (len-1) >>= fun i ->
string_len (return len) >>= fun s ->
char >>= fun c ->
return (s,i,c)
) in
let test (s,i,c) =
let s' = Bytes.of_string s in
Bytes.set s' i c;
let a = Levenshtein.of_string ~limit:1 s in
Levenshtein.match_with a (Bytes.to_string s')
in
let name = "mutating s.[i] into s' still accepted by automaton(s)" in
QCheck.mk_test ~name ~size:(fun (s,_,_)->String.length s) gen test
(* test that, for an index, all retrieved strings are at a distance to
the key that is not too high *)
let test_index =
let gen = QCheck.Arbitrary.(
list string >>= fun l ->
let l = List.map (fun s->s,s) l in
return (List.map fst l, Levenshtein.Index.of_list l)
) in
let test (l, idx) =
List.for_all
(fun s ->
let retrieved = Levenshtein.Index.retrieve ~limit:2 idx s
|> Levenshtein.klist_to_list in
List.for_all
(fun s' -> Levenshtein.edit_distance s s' <= 2) retrieved
) l
in
let name = "strings retrieved from automaton with limit:n are at distance <= n" in
QCheck.mk_test ~name gen test
let props =
[ test_automaton
; test_mutation
; test_index
]

View file

@ -1,98 +0,0 @@
open OUnit
open Containers_misc
open CCFun
module Mixtbl = CCMixtbl
let example () =
let inj_int = Mixtbl.create_inj () in
let tbl = Mixtbl.create 10 in
OUnit.assert_equal None (Mixtbl.get ~inj:inj_int tbl "a");
Mixtbl.set ~inj:inj_int tbl "a" 1;
OUnit.assert_equal (Some 1) (Mixtbl.get ~inj:inj_int tbl "a");
let inj_string = Mixtbl.create_inj () in
Mixtbl.set ~inj:inj_string tbl "b" "Hello";
OUnit.assert_equal (Some "Hello") (Mixtbl.get ~inj:inj_string tbl "b");
OUnit.assert_equal None (Mixtbl.get ~inj:inj_string tbl "a");
OUnit.assert_equal (Some 1) (Mixtbl.get ~inj:inj_int tbl "a");
Mixtbl.set ~inj:inj_string tbl "a" "Bye";
OUnit.assert_equal None (Mixtbl.get ~inj:inj_int tbl "a");
OUnit.assert_equal (Some "Bye") (Mixtbl.get ~inj:inj_string tbl "a");
()
let test_length () =
let inj_int = Mixtbl.create_inj () in
let tbl = Mixtbl.create 5 in
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
OUnit.assert_equal 2 (Mixtbl.length tbl);
OUnit.assert_equal 2 (Mixtbl.find ~inj:inj_int tbl "bar");
Mixtbl.set ~inj:inj_int tbl "foo" 42;
OUnit.assert_equal 2 (Mixtbl.length tbl);
Mixtbl.remove tbl "bar";
OUnit.assert_equal 1 (Mixtbl.length tbl);
()
let test_clear () =
let inj_int = Mixtbl.create_inj () in
let inj_str = Mixtbl.create_inj () in
let tbl = Mixtbl.create 5 in
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
OUnit.assert_equal 3 (Mixtbl.length tbl);
Mixtbl.clear tbl;
OUnit.assert_equal 0 (Mixtbl.length tbl);
()
let test_mem () =
let inj_int = Mixtbl.create_inj () in
let inj_str = Mixtbl.create_inj () in
let tbl = Mixtbl.create 5 in
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
OUnit.assert_bool "mem foo int" (Mixtbl.mem ~inj:inj_int tbl "foo");
OUnit.assert_bool "mem bar int" (Mixtbl.mem ~inj:inj_int tbl "bar");
OUnit.assert_bool "not mem baaz int" (not (Mixtbl.mem ~inj:inj_int tbl "baaz"));
OUnit.assert_bool "not mem foo str" (not (Mixtbl.mem ~inj:inj_str tbl "foo"));
OUnit.assert_bool "not mem bar str" (not (Mixtbl.mem ~inj:inj_str tbl "bar"));
OUnit.assert_bool "mem baaz str" (Mixtbl.mem ~inj:inj_str tbl "baaz");
()
let test_keys () =
let inj_int = Mixtbl.create_inj () in
let inj_str = Mixtbl.create_inj () in
let tbl = Mixtbl.create 5 in
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
let l = Mixtbl.keys_seq tbl |> Sequence.to_list in
OUnit.assert_equal ["baaz"; "bar"; "foo"] (List.sort compare l);
()
let test_bindings () =
let inj_int = Mixtbl.create_inj () in
let inj_str = Mixtbl.create_inj () in
let tbl = Mixtbl.create 5 in
Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
Mixtbl.set ~inj:inj_str tbl "str" "rts";
let l_int = Mixtbl.bindings_of tbl ~inj:inj_int |> Sequence.to_list in
OUnit.assert_equal ["bar", 2; "foo", 1] (List.sort compare l_int);
let l_str = Mixtbl.bindings_of tbl ~inj:inj_str |> Sequence.to_list in
OUnit.assert_equal ["baaz", "hello"; "str", "rts"] (List.sort compare l_str);
()
let suite =
"mixtbl" >:::
[ "example" >:: example;
"length" >:: test_length;
"clear" >:: test_clear;
"mem" >:: test_mem;
"bindings" >:: test_bindings;
"keys" >:: test_keys;
]

View file

@ -1,93 +0,0 @@
open OUnit
module Vector = CCVector
let test_clear () =
let v = Vector.of_seq Sequence.(1 -- 10) in
OUnit.assert_equal 10 (Vector.size v);
Vector.clear v;
OUnit.assert_equal 0 (Vector.size v);
OUnit.assert_bool "empty_after_clear" (Sequence.is_empty (Vector.to_seq v));
()
let test_append () =
let a = Vector.of_seq Sequence.(1 -- 5) in
let b = Vector.of_seq Sequence.(6 -- 10) in
Vector.append a b;
OUnit.assert_equal 10 (Vector.size a);
OUnit.assert_equal (Sequence.to_array Sequence.(1 -- 10)) (Vector.to_array a);
OUnit.assert_equal (Sequence.to_array Sequence.(6 -- 10)) (Vector.to_array b);
()
let test_copy () =
let v = Vector.of_seq Sequence.(1 -- 100) in
OUnit.assert_equal 100 (Vector.size v);
let v' = Vector.copy v in
OUnit.assert_equal 100 (Vector.size v');
Vector.clear v';
OUnit.assert_bool "empty" (Vector.is_empty v');
OUnit.assert_bool "not_empty" (not (Vector.is_empty v));
()
let test_shrink () =
let v = Vector.of_seq Sequence.(1 -- 10) in
Vector.shrink v 5;
OUnit.assert_equal [1;2;3;4;5] (Vector.to_list v);
()
let suite =
"test_vector" >:::
[ "test_clear" >:: test_clear;
"test_append" >:: test_append;
"test_copy" >:: test_copy;
"test_shrink" >:: test_shrink;
]
open QCheck
module V = Vector
let gen sub = Arbitrary.(lift V.of_list (list sub))
let pp v = PP.(list string) (List.map string_of_int (V.to_list v))
let check_append =
let gen = Arbitrary.(pair (gen small_int) (gen small_int)) in
let prop (v1, v2) =
let l1 = V.to_list v1 in
V.append v1 v2;
Sequence.to_list (V.to_seq v1) =
Sequence.(to_list (append (of_list l1) (V.to_seq v2)))
in
let name = "vector_append" in
mk_test ~name ~pp:PP.(pair pp pp) gen prop
let check_sort =
let gen = Arbitrary.(gen small_int) in
let prop v =
let v' = V.copy v in
V.sort' Pervasives.compare v';
let l = V.to_list v' in
List.sort compare l = l
in
let name = "vector_sort" in
mk_test ~name ~pp gen prop
let check_shrink =
let gen = Arbitrary.(gen small_int) in
let prop v =
let n = V.size v / 2 in
let l = V.to_list v in
let h = Sequence.(to_list (take n (of_list l))) in
let v' = V.copy v in
V.shrink v' n;
h = V.to_list v'
in
let name = "vector_shrink" in
mk_test ~name ~pp gen prop
let props =
[ check_append
; check_sort
; check_shrink
]