mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
move many tests into their modules with qtest
This commit is contained in:
parent
ada364ae3a
commit
eb1c9bc0be
20 changed files with 640 additions and 765 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -475,4 +516,4 @@ let print pp_x out d =
|
|||
pp_x out x
|
||||
) d;
|
||||
Format.fprintf out "}@]"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*)
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
&&
|
||||
|
|
|
|||
|
|
@ -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,_) -> \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*)
|
||||
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
()
|
||||
|
|
|
|||
|
|
@ -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! *)
|
||||
]
|
||||
|
|
@ -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
|
||||
]
|
||||
100
tests/test_bv.ml
100
tests/test_bv.ml
|
|
@ -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
|
||||
]
|
||||
|
|
@ -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;
|
||||
]
|
||||
|
|
@ -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;
|
||||
]
|
||||
|
|
@ -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
|
||||
]
|
||||
|
|
@ -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;
|
||||
]
|
||||
|
||||
|
|
@ -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
|
||||
]
|
||||
Loading…
Add table
Reference in a new issue