trackler 2.0.3.2 → 2.0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +10 -0
- data/tracks/c/exercises/robot-simulator/makefile +16 -0
- data/tracks/c/exercises/robot-simulator/src/example.c +74 -0
- data/tracks/c/exercises/robot-simulator/src/robot_simulator.h +41 -0
- data/tracks/c/exercises/robot-simulator/test/test_robot_simulator.c +165 -0
- data/tracks/c/exercises/robot-simulator/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/robot-simulator/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/robot-simulator/test/vendor/unity_internals.h +701 -0
- data/tracks/ecmascript/exercises/rna-transcription/example.js +9 -2
- data/tracks/ecmascript/exercises/rna-transcription/rna-transcription.spec.js +18 -0
- data/tracks/go/exercises/hello-world/example.go +4 -2
- data/tracks/go/exercises/hello-world/hello_test.go +4 -4
- data/tracks/go/exercises/hello-world/hello_world.go +6 -6
- data/tracks/groovy/config.json +5 -0
- data/tracks/groovy/exercises/phone-number/Example.groovy +20 -0
- data/tracks/groovy/exercises/phone-number/PhoneNumberSpec.groovy +75 -0
- data/tracks/haskell/exercises/difference-of-squares/test/Tests.hs +2 -0
- data/tracks/java/config.json +13 -1
- data/tracks/java/exercises/all-your-base/build.gradle +17 -0
- data/tracks/java/exercises/all-your-base/src/example/java/BaseConverter.java +80 -0
- data/tracks/java/exercises/all-your-base/src/main/java/BaseConverter.java +5 -0
- data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +256 -0
- data/tracks/java/exercises/binary-search/build.gradle +17 -0
- data/tracks/java/exercises/binary-search/src/example/java/BinarySearch.java +40 -0
- data/tracks/java/exercises/binary-search/src/main/java/.keep +0 -0
- data/tracks/java/exercises/binary-search/src/main/java/BinarySearch.java +4 -0
- data/tracks/java/exercises/binary-search/src/test/java/.keep +0 -0
- data/tracks/java/exercises/binary-search/src/test/java/BinarySearchTest.java +136 -0
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/lua/config.json +16 -0
- data/tracks/lua/exercises/say/example.lua +92 -0
- data/tracks/lua/exercises/say/say_spec.lua +105 -0
- data/tracks/lua/exercises/secret-handshake/example.lua +17 -0
- data/tracks/lua/exercises/secret-handshake/secret-handshake_spec.lua +38 -0
- data/tracks/ocaml/config.json +10 -1
- data/tracks/ocaml/exercises/bracket-push/.merlin +3 -0
- data/tracks/ocaml/exercises/bracket-push/Makefile +11 -0
- data/tracks/ocaml/exercises/bracket-push/bracket_push.mli +3 -0
- data/tracks/ocaml/exercises/bracket-push/example.ml +40 -0
- data/tracks/ocaml/exercises/bracket-push/test.ml +38 -0
- data/tracks/ocaml/exercises/leap/test.ml +7 -7
- data/tracks/ocaml/tools/test-generator/Makefile +2 -2
- data/tracks/ocaml/tools/test-generator/interfaces/codegen.mli +2 -2
- data/tracks/ocaml/tools/test-generator/interfaces/{test_generator.mli → controller.mli} +0 -0
- data/tracks/ocaml/tools/test-generator/interfaces/parser.mli +7 -1
- data/tracks/ocaml/tools/test-generator/interfaces/special_cases.mli +2 -2
- data/tracks/ocaml/tools/test-generator/interfaces/utils.mli +4 -0
- data/tracks/ocaml/tools/test-generator/src/codegen.ml +9 -5
- data/tracks/ocaml/tools/test-generator/src/{test_generator.ml → controller.ml} +24 -15
- data/tracks/ocaml/tools/test-generator/src/model.ml +6 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +34 -7
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +11 -4
- data/tracks/ocaml/tools/test-generator/src/template.ml +49 -6
- data/tracks/ocaml/tools/test-generator/src/test_gen.ml +1 -1
- data/tracks/ocaml/tools/test-generator/src/utils.ml +6 -0
- data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/bracket-push/template.ml +16 -0
- data/tracks/ocaml/tools/test-generator/templates/difference-of-squares/template.ml +19 -0
- data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/hello-world/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/leap/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/templates/say/template.ml +3 -3
- data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +2 -2
- data/tracks/ocaml/tools/test-generator/test/all_tests.ml +3 -1
- data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +7 -7
- data/tracks/ocaml/tools/test-generator/test/difference_of_squares.json +67 -0
- data/tracks/ocaml/tools/test-generator/test/hello_world.json +23 -0
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +30 -12
- data/tracks/ocaml/tools/test-generator/test/sample-suite-template.txt +16 -0
- data/tracks/ocaml/tools/test-generator/test/sample_template.txt +2 -2
- data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +1 -1
- data/tracks/ocaml/tools/test-generator/test/template_test.ml +40 -6
- data/tracks/perl6/.travis.yml +3 -0
- data/tracks/perl6/docs/RESOURCES.md +1 -1
- data/tracks/perl6/exercises/accumulate/accumulate.t +3 -7
- data/tracks/perl6/exercises/anagram/anagram.t +3 -7
- data/tracks/perl6/exercises/binary/binary.t +3 -7
- data/tracks/perl6/exercises/bob/bob.t +4 -8
- data/tracks/perl6/exercises/grains/grains.t +3 -7
- data/tracks/perl6/exercises/leap/leap.t +3 -7
- data/tracks/perl6/exercises/rna-transcription/rna_transcription.t +4 -8
- data/tracks/perl6/exercises/robot-name/robot.t +4 -8
- data/tracks/perl6/exercises/scrabble-score/scrabble_score.t +3 -7
- data/tracks/perl6/exercises/word-count/word_count.t +3 -8
- data/tracks/r/config.json +10 -0
- data/tracks/r/docs/ABOUT.md +14 -0
- data/tracks/r/exercises/difference-of-squares/difference-of-squares.R +5 -0
- data/tracks/r/exercises/difference-of-squares/example.R +6 -0
- data/tracks/r/exercises/difference-of-squares/test_difference-of-squares.R +23 -0
- data/tracks/r/exercises/hamming/example.R +8 -0
- data/tracks/r/exercises/hamming/hamming.R +4 -0
- data/tracks/r/exercises/hamming/test_hamming.R +87 -0
- data/tracks/ruby/exercises/binary/.version +1 -1
- data/tracks/ruby/exercises/binary/binary_test.rb +17 -19
- data/tracks/ruby/exercises/binary/example.rb +13 -13
- data/tracks/ruby/exercises/isogram/.version +1 -1
- data/tracks/ruby/exercises/isogram/example.rb +1 -1
- data/tracks/ruby/exercises/isogram/isogram_test.rb +16 -30
- data/tracks/ruby/lib/binary_cases.rb +2 -3
- data/tracks/ruby/lib/isogram_cases.rb +1 -5
- data/tracks/scala/exercises/phone-number/HINTS.md +9 -0
- metadata +45 -4
@@ -3,22 +3,65 @@ open Core.Std
|
|
3
3
|
open Codegen
|
4
4
|
open Utils
|
5
5
|
|
6
|
-
(* start and finish are the lines where the generated code
|
7
|
-
type t = {start: int;
|
6
|
+
(* start and finish are the lines where the generated code should be copied *)
|
7
|
+
type t = {start: int;
|
8
|
+
finish: int;
|
9
|
+
file_text: string;
|
10
|
+
template: string;
|
11
|
+
suite_name_line: int option;
|
12
|
+
suite_end: int option;
|
13
|
+
suite_all_names_line: int option;
|
14
|
+
} [@@deriving eq, show]
|
8
15
|
|
9
16
|
let find_template ~(template_text: string): t option =
|
10
17
|
let open Option.Monad_infix in
|
11
18
|
let str_contains pattern s = String.substr_index s ~pattern |> Option.is_some in
|
12
19
|
let lines = String.split_lines template_text |> List.to_array in
|
13
|
-
let
|
14
|
-
let
|
20
|
+
let suite_end = find_arrayi lines ~f:(str_contains "(* END SUITE *)") |> Option.map ~f:fst in
|
21
|
+
let start_index = find_arrayi lines ~f:(str_contains "(* TEST") |> Option.map ~f:fst in
|
22
|
+
let finish_index = (start_index >>= (fun start -> find_arrayi ~start lines ~f:(str_contains "END TEST *"))) |> Option.map ~f:fst in
|
15
23
|
let template_lines = Option.map2 start_index finish_index (fun s -> Array.slice lines (s+1)) in
|
16
|
-
|
24
|
+
let suite_name_line = find_arrayi lines ~f:(str_contains "(* SUITE *)$(suite_name)") |> Option.map ~f:fst in
|
25
|
+
let suite_all_names_line = find_arrayi lines ~f:(str_contains "(* suite-all-names *)") |> Option.map ~f:fst in
|
26
|
+
Option.map2 start_index template_lines ~f:(fun s l -> {start=s;
|
27
|
+
finish=(s + 1 + Array.length l);
|
28
|
+
file_text = template_text;
|
29
|
+
template=String.concat_array l ~sep:"\n";
|
30
|
+
suite_name_line = suite_name_line;
|
31
|
+
suite_end = suite_end;
|
32
|
+
suite_all_names_line = suite_all_names_line
|
33
|
+
})
|
17
34
|
|
18
|
-
let
|
35
|
+
let fill_tests (template: t) (substs: subst list): string =
|
19
36
|
let lines = String.split_lines template.file_text |> List.to_array in
|
20
37
|
let before = Array.slice lines 0 template.start in
|
21
38
|
let subst = Array.of_list (List.map ~f:subst_to_string substs) in
|
22
39
|
let after = Array.slice lines (template.finish + 1) (Array.length lines) in
|
23
40
|
let join = String.concat_array ~sep:"\n" in
|
24
41
|
String.concat [join before; join subst; join after] ~sep:"\n"
|
42
|
+
|
43
|
+
(* HACKS HERE *)
|
44
|
+
let fill_single_suite (template: t) (suite_substs: string * subst list): string =
|
45
|
+
let (suite_name, substs) = suite_substs in
|
46
|
+
let suite_name_line = Option.value_exn template.suite_name_line in
|
47
|
+
let suite_end_line = Option.value_exn template.suite_end in
|
48
|
+
let lines = String.split_lines template.file_text |> Fn.flip List.drop suite_name_line |> List.to_array in
|
49
|
+
Array.replace lines 0 ~f:(String.substr_replace_all ~pattern:"(* SUITE *)$(suite_name)_tests" ~with_:(suite_name ^ "_tests"));
|
50
|
+
let before = Array.slice lines 0 (template.start - suite_name_line) in
|
51
|
+
let subst = Array.of_list (List.map ~f:subst_to_string substs) in
|
52
|
+
let after = Array.slice lines (template.finish - suite_name_line + 1) (suite_end_line - suite_name_line) in
|
53
|
+
let join = String.concat_array ~sep:"\n" in
|
54
|
+
String.concat [join before; join subst; join after] ~sep:"\n"
|
55
|
+
|
56
|
+
(* HACKS HERE *)
|
57
|
+
let fill_suite (template: t) (suite_substs: (string * subst list) list): string =
|
58
|
+
let fills = List.map suite_substs ~f:(fun x -> (fill_single_suite template x) ^ "\n") in
|
59
|
+
let suite_name_line = Option.value_exn template.suite_name_line in
|
60
|
+
let lines = String.split_lines template.file_text |> List.to_array in
|
61
|
+
let before = Array.slice lines 0 suite_name_line in
|
62
|
+
let subst = Array.of_list fills in
|
63
|
+
let after = Array.slice lines (template.finish + 4) (Array.length lines) in
|
64
|
+
let join = String.concat_array ~sep:"\n" in
|
65
|
+
let generated = String.concat [join before; join subst; join after] ~sep:"\n" in
|
66
|
+
let all_suite_names = String.concat ~sep:"; " @@ List.map ~f:(fun (s,_) -> s ^ "_tests") suite_substs in
|
67
|
+
String.substr_replace_all generated ~pattern:"(* suite-all-names *)" ~with_:all_suite_names
|
@@ -19,7 +19,7 @@ let command =
|
|
19
19
|
+> flag "-c" (optional_with_default "../../../x-common/exercises" is_directory) ~doc:"string Directory containing canonical data."
|
20
20
|
+> flag "-o" (optional_with_default "../../exercises" is_directory) ~doc:"string Directory to output generated tests."
|
21
21
|
)
|
22
|
-
(fun templates_folder canonical_data_folder output_folder () ->
|
22
|
+
(fun templates_folder canonical_data_folder output_folder () -> Controller.run templates_folder canonical_data_folder output_folder)
|
23
23
|
|
24
24
|
let () =
|
25
25
|
Command.run ~version:"0.1" command
|
@@ -16,12 +16,18 @@ let to_list_option json =
|
|
16
16
|
let to_list_note error json =
|
17
17
|
try Ok (to_list json) with Type_error _ -> Error error
|
18
18
|
|
19
|
+
let to_assoc_note error json =
|
20
|
+
try Ok (to_assoc json) with Type_error _ -> Error error
|
21
|
+
|
19
22
|
let to_string_note error json =
|
20
23
|
try Ok (to_string json) with Type_error _ -> Error error
|
21
24
|
|
22
25
|
let safe_to_int_option json =
|
23
26
|
try Some (to_int json) with Type_error _ -> None
|
24
27
|
|
28
|
+
let member_note error m json =
|
29
|
+
try Ok (member m json) with Type_error _ -> Error error
|
30
|
+
|
25
31
|
let (>>) f g = Fn.compose f g
|
26
32
|
|
27
33
|
let find_arrayi ?start:(start = 0) xs ~f =
|
@@ -7,10 +7,10 @@ let ae exp got _test_ctxt =
|
|
7
7
|
assert_equal exp got ~cmp:(List.equal ~equal:String.equal) ~printer
|
8
8
|
|
9
9
|
let tests = [
|
10
|
-
(*
|
10
|
+
(* TEST
|
11
11
|
"$description" >::
|
12
12
|
ae $expected (anagrams "$subject" $candidates);
|
13
|
-
END
|
13
|
+
END TEST *)
|
14
14
|
]
|
15
15
|
|
16
16
|
let () =
|
@@ -5,10 +5,10 @@ open Bob
|
|
5
5
|
let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
|
6
6
|
|
7
7
|
let tests = [
|
8
|
-
(*
|
8
|
+
(* TEST
|
9
9
|
"$description" >::
|
10
10
|
ae "$expected" (response_for "$input");
|
11
|
-
END
|
11
|
+
END TEST *)
|
12
12
|
]
|
13
13
|
|
14
14
|
let () =
|
@@ -0,0 +1,16 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Bracket_push
|
4
|
+
|
5
|
+
let ae exp got _test_ctxt =
|
6
|
+
assert_equal exp got ~printer:Bool.to_string
|
7
|
+
|
8
|
+
let tests = [
|
9
|
+
(* TEST
|
10
|
+
"$description" >::
|
11
|
+
ae $expected (are_balanced "$input");
|
12
|
+
END TEST *)
|
13
|
+
]
|
14
|
+
|
15
|
+
let () =
|
16
|
+
run_test_tt_main ("bracket-push tests" >::: tests)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Difference_of_squares
|
4
|
+
|
5
|
+
let ae exp got _test_ctxt = assert_equal exp got
|
6
|
+
|
7
|
+
let (* SUITE *)$(suite_name)_tests = [
|
8
|
+
(* TEST
|
9
|
+
"$description" >::
|
10
|
+
ae $expected ($suite-name $number);
|
11
|
+
END TEST *)
|
12
|
+
]
|
13
|
+
(* END SUITE *)
|
14
|
+
|
15
|
+
let () =
|
16
|
+
run_test_tt_main (
|
17
|
+
"difference of squares tests" >:::
|
18
|
+
List.concat [(* suite-all-names *)]
|
19
|
+
)
|
@@ -20,10 +20,10 @@ let dna_of_string s =
|
|
20
20
|
let hamdist a b = Hamming.hamming_distance (dna_of_string a) (dna_of_string b)
|
21
21
|
|
22
22
|
let tests = [
|
23
|
-
(*
|
23
|
+
(* TEST
|
24
24
|
"$description" >::
|
25
25
|
ae $expected (hamdist "$strand1" "$strand2");
|
26
|
-
END
|
26
|
+
END TEST *)
|
27
27
|
]
|
28
28
|
|
29
29
|
let () =
|
@@ -5,11 +5,11 @@ open Say
|
|
5
5
|
let ae exp got _ctx = assert_equal ~printer:(Option.value ~default:"None") exp got
|
6
6
|
|
7
7
|
let tests = [
|
8
|
-
(*
|
8
|
+
(* TEST
|
9
9
|
"$description" >:: (
|
10
10
|
ae $expected
|
11
|
-
(in_english $
|
12
|
-
END
|
11
|
+
(in_english $input));
|
12
|
+
END TEST *)
|
13
13
|
"all numbers from 1 to 10_000 can be spelt">::(fun _ ->
|
14
14
|
assert_bool "range test" (Sequence.range 0 10_000
|
15
15
|
|> Sequence.map ~f:(fun n -> Int64.of_int n |> in_english)
|
@@ -9,11 +9,11 @@ let ae exp got _test_ctxt =
|
|
9
9
|
assert_equal (SMap.of_alist_exn exp) got ~cmp:(SMap.equal (=)) ~printer
|
10
10
|
|
11
11
|
let tests = [
|
12
|
-
(*
|
12
|
+
(* TEST
|
13
13
|
"$description" >::
|
14
14
|
ae $expected
|
15
15
|
(word_count "$input");
|
16
|
-
END
|
16
|
+
END TEST *)
|
17
17
|
]
|
18
18
|
|
19
19
|
let () =
|
@@ -8,4 +8,6 @@ open Template_test
|
|
8
8
|
open Utils_test
|
9
9
|
|
10
10
|
let () =
|
11
|
-
run_test_tt_main ("tests" >:::List.concat [
|
11
|
+
run_test_tt_main ("tests" >:::List.concat [
|
12
|
+
codegen_tests; model_tests; parser_tests;
|
13
|
+
special_cases_tests; template_tests; utils_tests])
|
@@ -5,19 +5,19 @@ open Model
|
|
5
5
|
|
6
6
|
let leap_template = "\"$description\" >:: ae $expected (leap_year $input);"
|
7
7
|
|
8
|
-
let
|
9
|
-
let
|
10
|
-
let
|
8
|
+
let edit_expected ~value = parameter_to_string value
|
9
|
+
let edit_parameters = Fn.id
|
10
|
+
let assert_fill_in_template exp cases = assert_equal exp
|
11
11
|
~printer:(fun xs -> "[" ^ (String.concat ~sep:";" xs) ^ "]")
|
12
|
-
(
|
13
|
-
let ae exp cases _test_ctxt =
|
12
|
+
(fill_in_template edit_expected edit_parameters leap_template "suite-name" cases |> List.map ~f:subst_to_string)
|
13
|
+
let ae exp cases _test_ctxt = assert_fill_in_template exp cases
|
14
14
|
|
15
15
|
let codegen_tests = [
|
16
16
|
"if there are no cases then generate an empty string" >::
|
17
|
-
|
17
|
+
ae [] [];
|
18
18
|
|
19
19
|
"generates one function based on leap year for one case" >::(fun ctxt ->
|
20
20
|
let c = {description = "leap_year"; parameters = [("input", Int 1996)]; expected = Bool true} in
|
21
|
-
|
21
|
+
assert_fill_in_template ["\"leap_year\" >:: ae true (leap_year 1996);"] [c]
|
22
22
|
);
|
23
23
|
]
|
@@ -0,0 +1,67 @@
|
|
1
|
+
{
|
2
|
+
"square_of_sum": {
|
3
|
+
"description": ["Square the sum of the numbers up to the given number"],
|
4
|
+
"cases": [
|
5
|
+
{
|
6
|
+
"description": "square of sum 5",
|
7
|
+
"number": 5,
|
8
|
+
"expected": 225
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"description": "square of sum 10",
|
12
|
+
"number": 10,
|
13
|
+
"expected": 3025
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"description": "square of sum 100",
|
17
|
+
"number": 100,
|
18
|
+
"expected": 25502500
|
19
|
+
}
|
20
|
+
]
|
21
|
+
},
|
22
|
+
"sum_of_squares": {
|
23
|
+
"description": ["Sum the squares of the numbers up to the given number"],
|
24
|
+
"cases": [
|
25
|
+
{
|
26
|
+
"description": "sum of squares 5",
|
27
|
+
"number": 5,
|
28
|
+
"expected": 55
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"description": "sum of squares 10",
|
32
|
+
"number": 10,
|
33
|
+
"expected": 385
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"description": "sum of squares 100",
|
37
|
+
"number": 100,
|
38
|
+
"expected": 338350
|
39
|
+
}
|
40
|
+
]
|
41
|
+
},
|
42
|
+
"difference_of_squares": {
|
43
|
+
"description": ["Subtract sum of squares from square of sums"],
|
44
|
+
"cases": [
|
45
|
+
{
|
46
|
+
"description": "difference of squares 0",
|
47
|
+
"number": 0,
|
48
|
+
"expected": 0
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"description": "difference of squares 5",
|
52
|
+
"number": 5,
|
53
|
+
"expected": 170
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"description": "difference of squares 10",
|
57
|
+
"number": 10,
|
58
|
+
"expected": 2640
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"description": "difference of squares 100",
|
62
|
+
"number": 100,
|
63
|
+
"expected": 25164150
|
64
|
+
}
|
65
|
+
]
|
66
|
+
}
|
67
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"#": [
|
3
|
+
"Language implementations vary on the issue of missing input variables.",
|
4
|
+
"In this set of test cases, the input variable is left out of the definition,",
|
5
|
+
"and the generator would need to handle the language implementation."
|
6
|
+
],
|
7
|
+
"cases": [
|
8
|
+
{
|
9
|
+
"description": "no name",
|
10
|
+
"expected": "Hello, World!"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"description": "sample name",
|
14
|
+
"name": "Alice",
|
15
|
+
"expected": "Hello, Alice!"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"description": "other sample name",
|
19
|
+
"name": "Bob",
|
20
|
+
"expected": "Hello, Bob!"
|
21
|
+
}
|
22
|
+
]
|
23
|
+
}
|
@@ -4,17 +4,20 @@ open Parser
|
|
4
4
|
open Model
|
5
5
|
|
6
6
|
let show_cases = function
|
7
|
-
| Ok cs -> List.map ~f:show_case cs |> String.concat
|
7
|
+
| Ok (Single cs) -> List.map ~f:show_case cs |> String.concat
|
8
|
+
| Ok (Suite cs) -> failwith "no printer"
|
8
9
|
| Error e -> show_error e
|
9
10
|
|
10
11
|
let ae exp got _test_ctxt = assert_equal exp got ~printer:show_cases
|
11
12
|
|
13
|
+
let single x = Ok (Single x)
|
14
|
+
|
12
15
|
let parser_tests = [
|
13
16
|
"parses empty json as empty list" >::
|
14
|
-
ae (
|
17
|
+
ae (single []) (parse_json_text "{\"cases\" : []}");
|
15
18
|
|
16
19
|
"gives an error with a json map that does not have the key cases in" >::
|
17
|
-
ae (Error
|
20
|
+
ae (Error UnrecognizedJson)
|
18
21
|
(parse_json_text "{\"case\" : [{\"description\" : \"d1\", \"expected\" : 100}]}");
|
19
22
|
|
20
23
|
"gives an error with cases that is not a json list" >::
|
@@ -26,27 +29,27 @@ let parser_tests = [
|
|
26
29
|
(parse_json_text "{\"cases\" : [\"key\"]}");
|
27
30
|
|
28
31
|
"parses a single element with a description and expected string output" >::
|
29
|
-
ae (
|
32
|
+
ae (single [{description = "d1"; parameters = []; expected = String "value"}])
|
30
33
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : \"value\"}]}");
|
31
34
|
|
32
35
|
"parses a single element with a description and expected float output" >::
|
33
|
-
ae (
|
36
|
+
ae (single [{description = "d1"; parameters = []; expected = Float 100.}])
|
34
37
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : 100.0}]}");
|
35
38
|
|
36
39
|
"parses a single element with a description and expected bool output" >::
|
37
|
-
ae (
|
40
|
+
ae (single [{description = "d1"; parameters = []; expected = Bool true}])
|
38
41
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : true}]}");
|
39
42
|
|
40
43
|
"parses a single element with an int key value pair" >::
|
41
|
-
ae (
|
44
|
+
ae (single [{description = "d1"; parameters = [("input", Int 1996)]; expected = Bool true}])
|
42
45
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"input\" : 1996, \"expected\" : true}]}");
|
43
46
|
|
44
47
|
"parses a single element with a string key value pair" >::
|
45
|
-
ae (
|
48
|
+
ae (single [{description = "d1"; parameters = [("input", String "some-string")]; expected = Int 85}])
|
46
49
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"input\" : \"some-string\", \"expected\" : 85}]}");
|
47
50
|
|
48
51
|
"parses a single element with a string list key value pair" >::
|
49
|
-
ae (
|
52
|
+
ae (single [{description = "d1"; parameters = [("input", StringList ["s1"; "s2"])]; expected = Int 85}])
|
50
53
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [\"s1\", \"s2\"], \"expected\" : 85}]}");
|
51
54
|
|
52
55
|
"an element without a description is an Error" >::
|
@@ -62,13 +65,28 @@ let parser_tests = [
|
|
62
65
|
(parse_json_text "{\"cases\" : [{\"input\" : 11}]}");
|
63
66
|
|
64
67
|
"parses a map in the expected parameter" >::(fun _ctx ->
|
65
|
-
assert_equal (
|
68
|
+
assert_equal (single [{description = "d1"; parameters = []; expected = IntStringMap [("one", 1); ("two", 2)]}])
|
66
69
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : {\"one\": 1, \"two\": 2}}]}");
|
67
70
|
);
|
68
71
|
|
69
72
|
"parses leap.json" >::(fun ctxt ->
|
70
73
|
match parse_json_text @@ In_channel.read_all "test/leap.json" with
|
71
|
-
| Ok p -> assert_equal 7 (List.length p)
|
72
|
-
|
|
74
|
+
| Ok (Single p) -> assert_equal 7 (List.length p)
|
75
|
+
| Ok (Suite p) -> assert_failure "was suite"
|
76
|
+
| Error e -> assert_failure ("failed to parse leap.json: " ^ show_error e)
|
73
77
|
);
|
78
|
+
|
79
|
+
"parses hello_world.json which has a # element as documentation" >::(fun ctxt ->
|
80
|
+
match parse_json_text @@ In_channel.read_all "test/hello_world.json" with
|
81
|
+
| Ok (Single p) -> ()
|
82
|
+
| Ok (Suite p) -> assert_failure "was suite"
|
83
|
+
| Error e -> assert_failure ("failed to parse hello_world.json: " ^ show_error e)
|
84
|
+
);
|
85
|
+
|
86
|
+
"parses difference_of_squares.json" >::(fun ctxt ->
|
87
|
+
match parse_json_text @@ In_channel.read_all "test/difference_of_squares.json" with
|
88
|
+
| Ok (Suite p) -> assert_equal ["square_of_sum"; "sum_of_squares"; "difference_of_squares"] (List.map ~f:(fun x -> x.name) p)
|
89
|
+
| Ok (Single p) -> assert_failure "was single"
|
90
|
+
| Error e -> assert_failure ("failed to parse difference_of_squares.json: " ^ show_error e)
|
91
|
+
);
|
74
92
|
]
|