From abf34dcc35087c0233b29aab7f5693b8540c03e5 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sat, 21 Oct 2017 12:47:12 -0400 Subject: [PATCH] Added unit minimal unit testing framework --- Makefile | 5 ++- lib/buf.ml | 9 +++++ lib/rope.ml | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/test.ml | 15 ++++++++ tests.ml | 3 ++ 5 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 lib/test.ml create mode 100644 tests.ml diff --git a/Makefile b/Makefile index 6ed9a5e..30f86ca 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,9 @@ endif # Target Definitions #------------------------------------------------------------------------------- -BINS = edit +BINS = edit tests LIBOBJS = \ + lib/test.$(OBJEXT) \ lib/misc.$(OBJEXT) \ lib/tide.$(OBJEXT) \ lib/x11.$(OBJEXT) \ @@ -38,12 +39,14 @@ LIBOBJS = \ .PHONY: all clean all: $(BINS) + ./tests clean: $(RM) deps.mk $(BINS) *.cm* *.o *.a *.so lib/*.cm* lib/*.o # Executable targets edit: tide.$(LIBEXT) edit.$(OBJEXT) +tests: tide.$(LIBEXT) tests.$(OBJEXT) # Library targets tide.$(LIBEXT): $(LIBOBJS) diff --git a/lib/buf.ml b/lib/buf.ml index 80e33fd..4a58ba7 100644 --- a/lib/buf.ml +++ b/lib/buf.ml @@ -1,3 +1,5 @@ +type item = Ch | Word | Line + type buf = { path : string; rope : Rope.t @@ -17,3 +19,10 @@ let saveas buf path = let save buf = saveas buf buf.path + +let move item count buf pos = + match item with + | Ch -> pos + count + | Word -> pos + count + | Line -> pos + count + diff --git a/lib/rope.ml b/lib/rope.ml index a2520e4..69dd58b 100644 --- a/lib/rope.ml +++ b/lib/rope.ml @@ -97,3 +97,106 @@ let gets rope i j = let to_string rope = gets rope 0 (length rope) + +(* Unit Tests *****************************************************************) + +let run_unit_tests () = + let open Test in + (* length() tests *) + test "length : 0 for empty string" (fun () -> + let rope = Leaf("", 0, 0) in + assert( length rope == 0 ) + ); + test "length : equal to length of leaf" (fun () -> + let rope = Leaf("a", 0, 1) in + assert( length rope == 1 ) + ); + test "length : equal to sum of leaf lengths" (fun () -> + let rope = (join (Leaf("a", 0, 1)) (Leaf("a", 0, 1))) in + assert( length rope == 2 ) + ); + + (* join() tests *) + test "join : join two leaves into rope" (fun () -> + let left = Leaf("a", 0, 1) in + let right = Leaf("a", 0, 1) in + let rope = (join left right) in + assert( match rope with + | Node (l,r,2) -> (l == left && r == right) + | _ -> false) + ); + test "join : join a rope with a leaf (l to r)" (fun () -> + let left = join (Leaf("a", 0, 1)) (Leaf("a", 0, 1)) in + let right = Leaf("a", 0, 1) in + let rope = (join left right) in + assert( match rope with + | Node (l,r,3) -> (l == left && r == right) + | _ -> false) + ); + test "join : join a rope with a leaf (r to l)" (fun () -> + let left = Leaf("a", 0, 1) in + let right = join (Leaf("a", 0, 1)) (Leaf("a", 0, 1)) in + let rope = (join left right) in + assert( match rope with + | Node (l,r,3) -> (l == left && r == right) + | _ -> false) + ); + + (* getc() tests *) + test "getc : raise Out_of_bounds on negative index" (fun () -> + let rope = Leaf("a", 0, 1) in + try getc rope (-1); assert false + with Out_of_bounds _ -> assert true + ); + test "getc : raise Out_of_bounds on out of bounds index" (fun () -> + let rope = Leaf("a", 0, 1) in + try getc rope (2); assert false + with Out_of_bounds _ -> assert true + ); + test "getc : return index 0 of leaf" (fun () -> + let rope = Leaf("abc", 0, 3) in + assert( (getc rope (0)) == 'a' ); + ); + test "getc : return index 1 of leaf" (fun () -> + let rope = Leaf("abc", 0, 3) in + assert( (getc rope (1)) == 'b' ); + ); + test "getc : return index 2 of leaf" (fun () -> + let rope = Leaf("abc", 0, 3) in + assert( (getc rope (2)) == 'c' ); + ); + test "getc : return index 0 of rope" (fun () -> + let rope = Node((Leaf("a", 0, 1)), (Leaf("b", 0, 1)), 2) in + assert( (getc rope (0)) == 'a' ); + ); + test "getc : return index 1 of rope" (fun () -> + let rope = Node((Leaf("a", 0, 1)), (Leaf("b", 0, 1)), 2) in + assert( (getc rope (1)) == 'b' ); + ); + + (* puts() tests *) + test "puts : insert at index 0" (fun () -> + let rope = Leaf("bc", 0, 2) in + let rope = (puts rope "a" 0) in + assert( (length rope) == 3 ); + assert( (getc rope (0)) == 'a' ); + assert( (getc rope (1)) == 'b' ); + assert( (getc rope (2)) == 'c' ); + ); + test "puts : insert at index 1" (fun () -> + let rope = Leaf("ac", 0, 2) in + let rope = (puts rope "b" 1) in + assert( (length rope) == 3 ); + assert( (getc rope (0)) == 'a' ); + assert( (getc rope (1)) == 'b' ); + assert( (getc rope (2)) == 'c' ); + ); + test "puts : insert index at 2" (fun () -> + let rope = Leaf("ab", 0, 2) in + let rope = (puts rope "c" 2) in + assert( (length rope) == 3 ); + assert( (getc rope (0)) == 'a' ); + assert( (getc rope (1)) == 'b' ); + assert( (getc rope (2)) == 'c' ); + ); + () diff --git a/lib/test.ml b/lib/test.ml new file mode 100644 index 0000000..de90100 --- /dev/null +++ b/lib/test.ml @@ -0,0 +1,15 @@ +let passed = ref 0 +let failed = ref 0 + +let test name testfn = + try + (testfn ()); + passed := !passed + 1 + with e -> + Printf.printf "FAIL: %s\n %s\n" name (Printexc.to_string e); + failed := !failed + 1 + +let report_results () = + Printf.printf "%d tests, %d passed, %d failed\n" + (!passed + !failed) !passed !failed; + if (!failed > 0) then (exit 1) else (exit 0) diff --git a/tests.ml b/tests.ml new file mode 100644 index 0000000..c58c2f1 --- /dev/null +++ b/tests.ml @@ -0,0 +1,3 @@ +let () = + Rope.run_unit_tests (); + Test.report_results () -- 2.52.0