trackler 2.0.6.30 → 2.0.6.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/beer-song/canonical-data.json +49 -0
  3. data/common/exercises/food-chain/description.md +1 -2
  4. data/common/exercises/list-ops/canonical-data.json +147 -0
  5. data/lib/trackler/version.rb +1 -1
  6. data/tracks/erlang/README.md +2 -3
  7. data/tracks/erlang/exercises/accumulate/include/exercism.hrl +5 -0
  8. data/tracks/erlang/exercises/accumulate/src/example.erl +4 -1
  9. data/tracks/erlang/exercises/accumulate/test/accumulate_tests.erl +2 -3
  10. data/tracks/erlang/exercises/allergies/include/exercism.hrl +5 -0
  11. data/tracks/erlang/exercises/allergies/src/example.erl +4 -1
  12. data/tracks/erlang/exercises/allergies/test/allergies_tests.erl +2 -3
  13. data/tracks/erlang/exercises/anagram/include/exercism.hrl +5 -0
  14. data/tracks/erlang/exercises/anagram/src/example.erl +4 -1
  15. data/tracks/erlang/exercises/anagram/test/anagram_tests.erl +2 -3
  16. data/tracks/erlang/exercises/atbash-cipher/include/exercism.hrl +5 -0
  17. data/tracks/erlang/exercises/atbash-cipher/src/example.erl +4 -1
  18. data/tracks/erlang/exercises/atbash-cipher/test/atbash_cipher_tests.erl +2 -3
  19. data/tracks/erlang/exercises/bank-account/include/exercism.hrl +5 -0
  20. data/tracks/erlang/exercises/bank-account/src/example.erl +5 -1
  21. data/tracks/erlang/exercises/bank-account/test/bank_account_tests.erl +2 -2
  22. data/tracks/erlang/exercises/beer-song/include/exercism.hrl +5 -0
  23. data/tracks/erlang/exercises/beer-song/src/example.erl +5 -1
  24. data/tracks/erlang/exercises/beer-song/test/beer_song_tests.erl +2 -2
  25. data/tracks/erlang/exercises/binary/include/exercism.hrl +5 -0
  26. data/tracks/erlang/exercises/binary/src/example.erl +4 -1
  27. data/tracks/erlang/exercises/binary/test/binary_string_tests.erl +2 -2
  28. data/tracks/erlang/exercises/bob/include/exercism.hrl +5 -0
  29. data/tracks/erlang/exercises/bob/src/example.erl +6 -1
  30. data/tracks/erlang/exercises/bob/test/bob_tests.erl +2 -3
  31. data/tracks/erlang/exercises/circular-buffer/include/exercism.hrl +5 -0
  32. data/tracks/erlang/exercises/circular-buffer/src/example.erl +4 -1
  33. data/tracks/erlang/exercises/circular-buffer/test/circular_buffer_tests.erl +2 -2
  34. data/tracks/erlang/exercises/clock/include/exercism.hrl +5 -0
  35. data/tracks/erlang/exercises/clock/src/example.erl +9 -3
  36. data/tracks/erlang/exercises/clock/test/clock_tests.erl +2 -2
  37. data/tracks/erlang/exercises/difference-of-squares/include/exercism.hrl +5 -0
  38. data/tracks/erlang/exercises/difference-of-squares/src/example.erl +4 -1
  39. data/tracks/erlang/exercises/difference-of-squares/test/difference_of_squares_tests.erl +2 -2
  40. data/tracks/erlang/exercises/etl/include/exercism.hrl +5 -0
  41. data/tracks/erlang/exercises/etl/src/example.erl +6 -1
  42. data/tracks/erlang/exercises/etl/test/etl_tests.erl +2 -2
  43. data/tracks/erlang/exercises/gigasecond/include/exercism.hrl +5 -0
  44. data/tracks/erlang/exercises/gigasecond/src/example.erl +4 -1
  45. data/tracks/erlang/exercises/gigasecond/test/gigasecond_tests.erl +2 -2
  46. data/tracks/erlang/exercises/grade-school/include/exercism.hrl +5 -0
  47. data/tracks/erlang/exercises/grade-school/src/example.erl +4 -1
  48. data/tracks/erlang/exercises/grade-school/test/grade_school_tests.erl +2 -2
  49. data/tracks/erlang/exercises/grains/include/exercism.hrl +5 -0
  50. data/tracks/erlang/exercises/grains/src/example.erl +4 -1
  51. data/tracks/erlang/exercises/grains/test/grains_tests.erl +2 -2
  52. data/tracks/erlang/exercises/hamming/include/exercism.hrl +5 -0
  53. data/tracks/erlang/exercises/hamming/src/example.erl +4 -1
  54. data/tracks/erlang/exercises/hamming/test/hamming_tests.erl +2 -2
  55. data/tracks/erlang/exercises/hello-world/include/exercism.hrl +5 -0
  56. data/tracks/erlang/exercises/hello-world/src/example.erl +4 -1
  57. data/tracks/erlang/exercises/hello-world/test/hello_world_tests.erl +2 -2
  58. data/tracks/erlang/exercises/largest-series-product/include/exercism.hrl +5 -0
  59. data/tracks/erlang/exercises/largest-series-product/src/example.erl +3 -1
  60. data/tracks/erlang/exercises/largest-series-product/test/largest_series_product_tests.erl +2 -2
  61. data/tracks/erlang/exercises/leap/include/exercism.hrl +5 -0
  62. data/tracks/erlang/exercises/leap/src/example.erl +6 -1
  63. data/tracks/erlang/exercises/leap/test/leap_tests.erl +2 -2
  64. data/tracks/erlang/exercises/luhn/include/exercism.hrl +5 -0
  65. data/tracks/erlang/exercises/luhn/src/example.erl +6 -1
  66. data/tracks/erlang/exercises/luhn/test/luhn_tests.erl +2 -2
  67. data/tracks/erlang/exercises/meetup/include/exercism.hrl +5 -0
  68. data/tracks/erlang/exercises/meetup/src/example.erl +6 -1
  69. data/tracks/erlang/exercises/meetup/test/meetup_tests.erl +2 -2
  70. data/tracks/erlang/exercises/nucleotide-count/include/exercism.hrl +5 -0
  71. data/tracks/erlang/exercises/nucleotide-count/src/example.erl +4 -1
  72. data/tracks/erlang/exercises/nucleotide-count/test/dna_tests.erl +2 -2
  73. data/tracks/erlang/exercises/parallel-letter-frequency/include/exercism.hrl +5 -0
  74. data/tracks/erlang/exercises/parallel-letter-frequency/src/example.erl +3 -1
  75. data/tracks/erlang/exercises/parallel-letter-frequency/test/parallel_letter_frequency_tests.erl +2 -2
  76. data/tracks/erlang/exercises/phone-number/include/exercism.hrl +5 -0
  77. data/tracks/erlang/exercises/phone-number/src/example.erl +4 -1
  78. data/tracks/erlang/exercises/phone-number/test/phone_tests.erl +2 -2
  79. data/tracks/erlang/exercises/rna-transcription/include/exercism.hrl +5 -0
  80. data/tracks/erlang/exercises/rna-transcription/src/example.erl +6 -1
  81. data/tracks/erlang/exercises/rna-transcription/test/rna_transcription_tests.erl +2 -2
  82. data/tracks/erlang/exercises/robot-simulator/include/exercism.hrl +5 -0
  83. data/tracks/erlang/exercises/robot-simulator/src/example.erl +12 -1
  84. data/tracks/erlang/exercises/robot-simulator/test/robot_simulator_tests.erl +2 -2
  85. data/tracks/erlang/exercises/roman-numerals/include/exercism.hrl +5 -0
  86. data/tracks/erlang/exercises/roman-numerals/src/example.erl +6 -1
  87. data/tracks/erlang/exercises/roman-numerals/test/roman_numerals_tests.erl +2 -2
  88. data/tracks/erlang/exercises/scrabble-score/include/exercism.hrl +5 -0
  89. data/tracks/erlang/exercises/scrabble-score/src/example.erl +4 -1
  90. data/tracks/erlang/exercises/scrabble-score/test/scrabble_score_tests.erl +2 -2
  91. data/tracks/erlang/exercises/series/include/exercism.hrl +5 -0
  92. data/tracks/erlang/exercises/series/src/example.erl +3 -1
  93. data/tracks/erlang/exercises/series/test/series_tests.erl +2 -2
  94. data/tracks/erlang/exercises/space-age/include/exercism.hrl +5 -0
  95. data/tracks/erlang/exercises/space-age/src/example.erl +6 -1
  96. data/tracks/erlang/exercises/space-age/test/space_age_tests.erl +2 -2
  97. data/tracks/erlang/exercises/strain/include/exercism.hrl +5 -0
  98. data/tracks/erlang/exercises/strain/src/example.erl +4 -1
  99. data/tracks/erlang/exercises/strain/test/strain_tests.erl +2 -2
  100. data/tracks/erlang/exercises/sum-of-multiples/include/exercism.hrl +5 -0
  101. data/tracks/erlang/exercises/sum-of-multiples/src/example.erl +6 -1
  102. data/tracks/erlang/exercises/sum-of-multiples/test/sum_of_multiples_tests.erl +2 -2
  103. data/tracks/erlang/exercises/triangle/include/exercism.hrl +5 -0
  104. data/tracks/erlang/exercises/triangle/src/example.erl +4 -1
  105. data/tracks/erlang/exercises/triangle/test/triangle_tests.erl +2 -2
  106. data/tracks/erlang/exercises/trinary/include/exercism.hrl +5 -0
  107. data/tracks/erlang/exercises/trinary/src/example.erl +4 -1
  108. data/tracks/erlang/exercises/trinary/test/trinary_tests.erl +2 -2
  109. data/tracks/erlang/exercises/word-count/include/exercism.hrl +5 -0
  110. data/tracks/erlang/exercises/word-count/src/example.erl +6 -1
  111. data/tracks/erlang/exercises/word-count/test/word_count_tests.erl +2 -2
  112. data/tracks/erlang/exercises/zipper/include/exercism.hrl +5 -0
  113. data/tracks/erlang/exercises/zipper/src/example.erl +4 -5
  114. data/tracks/erlang/exercises/zipper/test/zipper_tests.erl +2 -2
  115. data/tracks/go/exercises/pangram/pangram_test.go +9 -1
  116. data/tracks/java/.travis.yml +8 -0
  117. data/tracks/java/README.md +1 -1
  118. data/tracks/julia/config.json +11 -1
  119. data/tracks/julia/exercises/sieve/example.jl +15 -0
  120. data/tracks/julia/exercises/sieve/runtests.jl +37 -0
  121. data/tracks/julia/exercises/sieve/sieve.jl +3 -0
  122. data/tracks/objective-c/circle.yml +6 -0
  123. data/tracks/ocaml/SETUP.md +1 -13
  124. data/tracks/ocaml/exercises/atbash-cipher/test.ml +38 -29
  125. data/tracks/ocaml/tools/test-generator/src/codegen.ml +4 -3
  126. data/tracks/ocaml/tools/test-generator/src/controller.ml +1 -1
  127. data/tracks/ocaml/tools/test-generator/src/model.ml +16 -33
  128. data/tracks/ocaml/tools/test-generator/src/parser.ml +2 -35
  129. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +36 -23
  130. data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +1 -1
  131. data/tracks/ocaml/tools/test-generator/templates/atbash-cipher/template.ml +24 -0
  132. data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +1 -1
  133. data/tracks/ocaml/tools/test-generator/templates/bracket-push/template.ml +1 -1
  134. data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +1 -1
  135. data/tracks/ocaml/tools/test-generator/templates/hello-world/template.ml +1 -1
  136. data/tracks/ocaml/tools/test-generator/templates/luhn/template.ml +1 -1
  137. data/tracks/ocaml/tools/test-generator/templates/pangram/template.ml +1 -1
  138. data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +1 -1
  139. data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +1 -1
  140. data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +5 -3
  141. data/tracks/ocaml/tools/test-generator/test/model_test.ml +2 -20
  142. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +10 -19
  143. data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +7 -6
  144. data/tracks/perl6/config.json +5 -0
  145. data/tracks/perl6/exercises/hello-world/Example.pm +5 -0
  146. data/tracks/perl6/exercises/hello-world/HelloWorld.pm6 +15 -0
  147. data/tracks/perl6/exercises/hello-world/hello-world.t +32 -0
  148. metadata +12 -2
@@ -9,19 +9,7 @@ To work on the exercises, you will need `Opam` and `Core`. Consult [opam](https:
9
9
  opam install core
10
10
 
11
11
  ## Running Tests
12
- Because OCaml is a compiled language you need to compile your submission and the test code before you can run the tests. Compile with
13
-
14
- ```bash
15
- $ corebuild -quiet test.native
16
- ```
17
-
18
- and when successful run the tests by running the `test.native` executable:
19
-
20
- ```bash
21
- ./test.native
22
- ```
23
-
24
- Alternatively just type
12
+ A Makefile is provided with a default target to compile your solution and run the tests. At the command line, type:
25
13
 
26
14
  ```bash
27
15
  make
@@ -4,34 +4,43 @@ open Atbash_cipher
4
4
 
5
5
  let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
6
6
 
7
- let tests =
8
- ["encode yes">::
9
- ae "bvh" (encode "yes");
10
- "encode no">::
11
- ae "ml" (encode "no");
12
- "encode OMG">::
13
- ae "lnt" (encode "OMG");
14
- "encode spaces">::
15
- ae "lnt" (encode "O M G");
16
- "encode mindblowingly">::
17
- ae "nrmwy oldrm tob" (encode "mindblowingly");
18
- "encode numbers">::
19
- ae "gvhgr mt123 gvhgr mt" (encode "Testing,1 2 3, testing.");
20
- "encode deep thought">::
21
- ae "gifgs rhurx grlm" (encode "Truth is fiction.");
22
- "encode all the letters">::
23
- ae "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" (encode "The quick brown fox jumps over the lazy dog.");
24
- "encode ignores non ascii">::
25
- ae "mlmzh xrrrt mlivw" (encode "non ascii éignored");
26
- "encode mindblowingly with a different block size">::
27
- ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
28
- "decode exercism">::
29
- ae "exercism" (decode "vcvix rhn");
30
- "decode a sentence">::
31
- ae "anobstacleisoftenasteppingstone" (decode "zmlyh gzxov rhlug vmzhg vkkrm thglm v");
32
- "decode all the letters">::
33
- ae "thequickbrownfoxjumpsoverthelazydog" (decode "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt");
34
- ]
7
+ let encode_tests = [
8
+ "encode yes" >::
9
+ ae "bvh" (encode "yes");
10
+ "encode no" >::
11
+ ae "ml" (encode "no");
12
+ "encode OMG" >::
13
+ ae "lnt" (encode "OMG");
14
+ "encode spaces" >::
15
+ ae "lnt" (encode "O M G");
16
+ "encode mindblowingly" >::
17
+ ae "nrmwy oldrm tob" (encode "mindblowingly");
18
+ "encode numbers" >::
19
+ ae "gvhgr mt123 gvhgr mt" (encode "Testing,1 2 3, testing.");
20
+ "encode deep thought" >::
21
+ ae "gifgs rhurx grlm" (encode "Truth is fiction.");
22
+ "encode all the letters" >::
23
+ ae "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" (encode "The quick brown fox jumps over the lazy dog.");
24
+ ]
25
+
26
+ let decode_tests = [
27
+ "decode exercism" >::
28
+ ae "exercism" (decode "vcvix rhn");
29
+ "decode a sentence" >::
30
+ ae "anobstacleisoftenasteppingstone" (decode "zmlyh gzxov rhlug vmzhg vkkrm thglm v");
31
+ "decode numbers" >::
32
+ ae "testing123testing" (decode "gvhgr mt123 gvhgr mt");
33
+ "decode all the letters" >::
34
+ ae "thequickbrownfoxjumpsoverthelazydog" (decode "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt");
35
+ ]
36
+
37
+ let different_block_size_test = [
38
+ "encode mindblowingly with a different block size">::
39
+ ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
40
+ ]
35
41
 
36
42
  let () =
37
- run_test_tt_main ("atbash cipher" >::: tests)
43
+ run_test_tt_main (
44
+ "atbash-cipher tests" >:::
45
+ List.concat [encode_tests; decode_tests; different_block_size_test]
46
+ )
@@ -1,10 +1,11 @@
1
1
  open Core.Std
2
2
 
3
3
  open Model
4
+ open Yojson.Basic
4
5
 
5
- type edit_expected_function = value: parameter -> string
6
+ type edit_expected_function = value: json -> string
6
7
 
7
- type edit_parameters_function = (string * string) list -> (string * string) list
8
+ type edit_parameters_function = (string * json) list -> (string * string) list
8
9
 
9
10
  type subst = Subst of string [@@deriving eq, show]
10
11
 
@@ -22,7 +23,7 @@ let rec replace_keys (f: edit_expected_function) (ed: edit_parameters_function)
22
23
  let expected = f ~value:c.expected in
23
24
  let s = replace_key "expected" expected s in
24
25
  let s = replace_key "suite-name" suite_name s in
25
- let parameter_strings = ed @@ List.map ~f:(fun (k,p) -> (k,parameter_to_string p)) c.parameters in
26
+ let parameter_strings = ed @@ List.map ~f:(fun (k,p) -> (k,p)) c.parameters in
26
27
  List.fold parameter_strings ~init:(Subst s) ~f:(fun (Subst s) (k,v) -> Subst (replace_key k v s))
27
28
 
28
29
  let fill_in_template (f: edit_expected_function) (ed: edit_parameters_function) test_template suite_name cases =
@@ -24,7 +24,7 @@ let combine_files (template_files: (string * content) list) (canonical_data_file
24
24
 
25
25
  let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_file: content): (content, content) Result.t =
26
26
  let template = find_template template_file in
27
- let edit_expected = edit_expected ~stringify:parameter_to_string ~slug in
27
+ let edit_expected = edit_expected ~stringify:json_to_string ~slug in
28
28
  let edit_parameters = edit_parameters ~slug in
29
29
  let fill_in_template = fill_in_template edit_expected edit_parameters in
30
30
  let open Result.Monad_infix in
@@ -1,43 +1,26 @@
1
1
  open Core.Std
2
2
 
3
3
  open Utils
4
-
5
- type parameter =
6
- | Null
7
- | String of string
8
- | Float of float
9
- | Int of int
10
- | Bool of bool
11
- | StringList of (string list)
12
- | IntList of (int list)
13
- | IntTupleList of ((int * int) list)
14
- | IntStringMap of ((string * int) list) [@@deriving eq, show]
15
-
16
- type 'a elements = (string * 'a) list [@@deriving eq, show]
4
+ open Yojson.Basic
17
5
 
18
6
  type case = {
19
7
  description: string;
20
- parameters: parameter elements;
21
- expected: parameter;
22
- } [@@deriving eq, show]
8
+ parameters: (string * json) list;
9
+ expected: json;
10
+ }
23
11
 
24
- type test = {name: string; cases: case list} [@@deriving eq, show]
12
+ type test = {name: string; cases: case list}
25
13
 
26
14
  type tests =
27
15
  | Single of case list
28
- | Suite of test list [@@deriving eq, show]
29
-
30
- let surround (ch: char) (s: string): string =
31
- Char.to_string ch ^ s ^ Char.to_string ch
32
-
33
- let parameter_to_string = function
34
- | Null -> "null"
35
- | String s -> String.escaped s
36
- | Float f -> Float.to_string f
37
- | Int n -> Int.to_string n
38
- | Bool b -> Bool.to_string b
39
- | StringList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:(surround '\"' >> String.escaped) xs) ^ "]"
40
- | IntList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:Int.to_string xs) ^ "]"
41
- | IntTupleList xs -> "[" ^ String.concat ~sep:"; " (List.map xs ~f:(fun (x,y) -> sprintf "(%d,%d)" x y)) ^ "]"
42
- | IntStringMap xs -> "[" ^ String.concat ~sep:"; "
43
- (List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ Int.to_string v ^ ")")) ^ "]"
16
+ | Suite of test list
17
+
18
+ let rec json_to_string (j: json): string = match j with
19
+ | `Null -> "null"
20
+ | `String s -> "\"" ^ (String.escaped s) ^ "\""
21
+ | `Float f -> Float.to_string f
22
+ | `Int n -> Int.to_string n
23
+ | `Bool b -> Bool.to_string b
24
+ | `List xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:json_to_string xs) ^ "]"
25
+ | `Assoc xs -> "[" ^ String.concat ~sep:"; "
26
+ (List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ json_to_string v ^ ")")) ^ "]"
@@ -8,38 +8,6 @@ type error =
8
8
  TestMustHaveKeyCalledCases of string | ExpectingListOfCases | ExpectingMapForCase |
9
9
  NoDescription | BadDescription | NoExpected of string | BadExpected | UnrecognizedJson [@@deriving eq, show]
10
10
 
11
- let to_int_safe = function
12
- | `Int x -> Some x
13
- | _ -> None
14
-
15
- let to_tuple_safe xs = match xs with
16
- | `List [`Int x; `Int y] -> Some (x,y)
17
- | _ -> None
18
-
19
- let rec to_list_safe xs: parameter option = let open Option.Monad_infix in match xs with
20
- | [] -> Some (StringList [])
21
- | `String x :: _ -> Some (StringList (List.map xs ~f:to_string))
22
- | `Int x :: _ -> List.map xs ~f:to_int_safe |> sequence_option >>= (fun xs -> Some (IntList xs))
23
- | `List x :: _ -> List.map xs ~f:to_tuple_safe |> sequence_option >>= (fun xs -> Some (IntTupleList xs))
24
- | _ -> None
25
-
26
- let q xs = let open Option.Monad_infix in
27
- List.map xs ~f:(fun (k,v) -> (to_int_safe v |> Option.map ~f:(fun v -> (k,v))))
28
-
29
- let to_parameter (s: json) = match s with
30
- | `Null -> Some (Null)
31
- | `String x -> Some (String x)
32
- | `Float x -> Some (Float x)
33
- | `Int x -> Some (Int x)
34
- | `Bool x -> Some (Bool x)
35
- | `List x -> to_list_safe x
36
- | `Assoc xs -> let open Option.Monad_infix in
37
- let xs = List.map xs ~f:(fun (k,v) -> (to_int_safe v |> Option.map ~f:(fun v -> (k,v)))) in
38
- sequence_option xs >>= fun xs -> Some (IntStringMap xs)
39
-
40
- let parse_parameters (parameters: (string * json) list): parameter elements =
41
- List.filter_map parameters ~f:(fun (k, v) -> Option.map ~f:(fun v -> (k, v)) (to_parameter v))
42
-
43
11
  let parse_case_assoc (parameters: (string * json) list) (expected_key: string): (case, error) Result.t =
44
12
  let find name e = List.Assoc.find parameters name |> Result.of_option ~error:e in
45
13
  let test_parameters = List.Assoc.remove parameters "description" in
@@ -47,9 +15,8 @@ let parse_case_assoc (parameters: (string * json) list) (expected_key: string):
47
15
  let open Result.Monad_infix in
48
16
  find "description" NoDescription >>=
49
17
  to_string_note BadDescription >>= fun description ->
50
- find expected_key (NoExpected description) >>= fun expectedJson ->
51
- to_parameter expectedJson |> Result.of_option ~error:BadExpected >>= fun expected ->
52
- Ok {description = description; parameters = parse_parameters test_parameters; expected = expected}
18
+ find expected_key (NoExpected description) >>= fun expected ->
19
+ Ok {description = description; parameters = test_parameters; expected = expected}
53
20
 
54
21
  let parse_case (expected_key: string) (s: json): (case, error) Result.t = match s with
55
22
  | `Assoc assoc -> parse_case_assoc assoc expected_key
@@ -1,60 +1,73 @@
1
1
  open Core.Std
2
2
 
3
3
  open Model
4
+ open Yojson.Basic
5
+
6
+ let map_elements (to_str: json -> string) (parameters: (string * json) list): (string * string) list =
7
+ List.map parameters ~f:(fun (k,j) -> (k,to_str j))
4
8
 
5
9
  let optional_int ~(none: int) = function
6
- | Int n when n = none -> "None"
7
- | Int n -> "(Some " ^ Int.to_string n ^ ")"
8
- | x -> parameter_to_string x
10
+ | `Int n when n = none -> "None"
11
+ | `Int n -> "(Some " ^ Int.to_string n ^ ")"
12
+ | x -> json_to_string x
9
13
 
10
14
  let optional_int_list = function
11
- | IntList xs -> "(Some [" ^ String.concat ~sep:"; " (List.map ~f:Int.to_string xs) ^ "])"
15
+ | `List xs -> "(Some [" ^ String.concat ~sep:"; " (List.map ~f:json_to_string xs) ^ "])"
12
16
  | _ -> "None"
13
17
 
14
18
  let optional_int_or_string ~(none: int) = function
15
- | String s -> "(Some \"" ^ s ^ "\")"
16
- | Int n when n = none -> "None"
17
- | x -> parameter_to_string x
19
+ | `String s -> "(Some \"" ^ s ^ "\")"
20
+ | `Int n when n = none -> "None"
21
+ | x -> json_to_string x
18
22
 
19
23
  let default_value ~(key: string) ~(value: string) (parameters: (string * string) list): (string * string) list =
20
24
  if List.exists ~f:(fun (k, _) -> k = key) parameters
21
25
  then parameters
22
26
  else (key, value) :: parameters
23
27
 
24
- let optional_strings ~(f: string -> bool) (parameters: (string * string) list): (string * string) list =
28
+ let optional_strings ~(f: string -> bool) (parameters: (string * json) list): (string * string) list =
25
29
  let replace parameter =
26
30
  let (k, v) = parameter in
27
31
  if f k
28
- then (k, "(Some \"" ^ v ^ "\")")
29
- else parameter in
32
+ then (k, "(Some " ^ json_to_string v ^ ")")
33
+ else (k, json_to_string v) in
30
34
  List.map ~f:replace parameters
31
35
 
32
- let edit_expected ~(stringify: parameter -> string) ~(slug: string) ~(value: parameter) = match slug with
36
+ let edit_expected ~(stringify: json -> string) ~(slug: string) ~(value: json) = match slug with
33
37
  | "hamming" -> optional_int ~none:(-1) value
34
38
  | "all-your-base" -> optional_int_list value
35
39
  | "say" -> optional_int_or_string ~none:(-1) value
36
40
  | _ -> stringify value
37
41
 
38
- let edit_say (ps: (string * string) list) =
42
+ let edit_say (ps: (string * json) list) =
39
43
  let edit = function
40
- | ("input", v) -> ("input", if Int.of_string v >= 0 then "(" ^ v ^ "L)" else v ^ "L")
41
- | x -> x in
44
+ | ("input", v) -> ("input", let v = json_to_string v in if Int.of_string v >= 0 then "(" ^ v ^ "L)" else v ^ "L")
45
+ | (k, ps) -> (k, json_to_string ps) in
42
46
  List.map ps ~f:edit
43
47
 
44
- let edit_all_your_base (ps: (string * string) list) =
48
+ let edit_all_your_base (ps: (string * json) list): (string * string) list =
45
49
  let edit = function
46
- | ("output_base", v) -> ("output_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
47
- | ("input_base", v) -> ("input_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
48
- | x -> x in
50
+ | ("output_base", v) -> let v = json_to_string v in ("output_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
51
+ | ("input_base", v) -> let v = json_to_string v in ("input_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
52
+ | (k, v) -> (k, json_to_string v) in
49
53
  List.map ps ~f:edit
50
54
 
51
- let edit_parameters ~(slug: string) (parameters: (string * string) list) = match (slug, parameters) with
52
- | ("hello-world", ps) -> default_value ~key:"name" ~value:"None"
53
- @@ optional_strings ~f:(fun _x -> true)
54
- @@ parameters
55
+ let two_elt_list_to_tuple (j: json): string = match j with
56
+ | `List [`Int x1; `Int x2] -> sprintf "(%d,%d)" x1 x2
57
+ | _ -> failwith "two element list expected, but got " ^ (json_to_string j)
58
+
59
+ let edit_dominoes (ps: (string * json) list): (string * string) list =
60
+ let edit (p: (string * json)) = match p with
61
+ | ("input", `List j) -> ("input", "[" ^ (List.map ~f:two_elt_list_to_tuple j |> String.concat ~sep:"; ") ^ "]")
62
+ | (k, v) -> (k, json_to_string v) in
63
+ List.map ps ~f:edit
64
+
65
+ let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (slug, parameters) with
66
+ | ("hello-world", ps) -> default_value ~key:"name" ~value:"None" (optional_strings ~f:(fun _x -> true) parameters)
55
67
  | ("say", ps) -> edit_say ps
56
68
  | ("all-your-base", ps) -> edit_all_your_base ps
57
- | (_, ps) -> ps
69
+ | ("dominoes", ps) -> edit_dominoes ps
70
+ | (_, ps) -> map_elements json_to_string ps
58
71
 
59
72
  let expected_key_name slug = match slug with
60
73
  | "dominoes" -> "can_chain"
@@ -9,7 +9,7 @@ let ae exp got _test_ctxt =
9
9
  let tests = [
10
10
  (* TEST
11
11
  "$description" >::
12
- ae $expected (anagrams "$subject" $candidates);
12
+ ae $expected (anagrams $subject $candidates);
13
13
  END TEST *)
14
14
  ]
15
15
 
@@ -0,0 +1,24 @@
1
+ open Core.Std
2
+ open OUnit2
3
+ open Atbash_cipher
4
+
5
+ let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
6
+
7
+ let (* SUITE *)$(suite_name)_tests = [
8
+ (* TEST
9
+ "$description" >::
10
+ ae $expected ($suite-name $phrase);
11
+ END TEST *)
12
+ ]
13
+ (* END SUITE *)
14
+
15
+ let different_block_size_test = [
16
+ "encode mindblowingly with a different block size" >::
17
+ ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
18
+ ]
19
+
20
+ let () =
21
+ run_test_tt_main (
22
+ "atbash-cipher tests" >:::
23
+ List.concat [(* suite-all-names *); different_block_size_test]
24
+ )
@@ -7,7 +7,7 @@ let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
7
7
  let tests = [
8
8
  (* TEST
9
9
  "$description" >::
10
- ae "$expected" (response_for "$input");
10
+ ae $expected (response_for $input);
11
11
  END TEST *)
12
12
  ]
13
13
 
@@ -8,7 +8,7 @@ let ae exp got _test_ctxt =
8
8
  let tests = [
9
9
  (* TEST
10
10
  "$description" >::
11
- ae $expected (are_balanced "$input");
11
+ ae $expected (are_balanced $input);
12
12
  END TEST *)
13
13
  ]
14
14
 
@@ -22,7 +22,7 @@ let hamdist a b = Hamming.hamming_distance (dna_of_string a) (dna_of_string b)
22
22
  let tests = [
23
23
  (* TEST
24
24
  "$description" >::
25
- ae $expected (hamdist "$strand1" "$strand2");
25
+ ae $expected (hamdist $strand1 $strand2);
26
26
  END TEST *)
27
27
  ]
28
28
 
@@ -6,7 +6,7 @@ let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
6
6
 
7
7
  let tests = [
8
8
  (* TEST
9
- "$description" >:: ae "$expected" (greet $name);
9
+ "$description" >:: ae $expected (greet $name);
10
10
  END TEST *)
11
11
  ]
12
12
 
@@ -8,7 +8,7 @@ let assert_valid expected input _test_ctxt =
8
8
  let tests = [
9
9
  (* TEST
10
10
  "$description" >::
11
- assert_valid $expected "$input";
11
+ assert_valid $expected $input;
12
12
  END TEST *)
13
13
  ]
14
14
 
@@ -7,7 +7,7 @@ let ae exp got _test_ctxt = assert_equal ~printer:Bool.to_string exp got
7
7
  let tests = [
8
8
  (* TEST
9
9
  "$description" >::
10
- ae $expected (is_pangram "$input");
10
+ ae $expected (is_pangram $input);
11
11
  END TEST *)
12
12
  ]
13
13
 
@@ -7,7 +7,7 @@ let ae exp got _test_ctxt = assert_equal ~printer:Fn.id exp got
7
7
  let tests = [
8
8
  (* TEST
9
9
  "$description" >::
10
- ae "$expected" (raindrop $number);
10
+ ae $expected (raindrop $number);
11
11
  END TEST *)
12
12
  ]
13
13
 
@@ -12,7 +12,7 @@ let tests = [
12
12
  (* TEST
13
13
  "$description" >::
14
14
  ae $expected
15
- (word_count "$input");
15
+ (word_count $input);
16
16
  END TEST *)
17
17
  ]
18
18
 
@@ -2,11 +2,13 @@ open Core.Std
2
2
  open OUnit2
3
3
  open Codegen
4
4
  open Model
5
+ open Yojson.Basic
5
6
 
6
7
  let leap_template = "\"$description\" >:: ae $expected (leap_year $input);"
7
8
 
8
- let edit_expected ~value = parameter_to_string value
9
- let edit_parameters = Fn.id
9
+ let edit_expected ~value = json_to_string value
10
+ let edit_parameters (j: (string * json) list): (string * string) list =
11
+ List.map ~f:(fun (k,v) -> (k,to_string v)) j
10
12
  let assert_fill_in_template exp cases = assert_equal exp
11
13
  ~printer:(fun xs -> "[" ^ (String.concat ~sep:";" xs) ^ "]")
12
14
  (fill_in_template edit_expected edit_parameters leap_template "suite-name" cases |> List.map ~f:subst_to_string)
@@ -17,7 +19,7 @@ let codegen_tests = [
17
19
  ae [] [];
18
20
 
19
21
  "generates one function based on leap year for one case" >::(fun ctxt ->
20
- let c = {description = "leap_year"; parameters = [("input", Int 1996)]; expected = Bool true} in
22
+ let c = {description = "leap_year"; parameters = [("input", `Int 1996)]; expected = `Bool true} in
21
23
  assert_fill_in_template ["\"leap_year\" >:: ae true (leap_year 1996);"] [c]
22
24
  );
23
25
  ]
@@ -6,24 +6,6 @@ open Model
6
6
  let ae exp got _ctxt = assert_equal ~printer:Fn.id exp got
7
7
 
8
8
  let model_tests = [
9
- "int parameter to string" >::
10
- ae "8" @@ parameter_to_string (Int 8);
11
- "bool parameter to string" >::
12
- ae "true" @@ parameter_to_string (Bool true);
13
- "string parameter to string" >::
14
- ae "xyz" @@ parameter_to_string (String "xyz");
15
- "string parameter containing escaped characters to string" >::
16
- ae "x\\t\\ny" @@ parameter_to_string (String "x\t\ny");
17
- "float parameter to string" >::
18
- ae "3.14" @@ parameter_to_string (Float 3.14);
19
- "string list parameter to string" >::
20
- ae "[\"a\"; \"bc\"; \"def\"]" @@ parameter_to_string (StringList ["a"; "bc"; "def"]);
21
- "string list parameter with escaped characters to string" >::
22
- ae "[\"a\\r\"; \"b\\nc\"; \"d\\tef\"]" @@ parameter_to_string (StringList ["a\r"; "b\nc"; "d\tef"]);
23
- "int list parameter to string" >::
24
- ae "[1; 2; 3; 4]" @@ parameter_to_string (IntList [1; 2; 3; 4]);
25
- "int string map parameter to string" >::
26
- ae "[(\"one\", 1); (\"two\", 1)]" @@ parameter_to_string (IntStringMap [("one", 1); ("two", 1)]);
27
- "int string map parameter to string with escaped characters in the keys" >::
28
- ae "[(\"\\t\\r\", 1); (\"two\\n\", 1)]" @@ parameter_to_string (IntStringMap [("\t\r", 1); ("two\n", 1)]);
9
+ "json_to_string on list of strings" >::
10
+ ae "[\"a\"; \"b\"; \"c\"]" @@ json_to_string (`List [`String "a"; `String "b"; `String "c"]);
29
11
  ]
@@ -3,12 +3,7 @@ open OUnit2
3
3
  open Parser
4
4
  open Model
5
5
 
6
- let show_cases = function
7
- | Ok (Single cs) -> List.map ~f:show_case cs |> String.concat
8
- | Ok (Suite cs) -> failwith "no printer"
9
- | Error e -> show_error e
10
-
11
- let ae exp got _test_ctxt = assert_equal exp got ~printer:show_cases
6
+ let ae exp got _test_ctxt = assert_equal exp got
12
7
 
13
8
  let single x = Ok (Single x)
14
9
 
@@ -31,41 +26,37 @@ let parser_tests = [
31
26
  (call_parser "{\"cases\" : [\"key\"]}");
32
27
 
33
28
  "parses a single element with a description and expected string output" >::
34
- ae (single [{description = "d1"; parameters = []; expected = String "value"}])
29
+ ae (single [{description = "d1"; parameters = []; expected = `String "value"}])
35
30
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : \"value\"}]}");
36
31
 
37
32
  "parses a single element with a description and expected float output" >::
38
- ae (single [{description = "d1"; parameters = []; expected = Float 100.}])
33
+ ae (single [{description = "d1"; parameters = []; expected = `Float 100.}])
39
34
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : 100.0}]}");
40
35
 
41
36
  "parses a single element with a description and expected bool output" >::
42
- ae (single [{description = "d1"; parameters = []; expected = Bool true}])
37
+ ae (single [{description = "d1"; parameters = []; expected = `Bool true}])
43
38
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : true}]}");
44
39
 
45
40
  "parses a single element with a description and expected int list output" >::
46
- ae (single [{description = "d1"; parameters = []; expected = IntList [1;2;3]}])
41
+ ae (single [{description = "d1"; parameters = []; expected = `List [`Int 1;`Int 2;`Int 3]}])
47
42
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : [1, 2, 3]}]}");
48
43
 
49
44
  "parses a single element with a description and expected null output" >::
50
- ae (single [{description = "d1"; parameters = []; expected = Null}])
45
+ ae (single [{description = "d1"; parameters = []; expected = `Null}])
51
46
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : null}]}");
52
47
 
53
48
  "parses a single element with an int key value pair" >::
54
- ae (single [{description = "d1"; parameters = [("input", Int 1996)]; expected = Bool true}])
49
+ ae (single [{description = "d1"; parameters = [("input", `Int 1996)]; expected = `Bool true}])
55
50
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : 1996, \"expected\" : true}]}");
56
51
 
57
52
  "parses a single element with a string key value pair" >::
58
- ae (single [{description = "d1"; parameters = [("input", String "some-string")]; expected = Int 85}])
53
+ ae (single [{description = "d1"; parameters = [("input", `String "some-string")]; expected = `Int 85}])
59
54
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : \"some-string\", \"expected\" : 85}]}");
60
55
 
61
56
  "parses a single element with a string list key value pair" >::
62
- ae (single [{description = "d1"; parameters = [("input", StringList ["s1"; "s2"])]; expected = Int 85}])
57
+ ae (single [{description = "d1"; parameters = [("input", `List [`String "s1"; `String "s2"])]; expected = `Int 85}])
63
58
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [\"s1\", \"s2\"], \"expected\" : 85}]}");
64
59
 
65
- "parses a single element with a int tuple list (modelled as an int list) key value pair" >::
66
- ae (single [{description = "d1"; parameters = [("input", IntTupleList [(1,2);(3,4)])]; expected = Int 85}])
67
- (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"input\" : [[1,2],[3,4]], \"expected\" : 85}]}");
68
-
69
60
  "an element without a description is an Error" >::
70
61
  ae (Error NoDescription)
71
62
  (call_parser "{\"cases\" : [{\"input\" : 11, \"expected\" : 85}]}");
@@ -79,7 +70,7 @@ let parser_tests = [
79
70
  (call_parser "{\"cases\" : [{\"input\" : 11}]}");
80
71
 
81
72
  "parses a map in the expected parameter" >::(fun _ctx ->
82
- assert_equal (single [{description = "d1"; parameters = []; expected = IntStringMap [("one", 1); ("two", 2)]}])
73
+ assert_equal (single [{description = "d1"; parameters = []; expected = `Assoc [("one", `Int 1); ("two", `Int 2)]}])
83
74
  (call_parser "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : {\"one\": 1, \"two\": 2}}]}");
84
75
  );
85
76
 
@@ -3,6 +3,7 @@ open OUnit2
3
3
  open Model
4
4
  open Codegen
5
5
  open Special_cases
6
+ open Yojson.Basic
6
7
 
7
8
  let ae exp got _ctxt = assert_equal ~printer:Fn.id exp got
8
9
 
@@ -10,20 +11,20 @@ let tuples_printer kvs =
10
11
  String.concat ~sep:";" @@ List.map ~f:(fun (k,v) -> "(" ^ k ^ "," ^ v ^ ")") kvs
11
12
 
12
13
  let stringify = function
13
- | Bool true -> "stringified"
14
+ | `Bool true -> "stringified"
14
15
  | _ -> failwith "Bad type for stringify"
15
16
 
16
17
  let special_cases_tests = [
17
18
  "for a non special cased slug convert the parameter to a string" >:: (fun _ctx ->
18
- assert_equal ~printer:Fn.id "stringified" @@ edit_expected ~stringify ~slug:"some-slug" ~value:(Bool true)
19
+ assert_equal ~printer:Fn.id "stringified" @@ edit_expected ~stringify ~slug:"some-slug" ~value:(`Bool true)
19
20
  );
20
21
 
21
22
  "an optional int parameter is converted to none if it matches the special value" >:: (fun _ctx ->
22
- assert_equal "None" @@ optional_int ~none:88 (Int 88)
23
+ assert_equal "None" @@ optional_int ~none:88 (`Int 88)
23
24
  );
24
25
 
25
26
  "an optional int parameter is converted to (Some value) if it does not match the special value" >:: (fun _ctx ->
26
- assert_equal "(Some 0)" @@ optional_int ~none:88 (Int 0)
27
+ assert_equal "(Some 0)" @@ optional_int ~none:88 (`Int 0)
27
28
  );
28
29
 
29
30
  "default_value does not provide a default for a list that has the given key already" >:: (fun _ctx ->
@@ -36,7 +37,7 @@ let special_cases_tests = [
36
37
  );
37
38
 
38
39
  "optional_strings replace value with Some(value)" >:: (fun _ctx ->
39
- assert_equal ~printer:tuples_printer [("key", "(Some \"value\")"); ("key2", "value2")]
40
- @@ optional_strings ~f:(fun x -> x = "key") [("key", "value"); ("key2", "value2")]
40
+ assert_equal ~printer:tuples_printer [("key", "(Some \"value\")"); ("key2", "\"value2\"")]
41
+ @@ optional_strings ~f:(fun x -> x = "key") [("key", `String "value"); ("key2", `String "value2")]
41
42
  );
42
43
  ]
@@ -16,6 +16,11 @@
16
16
 
17
17
  ],
18
18
  "exercises": [
19
+ {
20
+ "difficulty": 1,
21
+ "slug": "hello-world",
22
+ "topics": []
23
+ },
19
24
  {
20
25
  "difficulty": 1,
21
26
  "slug": "bob",