mirror of
https://github.com/c-cube/iter.git
synced 2025-12-05 19:00:31 -05:00
349 lines
9.3 KiB
OCaml
349 lines
9.3 KiB
OCaml
module Q = QCheck
|
|
open Iter
|
|
|
|
let spf = Printf.sprintf
|
|
let pp_ilist = Q.Print.(list int)
|
|
let qchecks = ref []
|
|
|
|
let add_qcheck line gen prop =
|
|
let test = Q.Test.make gen prop ~name:(spf "qcheck %d" line) in
|
|
qchecks := test :: !qchecks
|
|
|
|
let () =
|
|
let seq = empty in
|
|
OUnit.assert_bool "empty" (is_empty seq);
|
|
OUnit.assert_bool "empty"
|
|
(try
|
|
iter (fun _ -> raise Exit) seq;
|
|
true
|
|
with Exit -> false)
|
|
|
|
let () =
|
|
let seq = repeat "hello" in
|
|
OUnit.assert_equal [ "hello"; "hello"; "hello" ] (seq |> take 3 |> to_list)
|
|
|
|
let () =
|
|
OUnit.assert_equal [ 0; 1; 2; 3; 4 ] (init (fun x -> x) |> take 5 |> to_list)
|
|
|
|
let () =
|
|
let n = 1 -- 10 |> fold ( + ) 0 in
|
|
OUnit.assert_equal 55 n;
|
|
()
|
|
|
|
let () =
|
|
let l =
|
|
[ "hello"; "world" ] |> of_list |> foldi (fun acc i x -> (i, x) :: acc) []
|
|
in
|
|
OUnit.assert_equal [ 1, "world"; 0, "hello" ] l;
|
|
()
|
|
|
|
let () =
|
|
OUnit.assert_equal
|
|
~printer:Q.Print.(list int)
|
|
[ 0; 1; 3; 5 ]
|
|
(0 -- 3 |> fold_map (fun prev x -> x, prev + x) 0 |> to_list)
|
|
|
|
let () =
|
|
let s1 = 1 -- 5 in
|
|
let s2 = 6 -- 10 in
|
|
let l = [ 1; 2; 3; 4; 5; 6; 7; 8; 9; 10 ] in
|
|
OUnit.assert_equal l (to_list (append s1 s2));
|
|
()
|
|
|
|
let () =
|
|
1 -- 1000
|
|
|> map (fun i -> i -- (i + 1))
|
|
|> concat |> length |> OUnit.assert_equal 2000
|
|
|
|
let () =
|
|
1 -- 1000
|
|
|> flat_map (fun i -> i -- (i + 1))
|
|
|> length |> OUnit.assert_equal 2000
|
|
|
|
let test = OUnit.assert_equal ~printer:Q.Print.(list @@ list int)
|
|
|
|
let () =
|
|
test
|
|
[ [ 1; 2 ]; [ 1; 3 ] ]
|
|
(seq_list [ singleton 1; doubleton 2 3 ] |> to_list)
|
|
|
|
let () = test [] (seq_list [ singleton 1; empty; doubleton 2 3 ] |> to_list)
|
|
|
|
let () =
|
|
test
|
|
[ [ 1; 2; 4 ]; [ 1; 3; 4 ] ]
|
|
(seq_list [ singleton 1; doubleton 2 3; singleton 4 ] |> to_list)
|
|
|
|
let () =
|
|
add_qcheck __LINE__
|
|
Q.(list int)
|
|
(fun l ->
|
|
let seq = of_list l and f x = x mod 2 = 0 in
|
|
filter_count f seq = (filter f seq |> length))
|
|
|
|
let () =
|
|
1 -- 100
|
|
|> (fun seq -> intersperse 0 seq)
|
|
|> take 10 |> to_list
|
|
|> OUnit.assert_equal [ 1; 0; 2; 0; 3; 0; 4; 0; 5; 0 ]
|
|
|
|
let () =
|
|
let printer = pp_ilist in
|
|
let iter =
|
|
of_gen_once
|
|
(let i = ref (-1) in
|
|
fun () ->
|
|
incr i;
|
|
if !i < 5 then
|
|
Some !i
|
|
else
|
|
None)
|
|
in
|
|
(* consume iter into a persistent version of itself *)
|
|
let iter' = persistent iter in
|
|
OUnit.assert_raises OneShotSequence (fun () -> iter |> to_list);
|
|
OUnit.assert_equal ~printer [ 0; 1; 2; 3; 4 ] (iter' |> to_list);
|
|
OUnit.assert_equal ~printer [ 0; 1; 2; 3; 4 ] (iter' |> to_list);
|
|
OUnit.assert_equal ~printer [ 0; 1; 2; 3; 4 ]
|
|
(iter' |> to_seq_persistent |> of_seq |> to_list);
|
|
()
|
|
|
|
let () =
|
|
let printer = pp_ilist in
|
|
let iter = 0 -- 10_000 in
|
|
let iter' = persistent iter in
|
|
OUnit.assert_equal 10_001 (length iter');
|
|
OUnit.assert_equal 10_001 (length iter');
|
|
OUnit.assert_equal ~printer [ 0; 1; 2; 3 ] (iter' |> take 4 |> to_list);
|
|
()
|
|
|
|
let () =
|
|
1 -- 100
|
|
|> sort ~cmp:(fun i j -> j - i)
|
|
|> take 4 |> to_list
|
|
|> OUnit.assert_equal [ 100; 99; 98; 97 ]
|
|
|
|
let test line p = OUnit.assert_bool (spf "test at %d" line) p
|
|
let () = test __LINE__ @@ (of_list [ 1; 2; 3; 4 ] |> sorted)
|
|
let () = test __LINE__ @@ not (of_list [ 1; 2; 3; 0; 4 ] |> sorted)
|
|
let () = test __LINE__ @@ sorted empty
|
|
|
|
let () =
|
|
[ 1; 2; 3; 3; 2; 2; 3; 4 ] |> of_list |> group_succ_by ?eq:None |> to_list
|
|
|> OUnit.assert_equal [ [ 1 ]; [ 2 ]; [ 3; 3 ]; [ 2; 2 ]; [ 3 ]; [ 4 ] ]
|
|
|
|
let () =
|
|
[ 1; 2; 3; 3; 2; 2; 3; 4 ] |> of_list
|
|
|> group_by ?eq:None ?hash:None
|
|
|> sort ?cmp:None |> to_list
|
|
|> OUnit.assert_equal [ [ 1 ]; [ 2; 2; 2 ]; [ 3; 3; 3 ]; [ 4 ] ]
|
|
|
|
let () =
|
|
[ 1; 2; 3; 3; 2; 2; 3; 4 ] |> of_list |> count ?eq:None ?hash:None
|
|
|> sort ?cmp:None |> to_list
|
|
|> OUnit.assert_equal [ 1, 1; 2, 3; 3, 3; 4, 1 ]
|
|
|
|
let () =
|
|
[ 1; 2; 2; 3; 4; 4; 4; 3; 3 ]
|
|
|> of_list |> uniq ?eq:None |> to_list
|
|
|> OUnit.assert_equal [ 1; 2; 3; 4; 3 ]
|
|
|
|
let () =
|
|
[ 42; 1; 2; 3; 4; 5; 4; 3; 2; 1 ]
|
|
|> of_list |> sort_uniq ?cmp:None |> to_list
|
|
|> OUnit.assert_equal [ 1; 2; 3; 4; 5; 42 ]
|
|
|
|
let () =
|
|
let a = 0 -- 2 in
|
|
let b = of_list [ "a"; "b"; "c" ] in
|
|
let s =
|
|
product a b |> map (fun (x, y) -> y, x) |> to_list |> List.sort compare
|
|
in
|
|
OUnit.assert_equal
|
|
[ "a", 0; "a", 1; "a", 2; "b", 0; "b", 1; "b", 2; "c", 0; "c", 1; "c", 2 ]
|
|
s
|
|
|
|
let () =
|
|
OUnit.assert_equal [ 0, 1; 0, 2; 1, 2 ] (diagonal_l [ 0; 1; 2 ] |> to_list)
|
|
|
|
let () =
|
|
OUnit.assert_equal
|
|
[ 0, 1; 0, 2; 1, 2 ]
|
|
(of_list [ 0; 1; 2 ] |> diagonal |> to_list)
|
|
|
|
let () =
|
|
let s1 = 1 -- 3 in
|
|
let s2 = of_list [ "1"; "2" ] in
|
|
let join_row i j =
|
|
if string_of_int i = j then
|
|
Some (string_of_int i ^ " = " ^ j)
|
|
else
|
|
None
|
|
in
|
|
let s = join ~join_row s1 s2 in
|
|
OUnit.assert_equal [ "1 = 1"; "2 = 2" ] (to_list s);
|
|
()
|
|
|
|
let () =
|
|
OUnit.assert_equal
|
|
[ 'a', [ "abc"; "attic" ]; 'b', [ "barbary"; "boom"; "bop" ]; 'c', [] ]
|
|
(group_join_by
|
|
(fun s -> s.[0])
|
|
(of_str "abc")
|
|
(of_list [ "abc"; "boom"; "attic"; "deleted"; "barbary"; "bop" ])
|
|
|> map (fun (c, l) -> c, List.sort Stdlib.compare l)
|
|
|> sort |> to_list)
|
|
|
|
let () =
|
|
let f x =
|
|
if x < 5 then
|
|
Some (string_of_int x, x + 1)
|
|
else
|
|
None
|
|
in
|
|
unfoldr f 0 |> to_list |> OUnit.assert_equal [ "0"; "1"; "2"; "3"; "4" ]
|
|
|
|
let () =
|
|
1 -- 5 |> scan ( + ) 0 |> to_list
|
|
|> OUnit.assert_equal ~printer:pp_ilist [ 0; 1; 3; 6; 10; 15 ]
|
|
|
|
let test = OUnit.assert_equal ~printer:Q.Print.int
|
|
let () = test 100 (0 -- 100 |> max_exn ?lt:None)
|
|
let () = test 0 (0 -- 100 |> min_exn ?lt:None)
|
|
let () = OUnit.assert_equal 6 (of_list [ 1; 2; 3 ] |> sum)
|
|
|
|
let () =
|
|
let seq = of_list [ 10000.0; 3.14159; 2.71828 ] in
|
|
OUnit.assert_equal ~printer:string_of_float 10005.85987 (sumf seq)
|
|
|
|
let () =
|
|
let l = to_list (take 0 (of_list [ 1 ])) in
|
|
OUnit.assert_equal ~printer:pp_ilist [] l;
|
|
let l = to_list (take 5 (of_list [ 1; 2; 3; 4; 5; 6; 7; 8; 9; 10 ])) in
|
|
OUnit.assert_equal ~printer:pp_ilist [ 1; 2; 3; 4; 5 ] l;
|
|
()
|
|
|
|
let () =
|
|
let n =
|
|
of_list [ true; true; false; true ]
|
|
|> fold_while
|
|
(fun acc b ->
|
|
if b then
|
|
acc + 1, `Continue
|
|
else
|
|
acc, `Stop)
|
|
0
|
|
in
|
|
OUnit.assert_equal 2 n;
|
|
()
|
|
|
|
let () = 1 -- 5 |> drop 2 |> to_list |> OUnit.assert_equal [ 3; 4; 5 ]
|
|
let () = 1 -- 5 |> rev |> to_list |> OUnit.assert_equal [ 5; 4; 3; 2; 1 ]
|
|
|
|
let () =
|
|
OUnit.assert_bool "true" (for_all (fun x -> x < 10) (1 -- 9));
|
|
OUnit.assert_bool "false" (not (for_all (fun x -> x < 10) (2 -- 11)));
|
|
OUnit.assert_bool "true" (for_all (fun _ -> false) empty);
|
|
OUnit.assert_bool "nested"
|
|
(for_all
|
|
(fun seq -> not (for_all (fun x -> x < 8) seq))
|
|
(1 -- 10 >|= fun x -> x -- 20));
|
|
()
|
|
|
|
let () =
|
|
1 -- 100 |> exists (fun x -> x = 59) |> OUnit.assert_bool "exists";
|
|
1 -- 100
|
|
|> exists (fun x -> x < 0)
|
|
|> (fun x -> not x)
|
|
|> OUnit.assert_bool "not exists";
|
|
()
|
|
|
|
let () = 1 -- 1000 |> length |> OUnit.assert_equal 1000
|
|
|
|
let () =
|
|
let h = 1 -- 5 |> zip_i |> to_hashtbl in
|
|
0 -- 4 |> iter (fun i -> OUnit.assert_equal (i + 1) (Hashtbl.find h i));
|
|
OUnit.assert_equal [ 0; 1; 2; 3; 4 ]
|
|
(hashtbl_keys h |> sort ?cmp:None |> to_list);
|
|
()
|
|
|
|
let () =
|
|
let b = Buffer.create 4 in
|
|
let upp = function
|
|
| 'a' .. 'z' as c -> Char.chr (Char.code c - Char.code 'a' + Char.code 'A')
|
|
| c -> c
|
|
in
|
|
("hello world" |> of_str |> rev |> map upp |> fun seq -> to_buffer seq b);
|
|
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
|
|
()
|
|
|
|
let () =
|
|
OUnit.assert_equal ~printer:pp_ilist [ 1; 2; 3; 4 ] (to_list (1 -- 4));
|
|
OUnit.assert_equal ~printer:pp_ilist [ 10; 9; 8; 7; 6 ] (to_list (10 --^ 6));
|
|
OUnit.assert_equal ~printer:pp_ilist [] (to_list (10 -- 4));
|
|
OUnit.assert_equal ~printer:pp_ilist [] (to_list (10 --^ 60));
|
|
()
|
|
|
|
let test = OUnit.assert_equal ~printer:Q.Print.(list int)
|
|
let () = test [ 1; 2; 3; 4 ] (int_range_by ~step:1 1 4 |> to_list)
|
|
let () = test [ 4; 3; 2; 1 ] (int_range_by ~step:~-1 4 1 |> to_list)
|
|
let () = test [ 6; 4; 2 ] (int_range_by 6 1 ~step:~-2 |> to_list)
|
|
let () = test [] (int_range_by ~step:1 4 1 |> to_list)
|
|
|
|
let () =
|
|
add_qcheck __LINE__
|
|
Q.(pair small_int small_int)
|
|
(fun (i, j) ->
|
|
let i = Stdlib.min i j and j = Stdlib.max i j in
|
|
i -- j |> to_list = (int_range_by ~step:1 i j |> to_list))
|
|
|
|
let () =
|
|
add_qcheck __LINE__
|
|
Q.(pair small_int small_int)
|
|
(fun (i, j) ->
|
|
let i = Stdlib.min i j and j = Stdlib.max i j in
|
|
i -- j |> to_rev_list = (int_range_by ~step:~-1 j i |> to_list))
|
|
|
|
let array_for_all f a =
|
|
try
|
|
for i = 0 to Array.length a - 1 do
|
|
if not (f a.(i)) then raise Exit
|
|
done;
|
|
true
|
|
with Exit -> false
|
|
|
|
let () =
|
|
add_qcheck __LINE__
|
|
Q.(pair (list int) (1 -- 20))
|
|
(fun (l, n) ->
|
|
let seq = of_list l in
|
|
let a = sample n seq in
|
|
array_for_all (fun x -> exists (( = ) x) seq) a
|
|
&& Array.length a = Stdlib.min (length seq) n)
|
|
|
|
(* regression tests *)
|
|
|
|
let () =
|
|
let s = take 10 (repeat 1) in
|
|
OUnit.assert_bool "not empty" (not (is_empty s));
|
|
()
|
|
|
|
let with_tmp_file f =
|
|
let path = Filename.temp_file "test_iter" "data" in
|
|
try
|
|
let x = f path in
|
|
(try Sys.remove path with _ -> ());
|
|
x
|
|
with e ->
|
|
(try Sys.remove path with _ -> ());
|
|
raise e
|
|
|
|
let () =
|
|
with_tmp_file @@ fun path ->
|
|
Iter.IO.write_lines path Iter.empty;
|
|
let l = Iter.IO.lines_of path |> Iter.to_list in
|
|
OUnit.assert_equal ~printer:Q.Print.(list @@ Printf.sprintf "%S") [] l
|
|
|
|
let () =
|
|
let errcode = QCheck_base_runner.run_tests ~colors:false !qchecks in
|
|
if errcode <> 0 then exit errcode
|