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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/c/config.json +10 -0
  4. data/tracks/c/exercises/robot-simulator/makefile +16 -0
  5. data/tracks/c/exercises/robot-simulator/src/example.c +74 -0
  6. data/tracks/c/exercises/robot-simulator/src/robot_simulator.h +41 -0
  7. data/tracks/c/exercises/robot-simulator/test/test_robot_simulator.c +165 -0
  8. data/tracks/c/exercises/robot-simulator/test/vendor/unity.c +1300 -0
  9. data/tracks/c/exercises/robot-simulator/test/vendor/unity.h +274 -0
  10. data/tracks/c/exercises/robot-simulator/test/vendor/unity_internals.h +701 -0
  11. data/tracks/ecmascript/exercises/rna-transcription/example.js +9 -2
  12. data/tracks/ecmascript/exercises/rna-transcription/rna-transcription.spec.js +18 -0
  13. data/tracks/go/exercises/hello-world/example.go +4 -2
  14. data/tracks/go/exercises/hello-world/hello_test.go +4 -4
  15. data/tracks/go/exercises/hello-world/hello_world.go +6 -6
  16. data/tracks/groovy/config.json +5 -0
  17. data/tracks/groovy/exercises/phone-number/Example.groovy +20 -0
  18. data/tracks/groovy/exercises/phone-number/PhoneNumberSpec.groovy +75 -0
  19. data/tracks/haskell/exercises/difference-of-squares/test/Tests.hs +2 -0
  20. data/tracks/java/config.json +13 -1
  21. data/tracks/java/exercises/all-your-base/build.gradle +17 -0
  22. data/tracks/java/exercises/all-your-base/src/example/java/BaseConverter.java +80 -0
  23. data/tracks/java/exercises/all-your-base/src/main/java/BaseConverter.java +5 -0
  24. data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +256 -0
  25. data/tracks/java/exercises/binary-search/build.gradle +17 -0
  26. data/tracks/java/exercises/binary-search/src/example/java/BinarySearch.java +40 -0
  27. data/tracks/java/exercises/binary-search/src/main/java/.keep +0 -0
  28. data/tracks/java/exercises/binary-search/src/main/java/BinarySearch.java +4 -0
  29. data/tracks/java/exercises/binary-search/src/test/java/.keep +0 -0
  30. data/tracks/java/exercises/binary-search/src/test/java/BinarySearchTest.java +136 -0
  31. data/tracks/java/exercises/settings.gradle +1 -0
  32. data/tracks/lua/config.json +16 -0
  33. data/tracks/lua/exercises/say/example.lua +92 -0
  34. data/tracks/lua/exercises/say/say_spec.lua +105 -0
  35. data/tracks/lua/exercises/secret-handshake/example.lua +17 -0
  36. data/tracks/lua/exercises/secret-handshake/secret-handshake_spec.lua +38 -0
  37. data/tracks/ocaml/config.json +10 -1
  38. data/tracks/ocaml/exercises/bracket-push/.merlin +3 -0
  39. data/tracks/ocaml/exercises/bracket-push/Makefile +11 -0
  40. data/tracks/ocaml/exercises/bracket-push/bracket_push.mli +3 -0
  41. data/tracks/ocaml/exercises/bracket-push/example.ml +40 -0
  42. data/tracks/ocaml/exercises/bracket-push/test.ml +38 -0
  43. data/tracks/ocaml/exercises/leap/test.ml +7 -7
  44. data/tracks/ocaml/tools/test-generator/Makefile +2 -2
  45. data/tracks/ocaml/tools/test-generator/interfaces/codegen.mli +2 -2
  46. data/tracks/ocaml/tools/test-generator/interfaces/{test_generator.mli → controller.mli} +0 -0
  47. data/tracks/ocaml/tools/test-generator/interfaces/parser.mli +7 -1
  48. data/tracks/ocaml/tools/test-generator/interfaces/special_cases.mli +2 -2
  49. data/tracks/ocaml/tools/test-generator/interfaces/utils.mli +4 -0
  50. data/tracks/ocaml/tools/test-generator/src/codegen.ml +9 -5
  51. data/tracks/ocaml/tools/test-generator/src/{test_generator.ml → controller.ml} +24 -15
  52. data/tracks/ocaml/tools/test-generator/src/model.ml +6 -0
  53. data/tracks/ocaml/tools/test-generator/src/parser.ml +34 -7
  54. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +11 -4
  55. data/tracks/ocaml/tools/test-generator/src/template.ml +49 -6
  56. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +1 -1
  57. data/tracks/ocaml/tools/test-generator/src/utils.ml +6 -0
  58. data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +2 -2
  59. data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +2 -2
  60. data/tracks/ocaml/tools/test-generator/templates/bracket-push/template.ml +16 -0
  61. data/tracks/ocaml/tools/test-generator/templates/difference-of-squares/template.ml +19 -0
  62. data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +2 -2
  63. data/tracks/ocaml/tools/test-generator/templates/hello-world/template.ml +2 -2
  64. data/tracks/ocaml/tools/test-generator/templates/leap/template.ml +2 -2
  65. data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +2 -2
  66. data/tracks/ocaml/tools/test-generator/templates/say/template.ml +3 -3
  67. data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +2 -2
  68. data/tracks/ocaml/tools/test-generator/test/all_tests.ml +3 -1
  69. data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +7 -7
  70. data/tracks/ocaml/tools/test-generator/test/difference_of_squares.json +67 -0
  71. data/tracks/ocaml/tools/test-generator/test/hello_world.json +23 -0
  72. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +30 -12
  73. data/tracks/ocaml/tools/test-generator/test/sample-suite-template.txt +16 -0
  74. data/tracks/ocaml/tools/test-generator/test/sample_template.txt +2 -2
  75. data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +1 -1
  76. data/tracks/ocaml/tools/test-generator/test/template_test.ml +40 -6
  77. data/tracks/perl6/.travis.yml +3 -0
  78. data/tracks/perl6/docs/RESOURCES.md +1 -1
  79. data/tracks/perl6/exercises/accumulate/accumulate.t +3 -7
  80. data/tracks/perl6/exercises/anagram/anagram.t +3 -7
  81. data/tracks/perl6/exercises/binary/binary.t +3 -7
  82. data/tracks/perl6/exercises/bob/bob.t +4 -8
  83. data/tracks/perl6/exercises/grains/grains.t +3 -7
  84. data/tracks/perl6/exercises/leap/leap.t +3 -7
  85. data/tracks/perl6/exercises/rna-transcription/rna_transcription.t +4 -8
  86. data/tracks/perl6/exercises/robot-name/robot.t +4 -8
  87. data/tracks/perl6/exercises/scrabble-score/scrabble_score.t +3 -7
  88. data/tracks/perl6/exercises/word-count/word_count.t +3 -8
  89. data/tracks/r/config.json +10 -0
  90. data/tracks/r/docs/ABOUT.md +14 -0
  91. data/tracks/r/exercises/difference-of-squares/difference-of-squares.R +5 -0
  92. data/tracks/r/exercises/difference-of-squares/example.R +6 -0
  93. data/tracks/r/exercises/difference-of-squares/test_difference-of-squares.R +23 -0
  94. data/tracks/r/exercises/hamming/example.R +8 -0
  95. data/tracks/r/exercises/hamming/hamming.R +4 -0
  96. data/tracks/r/exercises/hamming/test_hamming.R +87 -0
  97. data/tracks/ruby/exercises/binary/.version +1 -1
  98. data/tracks/ruby/exercises/binary/binary_test.rb +17 -19
  99. data/tracks/ruby/exercises/binary/example.rb +13 -13
  100. data/tracks/ruby/exercises/isogram/.version +1 -1
  101. data/tracks/ruby/exercises/isogram/example.rb +1 -1
  102. data/tracks/ruby/exercises/isogram/isogram_test.rb +16 -30
  103. data/tracks/ruby/lib/binary_cases.rb +2 -3
  104. data/tracks/ruby/lib/isogram_cases.rb +1 -5
  105. data/tracks/scala/exercises/phone-number/HINTS.md +9 -0
  106. 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 is *)
7
- type t = {start: int; finish: int; file_text: string; template: string} [@@deriving eq, show]
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 start_index = find_arrayi lines ~f:(str_contains "(* GENERATED-CODE") |> Option.map ~f:fst in
14
- let finish_index = (start_index >>= (fun start -> find_arrayi ~start lines ~f:(str_contains "END GENERATED-CODE *"))) |> Option.map ~f:fst in
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
- Option.map2 start_index template_lines ~f:(fun s l -> {start=s; finish=(s + 1 + Array.length l); file_text = template_text; template=String.concat_array l ~sep:"\n"})
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 fill (template: t) (substs: subst list): string =
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 () -> Test_generator.run 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
- (* GENERATED-CODE
10
+ (* TEST
11
11
  "$description" >::
12
12
  ae $expected (anagrams "$subject" $candidates);
13
- END GENERATED-CODE *)
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
- (* GENERATED-CODE
8
+ (* TEST
9
9
  "$description" >::
10
10
  ae "$expected" (response_for "$input");
11
- END GENERATED-CODE *)
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
- (* GENERATED-CODE
23
+ (* TEST
24
24
  "$description" >::
25
25
  ae $expected (hamdist "$strand1" "$strand2");
26
- END GENERATED-CODE *)
26
+ END TEST *)
27
27
  ]
28
28
 
29
29
  let () =
@@ -5,9 +5,9 @@ open Hello_world
5
5
  let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
6
6
 
7
7
  let tests = [
8
- (* GENERATED-CODE
8
+ (* TEST
9
9
  "$description" >:: ae "$expected" (greet $name);
10
- END GENERATED-CODE *)
10
+ END TEST *)
11
11
  ]
12
12
 
13
13
  let () =
@@ -5,10 +5,10 @@ open Leap
5
5
  let ae exp got _test_ctxt = assert_equal exp got
6
6
 
7
7
  let tests = [
8
- (* GENERATED-CODE
8
+ (* TEST
9
9
  "$description" >::
10
10
  ae $expected (leap_year $input);
11
- END GENERATED-CODE *)
11
+ END TEST *)
12
12
  ]
13
13
 
14
14
  let () =
@@ -5,10 +5,10 @@ open Raindrops
5
5
  let ae exp got _test_ctxt = assert_equal ~printer:Fn.id exp got
6
6
 
7
7
  let tests = [
8
- (* GENERATED-CODE
8
+ (* TEST
9
9
  "$description" >::
10
10
  ae "$expected" (raindrop $number);
11
- END GENERATED-CODE *)
11
+ END TEST *)
12
12
  ]
13
13
 
14
14
  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
- (* GENERATED-CODE
8
+ (* TEST
9
9
  "$description" >:: (
10
10
  ae $expected
11
- (in_english $(input)L));
12
- END GENERATED-CODE *)
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
- (* GENERATED-CODE
12
+ (* TEST
13
13
  "$description" >::
14
14
  ae $expected
15
15
  (word_count "$input");
16
- END GENERATED-CODE *)
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 [codegen_tests; model_tests; parser_tests; special_cases_tests; template_tests; utils_tests])
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 fixup ~key ~value = parameter_to_string value
9
- let edit = Fn.id
10
- let assert_gen exp cases = assert_equal exp
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
- (Result.ok_or_failwith @@ generate_code fixup edit leap_template cases |> List.map ~f:subst_to_string)
13
- let ae exp cases _test_ctxt = assert_gen exp cases
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
- ae [] [];
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
- assert_gen ["\"leap_year\" >:: ae true (leap_year 1996);"] [c]
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 (Ok []) (parse_json_text "{\"cases\" : []}");
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 TopLevelMustHaveKeyCalledCases)
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 (Ok [{description = "d1"; parameters = []; expected = String "value"}])
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 (Ok [{description = "d1"; parameters = []; expected = Float 100.}])
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 (Ok [{description = "d1"; parameters = []; expected = Bool true}])
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 (Ok [{description = "d1"; parameters = [("input", Int 1996)]; expected = Bool true}])
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 (Ok [{description = "d1"; parameters = [("input", String "some-string")]; expected = Int 85}])
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 (Ok [{description = "d1"; parameters = [("input", StringList ["s1"; "s2"])]; expected = Int 85}])
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 (Ok [{description = "d1"; parameters = []; expected = IntStringMap [("one", 1); ("two", 2)]}])
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
- | _ -> failwith "failed to parse leap.json"
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
  ]