From b695918e998bf9efb36090d33911a5d01a331bd0 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sat, 2 Jul 2022 00:29:25 -0400 Subject: [PATCH] move all core tests to new testlib --- src/bencode/containers_bencode.ml | 55 ---- src/core/CCEqualLabels.mli | 25 +- src/core/CCHashtbl.ml | 56 ---- src/core/CCHeap.ml | 92 ------ src/core/CCIO.ml | 71 ----- src/core/CCInt.ml | 163 ---------- src/core/CCInt32.ml | 75 ----- src/core/CCInt64.ml | 75 ----- src/core/CCMap.ml | 28 -- src/core/CCNativeint.ml | 75 ----- src/core/CCOption.ml | 40 --- src/core/CCOrd.ml | 56 ---- src/core/CCParse.ml | 229 -------------- src/core/CCRandom.ml | 17 -- src/core/CCResult.ml | 43 --- src/core/CCSeq.ml | 130 -------- src/core/CCSet.ml | 23 -- src/core/CCSexp.ml | 88 ------ src/core/CCString.ml | 343 --------------------- src/core/CCUtf8_string.ml | 181 ----------- src/core/CCVector.ml | 468 ----------------------------- src/testlib/containers_testlib.ml | 11 +- src/testlib/containers_testlib.mli | 2 +- src/unix/CCUnix.ml | 53 ---- tests/core/compat/dune | 5 + tests/core/compat/t_compat.ml | 9 + tests/core/dune | 4 +- tests/core/t.ml | 21 ++ tests/core/t_IO.ml | 69 +++++ tests/core/t_bencode.ml | 57 ++++ tests/core/t_eq.ml | 2 +- tests/core/t_hashtbl.ml | 55 ++++ tests/core/t_heap.ml | 87 ++++++ tests/core/t_int.ml | 132 ++++++++ tests/core/t_int32.ml | 66 ++++ tests/core/t_int64.ml | 65 ++++ tests/core/t_map.ml | 27 ++ tests/core/t_nativeint.ml | 67 +++++ tests/core/t_option.ml | 25 ++ tests/core/t_ord.ml | 43 +++ tests/core/t_parse.ml | 214 +++++++++++++ tests/core/t_random.ml | 19 ++ tests/core/t_result.ml | 32 ++ tests/core/t_seq.ml | 88 ++++++ tests/core/t_set.ml | 22 ++ tests/core/t_sexp.ml | 80 +++++ tests/core/t_string.ml | 264 ++++++++++++++++ tests/core/t_unix.ml | 48 +++ tests/core/t_utf8string.ml | 162 ++++++++++ tests/core/t_vector.ml | 361 ++++++++++++++++++++++ 50 files changed, 2039 insertions(+), 2384 deletions(-) create mode 100644 tests/core/compat/dune create mode 100644 tests/core/compat/t_compat.ml create mode 100644 tests/core/t_IO.ml create mode 100644 tests/core/t_bencode.ml create mode 100644 tests/core/t_hashtbl.ml create mode 100644 tests/core/t_heap.ml create mode 100644 tests/core/t_int.ml create mode 100644 tests/core/t_int32.ml create mode 100644 tests/core/t_int64.ml create mode 100644 tests/core/t_map.ml create mode 100644 tests/core/t_nativeint.ml create mode 100644 tests/core/t_option.ml create mode 100644 tests/core/t_ord.ml create mode 100644 tests/core/t_parse.ml create mode 100644 tests/core/t_random.ml create mode 100644 tests/core/t_result.ml create mode 100644 tests/core/t_seq.ml create mode 100644 tests/core/t_set.ml create mode 100644 tests/core/t_sexp.ml create mode 100644 tests/core/t_string.ml create mode 100644 tests/core/t_unix.ml create mode 100644 tests/core/t_utf8string.ml create mode 100644 tests/core/t_vector.ml diff --git a/src/bencode/containers_bencode.ml b/src/bencode/containers_bencode.ml index 1ec9f692..88ce7d62 100644 --- a/src/bencode/containers_bencode.ml +++ b/src/bencode/containers_bencode.ml @@ -157,58 +157,3 @@ module Decode = struct | Some x -> x | None -> failwith "bencode.decode: invalid string" end - -(*$= & ~printer:to_string_debug - (map_of_list []) (Decode.of_string_exn "de") - (list [int 1; int 2; string "foo"]) (Decode.of_string_exn "li1ei2e3:fooe") -*) - -(*$inject - module B = Containers_bencode - - let rec size = function - | Int _ | String _ -> 1 - | List l -> List.fold_left (fun n x -> n + size x) 0 l - | Map m -> Str_map.fold(fun _ v n -> size v + n) m 0 - - let g_rand_b = - Q.Gen.( - sized_size (0--7) @@ fix @@ fun self n -> - let str n = string_size ~gen:char (0 -- n) in - let base = [ - int >|= B.int; - str 100 >|= B.string; - ] in - match n with - | 0 -> oneof base - | n -> - frequency @@ - List.map (fun x -> 2, x) base @ - [ 1, list_size (0 -- 10) (self (n-1)) >|= B.list; - 1, list_size (0 -- 10) (pair (str 10) (self (n-1)) ) >|= B.map_of_list; - ] - ) - - let rec shrink_b self = Q.(Iter.( - match self with - | Int i -> Shrink.int64 i >|= B.int64 - | String s -> Shrink.string s >|= B.string - | List l -> Shrink.list ~shrink:shrink_b l >|= B.list - | Map l -> - let l = Str_map.fold (fun k v l -> (k,v) :: l) l [] in - Shrink.list ~shrink:(fun (k,v) -> - (Shrink.string k >|= fun k -> k,v) <+> - (shrink_b v >|= fun v -> k,v)) - l - >|= B.map_of_list - )) - - let rand_b = Q.make ~print:to_string_debug ~stats:["size", size] - ~shrink:shrink_b g_rand_b - *) - -(*$Q - rand_b (fun b -> \ - let s=Encode.to_string b in \ - equal (Decode.of_string_exn s) b) -*) diff --git a/src/core/CCEqualLabels.mli b/src/core/CCEqualLabels.mli index 764abe2d..4014ac5e 100644 --- a/src/core/CCEqualLabels.mli +++ b/src/core/CCEqualLabels.mli @@ -36,24 +36,19 @@ val map : f:('a -> 'b) -> 'b t -> 'a t [map fst int] compares values of type [(int * 'a)] by their first component. *) +val always_eq : _ t +(** Always returns true. All values are equal. + @since NEXT_RELEASE *) + +val never_eq : _ t +(** Always returns false. No values are, so this + is not even reflexive (i.e. [x=x] is false). + Be careful! + @since NEXT_RELEASE *) + module Infix : sig val (>|=) : 'b t -> ('a -> 'b) -> 'a t (** Infix equivalent of {!map}. *) end include module type of Infix - -(* test consistency of interfaces *) -(*$inject - module type L = module type of CCEqual - module type LL = module type of CCEqualLabels -*) - -(*$R - ignore (module CCEqualLabels : L) -*) - -(*$R - ignore (module CCEqual : LL) -*) - diff --git a/src/core/CCHashtbl.ml b/src/core/CCHashtbl.ml index ed69ff88..ae14ff53 100644 --- a/src/core/CCHashtbl.ml +++ b/src/core/CCHashtbl.ml @@ -19,10 +19,6 @@ module Poly = struct try Hashtbl.find tbl x with Not_found -> default - (*$= - "c" (let tbl = of_list [1,"a"; 2,"b"] in get_or tbl 3 ~default:"c") - "b" (let tbl = of_list [1,"a"; 2,"b"] in get_or tbl 2 ~default:"c") - *) let keys tbl k = Hashtbl.iter (fun key _ -> k key) tbl @@ -54,11 +50,6 @@ module Poly = struct (fun x y acc -> f x y :: acc) h [] - (*$T - of_list [1,"a"; 2,"b"] |> map_list (fun x y -> string_of_int x ^ y) \ - |> List.sort Stdlib.compare = ["1a"; "2b"] - *) - let to_iter tbl k = Hashtbl.iter (fun key v -> k (key,v)) tbl let add_iter tbl i = i (fun (k,v) -> Hashtbl.add tbl k v) @@ -123,17 +114,6 @@ module Poly = struct | Some _, Some v' -> Hashtbl.replace tbl k v' | Some _, None -> Hashtbl.remove tbl k - (*$R - let tbl = Hashtbl.create 32 in - update tbl ~f:(fun _ _ -> Some "1") ~k:1; - assert_equal (Some "1") (get tbl 1); - update tbl ~f:(fun _ v->match v with Some _ -> assert false | None -> Some "2") ~k:2; - assert_equal (Some "2") (get tbl 2); - assert_equal 2 (Hashtbl.length tbl); - update tbl ~f:(fun _ _ -> None) ~k:1; - assert_equal None (get tbl 1); - *) - let get_or_add tbl ~f ~k = try Hashtbl.find tbl k with Not_found -> @@ -141,19 +121,6 @@ module Poly = struct Hashtbl.add tbl k v; v - (*$R - let tbl = Hashtbl.create 32 in - let v1 = get_or_add tbl ~f:(fun _ -> "1") ~k:1 in - assert_equal "1" v1; - assert_equal (Some "1") (get tbl 1); - let v2 = get_or_add tbl ~f:(fun _ ->"2") ~k:2 in - assert_equal "2" v2; - assert_equal (Some "2") (get tbl 2); - assert_equal "2" (get_or_add tbl ~f:(fun _ -> assert false) ~k:2); - assert_equal 2 (Hashtbl.length tbl); - () - *) - let pp ?(pp_start=fun _ () -> ()) ?(pp_stop=fun _ () -> ()) ?(pp_sep=fun fmt () -> Format.fprintf fmt ",@ ") ?(pp_arrow=fun fmt () -> Format.fprintf fmt "@ -> ") pp_k pp_v fmt m = @@ -342,10 +309,6 @@ module type S = sig @since 0.13 *) end -(*$inject - module T = Make(CCInt) -*) - module Make(X : Hashtbl.HashedType) : S with type key = X.t and type 'a t = 'a Hashtbl.Make(X).t = struct @@ -359,31 +322,12 @@ module Make(X : Hashtbl.HashedType) try find tbl x with Not_found -> default - (*$= - "c" (let tbl = T.of_list [1,"a"; 2,"b"] in T.get_or tbl 3 ~default:"c") - "b" (let tbl = T.of_list [1,"a"; 2,"b"] in T.get_or tbl 2 ~default:"c") - *) - let incr ?(by=1) tbl x = let n = get_or tbl x ~default:0 in if n+by <= 0 then remove tbl x else replace tbl x (n+by) - (*$R - let tbl = T.create 32 in - T.incr tbl 1 ; - T.incr tbl 2; - T.incr tbl 1; - assert_equal 2 (T.find tbl 1); - assert_equal 1 (T.find tbl 2); - assert_equal 2 (T.length tbl); - T.decr tbl 2; - assert_equal 0 (T.get_or tbl 2 ~default:0); - assert_equal 1 (T.length tbl); - assert_bool "2 removed" (not (T.mem tbl 2)); - *) - let add_list tbl k v = let l = try find tbl k with Not_found -> [] in replace tbl k (v::l) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index 0b986f91..01acd3c8 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -23,69 +23,6 @@ module type TOTAL_ORD = sig a positive value if [a] is greater than [b] *) 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 = H.to_list_sorted -*) - -(*$R - let h = H.of_list [5;3;4;1;42;0] in - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 0 x; - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 1 x; - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 3 x; - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 4 x; - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 5 x; - let h, x = H.take_exn h in - OUnit2.assert_equal ~printer:string_of_int 42 x; - OUnit2.assert_raises H.Empty (fun () -> H.take_exn h); -*) - -(*$QR & ~count:30 - Q.(list_of_size Gen.(return 1_000) int) (fun l -> - (* put elements into a heap *) - let h = H.of_iter (Iter.of_list l) in - OUnit2.assert_equal 1_000 (H.size h); - let l' = extract_list h in - is_sorted l' - ) -*) - -(* test filter *) -(*$QR & ~count:30 - Q.(list_of_size Gen.(return 1_000) int) (fun l -> - (* put elements into a heap *) - let h = H.of_iter (Iter.of_list l) in - let h = H.filter (fun x->x mod 2=0) h in - OUnit2.assert_bool "all odd" - (H.to_iter h |> Iter.for_all (fun x -> x mod 2 = 0)); - let l' = extract_list h in - is_sorted l' - ) -*) - -(*$QR - Q.(list_of_size Gen.(return 1_000) int) (fun l -> - (* put elements into a heap *) - let h = H.of_iter (Iter.of_list l) in - let l' = H.to_iter_sorted h |> Iter.to_list in - is_sorted l' - ) -*) - module type S = sig type elt type t @@ -405,16 +342,6 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct Some x in next - (*$Q - Q.(list int) (fun l -> \ - extract_list (H.of_list l) = \ - extract_list (H.of_gen (CCList.to_gen l))) - Q.(list int) (fun l -> \ - let h = H.of_list l in \ - (H.to_gen h |> CCList.of_gen |> List.sort Stdlib.compare) \ - = (H.to_list h |> List.sort Stdlib.compare)) - *) - let rec to_tree h () = match h with | E -> `Nil | N (_, x, l, r) -> `Node(x, [to_tree l; to_tree r]) @@ -424,17 +351,6 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct |> List.map elt_to_string |> String.concat sep - (*$Q - Q.(list int) (fun l -> \ - let h = H.of_list l in \ - (H.to_string string_of_int h) \ - = (List.sort Stdlib.compare l |> List.map string_of_int |> String.concat ",")) - Q.(list int) (fun l -> \ - let h = H.of_list l in \ - (H.to_string ~sep:" " string_of_int h) \ - = (List.sort Stdlib.compare l |> List.map string_of_int |> String.concat " ")) - *) - let pp ?(pp_start=fun _ () -> ()) ?(pp_stop=fun _ () -> ()) ?(pp_sep=fun out () -> Format.fprintf out ",") pp_elt out h = let first=ref true in @@ -453,11 +369,3 @@ module Make_from_compare(E : TOTAL_ORD) = let leq a b = E.compare a b <= 0 end) -(*$QR - Q.(list_of_size Gen.(return 1_000) int) (fun l -> - let module H' = Make_from_compare(CCInt) in - let h = H'.of_list l in - let l' = H'.to_list_sorted h in - is_sorted l' - ) -*) diff --git a/src/core/CCIO.ml b/src/core/CCIO.ml index 8bc329c0..29c90af0 100644 --- a/src/core/CCIO.ml +++ b/src/core/CCIO.ml @@ -167,19 +167,6 @@ let read_all_bytes ?(size=1024) ic = read_all_ ~op:Ret_bytes ~size ic let read_all ?(size=1024) ic = read_all_ ~op:Ret_string ~size ic -(*$R - let s = String.make 200 'y' in - let s = Printf.sprintf "a\nb\n %s\nlast line\n" s in - File.with_temp ~prefix:"test_containers" ~suffix:"" - (fun name -> - with_out name @@ fun oc -> - output_string oc s; - flush oc; - let s' = with_in name read_all in - OUnit2.assert_equal ~printer:(fun s->s) s s' - ) -*) - let with_out ?(mode=0o644) ?(flags=[Open_creat; Open_trunc; Open_text]) filename f = let oc = open_out_gen (Open_wronly::flags) mode filename in @@ -235,34 +222,6 @@ let write_lines_l oc l = (* test {read,write}_lines. Need to concatenate the lists because some strings in the random input might contain '\n' themselves *) -(*$QR - Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> - let l' = ref [] in - File.with_temp ~prefix:"test_containers" ~suffix:"" - (fun name -> - with_out name @@ fun oc -> - write_lines_l oc l; - flush oc; - l' := with_in name read_lines_l; - ); - String.concat "\n" l = String.concat "\n" !l' - ) -*) - -(*$QR - Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> - let l' = ref [] in - File.with_temp ~prefix:"test_containers" ~suffix:"" - (fun name -> - with_out name @@ fun oc -> - write_lines oc (Gen.of_list l); - flush oc; - l' := with_in name (fun ic -> read_lines_gen ic |> Gen.to_list); - ); - String.concat "\n" l = String.concat "\n" !l' - ) -*) - let with_in_out ?(mode=0o644) ?(flags=[Open_creat]) filename f = let ic = open_in_gen (Open_rdonly::flags) mode filename in let oc = open_out_gen (Open_wronly::flags) mode filename in @@ -288,25 +247,6 @@ let copy_into ?(bufsize=4_096) ic oc : unit = ) done -(*$QR - Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> - let s = ref "" in - File.with_temp ~prefix:"test_containers1" ~suffix:"" - (fun name1 -> - with_out name1 @@ fun oc1 -> - write_gen ~sep:"" oc1 (Gen.of_list l); - flush oc1; - File.with_temp ~prefix:"test_containers2" ~suffix:"" - (fun name2 -> - with_out name2 @@ fun oc2 -> - CCIO.with_in name1 (fun ic1 -> copy_into ic1 oc2); - flush oc2; - s := with_in name2 read_all;); - ); - String.concat "" l = !s - ) -*) - let tee funs g () = match g() with | None -> None | Some x as res -> @@ -394,17 +334,6 @@ module File = struct ) else gen_singleton (`File, d) - (*$R - OUnit2.assert_bool "walk categorizes files" - (File.walk "." - |> Gen.for_all - (function - | `File, f -> not (Sys.is_directory f) - | `Dir, f -> Sys.is_directory f - ) - ) - *) - let walk_seq d = seq_of_gen_ (walk d) let walk_iter d = fun yield -> gen_iter yield (walk d) diff --git a/src/core/CCInt.ml b/src/core/CCInt.ml index 8f2e38f6..ff466136 100644 --- a/src/core/CCInt.ml +++ b/src/core/CCInt.ml @@ -74,23 +74,11 @@ let range i j yield = in if i<=j then up i j yield else down i j yield -(*$= & ~printer:Q.Print.(list int) - [0;1;2;3;4;5] (range 0 5 |> Iter.to_list) - [0] (range 0 0 |> Iter.to_list) - [5;4;3;2] (range 5 2 |> Iter.to_list) -*) - let range' i j yield = if i Iter.to_list) - [0;1;2;3;4] (range' 0 5 |> Iter.to_list) - [5;4;3] (range' 5 2 |> Iter.to_list) -*) - let sign i = compare i 0 let neg i = -i @@ -108,14 +96,6 @@ let pow a b = | b when b < 0 -> raise (Invalid_argument "pow: can't raise int to negative power") | b -> aux a b -(*$T - pow 2 10 = 1024 - pow 2 15 = 32768 - pow 10 5 = 100000 - pow 1 0 = 1 - pow 0 1 = 0 -*) - module Infix : sig val (=) : t -> t -> bool val (<>) : t -> t -> bool @@ -158,36 +138,6 @@ let floor_div a n = else a / n -(*$T - (floor_div 3 5 = 0) - (floor_div 5 5 = 1) - (floor_div 20 5 = 4) - (floor_div 12 5 = 2) - (floor_div 0 5 = 0) - (floor_div (-1) 5 = -1) - (floor_div (-5) 5 = -1) - (floor_div (-12) 5 = -3) - - (floor_div 0 (-5) = 0) - (floor_div 3 (-5) = -1) - (floor_div 5 (-5) = -1) - (floor_div 9 (-5) = -2) - (floor_div 20 (-5) = -4) - (floor_div (-2) (-5) = 0) - (floor_div (-8) (-5) = 1) - (floor_div (-35) (-5) = 7) - - try ignore (floor_div 12 0); false with Division_by_zero -> true - try ignore (floor_div (-12) 0); false with Division_by_zero -> true -*) - -(*$Q - (Q.pair Q.small_signed_int Q.pos_int) \ - (fun (n, m) -> floor_div n m = int_of_float @@ floor (float n /. float m)) - (Q.pair Q.small_signed_int Q.pos_int) \ - (fun (n, m) -> floor_div n (-m) = int_of_float @@ floor (float n /. float (-m))) -*) - let bool_neq (a : bool) b = Stdlib.(<>) a b let rem a n = @@ -197,38 +147,6 @@ let rem a n = else y -(*$T - (rem 3 5 = 3) - (rem 5 5 = 0) - (rem 9 5 = 4) - (rem (-1) 5 = 4) - (rem (-5) 5 = 0) - (rem (-20) 5 = 0) - (rem (-9) 5 = 1) - (rem 0 5 = 0) - - (rem 0 (-5) = 0) - (rem 3 (-5) = -2) - (rem 5 (-5) = 0) - (rem 9 (-5) = -1) - (rem (-2) (-5) = -2) - (rem (-8) (-5) = -3) - (rem (-35) (-5) = 0) - - try ignore (rem 12 0); false with Division_by_zero -> true - try ignore (rem (-12) 0); false with Division_by_zero -> true -*) - -(*$Q - (Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n m in y >= 0 && y < m) - (Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n (-m) in y > (-m) && y <= 0) -*) - -(*$Q - (Q.pair Q.int Q.pos_int) (fun (n, m) -> n = m * floor_div n m + rem n m) - (Q.pair Q.int Q.pos_int) (fun (n, m) -> n = (-m) * floor_div n (-m) + rem n (-m)) -*) - type 'a printer = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a @@ -247,21 +165,12 @@ let of_string s = try Some (int_of_string s) with Failure _ -> None -(*$= - None (of_string "moo") - (Some 42) (of_string "42") -*) - let of_string_exn = Stdlib.int_of_string let to_float = float_of_int let of_float = int_of_float -(*$= - 1 (of_float 1.2) -*) - type output = char -> unit (* abstract printer *) @@ -292,17 +201,6 @@ let to_string_binary n = to_binary_gen (Buffer.add_char buf) n; Buffer.contents buf -(*$= & ~printer:CCFun.id - "0b111" (to_string_binary 7) - "-0b111" (to_string_binary (-7)) - "0b0" (to_string_binary 0) -*) - - -(*$Q & ~count:10_000 - Q.int (fun n -> n = int_of_string (to_string_binary n)) -*) - let range_by ~step i j yield = let rec range i j yield = if i=j then yield i @@ -316,29 +214,6 @@ let range_by ~step i j yield = else if (if step > 0 then i>j else i Iter.to_list) - [] (range_by ~step:1 5 0 |> Iter.to_list) - [] (range_by ~step:2 1 0 |> Iter.to_list) - [0;2;4] (range_by ~step:2 0 4 |> Iter.to_list) - [0;2;4] (range_by ~step:2 0 5 |> Iter.to_list) - [0] (range_by ~step:~-1 0 0 |> Iter.to_list) - [] (range_by ~step:~-1 0 5 |> Iter.to_list) - [] (range_by ~step:~-2 0 1 |> Iter.to_list) - [5;3;1] (range_by ~step:~-2 5 1 |> Iter.to_list) - [5;3;1] (range_by ~step:~-2 5 0 |> Iter.to_list) - [0] (range_by ~step:max_int 0 2 |> Iter.to_list) -*) - -(*$Q - Q.(pair small_int small_int) (fun (i,j) -> \ - let i = min i j and j = max i j in \ - CCList.equal CCInt.equal \ - (CCInt.range_by ~step:1 i j |> Iter.to_list) \ - (CCInt.range i j |> Iter.to_list) ) -*) - (* from https://en.wikipedia.org/wiki/Hamming_weight @@ -377,44 +252,6 @@ let popcount (b:int) : int = let b = logand b 0x7fL in to_int b -(*$= - 0 (popcount 0) - 1 (popcount 1) - (Sys.word_size-2) (popcount max_int) - 1 (popcount min_int) - 10 (popcount 0b1110010110110001010) - 5 (popcount 0b1101110000000000) -*) - -(*$inject - let simple_popcnt i = - let rec loop n i = - if i=0 then n - else if i land 0b1 = 1 then loop (n+1) (i lsr 1) - else loop n (i lsr 1) - in - loop 0 i -*) - -(*$= - 0 (simple_popcnt 0) - 1 (simple_popcnt 1) - (Sys.word_size-2) (simple_popcnt max_int) - 1 (simple_popcnt min_int) - 5 (simple_popcnt 0b1101110000000000) -*) - -(*$QR & ~count:3_000 ~long_factor:10 - Q.(let g = int in - set_gen (Gen.graft_corners g.gen [min_int; max_int; 0; -1; 1] ()) g) - (fun i -> - if simple_popcnt i <> popcount i then ( - Q.Test.fail_reportf "on %d: simple-popcount=%d, popcount=%d" - i (simple_popcnt i) (popcount i) - ); - true) - *) - let logand = (land) let logor = (lor) diff --git a/src/core/CCInt32.ml b/src/core/CCInt32.ml index 2abe36cd..149fea02 100644 --- a/src/core/CCInt32.ml +++ b/src/core/CCInt32.ml @@ -24,14 +24,6 @@ let pow a b = | b when compare b 0l < 0 -> raise (Invalid_argument "pow: can't raise int to negative power") | b -> aux a b -(*$T - pow 2l 10l = 1024l - pow 2l 15l = 32768l - pow 10l 5l = 100000l - pow 42l 0l = 1l - pow 0l 1l = 0l -*) - let floor_div a n = if compare a 0l < 0 && compare n 0l >= 0 then sub (div (add a 1l) n) 1l @@ -40,38 +32,6 @@ let floor_div a n = else div a n -(*$T - (floor_div 3l 5l = 0l) - (floor_div 5l 5l = 1l) - (floor_div 20l 5l = 4l) - (floor_div 12l 5l = 2l) - (floor_div 0l 5l = 0l) - (floor_div (-1l) 5l = -1l) - (floor_div (-5l) 5l = -1l) - (floor_div (-12l) 5l = -3l) - - (floor_div 0l (-5l) = 0l) - (floor_div 3l (-5l) = -1l) - (floor_div 5l (-5l) = -1l) - (floor_div 9l (-5l) = -2l) - (floor_div 20l (-5l) = -4l) - (floor_div (-2l) (-5l) = 0l) - (floor_div (-8l) (-5l) = 1l) - (floor_div (-35l) (-5l) = 7l) - - try ignore (floor_div 12l 0l); false with Division_by_zero -> true - try ignore (floor_div (-12l) 0l); false with Division_by_zero -> true -*) - -(*$Q - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1l in \ - floor_div n m = of_float @@ floor (to_float n /. to_float m)) - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1l in \ - floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m))) -*) - type 'a printer = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a type 'a iter = ('a -> unit) -> unit @@ -92,12 +52,6 @@ let range i j yield = in if compare i j <= 0 then up i j yield else down i j yield -(*$= & ~printer:Q.Print.(list to_string) - [0l;1l;2l;3l;4l;5l] (range 0l 5l |> Iter.to_list) - [0l] (range 0l 0l |> Iter.to_list) - [5l;4l;3l;2l] (range 5l 2l |> Iter.to_list) -*) - let range' i j yield = if compare i j < 0 then range i (sub j 1l) yield else if equal i j then () @@ -116,29 +70,6 @@ let range_by ~step i j yield = else if (if compare step 0l > 0 then compare i j > 0 else compare i j < 0) then () else range i (add (mul (div (sub j i) step) step) i) yield -(* note: the last test checks that no error occurs due to overflows. *) -(*$= & ~printer:Q.Print.(list to_string) - [0l] (range_by ~step:1l 0l 0l |> Iter.to_list) - [] (range_by ~step:1l 5l 0l |> Iter.to_list) - [] (range_by ~step:2l 1l 0l |> Iter.to_list) - [0l;2l;4l] (range_by ~step:2l 0l 4l |> Iter.to_list) - [0l;2l;4l] (range_by ~step:2l 0l 5l |> Iter.to_list) - [0l] (range_by ~step:(neg 1l) 0l 0l |> Iter.to_list) - [] (range_by ~step:(neg 1l) 0l 5l |> Iter.to_list) - [] (range_by ~step:(neg 2l) 0l 1l |> Iter.to_list) - [5l;3l;1l] (range_by ~step:(neg 2l) 5l 1l |> Iter.to_list) - [5l;3l;1l] (range_by ~step:(neg 2l) 5l 0l |> Iter.to_list) - [0l] (range_by ~step:max_int 0l 2l |> Iter.to_list) -*) - -(*$Q - Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \ - let i = min i j and j = max i j in \ - CCList.equal CCInt32.equal \ - (CCInt32.range_by ~step:1l i j |> Iter.to_list) \ - (CCInt32.range i j |> Iter.to_list) ) -*) - let random n st = Random.State.int32 st n let random_small = random 100l let random_range i j st = add i (random (sub j i) st) @@ -181,12 +112,6 @@ let to_string_binary n = to_binary_gen (Buffer.add_char buf) n; Buffer.contents buf -(*$= & ~printer:CCFun.id - "0b111" (to_string_binary 7l) - "-0b111" (to_string_binary (-7l)) - "0b0" (to_string_binary 0l) -*) - (** {2 Printing} *) let pp out n = Format.pp_print_string out (to_string n) diff --git a/src/core/CCInt64.ml b/src/core/CCInt64.ml index ab290798..1bbd1473 100644 --- a/src/core/CCInt64.ml +++ b/src/core/CCInt64.ml @@ -24,14 +24,6 @@ let pow a b = | b when compare b 0L < 0 -> raise (Invalid_argument "pow: can't raise int to negative power") | b -> aux a b -(*$T - pow 2L 10L = 1024L - pow 2L 15L = 32768L - pow 10L 5L = 100000L - pow 42L 0L = 1L - pow 0L 1L = 0L -*) - let floor_div a n = if compare a 0L < 0 && compare n 0L >= 0 then sub (div (add a 1L) n) 1L @@ -40,38 +32,6 @@ let floor_div a n = else div a n -(*$T - (floor_div 3L 5L = 0L) - (floor_div 5L 5L = 1L) - (floor_div 20L 5L = 4L) - (floor_div 12L 5L = 2L) - (floor_div 0L 5L = 0L) - (floor_div (-1L) 5L = -1L) - (floor_div (-5L) 5L = -1L) - (floor_div (-12L) 5L = -3L) - - (floor_div 0L (-5L) = 0L) - (floor_div 3L (-5L) = -1L) - (floor_div 5L (-5L) = -1L) - (floor_div 9L (-5L) = -2L) - (floor_div 20L (-5L) = -4L) - (floor_div (-2L) (-5L) = 0L) - (floor_div (-8L) (-5L) = 1L) - (floor_div (-35L) (-5L) = 7L) - - try ignore (floor_div 12L 0L); false with Division_by_zero -> true - try ignore (floor_div (-12L) 0L); false with Division_by_zero -> true -*) - -(*$Q - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1L in \ - floor_div n m = of_float @@ floor (to_float n /. to_float m)) - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1L in \ - floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m))) -*) - type 'a printer = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a type 'a iter = ('a -> unit) -> unit @@ -92,12 +52,6 @@ let range i j yield = in if compare i j <= 0 then up i j yield else down i j yield -(*$= & ~printer:Q.Print.(list to_string) - [0L;1L;2L;3L;4L;5L] (range 0L 5L |> Iter.to_list) - [0L] (range 0L 0L |> Iter.to_list) - [5L;4L;3L;2L] (range 5L 2L |> Iter.to_list) -*) - let range' i j yield = if compare i j < 0 then range i (sub j 1L) yield else if equal i j then () @@ -116,29 +70,6 @@ let range_by ~step i j yield = else if (if compare step 0L > 0 then compare i j > 0 else compare i j < 0) then () else range i (add (mul (div (sub j i) step) step) i) yield -(* note: the last test checks that no error occurs due to overflows. *) -(*$= & ~printer:Q.Print.(list to_string) - [0L] (range_by ~step:1L 0L 0L |> Iter.to_list) - [] (range_by ~step:1L 5L 0L |> Iter.to_list) - [] (range_by ~step:2L 1L 0L |> Iter.to_list) - [0L;2L;4L] (range_by ~step:2L 0L 4L |> Iter.to_list) - [0L;2L;4L] (range_by ~step:2L 0L 5L |> Iter.to_list) - [0L] (range_by ~step:(neg 1L) 0L 0L |> Iter.to_list) - [] (range_by ~step:(neg 1L) 0L 5L |> Iter.to_list) - [] (range_by ~step:(neg 2L) 0L 1L |> Iter.to_list) - [5L;3L;1L] (range_by ~step:(neg 2L) 5L 1L |> Iter.to_list) - [5L;3L;1L] (range_by ~step:(neg 2L) 5L 0L |> Iter.to_list) - [0L] (range_by ~step:max_int 0L 2L |> Iter.to_list) -*) - -(*$Q - Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \ - let i = min i j and j = max i j in \ - CCList.equal CCInt64.equal \ - (CCInt64.range_by ~step:1L i j |> Iter.to_list) \ - (CCInt64.range i j |> Iter.to_list) ) -*) - let random n st = Random.State.int64 st n let random_small = random 100L let random_range i j st = add i (random (sub j i) st) @@ -181,12 +112,6 @@ let to_string_binary n = to_binary_gen (Buffer.add_char buf) n; Buffer.contents buf -(*$= & ~printer:CCFun.id - "0b111" (to_string_binary 7L) - "-0b111" (to_string_binary (-7L)) - "0b0" (to_string_binary 0L) -*) - (** {2 Printing} *) let pp out n = Format.pp_print_string out (to_string n) diff --git a/src/core/CCMap.ml b/src/core/CCMap.ml index 0ffdc293..228d7dc2 100644 --- a/src/core/CCMap.ml +++ b/src/core/CCMap.ml @@ -162,10 +162,6 @@ module type S = sig contents of the map. *) end -(*$inject - module M = CCMap.Make(String) -*) - module Make(O : Map.OrderedType) = struct module M = Map.Make(O) @@ -238,15 +234,6 @@ module Make(O : Map.OrderedType) = struct | None -> raise Not_found | Some (k,v) -> k, v - (*$= & ~printer:CCFormat.(to_string @@ Dump.(list (pair string int))) - ["a", 1; "b", 20] \ - (M.of_list ["b", 2; "c", 3] \ - |> M.update "a" (function _ -> Some 1) \ - |> M.update "c" (fun _ -> None) \ - |> M.update "b" (CCOption.map (fun x -> x * 10)) \ - |> M.to_list |> List.sort CCOrd.compare) - *) - (* === include M. This will shadow some values depending on OCaml's current version === *) @@ -333,18 +320,3 @@ module Make(O : Map.OrderedType) = struct m; pp_stop fmt () end - -(*$inject - module M2 = Make(CCInt) -*) - -(*$Q - Q.(list (pair small_int small_int)) M2.(fun l -> \ - to_list (of_list l) = to_list (of_list_with ~f:(fun _ v _ ->v) l)) - Q.(list (pair small_int small_int)) M2.(fun l -> \ - to_list (of_iter @@ Iter.of_list l) = \ - to_list (of_iter_with ~f:(fun _ v _ ->v) @@ Iter.of_list l)) - Q.(list (pair small_int small_int)) M2.(fun l -> \ - to_list (of_seq @@ CCSeq.of_list l) = \ - to_list (of_seq_with ~f:(fun _ v _ ->v) @@ CCSeq.of_list l)) -*) diff --git a/src/core/CCNativeint.ml b/src/core/CCNativeint.ml index 030bb811..1ca041dd 100644 --- a/src/core/CCNativeint.ml +++ b/src/core/CCNativeint.ml @@ -24,14 +24,6 @@ let pow a b = | b when compare b 0n < 0 -> raise (Invalid_argument "pow: can't raise int to negative power") | b -> aux a b -(*$T - pow 2n 10n = 1024n - pow 2n 15n = 32768n - pow 10n 5n = 100000n - pow 42n 0n = 1n - pow 0n 1n = 0n -*) - let floor_div a n = if compare a 0n < 0 && compare n 0n >= 0 then sub (div (add a 1n) n) 1n @@ -40,38 +32,6 @@ let floor_div a n = else div a n -(*$T - (floor_div 3n 5n = 0n) - (floor_div 5n 5n = 1n) - (floor_div 20n 5n = 4n) - (floor_div 12n 5n = 2n) - (floor_div 0n 5n = 0n) - (floor_div (-1n) 5n = -1n) - (floor_div (-5n) 5n = -1n) - (floor_div (-12n) 5n = -3n) - - (floor_div 0n (-5n) = 0n) - (floor_div 3n (-5n) = -1n) - (floor_div 5n (-5n) = -1n) - (floor_div 9n (-5n) = -2n) - (floor_div 20n (-5n) = -4n) - (floor_div (-2n) (-5n) = 0n) - (floor_div (-8n) (-5n) = 1n) - (floor_div (-35n) (-5n) = 7n) - - try ignore (floor_div 12n 0n); false with Division_by_zero -> true - try ignore (floor_div (-12n) 0n); false with Division_by_zero -> true -*) - -(*$Q - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1n in \ - floor_div n m = of_float @@ floor (to_float n /. to_float m)) - (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \ - (fun (n, m) -> let m = m + 1n in \ - floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m))) -*) - type 'a printer = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a type 'a iter = ('a -> unit) -> unit @@ -92,12 +52,6 @@ let range i j yield = in if compare i j <= 0 then up i j yield else down i j yield -(*$= & ~printer:Q.Print.(list to_string) - [0n;1n;2n;3n;4n;5n] (range 0n 5n |> Iter.to_list) - [0n] (range 0n 0n |> Iter.to_list) - [5n;4n;3n;2n] (range 5n 2n |> Iter.to_list) -*) - let range' i j yield = if compare i j < 0 then range i (sub j 1n) yield else if equal i j then () @@ -116,29 +70,6 @@ let range_by ~step i j yield = else if (if compare step 0n > 0 then compare i j > 0 else compare i j < 0) then () else range i (add (mul (div (sub j i) step) step) i) yield -(* note: the last test checks that no error occurs due to overflows. *) -(*$= & ~printer:Q.Print.(list to_string) - [0n] (range_by ~step:1n 0n 0n |> Iter.to_list) - [] (range_by ~step:1n 5n 0n |> Iter.to_list) - [] (range_by ~step:2n 1n 0n |> Iter.to_list) - [0n;2n;4n] (range_by ~step:2n 0n 4n |> Iter.to_list) - [0n;2n;4n] (range_by ~step:2n 0n 5n |> Iter.to_list) - [0n] (range_by ~step:(neg 1n) 0n 0n |> Iter.to_list) - [] (range_by ~step:(neg 1n) 0n 5n |> Iter.to_list) - [] (range_by ~step:(neg 2n) 0n 1n |> Iter.to_list) - [5n;3n;1n] (range_by ~step:(neg 2n) 5n 1n |> Iter.to_list) - [5n;3n;1n] (range_by ~step:(neg 2n) 5n 0n |> Iter.to_list) - [0n] (range_by ~step:max_int 0n 2n |> Iter.to_list) -*) - -(*$Q - Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \ - let i = min i j and j = max i j in \ - CCList.equal CCNativeint.equal \ - (CCNativeint.range_by ~step:1n i j |> Iter.to_list) \ - (CCNativeint.range i j |> Iter.to_list) ) -*) - let random n st = Random.State.nativeint st n let random_small = random 100n let random_range i j st = add i (random (sub j i) st) @@ -181,12 +112,6 @@ let to_string_binary n = to_binary_gen (Buffer.add_char buf) n; Buffer.contents buf -(*$= & ~printer:CCFun.id - "0b111" (to_string_binary 7n) - "-0b111" (to_string_binary (-7n)) - "0b0" (to_string_binary 0n) -*) - (** {2 Printing} *) let pp out n = Format.pp_print_string out (to_string n) diff --git a/src/core/CCOption.ml b/src/core/CCOption.ml index 81a522ca..a0e9f9cc 100644 --- a/src/core/CCOption.ml +++ b/src/core/CCOption.ml @@ -76,12 +76,6 @@ let filter p = function | Some x as o when p x -> o | _ -> None -(*$= - None (filter ((=) 0) (Some 1)) - (Some 0) (filter ((=) 0) (Some 0)) - None (filter (fun _ -> true) None) -*) - let if_ p x = if p x then Some x else None let exists p = function @@ -116,11 +110,6 @@ let get_exn_or msg = function | Some x -> x | None -> invalid_arg msg -(*$T - (try get_exn_or "ohno" (None:unit option); false with Invalid_argument s->s= "ohno") - 123 = get_exn_or "yes" (Some 123) -*) - let get_lazy default_fn x = match x with | None -> default_fn () | Some y -> y @@ -133,12 +122,6 @@ let sequence_l l = in try aux [] l with Exit -> None -(*$T - sequence_l [None; Some 1; Some 2] = None - sequence_l [Some 1; Some 2; Some 3] = Some [1;2;3] - sequence_l [] = Some [] -*) - let wrap ?(handler=fun _ -> true) f x = try Some (f x) with e -> @@ -211,23 +194,11 @@ let choice_iter s = end; !r -(*$T - choice_iter (Iter.of_list [None; Some 1; Some 2]) = Some 1 - choice_iter Iter.empty = None - choice_iter (Iter.repeat None |> Iter.take 100) = None -*) - let rec choice_seq s = match s() with | Seq.Nil -> None | Seq.Cons (Some x, _) -> Some x | Seq.Cons (None, tl) -> choice_seq tl -(*$T - choice_seq (CCSeq.of_list [None; Some 1; Some 2]) = Some 1 - choice_seq CCSeq.empty = None - choice_seq (CCSeq.repeat None |> CCSeq.take 100) = None -*) - let to_gen o = match o with | None -> (fun () -> None) @@ -251,19 +222,8 @@ let flatten = function | Some x -> x | None -> None -(*$T - flatten None = None - flatten (Some None) = None - flatten (Some (Some 1)) = Some 1 -*) - let return_if b x = if b then Some x else None - -(*$T - return_if false 1 = None - return_if true 1 = Some 1 -*) diff --git a/src/core/CCOrd.ml b/src/core/CCOrd.ml index 9a6b8513..c2c13bd8 100644 --- a/src/core/CCOrd.ml +++ b/src/core/CCOrd.ml @@ -18,35 +18,11 @@ let equiv i j = else if i>0 then j>0 else j=0 -(*$T - equiv 1 2 - equiv ~-1 ~-10 - equiv 0 0 - equiv ~-1 ~-1 - not (equiv 0 1) - not (equiv 1 ~-1) - not (equiv 1 0) -*) - -(*$Q - Q.(pair int int) (fun (x,y) -> \ - (equiv x y) = (equiv y x)) - Q.(triple int int int) (fun (x,y,z) -> \ - if (equiv x y && equiv y z) then (equiv x z) else true) -*) - let int (x:int) y = Stdlib.compare x y let string (x:string) y = Stdlib.compare x y let bool (x:bool) y = Stdlib.compare x y let float (x:float) y = Stdlib.compare x y -(*$T - bool true false > 0 - bool false true < 0 - bool true true = 0 - bool false false = 0 -*) - (** {2 Lexicographic Combination} *) let () c (ord,x,y) = @@ -60,22 +36,12 @@ let option c o1 o2 = match o1, o2 with | Some _, None -> 1 | Some x1, Some x2 -> c x1 x2 -(*$Q - Q.(option int) (fun o -> option int None o <= 0) -*) - let pair o_x o_y (x1,y1) (x2,y2) = let c = o_x x1 x2 in if c = 0 then o_y y1 y2 else c -(*$T - pair int string (1, "b") (2, "a") < 0 - pair int string (1, "b") (0, "a") > 0 - pair int string (1, "b") (1, "b") = 0 -*) - let triple o_x o_y o_z (x1,y1,z1) (x2,y2,z2) = let c = o_x x1 x2 in if c = 0 @@ -96,17 +62,6 @@ let rec list ord l1 l2 = match l1, l2 with then list ord l1' l2' else c -(*$T - list int [1;2;3] [1;2;3;4] < 0 - list int [1;2;3;4] [1;2;3] > 0 - list int [1;2;3;4] [1;3;4] < 0 -*) - -(*$Q - Q.(pair (list int)(list int)) CCOrd.(fun (l1,l2) -> \ - equiv (list int l1 l2) (Stdlib.compare l1 l2)) -*) - let array ord a1 a2 = let rec aux i = if i = Array.length a1 @@ -121,17 +76,6 @@ let array ord a1 a2 = in aux 0 -(*$T - array int [|1;2;3|] [|1;2;3;4|] < 0 - array int [|1;2;3;4|] [|1;2;3|] > 0 - array int [|1;2;3;4|] [|1;3;4|] < 0 -*) - -(*$Q & ~small:(fun (a1, a2) -> Array.length a1+Array.length a2) - Q.(pair (array int)(array int)) CCOrd.(fun (a1,a2) -> \ - equiv (array int a1 a2) (list int (Array.to_list a1) (Array.to_list a2))) -*) - let map f ord a b = ord (f a) (f b) let (>|=) x f = map f x diff --git a/src/core/CCParse.ml b/src/core/CCParse.ml index 26e7eafa..72587d33 100644 --- a/src/core/CCParse.ml +++ b/src/core/CCParse.ml @@ -4,108 +4,6 @@ open CCShims_ -(*$inject - module T = struct - type tree = L of int | N of tree * tree - end - open T - - let mk_leaf x = L x - let mk_node x y = N(x,y) - - let ptree = fix @@ fun self -> - skip_space *> - ( (char '(' *> (pure mk_node <*> self <*> self) <* char ')') - <|> - (U.int >|= mk_leaf) ) - - let ptree' = fix_memo @@ fun self -> - skip_space *> - ( (char '(' *> (pure mk_node <*> self <*> self) <* char ')') - <|> - (U.int >|= mk_leaf) ) - - let rec pptree = function - | N (a,b) -> Printf.sprintf "N (%s, %s)" (pptree a) (pptree b) - | L x -> Printf.sprintf "L %d" x - - let errpp pp = function - | Ok x -> "Ok " ^ pp x - | Error s -> "Error " ^ s - - let errpptree = errpp pptree - - let erreq eq x y = match x, y with - | Ok x, Ok y -> eq x y - | Error _ , Error _ -> true - | _ -> false ;; -*) - -(*$= & ~printer:errpptree - (Ok (N (L 1, N (L 2, L 3)))) \ - (parse_string ptree "(1 (2 3))" ) - (Ok (N (N (L 1, L 2), N (L 3, N (L 4, L 5))))) \ - (parse_string ptree "((1 2) (3 (4 5)))" ) - (Ok (N (L 1, N (L 2, L 3)))) \ - (parse_string ptree' "(1 (2 3))" ) - (Ok (N (N (L 1, L 2), N (L 3, N (L 4, L 5))))) \ - (parse_string ptree' "((1 2) (3 (4 5)))" ) -*) - -(*$R - let p = U.list ~sep:"," U.word in - let printer = function - | Ok l -> "Ok " ^ CCFormat.(to_string (Dump.list string_quoted)) l - | Error s -> "Error " ^ s - in - assert_equal ~printer - (Ok ["abc"; "de"; "hello"; "world"]) - (parse_string p "[abc , de, hello ,world ]"); -*) - -(*$R - let test n = - let p = CCParse.(U.list ~sep:"," U.int) in - - let l = CCList.(1 -- n) in - let l_printed = - CCFormat.(to_string (within "[" "]" (list ~sep:(return ",") int))) l in - - let l' = CCParse.parse_string_exn p l_printed in - - assert_equal ~printer:Q.Print.(list int) l l' - in - test 300_000; - -*) - -(*$R - let open CCParse.Infix in - let module P = CCParse in - - let parens p = P.char '(' *> p <* P.char ')' in - let add = P.char '+' *> P.return (+) in - let sub = P.char '-' *> P.return (-) in - let mul = P.char '*' *> P.return ( * ) in - let div = P.char '/' *> P.return ( / ) in - let integer = - P.chars1_if (function '0'..'9'->true|_->false) >|= int_of_string in - - let chainr1 e op = - P.fix (fun r -> - e >>= fun x -> (op <*> P.return x <*> r) <|> P.return x) in - - let expr : int P.t = - P.fix (fun expr -> - let factor = parens expr <|> integer in - let term = chainr1 factor (mul <|> div) in - chainr1 term (add <|> sub)) in - - assert_equal (Ok 6) (P.parse_string expr "4*1+2"); - assert_equal (Ok 12) (P.parse_string expr "4*(1+2)"); - () -*) - module Memo_tbl = Hashtbl.Make(struct type t = int * int (* id of parser, position *) let equal ((a,b):t)(c,d) = a=c && b=d @@ -381,12 +279,6 @@ let eoi = { else err (mk_error_ st (const_str_ "expected end of input")) } -(*$= & ~printer:(errpp Q.Print.bool) ~cmp:(erreq (=)) - (Ok true) (parse_string (U.bool <* eoi) "true") - (Error "") (parse_string (U.bool <* eoi) "true ") - (Ok true) (parse_string (U.bool <* skip_white <* eoi) "true") -*) - let with_pos p : _ t = { run=fun st ~ok ~err -> p.run st @@ -399,21 +291,6 @@ let pos : _ t = { run=fun st ~ok ~err:_ -> ok st (pos_of_st_ st) } -(*$= & ~printer:Q.Print.(pair int int) - (0,5) (let p = any_char_n 5 *> pos in \ - match parse_string p "abcde " with \ - | Ok p -> Position.line_and_column p \ - | Error _ -> assert false) -*) - -(*$= & ~printer:Q.Print.(list @@ pair int int) - [(0,2); (1,3); (2,1); (3,0); (4,0); (5,2)] \ - (let p = each_line (skip_space *> pos) in \ - match parse_string p " a\n b\nc\n\n\n a" with \ - | Ok ps -> List.map Position.line_and_column ps \ - | Error _ -> assert false) -*) - (* a slice is just a state, which makes {!recurse} quite easy. *) type slice = state @@ -443,16 +320,6 @@ let all = { let all_str = all >|= Slice.to_string -(*$= & ~printer:(errpp Q.Print.string) ~cmp:(erreq (=)) - (Ok "abcd") (parse_string all_str "abcd") - (Ok "cd") (parse_string (string "ab" *> all_str) "abcd") - (Ok "") (parse_string (string "ab" *> all_str) "ab") -*) - -(*$= & ~printer:(errpp Q.Print.(pair string string)) ~cmp:(erreq (=)) - (Ok ("foobar", "")) (parse_string (both all_str all_str) "foobar") - *) - let fail msg : _ t = { run=fun st ~ok:_ ~err -> err (mk_error_ st (const_str_ msg)) @@ -559,19 +426,6 @@ let chars1_if ?descr p = { ~err } -(*$QR - Q.(printable_string) (fun s -> - let pred = (function 'a'..'z' | 'A' .. 'Z' | '{' | '}' -> true | _ -> false) in - let p1 = chars1_if pred in - let p2 = take1_if pred >|= Slice.to_string in - parse_string p1 s = parse_string p2 s) - *) - -(*$T - let pred = (function 'a'..'z' | 'A' .. 'Z' | '{' | '}' -> true | _ -> false) in \ - parse_string (chars_if pred) "coucou{lol} 123" = Ok "coucou{lol}" -*) - exception Fold_fail of state * string let chars_fold ~f acc0 = { @@ -787,16 +641,6 @@ let many p : _ t = { } *) -(*$R - let p0 = skip_white *> U.int in - let p = (skip_white *> char '(' *> many p0) <* (skip_white <* char ')') in - let printer = CCFormat.(to_string @@ Dump.result @@ Dump.list int) in - assert_equal ~printer - (Ok [1;2;3]) (parse_string p "(1 2 3)"); - assert_equal ~printer - (Ok [1;2; -30; 4]) (parse_string p "( 1 2 -30 4 )") - *) - let many1 p = p >>= fun x -> @@ -836,16 +680,6 @@ let sep ~by p = ) in Lazy.force read_p -(*$inject - let aword = chars1_if (function 'a'..'z'|'A'..'Z'->true|_ -> false);; -*) -(*$= & ~printer:(errpp Q.Print.(list string)) -(Ok ["a";"b";"c"]) \ - (parse_string (optional (char '/') *> sep ~by:(char '/') aword) "/a/b/c") -(Ok ["a";"b";"c"]) \ - (parse_string (optional (char '/') *> sep ~by:(char '/') aword) "a/b/c") -*) - let sep1 ~by p = p >>= fun x -> sep ~by p >|= fun tl -> @@ -871,18 +705,6 @@ let set_current_slice sl : _ t = { ok sl () (* jump to slice *) } -(*$= & ~printer:(errpp Q.Print.(string)) - (Ok "abc") (parse_string (lookahead (string "ab") *> (string "abc")) "abcd") -*) - -(*$= & ~printer:(errpp Q.Print.(string)) - (Ok "1234") (parse_string line_str "1234\nyolo") - *) - -(*$= & ~printer:(errpp Q.Print.(pair String.escaped String.escaped)) - (Ok ("1234", "yolo")) (parse_string (line_str ||| line_str) "1234\nyolo\nswag") -*) - let split_1 ~on_char : _ t = { run=fun st ~ok ~err:_ -> if st.i >= st.j then ( @@ -922,13 +744,6 @@ let split_list_at_most ~on_char n : slice list t = in loop [] n -(*$= & ~printer:(errpp Q.Print.(list string)) ~cmp:(erreq (=)) - (Ok ["a";"b";"c";"d,e,f"]) \ - (parse_string (split_list_at_most ~on_char:',' 3 >|= List.map Slice.to_string) "a,b,c,d,e,f") - (Ok ["a";"bc"]) \ - (parse_string (split_list_at_most ~on_char:',' 3 >|= List.map Slice.to_string) "a,bc") -*) - let split_list ~on_char : _ t = split_list_at_most ~on_char max_int @@ -986,11 +801,6 @@ let line_str = line >|= Slice.to_string let each_line p : _ t = each_split ~on_char:'\n' p -(*$= & ~printer:(errpp Q.Print.(list @@ list int)) - (Ok ([[1;1];[2;2];[3;3];[]])) \ - (parse_string (each_line (sep ~by:skip_space U.int)) "1 1\n2 2\n3 3\n") -*) - let memo (type a) (p:a t) : a t = let id = !Memo_state.id_ in incr Memo_state.id_; @@ -1094,13 +904,6 @@ module U = struct try return (int_of_string s) with Failure _ -> fail "expected an int" - (*$= & ~printer:(errpp Q.Print.int) ~cmp:(erreq (=)) - (Ok 42) (parse_string U.int " 42") - (Ok 2) (parse_string U.int "2") - (Error "") (parse_string U.int "abc") - (Error "") (parse_string U.int "") - *) - let in_paren (p:'a t) : 'a t = skip_white *> (char '(' *> skip_white *> p <* skip_white <* char ')') @@ -1113,16 +916,6 @@ module U = struct ~f:(fun _ -> skip_white *> self <* skip_white <* char ')') ~else_:p) - (*$= & ~printer:(errpp Q.Print.int) ~cmp:(erreq (=)) - (Ok 15) (parse_string (U.in_paren (U.in_paren U.int)) "( ( 15) )") - (Ok 2) (parse_string (U.in_paren U.int) "(2)") - (Error "") (parse_string (U.in_paren U.int) "2") - (Error "") (parse_string (U.in_paren U.int) "") - (Ok 2) (parse_string (U.in_parens_opt U.int) "((((2))))") - (Ok 2) (parse_string (U.in_parens_opt U.int) "2") - (Ok 200) (parse_string (U.in_parens_opt U.int) "( ( 200 ) )") - *) - let option p = skip_white *> try_or @@ -1130,13 +923,6 @@ module U = struct ~f:(fun _ -> skip_white *> p >|= fun x -> Some x) ~else_:(string "None" *> return None) - (*$= & ~printer:(errpp Q.Print.(option int)) ~cmp:(erreq (=)) - (Ok (Some 12)) (parse_string U.(option int) " Some 12") - (Ok None) (parse_string U.(option int) " None") - (Ok (Some 0)) (parse_string U.(option int) "Some 0") - (Ok (Some 0)) (parse_string U.(in_parens_opt @@ option int) "(( Some 0) )") - *) - let hexa_int = (exact "0x" <|> return "") *> begin @@ -1156,13 +942,6 @@ module U = struct !i end - (*$= & ~printer:(errpp Q.Print.int) ~cmp:(erreq (=)) - (Ok 16) (parse_string U.hexa_int "0x10") - (Ok 16) (parse_string U.hexa_int "10") - (Error "") (parse_string U.hexa_int "x10") - (Error "") (parse_string U.hexa_int "0xz") - *) - let prepend_str c s = String.make 1 c ^ s let word = @@ -1171,10 +950,6 @@ module U = struct let bool = skip_white *> ((string "true" *> return true) <|> (string "false" *> return false)) - (*$= & ~printer:(errpp Q.Print.bool) ~cmp:(erreq (=)) - (Ok true) (parse_string U.bool "true") - (Ok false) (parse_string U.bool "false") - *) let pair ?(start="(") ?(stop=")") ?(sep=",") p1 p2 = skip_white *> string start *> skip_white *> @@ -1183,10 +958,6 @@ module U = struct p2 >>= fun x2 -> skip_white *> string stop *> return (x1,x2) - (*$= & ~printer:Q.Print.(errpp (pair int int)) - (Ok(1,2)) U.(parse_string (pair int int) "(1 , 2 )") - *) - let triple ?(start="(") ?(stop=")") ?(sep=",") p1 p2 p3 = string start *> skip_white *> p1 >>= fun x1 -> diff --git a/src/core/CCRandom.ml b/src/core/CCRandom.ml index c1567b65..2618f8fd 100644 --- a/src/core/CCRandom.ml +++ b/src/core/CCRandom.ml @@ -47,11 +47,6 @@ let pick_list l = fun st -> List.nth l (Random.State.int st n) -(*$Q - Q.(list small_int) (fun l -> \ - l=[] || List.mem (run (pick_list l)) l) -*) - let pick_array a = let n = Array.length a in if n=0 then raise Pick_from_empty; @@ -123,13 +118,6 @@ let split_list i ~len st = ) else None -(*$Q - Q.(pair small_int small_int) (fun (i,j) -> \ - let len, n = 2+min i j, max i j in \ - let l = QCheck.Gen.generate1 (split_list n ~len) in \ - match l with None -> true | Some l -> l<> [] && List.for_all (fun x->x>0) l) -*) - let retry ?(max=10) g st = let rec aux n = match g st with @@ -208,8 +196,3 @@ let (and*) = (and+) let __default_state = Random.State.make_self_init () let run ?(st=__default_state) g = g st - -(*$R - let open Containers in - ignore @@ List.random_choose [1;2;3] (Random.get_state()) -*) diff --git a/src/core/CCResult.ml b/src/core/CCResult.ml index 469c143a..12a35e7a 100644 --- a/src/core/CCResult.ml +++ b/src/core/CCResult.ml @@ -27,10 +27,6 @@ let fail_printf format = (fun buf -> fail (Buffer.contents buf)) buf format -(*$T - (Error "ohno 42") = (fail_printf "ohno %d" 42) -*) - let fail_fprintf format = let buf = Buffer.create 64 in let out = Format.formatter_of_buffer buf in @@ -38,10 +34,6 @@ let fail_fprintf format = (fun out -> Format.pp_print_flush out (); fail (Buffer.contents buf)) out format -(*$T - (Error "ohno 42") = (fail_fprintf "ohno %d" 42) -*) - let add_ctx msg x = match x with | Error e -> Error (e ^ "\ncontext:" ^ msg) | Ok x -> Ok x @@ -53,11 +45,6 @@ let add_ctxf msg = (fun out e -> Format.pp_print_flush out (); add_ctx (Buffer.contents buf) e) out msg -(*$= - (Error "error\ncontext:message(number 42, foo: true)") \ - (add_ctxf "message(number %d, foo: %B)" 42 true (Error "error")) -*) - let of_exn e = let msg = Printexc.to_string e in Error msg @@ -96,15 +83,6 @@ let iter_err f e = match e with | Ok _ -> () | Error err -> f err -(*$R iter_err - let called_with = ref None in - let f e = called_with := Some e in - iter_err f (Ok 1); - assert_bool "should not apply when Ok" (!called_with = None); - iter_err f (Error 1); - assert_bool "should apply f to Error" (!called_with = Some 1) -*) - exception Get_error let get_exn = function @@ -123,20 +101,10 @@ let get_or_failwith = function | Ok x -> x | Error msg -> failwith msg -(*$T - get_or_failwith (Ok 1) = 1 - try ignore @@ get_or_failwith (Error "e"); false with Failure msg -> msg = "e" -*) - let get_lazy default_fn x = match x with | Ok x -> x | Error e -> default_fn e -(*$= get_lazy - (get_lazy (fun _ -> 2) (Ok 1)) (1) - (get_lazy (fun _ -> 2) (Error "error")) (2) -*) - let map_or f e ~default = match e with | Ok x -> f x | Error _ -> default @@ -168,11 +136,6 @@ let fold_ok f acc r = match r with | Ok x -> f acc x | Error _ -> acc -(*$= - 42 (fold_ok (+) 2 (Ok 40)) - 40 (fold_ok (+) 40 (Error "foo")) -*) - let is_ok = function | Ok _ -> true | Error _ -> false @@ -243,12 +206,6 @@ let flatten_l l = | Error e::_ -> Error e in loop [] l -(*$= - (Ok []) (flatten_l []) - (Ok [1;2;3]) (flatten_l [Ok 1; Ok 2; Ok 3]) - (Error "ohno") (flatten_l [Ok 1; Error "ohno"; Ok 2; Ok 3; Error "wut"]) -*) - exception LocalExit let fold_iter f acc seq = diff --git a/src/core/CCSeq.ml b/src/core/CCSeq.ml index b911caeb..1a9e68d6 100644 --- a/src/core/CCSeq.ml +++ b/src/core/CCSeq.ml @@ -27,12 +27,6 @@ let repeat ?n x = match n with | None -> _forever x | Some n -> _repeat n x -(*$T - repeat ~n:4 0 |> to_list = [0;0;0;0] - repeat ~n:0 1 |> to_list = [] - repeat 1 |> take 20 |> to_list = (repeat ~n:20 1 |> to_list) -*) - let is_empty l = match l () with | Nil -> true | Cons _ -> false @@ -89,10 +83,6 @@ let rec take_while p l () = match l () with | Cons (x,l') -> if p x then Cons (x, take_while p l') else Nil -(*$T - of_list [1;2;3;4] |> take_while (fun x->x < 4) |> to_list = [1;2;3] -*) - let rec drop n (l:'a t) () = match l () with | l' when n=0 -> l' | Nil -> Nil @@ -103,20 +93,10 @@ let rec drop_while p l () = match l() with | Cons (x,l') when p x -> drop_while p l' () | Cons _ as res -> res -(*$Q - (Q.pair (Q.list Q.small_int) Q.small_int) (fun (l,n) -> \ - let s = of_list l in let s1, s2 = take n s, drop n s in \ - append s1 s2 |> to_list = l ) -*) - let rec map f l () = match l () with | Nil -> Nil | Cons (x, l') -> Cons (f x, map f l') -(*$T - (map ((+) 1) (1 -- 5) |> to_list) = (2 -- 6 |> to_list) -*) - let mapi f l = let rec aux f l i () = match l() with | Nil -> Nil @@ -125,10 +105,6 @@ let mapi f l = in aux f l 0 -(*$T - mapi (fun i x -> i,x) (1 -- 3) |> to_list = [0, 1; 1, 2; 2, 3] -*) - let rec fmap f (l:'a t) () = match l() with | Nil -> Nil | Cons (x, l') -> @@ -137,11 +113,6 @@ let rec fmap f (l:'a t) () = match l() with | Some y -> Cons (y, fmap f l') end -(*$T - fmap (fun x -> if x mod 2=0 then Some (x*3) else None) (1--10) |> to_list \ - = [6;12;18;24;30] -*) - let rec filter p l () = match l () with | Nil -> Nil | Cons (x, l') -> @@ -155,54 +126,20 @@ let rec append l1 l2 () = match l1 () with let rec cycle l () = append l (cycle l) () -(*$T - cycle (of_list [1;2]) |> take 5 |> to_list = [1;2;1;2;1] - cycle (of_list [1; ~-1]) |> take 100_000 |> fold (+) 0 = 0 -*) - let rec unfold f acc () = match f acc with | None -> Nil | Some (x, acc') -> Cons (x, unfold f acc') -(*$T - let f = function 10 -> None | x -> Some (x, x+1) in \ - unfold f 0 |> to_list = [0;1;2;3;4;5;6;7;8;9] -*) - let rec for_all p l = match l () with | Nil -> true | Cons (x, tl) -> p x && for_all p tl -(*$T - for_all ((=) 1) (of_list []) = true - for_all ((=) 1) (of_list [0]) = false - for_all ((=) 1) (of_list [1]) = true - for_all ((=) 1) (of_list [1; 0]) = false - for_all ((=) 1) (of_list [0; 1]) = false - for_all ((=) 1) (of_list [1; 1]) = true - - let l () = Cons (0, fun () -> failwith "no second element") in \ - try ignore (for_all ((=) 1) l); true with Failure _ -> false -*) - let rec exists p l = match l () with | Nil -> false | Cons (x, tl) -> p x || exists p tl -(*$T - exists ((=) 1) (of_list []) = false - exists ((=) 1) (of_list [0]) = false - exists ((=) 1) (of_list [1]) = true - exists ((=) 1) (of_list [1; 0]) = true - exists ((=) 1) (of_list [0; 1]) = true - exists ((=) 1) (of_list [0; 0]) = false - - let l () = Cons (1, fun () -> failwith "no second element") in \ - try ignore (exists ((=) 1) l); true with Failure _ -> false -*) - let rec flat_map f l () = match l () with | Nil -> Nil | Cons (x, l') -> @@ -245,11 +182,6 @@ let rec group eq l () = match l() with | Cons (x, l') -> Cons (cons x (take_while (eq x) l'), group eq (drop_while (eq x) l')) -(*$T - of_list [1;1;1;2;2;3;3;1] |> group (=) |> map to_list |> to_list = \ - [[1;1;1]; [2;2]; [3;3]; [1]] -*) - let rec _uniq eq prev l () = match prev, l() with | _, Nil -> Nil | None, Cons (x, l') -> @@ -278,12 +210,6 @@ let range i j = else Cons (i, aux (i-1) j) in aux i j -(*$T - range 0 5 |> to_list = [0;1;2;3;4;5] - range 0 0 |> to_list = [0] - range 5 2 |> to_list = [5;4;3;2] -*) - let (--) = range let (--^) i j = @@ -291,13 +217,6 @@ let (--^) i j = else if i to_list = [1;2;3;4] - 5 --^ 1 |> to_list = [5;4;3;2] - 1 --^ 2 |> to_list = [1] - 0 --^ 0 |> to_list = [] -*) - let rec fold2 f acc l1 l2 = match l1(), l2() with | Nil, _ | _, Nil -> acc @@ -351,11 +270,6 @@ let unzip l = in first l, second l -(*$Q - Q.(list (pair int int)) (fun l -> \ - let l = of_list l in let a, b = unzip l in equal (=) l (zip a b)) -*) - let zip_i seq = let rec loop i seq () = match seq() with | Nil -> Nil @@ -363,10 +277,6 @@ let zip_i seq = in loop 0 seq -(*$= - [0,'a'; 1, 'b'; 2, 'c'] (of_string "abcde" |> zip_i |> take 3 |> to_list) -*) - (** {2 Implementations} *) let return x () = Cons (x, nil) @@ -428,18 +338,6 @@ let to_array l = ignore (List.fold_left (fun i x -> a.(i) <- x; i - 1) idx rest : int); a -(*$Q - Q.(array int) (fun a -> of_array a |> to_array = a) -*) - -(*$T - of_array [| 1; 2; 3 |] |> to_list = [1;2;3] - of_list [1;2;3] |> to_array = [| 1; 2; 3; |] - let r = ref 1 in \ - let s = unfold (fun i -> if i < 3 then let x = !r in incr r; Some (x, succ i) else None) 0 in \ - to_array s = [| 1; 2; 3; |] -*) - let rec to_iter res k = match res () with | Nil -> () | Cons (s, f) -> k s; to_iter f k @@ -474,14 +372,6 @@ let of_gen g = in consume (ref (Of_gen_thunk g)) -(*$R - let g = let n = ref 0 in fun () -> Some (incr n; !n) in - let l = of_gen g in - assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list); - assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list); - assert_equal [11;12] (drop 10 l |> take 2 |> to_list); -*) - let sort ~cmp l = let l = to_list l in of_list (List.sort cmp l) @@ -506,20 +396,6 @@ let rec memoize f = r := MemoSave l; l -(*$R - let printer = Q.Print.(list int) in - let gen () = - let rec l = let r = ref 0 in fun () -> incr r; Cons (!r, l) in l - in - let l1 = gen () in - assert_equal ~printer [1;2;3;4] (take 4 l1 |> to_list); - assert_equal ~printer [5;6;7;8] (take 4 l1 |> to_list); - let l2 = gen () |> memoize in - assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); - assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); -*) - - (** {2 Fair Combinations} *) let rec interleave a b () = match a() with @@ -540,12 +416,6 @@ let rec fair_app f a () = match f() with let (>>-) a f = fair_flat_map f a let (<.>) f a = fair_app f a -(*$T - interleave (of_list [1;3;5]) (of_list [2;4;6]) |> to_list = [1;2;3;4;5;6] - fair_app (of_list [(+)1; ( * ) 3]) (of_list [1; 10]) \ - |> to_list |> List.sort Stdlib.compare = [2; 3; 11; 30] -*) - (** {2 Infix} *) module Infix = struct diff --git a/src/core/CCSet.ml b/src/core/CCSet.ml index 16f17ea1..47e18616 100644 --- a/src/core/CCSet.ml +++ b/src/core/CCSet.ml @@ -8,13 +8,6 @@ type 'a printer = Format.formatter -> 'a -> unit module type OrderedType = Set.OrderedType -(*$inject - module S = CCSet.Make(struct - type t = int - let compare x y = Stdlib.compare x y - end) -*) - module type S = sig include Set.S @@ -165,22 +158,6 @@ module Make(O : Map.OrderedType) = struct to_list h |> CCList.to_string ~start ~stop ~sep elt_to_string - (*$= & ~printer:(fun s -> s) - (S.to_string string_of_int (S.of_list [4; 3])) "3,4" - *) - (*$Q - Q.(list int) (fun l -> \ - let s = S.of_list l in \ - (S.to_string string_of_int s) \ - = (CCList.sort_uniq ~cmp:CCInt.compare l \ - |> List.map string_of_int |> String.concat ",")) - Q.(list int) (fun l -> \ - let s = S.of_list l in \ - (S.to_string ~sep:" " string_of_int s) \ - = (CCList.sort_uniq ~cmp:CCInt.compare l \ - |> List.map string_of_int |> String.concat " ")) - *) - let pp ?(pp_start=fun _ () -> ()) ?(pp_stop=fun _ () -> ()) ?(pp_sep=fun fmt () -> Format.fprintf fmt ",@ ") pp_x fmt m = pp_start fmt (); diff --git a/src/core/CCSexp.ml b/src/core/CCSexp.ml index e4fb37ba..c1e6234a 100644 --- a/src/core/CCSexp.ml +++ b/src/core/CCSexp.ml @@ -347,92 +347,4 @@ end include (Make(Basic_) : S with type t := t and type loc = unit) -(*$T - CCResult.to_opt (parse_string "(abc d/e/f \"hello \\\" () world\" )") <> None - CCResult.to_opt (parse_string "(abc ( d e ffff ) \"hello/world\")") <> None - CCResult.to_opt (parse_string "\"\123\bcoucou\"") <> None -*) - -(*$= & ~printer:(function Ok x -> to_string x | Error e -> "error " ^ e) - (parse_string "(a b)") (Ok (`List [`Atom "a"; `Atom "b"])) - (parse_string "(a\n ;coucou\n b)") (Ok (`List [`Atom "a"; `Atom "b"])) - (parse_string "(a #; (foo bar\n (1 2 3)) b)") (Ok (`List [`Atom "a"; `Atom "b"])) - (parse_string "#; (a b) (c d)") (Ok (`List [`Atom "c"; `Atom "d"])) - (parse_string "#; (a b) 1") (Ok (`Atom "1")) -*) - -(*$= & ~printer:(function Ok x -> String.concat ";" @@ List.map to_string x | Error e -> "error " ^ e) - (parse_string_list "(a b)(c)") (Ok [`List [`Atom "a"; `Atom "b"]; `List [`Atom "c"]]) - (parse_string_list " ") (Ok []) - (parse_string_list "(a\n ;coucou\n b)") (Ok [`List [`Atom "a"; `Atom "b"]]) - (parse_string_list "#; (a b) (c d) e ") (Ok [`List [`Atom "c"; `Atom "d"]; `Atom "e"]) - (parse_string_list "#; (a b) 1") (Ok [`Atom "1"]) -*) - - -(*$inject - let sexp_bijective s = to_string s |> parse_string = Ok s -*) - -(*$= & ~printer:CCFormat.(to_string (Dump.result pp)) - (Ok (`List [`Atom ""])) (parse_string "(\"\")") -*) - -(*$T - sexp_bijective (`List [`Atom ""]) -*) - -(*$inject - let sexp_gen = - let mkatom a = `Atom a and mklist l = `List l in - let atom = Q.Gen.(map mkatom (string_size ~gen:printable (1 -- 30))) in - let gen = Q.Gen.( - sized (fix - (fun self n st -> match n with - | 0 -> atom st - | _ -> - frequency - [ 1, atom - ; 2, map mklist (list_size (0 -- 10) (self (n/10))) - ] st - ) - )) in - let rec small = function - | `Atom s -> String.length s - | `List l -> List.fold_left (fun n x->n+small x) 0 l - and print = function - | `Atom s -> Printf.sprintf "`Atom \"%s\"" s - | `List l -> "`List " ^ Q.Print.list print l - and shrink = function - | `Atom s -> Q.Iter.map mkatom (Q.Shrink.string s) - | `List l -> Q.Iter.map mklist (Q.Shrink.list ~shrink l) - in - Q.make ~print ~small ~shrink gen -*) - -(*$Q & ~count:100 - sexp_gen sexp_bijective -*) - let atom s : t = `Atom s - -(* regression for #338 *) -(*$R - Printexc.record_backtrace true; - let cases = [ - "\"\\256\""; - "\"\\722\02622222\\\\\n\r<\\\\\\\\\"\\222222222\\\\\"\"\2032!2222\\\\\"\""; - "\"\n\r<\\t\023\n\203\\622222222\\\\\"\"\2032!2222\\\\\"\""; - "\"\n\r<@t\023\n\203\\2222D2\n\r22222\01622222222222222222222222\203\\292242\222 2\\\\\">K2"; - "\"\n\r<\\t\023\n\203\\272222222\\\\\"\"\2032\0042222\\\\\"\""; - "\"\023\n\203\\5222\n\r<\\t\023\n\203\\52222222\\\\\"2\\\216\216\216\216\216\\\\\"\216\216\216\216\216\216\216\216\216222222222222222\147"; - "\"\\722\02622222\\\\\n\r<\\\\\\\\\"\\222222222\\\\\"\"\2032!2222\\\\\"\""; - ] in - cases - |> List.iter (fun s -> - try ignore (parse_string s); - with e -> - let st = Printexc.get_backtrace() in - print_endline @@ Printexc.to_string e ^ "\n" ^ st; - assert false) -*) diff --git a/src/core/CCString.ml b/src/core/CCString.ml index aab63806..facf7da0 100644 --- a/src/core/CCString.ml +++ b/src/core/CCString.ml @@ -3,10 +3,6 @@ (** {1 Basic String Utils} *) -(*$inject - open CCShims_.Stdlib -*) - open CCShims_ type 'a iter = ('a -> unit) -> unit @@ -29,23 +25,6 @@ let rev s = let n = length s in init n (fun i -> s.[n-i-1]) -(*$Q - Q.printable_string (fun s -> s = rev (rev s)) - Q.printable_string (fun s -> length s = length (rev s)) -*) - -(*$Q - Q.printable_string (fun s -> \ - rev s = (to_list s |> List.rev |> of_list)) -*) - - -(*$= - "abc" (rev "cba") - "" (rev "") - " " (rev " ") -*) - let rec _to_list s acc i len = if len=0 then List.rev acc else _to_list s (s.[i]::acc) (i+1) (len-1) @@ -234,19 +213,6 @@ let find ?(start=0) ~sub = let pattern = Find.compile sub in fun s -> Find.find ~start ~pattern s -(*$= & ~printer:string_of_int - 1 (find ~sub:"bc" "abcd") - ~-1 (find ~sub:"bc" "abd") - 1 (find ~sub:"a" "_a_a_a_") - 6 (find ~start:5 ~sub:"a" "a1a234a") -*) - -(*$Q & ~count:10_000 - Q.(pair printable_string printable_string) (fun (s1,s2) -> \ - let i = find ~sub:s2 s1 in \ - i < 0 || String.sub s1 i (length s2) = s2) -*) - let find_all ?(start=0) ~sub = let pattern = Find.compile sub in fun s -> @@ -266,38 +232,12 @@ let find_all_l ?start ~sub s = in aux [] (find_all ?start ~sub s) -(*$= & ~printer:Q.Print.(list int) - [1; 6] (find_all_l ~sub:"bc" "abc aabc aab") - [] (find_all_l ~sub:"bc" "abd") - [76] (find_all_l ~sub:"aaaaaa" \ - "aabbaabbaaaaabbbbabababababbbbabbbabbaaababbbaaabaabbaabbaaaabbababaaaabbaabaaaaaabbbaaaabababaabaaabbaabaaaabbababbaabbaaabaabbabababbbaabababaaabaaababbbaaaabbbaabaaababbabaababbaabbaaaaabababbabaababbbaaabbabbabababaaaabaaababaaaaabbabbaabbabbbbbbbbbbbbbbaabbabbbbbabbaaabbabbbbabaaaaabbababbbaaaa") -*) - let mem ?start ~sub s = find ?start ~sub s >= 0 -(*$T - mem ~sub:"bc" "abcd" - not (mem ~sub:"a b" "abcd") -*) - let rfind ~sub = let pattern = Find.rcompile sub in fun s -> Find.rfind ~start:(String.length s-1) ~pattern s -(*$= & ~printer:string_of_int - 1 (rfind ~sub:"bc" "abcd") - ~-1 (rfind ~sub:"bc" "abd") - 5 (rfind ~sub:"a" "_a_a_a_") - 4 (rfind ~sub:"bc" "abcdbcd") - 6 (rfind ~sub:"a" "a1a234a") -*) - -(*$Q & ~count:10_000 - Q.(pair printable_string printable_string) (fun (s1,s2) -> \ - let i = rfind ~sub:s2 s1 in \ - i < 0 || String.sub s1 i (length s2) = s2) -*) - (* Replace substring [s.[pos] … s.[pos+len-1]] by [by] in [s] *) let replace_at_ ~pos ~len ~by s = let b = Buffer.create (length s + length by - len) in @@ -335,16 +275,6 @@ let replace ?(which=`All) ~sub ~by s = done; Buffer.contents b -(*$= & ~printer:CCFun.id - (replace ~which:`All ~sub:"a" ~by:"b" "abcdabcd") "bbcdbbcd" - (replace ~which:`Left ~sub:"a" ~by:"b" "abcdabcd") "bbcdabcd" - (replace ~which:`Right ~sub:"a" ~by:"b" "abcdabcd") "abcdbbcd" - (replace ~which:`All ~sub:"ab" ~by:"hello" " abab cdabb a") \ - " hellohello cdhellob a" - (replace ~which:`Left ~sub:"ab" ~by:"nope" " a b c d ") " a b c d " - (replace ~sub:"a" ~by:"b" "1aa234a") "1bb234b" -*) - module Split = struct type drop_if_empty = { first: bool; @@ -403,12 +333,6 @@ module Split = struct let list_cpy ?(drop=default_drop) ~by s = _mklist ~drop ~by s String.sub - (*$T - Split.list_cpy ~by:"," "aa,bb,cc" = ["aa"; "bb"; "cc"] - Split.list_cpy ~by:"--" "a--b----c--" = ["a"; "b"; ""; "c"; ""] - Split.list_cpy ~by:" " "hello world aie" = ["hello"; ""; "world"; "aie"] - *) - let _mkseq ~drop ~by s k = let by = Find.compile by in let rec make state () = match _split ~by s state with @@ -444,14 +368,6 @@ module Split = struct let left ~by s = try Some (left_exn ~by s) with Not_found -> None - (*$T - Split.left ~by:" " "ab cde f g " = Some ("ab", "cde f g ") - Split.left ~by:"__" "a__c__e_f" = Some ("a", "c__e_f") - Split.left ~by:"_" "abcde" = None - Split.left ~by:"bb" "abbc" = Some ("a", "c") - Split.left ~by:"a_" "abcde" = None - *) - let right_exn ~by s = let i = rfind ~sub:by s in if i = ~-1 then raise Not_found @@ -460,13 +376,6 @@ module Split = struct String.sub s 0 i, String.sub s right (String.length s - right) let right ~by s = try Some (right_exn ~by s) with Not_found -> None - - (*$T - Split.right ~by:" " "ab cde f g" = Some ("ab cde f", "g") - Split.right ~by:"__" "a__c__e_f" = Some ("a__c", "e_f") - Split.right ~by:"_" "abcde" = None - Split.right ~by:"a_" "abcde" = None - *) end [@@@ifge 4.04] @@ -477,17 +386,6 @@ let split_on_char c s: _ list = [@@@endif] -(*$= & ~printer:Q.Print.(list string) - ["a"; "few"; "words"; "from"; "our"; "sponsors"] \ - (split_on_char ' ' "a few words from our sponsors") -*) - -(*$Q - Q.(printable_string) (fun s -> \ - let s = split_on_char ' ' s |> String.concat " " in \ - s = (split_on_char ' ' s |> String.concat " ")) -*) - let split ~by s = Split.list_cpy ~by s let compare_versions a b = @@ -509,20 +407,6 @@ let compare_versions a b = in cmp_rec (Split.gen_cpy ~by:"." a) (Split.gen_cpy ~by:"." b) -(*$T - compare_versions "0.1.3" "0.1" > 0 - compare_versions "10.1" "2.0" > 0 - compare_versions "0.1.alpha" "0.1" > 0 - compare_versions "0.3.dev" "0.4" < 0 - compare_versions "0.foo" "0.0" < 0 - compare_versions "1.2.3.4" "01.2.4.3" < 0 -*) - -(*$Q - Q.(pair printable_string printable_string) (fun (a,b) -> \ - CCOrd.equiv (compare_versions a b) (CCOrd.opp compare_versions b a)) -*) - type nat_chunk = | NC_char of char | NC_int of int @@ -561,25 +445,6 @@ let compare_natural a b = in cmp_rec (chunks a) (chunks b) -(*$T - compare_natural "foo1" "foo2" < 0 - compare_natural "foo11" "foo2" > 0 - compare_natural "foo11" "foo11" = 0 - compare_natural "foo011" "foo11" = 0 - compare_natural "foo1a" "foo1b" < 0 - compare_natural "foo1a1" "foo1a2" < 0 - compare_natural "foo1a17" "foo1a2" > 0 -*) - -(*Q - (Q.pair printable_string printable_string) (fun (a,b) -> \ - CCOrd.opp (compare_natural a b) = compare_natural b a) - (Q.printable_string) (fun a -> compare_natural a a = 0) - (Q.triple printable_string printable_string printable_string) (fun (a,b,c) -> \ - if compare_natural a b < 0 && compare_natural b c < 0 \ - then compare_natural a c < 0 else Q.assume_fail()) -*) - let edit_distance ?(cutoff=max_int) s1 s2 = let n1 = length s1 in let n2 = length s2 in @@ -622,52 +487,6 @@ let edit_distance ?(cutoff=max_int) s1 s2 = v1.(length s2) with Exit -> cutoff -(*$Q - Q.(string_of_size Gen.(0 -- 30)) (fun s -> \ - edit_distance s s = 0) - Q.(let p = string_of_size Gen.(0 -- 20) in pair p p) (fun (s1,s2) -> \ - edit_distance s1 s2 = edit_distance s2 s1) - Q.(let p = string_of_size Gen.(0 -- 20) in pair p p) (fun (s1,s2) -> \ - let e = edit_distance s1 s2 in \ - let e' = edit_distance ~cutoff:3 s1 s2 in \ - (if e' < 3 then e=e' else e >= 3) && \ - (if e <= 3 then e=e' else true)) -*) - -(*$= & ~printer:string_of_int - 2 (edit_distance "hello" "helo!") - 5 (edit_distance "abcde" "tuvwx") - 2 (edit_distance ~cutoff:2 "abcde" "tuvwx") - 1 (edit_distance ("a" ^ String.make 100 '_') ("b"^String.make 100 '_')) - 1 (edit_distance ~cutoff:4 ("a" ^ String.make 1000 '_') ("b"^String.make 1000 '_')) - 2 (edit_distance ~cutoff:3 ("a" ^ String.make 1000 '_' ^ "c")\ - ("b" ^ String.make 1000 '_' ^ "d")) -*) - -(* 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; - edit_distance s (Bytes.to_string s') <= 1) -*) - let repeat s n = assert (n>=0); let len = String.length s in @@ -686,16 +505,6 @@ let prefix ~pre s = check 0 ) -(*$T - prefix ~pre:"aab" "aabcd" - not (prefix ~pre:"ab" "aabcd") - not (prefix ~pre:"abcd" "abc") - prefix ~pre:"abc" "abcde" - prefix ~pre:"" "" - prefix ~pre:"" "abc" - prefix ~pre:"abc" "abc" -*) - let suffix ~suf s = let len = String.length suf in if len > String.length s then false @@ -709,14 +518,6 @@ let suffix ~suf s = check 0 ) -(*$T - suffix ~suf:"cd" "abcd" - suffix ~suf:"" "" - suffix ~suf:"" "abc" - not (suffix ~suf:"cd" "abcde") - not (suffix ~suf:"abcd" "cd") -*) - let take n s = if n < String.length s then String.sub s 0 n @@ -729,34 +530,16 @@ let drop n s = let take_drop n s = take n s, drop n s -(*$= - ("ab", "cd") (take_drop 2 "abcd") - ("abc", "") (take_drop 3 "abc") - ("abc", "") (take_drop 5 "abc") -*) - let chop_suffix ~suf s = if suffix ~suf s then Some (String.sub s 0 (String.length s-String.length suf)) else None -(*$= & ~printer:Q.Print.(option string) - (Some "ab") (chop_suffix ~suf:"cd" "abcd") - None (chop_suffix ~suf:"cd" "abcde") - None (chop_suffix ~suf:"abcd" "cd") -*) - let chop_prefix ~pre s = if prefix ~pre s then Some (String.sub s (String.length pre) (String.length s-String.length pre)) else None -(*$= & ~printer:Q.Print.(option string) - (Some "cd") (chop_prefix ~pre:"aab" "aabcd") - None (chop_prefix ~pre:"ab" "aabcd") - None (chop_prefix ~pre:"abcd" "abc") -*) - let blit = String.blit let fold f acc s = @@ -780,15 +563,6 @@ let pad ?(side=`Left) ?(c=' ') n s = | `Left -> init n (fun i -> if i < pad_len then c else s.[i-pad_len]) | `Right -> init n (fun i -> if i < len_s then s.[i] else c) -(*$= & ~printer:Q.Print.string - " 42" (pad 4 "42") - "0042" (pad ~c:'0' 4 "42") - "4200" (pad ~side:`Right ~c:'0' 4 "42") - "hello" (pad 4 "hello") - "aaa" (pad ~c:'a' 3 "") - "aaa" (pad ~side:`Right ~c:'a' 3 "") -*) - let _to_gen s i0 len = let i = ref i0 in fun () -> @@ -835,11 +609,6 @@ let of_list l = List.iter (Buffer.add_char buf) l; Buffer.contents buf -(*$T - of_list ['a'; 'b'; 'c'] = "abc" - of_list [] = "" -*) - let of_array a = init (Array.length a) (fun i -> a.(i)) @@ -854,21 +623,6 @@ let lines_seq s = Split.seq_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s let lines s = Split.list_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s -(*$= & ~printer:Q.Print.(list @@ Printf.sprintf "%S") - ["ab"; "c"] (lines "ab\nc") - ["ab"; "c"] (lines "ab\nc\n") - [] (lines "") - [""] (lines "\n") - [""; "a"] (lines "\na") -*) - -(*$Q - Q.(printable_string) (fun s -> \ - lines s = (lines_gen s |> Gen.to_list)) - Q.(printable_string) (fun s -> \ - lines s = (lines_iter s |> Iter.to_list)) -*) - let concat_gen_buf ~sep g : Buffer.t = let b = Buffer.create 256 in let rec aux ~first () = match g () with @@ -909,15 +663,6 @@ let concat_seq ~sep seq = let buf = concat_seq_buf ~sep seq in Buffer.contents buf -(*$Q - Q.(small_list printable_string) (fun l -> \ - concat_iter ~sep:"\n" (Iter.of_list l) = concat "\n" l) - Q.(small_list printable_string) (fun l -> \ - concat_gen ~sep:"\n" (Gen.of_list l) = concat "\n" l) - Q.(small_list printable_string) (fun l -> \ - concat_seq ~sep:"\n" (CCSeq.of_list l) = concat "\n" l) -*) - let unlines l = let len = List.fold_left (fun n s -> n + 1 + String.length s) 0 l in let buf = Bytes.create len in @@ -948,32 +693,10 @@ let unlines_seq seq = Buffer.add_char buf '\n'; Buffer.contents buf -(*$= & ~printer:CCFun.id - "" (unlines []) - "ab\nc\n" (unlines ["ab"; "c"]) -*) - -(*$Q - Q.printable_string (fun s -> trim (unlines (lines s)) = trim s) - Q.printable_string (fun s -> trim (unlines_gen (lines_gen s)) = trim s) -*) - -(*$Q - Q.(small_list small_string) (fun l -> \ - let l = unlines l |> lines in \ - l = (unlines l |> lines)) -*) - let set s i c = if i<0 || i>= String.length s then invalid_arg "CCString.set"; init (String.length s) (fun j -> if i=j then c else s.[j]) -(*$T - set "abcd" 1 '_' = "a_cd" - set "abcd" 0 '-' = "-bcd" - (try ignore (set "abc" 5 '_'); false with Invalid_argument _ -> true) -*) - let iter = String.iter let filter_map f s = @@ -985,11 +708,6 @@ let filter_map f s = s; Buffer.contents buf -(*$= & ~printer:Q.Print.string - "bcef" (filter_map \ - (function 'c' -> None | c -> Some (Char.chr (Char.code c + 1))) "abcde") -*) - let filter f s = let buf = Buffer.create (String.length s) in iter @@ -997,14 +715,6 @@ let filter f s = s; Buffer.contents buf -(*$= & ~printer:Q.Print.string - "abde" (filter (function 'c' -> false | _ -> true) "abcdec") -*) - -(*$Q - Q.printable_string (fun s -> filter (fun _ -> true) s = s) -*) - let uniq eq s = if String.length s = 0 then s else begin @@ -1019,10 +729,6 @@ let uniq eq s = Buffer.contents buf end -(*$= & ~printer:Q.Print.string - "abcde" (uniq CCShims_.Stdlib.(=) "abbccdeeeee") -*) - let flat_map ?sep f s = let buf = Buffer.create (String.length s) in iteri @@ -1064,24 +770,6 @@ let is_space_ = function let ltrim s = drop_while is_space_ s let rtrim s = rdrop_while is_space_ s -(*$= & ~printer:id - "abc " (ltrim " abc ") - " abc" (rtrim " abc ") -*) - -(*$Q - Q.(printable_string) (fun s -> \ - String.trim s = (s |> ltrim |> rtrim)) - Q.(printable_string) (fun s -> ltrim s = ltrim (ltrim s)) - Q.(printable_string) (fun s -> rtrim s = rtrim (rtrim s)) - Q.(printable_string) (fun s -> \ - let s' = ltrim s in \ - if s'="" then Q.assume_fail() else s'.[0] <> ' ') - Q.(printable_string) (fun s -> \ - let s' = rtrim s in \ - if s'="" then Q.assume_fail() else s'.[String.length s'-1] <> ' ') -*) - let map2 f s1 s2 = if length s1 <> length s2 then invalid_arg "CCString.map2"; init (String.length s1) (fun i -> f s1.[i] s2.[i]) @@ -1122,18 +810,6 @@ let equal_caseless s1 s2: bool = (fun c1 c2 -> CCChar.equal (CCChar.lowercase_ascii c1) (CCChar.lowercase_ascii c2)) s1 s2 -(*$T - equal_caseless "foo" "FoO" - equal_caseless "helLo" "HEllO" -*) - -(*$Q - Q.(pair printable_string printable_string) (fun (s1,s2) -> \ - equal_caseless s1 s2 = (lowercase_ascii s1=lowercase_ascii s2)) - Q.(printable_string) (fun s -> equal_caseless s s) - Q.(printable_string) (fun s -> equal_caseless (uppercase_ascii s) s) -*) - let to_hex (s:string) : string = let i_to_hex (i:int) = if i < 10 then Char.chr (i + Char.code '0') @@ -1167,20 +843,6 @@ let of_hex_exn (s:string) : string = let of_hex s = try Some (of_hex_exn s) with Invalid_argument _ -> None -(*$= & ~printer:(Printf.sprintf "%S") - "0068656c6c6f20776f726c64" (to_hex "\000hello world") - "" (to_hex "") - "\000hello world" (of_hex_exn "0068656c6c6f20776f726c64") - "hello world" (of_hex_exn "68656C6C6F20776F726C64") -*) - -(*$Q - Q.(string) (fun s -> \ - of_hex_exn (to_hex s) = s) - Q.(string) (fun s -> \ - CCString.for_all (function 'A'..'F'|'a'..'f'|'0'..'9' -> true | _ -> false) @@ to_hex s) -*) - let pp_buf buf s = Buffer.add_char buf '"'; Buffer.add_string buf s; @@ -1199,8 +861,3 @@ module Infix = struct end include Infix - -(*$T - "ab" < "abc" - "123" < "14" - *) diff --git a/src/core/CCUtf8_string.ml b/src/core/CCUtf8_string.ml index abc4666d..b9f3893d 100644 --- a/src/core/CCUtf8_string.ml +++ b/src/core/CCUtf8_string.ml @@ -141,22 +141,6 @@ let to_seq ?(idx=0) s : uchar Seq.t = let st = Dec.make ~idx s in loop st -(*$= & ~cmp:(=) ~printer:Q.Print.(list (fun c -> string_of_int@@ Uchar.to_int c)) - (to_list (of_string_exn "aébõ😀")) (to_seq (of_string_exn "aébõ😀") |> CCList.of_seq) - *) - -(* make sure it's persisted correctly *) -(*$R - let s = (of_string_exn "aébõ😀") in - let seq = to_seq s in - let l = to_list s in - let testeq seq = assert_equal ~cmp:(=) l (CCList.of_seq seq) in - testeq seq; - testeq seq; - testeq seq; - *) - - let iter ?idx f s = to_iter ?idx s f let fold ?idx f acc s = @@ -318,168 +302,3 @@ let of_string_exn s = else invalid_arg "CCUtf8_string.of_string_exn" let of_string s = if is_valid s then Some s else None - -(*$inject - - let printer s = String.escaped (to_string s) - let pp_uchar (c:Uchar.t) = Printf.sprintf "0x%x" (Uchar.to_int c) - - let arb_uchar = - let rec gen = lazy ( - let open Q.Gen in - Q.Gen.int_range Uchar.(to_int min) Uchar.(to_int max) >>= fun n -> - try return (Uchar.of_int n) - with _ -> Lazy.force gen - ) in - Q.make - ~print:(fun c -> Printf.sprintf "" (Uchar.to_int c)) - (Lazy.force gen) - - let uutf_is_valid s = - try - Uutf.String.fold_utf_8 - (fun () _ -> function - | `Malformed _ -> raise Exit - | `Uchar _ -> ()) - () s; - true - with Exit -> - false - - let uutf_to_iter s f = - Uutf.String.fold_utf_8 - (fun () _ -> function - | `Malformed _ -> f (Uchar.of_int 0xfffd) - | `Uchar c -> f c) - () s - - let uutf_of_l l = - let buf = Buffer.create 32 in - List.iter (Uutf.Buffer.add_utf_8 buf) l; - Buffer.contents buf -*) - -(*$R - let s = of_string_exn "このため、" in - let s' = to_iter s |> of_iter in - assert_equal ~cmp:equal ~printer s s' -*) - -(*$QR - Q.small_string (fun s -> - Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); - is_valid s) -*) - -(*$QR & ~long_factor:10 - Q.small_string (fun s -> - Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); - s = (of_string_exn s |> to_iter|> of_iter|> to_string) - ) -*) - -(*$QR & ~long_factor:10 - Q.string (fun s -> - Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); - String.length s = List.length (of_string_exn s |> to_list) - ) -*) - -(*$QR & ~long_factor:10 ~count:20_000 - Q.(small_list arb_uchar) (fun l -> - let s = of_list l in - l = to_list s) -*) - -(*$QR & ~long_factor:10 - Q.(small_list arb_uchar) (fun l -> - let s = of_list l in - l = (to_list @@ of_gen @@ to_gen s) - ) -*) - -(*$QR & ~long_factor:10 - Q.(small_list arb_uchar) (fun l -> - let s = of_list l in - l = (to_list @@ of_iter @@ to_iter s) - ) -*) - -(*$T - not (is_valid "\192\181") - not (is_valid "\193\143") - not (is_valid "\224\151\167") - not (is_valid "\224\137\165") - is_valid "\240\151\189\163" -*) - -(*$QR & ~long_factor:40 - Q.string (fun s -> - Q.assume (is_valid s); - let s = of_string_exn s in - let s2 = s |> to_iter|> of_iter in - if s=s2 then true - else Q.Test.fail_reportf "s=%S, s2=%S" (to_string s)(to_string s2) - ) -*) - -(*$QR & ~long_factor:40 - Q.string (fun s -> - Q.assume (is_valid s); - let s = of_string_exn s in - let s2 = s |> to_gen |> of_gen in - if s=s2 then true - else Q.Test.fail_reportf "s=%S, s2=%S" (to_string s)(to_string s2) - ) -*) - -(* compare with uutf *) - -(*$QR & ~long_factor:40 ~count:50_000 - Q.small_string (fun s -> - let v1 = is_valid s in - let v2 = uutf_is_valid s in - if v1=v2 then true - else Q.Test.fail_reportf "s:%S, valid: %B, uutf_valid: %B" s v1 v2 - ) -*) - -(*$QR & ~long_factor:40 ~count:50_000 - Q.(small_list arb_uchar) (fun l -> - let pp s = Q.Print.(list pp_uchar) s in - let uutf = uutf_of_l l in - let s = (of_list l:>string) in - if uutf = s then true - else Q.Test.fail_reportf "l: '%s', uutf: '%s', containers: '%s'" - (pp l) uutf s - ) -*) - -(*$QR & ~long_factor:40 ~count:50_000 - Q.small_string (fun s -> - Q.assume (is_valid s && uutf_is_valid s); - let pp s = Q.Print.(list pp_uchar) s in - let l_uutf = uutf_to_iter s |> Iter.to_list in - let l_co = of_string_exn s |> to_iter |> Iter.to_list in - if l_uutf = l_co then true - else Q.Test.fail_reportf "uutf: '%s', containers: '%s', is_valid %B, uutf_is_valid %B" - (pp l_uutf) (pp l_co) (is_valid s) (uutf_is_valid s) - ) -*) - -(*$R - for i = 0 to 127 do - let c = Uchar.of_int i in - assert_equal 1 (n_bytes (of_list [c])) - done -*) - -(*$QR - Q.(small_list arb_uchar) (fun l -> - of_list l = concat empty (List.map of_uchar l)) - *) - -(*$QR - Q.(pair small_nat arb_uchar) (fun (i,c) -> - make i c = concat empty (CCList.init i (fun _ -> of_uchar c))) - *) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 8d512537..07ccf4da 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -54,20 +54,11 @@ let create_with ?(capacity=128) x = vec } -(*$T - (create_with ~capacity:200 1 |> capacity) >= 200 -*) - let return x = { size=1; vec= [| x |]; } -(*$T - return 42 |> to_list = [42] - return 42 |> length = 1 -*) - let make n x = { size=n; vec=Array.make n x; @@ -96,33 +87,6 @@ let resize_ v newcapacity x = v.vec <- new_vec; () -(*$T - let v = create_with ~capacity:10 1 in \ - ensure v 200; capacity v >= 200 -*) - -(*$T - let v = create() in push v 0.; push v 1.; push v 2.; 3=length v - let v = create() in push v 1.; push v 2.; push v 3.; 6. = (get v 0 +. get v 1 +. get v 2) - let v = create() in push v 0; push v 1; push v 2; 3=length v - let v = create() in push v 1; push v 2; push v 3; 6 = (get v 0 + get v 1 + get v 2) - let v = create() in push v "a"; push v "b"; push v "c"; 3=length v - let v = create() in push v "a"; push v "b"; push v "c"; "abc" = String.concat "" (to_list v) -*) - -(*$R - let v = create() in - push v 0.; push v 1.; - clear v; - push v 0.; push v 1.; push v 7.; push v 10.; push v 12.; - truncate v 2; - assert_equal 1. (fold (+.) 0. v); - clear v; - assert_equal 0 (size v); - push v 0.; push v 1.; push v 7.; push v 10.; push v 12.; - assert_equal (1. +. 7. +. 10. +. 12.) (fold (+.) 0. v); - *) - (* grow the array, using [x] as a filler if required *) let grow_with_ v ~filler:x = if array_is_empty_ v then ( @@ -168,14 +132,6 @@ let ensure v size = let[@inline] clear v = v.size <- 0 -(*$R - let v = of_iter Iter.(1 -- 10) in - OUnit2.assert_equal 10 (size v); - clear v; - OUnit2.assert_equal 0 (size v); - OUnit2.assert_bool "empty_after_clear" (Iter.is_empty (to_iter v)); -*) - let clear_and_reset v = v.size <- 0; v.vec <- [||] @@ -202,11 +158,6 @@ let push v x = if v.size = Array.length v.vec then grow_with_ v ~filler:x; push_unsafe_ v x -(*$T - let v = create () in push v 1; to_list v = [1] - let v = of_list [1;2;3] in push v 4; to_list v = [1;2;3;4] -*) - let resize_with v f size = if size<0 then invalid_arg "Vec.resize_with"; if Array.length v.vec = 0 then ( @@ -221,17 +172,6 @@ let resize_with v f size = v.size <- size ) -(*$T - let v = make 1 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4] - let v = make 1 0 in resize_with v (fun i -> i) 5; CCList.length (to_list v) = 5 - let v = create_with ~capacity:2 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4] - let v = make 5 0 in resize_with v (fun i -> i) 5; to_list v = [0;0;0;0;0] - let v = make 5 0 in resize_with v (fun i -> i) 6; to_list v = [0;0;0;0;0;5] - let v = make 5 0 in try resize_with v (fun i -> i) (-1); false \ - with Invalid_argument _ -> true - let v = make 5 0 in resize_with v (fun i -> i) 5; List.length (to_list v) = 5 -*) - let resize_with_init v ~init size = if size<0 then invalid_arg "Vec.resize_with_init"; if Array.length v.vec = 0 then ( @@ -246,23 +186,6 @@ let resize_with_init v ~init size = v.size <- size; ) -(*$T - let v = make 1 0 in resize_with_init v ~init:1 5; to_list v = [0;1;1;1;1] - let v = make 1 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5 - - let v = create_with ~capacity:2 0 in resize_with_init v ~init:1 5; to_list v = [1;1;1;1;1] - let v = make 5 0 in resize_with_init v ~init:1 5; to_list v = [0;0;0;0;0] - let v = make 3 0 in resize_with_init v ~init:1 5; to_list v = [0;0;0;1;1] - let v = make 5 0 in try resize_with_init v ~init:1 (-1); false \ - with Invalid_argument _ -> true - let v = make 5 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5 -*) - -(* test for asymptotic behavior *) -(*$T - let v =make 1 0 in for i=0 to 100_000 do resize_with_init v ~init:10 i; done; true - *) - (** Add all elements of b to a *) let append a b = if array_is_empty_ a then ( @@ -278,28 +201,6 @@ let append a b = a.size <- a.size + b.size ) -(*$T - let v1 = init 5 (fun i->i) and v2 = init 5 (fun i->i+5) in \ - append v1 v2; to_list v1 = CCList.(0--9) - let empty = create () and v2 = init 5 (fun i->i) in \ - append empty v2; to_list empty = CCList.(0--4) - let v1 = init 5 (fun i->i) and empty = create () in \ - append v1 empty; to_list v1 = CCList.(0--4) - let v = init 3 (fun i->i) in \ - append v v; to_list v = [0; 1; 2; 0; 1; 2] - let empty = create () in \ - append empty empty; to_list empty = [] -*) - -(*$R - let a = of_iter Iter.(1 -- 5) in - let b = of_iter Iter.(6 -- 10) in - append a b; - OUnit2.assert_equal 10 (size a); - OUnit2.assert_equal (Iter.to_array Iter.(1 -- 10)) (to_array a); - OUnit2.assert_equal (Iter.to_array Iter.(6 -- 10)) (to_array b); -*) - let[@inline] get v i = if i < 0 || i >= v.size then invalid_arg "CCVector.get"; Array.unsafe_get v.vec i @@ -326,25 +227,6 @@ let remove_unordered v i = v.size <- v.size - 1; fill_with_junk_ v.vec v.size 1 -(*$Q remove_and_shift - Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> \ - let v1 = of_list l and v2 = of_list l in \ - remove_and_shift v1 9; \ - remove_unordered v2 9; \ - to_list v1 = (to_list v2)) - Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> \ - let l = List.sort CCInt.compare l in \ - let v = of_list l in\ - remove_and_shift v 3; \ - to_list v = (List.sort CCInt.compare (to_list v))) - Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> \ - let l = List.sort CCInt.compare l in \ - let v1 = of_list l and v2 = of_list l in \ - remove_and_shift v1 3; \ - remove_unordered v2 3; \ - to_list v1 = (List.sort CCInt.compare (to_list v2))) -*) - let insert v i x = (* Note that we can insert at i=v.size *) if i < 0 || i > v.size then invalid_arg "CCVector.insert"; @@ -355,14 +237,6 @@ let insert v i x = v.vec.(i) <- x; v.size <- v.size + 1 -(*$T - let v = (1 -- 5) in insert v 3 9; to_list v = [1;2;3;9;4;5] - let v = create () in insert v 0 2; to_list v = [2] - let v = (1 -- 3) in remove_and_shift v 1; insert v 1 5; to_list v = [1;5;3] - let v = (1 -- 3) in remove_and_shift v 0; insert v 2 5; to_list v = [2;3;5] - let v = (1 -- 3) in insert v 3 5; to_list v = [1;2;3;5] -*) - let[@inline] append_iter a i = i (fun x -> push a x) let append_seq a seq = Seq.iter (fun x -> push a x) seq @@ -378,17 +252,6 @@ let append_array a b = a.size <- a.size + len_b ) -(*$T - let v1 = init 5 (fun i->i) and v2 = Array.init 5 (fun i->i+5) in \ - append_array v1 v2; to_list v1 = CCList.(0--9) - let empty = create () in \ - append_array empty CCArray.(0--5); to_list empty = CCList.(0--5) - let v1 = init 5 (fun i->i) in \ - append_array v1 [| |]; to_list v1 = CCList.(0--4) - let empty = create () in \ - append_array empty [| |]; to_list empty = [] -*) - let append_list a b = match b with | [] -> () | x :: _ -> @@ -399,45 +262,10 @@ let append_list a b = match b with List.iter (push_unsafe_ a) b; () -(*$Q - Q.(pair (list int)(list int)) (fun (l1,l2) -> \ - let v = of_list l1 in append_list v l2; \ - to_list v = (l1 @ l2)) - Q.(pair (list int)(list int)) (fun (l1,l2) -> \ - let v = of_list l1 in append_list v l2; \ - length v = List.length l1 + List.length l2) -*) - let rec append_gen a b = match b() with | None -> () | Some x -> push a x; append_gen a b -(*$Q - Q.(pair (list int)(list int)) (fun (l1,l2) -> \ - let v = of_list l1 in append_gen v (Gen.of_list l2); \ - to_list v = (l1 @ l2)) - Q.(pair (list int)(list int)) (fun (l1,l2) -> \ - let v = of_list l1 in append_gen v (Gen.of_list l2); \ - length v = List.length l1 + List.length l2) -*) - - -(*$inject - let gen x = - let small = length in - let print = CCOption.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; - Iter.to_list (to_iter v1) = - Iter.(to_list (append (of_list l1) (to_iter v2))) - ) -*) - let equal eq v1 v2 = v1.size = v2.size && @@ -447,25 +275,6 @@ let equal eq v1 v2 = in check 0 -(*$T - equal (=) (create ()) (create ()) - equal (=) (return 42) (return 42) - not (equal (=) (create ()) (return 42)) - not (equal (=) (return 42) (create ())) -*) - -(*$Q - Q.(let g = list_of_size Gen.(0--10) small_int in pair g g) (fun (l1,l2) -> \ - equal (=) (of_list l1) (of_list l2) = (l1=l2)) -*) - -(*$QR - Q.(pair (small_list small_int)(small_list small_int)) (fun (l1,l2) -> - let v1 = of_list l1 in - let v2 = of_list l2 in - equal (=) v1 v2 = (l1=l2)) -*) - let compare cmp v1 v2 = let n = min v1.size v2.size in let rec check i = @@ -477,13 +286,6 @@ let compare cmp v1 v2 = ) in check 0 -(*$QR - Q.(pair (small_list small_int)(small_list small_int)) (fun (l1,l2) -> - let v1 = of_list l1 in - let v2 = of_list l2 in - compare Stdlib.compare v1 v2 = CCList.compare Stdlib.compare l1 l2) -*) - exception Empty let pop_exn v = @@ -506,40 +308,11 @@ let[@inline] top_exn v = if v.size = 0 then raise Empty; Array.unsafe_get v.vec (v.size-1) -(*$T - 1 -- 10 |> top = Some 10 - create () |> top = None - 1 -- 10 |> top_exn = 10 -*) - let[@inline] copy v = { size = v.size; vec = Array.sub v.vec 0 v.size; } -(*$T - (let v = of_list [1;2;3] in let v' = copy v in \ - to_list v' = [1;2;3]) - create () |> copy |> is_empty -*) - -(*$R - let v = of_iter Iter.(1 -- 100) in - OUnit2.assert_equal 100 (size v); - let v' = copy v in - OUnit2.assert_equal 100 (size v'); - clear v'; - OUnit2.assert_bool "empty" (is_empty v'); - OUnit2.assert_bool "not_empty" (not (is_empty v)); -*) - -(*$QR - Q.(small_list small_int) (fun l -> - let v = of_list l in - let v' = copy v in - equal (=) v v') -*) - let truncate v n = let old_size = v.size in if n < old_size then ( @@ -548,23 +321,6 @@ let truncate v n = fill_with_junk_ v.vec n (old_size-n); ) -(*$R - let v = of_iter Iter.(1 -- 10) in - truncate v 5; - OUnit2.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 = Iter.(to_list (take n (of_list l))) in - let v' = copy v in - truncate v' n; - h = to_list v' - ) -*) - let shrink_to_fit v : unit = if v.size = 0 then ( v.vec <- [| |] @@ -572,14 +328,6 @@ let shrink_to_fit v : unit = v.vec <- Array.sub v.vec 0 v.size ) -(*$QR - (gen Q.small_int) (fun v -> - let v' = copy v in - shrink_to_fit v; - to_list v = to_list v' - ) -*) - let sort' cmp v = (* possibly copy array (to avoid junk at its end), then sort the array *) let a = @@ -597,15 +345,6 @@ let sort cmp v = Array.sort cmp v'.vec; v' -(*$QR - (gen Q.small_int) (fun v -> - let v' = copy v in - sort' Stdlib.compare v'; - let l = to_list v' in - List.sort Stdlib.compare l = l - ) -*) - let uniq_sort cmp v = sort' cmp v; let n = v.size in @@ -628,18 +367,6 @@ let uniq_sort cmp v = then traverse v.vec.(0) 1 1 (* start at 1, to get the first element in hand *) -(*$T - let v = of_list [1;4;5;3;2;4;1] in \ - uniq_sort Stdlib.compare v; to_list v = [1;2;3;4;5] -*) - -(*$QR & ~long_factor:10 - Q.(small_list small_int) (fun l -> - let v = of_list l in - uniq_sort Stdlib.compare v; - to_list v = (CCList.sort_uniq ~cmp:Stdlib.compare l)) -*) - let iter k v = let n = v.size in for i = 0 to n-1 do @@ -652,11 +379,6 @@ let iteri k v = k i (Array.unsafe_get v.vec i) done -(*$T - let v = (0--6) in \ - iteri (fun i x -> if i = 3 then remove_unordered v i) v; length v = 6 -*) - let map f v = if array_is_empty_ v then create () @@ -665,17 +387,6 @@ let map f v = { size=v.size; vec; } ) -(*$T - let v = create() in push v 1; push v 2; push v 3; \ - to_list (map string_of_int v) = ["1"; "2"; "3"] -*) - -(*$QR - Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - to_list (map f v) = List.map f l) -*) - let mapi f v = if array_is_empty_ v then create () @@ -684,30 +395,11 @@ let mapi f v = { size=v.size; vec; } ) -(*$T mapi - let v = create() in push v 1; push v 2; push v 3; \ - to_list (mapi (fun i e -> Printf.sprintf "%i %i" i e) v) = ["0 1"; "1 2"; "2 3"] -*) - -(*$QR mapi - Q.(pair (fun2 Observable.int Observable.int small_int) (small_list small_int)) - (fun (Q.Fun (_,f),l) -> - let v = of_list l in - to_list (mapi f v) = List.mapi f l) -*) - let map_in_place f v = iteri (fun i x -> Array.unsafe_set v.vec i (f x)) v -(*$QR - Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - map_in_place f v; - to_list v = List.map f l) -*) - let filter_in_place p v = let i = ref 0 in (* cur element *) @@ -726,18 +418,6 @@ let filter_in_place p v = fill_with_junk_ v.vec !j (v.size - !j); v.size <- !j -(*$T - let v = 1 -- 10 in filter_in_place (fun x->x<4) v; \ - to_list v = [1;2;3] -*) - -(*$QR - Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - filter_in_place f v; - to_list v = List.filter f l) -*) - let filter p v = if array_is_empty_ v then ( create () @@ -749,17 +429,6 @@ let filter p v = v' ) -(*$T - filter (fun x-> x mod 2=0) (of_list [1;2;3;4;5]) |> to_list = [2;4] - filter (fun x-> x mod 2=0) (1 -- 1_000_000) |> length = 500_000 -*) - -(*$QR - Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - to_list (filter f v) = List.filter f l) -*) - let fold f acc v = let rec fold acc i = if i = v.size then acc @@ -768,17 +437,6 @@ let fold f acc v = fold (f acc x) (i+1) in fold acc 0 -(*$T - fold (+) 0 (of_list [1;2;3;4;5]) = 15 - fold (+) 0 (create ()) = 0 -*) - -(*$QR - Q.(pair (fun2 Observable.int Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - fold f 0 v = List.fold_left f 0 l) -*) - let exists p v = let n = v.size in let rec check i = @@ -786,12 +444,6 @@ let exists p v = else p v.vec.(i) || check (i+1) in check 0 -(*$QR - Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - exists f v = List.exists f l) -*) - let for_all p v = let n = v.size in let rec check i = @@ -799,12 +451,6 @@ let for_all p v = else p v.vec.(i) && check (i+1) in check 0 -(*$QR - Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - for_all f v = List.for_all f l) -*) - let member ~eq x v = exists (eq x) v @@ -828,12 +474,6 @@ let find p v = try Some (find_internal_ p v) with Not_found -> None -(*$QR - Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - find f v = CCList.find_pred f l) -*) - let find_map f v = let n = v.size in let rec search i = @@ -844,13 +484,6 @@ let find_map f v = in search 0 -(*$Q - Q.(list small_int) (fun l -> \ - let v = of_list l in \ - let f x = x>30 && x < 35 in \ - find_map (fun x -> if f x then Some x else None) v = find f v) -*) - let filter_map f v = let v' = create () in iter @@ -860,12 +493,6 @@ let filter_map f v = v; v' -(*$QR - Q.(pair (fun1 Observable.int (option bool)) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - to_list (filter_map f v) = CCList.filter_map f l) -*) - let filter_map_in_place f v = let i = ref 0 in (* cur element *) let j = ref 0 in (* cur insertion point *) @@ -884,26 +511,6 @@ let filter_map_in_place f v = fill_with_junk_ v.vec !j (v.size - !j); v.size <- !j -(*$QR - Q.(pair (fun1 Observable.int (option small_int)) (small_list small_int)) (fun (Q.Fun (_,f),l) -> - let v = of_list l in - filter_map_in_place f v; - to_list v = CCList.filter_map f l) -*) - -(* check it frees memory properly *) -(*$R - let s = "coucou" ^ "lol" in - let w = Weak.create 1 in - Weak.set w 0 (Some s); - let v = of_list ["a"; s] in - filter_in_place (fun s -> String.length s <= 1) v; - assert_equal 1 (length v); - assert_equal "a" (get v 0); - Gc.full_major(); - assert_equal None (Weak.get w 0); -*) - let flat_map f v = let v' = create () in iter (fun x -> iter (push v') (f x)) v; @@ -944,13 +551,6 @@ let monoid_product f a1 a2 : _ t = let j = i_prod / na1 in f a1.vec.(i) a2.vec.(j)) -(*$= & ~cmp:(=) ~printer:Q.Print.(list int) - [ 11; 12; 21; 22 ] (List.sort CCInt.compare @@ \ - to_list @@ monoid_product (+) (of_list [10; 20]) (of_list [1; 2])) - [ 11; 12; 13; 14 ] (List.sort CCInt.compare @@ \ - to_list @@ monoid_product (+) (of_list [10]) (of_list [1; 2; 3; 4])) -*) - let (>>=) x f = flat_map f x let (>|=) x f = map f x @@ -968,46 +568,17 @@ let rev_in_place v = done ) -(*$QR - Q.(small_list small_int) (fun l -> - let v = of_list l in - rev_in_place v; - to_list v = List.rev l) -*) - let rev v = let v' = copy v in rev_in_place v'; v' -(*$T - rev (of_list [1;2;3;4]) |> to_list = [4;3;2;1] - rev (of_list [1;2;3;4;5]) |> to_list = [5;4;3;2;1] - rev (create ()) |> to_list = [] -*) - -(*$QR - Q.(small_list small_int) (fun l -> - let v = of_list l in - to_list (rev v) = List.rev l) -*) - let rev_iter f v = let n = v.size in for i = n-1 downto 0 do f (Array.unsafe_get v.vec i) done -(*$T - let v = of_list [1;2;3] in (fun f->rev_iter f v) |> Iter.to_list = [3;2;1] -*) - -(*$Q - Q.(list int) (fun l -> \ - let v = of_list l in \ - (fun f->rev_iter f v) |> Iter.to_list = List.rev l) -*) - let size v = v.size let length v = v.size @@ -1024,10 +595,6 @@ let of_seq ?(init=create ()) seq = append_seq init seq; init -(*$T - of_iter Iter.(1 -- 10) |> to_list = CCList.(1 -- 10) -*) - let to_iter v k = iter k v let to_iter_rev v k = @@ -1050,11 +617,6 @@ let to_seq_rev v = in aux (size v-1) -(*$Q - Q.(list int) (fun l -> \ - let v= of_list l in v |> to_iter_rev |> Iter.to_rev_list = l) -*) - let slice_iter v start len = assert (start >= 0 && len >= 0); fun k -> @@ -1064,12 +626,6 @@ let slice_iter v start len = k x done -(*$T - slice_iter (of_list [0;1;2;3;4]) 1 3 |> CCList.of_iter = [1;2;3] - slice_iter (of_list [0;1;2;3;4]) 1 4 |> CCList.of_iter = [1;2;3;4] - slice_iter (of_list [0;1;2;3;4]) 0 5 |> CCList.of_iter = [0;1;2;3;4] -*) - let slice v = (v.vec, 0, v.size) let (--) i j = @@ -1077,28 +633,12 @@ let (--) i j = then init (i-j+1) (fun k -> i-k) else init (j-i+1) (fun k -> i+k) -(*$T - (1 -- 4) |> to_list = [1;2;3;4] - (4 -- 1) |> to_list = [4;3;2;1] - (0 -- 0) |> to_list = [0] -*) - -(*$Q - Q.(pair small_int small_int) (fun (a,b) -> \ - (a -- b) |> to_list = CCList.(a -- b)) -*) - let (--^) i j = if i=j then create() else if i>j then init (i-j) (fun k -> i-k) else init (j-i) (fun k -> i+k) -(*$Q - Q.(pair small_int small_int) (fun (a,b) -> \ - (a --^ b) |> to_list = CCList.(a --^ b)) -*) - let of_array a = if Array.length a = 0 then create () @@ -1116,10 +656,6 @@ let of_list l = match l with List.iter (push_unsafe_ v) l; v -(*$T - of_list CCList.(1--300_000) |> to_list = CCList.(1--300_000) -*) - let to_array v = Array.sub v.vec 0 v.size @@ -1142,10 +678,6 @@ let to_gen v = Some x ) else None -(*$T - let v = (1--10) in to_list v = Gen.to_list (to_gen v) -*) - let to_string ?(start="") ?(stop="") ?(sep=", ") item_to_string v = start ^ (to_list v |> List.map item_to_string |> String.concat sep) ^ stop diff --git a/src/testlib/containers_testlib.ml b/src/testlib/containers_testlib.ml index e9c9df7c..aa0a7d83 100644 --- a/src/testlib/containers_testlib.ml +++ b/src/testlib/containers_testlib.ml @@ -18,6 +18,7 @@ module Test = struct count: int option; arb: 'a Q.arbitrary; prop: 'a -> bool; + long_factor: int option; } -> run type t = { @@ -45,7 +46,7 @@ module Test = struct in Error msg ) - | Q {count; arb; prop} -> + | Q {count; arb; prop; long_factor} -> (* create a random state from the seed *) let rand = @@ -54,7 +55,7 @@ module Test = struct in let module Fmt = CCFormat in - let cell = Q.Test.make_cell ?count ~name:(str_loc self) arb prop in + let cell = Q.Test.make_cell ?count ?long_factor ~name:(str_loc self) arb prop in let pp_cex out (cx: _ Q.TestResult.counter_ex) = let {Q.TestResult.instance; shrink_steps=n; msg_l} = cx in @@ -98,7 +99,7 @@ module type S = sig val eq : ?cmp:'a eq -> ?printer:'a print -> 'a -> 'a -> unit - val q : ?count:int -> 'a Q.arbitrary -> ('a -> bool) -> unit + val q : ?count:int -> ?long_factor:int -> 'a Q.arbitrary -> ('a -> bool) -> unit val assert_equal : ?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) -> @@ -130,8 +131,8 @@ module Make_test(X:sig val file: string end) = struct let eq ?cmp ?printer lhs rhs : unit = add_ @@ mk @@ Test.Eq {eq=cmp; print=printer; lhs; rhs} - let q ?count arb prop : unit = - add_ @@ mk @@ Test.Q {arb; prop; count} + let q ?count ?long_factor arb prop : unit = + add_ @@ mk @@ Test.Q {arb; prop; count; long_factor} let assert_equal ?printer ?(cmp=(=)) x y : unit = if not @@ cmp x y then ( diff --git a/src/testlib/containers_testlib.mli b/src/testlib/containers_testlib.mli index 2084c11f..217c9331 100644 --- a/src/testlib/containers_testlib.mli +++ b/src/testlib/containers_testlib.mli @@ -13,7 +13,7 @@ module type S = sig val eq : ?cmp:'a eq -> ?printer:'a print -> 'a -> 'a -> unit - val q : ?count:int -> 'a Q.arbitrary -> ('a -> bool) -> unit + val q : ?count:int -> ?long_factor:int -> 'a Q.arbitrary -> ('a -> bool) -> unit val assert_equal : ?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) -> diff --git a/src/unix/CCUnix.ml b/src/unix/CCUnix.ml index c3c10352..aadeb43a 100644 --- a/src/unix/CCUnix.ml +++ b/src/unix/CCUnix.ml @@ -50,12 +50,6 @@ let escape_str s = Buffer.contents buf ) else s -(*$T - escape_str "foo" = "foo" - escape_str "foo bar" = "'foo bar'" - escape_str "fo'o b'ar" = "'fo'\\''o b'\\''ar'" -*) - let read_all ?(size=1024) ic = let buf = ref (Bytes.create size) in let len = ref 0 in @@ -113,12 +107,6 @@ let call_full ?bufsize ?stdin ?env cmd = method errcode = int_of_process_status status end) -(*$T - call_full ~stdin:(`Str "abc") "cat" |> stdout = "abc" - call_full "echo %s" (escape_str "a'b'c") |> stdout = "a'b'c\n" - call_full "echo %s" "a'b'c" |> stdout = "abc\n" -*) - let call ?bufsize ?stdin ?env cmd = call_full_inner ?bufsize ?stdin ?env cmd ~f:(fun (out,err,status) -> out, err, int_of_process_status status) @@ -127,12 +115,6 @@ let call_stdout ?bufsize ?stdin ?env cmd = call_full_inner ?bufsize ?stdin ?env cmd ~f:(fun (out,_err,_status) -> out) -(*$T - call_stdout ~stdin:(`Str "abc") "cat" = "abc" - call_stdout "echo %s" (escape_str "a'b'c") = "a'b'c\n" - call_stdout "echo %s" "a'b'c" = "abc\n" -*) - type line = string type async_call_result = @@ -270,29 +252,6 @@ let with_file_lock ~kind filename f = Unix.close lock_file; raise e -(*$R - let m = 200 in - let n = 50 in - let write_atom filename s = - with_file_lock ~kind:`Write filename - (fun () -> - CCIO.with_out ~flags:[Open_append; Open_creat] - filename (fun oc -> output_string oc s; flush oc)) - in - let f filename = - for j=1 to m do - write_atom filename "foo\n" - done - in - CCIO.File.with_temp ~prefix:"containers_" ~suffix:".txt" - (fun filename -> - let a = Array.init n (fun _ -> Thread.create f filename) in - Array.iter Thread.join a; - let lines = CCIO.with_in filename CCIO.read_lines_l in - assert_equal ~printer:string_of_int (n * m) (List.length lines); - assert_bool "all valid" (List.for_all ((=) "foo") lines)) -*) - module Infix = struct let (?|) fmt = call_full fmt @@ -334,15 +293,3 @@ let with_temp_dir ?(mode=0o700) ?dir pat (f: string -> 'a) : 'a = ) in loop 1000 - -(*$R - let filename = with_temp_dir "test_containers" - (fun dir -> - let name = Filename.concat dir "test" in - CCIO.with_out name (fun oc -> output_string oc "content"; flush oc); - assert_bool ("file exists:"^name) (Sys.file_exists name); - name) - in - assert_bool ("file does not exist"^filename) (not (Sys.file_exists filename)); - () -*) diff --git a/tests/core/compat/dune b/tests/core/compat/dune new file mode 100644 index 00000000..67bd6259 --- /dev/null +++ b/tests/core/compat/dune @@ -0,0 +1,5 @@ + +(tests + (names t_compat) + (flags :standard -nolabels) + (libraries containers)) diff --git a/tests/core/compat/t_compat.ml b/tests/core/compat/t_compat.ml new file mode 100644 index 00000000..c14764e7 --- /dev/null +++ b/tests/core/compat/t_compat.ml @@ -0,0 +1,9 @@ + +(* test consistency of interfaces *) +module type L = module type of CCEqual +module type LL = module type of CCEqualLabels ;; + +ignore (module CCEqualLabels : L);; + +ignore (module CCEqual : LL);; + diff --git a/tests/core/dune b/tests/core/dune index 44f81944..3bb08d4c 100644 --- a/tests/core/dune +++ b/tests/core/dune @@ -1,4 +1,6 @@ (test (name t) (flags :standard -strict-sequence -warn-error -a+8) - (libraries containers containers_testlib)) + (modes native) + (libraries containers containers.bencode containers.unix threads + containers_testlib iter gen uutf)) diff --git a/tests/core/t.ml b/tests/core/t.ml index 301e80b6..f3c74c44 100644 --- a/tests/core/t.ml +++ b/tests/core/t.ml @@ -13,4 +13,25 @@ Containers_testlib.run_all ~descr:"containers" [ T_format.get(); T_fun.get (); T_hash.get(); + T_hashtbl.get(); + T_heap.get(); + T_IO.get(); + T_int.get(); + T_int32.get(); + T_int64.get(); + T_map.get(); + T_nativeint.get(); + T_option.get(); + T_ord.get(); + T_parse.get(); + T_random.get(); + T_result.get(); + T_set.get(); + T_seq.get(); + T_sexp.get(); + T_string.get(); + T_utf8string.get(); + T_vector.get(); + T_bencode.get(); + T_unix.get(); ];; diff --git a/tests/core/t_IO.ml b/tests/core/t_IO.ml new file mode 100644 index 00000000..50b7b02d --- /dev/null +++ b/tests/core/t_IO.ml @@ -0,0 +1,69 @@ + +open CCIO + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + + +t @@ fun () -> + let s = String.make 200 'y' in + let s = Printf.sprintf "a\nb\n %s\nlast line\n" s in + File.with_temp ~prefix:"test_containers" ~suffix:"" + (fun name -> + with_out name @@ fun oc -> + output_string oc s; + flush oc; + let s' = with_in name read_all in + assert_equal ~printer:(fun s->s) s s' + ); + true;; + +q Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> + let l' = ref [] in + File.with_temp ~prefix:"test_containers" ~suffix:"" + (fun name -> + with_out name @@ fun oc -> + write_lines_l oc l; + flush oc; + l' := with_in name read_lines_l; + ); + String.concat "\n" l = String.concat "\n" !l' +);; + +q Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> + let l' = ref [] in + File.with_temp ~prefix:"test_containers" ~suffix:"" + (fun name -> + with_out name @@ fun oc -> + write_lines oc (Gen.of_list l); + flush oc; + l' := with_in name (fun ic -> read_lines_gen ic |> Gen.to_list); + ); + String.concat "\n" l = String.concat "\n" !l' +);; + +q Q.(list_of_size Gen.(0 -- 40) printable_string) (fun l -> + let s = ref "" in + File.with_temp ~prefix:"test_containers1" ~suffix:"" + (fun name1 -> + with_out name1 @@ fun oc1 -> + write_gen ~sep:"" oc1 (Gen.of_list l); + flush oc1; + File.with_temp ~prefix:"test_containers2" ~suffix:"" + (fun name2 -> + with_out name2 @@ fun oc2 -> + CCIO.with_in name1 (fun ic1 -> copy_into ic1 oc2); + flush oc2; + s := with_in name2 read_all;); + ); + String.concat "" l = !s +);; + +t @@ fun () -> + File.walk "." + |> Gen.for_all + (function + | `File, f -> not (Sys.is_directory f) + | `Dir, f -> Sys.is_directory f + ) + ;; diff --git a/tests/core/t_bencode.ml b/tests/core/t_bencode.ml new file mode 100644 index 00000000..377b54a8 --- /dev/null +++ b/tests/core/t_bencode.ml @@ -0,0 +1,57 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +open Containers_bencode;; + + +eq ~printer:to_string_debug + (map_of_list []) (Decode.of_string_exn "de");; +eq ~printer:to_string_debug + (list [int 1; int 2; string "foo"]) (Decode.of_string_exn "li1ei2e3:fooe");; + +module B = Containers_bencode + +let rec size = function + | Int _ | String _ -> 1 + | List l -> List.fold_left (fun n x -> n + size x) 0 l + | Map m -> Str_map.fold(fun _ v n -> size v + n) m 0 + +let g_rand_b = + Q.Gen.( + sized_size (0--7) @@ fix @@ fun self n -> + let str n = string_size ~gen:char (0 -- n) in + let base = [ + int >|= B.int; + str 100 >|= B.string; + ] in + match n with + | 0 -> oneof base + | n -> + frequency @@ + List.map (fun x -> 2, x) base @ + [ 1, list_size (0 -- 10) (self (n-1)) >|= B.list; + 1, list_size (0 -- 10) (pair (str 10) (self (n-1)) ) >|= B.map_of_list; + ] + ) + +let rec shrink_b self = Q.(Iter.( + match self with + | Int i -> Shrink.int64 i >|= B.int64 + | String s -> Shrink.string s >|= B.string + | List l -> Shrink.list ~shrink:shrink_b l >|= B.list + | Map l -> + let l = Str_map.fold (fun k v l -> (k,v) :: l) l [] in + Shrink.list ~shrink:(fun (k,v) -> + (Shrink.string k >|= fun k -> k,v) <+> + (shrink_b v >|= fun v -> k,v)) + l + >|= B.map_of_list + )) + +let rand_b = Q.make ~print:to_string_debug ~stats:["size", size] +~shrink:shrink_b g_rand_b ;; + +q rand_b (fun b -> + let s=Encode.to_string b in + equal (Decode.of_string_exn s) b) ;; diff --git a/tests/core/t_eq.ml b/tests/core/t_eq.ml index 19569565..7e802a0d 100644 --- a/tests/core/t_eq.ml +++ b/tests/core/t_eq.ml @@ -5,4 +5,4 @@ module T = (val Containers_testlib.make ~__FILE__ ()) include T;; q Q.(let p = small_list (pair small_int bool) in pair p p) (fun (l1,l2) -> - CCEqual.(list (pair int bool)) l1 l2 = (l1=l2));; + (list (pair int bool)) l1 l2 = (l1=l2));; diff --git a/tests/core/t_hashtbl.ml b/tests/core/t_hashtbl.ml new file mode 100644 index 00000000..08a2ff0e --- /dev/null +++ b/tests/core/t_hashtbl.ml @@ -0,0 +1,55 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +open CCHashtbl;; + +eq "c" (let tbl = of_list [1,"a"; 2,"b"] in get_or tbl 3 ~default:"c");; +eq "b" (let tbl = of_list [1,"a"; 2,"b"] in get_or tbl 2 ~default:"c");; + +t @@ fun () -> of_list [1,"a"; 2,"b"] |> map_list (fun x y -> string_of_int x ^ y) + |> List.sort Stdlib.compare = ["1a"; "2b"];; + +t @@ fun () -> + let tbl = Hashtbl.create 32 in + update tbl ~f:(fun _ _ -> Some "1") ~k:1; + assert_equal (Some "1") (get tbl 1); + update tbl ~f:(fun _ v->match v with Some _ -> assert false | None -> Some "2") ~k:2; + assert_equal (Some "2") (get tbl 2); + assert_equal 2 (Hashtbl.length tbl); + update tbl ~f:(fun _ _ -> None) ~k:1; + assert_equal None (get tbl 1); + true +;; + +t @@ fun () -> + let tbl = Hashtbl.create 32 in + let v1 = get_or_add tbl ~f:(fun _ -> "1") ~k:1 in + assert_equal "1" v1; + assert_equal (Some "1") (get tbl 1); + let v2 = get_or_add tbl ~f:(fun _ ->"2") ~k:2 in + assert_equal "2" v2; + assert_equal (Some "2") (get tbl 2); + assert_equal "2" (get_or_add tbl ~f:(fun _ -> assert false) ~k:2); + assert_equal 2 (Hashtbl.length tbl); + true +;; + +module TI = Make(CCInt);; + +eq "c" (let tbl = TI.of_list [1,"a"; 2,"b"] in TI.get_or tbl 3 ~default:"c");; +eq "b" (let tbl = TI.of_list [1,"a"; 2,"b"] in TI.get_or tbl 2 ~default:"c");; + +t @@ fun () -> + let tbl = TI.create 32 in + TI.incr tbl 1 ; + TI.incr tbl 2; + TI.incr tbl 1; + assert_equal 2 (TI.find tbl 1); + assert_equal 1 (TI.find tbl 2); + assert_equal 2 (TI.length tbl); + TI.decr tbl 2; + assert_equal 0 (TI.get_or tbl 2 ~default:0); + assert_equal 1 (TI.length tbl); + assert(not (TI.mem tbl 2)); + true;; diff --git a/tests/core/t_heap.ml b/tests/core/t_heap.ml new file mode 100644 index 00000000..cc908f4e --- /dev/null +++ b/tests/core/t_heap.ml @@ -0,0 +1,87 @@ + +open CCHeap + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +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 = H.to_list_sorted;; + +t @@ fun () -> + let h = H.of_list [5;3;4;1;42;0] in + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 0 x; + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 1 x; + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 3 x; + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 4 x; + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 5 x; + let h, x = H.take_exn h in + assert_equal ~printer:string_of_int 42 x; + assert_raises (function H.Empty ->true| _ -> false)(fun () -> H.take_exn h); + true;; + +q ~count:30 + Q.(list_of_size Gen.(return 1_000) int) (fun l -> + (* put elements into a heap *) + let h = H.of_iter (Iter.of_list l) in + assert_equal 1_000 (H.size h); + let l' = extract_list h in + is_sorted l' + ) +;; + +(* test filter *) +q ~count:30 + Q.(list_of_size Gen.(return 1_000) int) (fun l -> + (* put elements into a heap *) + let h = H.of_iter (Iter.of_list l) in + let h = H.filter (fun x->x mod 2=0) h in + assert + (H.to_iter h |> Iter.for_all (fun x -> x mod 2 = 0)); + let l' = extract_list h in + is_sorted l' + );; + +q Q.(list_of_size Gen.(return 1_000) int) (fun l -> + (* put elements into a heap *) + let h = H.of_iter (Iter.of_list l) in + let l' = H.to_iter_sorted h |> Iter.to_list in + is_sorted l' +) ;; + +q Q.(list int) (fun l -> + extract_list (H.of_list l) = + extract_list (H.of_gen (CCList.to_gen l))) ;; +q Q.(list int) (fun l -> + let h = H.of_list l in + (H.to_gen h |> CCList.of_gen |> List.sort Stdlib.compare) + = (H.to_list h |> List.sort Stdlib.compare)) ;; + +q Q.(list int) (fun l -> + let h = H.of_list l in + (H.to_string string_of_int h) + = (List.sort Stdlib.compare l |> List.map string_of_int |> String.concat ","));; +q Q.(list int) (fun l -> + let h = H.of_list l in + (H.to_string ~sep:" " string_of_int h) + = (List.sort Stdlib.compare l |> List.map string_of_int |> String.concat " "));; + +q Q.(list_of_size Gen.(return 1_000) int) (fun l -> + let module H' = Make_from_compare(CCInt) in + let h = H'.of_list l in + let l' = H'.to_list_sorted h in + is_sorted l' +);; diff --git a/tests/core/t_int.ml b/tests/core/t_int.ml new file mode 100644 index 00000000..0310f337 --- /dev/null +++ b/tests/core/t_int.ml @@ -0,0 +1,132 @@ + +open CCInt + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + + +eq ~printer:Q.Print.(list int) [0;1;2;3;4;5] (range 0 5 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0] (range 0 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [5;4;3;2] (range 5 2 |> Iter.to_list);; + + +eq ~printer:Q.Print.(list int) [] (range' 0 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0;1;2;3;4] (range' 0 5 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [5;4;3] (range' 5 2 |> Iter.to_list);; + +t @@ fun () -> pow 2 10 = 1024;; +t @@ fun () -> pow 2 15 = 32768;; +t @@ fun () -> pow 10 5 = 100000;; +t @@ fun () -> pow 1 0 = 1;; +t @@ fun () -> pow 0 1 = 0;; + +t @@ fun () -> (floor_div 3 5 = 0);; +t @@ fun () -> (floor_div 5 5 = 1);; +t @@ fun () -> (floor_div 20 5 = 4);; +t @@ fun () -> (floor_div 12 5 = 2);; +t @@ fun () -> (floor_div 0 5 = 0);; +t @@ fun () -> (floor_div (-1) 5 = -1);; +t @@ fun () -> (floor_div (-5) 5 = -1);; +t @@ fun () -> (floor_div (-12) 5 = -3);; +t @@ fun () -> (floor_div 0 (-5) = 0);; +t @@ fun () -> (floor_div 3 (-5) = -1);; +t @@ fun () -> (floor_div 5 (-5) = -1);; +t @@ fun () -> (floor_div 9 (-5) = -2);; +t @@ fun () -> (floor_div 20 (-5) = -4);; +t @@ fun () -> (floor_div (-2) (-5) = 0);; +t @@ fun () -> (floor_div (-8) (-5) = 1);; +t @@ fun () -> (floor_div (-35) (-5) = 7);; +t @@ fun () -> try ignore (floor_div 12 0); false with Division_by_zero -> true;; +t @@ fun () -> try ignore (floor_div (-12) 0); false with Division_by_zero -> true;; + +q (Q.pair Q.small_signed_int Q.pos_int) + (fun (n, m) -> floor_div n m = int_of_float @@ floor (float n /. float m));; +q (Q.pair Q.small_signed_int Q.pos_int) + (fun (n, m) -> floor_div n (-m) = int_of_float @@ floor (float n /. float (-m)));; + +t @@ fun () -> (rem 3 5 = 3);; +t @@ fun () -> (rem 5 5 = 0);; +t @@ fun () -> (rem 9 5 = 4);; +t @@ fun () -> (rem (-1) 5 = 4);; +t @@ fun () -> (rem (-5) 5 = 0);; +t @@ fun () -> (rem (-20) 5 = 0);; +t @@ fun () -> (rem (-9) 5 = 1);; +t @@ fun () -> (rem 0 5 = 0);; +t @@ fun () -> (rem 0 (-5) = 0);; +t @@ fun () -> (rem 3 (-5) = -2);; +t @@ fun () -> (rem 5 (-5) = 0);; +t @@ fun () -> (rem 9 (-5) = -1);; +t @@ fun () -> (rem (-2) (-5) = -2);; +t @@ fun () -> (rem (-8) (-5) = -3);; +t @@ fun () -> (rem (-35) (-5) = 0);; +t @@ fun () -> try ignore (rem 12 0); false with Division_by_zero -> true;; +t @@ fun () -> try ignore (rem (-12) 0); false with Division_by_zero -> true;; + +q (Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n m in y >= 0 && y < m);; +q (Q.pair Q.int Q.pos_int) (fun (n, m) -> let y = rem n (-m) in y > (-m) && y <= 0);; +q (Q.pair Q.int Q.pos_int) (fun (n, m) -> n = m * floor_div n m + rem n m);; +q (Q.pair Q.int Q.pos_int) (fun (n, m) -> n = (-m) * floor_div n (-m) + rem n (-m));; + +eq None (of_string "moo");; +eq (Some 42) (of_string "42");; + +eq 1 (of_float 1.2);; + + +eq ~printer:CCFun.id "0b111" (to_string_binary 7);; +eq ~printer:CCFun.id "-0b111" (to_string_binary (-7));; +eq ~printer:CCFun.id "0b0" (to_string_binary 0);; + +q ~count:10_000 + Q.int (fun n -> n = int_of_string (to_string_binary n));; + +(* note: the last test checks that no error occurs due to overflows. *) + +eq ~printer:Q.Print.(list int) [0] (range_by ~step:1 0 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [] (range_by ~step:1 5 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [] (range_by ~step:2 1 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0;2;4] (range_by ~step:2 0 4 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0;2;4] (range_by ~step:2 0 5 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0] (range_by ~step:~-1 0 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [] (range_by ~step:~-1 0 5 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [] (range_by ~step:~-2 0 1 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [5;3;1] (range_by ~step:~-2 5 1 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [5;3;1] (range_by ~step:~-2 5 0 |> Iter.to_list);; +eq ~printer:Q.Print.(list int) [0] (range_by ~step:max_int 0 2 |> Iter.to_list);; + +q Q.(pair small_int small_int) (fun (i,j) -> + let i = min i j and j = max i j in + CCList.equal CCInt.equal + (CCInt.range_by ~step:1 i j |> Iter.to_list) + (CCInt.range i j |> Iter.to_list) );; + +eq 0 (popcount 0);; +eq 1 (popcount 1);; +eq (Sys.word_size-2) (popcount max_int);; +eq 1 (popcount min_int);; +eq 10 (popcount 0b1110010110110001010);; +eq 5 (popcount 0b1101110000000000);; + +let simple_popcnt i = + let rec loop n i = + if i=0 then n + else if i land 0b1 = 1 then loop (n+1) (i lsr 1) + else loop n (i lsr 1) + in + loop 0 i ;; + +eq 0 (simple_popcnt 0);; +eq 1 (simple_popcnt 1);; +eq (Sys.word_size-2) (simple_popcnt max_int);; +eq 1 (simple_popcnt min_int);; +eq 5 (simple_popcnt 0b1101110000000000);; + +q ~count:3_000 ~long_factor:10 + Q.(let g = int in + set_gen (Gen.graft_corners g.gen [min_int; max_int; 0; -1; 1] ()) g) + (fun i -> + if simple_popcnt i <> popcount i then ( + Q.Test.fail_reportf "on %d: simple-popcount=%d, popcount=%d" + i (simple_popcnt i) (popcount i) + ); + true);; diff --git a/tests/core/t_int32.ml b/tests/core/t_int32.ml new file mode 100644 index 00000000..3f5cb40d --- /dev/null +++ b/tests/core/t_int32.ml @@ -0,0 +1,66 @@ + +open CCInt32 + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +t @@ fun () -> pow 2l 10l = 1024l;; +t @@ fun () -> pow 2l 15l = 32768l;; +t @@ fun () -> pow 10l 5l = 100000l;; +t @@ fun () -> pow 42l 0l = 1l;; +t @@ fun () -> pow 0l 1l = 0l;; +t @@ fun () -> (floor_div 3l 5l = 0l);; +t @@ fun () -> (floor_div 5l 5l = 1l);; +t @@ fun () -> (floor_div 20l 5l = 4l);; +t @@ fun () -> (floor_div 12l 5l = 2l);; +t @@ fun () -> (floor_div 0l 5l = 0l);; +t @@ fun () -> (floor_div (-1l) 5l = -1l);; +t @@ fun () -> (floor_div (-5l) 5l = -1l);; +t @@ fun () -> (floor_div (-12l) 5l = -3l);; +t @@ fun () -> (floor_div 0l (-5l) = 0l);; +t @@ fun () -> (floor_div 3l (-5l) = -1l);; +t @@ fun () -> (floor_div 5l (-5l) = -1l);; +t @@ fun () -> (floor_div 9l (-5l) = -2l);; +t @@ fun () -> (floor_div 20l (-5l) = -4l);; +t @@ fun () -> (floor_div (-2l) (-5l) = 0l);; +t @@ fun () -> (floor_div (-8l) (-5l) = 1l);; +t @@ fun () -> (floor_div (-35l) (-5l) = 7l);; +t @@ fun () -> try ignore (floor_div 12l 0l); false with Division_by_zero -> true;; +t @@ fun () -> try ignore (floor_div (-12l) 0l); false with Division_by_zero -> true;; + +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1l in + floor_div n m = of_float @@ floor (to_float n /. to_float m));; +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1l in + floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)));; + +let eq' = eq ~printer:Q.Print.(list to_string);; +eq' [0l;1l;2l;3l;4l;5l] (range 0l 5l |> Iter.to_list);; +eq' [0l] (range 0l 0l |> Iter.to_list);; +eq' [5l;4l;3l;2l] (range 5l 2l |> Iter.to_list);; + +(* note: the last test checks that no error occurs due to overflows. *) +let eq'= eq~printer:Q.Print.(list to_string);; +eq' [0l] (range_by ~step:1l 0l 0l |> Iter.to_list);; +eq' [] (range_by ~step:1l 5l 0l |> Iter.to_list);; +eq' [] (range_by ~step:2l 1l 0l |> Iter.to_list);; +eq' [0l;2l;4l] (range_by ~step:2l 0l 4l |> Iter.to_list);; +eq' [0l;2l;4l] (range_by ~step:2l 0l 5l |> Iter.to_list);; +eq' [0l] (range_by ~step:(neg 1l) 0l 0l |> Iter.to_list);; +eq' [] (range_by ~step:(neg 1l) 0l 5l |> Iter.to_list);; +eq' [] (range_by ~step:(neg 2l) 0l 1l |> Iter.to_list);; +eq' [5l;3l;1l] (range_by ~step:(neg 2l) 5l 1l |> Iter.to_list);; +eq' [5l;3l;1l] (range_by ~step:(neg 2l) 5l 0l |> Iter.to_list);; +eq' [0l] (range_by ~step:max_int 0l 2l |> Iter.to_list);; + +q Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> + let i = min i j and j = max i j in + CCList.equal CCInt32.equal + (CCInt32.range_by ~step:1l i j |> Iter.to_list) + (CCInt32.range i j |> Iter.to_list) );; + +eq ~printer:CCFun.id "0b111" (to_string_binary 7l);; +eq ~printer:CCFun.id "-0b111" (to_string_binary (-7l));; +eq ~printer:CCFun.id "0b0" (to_string_binary 0l);; + diff --git a/tests/core/t_int64.ml b/tests/core/t_int64.ml new file mode 100644 index 00000000..9fab16d7 --- /dev/null +++ b/tests/core/t_int64.ml @@ -0,0 +1,65 @@ + +open CCInt64 + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +t @@ fun () -> pow 2L 10L = 1024L;; +t @@ fun () -> pow 2L 15L = 32768L;; +t @@ fun () -> pow 10L 5L = 100000L;; +t @@ fun () -> pow 42L 0L = 1L;; +t @@ fun () -> pow 0L 1L = 0L;; +t @@ fun () -> (floor_div 3L 5L = 0L);; +t @@ fun () -> (floor_div 5L 5L = 1L);; +t @@ fun () -> (floor_div 20L 5L = 4L);; +t @@ fun () -> (floor_div 12L 5L = 2L);; +t @@ fun () -> (floor_div 0L 5L = 0L);; +t @@ fun () -> (floor_div (-1L) 5L = -1L);; +t @@ fun () -> (floor_div (-5L) 5L = -1L);; +t @@ fun () -> (floor_div (-12L) 5L = -3L);; +t @@ fun () -> (floor_div 0L (-5L) = 0L);; +t @@ fun () -> (floor_div 3L (-5L) = -1L);; +t @@ fun () -> (floor_div 5L (-5L) = -1L);; +t @@ fun () -> (floor_div 9L (-5L) = -2L);; +t @@ fun () -> (floor_div 20L (-5L) = -4L);; +t @@ fun () -> (floor_div (-2L) (-5L) = 0L);; +t @@ fun () -> (floor_div (-8L) (-5L) = 1L);; +t @@ fun () -> (floor_div (-35L) (-5L) = 7L);; +t @@ fun () -> try ignore (floor_div 12L 0L); false with Division_by_zero -> true;; +t @@ fun () -> try ignore (floor_div (-12L) 0L); false with Division_by_zero -> true;; + +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1L in + floor_div n m = of_float @@ floor (to_float n /. to_float m));; +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1L in + floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)));; + + +eq ~printer:Q.Print.(list to_string) [0L;1L;2L;3L;4L;5L] (range 0L 5L |> Iter.to_list);; +eq ~printer:Q.Print.(list to_string) [0L] (range 0L 0L |> Iter.to_list);; +eq ~printer:Q.Print.(list to_string) [5L;4L;3L;2L] (range 5L 2L |> Iter.to_list);; + +(* note: the last test checks that no error occurs due to overflows. *) +let eq' = eq ~printer:Q.Print.(list to_string);; +eq' [0L] (range_by ~step:1L 0L 0L |> Iter.to_list);; +eq' [] (range_by ~step:1L 5L 0L |> Iter.to_list);; +eq' [] (range_by ~step:2L 1L 0L |> Iter.to_list);; +eq' [0L;2L;4L] (range_by ~step:2L 0L 4L |> Iter.to_list);; +eq' [0L;2L;4L] (range_by ~step:2L 0L 5L |> Iter.to_list);; +eq' [0L] (range_by ~step:(neg 1L) 0L 0L |> Iter.to_list);; +eq' [] (range_by ~step:(neg 1L) 0L 5L |> Iter.to_list);; +eq' [] (range_by ~step:(neg 2L) 0L 1L |> Iter.to_list);; +eq' [5L;3L;1L] (range_by ~step:(neg 2L) 5L 1L |> Iter.to_list);; +eq' [5L;3L;1L] (range_by ~step:(neg 2L) 5L 0L |> Iter.to_list);; +eq' [0L] (range_by ~step:max_int 0L 2L |> Iter.to_list);; + +q Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> + let i = min i j and j = max i j in + CCList.equal CCInt64.equal + (CCInt64.range_by ~step:1L i j |> Iter.to_list) + (CCInt64.range i j |> Iter.to_list) );; + +eq ~printer:CCFun.id "0b111" (to_string_binary 7L);; +eq ~printer:CCFun.id "-0b111" (to_string_binary (-7L));; +eq ~printer:CCFun.id "0b0" (to_string_binary 0L);; diff --git a/tests/core/t_map.ml b/tests/core/t_map.ml new file mode 100644 index 00000000..fdf8b13f --- /dev/null +++ b/tests/core/t_map.ml @@ -0,0 +1,27 @@ + + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +open CCMap;; + +module M = CCMap.Make(String);; + +let eq' = eq ~printer:CCFormat.(to_string @@ Dump.(list (pair string int)));; +eq' ["a", 1; "b", 20] + (M.of_list ["b", 2; "c", 3] + |> M.update "a" (function _ -> Some 1) + |> M.update "c" (fun _ -> None) + |> M.update "b" (CCOption.map (fun x -> x * 10)) + |> M.to_list |> List.sort CCOrd.poly);; + +module M2 = Make(CCInt);; + +q Q.(list (pair small_int small_int)) M2.(fun l -> + to_list (of_list l) = to_list (of_list_with ~f:(fun _ v _ ->v) l));; +q Q.(list (pair small_int small_int)) M2.(fun l -> + to_list (of_iter @@ Iter.of_list l) = + to_list (of_iter_with ~f:(fun _ v _ ->v) @@ Iter.of_list l));; +q Q.(list (pair small_int small_int)) M2.(fun l -> + to_list (of_seq @@ CCSeq.of_list l) = + to_list (of_seq_with ~f:(fun _ v _ ->v) @@ CCSeq.of_list l));; diff --git a/tests/core/t_nativeint.ml b/tests/core/t_nativeint.ml new file mode 100644 index 00000000..505efcd5 --- /dev/null +++ b/tests/core/t_nativeint.ml @@ -0,0 +1,67 @@ + +open CCNativeint + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + + +t @@ fun () -> pow 2n 10n = 1024n;; +t @@ fun () -> pow 2n 15n = 32768n;; +t @@ fun () -> pow 10n 5n = 100000n;; +t @@ fun () -> pow 42n 0n = 1n;; +t @@ fun () -> pow 0n 1n = 0n;; +t @@ fun () -> (floor_div 3n 5n = 0n);; +t @@ fun () -> (floor_div 5n 5n = 1n);; +t @@ fun () -> (floor_div 20n 5n = 4n);; +t @@ fun () -> (floor_div 12n 5n = 2n);; +t @@ fun () -> (floor_div 0n 5n = 0n);; +t @@ fun () -> (floor_div (-1n) 5n = -1n);; +t @@ fun () -> (floor_div (-5n) 5n = -1n);; +t @@ fun () -> (floor_div (-12n) 5n = -3n);; +t @@ fun () -> (floor_div 0n (-5n) = 0n);; +t @@ fun () -> (floor_div 3n (-5n) = -1n);; +t @@ fun () -> (floor_div 5n (-5n) = -1n);; +t @@ fun () -> (floor_div 9n (-5n) = -2n);; +t @@ fun () -> (floor_div 20n (-5n) = -4n);; +t @@ fun () -> (floor_div (-2n) (-5n) = 0n);; +t @@ fun () -> (floor_div (-8n) (-5n) = 1n);; +t @@ fun () -> (floor_div (-35n) (-5n) = 7n);; +t @@ fun () -> try ignore (floor_div 12n 0n); false with Division_by_zero -> true;; +t @@ fun () -> try ignore (floor_div (-12n) 0n); false with Division_by_zero -> true;; + +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1n in + floor_div n m = of_float @@ floor (to_float n /. to_float m));; +q (Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) + (fun (n, m) -> let m = m + 1n in + floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)));; + +let eq' = eq ~printer:Q.Print.(list to_string);; +eq' [0n;1n;2n;3n;4n;5n] (range 0n 5n |> Iter.to_list);; +eq' [0n] (range 0n 0n |> Iter.to_list);; +eq' [5n;4n;3n;2n] (range 5n 2n |> Iter.to_list);; + +(* note: the last test checks that no error occurs due to overflows. *) +let eq' = eq ~printer:Q.Print.(list to_string);; +eq' [0n] (range_by ~step:1n 0n 0n |> Iter.to_list);; +eq' [] (range_by ~step:1n 5n 0n |> Iter.to_list);; +eq' [] (range_by ~step:2n 1n 0n |> Iter.to_list);; +eq' [0n;2n;4n] (range_by ~step:2n 0n 4n |> Iter.to_list);; +eq' [0n;2n;4n] (range_by ~step:2n 0n 5n |> Iter.to_list);; +eq' [0n] (range_by ~step:(neg 1n) 0n 0n |> Iter.to_list);; +eq' [] (range_by ~step:(neg 1n) 0n 5n |> Iter.to_list);; +eq' [] (range_by ~step:(neg 2n) 0n 1n |> Iter.to_list);; +eq' [5n;3n;1n] (range_by ~step:(neg 2n) 5n 1n |> Iter.to_list);; +eq' [5n;3n;1n] (range_by ~step:(neg 2n) 5n 0n |> Iter.to_list);; +eq' [0n] (range_by ~step:max_int 0n 2n |> Iter.to_list);; + +q Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> + let i = min i j and j = max i j in + CCList.equal CCNativeint.equal + (CCNativeint.range_by ~step:1n i j |> Iter.to_list) + (CCNativeint.range i j |> Iter.to_list) );; + + +eq ~printer:CCFun.id "0b111" (to_string_binary 7n);; +eq ~printer:CCFun.id "-0b111" (to_string_binary (-7n));; +eq ~printer:CCFun.id "0b0" (to_string_binary 0n);; diff --git a/tests/core/t_option.ml b/tests/core/t_option.ml new file mode 100644 index 00000000..60a7d1dd --- /dev/null +++ b/tests/core/t_option.ml @@ -0,0 +1,25 @@ + +open CCOption + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +eq None (filter ((=) 0) (Some 1));; +eq (Some 0) (filter ((=) 0) (Some 0));; +eq None (filter (fun _ -> true) None);; +eq (try get_exn_or "ohno" (None:unit option); false with Invalid_argument s->s= "ohno");; +t @@ fun () -> 123 = get_exn_or "yes" (Some 123);; +t @@ fun () -> sequence_l [None; Some 1; Some 2] = None;; +t @@ fun () -> sequence_l [Some 1; Some 2; Some 3] = Some [1;2;3];; +t @@ fun () -> sequence_l [] = Some [];; +t @@ fun () -> choice_iter (Iter.of_list [None; Some 1; Some 2]) = Some 1;; +t @@ fun () -> choice_iter Iter.empty = None;; +t @@ fun () -> choice_iter (Iter.repeat None |> Iter.take 100) = None;; +t @@ fun () -> choice_seq (CCSeq.of_list [None; Some 1; Some 2]) = Some 1;; +t @@ fun () -> choice_seq CCSeq.empty = None;; +t @@ fun () -> choice_seq (CCSeq.repeat None |> CCSeq.take 100) = None;; +t @@ fun () -> flatten None = None;; +t @@ fun () -> flatten (Some None) = None;; +t @@ fun () -> flatten (Some (Some 1)) = Some 1;; +t @@ fun () -> return_if false 1 = None;; +t @@ fun () -> return_if true 1 = Some 1;; diff --git a/tests/core/t_ord.ml b/tests/core/t_ord.ml new file mode 100644 index 00000000..a3dc64aa --- /dev/null +++ b/tests/core/t_ord.ml @@ -0,0 +1,43 @@ + +open CCOrd + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +t @@ fun () -> equiv 1 2;; +t @@ fun () -> equiv ~-1 ~-10;; +t @@ fun () -> equiv 0 0;; +t @@ fun () -> equiv ~-1 ~-1;; +t @@ fun () -> not (equiv 0 1);; +t @@ fun () -> not (equiv 1 ~-1);; +t @@ fun () -> not (equiv 1 0);; + +q Q.(pair int int) (fun (x,y) -> + (equiv x y) = (equiv y x));; +q Q.(triple int int int) (fun (x,y,z) -> + if (equiv x y && equiv y z) then (equiv x z) else true);; + +t @@ fun () -> bool true false > 0;; +t @@ fun () -> bool false true < 0;; +t @@ fun () -> bool true true = 0;; +t @@ fun () -> bool false false = 0;; + +q Q.(option int) (fun o -> option int None o <= 0);; + +t @@ fun () -> pair int string (1, "b") (2, "a") < 0;; +t @@ fun () -> pair int string (1, "b") (0, "a") > 0;; +t @@ fun () -> pair int string (1, "b") (1, "b") = 0;; +t @@ fun () -> list int [1;2;3] [1;2;3;4] < 0;; +t @@ fun () -> list int [1;2;3;4] [1;2;3] > 0;; +t @@ fun () -> list int [1;2;3;4] [1;3;4] < 0;; + +q Q.(pair (list int)(list int)) CCOrd.(fun (l1,l2) -> + equiv (list int l1 l2) (Stdlib.compare l1 l2));; + +t @@ fun () -> array int [|1;2;3|] [|1;2;3;4|] < 0;; +t @@ fun () -> array int [|1;2;3;4|] [|1;2;3|] > 0;; +t @@ fun () -> array int [|1;2;3;4|] [|1;3;4|] < 0;; + +q + Q.(pair (array int)(array int)) CCOrd.(fun (a1,a2) -> + equiv (array int a1 a2) (list int (Array.to_list a1) (Array.to_list a2)));; diff --git a/tests/core/t_parse.ml b/tests/core/t_parse.ml new file mode 100644 index 00000000..f377bcd7 --- /dev/null +++ b/tests/core/t_parse.ml @@ -0,0 +1,214 @@ + +module Tst = (val Containers_testlib.make ~__FILE__ ()) +include Tst;; + +open CCParse + +module T = struct + type tree = L of int | N of tree * tree +end +open T + +let mk_leaf x = L x +let mk_node x y = N(x,y) + +let ptree = fix @@ fun self -> + skip_space *> + ( (char '(' *> (pure mk_node <*> self <*> self) <* char ')') + <|> + (U.int >|= mk_leaf) ) + +let ptree' = fix_memo @@ fun self -> + skip_space *> + ( (char '(' *> (pure mk_node <*> self <*> self) <* char ')') + <|> + (U.int >|= mk_leaf) ) + +let rec pptree = function + | N (a,b) -> Printf.sprintf "N (%s, %s)" (pptree a) (pptree b) + | L x -> Printf.sprintf "L %d" x + +let errpp pp = function + | Ok x -> "Ok " ^ pp x + | Error s -> "Error " ^ s + +let errpptree = errpp pptree + +let erreq eq x y = match x, y with + | Ok x, Ok y -> eq x y + | Error _ , Error _ -> true + | _ -> false ;; + +(* ### start tests ### *) + +eq ~printer:errpptree (Ok (N (L 1, N (L 2, L 3)))) + (parse_string ptree "(1 (2 3))" );; +eq ~printer:errpptree (Ok (N (N (L 1, L 2), N (L 3, N (L 4, L 5))))) + (parse_string ptree "((1 2) (3 (4 5)))" );; +eq ~printer:errpptree (Ok (N (L 1, N (L 2, L 3)))) + (parse_string ptree' "(1 (2 3))" );; +eq ~printer:errpptree (Ok (N (N (L 1, L 2), N (L 3, N (L 4, L 5))))) + (parse_string ptree' "((1 2) (3 (4 5)))" );; + +t @@ fun () -> + let p = U.list ~sep:"," U.word in + let printer = function + | Ok l -> "Ok " ^ CCFormat.(to_string (Dump.list string_quoted)) l + | Error s -> "Error " ^ s + in + assert_equal ~printer + (Ok ["abc"; "de"; "hello"; "world"]) + (parse_string p "[abc , de, hello ,world ]"); + true;; + +t @@ fun () -> + let test n = + let p = CCParse.(U.list ~sep:"," U.int) in + + let l = CCList.(1 -- n) in + let l_printed = + CCFormat.(to_string (within "[" "]" (list ~sep:(return ",") int))) l in + + let l' = CCParse.parse_string_exn p l_printed in + + assert_equal ~printer:Q.Print.(list int) l l' + in + test 300_000; + true ;; + +t @@ fun () -> + let open CCParse.Infix in + let module P = CCParse in + + let parens p = P.char '(' *> p <* P.char ')' in + let add = P.char '+' *> P.return (+) in + let sub = P.char '-' *> P.return (-) in + let mul = P.char '*' *> P.return ( * ) in + let div = P.char '/' *> P.return ( / ) in + let integer = + P.chars1_if (function '0'..'9'->true|_->false) >|= int_of_string in + + let chainr1 e op = + P.fix (fun r -> + e >>= fun x -> (op <*> P.return x <*> r) <|> P.return x) in + + let expr : int P.t = + P.fix (fun expr -> + let factor = parens expr <|> integer in + let term = chainr1 factor (mul <|> div) in + chainr1 term (add <|> sub)) in + + assert_equal (Ok 6) (P.parse_string expr "4*1+2"); + assert_equal (Ok 12) (P.parse_string expr "4*(1+2)"); + true;; + +let eq' = eq ~printer:(errpp Q.Print.bool) ~cmp:(erreq (=)) ;; +eq' (Ok true) (parse_string (U.bool <* eoi) "true");; +eq' (Error "") (parse_string (U.bool <* eoi) "true ");; +eq' (Ok true) (parse_string (U.bool <* skip_white <* eoi) "true");; + +let eq' = eq ~printer:Q.Print.(pair int int);; +eq' (0,5) (let p = any_char_n 5 *> pos in + match parse_string p "abcde " with + | Ok p -> Position.line_and_column p + | Error _ -> assert false);; + +eq ~printer:Q.Print.(list @@ pair int int) + [(0,2); (1,3); (2,1); (3,0); (4,0); (5,2)] + (let p = each_line (skip_space *> pos) in + match parse_string p " a\n b\nc\n\n\n a" with + | Ok ps -> List.map Position.line_and_column ps + | Error _ -> assert false);; + +let eq' = eq ~printer:(errpp Q.Print.string) ~cmp:(erreq (=));; +eq' (Ok "abcd") (parse_string all_str "abcd");; +eq' (Ok "cd") (parse_string (string "ab" *> all_str) "abcd");; +eq' (Ok "") (parse_string (string "ab" *> all_str) "ab");; + +eq ~printer:(errpp Q.Print.(pair string string)) ~cmp:(erreq (=)) + (Ok ("foobar", "")) (parse_string (both all_str all_str) "foobar");; + +q Q.(printable_string) (fun s -> + let pred = (function 'a'..'z' | 'A' .. 'Z' | '{' | '}' -> true | _ -> false) in + let p1 = chars1_if pred in + let p2 = take1_if pred >|= Slice.to_string in + parse_string p1 s = parse_string p2 s);; + +t @@ fun () -> + let pred = (function 'a'..'z' | 'A' .. 'Z' | '{' | '}' -> true | _ -> false) in + parse_string (chars_if pred) "coucou{lol} 123" = Ok "coucou{lol}" ;; + +t @@ fun () -> + let p0 = skip_white *> U.int in + let p = (skip_white *> char '(' *> many p0) <* (skip_white <* char ')') in + let printer = CCFormat.(to_string @@ Dump.result @@ Dump.list int) in + assert_equal ~printer + (Ok [1;2;3]) (parse_string p "(1 2 3)"); + assert_equal ~printer + (Ok [1;2; -30; 4]) (parse_string p "( 1 2 -30 4 )"); + true;; + +let aword = chars1_if (function 'a'..'z'|'A'..'Z'->true|_ -> false);; + +eq ~printer:(errpp Q.Print.(list string)) + (Ok ["a";"b";"c"]) + (parse_string (optional (char '/') *> sep ~by:(char '/') aword) "/a/b/c");; +eq ~printer:(errpp Q.Print.(list string)) + (Ok ["a";"b";"c"]) + (parse_string (optional (char '/') *> sep ~by:(char '/') aword) "a/b/c");; + +eq ~printer:(errpp Q.Print.(string)) + (Ok "abc") (parse_string (lookahead (string "ab") *> (string "abc")) "abcd");; + +eq ~printer:(errpp Q.Print.(string)) + (Ok "1234") (parse_string line_str "1234\nyolo");; + +eq ~printer:(errpp Q.Print.(pair String.escaped String.escaped)) + (Ok ("1234", "yolo")) (parse_string (line_str ||| line_str) "1234\nyolo\nswag");; + +eq ~printer:(errpp Q.Print.(list string)) ~cmp:(erreq (=)) + (Ok ["a";"b";"c";"d,e,f"]) + (parse_string (split_list_at_most ~on_char:',' 3 >|= List.map Slice.to_string) "a,b,c,d,e,f");; +eq ~printer:(errpp Q.Print.(list string)) ~cmp:(erreq (=)) + (Ok ["a";"bc"]) + (parse_string (split_list_at_most ~on_char:',' 3 >|= List.map Slice.to_string) "a,bc");; + +eq ~printer:(errpp Q.Print.(list @@ list int)) + (Ok ([[1;1];[2;2];[3;3];[]])) + (parse_string (each_line (sep ~by:skip_space U.int)) "1 1\n2 2\n3 3\n");; + +let eq' = eq ~printer:(errpp Q.Print.int) ~cmp:(erreq (=)) ;; +eq' (Ok 42) (parse_string U.int " 42");; +eq' (Ok 2) (parse_string U.int "2");; +eq' (Error "") (parse_string U.int "abc");; +eq' (Error "") (parse_string U.int "");; + +let eq' = eq ~printer:(errpp Q.Print.int) ~cmp:(erreq (=));; +eq' (Ok 15) (parse_string (U.in_paren (U.in_paren U.int)) "( ( 15) )");; +eq' (Ok 2) (parse_string (U.in_paren U.int) "(2)");; +eq' (Error "") (parse_string (U.in_paren U.int) "2");; +eq' (Error "") (parse_string (U.in_paren U.int) "");; +eq' (Ok 2) (parse_string (U.in_parens_opt U.int) "((((2))))");; +eq' (Ok 2) (parse_string (U.in_parens_opt U.int) "2");; +eq' (Ok 200) (parse_string (U.in_parens_opt U.int) "( ( 200 ) )");; + +let eq' = eq ~printer:(errpp Q.Print.(option int)) ~cmp:(erreq (=));; +eq' (Ok (Some 12)) (parse_string U.(option int) " Some 12");; +eq' (Ok None) (parse_string U.(option int) " None");; +eq' (Ok (Some 0)) (parse_string U.(option int) "Some 0");; +eq' (Ok (Some 0)) (parse_string U.(in_parens_opt @@ option int) "(( Some 0) )");; + +let eq' = eq ~printer:(errpp Q.Print.int) ~cmp:(erreq (=)) ;; +eq' (Ok 16) (parse_string U.hexa_int "0x10");; +eq' (Ok 16) (parse_string U.hexa_int "10");; +eq' (Error "") (parse_string U.hexa_int "x10");; +eq' (Error "") (parse_string U.hexa_int "0xz");; + +eq ~printer:(errpp Q.Print.bool) ~cmp:(erreq (=)) + (Ok true) (parse_string U.bool "true");; +eq ~printer:(errpp Q.Print.bool) ~cmp:(erreq (=)) + (Ok false) (parse_string U.bool "false");; + +eq ~printer:Q.Print.(errpp (pair int int)) + (Ok(1,2)) U.(parse_string (pair int int) "(1 , 2 )");; + diff --git a/tests/core/t_random.ml b/tests/core/t_random.ml new file mode 100644 index 00000000..591906e9 --- /dev/null +++ b/tests/core/t_random.ml @@ -0,0 +1,19 @@ + +open CCRandom + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + + +q Q.(list small_int) (fun l -> + l=[] || List.mem (run (pick_list l)) l);; + +q Q.(pair small_int small_int) (fun (i,j) -> + let len, n = 2+min i j, max i j in + let l = QCheck.Gen.generate1 (split_list n ~len) in + match l with None -> true | Some l -> l<> [] && List.for_all (fun x->x>0) l);; + +t @@ fun () -> + let open Containers in + ignore (List.random_choose [1;2;3] (Random.get_state()) : int); + true;; diff --git a/tests/core/t_result.ml b/tests/core/t_result.ml new file mode 100644 index 00000000..313b3b0b --- /dev/null +++ b/tests/core/t_result.ml @@ -0,0 +1,32 @@ + +open CCResult + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +t @@ fun () -> (Error "ohno 42") = (fail_printf "ohno %d" 42);; +t @@ fun () -> (Error "ohno 42") = (fail_fprintf "ohno %d" 42);; + +eq (Error "error\ncontext:message(number 42, foo: true)") + (add_ctxf "message(number %d, foo: %B)" 42 true (Error "error"));; + +t @@ fun () -> + let called_with = ref None in + let f e = called_with := Some e in + iter_err f (Ok 1); + assert (!called_with = None); + iter_err f (Error 1); + assert (!called_with = Some 1); + true ;; + +t @@ fun () -> get_or_failwith (Ok 1) = 1;; +t @@ fun () -> try ignore @@ get_or_failwith (Error "e"); false with Failure msg -> msg = "e";; + +eq (get_lazy (fun _ -> 2) (Ok 1)) (1);; +eq (get_lazy (fun _ -> 2) (Error "error")) (2);; + +eq 42 (fold_ok (+) 2 (Ok 40));; +eq 40 (fold_ok (+) 40 (Error "foo"));; +eq (Ok []) (flatten_l []);; +eq (Ok [1;2;3]) (flatten_l [Ok 1; Ok 2; Ok 3]);; +eq (Error "ohno") (flatten_l [Ok 1; Error "ohno"; Ok 2; Ok 3; Error "wut"]);; diff --git a/tests/core/t_seq.ml b/tests/core/t_seq.ml new file mode 100644 index 00000000..2ab9e1c4 --- /dev/null +++ b/tests/core/t_seq.ml @@ -0,0 +1,88 @@ + +open CCSeq + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +t @@ fun () -> repeat ~n:4 0 |> to_list = [0;0;0;0];; +t @@ fun () -> repeat ~n:0 1 |> to_list = [];; +t @@ fun () -> repeat 1 |> take 20 |> to_list = (repeat ~n:20 1 |> to_list);; +t @@ fun () -> of_list [1;2;3;4] |> take_while (fun x->x < 4) |> to_list = [1;2;3];; + +q (Q.pair (Q.list Q.small_int) Q.small_int) (fun (l,n) -> + let s = of_list l in let s1, s2 = take n s, drop n s in + append s1 s2 |> to_list = l );; + +t @@ fun () -> (map ((+) 1) (1 -- 5) |> to_list) = (2 -- 6 |> to_list);; +t @@ fun () -> mapi (fun i x -> i,x) (1 -- 3) |> to_list = [0, 1; 1, 2; 2, 3];; +t @@ fun () -> fmap (fun x -> if x mod 2=0 then Some (x*3) else None) (1--10) |> to_list + = [6;12;18;24;30];; + +t @@ fun () -> cycle (of_list [1;2]) |> take 5 |> to_list = [1;2;1;2;1];; +t @@ fun () -> cycle (of_list [1; ~-1]) |> take 100_000 |> fold (+) 0 = 0;; +t @@ fun () -> let f = function 10 -> None | x -> Some (x, x+1) in + unfold f 0 |> to_list = [0;1;2;3;4;5;6;7;8;9];; +t @@ fun () -> for_all ((=) 1) (of_list []) = true;; +t @@ fun () -> for_all ((=) 1) (of_list [0]) = false;; +t @@ fun () -> for_all ((=) 1) (of_list [1]) = true;; +t @@ fun () -> for_all ((=) 1) (of_list [1; 0]) = false;; +t @@ fun () -> for_all ((=) 1) (of_list [0; 1]) = false;; +t @@ fun () -> for_all ((=) 1) (of_list [1; 1]) = true;; +t @@ fun () -> let l () = Cons (0, fun () -> failwith "no second element") in + try ignore (for_all ((=) 1) l); true with Failure _ -> false;; +t @@ fun () -> exists ((=) 1) (of_list []) = false;; +t @@ fun () -> exists ((=) 1) (of_list [0]) = false;; +t @@ fun () -> exists ((=) 1) (of_list [1]) = true;; +t @@ fun () -> exists ((=) 1) (of_list [1; 0]) = true;; +t @@ fun () -> exists ((=) 1) (of_list [0; 1]) = true;; +t @@ fun () -> exists ((=) 1) (of_list [0; 0]) = false;; +t @@ fun () -> let l () = Cons (1, fun () -> failwith "no second element") in + try ignore (exists ((=) 1) l); true with Failure _ -> false;; +t @@ fun () -> of_list [1;1;1;2;2;3;3;1] |> group (=) + |> map to_list |> to_list = [[1;1;1]; [2;2]; [3;3]; [1]];; +t @@ fun () -> range 0 5 |> to_list = [0;1;2;3;4;5];; +t @@ fun () -> range 0 0 |> to_list = [0];; +t @@ fun () -> range 5 2 |> to_list = [5;4;3;2];; +t @@ fun () -> 1 --^ 5 |> to_list = [1;2;3;4];; +t @@ fun () -> 5 --^ 1 |> to_list = [5;4;3;2];; +t @@ fun () -> 1 --^ 2 |> to_list = [1];; +t @@ fun () -> 0 --^ 0 |> to_list = [];; + +q Q.(list (pair int int)) (fun l -> + let l = of_list l in let a, b = unzip l in equal (=) l (zip a b));; + +eq [0,'a'; 1, 'b'; 2, 'c'] (of_string "abcde" |> zip_i |> take 3 |> to_list);; + +q Q.(array int) (fun a -> of_array a |> to_array = a);; + +t @@ fun () -> of_array [| 1; 2; 3 |] |> to_list = [1;2;3];; +t @@ fun () -> of_list [1;2;3] |> to_array = [| 1; 2; 3; |];; +t @@ fun () -> + let r = ref 1 in + let s = unfold (fun i -> if i < 3 then let x = !r in incr r; Some (x, succ i) else None) 0 in + to_array s = [| 1; 2; 3; |];; + +t @@ fun () -> + let g = let n = ref 0 in fun () -> Some (incr n; !n) in + let l = of_gen g in + assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list); + assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list); + assert_equal [11;12] (drop 10 l |> take 2 |> to_list); + true;; + +t @@ fun () -> + let printer = Q.Print.(list int) in + let gen () = + let rec l = let r = ref 0 in fun () -> incr r; Cons (!r, l) in l + in + let l1 = gen () in + assert_equal ~printer [1;2;3;4] (take 4 l1 |> to_list); + assert_equal ~printer [5;6;7;8] (take 4 l1 |> to_list); + let l2 = gen () |> memoize in + assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); + assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); + true;; + +t @@ fun () -> interleave (of_list [1;3;5]) (of_list [2;4;6]) |> to_list = [1;2;3;4;5;6];; +t @@ fun () -> fair_app (of_list [(+)1; ( * ) 3]) (of_list [1; 10]) + |> to_list |> List.sort Stdlib.compare = [2; 3; 11; 30];; diff --git a/tests/core/t_set.ml b/tests/core/t_set.ml new file mode 100644 index 00000000..4bfa330d --- /dev/null +++ b/tests/core/t_set.ml @@ -0,0 +1,22 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +module S = CCSet.Make(struct + type t = int + let compare x y = Stdlib.compare x y +end);; + +eq ~printer:(fun s -> s) + (S.to_string string_of_int (S.of_list [4; 3])) "3,4";; + +q Q.(list int) (fun l -> + let s = S.of_list l in + (S.to_string string_of_int s) + = (CCList.sort_uniq ~cmp:CCInt.compare l + |> List.map string_of_int |> String.concat ","));; +q Q.(list int) (fun l -> + let s = S.of_list l in + (S.to_string ~sep:" " string_of_int s) + = (CCList.sort_uniq ~cmp:CCInt.compare l + |> List.map string_of_int |> String.concat " "));; diff --git a/tests/core/t_sexp.ml b/tests/core/t_sexp.ml new file mode 100644 index 00000000..f0004b43 --- /dev/null +++ b/tests/core/t_sexp.ml @@ -0,0 +1,80 @@ + +open CCSexp + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + + +t @@ fun () -> CCResult.to_opt (parse_string "(abc d/e/f \"hello \\\" () world\" )") <> None;; +t @@ fun () -> CCResult.to_opt (parse_string "(abc ( d e ffff ) \"hello/world\")") <> None;; +t @@ fun () -> CCResult.to_opt (parse_string "\"\123\bcoucou\"") <> None;; + +let eq' = eq ~printer:(function Ok x -> to_string x | Error e -> "error " ^ e);; +eq' (parse_string "(a b)") (Ok (`List [`Atom "a"; `Atom "b"]));; +eq' (parse_string "(a\n ;coucou\n b)") (Ok (`List [`Atom "a"; `Atom "b"]));; +eq' (parse_string "(a #; (foo bar\n (1 2 3)) b)") (Ok (`List [`Atom "a"; `Atom "b"]));; +eq' (parse_string "#; (a b) (c d)") (Ok (`List [`Atom "c"; `Atom "d"]));; +eq' (parse_string "#; (a b) 1") (Ok (`Atom "1"));; + +let eq' = eq ~printer:(function Ok x -> String.concat ";" @@ List.map to_string x | Error e -> "error " ^ e) ;; +eq' (parse_string_list "(a b)(c)") (Ok [`List [`Atom "a"; `Atom "b"]; `List [`Atom "c"]]);; +eq' (parse_string_list " ") (Ok []);; +eq' (parse_string_list "(a\n ;coucou\n b)") (Ok [`List [`Atom "a"; `Atom "b"]]);; +eq' (parse_string_list "#; (a b) (c d) e ") (Ok [`List [`Atom "c"; `Atom "d"]; `Atom "e"]);; +eq' (parse_string_list "#; (a b) 1") (Ok [`Atom "1"]);; + +let sexp_bijective s = to_string s |> parse_string = Ok s;; + +eq ~printer:CCFormat.(to_string (Dump.result pp)) + (Ok (`List [`Atom ""])) (parse_string "(\"\")");; + +t @@ fun () -> sexp_bijective (`List [`Atom ""]);; + +let sexp_gen = + let mkatom a = `Atom a and mklist l = `List l in + let atom = Q.Gen.(map mkatom (string_size ~gen:printable (1 -- 30))) in + let gen = Q.Gen.( + sized (fix + (fun self n st -> match n with + | 0 -> atom st + | _ -> + frequency + [ 1, atom + ; 2, map mklist (list_size (0 -- 10) (self (n/10))) + ] st + ) + )) in + let rec small = function + | `Atom s -> String.length s + | `List l -> List.fold_left (fun n x->n+small x) 0 l + and print = function + | `Atom s -> Printf.sprintf "`Atom \"%s\"" s + | `List l -> "`List " ^ Q.Print.list print l + and shrink = function + | `Atom s -> Q.Iter.map mkatom (Q.Shrink.string s) + | `List l -> Q.Iter.map mklist (Q.Shrink.list ~shrink l) + in + Q.make ~print ~small ~shrink gen;; + +q ~count:100 sexp_gen sexp_bijective;; + +(* regression for #338 *) +t @@ fun () -> + Printexc.record_backtrace true; + let cases = [ + "\"\\256\""; + "\"\\722\02622222\\\\\n\r<\\\\\\\\\"\\222222222\\\\\"\"\2032!2222\\\\\"\""; + "\"\n\r<\\t\023\n\203\\622222222\\\\\"\"\2032!2222\\\\\"\""; + "\"\n\r<@t\023\n\203\\2222D2\n\r22222\01622222222222222222222222\203\\292242\222 2\\\\\">K2"; + "\"\n\r<\\t\023\n\203\\272222222\\\\\"\"\2032\0042222\\\\\"\""; + "\"\023\n\203\\5222\n\r<\\t\023\n\203\\52222222\\\\\"2\\\216\216\216\216\216\\\\\"\216\216\216\216\216\216\216\216\216222222222222222\147"; + "\"\\722\02622222\\\\\n\r<\\\\\\\\\"\\222222222\\\\\"\"\2032!2222\\\\\"\""; + ] in + cases + |> List.iter (fun s -> + try ignore (parse_string s); + with e -> + let st = Printexc.get_backtrace() in + print_endline @@ Printexc.to_string e ^ "\n" ^ st; + assert false); + true;; diff --git a/tests/core/t_string.ml b/tests/core/t_string.ml new file mode 100644 index 00000000..71a1f35e --- /dev/null +++ b/tests/core/t_string.ml @@ -0,0 +1,264 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +open CCString;; + +open CCShims_.Stdlib;; + +q Q.printable_string (fun s -> s = rev (rev s));; +q Q.printable_string (fun s -> length s = length (rev s));; +q Q.printable_string (fun s -> rev s = (to_list s |> List.rev |> of_list));; + + +eq "abc" (rev "cba");; +eq "" (rev "");; +eq " " (rev " ");; + +let eq' = eq ~printer:string_of_int;; +eq' 1 (find ~sub:"bc" "abcd");; +eq' ~-1 (find ~sub:"bc" "abd");; +eq' 1 (find ~sub:"a" "_a_a_a_");; +eq' 6 (find ~start:5 ~sub:"a" "a1a234a");; + +q ~count:10_000 + Q.(pair printable_string printable_string) (fun (s1,s2) -> + let i = find ~sub:s2 s1 in + i < 0 || String.sub s1 i (length s2) = s2);; + +let eq' = eq ~printer:Q.Print.(list int);; +eq' [1; 6] (find_all_l ~sub:"bc" "abc aabc aab");; +eq' [] (find_all_l ~sub:"bc" "abd");; +eq' [76] (find_all_l ~sub:"aaaaaa" + "aabbaabbaaaaabbbbabababababbbbabbbabbaaababbbaaabaabbaabbaaaabbababaaaabbaabaaaaaabbbaaaabababaabaaabbaabaaaabbababbaabbaaabaabbabababbbaabababaaabaaababbbaaaabbbaabaaababbabaababbaabbaaaaabababbabaababbbaaabbabbabababaaaabaaababaaaaabbabbaabbabbbbbbbbbbbbbbaabbabbbbbabbaaabbabbbbabaaaaabbababbbaaaa");; + +t @@ fun () -> mem ~sub:"bc" "abcd";; +t @@ fun () -> not (mem ~sub:"a b" "abcd");; + +let eq' = eq ~printer:string_of_int ;; +eq' 1 (rfind ~sub:"bc" "abcd");; +eq' ~-1 (rfind ~sub:"bc" "abd");; +eq' 5 (rfind ~sub:"a" "_a_a_a_");; +eq' 4 (rfind ~sub:"bc" "abcdbcd");; +eq' 6 (rfind ~sub:"a" "a1a234a");; + +q ~count:10_000 + Q.(pair printable_string printable_string) (fun (s1,s2) -> + let i = rfind ~sub:s2 s1 in + i < 0 || String.sub s1 i (length s2) = s2);; + + +eq ~printer:CCFun.id (replace ~which:`All ~sub:"a" ~by:"b" "abcdabcd") "bbcdbbcd";; +eq ~printer:CCFun.id (replace ~which:`Left ~sub:"a" ~by:"b" "abcdabcd") "bbcdabcd";; +eq ~printer:CCFun.id (replace ~which:`Right ~sub:"a" ~by:"b" "abcdabcd") "abcdbbcd";; +eq ~printer:CCFun.id (replace ~which:`All ~sub:"ab" ~by:"hello" " abab cdabb a") + " hellohello cdhellob a";; +eq ~printer:CCFun.id (replace ~which:`Left ~sub:"ab" ~by:"nope" " a b c d ") " a b c d ";; +eq ~printer:CCFun.id (replace ~sub:"a" ~by:"b" "1aa234a") "1bb234b";; + +t @@ fun () -> Split.list_cpy ~by:"," "aa,bb,cc" = ["aa"; "bb"; "cc"];; +t @@ fun () -> Split.list_cpy ~by:"--" "a--b----c--" = ["a"; "b"; ""; "c"; ""];; +t @@ fun () -> Split.list_cpy ~by:" " "hello world aie" = ["hello"; ""; "world"; "aie"];; +t @@ fun () -> Split.left ~by:" " "ab cde f g " = Some ("ab", "cde f g ");; +t @@ fun () -> Split.left ~by:"__" "a__c__e_f" = Some ("a", "c__e_f");; +t @@ fun () -> Split.left ~by:"_" "abcde" = None;; +t @@ fun () -> Split.left ~by:"bb" "abbc" = Some ("a", "c");; +t @@ fun () -> Split.left ~by:"a_" "abcde" = None;; +t @@ fun () -> Split.right ~by:" " "ab cde f g" = Some ("ab cde f", "g");; +t @@ fun () -> Split.right ~by:"__" "a__c__e_f" = Some ("a__c", "e_f");; +t @@ fun () -> Split.right ~by:"_" "abcde" = None;; +t @@ fun () -> Split.right ~by:"a_" "abcde" = None;; + +eq ~printer:Q.Print.(list string) + ["a"; "few"; "words"; "from"; "our"; "sponsors"] + (split_on_char ' ' "a few words from our sponsors");; + +q Q.(printable_string) (fun s -> + let s = split_on_char ' ' s |> String.concat " " in + s = (split_on_char ' ' s |> String.concat " "));; + +t @@ fun () -> compare_versions "0.1.3" "0.1" > 0;; +t @@ fun () -> compare_versions "10.1" "2.0" > 0;; +t @@ fun () -> compare_versions "0.1.alpha" "0.1" > 0;; +t @@ fun () -> compare_versions "0.3.dev" "0.4" < 0;; +t @@ fun () -> compare_versions "0.foo" "0.0" < 0;; +t @@ fun () -> compare_versions "1.2.3.4" "01.2.4.3" < 0;; + +q Q.(pair printable_string printable_string) (fun (a,b) -> + CCOrd.equiv (compare_versions a b) (CCOrd.opp compare_versions b a));; + +t @@ fun () -> compare_natural "foo1" "foo2" < 0;; +t @@ fun () -> compare_natural "foo11" "foo2" > 0;; +t @@ fun () -> compare_natural "foo11" "foo11" = 0;; +t @@ fun () -> compare_natural "foo011" "foo11" = 0;; +t @@ fun () -> compare_natural "foo1a" "foo1b" < 0;; +t @@ fun () -> compare_natural "foo1a1" "foo1a2" < 0;; +t @@ fun () -> compare_natural "foo1a17" "foo1a2" > 0;; + +q Q.(pair printable_string printable_string) (fun (a,b) -> + CCOrd.opp compare_natural a b = compare_natural b a);; +q Q.(printable_string) (fun a -> compare_natural a a = 0);; +q Q.(triple printable_string printable_string printable_string) (fun (a,b,c) -> + if compare_natural a b < 0 && compare_natural b c < 0 + then compare_natural a c < 0 else Q.assume_fail());; + +q Q.(string_of_size Gen.(0 -- 30)) (fun s -> + edit_distance s s = 0);; +q Q.(let p = string_of_size Gen.(0 -- 20) in pair p p) (fun (s1,s2) -> + edit_distance s1 s2 = edit_distance s2 s1);; +q Q.(let p = string_of_size Gen.(0 -- 20) in pair p p) (fun (s1,s2) -> + let e = edit_distance s1 s2 in + let e' = edit_distance ~cutoff:3 s1 s2 in + (if e' < 3 then e=e' else e >= 3) && + (if e <= 3 then e=e' else true));; + +eq ~printer:string_of_int 2 (edit_distance "hello" "helo!");; +eq ~printer:string_of_int 5 (edit_distance "abcde" "tuvwx");; +eq ~printer:string_of_int 2 (edit_distance ~cutoff:2 "abcde" "tuvwx");; +eq ~printer:string_of_int 1 + (edit_distance ("a" ^ String.make 100 '_') ("b"^String.make 100 '_'));; +eq ~printer:string_of_int 1 + (edit_distance ~cutoff:4 ("a" ^ String.make 1000 '_') ("b"^String.make 1000 '_'));; +eq ~printer:string_of_int 2 + (edit_distance ~cutoff:3 ("a" ^ String.make 1000 '_' ^ "c") + ("b" ^ String.make 1000 '_' ^ "d"));; + +(* 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. +*) + +q ( + 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; + edit_distance s (Bytes.to_string s') <= 1) +;; + +t @@ fun () -> prefix ~pre:"aab" "aabcd";; +t @@ fun () -> not (prefix ~pre:"ab" "aabcd");; +t @@ fun () -> not (prefix ~pre:"abcd" "abc");; +t @@ fun () -> prefix ~pre:"abc" "abcde";; +t @@ fun () -> prefix ~pre:"" "";; +t @@ fun () -> prefix ~pre:"" "abc";; +t @@ fun () -> prefix ~pre:"abc" "abc";; +t @@ fun () -> suffix ~suf:"cd" "abcd";; +t @@ fun () -> suffix ~suf:"" "";; +t @@ fun () -> suffix ~suf:"" "abc";; +t @@ fun () -> not (suffix ~suf:"cd" "abcde");; +t @@ fun () -> not (suffix ~suf:"abcd" "cd");; + +eq ("ab", "cd") (take_drop 2 "abcd");; +eq ("abc", "") (take_drop 3 "abc");; +eq ("abc", "") (take_drop 5 "abc");; + +let eq' = eq ~printer:Q.Print.(option string);; +eq' (Some "ab") (chop_suffix ~suf:"cd" "abcd");; +eq' None (chop_suffix ~suf:"cd" "abcde");; +eq' None (chop_suffix ~suf:"abcd" "cd");; +eq' (Some "cd") (chop_prefix ~pre:"aab" "aabcd");; +eq' None (chop_prefix ~pre:"ab" "aabcd");; +eq' None (chop_prefix ~pre:"abcd" "abc");; + +let eq' = eq ~printer:Q.Print.string;; +eq' " 42" (pad 4 "42");; +eq' "0042" (pad ~c:'0' 4 "42");; +eq' "4200" (pad ~side:`Right ~c:'0' 4 "42");; +eq' "hello" (pad 4 "hello");; +eq' "aaa" (pad ~c:'a' 3 "");; +eq' "aaa" (pad ~side:`Right ~c:'a' 3 "");; + +t @@ fun () -> of_list ['a'; 'b'; 'c'] = "abc";; +t @@ fun () -> of_list [] = "";; + +let eq' = eq ~printer:Q.Print.(list @@ Printf.sprintf "%S");; +eq' ["ab"; "c"] (lines "ab\nc");; +eq' ["ab"; "c"] (lines "ab\nc\n");; +eq' [] (lines "");; +eq' [""] (lines "\n");; +eq' [""; "a"] (lines "\na");; + +q Q.(printable_string) (fun s -> + lines s = (lines_gen s |> Gen.to_list));; +q Q.(printable_string) (fun s -> + lines s = (lines_iter s |> Iter.to_list));; + +q Q.(small_list printable_string) (fun l -> + concat_iter ~sep:"\n" (Iter.of_list l) = concat "\n" l);; +q Q.(small_list printable_string) (fun l -> + concat_gen ~sep:"\n" (Gen.of_list l) = concat "\n" l);; +q Q.(small_list printable_string) (fun l -> + concat_seq ~sep:"\n" (CCSeq.of_list l) = concat "\n" l);; + +eq ~printer:CCFun.id "" (unlines []);; +eq ~printer:CCFun.id "ab\nc\n" (unlines ["ab"; "c"]);; + +q Q.printable_string (fun s -> trim (unlines (lines s)) = trim s);; +q Q.printable_string (fun s -> trim (unlines_gen (lines_gen s)) = trim s);; + +q Q.(small_list small_string) (fun l -> + let l = unlines l |> lines in + l = (unlines l |> lines));; + +t @@ fun () -> set "abcd" 1 '_' = "a_cd";; +t @@ fun () -> set "abcd" 0 '-' = "-bcd";; +t @@ fun () -> (try ignore (set "abc" 5 '_'); false with Invalid_argument _ -> true);; + +eq ~printer:Q.Print.string + "bcef" (filter_map + (function 'c' -> None | c -> Some (Char.chr (Char.code c + 1))) "abcde");; + +eq ~printer:Q.Print.string + "abde" (filter (function 'c' -> false | _ -> true) "abcdec");; + +q Q.printable_string (fun s -> filter (fun _ -> true) s = s);; + +eq ~printer:Q.Print.string + "abcde" (uniq CCShims_.Stdlib.(=) "abbccdeeeee");; + +eq ~printer:CCFun.id "abc " (ltrim " abc ");; +eq ~printer:CCFun.id " abc" (rtrim " abc ");; + +q Q.(printable_string) (fun s -> + String.trim s = (s |> ltrim |> rtrim));; +q Q.(printable_string) (fun s -> ltrim s = ltrim (ltrim s));; +q Q.(printable_string) (fun s -> rtrim s = rtrim (rtrim s));; +q Q.(printable_string) (fun s -> + let s' = ltrim s in + if s'="" then Q.assume_fail() else s'.[0] <> ' ');; +q Q.(printable_string) (fun s -> + let s' = rtrim s in + if s'="" then Q.assume_fail() else s'.[String.length s'-1] <> ' ');; + +t @@ fun () -> equal_caseless "foo" "FoO";; +t @@ fun () -> equal_caseless "helLo" "HEllO";; + +q Q.(pair printable_string printable_string) (fun (s1,s2) -> + equal_caseless s1 s2 = (lowercase_ascii s1=lowercase_ascii s2));; +q Q.(printable_string) (fun s -> equal_caseless s s);; +q Q.(printable_string) (fun s -> equal_caseless (uppercase_ascii s) s);; + +let eq' = eq ~printer:(Printf.sprintf "%S");; +eq' "0068656c6c6f20776f726c64" (to_hex "\000hello world");; +eq' "" (to_hex "");; +eq' "\000hello world" (of_hex_exn "0068656c6c6f20776f726c64");; +eq' "hello world" (of_hex_exn "68656C6C6F20776F726C64");; + +q Q.(string) (fun s -> + of_hex_exn (to_hex s) = s);; +q Q.(string) (fun s -> + CCString.for_all (function 'A'..'F'|'a'..'f'|'0'..'9' -> true | _ -> false) @@ to_hex s);; + +t @@ fun () -> "ab" < "abc";; +t @@ fun () -> "123" < "14";; diff --git a/tests/core/t_unix.ml b/tests/core/t_unix.ml new file mode 100644 index 00000000..a37fcb2e --- /dev/null +++ b/tests/core/t_unix.ml @@ -0,0 +1,48 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; +open CCUnix;; + +t @@ fun () -> escape_str "foo" = "foo";; +t @@ fun () -> escape_str "foo bar" = "'foo bar'";; +t @@ fun () -> escape_str "fo'o b'ar" = "'fo'\\''o b'\\''ar'";; +t @@ fun () -> call_full ~stdin:(`Str "abc") "cat" |> stdout = "abc";; +t @@ fun () -> call_full "echo %s" (escape_str "a'b'c") |> stdout = "a'b'c\n";; +t @@ fun () -> call_full "echo %s" "a'b'c" |> stdout = "abc\n";; +t @@ fun () -> call_stdout ~stdin:(`Str "abc") "cat" = "abc";; +t @@ fun () -> call_stdout "echo %s" (escape_str "a'b'c") = "a'b'c\n";; +t @@ fun () -> call_stdout "echo %s" "a'b'c" = "abc\n";; + +t @@ fun () -> + let m = 200 in + let n = 50 in + let write_atom filename s = + with_file_lock ~kind:`Write filename + (fun () -> + CCIO.with_out ~flags:[Open_append; Open_creat] + filename (fun oc -> output_string oc s; flush oc)) + in + let f filename = + for _j=1 to m do + write_atom filename "foo\n" + done + in + CCIO.File.with_temp ~prefix:"containers_" ~suffix:".txt" + (fun filename -> + let a = Array.init n (fun _ -> Thread.create f filename) in + Array.iter Thread.join a; + let lines = CCIO.with_in filename CCIO.read_lines_l in + assert_equal ~printer:string_of_int (n * m) (List.length lines); + assert (List.for_all ((=) "foo") lines)); + true;; + +t @@ fun () -> + let filename = with_temp_dir "test_containers" + (fun dir -> + let name = Filename.concat dir "test" in + CCIO.with_out name (fun oc -> output_string oc "content"; flush oc); + assert (Sys.file_exists name); + name) + in + assert (not (Sys.file_exists filename)); + true;; diff --git a/tests/core/t_utf8string.ml b/tests/core/t_utf8string.ml new file mode 100644 index 00000000..deb7bee7 --- /dev/null +++ b/tests/core/t_utf8string.ml @@ -0,0 +1,162 @@ + +open CCUtf8_string +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; + +eq ~cmp:(=) ~printer:Q.Print.(list (fun c -> string_of_int@@ Uchar.to_int c)) + (to_list (of_string_exn "aébõ😀")) (to_seq (of_string_exn "aébõ😀") |> CCList.of_seq);; + +(* make sure it's persisted correctly *) +t @@ fun () -> + let s = (of_string_exn "aébõ😀") in + let seq = to_seq s in + let l = to_list s in + let testeq seq = assert_equal ~cmp:(=) l (CCList.of_seq seq) in + testeq seq; + testeq seq; + testeq seq; + true;; + +let printer s = String.escaped (to_string s) +let pp_uchar (c:Uchar.t) = Printf.sprintf "0x%x" (Uchar.to_int c) + +let arb_uchar = + let rec gen = lazy ( + let open Q.Gen in + Q.Gen.int_range Uchar.(to_int min) Uchar.(to_int max) >>= fun n -> + try return (Uchar.of_int n) + with _ -> Lazy.force gen + ) in + Q.make + ~print:(fun c -> Printf.sprintf "" (Uchar.to_int c)) + (Lazy.force gen) + +let uutf_is_valid s = +try + Uutf.String.fold_utf_8 + (fun () _ -> function + | `Malformed _ -> raise Exit + | `Uchar _ -> ()) + () s; + true +with Exit -> + false + +let uutf_to_iter s f = +Uutf.String.fold_utf_8 + (fun () _ -> function + | `Malformed _ -> f (Uchar.of_int 0xfffd) + | `Uchar c -> f c) + () s + +let uutf_of_l l = + let buf = Buffer.create 32 in + List.iter (Uutf.Buffer.add_utf_8 buf) l; + Buffer.contents buf;; + +t @@ fun () -> + let s = of_string_exn "このため、" in + let s' = to_iter s |> of_iter in + assert_equal ~cmp:equal ~printer s s'; + true;; + +q Q.small_string (fun s -> + Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); + is_valid s);; + +q ~long_factor:10 + Q.small_string (fun s -> + Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); + s = (of_string_exn s |> to_iter|> of_iter|> to_string) + );; + +q ~long_factor:10 + Q.string (fun s -> + Q.assume (CCString.for_all (fun c -> Char.code c < 128) s); + String.length s = List.length (of_string_exn s |> to_list) + );; + +q ~long_factor:10 ~count:20_000 + Q.(small_list arb_uchar) (fun l -> + let s = of_list l in + l = to_list s);; + +q ~long_factor:10 + Q.(small_list arb_uchar) (fun l -> + let s = of_list l in + l = (to_list @@ of_gen @@ to_gen s) + );; + +q ~long_factor:10 + Q.(small_list arb_uchar) (fun l -> + let s = of_list l in + l = (to_list @@ of_iter @@ to_iter s) + );; + +t @@ fun () -> not (is_valid "\192\181");; +t @@ fun () -> not (is_valid "\193\143");; +t @@ fun () -> not (is_valid "\224\151\167");; +t @@ fun () -> not (is_valid "\224\137\165");; +t @@ fun () -> is_valid "\240\151\189\163";; + +q ~long_factor:40 + Q.string (fun s -> + Q.assume (is_valid s); + let s = of_string_exn s in + let s2 = s |> to_iter|> of_iter in + if s=s2 then true + else Q.Test.fail_reportf "s=%S, s2=%S" (to_string s)(to_string s2) + );; + +q ~long_factor:40 + Q.string (fun s -> + Q.assume (is_valid s); + let s = of_string_exn s in + let s2 = s |> to_gen |> of_gen in + if s=s2 then true + else Q.Test.fail_reportf "s=%S, s2=%S" (to_string s)(to_string s2) + );; + +(* compare with uutf *) + +q ~long_factor:40 ~count:50_000 + Q.small_string (fun s -> + let v1 = is_valid s in + let v2 = uutf_is_valid s in + if v1=v2 then true + else Q.Test.fail_reportf "s:%S, valid: %B, uutf_valid: %B" s v1 v2 + );; + +q ~long_factor:40 ~count:50_000 + Q.(small_list arb_uchar) (fun l -> + let pp s = Q.Print.(list pp_uchar) s in + let uutf = uutf_of_l l in + let s = (of_list l:>string) in + if uutf = s then true + else Q.Test.fail_reportf "l: '%s', uutf: '%s', containers: '%s'" + (pp l) uutf s + );; + +q ~long_factor:40 ~count:50_000 + Q.small_string (fun s -> + Q.assume (is_valid s && uutf_is_valid s); + let pp s = Q.Print.(list pp_uchar) s in + let l_uutf = uutf_to_iter s |> Iter.to_list in + let l_co = of_string_exn s |> to_iter |> Iter.to_list in + if l_uutf = l_co then true + else Q.Test.fail_reportf "uutf: '%s', containers: '%s', is_valid %B, uutf_is_valid %B" + (pp l_uutf) (pp l_co) (is_valid s) (uutf_is_valid s) + );; + +t @@ fun () -> + for i = 0 to 127 do + let c = Uchar.of_int i in + assert_equal 1 (n_bytes (of_list [c])) + done; + true ;; + +q Q.(small_list arb_uchar) (fun l -> + of_list l = concat empty (List.map of_uchar l));; + +q Q.(pair small_nat arb_uchar) (fun (i,c) -> + make i c = concat empty (CCList.init i (fun _ -> of_uchar c)));; diff --git a/tests/core/t_vector.ml b/tests/core/t_vector.ml new file mode 100644 index 00000000..db981d75 --- /dev/null +++ b/tests/core/t_vector.ml @@ -0,0 +1,361 @@ + +module T = (val Containers_testlib.make ~__FILE__ ()) +include T;; +open CCVector;; + +t @@ fun () -> (create_with ~capacity:200 1 |> capacity) >= 200;; +t @@ fun () -> return 42 |> to_list = [42];; +t @@ fun () -> return 42 |> length = 1;; +t @@ fun () -> + let v = create_with ~capacity:10 1 in + ensure v 200; + capacity v >= 200;; +t @@ fun () -> let v = create() in push v 0.; push v 1.; push v 2.; 3=length v;; +t @@ fun () -> let v = create() in push v 1.; push v 2.; push v 3.; + 6. = (get v 0 +. get v 1 +. get v 2);; +t @@ fun () -> let v = create() in push v 0; push v 1; push v 2; 3=length v;; +t @@ fun () -> let v = create() in push v 1; push v 2; push v 3; + 6 = (get v 0 + get v 1 + get v 2);; +t @@ fun () -> let v = create() in push v "a"; push v "b"; push v "c"; 3=length v;; +t @@ fun () -> let v = create() in push v "a"; push v "b"; push v "c"; + "abc" = String.concat "" (to_list v);; + +t @@ fun () -> + let v = create() in + push v 0.; push v 1.; + clear v; + push v 0.; push v 1.; push v 7.; push v 10.; push v 12.; + truncate v 2; + assert_equal 1. (fold (+.) 0. v); + clear v; + assert_equal 0 (size v); + push v 0.; push v 1.; push v 7.; push v 10.; push v 12.; + assert_equal (1. +. 7. +. 10. +. 12.) (fold (+.) 0. v); + true;; + +t @@ fun () -> + let v = of_iter Iter.(1 -- 10) in + assert_equal 10 (size v); + clear v; + assert_equal 0 (size v); + assert (Iter.is_empty (to_iter v)); + true;; + +t @@ fun () -> let v = create () in push v 1; to_list v = [1];; +t @@ fun () -> let v = of_list [1;2;3] in push v 4; to_list v = [1;2;3;4];; +t @@ fun () -> let v = make 1 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4];; +t @@ fun () -> let v = make 1 0 in resize_with v (fun i -> i) 5; CCList.length (to_list v) = 5;; +t @@ fun () -> let v = create_with ~capacity:2 0 in resize_with v (fun i -> i) 5; to_list v = [0;1;2;3;4];; +t @@ fun () -> let v = make 5 0 in resize_with v (fun i -> i) 5; to_list v = [0;0;0;0;0];; +t @@ fun () -> let v = make 5 0 in resize_with v (fun i -> i) 6; to_list v = [0;0;0;0;0;5];; +t @@ fun () -> let v = make 5 0 in + try resize_with v (fun i -> i) (-1); false + with Invalid_argument _ -> true;; +t @@ fun () -> let v = make 5 0 in resize_with v (fun i -> i) 5; List.length (to_list v) = 5;; + +t @@ fun () -> let v = make 1 0 in resize_with_init v ~init:1 5; to_list v = [0;1;1;1;1];; +t @@ fun () -> let v = make 1 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5;; +t @@ fun () -> + let v = create_with ~capacity:2 0 in + resize_with_init v ~init:1 5; to_list v = [1;1;1;1;1];; +t @@ fun () -> let v = make 5 0 in resize_with_init v ~init:1 5; to_list v = [0;0;0;0;0];; +t @@ fun () -> let v = make 3 0 in resize_with_init v ~init:1 5; to_list v = [0;0;0;1;1];; +t @@ fun () -> let v = make 5 0 in + try resize_with_init v ~init:1 (-1); false + with Invalid_argument _ -> true;; +t @@ fun () -> let v = make 5 0 in resize_with_init v ~init:1 5; List.length (to_list v) = 5;; + +(* test for asymptotic behavior *) +t @@ fun () -> let v =make 1 0 in + for i=0 to 100_000 do resize_with_init v ~init:10 i; done; true;; + +t @@ fun () -> let v1 = init 5 (fun i->i) and v2 = init 5 (fun i->i+5) in + append v1 v2; to_list v1 = CCList.(0--9);; +t @@ fun () -> let empty = create () and v2 = init 5 (fun i->i) in + append empty v2; to_list empty = CCList.(0--4);; +t @@ fun () -> let v1 = init 5 (fun i->i) and empty = create () in + append v1 empty; to_list v1 = CCList.(0--4);; +t @@ fun () -> let v = init 3 (fun i->i) in + append v v; to_list v = [0; 1; 2; 0; 1; 2];; +t @@ fun () -> let empty = create () in + append empty empty; to_list empty = [];; + +t @@ fun () -> + let a = of_iter Iter.(1 -- 5) in + let b = of_iter Iter.(6 -- 10) in + append a b; + assert_equal 10 (size a); + assert_equal (Iter.to_array Iter.(1 -- 10)) (to_array a); + assert_equal (Iter.to_array Iter.(6 -- 10)) (to_array b); + true;; + +q Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> + let v1 = of_list l and v2 = of_list l in + remove_and_shift v1 9; + remove_unordered v2 9; + to_list v1 = (to_list v2));; +q Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> + let l = List.sort CCInt.compare l in + let v = of_list l in + remove_and_shift v 3; + to_list v = (List.sort CCInt.compare (to_list v)));; +q Q.(list_of_size (Gen.int_range 10 10) small_int) (fun l -> + let l = List.sort CCInt.compare l in + let v1 = of_list l and v2 = of_list l in + remove_and_shift v1 3; + remove_unordered v2 3; + to_list v1 = (List.sort CCInt.compare (to_list v2)));; + +t @@ fun () -> let v = (1 -- 5) in insert v 3 9; to_list v = [1;2;3;9;4;5];; +t @@ fun () -> let v = create () in insert v 0 2; to_list v = [2];; +t @@ fun () -> let v = (1 -- 3) in remove_and_shift v 1; insert v 1 5; to_list v = [1;5;3];; +t @@ fun () -> let v = (1 -- 3) in remove_and_shift v 0; insert v 2 5; to_list v = [2;3;5];; +t @@ fun () -> let v = (1 -- 3) in insert v 3 5; to_list v = [1;2;3;5];; +t @@ fun () -> + let v1 = init 5 (fun i->i) and v2 = Array.init 5 (fun i->i+5) in + append_array v1 v2; to_list v1 = CCList.(0--9);; +t @@ fun () -> let empty = create () in + append_array empty CCArray.(0--5); to_list empty = CCList.(0--5);; +t @@ fun () -> let v1 = init 5 (fun i->i) in + append_array v1 [| |]; to_list v1 = CCList.(0--4);; +t @@ fun () -> let empty = create () in + append_array empty [| |]; to_list empty = [];; + +q Q.(pair (list int)(list int)) (fun (l1,l2) -> + let v = of_list l1 in append_list v l2; + to_list v = (l1 @ l2)) ;; +q Q.(pair (list int)(list int)) (fun (l1,l2) -> + let v = of_list l1 in append_list v l2; + length v = List.length l1 + List.length l2);; + +q Q.(pair (list int)(list int)) (fun (l1,l2) -> + let v = of_list l1 in append_gen v (Gen.of_list l2); + to_list v = (l1 @ l2));; +q Q.(pair (list int)(list int)) (fun (l1,l2) -> + let v = of_list l1 in append_gen v (Gen.of_list l2); + length v = List.length l1 + List.length l2);; + +let gen x = + let small = length in + let print = CCOption.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);; + +q (Q.pair (gen Q.int) (gen Q.int)) (fun (v1,v2) -> + let l1 = to_list v1 in + append v1 v2; + Iter.to_list (to_iter v1) = + Iter.(to_list (append (of_list l1) (to_iter v2))) +);; + +t @@ fun () -> equal (=) (create ()) (create ());; +t @@ fun () -> equal (=) (return 42) (return 42);; +t @@ fun () -> not (equal (=) (create ()) (return 42));; +t @@ fun () -> not (equal (=) (return 42) (create ()));; + +q Q.(let g = list_of_size Gen.(0--10) small_int in pair g g) (fun (l1,l2) -> + equal (=) (of_list l1) (of_list l2) = (l1=l2));; + +q Q.(pair (small_list small_int)(small_list small_int)) (fun (l1,l2) -> + let v1 = of_list l1 in + let v2 = of_list l2 in + equal (=) v1 v2 = (l1=l2));; + +q Q.(pair (small_list small_int)(small_list small_int)) (fun (l1,l2) -> + let v1 = of_list l1 in + let v2 = of_list l2 in + compare Stdlib.compare v1 v2 = CCList.compare Stdlib.compare l1 l2) ;; + +t @@ fun () -> 1 -- 10 |> top = Some 10;; +t @@ fun () -> create () |> top = None;; +t @@ fun () -> 1 -- 10 |> top_exn = 10;; + +t @@ fun () -> (let v = of_list [1;2;3] in let v' = copy v in to_list v' = [1;2;3]);; +t @@ fun () -> create () |> copy |> is_empty;; + +t @@ fun () -> + let v = of_iter Iter.(1 -- 100) in + assert_equal 100 (size v); + let v' = copy v in + assert_equal 100 (size v'); + clear v'; + assert (is_empty v'); + assert (not (is_empty v)); + true;; + +q Q.(small_list small_int) (fun l -> + let v = of_list l in + let v' = copy v in + equal (=) v v');; + +t @@ fun () -> + let v = of_iter Iter.(1 -- 10) in + truncate v 5; + assert_equal [1;2;3;4;5] (to_list v); + true ;; + +q (gen Q.small_int) (fun v -> + let n = size v / 2 in + let l = to_list v in + let h = Iter.(to_list (take n (of_list l))) in + let v' = copy v in + truncate v' n; + h = to_list v' +) ;; + +q (gen Q.small_int) (fun v -> + let v' = copy v in + shrink_to_fit v; + to_list v = to_list v' +) ;; + +q (gen Q.small_int) (fun v -> + let v' = copy v in + sort' Stdlib.compare v'; + let l = to_list v' in + List.sort Stdlib.compare l = l +);; + +t @@ fun () -> let v = of_list [1;4;5;3;2;4;1] in + uniq_sort Stdlib.compare v; to_list v = [1;2;3;4;5];; + +q ~long_factor:10 + Q.(small_list small_int) (fun l -> + let v = of_list l in + uniq_sort Stdlib.compare v; + to_list v = (CCList.sort_uniq ~cmp:Stdlib.compare l));; + +t @@ fun () -> let v = (0--6) in + iteri (fun i _ -> if i = 3 then remove_unordered v i) v; length v = 6;; + +t @@ fun () -> + let v = create() in push v 1; push v 2; push v 3; + to_list (map string_of_int v) = ["1"; "2"; "3"];; + +q Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + to_list (map f v) = List.map f l);; + +t @@ fun () -> + let v = create() in push v 1; push v 2; push v 3; + to_list (mapi (fun i e -> Printf.sprintf "%i %i" i e) v) = ["0 1"; "1 2"; "2 3"];; + +q Q.(pair (fun2 Observable.int Observable.int small_int) (small_list small_int)) + (fun (Q.Fun (_,f),l) -> + let v = of_list l in + to_list (mapi f v) = List.mapi f l);; + +q Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + map_in_place f v; + to_list v = List.map f l);; + +t @@ fun () -> + let v = 1 -- 10 in filter_in_place (fun x->x<4) v; + to_list v = [1;2;3];; + +q Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + filter_in_place f v; + to_list v = List.filter f l) ;; + +t @@ fun () -> filter (fun x-> x mod 2=0) (of_list [1;2;3;4;5]) |> to_list = [2;4];; +t @@ fun () -> filter (fun x-> x mod 2=0) (1 -- 1_000_000) |> length = 500_000;; + +q Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + to_list (filter f v) = List.filter f l);; + +t @@ fun () -> fold (+) 0 (of_list [1;2;3;4;5]) = 15;; +t @@ fun () -> fold (+) 0 (create ()) = 0;; + +q Q.(pair (fun2 Observable.int Observable.int small_int) (small_list small_int)) + (fun (Q.Fun (_,f),l) -> + let v = of_list l in + fold f 0 v = List.fold_left f 0 l);; + +q Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + exists f v = List.exists f l);; + +q Q.(pair (fun1 Observable.int bool) (small_list small_int)) + (fun (Q.Fun (_,f),l) -> + let v = of_list l in + for_all f v = List.for_all f l);; + +q Q.(pair (fun1 Observable.int bool) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + find f v = CCList.find_pred f l);; + +q Q.(list small_int) (fun l -> + let v = of_list l in + let f x = x>30 && x < 35 in + find_map (fun x -> if f x then Some x else None) v = find f v);; + +q Q.(pair (fun1 Observable.int (option bool)) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + to_list (filter_map f v) = CCList.filter_map f l);; + +q Q.(pair (fun1 Observable.int (option small_int)) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + filter_map_in_place f v; + to_list v = CCList.filter_map f l);; + +(* check it frees memory properly *) +t @@ fun () -> + let s = "coucou" ^ "lol" in + let w = Weak.create 1 in + Weak.set w 0 (Some s); + let v = of_list ["a"; s] in + filter_in_place (fun s -> String.length s <= 1) v; + assert_equal 1 (length v); + assert_equal "a" (get v 0); + Gc.full_major(); + assert_equal None (Weak.get w 0); + true;; + +eq ~cmp:(=) ~printer:Q.Print.(list int) + [ 11; 12; 21; 22 ] (List.sort CCInt.compare @@ + to_list @@ monoid_product (+) (of_list [10; 20]) (of_list [1; 2]));; +eq ~cmp:(=) ~printer:Q.Print.(list int) + [ 11; 12; 13; 14 ] (List.sort CCInt.compare @@ + to_list @@ monoid_product (+) (of_list [10]) (of_list [1; 2; 3; 4]));; + +q Q.(small_list small_int) (fun l -> + let v = of_list l in + rev_in_place v; + to_list v = List.rev l);; + +t @@ fun () -> rev (of_list [1;2;3;4]) |> to_list = [4;3;2;1];; +t @@ fun () -> rev (of_list [1;2;3;4;5]) |> to_list = [5;4;3;2;1];; +t @@ fun () -> rev (create ()) |> to_list = [];; + +q Q.(small_list small_int) (fun l -> + let v = of_list l in + to_list (rev v) = List.rev l);; + +t @@ fun () -> let v = of_list [1;2;3] in (fun f->rev_iter f v) |> Iter.to_list = [3;2;1];; + +q Q.(list int) (fun l -> + let v = of_list l in + (fun f->rev_iter f v) |> Iter.to_list = List.rev l);; + +t @@ fun () -> of_iter Iter.(1 -- 10) |> to_list = CCList.(1 -- 10);; + +q Q.(list int) (fun l -> + let v= of_list l in v |> to_iter_rev |> Iter.to_rev_list = l);; + +t @@ fun () -> slice_iter (of_list [0;1;2;3;4]) 1 3 |> CCList.of_iter = [1;2;3];; +t @@ fun () -> slice_iter (of_list [0;1;2;3;4]) 1 4 |> CCList.of_iter = [1;2;3;4];; +t @@ fun () -> slice_iter (of_list [0;1;2;3;4]) 0 5 |> CCList.of_iter = [0;1;2;3;4];; +t @@ fun () -> (1 -- 4) |> to_list = [1;2;3;4];; +t @@ fun () -> (4 -- 1) |> to_list = [4;3;2;1];; +t @@ fun () -> (0 -- 0) |> to_list = [0];; + +q Q.(pair small_int small_int) (fun (a,b) -> + (a -- b) |> to_list = CCList.(a -- b));; + +q Q.(pair small_int small_int) (fun (a,b) -> + (a --^ b) |> to_list = CCList.(a --^ b));; + +t @@ fun () -> of_list CCList.(1--300_000) |> to_list = CCList.(1--300_000);; +t @@ fun () -> let v = (1--10) in to_list v = Gen.to_list (to_gen v);;