From 0aaf51f73927b21462b1d3aa079671491636cc63 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sun, 24 Apr 2016 23:47:16 +0200 Subject: [PATCH] move files to 'src/', use qtest for tests --- .ocamlinit | 4 +- Makefile | 20 +- _oasis | 25 +- _tags | 2 +- sequenceLabels.ml | 1 - .../bigarray}/sequenceBigarray.ml | 0 .../bigarray}/sequenceBigarray.mli | 0 {invert => src/invert}/.merlin | 0 {invert => src/invert}/sequenceInvert.ml | 0 {invert => src/invert}/sequenceInvert.mli | 0 sequence.ml => src/sequence.ml | 233 ++++++++++++++++ sequence.mli => src/sequence.mli | 0 src/sequenceLabels.ml | 1 + sequenceLabels.mli => src/sequenceLabels.mli | 0 tests/run_tests.ml | 9 - tests/test_sequence.ml | 263 ------------------ 16 files changed, 268 insertions(+), 290 deletions(-) delete mode 100644 sequenceLabels.ml rename {bigarray => src/bigarray}/sequenceBigarray.ml (100%) rename {bigarray => src/bigarray}/sequenceBigarray.mli (100%) rename {invert => src/invert}/.merlin (100%) rename {invert => src/invert}/sequenceInvert.ml (100%) rename {invert => src/invert}/sequenceInvert.mli (100%) rename sequence.ml => src/sequence.ml (78%) rename sequence.mli => src/sequence.mli (100%) create mode 120000 src/sequenceLabels.ml rename sequenceLabels.mli => src/sequenceLabels.mli (100%) delete mode 100644 tests/run_tests.ml delete mode 100644 tests/test_sequence.ml diff --git a/.ocamlinit b/.ocamlinit index 7123b8d..c753a9f 100644 --- a/.ocamlinit +++ b/.ocamlinit @@ -1,9 +1,9 @@ -#directory "_build";; +#directory "_build/src";; #load "sequence.cma";; open Sequence.Infix;; -#directory "_build/bigarray/";; +#directory "_build/src/bigarray/";; #load "bigarray.cma";; (* vim:syntax=ocaml *) diff --git a/Makefile b/Makefile index cdc0e22..9908566 100644 --- a/Makefile +++ b/Makefile @@ -40,8 +40,24 @@ configure: # OASIS_STOP -run-tests: - ./run_tests.native +QTEST_PREAMBLE='' +DONTTEST=src/sequenceLabels.ml +QTESTABLE=$(filter-out $(DONTTEST), \ + $(wildcard src/*.ml) \ + $(wildcard src/*.mli) \ + ) + +qtest-clean: + @rm -rf qtest/ + +qtest-gen: + @mkdir -p qtest + @if which qtest > /dev/null ; then \ + qtest extract --preamble $(QTEST_PREAMBLE) \ + -o qtest/run_qtest.ml \ + $(QTESTABLE) 2> /dev/null ; \ + else touch qtest/run_qtest.ml ; \ + fi examples: ocamlbuild examples/test_sexpr.native diff --git a/_oasis b/_oasis index 10d80fa..51f1ac9 100644 --- a/_oasis +++ b/_oasis @@ -28,12 +28,12 @@ Flag bigarray Default: true Library "sequence" - Path: . + Path: src/ Modules: Sequence, SequenceLabels BuildDepends: bytes Library "invert" - Path: invert + Path: src/invert Build$: flag(invert) Install$: flag(invert) Modules: SequenceInvert @@ -42,7 +42,7 @@ Library "invert" BuildDepends: sequence,delimcc Library "bigarray" - Path: bigarray + Path: src/bigarray Build$: flag(bigarray) Install$: flag(bigarray) Modules: SequenceBigarray @@ -58,19 +58,20 @@ Document sequence XOCamlbuildPath: . XOCamlbuildLibraries: sequence -Test all - Type: custom - Command: make run-tests - TestTools: run_tests - Run$: flag(tests) +PreBuildCommand: make qtest-gen -Executable run_tests - Path: tests/ +Executable run_qtest + Path: qtest/ Install: false CompiledObject: native - MainIs: run_tests.ml + MainIs: run_qtest.ml Build$: flag(tests) - BuildDepends: sequence,oUnit + BuildDepends: sequence, qcheck + +Test all + Command: ./run_qtest.native + TestTools: run_qtest + Run$: flag(tests) Executable benchs Path: bench diff --git a/_tags b/_tags index 67a541e..6158cde 100644 --- a/_tags +++ b/_tags @@ -30,4 +30,4 @@ true: bin_annot <**/*.ml>: warn_A, warn(-4) true: mark_tag_used -: nolabels +: nolabels diff --git a/sequenceLabels.ml b/sequenceLabels.ml deleted file mode 100644 index fb15e92..0000000 --- a/sequenceLabels.ml +++ /dev/null @@ -1 +0,0 @@ -include Sequence diff --git a/bigarray/sequenceBigarray.ml b/src/bigarray/sequenceBigarray.ml similarity index 100% rename from bigarray/sequenceBigarray.ml rename to src/bigarray/sequenceBigarray.ml diff --git a/bigarray/sequenceBigarray.mli b/src/bigarray/sequenceBigarray.mli similarity index 100% rename from bigarray/sequenceBigarray.mli rename to src/bigarray/sequenceBigarray.mli diff --git a/invert/.merlin b/src/invert/.merlin similarity index 100% rename from invert/.merlin rename to src/invert/.merlin diff --git a/invert/sequenceInvert.ml b/src/invert/sequenceInvert.ml similarity index 100% rename from invert/sequenceInvert.ml rename to src/invert/sequenceInvert.ml diff --git a/invert/sequenceInvert.mli b/src/invert/sequenceInvert.mli similarity index 100% rename from invert/sequenceInvert.mli rename to src/invert/sequenceInvert.mli diff --git a/sequence.ml b/src/sequence.ml similarity index 78% rename from sequence.ml rename to src/sequence.ml index 0a3bff5..8257960 100644 --- a/sequence.ml +++ b/src/sequence.ml @@ -11,6 +11,10 @@ type 'a sequence = 'a t type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit (** Sequence of pairs of values of type ['a] and ['b]. *) +(*$inject + let pp_ilist = Q.Print.(list int) +*) + (** Build a sequence from a iter function *) let from_iter f = f @@ -20,6 +24,13 @@ let rec from_fun f k = match f () with let empty _ = () +(*$R + 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 singleton x k = k x let return x k = k x let pure f k = k f @@ -31,6 +42,12 @@ let snoc l x k = l k; k x let repeat x k = while true do k x done +(*$R + let seq = repeat "hello" in + OUnit.assert_equal ["hello"; "hello"; "hello"] + (seq |> take 3 |> to_list); +*) + let rec iterate f x k = k x; iterate f (f x) k @@ -55,6 +72,12 @@ let fold f init seq = seq (fun elt -> r := f !r elt); !r +(*$R + let n = (1 -- 10) + |> fold (+) 0 in + OUnit.assert_equal 55 n; +*) + let foldi f init seq = let i = ref 0 in let r = ref init in @@ -64,6 +87,13 @@ let foldi f init seq = incr i); !r +(*$R + let l = ["hello"; "world"] + |> of_list + |> foldi (fun acc i x -> (i,x) :: acc) [] in + OUnit.assert_equal [1, "world"; 0, "hello"] l; +*) + let map f seq k = seq (fun x -> k (f x)) let mapi f seq k = @@ -86,12 +116,34 @@ let append s1 s2 k = s1 k; s2 k let concat s k = s (fun s' -> s' k) +(*$R + 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)); +*) + +(*$R + (1 -- 1000) + |> map (fun i -> i -- (i+1)) + |> concat + |> length + |> OUnit.assert_equal 2000 +*) + let flatten s = concat s let flatMap f seq k = seq (fun x -> f x k) let flat_map = flatMap +(*$R + (1 -- 1000) + |> flat_map (fun i -> i -- (i+1)) + |> length + |> OUnit.assert_equal 2000 +*) + let flat_map_l f seq k = seq (fun x -> List.iter k (f x)) @@ -107,6 +159,14 @@ let intersperse elem seq k = let first = ref true in seq (fun x -> (if !first then first := false else k elem); k x) +(*$R + (1 -- 100) + |> (fun seq -> intersperse 0 seq) + |> take 10 + |> to_list + |> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0] +*) + (** Mutable unrolled list to serve as intermediate storage *) module MList = struct type 'a node = @@ -207,6 +267,35 @@ let persistent seq = let l = MList.of_seq seq in MList.to_seq l +(*$R + let printer = pp_ilist in + let stream = Stream.from (fun i -> if i < 5 then Some i else None) in + let seq = of_stream stream in + OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> to_list); + OUnit.assert_equal ~printer [] (seq |> to_list); +*) + +(*$R + let printer = pp_ilist in + let stream = Stream.from (fun i -> if i < 5 then Some i else None) in + let seq = of_stream stream in + (* consume seq into a persistent version of itself *) + let seq' = persistent seq in + OUnit.assert_equal ~printer [] (seq |> to_list); + OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list); + OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list); + OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_stream |> of_stream |> to_list); +*) + +(*$R + let printer = pp_ilist in + let seq = (0 -- 10_000) in + let seq' = persistent seq in + OUnit.assert_equal 10_001 (length seq'); + OUnit.assert_equal 10_001 (length seq'); + OUnit.assert_equal ~printer [0;1;2;3] (seq' |> take 4 |> to_list); +*) + type 'a lazy_state = | LazySuspend | LazyCached of 'a t @@ -227,6 +316,14 @@ let sort ?(cmp=Pervasives.compare) seq = let l = List.fast_sort cmp l in fun k -> List.iter k l +(*$R + (1 -- 100) + |> sort ~cmp:(fun i j -> j - i) + |> take 4 + |> to_list + |> OUnit.assert_equal [100;99;98;97] +*) + let group_succ_by ?(eq=fun x y -> x = y) seq k = let cur = ref [] in seq (fun x -> @@ -242,6 +339,12 @@ let group_succ_by ?(eq=fun x y -> x = y) seq k = let group = group_succ_by +(*$R + [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 group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq = let module Tbl = Hashtbl.Make(struct type t = k @@ -258,6 +361,12 @@ let group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq = fun yield -> Tbl.iter (fun _ l -> yield l) tbl +(*$R + [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 uniq ?(eq=fun x y -> x = y) seq k = let has_prev = ref false and prev = ref (Obj.magic 0) in (* avoid option type, costly *) @@ -271,6 +380,12 @@ let uniq ?(eq=fun x y -> x = y) seq k = k x )) +(*$R + [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 sort_uniq (type elt) ?(cmp=Pervasives.compare) seq = let module S = Set.Make(struct type t = elt @@ -279,9 +394,28 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq = let set = fold (fun acc x -> S.add x acc) S.empty seq in fun k -> S.iter k set +(*$R + [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 product outer inner k = outer (fun x -> inner (fun y -> k (x,y))) +(*$R + let stream = Stream.from (fun i -> if i < 3 then Some i else None) in + let a = of_stream stream 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 product2 outer inner k = outer (fun x -> inner (fun y -> k x y)) @@ -292,17 +426,41 @@ let join ~join_row s1 s2 k = | None -> () | Some c -> k c)) +(*$R + 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 rec unfoldr f b k = match f b with | None -> () | Some (x, b') -> k x; unfoldr f b' k +(*$R + 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 scan f acc seq k = k acc; let acc = ref acc in seq (fun elt -> let acc' = f !acc elt in k acc'; acc := acc') +(*$R + (1 -- 5) + |> scan (+) 0 + |> to_list + |> OUnit.assert_equal ~printer:pp_ilist [0;1;3;6;10;15] +*) + let max ?(lt=fun x y -> x < y) seq = let ret = ref None in seq @@ -344,6 +502,13 @@ let take n seq k = k x) with ExitTake -> () +(*$R + 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; +*) + exception ExitTakeWhile let take_while p seq k = @@ -365,11 +530,20 @@ let fold_while f s seq = try seq consume; !state with ExitFoldWhile -> !state +(*$R + 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 drop n seq k = let count = ref 0 in seq (fun x -> if !count >= n then k x else incr count) +(*$R + (1 -- 5) |> drop 2 |> to_list |> OUnit.assert_equal [3;4;5] +*) + let drop_while p seq k = let drop = ref true in seq @@ -382,6 +556,10 @@ let rev seq = let l = MList.of_seq seq in fun k -> MList.iter_rev k l +(*$R + (1 -- 5) |> rev |> to_list |> OUnit.assert_equal [5;4;3;2;1] +*) + exception ExitForall let for_all p seq = @@ -390,6 +568,16 @@ let for_all p seq = true with ExitForall -> false +(*$R + 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)); +*) + exception ExitExists (** Exists there some element satisfying the predicate? *) @@ -399,6 +587,16 @@ let exists p seq = false with ExitExists -> true +(*$R + (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 mem ?(eq=(=)) x seq = exists (eq x) seq exception ExitFind @@ -420,6 +618,10 @@ let length seq = seq (fun _ -> incr r); !r +(*$R + (1 -- 1000) |> length |> OUnit.assert_equal 1000 +*) + exception ExitIsEmpty let is_empty seq = @@ -522,6 +724,15 @@ let of_queue q k = Queue.iter k q let hashtbl_add h seq = seq (fun (k,v) -> Hashtbl.add h k v) +(*$R + let h = (1 -- 5) + |> zip_i + |> to_hashtbl2 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 hashtbl_replace h seq = seq (fun (k,v) -> Hashtbl.replace h k v) @@ -573,10 +784,25 @@ let of_in_channel ic = let to_buffer seq buf = seq (fun c -> Buffer.add_char buf c) +(*$R + let b = Buffer.create 4 in + "hello world" + |> of_str |> rev |> map Char.uppercase + |> (fun seq -> to_buffer seq b); + OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b); +*) + (** Iterator on integers in [start...stop] by steps 1 *) let int_range ~start ~stop k = for i = start to stop do k i done +(*$R + 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 int_range_dec ~start ~stop k = for i = start downto stop do k i done @@ -879,3 +1105,10 @@ module IO = struct let write_lines ?mode ?flags filename seq = write_bytes_lines ?mode ?flags filename (map Bytes.unsafe_of_string seq) end + +(* regression tests *) + +(*$R + let s = (take 10 (repeat 1)) in + OUnit.assert_bool "not empty" (not (is_empty s)); +*) diff --git a/sequence.mli b/src/sequence.mli similarity index 100% rename from sequence.mli rename to src/sequence.mli diff --git a/src/sequenceLabels.ml b/src/sequenceLabels.ml new file mode 120000 index 0000000..663d7cb --- /dev/null +++ b/src/sequenceLabels.ml @@ -0,0 +1 @@ +sequence.ml \ No newline at end of file diff --git a/sequenceLabels.mli b/src/sequenceLabels.mli similarity index 100% rename from sequenceLabels.mli rename to src/sequenceLabels.mli diff --git a/tests/run_tests.ml b/tests/run_tests.ml deleted file mode 100644 index 0fa3d58..0000000 --- a/tests/run_tests.ml +++ /dev/null @@ -1,9 +0,0 @@ - -open OUnit - -let suite = - "run_tests" >::: - [ Test_sequence.suite; ] - -let _ = - OUnit.run_test_tt_main suite diff --git a/tests/test_sequence.ml b/tests/test_sequence.ml deleted file mode 100644 index 0c0a23b..0000000 --- a/tests/test_sequence.ml +++ /dev/null @@ -1,263 +0,0 @@ - -open OUnit - -module S = Sequence - -let pp_ilist l = - let b = Buffer.create 15 in - let fmt = Format.formatter_of_buffer b in - Format.fprintf fmt "@[%a@]" (S.pp_seq Format.pp_print_int) (S.of_list l); - Buffer.contents b - -let test_empty () = - let seq = S.empty in - OUnit.assert_bool "empty" (S.is_empty seq); - OUnit.assert_bool "empty" - (try S.iter (fun _ -> raise Exit) seq; true with Exit -> false); - () - -let test_repeat () = - let seq = S.repeat "hello" in - OUnit.assert_equal ["hello"; "hello"; "hello"] - (seq |> S.take 3 |> S.to_list); - () - -let test_concat () = - let s1 = S.(1 -- 5) in - let s2 = S.(6 -- 10) in - let l = [1;2;3;4;5;6;7;8;9;10] in - OUnit.assert_equal l (S.to_list (S.append s1 s2)); - () - -let test_fold () = - let n = S.(1 -- 10) - |> S.fold (+) 0 in - OUnit.assert_equal 55 n; - () - -let test_foldi () = - let l = ["hello"; "world"] - |> S.of_list - |> S.foldi (fun acc i x -> (i,x) :: acc) [] in - OUnit.assert_equal [1, "world"; 0, "hello"] l; - () - -let test_fold_while () = - let n = S.of_list [true;true;false;true] - |> S.fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 in - OUnit.assert_equal 2 n; - () - -let test_exists () = - S.(1 -- 100) - |> S.exists (fun x -> x = 59) - |> OUnit.assert_bool "exists"; - S.(1 -- 100) - |> S.exists (fun x -> x < 0) - |> (fun x -> not x) - |> OUnit.assert_bool "not exists"; - () - -let test_length () = - S.(1 -- 1000) |> S.length |> OUnit.assert_equal 1000 - -let test_concat2 () = - S.(1 -- 1000) - |> S.map (fun i -> S.(i -- (i+1))) - |> S.concat - |> S.length - |> OUnit.assert_equal 2000 - -let test_flat_map () = - S.(1 -- 1000) - |> S.flat_map (fun i -> S.(i -- (i+1))) - |> S.length - |> OUnit.assert_equal 2000 - -let test_intersperse () = - S.(1 -- 100) - |> (fun seq -> S.intersperse 0 seq) - |> S.take 10 - |> S.to_list - |> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0] - -let test_not_persistent () = - let printer = pp_ilist in - let stream = Stream.from (fun i -> if i < 5 then Some i else None) in - let seq = S.of_stream stream in - OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> S.to_list); - OUnit.assert_equal ~printer [] (seq |> S.to_list); - () - -let test_persistent () = - let printer = pp_ilist in - let stream = Stream.from (fun i -> if i < 5 then Some i else None) in - let seq = S.of_stream stream in - (* consume seq into a persistent version of itself *) - let seq' = S.persistent seq in - OUnit.assert_equal ~printer [] (seq |> S.to_list); - OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list); - OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list); - OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_stream |> S.of_stream |> S.to_list); - () - -let test_big_persistent () = - let printer = pp_ilist in - let seq = S.(0 -- 10_000) in - let seq' = S.persistent seq in - OUnit.assert_equal 10_001 (S.length seq'); - OUnit.assert_equal 10_001 (S.length seq'); - OUnit.assert_equal ~printer [0;1;2;3] (seq' |> S.take 4 |> S.to_list); - () - -let test_sort () = - S.(1 -- 100) - |> S.sort ~cmp:(fun i j -> j - i) - |> S.take 4 - |> S.to_list - |> OUnit.assert_equal [100;99;98;97] - -let test_sort_uniq () = - [42;1;2;3;4;5;4;3;2;1] - |> S.of_list - |> S.sort_uniq ?cmp:None - |> S.to_list - |> OUnit.assert_equal [1;2;3;4;5;42] - -let test_group_succ () = - [1;2;3;3;2;2;3;4] - |> S.of_list |> S.group_succ_by ?eq:None |> S.to_list - |> OUnit.assert_equal [[1];[2];[3;3];[2;2];[3];[4]] - -let test_group_by () = - [1;2;3;3;2;2;3;4] - |> S.of_list |> S.group_by ?eq:None ?hash:None |> S.sort ?cmp:None |> S.to_list - |> OUnit.assert_equal [[1];[2;2;2];[3;3;3];[4]] - -let test_uniq () = - [1;2;2;3;4;4;4;3;3] - |> S.of_list |> S.uniq ?eq:None |> S.to_list - |> OUnit.assert_equal [1;2;3;4;3] - -let test_product () = - let stream = Stream.from (fun i -> if i < 3 then Some i else None) in - let a = S.of_stream stream in - let b = S.of_list ["a";"b";"c"] in - let s = S.product a b |> S.map (fun (x,y) -> y,x) - |> S.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 test_join () = - let s1 = S.(1 -- 3) in - let s2 = S.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 = S.join ~join_row s1 s2 in - OUnit.assert_equal ["1 = 1"; "2 = 2"] (S.to_list s); - () - -let test_scan () = - S.(1 -- 5) - |> S.scan (+) 0 - |> S.to_list - |> OUnit.assert_equal ~printer:pp_ilist [0;1;3;6;10;15] - -let test_drop () = - S.(1 -- 5) |> S.drop 2 |> S.to_list |> OUnit.assert_equal [3;4;5] - -let test_rev () = - S.(1 -- 5) |> S.rev |> S.to_list |> OUnit.assert_equal [5;4;3;2;1] - -let test_unfoldr () = - let f x = if x < 5 then Some (string_of_int x,x+1) else None in - S.unfoldr f 0 - |> S.to_list - |> OUnit.assert_equal ["0"; "1"; "2"; "3"; "4"] - -let test_hashtbl () = - let h = S.(1 -- 5) - |> S.zip_i - |> S.to_hashtbl2 in - S.(0 -- 4) - |> S.iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i)); - OUnit.assert_equal [0;1;2;3;4] (S.hashtbl_keys h |> S.sort ?cmp:None |> S.to_list); - () - -let test_buff () = - let b = Buffer.create 4 in - "hello world" - |> S.of_str |> S.rev |> S.map Char.uppercase - |> (fun seq -> S.to_buffer seq b); - OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b); - () - -let test_int_range () = - OUnit.assert_equal ~printer:pp_ilist [1;2;3;4] S.(to_list (1--4)); - OUnit.assert_equal ~printer:pp_ilist [10;9;8;7;6] S.(to_list (10 --^ 6)); - OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10--4)); - OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10 --^ 60)); - () - -let test_take () = - let l = S.(to_list (take 0 (of_list [1]))) in - OUnit.assert_equal ~printer:pp_ilist [] l; - let l = S.(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 test_for_all () = - OUnit.assert_bool "true" S.(for_all (fun x -> x < 10) (1--9)); - OUnit.assert_bool "false" S.(not (for_all (fun x -> x < 10) (2--11))); - OUnit.assert_bool "true" S.(for_all (fun _ -> false) empty); - OUnit.assert_bool "nested" - S.( - for_all - (fun seq -> - not (for_all (fun x -> x < 8) seq) - ) (1 -- 10 >|= fun x -> x--20) - ); - () - -let test_regression1 () = - let s = S.(take 10 (repeat 1)) in - OUnit.assert_bool "not empty" (not (S.is_empty s)); - () - -let suite = - "test_sequence" >::: - [ "test_empty" >:: test_empty; - "test_repeat" >:: test_repeat; - "test_concat" >:: test_concat; - "test_concat2" >:: test_concat2; - "test_fold" >:: test_fold; - "test_foldi" >:: test_foldi; - "test_exists" >:: test_exists; - "test_length" >:: test_length; - "test_concat" >:: test_concat; - "test_flatMap" >:: test_flat_map; - "test_intersperse" >:: test_intersperse; - "test_not_persistent" >:: test_not_persistent; - "test_persistent" >:: test_persistent; - "test_big_persistent" >:: test_big_persistent; - "test_sort" >:: test_sort; - "test_sort_uniq" >:: test_sort_uniq; - "test_group_succ_by" >:: test_group_succ; - "test_group_by" >:: test_group_by; - "test_uniq" >:: test_uniq; - "test_product" >:: test_product; - "test_join" >:: test_join; - "test_scan" >:: test_scan; - "test_drop" >:: test_drop; - "test_rev" >:: test_rev; - "test_unfoldr" >:: test_unfoldr; - "test_hashtbl" >:: test_hashtbl; - "test_int_range" >:: test_int_range; - "test_take" >:: test_take; - "test_fold_while" >:: test_fold_while; - "test_buff" >:: test_buff; - "test_for_all" >:: test_for_all; - "test_regression1" >:: test_regression1; - ]