mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2026-01-21 16:56:39 -05:00
move all core tests to new testlib
This commit is contained in:
parent
49c06e93fa
commit
b695918e99
50 changed files with 2039 additions and 2384 deletions
|
|
@ -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)
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
)
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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<j then range i (j-1) yield
|
||||
else if i=j then ()
|
||||
else range i (j+1) yield
|
||||
|
||||
(*$= & ~printer:Q.Print.(list int)
|
||||
[] (range' 0 0 |> 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<j) then ()
|
||||
else range i ((j-i)/step*step + i) yield
|
||||
|
||||
(* note: the last test checks that no error occurs due to overflows. *)
|
||||
(*$= & ~printer:Q.Print.(list int)
|
||||
[0] (range_by ~step:1 0 0 |> 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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ->
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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<j then range i (j-1)
|
||||
else range i (j+1)
|
||||
|
||||
(*$T
|
||||
1 --^ 5 |> 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
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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 '%d'>" (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)))
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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) ->
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
()
|
||||
*)
|
||||
|
|
|
|||
5
tests/core/compat/dune
Normal file
5
tests/core/compat/dune
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
(tests
|
||||
(names t_compat)
|
||||
(flags :standard -nolabels)
|
||||
(libraries containers))
|
||||
9
tests/core/compat/t_compat.ml
Normal file
9
tests/core/compat/t_compat.ml
Normal file
|
|
@ -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);;
|
||||
|
||||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
];;
|
||||
|
|
|
|||
69
tests/core/t_IO.ml
Normal file
69
tests/core/t_IO.ml
Normal file
|
|
@ -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
|
||||
)
|
||||
;;
|
||||
57
tests/core/t_bencode.ml
Normal file
57
tests/core/t_bencode.ml
Normal file
|
|
@ -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) ;;
|
||||
|
|
@ -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));;
|
||||
|
|
|
|||
55
tests/core/t_hashtbl.ml
Normal file
55
tests/core/t_hashtbl.ml
Normal file
|
|
@ -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;;
|
||||
87
tests/core/t_heap.ml
Normal file
87
tests/core/t_heap.ml
Normal file
|
|
@ -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'
|
||||
);;
|
||||
132
tests/core/t_int.ml
Normal file
132
tests/core/t_int.ml
Normal file
|
|
@ -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);;
|
||||
66
tests/core/t_int32.ml
Normal file
66
tests/core/t_int32.ml
Normal file
|
|
@ -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);;
|
||||
|
||||
65
tests/core/t_int64.ml
Normal file
65
tests/core/t_int64.ml
Normal file
|
|
@ -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);;
|
||||
27
tests/core/t_map.ml
Normal file
27
tests/core/t_map.ml
Normal file
|
|
@ -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));;
|
||||
67
tests/core/t_nativeint.ml
Normal file
67
tests/core/t_nativeint.ml
Normal file
|
|
@ -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);;
|
||||
25
tests/core/t_option.ml
Normal file
25
tests/core/t_option.ml
Normal file
|
|
@ -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;;
|
||||
43
tests/core/t_ord.ml
Normal file
43
tests/core/t_ord.ml
Normal file
|
|
@ -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)));;
|
||||
214
tests/core/t_parse.ml
Normal file
214
tests/core/t_parse.ml
Normal file
|
|
@ -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 )");;
|
||||
|
||||
19
tests/core/t_random.ml
Normal file
19
tests/core/t_random.ml
Normal file
|
|
@ -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;;
|
||||
32
tests/core/t_result.ml
Normal file
32
tests/core/t_result.ml
Normal file
|
|
@ -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"]);;
|
||||
88
tests/core/t_seq.ml
Normal file
88
tests/core/t_seq.ml
Normal file
|
|
@ -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];;
|
||||
22
tests/core/t_set.ml
Normal file
22
tests/core/t_set.ml
Normal file
|
|
@ -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 " "));;
|
||||
80
tests/core/t_sexp.ml
Normal file
80
tests/core/t_sexp.ml
Normal file
|
|
@ -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;;
|
||||
264
tests/core/t_string.ml
Normal file
264
tests/core/t_string.ml
Normal file
|
|
@ -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";;
|
||||
48
tests/core/t_unix.ml
Normal file
48
tests/core/t_unix.ml
Normal file
|
|
@ -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;;
|
||||
162
tests/core/t_utf8string.ml
Normal file
162
tests/core/t_utf8string.ml
Normal file
|
|
@ -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 '%d'>" (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)));;
|
||||
361
tests/core/t_vector.ml
Normal file
361
tests/core/t_vector.ml
Normal file
|
|
@ -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);;
|
||||
Loading…
Add table
Reference in a new issue