diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index db84107a..0b94b407 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -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 diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index de490786..60f68286 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -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 diff --git a/src/data/CCBV.ml b/src/data/CCBV.ml index aa91dca7..16500de6 100644 --- a/src/data/CCBV.ml +++ b/src/data/CCBV.ml @@ -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 diff --git a/src/data/CCDeque.ml b/src/data/CCDeque.ml index c5a1f90e..014a9832 100644 --- a/src/data/CCDeque.ml +++ b/src/data/CCDeque.ml @@ -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 diff --git a/src/data/CCFQueue.ml b/src/data/CCFQueue.ml index ba44bc2e..d7e0a161 100644 --- a/src/data/CCFQueue.ml +++ b/src/data/CCFQueue.ml @@ -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 "}@]" - + diff --git a/src/data/CCIntMap.ml b/src/data/CCIntMap.ml index 7e49c28f..2baf5901 100644 --- a/src/data/CCIntMap.ml +++ b/src/data/CCIntMap.ml @@ -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) *) diff --git a/src/data/CCMixtbl.ml b/src/data/CCMixtbl.ml index d89e6e67..730f3093 100644 --- a/src/data/CCMixtbl.ml +++ b/src/data/CCMixtbl.ml @@ -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); +*) diff --git a/src/data/CCPersistentHashtbl.ml b/src/data/CCPersistentHashtbl.ml index 9983ad98..338d9826 100644 --- a/src/data/CCPersistentHashtbl.ml +++ b/src/data/CCPersistentHashtbl.ml @@ -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 && diff --git a/src/data/CCTrie.ml b/src/data/CCTrie.ml index 7527083b..93b99a00 100644 --- a/src/data/CCTrie.ml +++ b/src/data/CCTrie.ml @@ -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,_) -> \ diff --git a/src/data/CCWBTree.ml b/src/data/CCWBTree.ml index deea8dd9..65f8fdd9 100644 --- a/src/data/CCWBTree.ml +++ b/src/data/CCWBTree.ml @@ -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) *) diff --git a/src/string/CCLevenshtein.ml b/src/string/CCLevenshtein.ml index b66a0671..7ccbb495 100644 --- a/src/string/CCLevenshtein.ml +++ b/src/string/CCLevenshtein.ml @@ -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_ diff --git a/tests/run_tests.ml b/tests/run_tests.ml index 7665d356..e54ced5a 100644 --- a/tests/run_tests.ml +++ b/tests/run_tests.ml @@ -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); () diff --git a/tests/test_CCHeap.ml b/tests/test_CCHeap.ml deleted file mode 100644 index 3b4547a3..00000000 --- a/tests/test_CCHeap.ml +++ /dev/null @@ -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! *) - ] diff --git a/tests/test_PersistentHashtbl.ml b/tests/test_PersistentHashtbl.ml deleted file mode 100644 index dd84be8a..00000000 --- a/tests/test_PersistentHashtbl.ml +++ /dev/null @@ -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 "@[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 - ] diff --git a/tests/test_bv.ml b/tests/test_bv.ml deleted file mode 100644 index 2a7a6152..00000000 --- a/tests/test_bv.ml +++ /dev/null @@ -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 - ] diff --git a/tests/test_deque.ml b/tests/test_deque.ml deleted file mode 100644 index 76a5448a..00000000 --- a/tests/test_deque.ml +++ /dev/null @@ -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; - ] diff --git a/tests/test_fQueue.ml b/tests/test_fQueue.ml deleted file mode 100644 index d164aba1..00000000 --- a/tests/test_fQueue.ml +++ /dev/null @@ -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; - ] diff --git a/tests/test_levenshtein.ml b/tests/test_levenshtein.ml deleted file mode 100644 index 38f5bbc8..00000000 --- a/tests/test_levenshtein.ml +++ /dev/null @@ -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 - ] diff --git a/tests/test_mixtbl.ml b/tests/test_mixtbl.ml deleted file mode 100644 index e8f4c82f..00000000 --- a/tests/test_mixtbl.ml +++ /dev/null @@ -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; - ] - diff --git a/tests/test_vector.ml b/tests/test_vector.ml deleted file mode 100644 index c8ece7c6..00000000 --- a/tests/test_vector.ml +++ /dev/null @@ -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 - ]