trackler 2.1.0.26 → 2.1.0.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/common/CONTRIBUTING.md +0 -15
  3. data/common/exercises/secret-handshake/canonical-data.json +14 -7
  4. data/lib/trackler/version.rb +1 -1
  5. data/tracks/dlang/config.json +18 -0
  6. data/tracks/dlang/exercises/leap/leap.d +8 -0
  7. data/tracks/dlang/exercises/leap/leap_example.d +15 -0
  8. data/tracks/dlang/exercises/react/react.d +211 -0
  9. data/tracks/dlang/exercises/react/react_example.d +291 -0
  10. data/tracks/factor/README.md +7 -7
  11. data/tracks/factor/config.json +13 -4
  12. data/tracks/factor/exercises/hello-world/hello-world-example.factor +2 -3
  13. data/tracks/factor/exercises/hello-world/hello-world-tests.factor +1 -5
  14. data/tracks/factor/exercises/hello-world/hello-world.factor +1 -1
  15. data/tracks/factor/exercises/two-fer/two-fer-example.factor +6 -0
  16. data/tracks/factor/exercises/two-fer/two-fer-tests.factor +8 -0
  17. data/tracks/fortran/Makefile +1 -2
  18. data/tracks/fortran/config.json +6 -0
  19. data/tracks/fortran/exercises/bob/bob.fun +18 -18
  20. data/tracks/fortran/exercises/hamming/example.f90 +25 -0
  21. data/tracks/fortran/exercises/hamming/hamming.fun +75 -0
  22. data/tracks/go/exercises/poker/.meta/gen.go +76 -0
  23. data/tracks/go/exercises/poker/cases_test.go +240 -0
  24. data/tracks/go/exercises/poker/example.go +10 -1
  25. data/tracks/go/exercises/poker/poker_test.go +1 -224
  26. data/tracks/go/exercises/sum-of-multiples/.meta/gen.go +43 -0
  27. data/tracks/go/exercises/sum-of-multiples/cases_test.go +24 -0
  28. data/tracks/go/exercises/sum-of-multiples/example.go +1 -1
  29. data/tracks/go/exercises/sum-of-multiples/sum_of_multiples_test.go +1 -18
  30. data/tracks/groovy/exercises/robot-name/RobotSpec.groovy +38 -0
  31. data/tracks/kotlin/config.json +10 -0
  32. data/tracks/kotlin/exercises/collatz-conjecture/build.gradle +28 -0
  33. data/tracks/kotlin/exercises/collatz-conjecture/src/example/kotlin/CollatzCalculator.kt +12 -0
  34. data/tracks/kotlin/exercises/collatz-conjecture/src/main/kotlin/.keep +0 -0
  35. data/tracks/kotlin/exercises/collatz-conjecture/src/test/kotlin/CollatzCalculatorTest.kt +51 -0
  36. data/tracks/kotlin/exercises/diamond/build.gradle +28 -0
  37. data/tracks/kotlin/exercises/diamond/src/example/kotlin/DiamondPrinter.kt +35 -0
  38. data/tracks/kotlin/exercises/diamond/src/main/kotlin/DiamondPrinter.kt +5 -0
  39. data/tracks/kotlin/exercises/diamond/src/test/kotlin/DiamondPrinterTest.kt +121 -0
  40. data/tracks/kotlin/exercises/settings.gradle +2 -0
  41. data/tracks/ocaml/.gitignore +1 -0
  42. data/tracks/ocaml/.vscode/launch.json +14 -0
  43. data/tracks/ocaml/tools/test-generator/src/controller.ml +15 -16
  44. data/tracks/ocaml/tools/test-generator/src/languages.ml +30 -0
  45. data/tracks/ocaml/tools/test-generator/src/ocaml_special_cases.ml +137 -0
  46. data/tracks/ocaml/tools/test-generator/src/purescript_special_cases.ml +13 -0
  47. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +7 -132
  48. data/tracks/ocaml/tools/test-generator/src/template.ml +3 -3
  49. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +13 -3
  50. data/tracks/ocaml/tools/test-generator/templates/{acronym → ocaml/acronym}/template.ml +0 -0
  51. data/tracks/ocaml/tools/test-generator/templates/{all-your-base → ocaml/all-your-base}/template.ml +0 -0
  52. data/tracks/ocaml/tools/test-generator/templates/{anagram → ocaml/anagram}/template.ml +0 -0
  53. data/tracks/ocaml/tools/test-generator/templates/{atbash-cipher → ocaml/atbash-cipher}/template.ml +0 -0
  54. data/tracks/ocaml/tools/test-generator/templates/{beer-song → ocaml/beer-song}/template.ml +0 -0
  55. data/tracks/ocaml/tools/test-generator/templates/{binary-search → ocaml/binary-search}/template.ml +0 -0
  56. data/tracks/ocaml/tools/test-generator/templates/{bob → ocaml/bob}/template.ml +0 -0
  57. data/tracks/ocaml/tools/test-generator/templates/{bowling → ocaml/bowling}/template.ml +0 -0
  58. data/tracks/ocaml/tools/test-generator/templates/{bracket-push → ocaml/bracket-push}/template.ml +0 -0
  59. data/tracks/ocaml/tools/test-generator/templates/{change → ocaml/change}/template.ml +0 -0
  60. data/tracks/ocaml/tools/test-generator/templates/{connect → ocaml/connect}/template.ml +0 -0
  61. data/tracks/ocaml/tools/test-generator/templates/{difference-of-squares → ocaml/difference-of-squares}/template.ml +0 -0
  62. data/tracks/ocaml/tools/test-generator/templates/{dominoes → ocaml/dominoes}/template.ml +0 -0
  63. data/tracks/ocaml/tools/test-generator/templates/{etl → ocaml/etl}/template.ml +0 -0
  64. data/tracks/ocaml/tools/test-generator/templates/{forth → ocaml/forth}/template.ml +0 -0
  65. data/tracks/ocaml/tools/test-generator/templates/{hamming → ocaml/hamming}/template.ml +0 -0
  66. data/tracks/ocaml/tools/test-generator/templates/{hello-world → ocaml/hello-world}/template.ml +0 -0
  67. data/tracks/ocaml/tools/test-generator/templates/{leap → ocaml/leap}/template.ml +0 -0
  68. data/tracks/ocaml/tools/test-generator/templates/{luhn → ocaml/luhn}/template.ml +0 -0
  69. data/tracks/ocaml/tools/test-generator/templates/{minesweeper → ocaml/minesweeper}/template.ml +0 -0
  70. data/tracks/ocaml/tools/test-generator/templates/{pangram → ocaml/pangram}/template.ml +0 -0
  71. data/tracks/ocaml/tools/test-generator/templates/{phone-number → ocaml/phone-number}/template.ml +0 -0
  72. data/tracks/ocaml/tools/test-generator/templates/{prime-factors → ocaml/prime-factors}/template.ml +0 -0
  73. data/tracks/ocaml/tools/test-generator/templates/{raindrops → ocaml/raindrops}/template.ml +0 -0
  74. data/tracks/ocaml/tools/test-generator/templates/{roman-numerals → ocaml/roman-numerals}/template.ml +0 -0
  75. data/tracks/ocaml/tools/test-generator/templates/{run-length-encoding → ocaml/run-length-encoding}/template.ml +0 -0
  76. data/tracks/ocaml/tools/test-generator/templates/{say → ocaml/say}/template.ml +0 -0
  77. data/tracks/ocaml/tools/test-generator/templates/{space-age → ocaml/space-age}/template.ml +0 -0
  78. data/tracks/ocaml/tools/test-generator/templates/{triangle → ocaml/triangle}/template.ml +0 -0
  79. data/tracks/ocaml/tools/test-generator/templates/{word-count → ocaml/word-count}/template.ml +0 -0
  80. data/tracks/ocaml/tools/test-generator/templates/purescript/hamming/Main.purs +18 -0
  81. data/tracks/ocaml/tools/test-generator/test/all_tests.ml +2 -2
  82. data/tracks/ocaml/tools/test-generator/test/{special_cases_test.ml → ocaml_special_cases_test.ml} +3 -3
  83. data/tracks/ocaml/tools/test-generator/test/template_test.ml +1 -0
  84. metadata +59 -34
  85. data/tracks/groovy/exercises/robot-name/RobotTest.groovy +0 -34
@@ -0,0 +1,13 @@
1
+ open Core
2
+
3
+ open Model
4
+ open Yojson.Basic
5
+
6
+ let optional_int ~(none: int) = function
7
+ | `Int n when n = none -> "Nothing"
8
+ | `Int n -> "(Just " ^ Int.to_string n ^ ")"
9
+ | x -> json_to_string x
10
+
11
+ let edit_expected ~(stringify: json -> string) ~(slug: string) ~(value: json) = match slug with
12
+ | "hamming" -> optional_int ~none:(-1) value
13
+ | _ -> stringify value
@@ -1,137 +1,12 @@
1
1
  open Core
2
2
 
3
- open Model
4
3
  open Yojson.Basic
4
+ open Ocaml_special_cases
5
+ open Purescript_special_cases
5
6
 
6
- let strip_quotes s = String.drop_prefix s 1 |> Fn.flip String.drop_suffix 1
7
+ let edit_expected ~(language: string) ~(stringify: json -> string) ~(slug: string) ~(value: json) = match language with
8
+ | "ocaml" -> Ocaml_special_cases.ocaml_edit_expected ~stringify ~slug ~value
9
+ | "purescript" -> Purescript_special_cases.edit_expected ~stringify ~slug ~value
10
+ | _ -> failwith "unknown language"
7
11
 
8
- let map_elements (to_str: json -> string) (parameters: (string * json) list): (string * string) list =
9
- List.map parameters ~f:(fun (k,j) -> (k,to_str j))
10
-
11
- let optional_int ~(none: int) = function
12
- | `Int n when n = none -> "None"
13
- | `Int n -> "(Some " ^ Int.to_string n ^ ")"
14
- | x -> json_to_string x
15
-
16
- let optional_int_list = function
17
- | `List xs -> "(Some [" ^ String.concat ~sep:"; " (List.map ~f:json_to_string xs) ^ "])"
18
- | _ -> "None"
19
-
20
- let optional_int_or_string ~(none: int) = function
21
- | `String s -> "(Some \"" ^ s ^ "\")"
22
- | `Int n when n = none -> "None"
23
- | x -> json_to_string x
24
-
25
- let default_value ~(key: string) ~(value: string) (parameters: (string * string) list): (string * string) list =
26
- if List.exists ~f:(fun (k, _) -> k = key) parameters
27
- then parameters
28
- else (key, value) :: parameters
29
-
30
- let optional_strings ~(f: string -> bool) (parameters: (string * json) list): (string * string) list =
31
- let replace parameter =
32
- let (k, v) = parameter in
33
- if f k
34
- then (k, "(Some " ^ json_to_string v ^ ")")
35
- else (k, json_to_string v) in
36
- List.map ~f:replace parameters
37
-
38
- let option_of_null (value: json): string = match value with
39
- | `Null -> "None"
40
- | `String s -> "(Some \"" ^ s ^ "\")"
41
- | `List xs as l -> "(Some " ^ (json_to_string l) ^ ")"
42
- | _ -> failwith "cannot handle this type"
43
-
44
- let is_empty_string (value: json): bool = match value with
45
- | `String s -> String.is_empty s
46
- | _ -> false
47
-
48
- let edit_connect_expected = function
49
- | `String "X" -> "(Some X)"
50
- | `String "O" -> "(Some O)"
51
- | `String "" -> "None"
52
- | x -> failwith "Bad json value in connect " ^ json_to_string x
53
-
54
- let edit_change_expected (value: json) = match value with
55
- | `List xs -> "(Some [" ^ (String.concat ~sep:"; " (List.map ~f:json_to_string xs)) ^ "])"
56
- | `Int (-1) -> "None"
57
- | _ -> failwith "Bad json value in change"
58
-
59
- let edit_bowling_expected (value: json) = match value with
60
- | `Int n -> "(Ok " ^ (Int.to_string n) ^ ")"
61
- | `Assoc [(k, v)] ->
62
- if k = "error" then "(Error " ^ json_to_string v ^ ")" else failwith ("Can only handle error value but got " ^ k)
63
- | _ -> failwith "Bad json value in bowling"
64
-
65
- let edit_expected ~(stringify: json -> string) ~(slug: string) ~(value: json) = match slug with
66
- | "hamming" -> optional_int ~none:(-1) value
67
- | "all-your-base" -> optional_int_list value
68
- | "say" -> optional_int_or_string ~none:(-1) value
69
- | "phone-number" -> option_of_null value
70
- | "connect" -> edit_connect_expected value
71
- | "change" -> edit_change_expected value
72
- | "bowling" -> edit_bowling_expected value
73
- | "binary-search" -> optional_int ~none:(-1) value
74
- | "forth" -> option_of_null value
75
- | _ -> stringify value
76
-
77
- let edit_say (ps: (string * json) list) =
78
- let edit = function
79
- | ("input", v) -> ("input", let v = json_to_string v in if Int.of_string v >= 0 then "(" ^ v ^ "L)" else v ^ "L")
80
- | (k, ps) -> (k, json_to_string ps) in
81
- List.map ps ~f:edit
82
-
83
- let edit_all_your_base (ps: (string * json) list): (string * string) list =
84
- let edit = function
85
- | ("output_base", v) -> let v = json_to_string v in ("output_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
86
- | ("input_base", v) -> let v = json_to_string v in ("input_base", if Int.of_string v >= 0 then v else "(" ^ v ^ ")")
87
- | (k, v) -> (k, json_to_string v) in
88
- List.map ps ~f:edit
89
-
90
- let edit_dominoes (ps: (string * json) list): (string * string) list =
91
- let two_elt_list_to_tuple (j: json): string = match j with
92
- | `List [`Int x1; `Int x2] -> sprintf "(%d,%d)" x1 x2
93
- | _ -> failwith "two element list expected, but got " ^ (json_to_string j) in
94
- let edit (p: (string * json)) = match p with
95
- | ("input", `List j) -> ("input", "[" ^ (List.map ~f:two_elt_list_to_tuple j |> String.concat ~sep:"; ") ^ "]")
96
- | (k, v) -> (k, json_to_string v) in
97
- List.map ps ~f:edit
98
-
99
-
100
- let edit_space_age (ps: (string * json) list): (string * string) list =
101
- let edit = function
102
- | ("planet", v) -> ("planet", json_to_string v |> strip_quotes)
103
- | (k, v) -> (k, json_to_string v) in
104
- List.map ps ~f:edit
105
-
106
- let edit_bowling (ps: (string * json) list): (string * string) list =
107
- let edit = function
108
- | ("property", v) -> ("property", json_to_string v |> strip_quotes)
109
- | ("roll", `Int n) -> ("roll", let s = Int.to_string n in if n < 0 then ("(" ^ s ^ ")") else s)
110
- | (k, v) -> (k, json_to_string v) in
111
- List.map ps ~f:edit
112
-
113
- let edit_binary_search (ps: (string * json) list): (string * string) list =
114
- let open Yojson.Basic.Util in
115
- let as_array_string xs =
116
- let xs = to_list xs |> List.map ~f:to_int |> List.map ~f:Int.to_string in
117
- "[|" ^ String.concat ~sep:"; " xs ^ "|]" in
118
- let edit = function
119
- | ("array", v) -> ("array", as_array_string v)
120
- | (k, v) -> (k, json_to_string v) in
121
- List.map ps ~f:edit
122
-
123
- let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (slug, parameters) with
124
- | ("hello-world", ps) -> default_value ~key:"name" ~value:"None" (optional_strings ~f:(fun _x -> true) parameters)
125
- | ("say", ps) -> edit_say ps
126
- | ("all-your-base", ps) -> edit_all_your_base ps
127
- | ("dominoes", ps) -> edit_dominoes ps
128
- | ("space-age", ps) -> edit_space_age ps
129
- | ("bowling", ps) -> edit_bowling ps
130
- | ("binary-search", ps) -> edit_binary_search ps
131
- | (_, ps) -> map_elements json_to_string ps
132
-
133
- let expected_key_name slug = match slug with
134
- | "dominoes" -> "can_chain"
135
- | _ -> "expected"
136
-
137
- let cases_name _slug = "cases"
12
+ include Ocaml_special_cases
@@ -24,11 +24,11 @@ type t = {file_text: string;
24
24
  template: template;
25
25
  } [@@deriving eq, show]
26
26
 
27
- let find_template ~(template_text: string): t option =
27
+ let find_template ~(template_text: string) (test_start_marker: string) (test_end_marker: string): t option =
28
28
  let open Option.Monad_infix in
29
29
  let lines = String.split_lines template_text |> List.to_array in
30
- let test_starts = Array.filter_mapi lines ~f:(fun i l -> if (String.is_substring l ~substring:"(* TEST") then Some i else None) in
31
- let test_ends = Array.filter_mapi lines ~f:(fun i l -> if (String.is_substring l ~substring:"END TEST") then Some i else None) in
30
+ let test_starts = Array.filter_mapi lines ~f:(fun i l -> if String.is_substring l ~substring:test_start_marker then Some i else None) in
31
+ let test_ends = Array.filter_mapi lines ~f:(fun i l -> if String.is_substring l ~substring:test_end_marker then Some i else None) in
32
32
  let test_starts_and_ends = Array.zip_exn test_starts test_ends in
33
33
  let template_lines = Array.map test_starts_and_ends ~f:(fun (s,e) -> Array.slice lines (s+1) e) in
34
34
  let suite_name_lines = Array.filter_mapi lines ~f:(fun i l -> if (String.is_prefix l ~prefix:"let (* SUITE ") then Some i else None) in
@@ -1,4 +1,5 @@
1
1
  open Core
2
+ open Languages
2
3
 
3
4
  let is_directory =
4
5
  Command.Spec.Arg_type.create
@@ -12,18 +13,27 @@ let is_directory =
12
13
 
13
14
  let home_dir = Option.value_exn (Sys.getenv "HOME")
14
15
 
16
+ let default_generated name = Option.value ~default:(home_dir ^ "/.x" ^ name ^ "-generated")
17
+
15
18
  let command =
16
19
  Command.basic
17
20
  ~summary:"Generates test code from canonical data."
18
21
  Command.Spec.(
19
22
  empty
23
+ +> flag "-l" (optional string) ~doc:"language to generate tests for"
20
24
  +> flag "-t" (optional_with_default "./templates" is_directory) ~doc:"string Directory containing templates."
21
25
  +> flag "-c" (optional_with_default "../../../x-common/exercises" is_directory) ~doc:"string Directory containing canonical data."
22
- +> flag "-o" (optional_with_default "../../exercises" is_directory) ~doc:"string Directory to output generated tests."
23
- +> flag "-g" (optional_with_default (home_dir ^ "/.xocaml-generated") is_directory) ~doc:"string Directory to backup generated tests."
26
+ +> flag "-o" (optional string) ~doc:"string Directory to output generated tests."
27
+ +> flag "-g" (optional string) ~doc:"string Directory to backup generated tests."
24
28
  +> flag "-f" (optional string) ~doc:"string Filter out files not matching this string."
25
29
  )
26
- (fun templates_folder canonical_data_folder output_folder generated_folder filter () -> Controller.run templates_folder canonical_data_folder output_folder generated_folder filter)
30
+ (fun language templates_folder canonical_data_folder output_folder generated_folder filter () ->
31
+ let language = Option.value language ~default:"ocaml" in
32
+ let lc = default_language_config language in
33
+ let generated_folder = default_generated language generated_folder in
34
+ let templates_folder = templates_folder ^ "/" ^ language in
35
+ let output_folder = Option.value output_folder ~default:(lc.default_base_folder ^ "/exercises") in
36
+ Controller.run lc templates_folder canonical_data_folder output_folder generated_folder filter)
27
37
 
28
38
  let () =
29
39
  Command.run ~version:"0.1" command
@@ -0,0 +1,18 @@
1
+ module Test.Main where
2
+
3
+ import Prelude
4
+ import Control.Monad.Eff (Eff)
5
+ import Test.Unit (suite, test)
6
+ import Test.Unit.Main (runTest)
7
+ import Test.Unit.Assert as Assert
8
+ import Data.List (List, fromFoldable)
9
+ import Data.String as String
10
+ import Hamming (distance)
11
+
12
+ main :: Eff _ Unit
13
+ main = runTest do
14
+ suite "hamming" do
15
+ --TEST
16
+ test "$description" $
17
+ Assert.equal $expected (distance $strand1 $strand2)
18
+ --END TEST
@@ -3,11 +3,11 @@ open OUnit2
3
3
  open Codegen_test
4
4
  open Model_test
5
5
  open Parser_test
6
- open Special_cases_test
6
+ open Ocaml_special_cases_test
7
7
  open Template_test
8
8
  open Utils_test
9
9
 
10
10
  let () =
11
11
  run_test_tt_main ("tests" >:::List.concat [
12
12
  codegen_tests; model_tests; parser_tests;
13
- special_cases_tests; template_tests; utils_tests])
13
+ ocaml_special_cases_tests; template_tests; utils_tests])
@@ -2,7 +2,7 @@ open Core
2
2
  open OUnit2
3
3
  open Model
4
4
  open Codegen
5
- open Special_cases
5
+ open Ocaml_special_cases
6
6
  open Yojson.Basic
7
7
 
8
8
  let ae exp got _ctxt = assert_equal ~printer:Fn.id exp got
@@ -14,9 +14,9 @@ let stringify = function
14
14
  | `Bool true -> "stringified"
15
15
  | _ -> failwith "Bad type for stringify"
16
16
 
17
- let special_cases_tests = [
17
+ let ocaml_special_cases_tests = [
18
18
  "for a non special cased slug convert the parameter to a string" >:: (fun _ctx ->
19
- assert_equal ~printer:Fn.id "stringified" @@ edit_expected ~stringify ~slug:"some-slug" ~value:(`Bool true)
19
+ assert_equal ~printer:Fn.id "stringified" @@ ocaml_edit_expected ~stringify ~slug:"some-slug" ~value:(`Bool true)
20
20
  );
21
21
 
22
22
  "an optional int parameter is converted to none if it matches the special value" >:: (fun _ctx ->
@@ -5,6 +5,7 @@ open Template
5
5
 
6
6
  let printer = Option.value_map ~f:show ~default:"None"
7
7
  let int_option_printer = Option.value_map ~f:Int.to_string ~default:"None"
8
+ let find_template = find_template "(* TEST" "END TEST"
8
9
 
9
10
  let template_tests = [
10
11
  "if there is no test marker in a string then find_template returns None" >:: (fun _ctx ->
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.26
4
+ version: 2.1.0.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Owen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-02 00:00:00.000000000 Z
11
+ date: 2017-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -2107,12 +2107,16 @@ files:
2107
2107
  - tracks/dlang/exercises/hamming/hamming_example.d
2108
2108
  - tracks/dlang/exercises/hello-world/hello_world.d
2109
2109
  - tracks/dlang/exercises/hello-world/hello_world_example.d
2110
+ - tracks/dlang/exercises/leap/leap.d
2111
+ - tracks/dlang/exercises/leap/leap_example.d
2110
2112
  - tracks/dlang/exercises/nucleotide-count/nucleotide_count.d
2111
2113
  - tracks/dlang/exercises/nucleotide-count/nucleotide_count_example.d
2112
2114
  - tracks/dlang/exercises/pangram/pangram.d
2113
2115
  - tracks/dlang/exercises/pangram/pangram_example.d
2114
2116
  - tracks/dlang/exercises/raindrops/raindrops.d
2115
2117
  - tracks/dlang/exercises/raindrops/raindrops_example.d
2118
+ - tracks/dlang/exercises/react/react.d
2119
+ - tracks/dlang/exercises/react/react_example.d
2116
2120
  - tracks/dlang/exercises/rna-transcription/rna_transcription.d
2117
2121
  - tracks/dlang/exercises/rna-transcription/rna_transcription_example.d
2118
2122
  - tracks/dlang/exercises/robot-name/robot_name.d
@@ -3130,6 +3134,8 @@ files:
3130
3134
  - tracks/factor/exercises/hello-world/hello-world.factor
3131
3135
  - tracks/factor/exercises/leap/leap-example.factor
3132
3136
  - tracks/factor/exercises/leap/leap-tests.factor
3137
+ - tracks/factor/exercises/two-fer/two-fer-example.factor
3138
+ - tracks/factor/exercises/two-fer/two-fer-tests.factor
3133
3139
  - tracks/factor/img/icon.png
3134
3140
  - tracks/fortran/.git
3135
3141
  - tracks/fortran/.github/PULL_REQUEST_TEMPLATE.md
@@ -3148,6 +3154,8 @@ files:
3148
3154
  - tracks/fortran/exercises/TRACK_HINTS.md
3149
3155
  - tracks/fortran/exercises/bob/bob.fun
3150
3156
  - tracks/fortran/exercises/bob/example.f90
3157
+ - tracks/fortran/exercises/hamming/example.f90
3158
+ - tracks/fortran/exercises/hamming/hamming.fun
3151
3159
  - tracks/fortran/exercises/hello_world/example.f90
3152
3160
  - tracks/fortran/exercises/hello_world/hello_world.fun
3153
3161
  - tracks/fortran/img/.keep
@@ -3599,6 +3607,8 @@ files:
3599
3607
  - tracks/go/exercises/phone-number/phone_number_test.go
3600
3608
  - tracks/go/exercises/pig-latin/example.go
3601
3609
  - tracks/go/exercises/pig-latin/pig_latin_test.go
3610
+ - tracks/go/exercises/poker/.meta/gen.go
3611
+ - tracks/go/exercises/poker/cases_test.go
3602
3612
  - tracks/go/exercises/poker/example.go
3603
3613
  - tracks/go/exercises/poker/poker_test.go
3604
3614
  - tracks/go/exercises/pov/example.go
@@ -3659,6 +3669,8 @@ files:
3659
3669
  - tracks/go/exercises/simple-cipher/simple_cipher_test.go
3660
3670
  - tracks/go/exercises/strain/example.go
3661
3671
  - tracks/go/exercises/strain/strain_test.go
3672
+ - tracks/go/exercises/sum-of-multiples/.meta/gen.go
3673
+ - tracks/go/exercises/sum-of-multiples/cases_test.go
3662
3674
  - tracks/go/exercises/sum-of-multiples/example.go
3663
3675
  - tracks/go/exercises/sum-of-multiples/sum_of_multiples_test.go
3664
3676
  - tracks/go/exercises/tournament/example.go
@@ -3732,7 +3744,7 @@ files:
3732
3744
  - tracks/groovy/exercises/rna-transcription/ComplementSpec.groovy
3733
3745
  - tracks/groovy/exercises/rna-transcription/Example.groovy
3734
3746
  - tracks/groovy/exercises/robot-name/Example.groovy
3735
- - tracks/groovy/exercises/robot-name/RobotTest.groovy
3747
+ - tracks/groovy/exercises/robot-name/RobotSpec.groovy
3736
3748
  - tracks/groovy/exercises/roman-numerals/Example.groovy
3737
3749
  - tracks/groovy/exercises/roman-numerals/RomanTest.groovy
3738
3750
  - tracks/groovy/exercises/word-count/Example.groovy
@@ -5057,6 +5069,14 @@ files:
5057
5069
  - tracks/kotlin/exercises/clock/src/test/kotlin/ClockAddTest.kt
5058
5070
  - tracks/kotlin/exercises/clock/src/test/kotlin/ClockCreationTest.kt
5059
5071
  - tracks/kotlin/exercises/clock/src/test/kotlin/ClockEqualTest.kt
5072
+ - tracks/kotlin/exercises/collatz-conjecture/build.gradle
5073
+ - tracks/kotlin/exercises/collatz-conjecture/src/example/kotlin/CollatzCalculator.kt
5074
+ - tracks/kotlin/exercises/collatz-conjecture/src/main/kotlin/.keep
5075
+ - tracks/kotlin/exercises/collatz-conjecture/src/test/kotlin/CollatzCalculatorTest.kt
5076
+ - tracks/kotlin/exercises/diamond/build.gradle
5077
+ - tracks/kotlin/exercises/diamond/src/example/kotlin/DiamondPrinter.kt
5078
+ - tracks/kotlin/exercises/diamond/src/main/kotlin/DiamondPrinter.kt
5079
+ - tracks/kotlin/exercises/diamond/src/test/kotlin/DiamondPrinterTest.kt
5060
5080
  - tracks/kotlin/exercises/difference-of-squares/build.gradle
5061
5081
  - tracks/kotlin/exercises/difference-of-squares/src/example/kotlin/Squares.kt
5062
5082
  - tracks/kotlin/exercises/difference-of-squares/src/main/kotlin/.keep
@@ -5944,6 +5964,7 @@ files:
5944
5964
  - tracks/ocaml/.gitignore
5945
5965
  - tracks/ocaml/.travis-ci.sh
5946
5966
  - tracks/ocaml/.travis.yml
5967
+ - tracks/ocaml/.vscode/launch.json
5947
5968
  - tracks/ocaml/LICENSE
5948
5969
  - tracks/ocaml/Makefile
5949
5970
  - tracks/ocaml/README.md
@@ -6180,42 +6201,46 @@ files:
6180
6201
  - tracks/ocaml/tools/test-generator/src/controller.ml
6181
6202
  - tracks/ocaml/tools/test-generator/src/debug.ml
6182
6203
  - tracks/ocaml/tools/test-generator/src/files.ml
6204
+ - tracks/ocaml/tools/test-generator/src/languages.ml
6183
6205
  - tracks/ocaml/tools/test-generator/src/model.ml
6206
+ - tracks/ocaml/tools/test-generator/src/ocaml_special_cases.ml
6184
6207
  - tracks/ocaml/tools/test-generator/src/parser.ml
6208
+ - tracks/ocaml/tools/test-generator/src/purescript_special_cases.ml
6185
6209
  - tracks/ocaml/tools/test-generator/src/special_cases.ml
6186
6210
  - tracks/ocaml/tools/test-generator/src/template.ml
6187
6211
  - tracks/ocaml/tools/test-generator/src/test_gen.ml
6188
6212
  - tracks/ocaml/tools/test-generator/src/utils.ml
6189
- - tracks/ocaml/tools/test-generator/templates/acronym/template.ml
6190
- - tracks/ocaml/tools/test-generator/templates/all-your-base/template.ml
6191
- - tracks/ocaml/tools/test-generator/templates/anagram/template.ml
6192
- - tracks/ocaml/tools/test-generator/templates/atbash-cipher/template.ml
6193
- - tracks/ocaml/tools/test-generator/templates/beer-song/template.ml
6194
- - tracks/ocaml/tools/test-generator/templates/binary-search/template.ml
6195
- - tracks/ocaml/tools/test-generator/templates/bob/template.ml
6196
- - tracks/ocaml/tools/test-generator/templates/bowling/template.ml
6197
- - tracks/ocaml/tools/test-generator/templates/bracket-push/template.ml
6198
- - tracks/ocaml/tools/test-generator/templates/change/template.ml
6199
- - tracks/ocaml/tools/test-generator/templates/connect/template.ml
6200
- - tracks/ocaml/tools/test-generator/templates/difference-of-squares/template.ml
6201
- - tracks/ocaml/tools/test-generator/templates/dominoes/template.ml
6202
- - tracks/ocaml/tools/test-generator/templates/etl/template.ml
6203
- - tracks/ocaml/tools/test-generator/templates/forth/template.ml
6204
- - tracks/ocaml/tools/test-generator/templates/hamming/template.ml
6205
- - tracks/ocaml/tools/test-generator/templates/hello-world/template.ml
6206
- - tracks/ocaml/tools/test-generator/templates/leap/template.ml
6207
- - tracks/ocaml/tools/test-generator/templates/luhn/template.ml
6208
- - tracks/ocaml/tools/test-generator/templates/minesweeper/template.ml
6209
- - tracks/ocaml/tools/test-generator/templates/pangram/template.ml
6210
- - tracks/ocaml/tools/test-generator/templates/phone-number/template.ml
6211
- - tracks/ocaml/tools/test-generator/templates/prime-factors/template.ml
6212
- - tracks/ocaml/tools/test-generator/templates/raindrops/template.ml
6213
- - tracks/ocaml/tools/test-generator/templates/roman-numerals/template.ml
6214
- - tracks/ocaml/tools/test-generator/templates/run-length-encoding/template.ml
6215
- - tracks/ocaml/tools/test-generator/templates/say/template.ml
6216
- - tracks/ocaml/tools/test-generator/templates/space-age/template.ml
6217
- - tracks/ocaml/tools/test-generator/templates/triangle/template.ml
6218
- - tracks/ocaml/tools/test-generator/templates/word-count/template.ml
6213
+ - tracks/ocaml/tools/test-generator/templates/ocaml/acronym/template.ml
6214
+ - tracks/ocaml/tools/test-generator/templates/ocaml/all-your-base/template.ml
6215
+ - tracks/ocaml/tools/test-generator/templates/ocaml/anagram/template.ml
6216
+ - tracks/ocaml/tools/test-generator/templates/ocaml/atbash-cipher/template.ml
6217
+ - tracks/ocaml/tools/test-generator/templates/ocaml/beer-song/template.ml
6218
+ - tracks/ocaml/tools/test-generator/templates/ocaml/binary-search/template.ml
6219
+ - tracks/ocaml/tools/test-generator/templates/ocaml/bob/template.ml
6220
+ - tracks/ocaml/tools/test-generator/templates/ocaml/bowling/template.ml
6221
+ - tracks/ocaml/tools/test-generator/templates/ocaml/bracket-push/template.ml
6222
+ - tracks/ocaml/tools/test-generator/templates/ocaml/change/template.ml
6223
+ - tracks/ocaml/tools/test-generator/templates/ocaml/connect/template.ml
6224
+ - tracks/ocaml/tools/test-generator/templates/ocaml/difference-of-squares/template.ml
6225
+ - tracks/ocaml/tools/test-generator/templates/ocaml/dominoes/template.ml
6226
+ - tracks/ocaml/tools/test-generator/templates/ocaml/etl/template.ml
6227
+ - tracks/ocaml/tools/test-generator/templates/ocaml/forth/template.ml
6228
+ - tracks/ocaml/tools/test-generator/templates/ocaml/hamming/template.ml
6229
+ - tracks/ocaml/tools/test-generator/templates/ocaml/hello-world/template.ml
6230
+ - tracks/ocaml/tools/test-generator/templates/ocaml/leap/template.ml
6231
+ - tracks/ocaml/tools/test-generator/templates/ocaml/luhn/template.ml
6232
+ - tracks/ocaml/tools/test-generator/templates/ocaml/minesweeper/template.ml
6233
+ - tracks/ocaml/tools/test-generator/templates/ocaml/pangram/template.ml
6234
+ - tracks/ocaml/tools/test-generator/templates/ocaml/phone-number/template.ml
6235
+ - tracks/ocaml/tools/test-generator/templates/ocaml/prime-factors/template.ml
6236
+ - tracks/ocaml/tools/test-generator/templates/ocaml/raindrops/template.ml
6237
+ - tracks/ocaml/tools/test-generator/templates/ocaml/roman-numerals/template.ml
6238
+ - tracks/ocaml/tools/test-generator/templates/ocaml/run-length-encoding/template.ml
6239
+ - tracks/ocaml/tools/test-generator/templates/ocaml/say/template.ml
6240
+ - tracks/ocaml/tools/test-generator/templates/ocaml/space-age/template.ml
6241
+ - tracks/ocaml/tools/test-generator/templates/ocaml/triangle/template.ml
6242
+ - tracks/ocaml/tools/test-generator/templates/ocaml/word-count/template.ml
6243
+ - tracks/ocaml/tools/test-generator/templates/purescript/hamming/Main.purs
6219
6244
  - tracks/ocaml/tools/test-generator/test/all_tests.ml
6220
6245
  - tracks/ocaml/tools/test-generator/test/beer-song.json
6221
6246
  - tracks/ocaml/tools/test-generator/test/clock.json
@@ -6224,10 +6249,10 @@ files:
6224
6249
  - tracks/ocaml/tools/test-generator/test/hello_world.json
6225
6250
  - tracks/ocaml/tools/test-generator/test/leap.json
6226
6251
  - tracks/ocaml/tools/test-generator/test/model_test.ml
6252
+ - tracks/ocaml/tools/test-generator/test/ocaml_special_cases_test.ml
6227
6253
  - tracks/ocaml/tools/test-generator/test/parser_test.ml
6228
6254
  - tracks/ocaml/tools/test-generator/test/sample-suite-template.txt
6229
6255
  - tracks/ocaml/tools/test-generator/test/sample_template.txt
6230
- - tracks/ocaml/tools/test-generator/test/special_cases_test.ml
6231
6256
  - tracks/ocaml/tools/test-generator/test/template_test.ml
6232
6257
  - tracks/ocaml/tools/test-generator/test/utils_test.ml
6233
6258
  - tracks/ocaml/tools/test-generator/test/with-methods-key.json