trackler 2.0.6.30 → 2.0.6.31

Sign up to get free protection for your applications and to get access to all the features.
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",