trackler 2.2.1.100 → 2.2.1.101

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 (204) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/kindergarten-garden/canonical-data.json +37 -19
  4. data/problem-specifications/exercises/ocr-numbers/canonical-data.json +144 -110
  5. data/problem-specifications/exercises/palindrome-products/canonical-data.json +49 -25
  6. data/problem-specifications/exercises/poker/canonical-data.json +171 -115
  7. data/problem-specifications/exercises/prime-factors/canonical-data.json +22 -8
  8. data/problem-specifications/exercises/protein-translation/canonical-data.json +70 -24
  9. data/problem-specifications/exercises/proverb/canonical-data.json +24 -12
  10. data/problem-specifications/exercises/queen-attack/canonical-data.json +115 -91
  11. data/problem-specifications/exercises/rail-fence-cipher/canonical-data.json +25 -13
  12. data/problem-specifications/exercises/raindrops/canonical-data.json +55 -19
  13. data/problem-specifications/exercises/rational-numbers/canonical-data.json +374 -0
  14. data/problem-specifications/exercises/rational-numbers/description.md +27 -0
  15. data/problem-specifications/exercises/rational-numbers/metadata.yml +4 -0
  16. data/problem-specifications/exercises/rectangles/canonical-data.json +93 -67
  17. data/problem-specifications/exercises/reverse-string/canonical-data.json +16 -6
  18. data/problem-specifications/exercises/rna-transcription/metadata.yml +3 -3
  19. data/problem-specifications/exercises/roman-numerals/canonical-data.json +10 -2
  20. data/tracks/bash/config.json +11 -11
  21. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +7 -0
  22. data/tracks/clojure/exercises/armstrong-numbers/README.md +1 -1
  23. data/tracks/delphi/config.json +11 -0
  24. data/tracks/delphi/exercises/clock/uClockExample.pas +6 -1
  25. data/tracks/delphi/exercises/clock/uClockTest.pas +22 -19
  26. data/tracks/delphi/exercises/isbn-verifier/README.md +1 -1
  27. data/tracks/delphi/exercises/reverse-string/README.md +1 -1
  28. data/tracks/delphi/exercises/rna-transcription/README.md +1 -1
  29. data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsTest.pas +14 -0
  30. data/tracks/delphi/exercises/space-age/README.md +45 -0
  31. data/tracks/delphi/exercises/space-age/SpaceAge.dpr +60 -0
  32. data/tracks/delphi/exercises/space-age/uSpaceAgeExample.pas +120 -0
  33. data/tracks/delphi/exercises/space-age/uSpaceAgeTests.pas +135 -0
  34. data/tracks/delphi/exercises/two-fer/README.md +1 -1
  35. data/tracks/elixir/exercises/nth-prime/nth_prime.exs +0 -1
  36. data/tracks/fsharp/exercises/pov/PovTest.fs +66 -53
  37. data/tracks/fsharp/exercises/space-age/Example.fs +11 -11
  38. data/tracks/fsharp/exercises/space-age/SpaceAge.fs +1 -1
  39. data/tracks/fsharp/exercises/space-age/SpaceAgeTest.fs +21 -34
  40. data/tracks/fsharp/exercises/triangle/Example.fs +11 -16
  41. data/tracks/fsharp/exercises/triangle/Triangle.fs +4 -5
  42. data/tracks/fsharp/exercises/triangle/TriangleTest.fs +44 -31
  43. data/tracks/fsharp/generators/Generators.fs +121 -0
  44. data/tracks/go/config.json +12 -0
  45. data/tracks/go/exercises/clock/.meta/gen.go +37 -13
  46. data/tracks/go/exercises/clock/cases_test.go +10 -10
  47. data/tracks/go/exercises/clock/clock_test.go +16 -2
  48. data/tracks/go/exercises/clock/example.go +4 -0
  49. data/tracks/go/exercises/clock/example_clock_test.go +3 -3
  50. data/tracks/go/exercises/parallel-letter-frequency/.meta/hints.md +33 -0
  51. data/tracks/go/exercises/parallel-letter-frequency/README.md +35 -0
  52. data/tracks/go/exercises/raindrops/.meta/hints.md +7 -4
  53. data/tracks/go/exercises/raindrops/README.md +12 -0
  54. data/tracks/go/exercises/roman-numerals/.meta/gen.go +4 -2
  55. data/tracks/go/exercises/roman-numerals/cases_test.go +3 -2
  56. data/tracks/go/exercises/space-age/.meta/hints.md +10 -0
  57. data/tracks/go/exercises/space-age/README.md +14 -1
  58. data/tracks/go/exercises/twelve-days/README.md +2 -5
  59. data/tracks/go/exercises/two-bucket/.meta/gen.go +62 -0
  60. data/tracks/go/exercises/two-bucket/.meta/hints.md +16 -0
  61. data/tracks/go/exercises/two-bucket/README.md +72 -0
  62. data/tracks/go/exercises/two-bucket/cases_test.go +44 -0
  63. data/tracks/go/exercises/two-bucket/example.go +198 -0
  64. data/tracks/go/exercises/two-bucket/two_bucket_test.go +61 -0
  65. data/tracks/idris/.travis.yml +3 -2
  66. data/tracks/idris/bin/fetch-idris-testing.sh +11 -0
  67. data/tracks/idris/bin/solve_exercises.sh +2 -2
  68. data/tracks/idris/config.json +11 -0
  69. data/tracks/idris/config/exercise_readme.go.tmpl +0 -3
  70. data/tracks/idris/docs/INSTALLATION.md +22 -0
  71. data/tracks/idris/docs/TESTS.md +12 -4
  72. data/tracks/idris/exercises/accumulate/src/Accumulate.idr +5 -0
  73. data/tracks/idris/exercises/hamming/Hamming.ipkg +2 -0
  74. data/tracks/idris/exercises/hamming/src/{example.idr → Example.idr} +5 -1
  75. data/tracks/idris/exercises/hamming/src/Hamming.idr +13 -5
  76. data/tracks/idris/exercises/hamming/src/Test/Hamming.idr +31 -58
  77. data/tracks/idris/exercises/hello-world/HelloWorld.ipkg +2 -0
  78. data/tracks/idris/exercises/hello-world/src/Example.idr +9 -0
  79. data/tracks/idris/exercises/hello-world/src/HelloWorld.idr +6 -1
  80. data/tracks/idris/exercises/hello-world/src/Test/HelloWorld.idr +18 -18
  81. data/tracks/idris/exercises/leap/Leap.ipkg +2 -0
  82. data/tracks/idris/exercises/leap/src/{example.idr → Example.idr} +4 -0
  83. data/tracks/idris/exercises/leap/src/Leap.idr +5 -1
  84. data/tracks/idris/exercises/leap/src/Test/Leap.idr +21 -30
  85. data/tracks/idris/exercises/rna-transcription/Makefile +23 -0
  86. data/tracks/idris/exercises/rna-transcription/README.md +27 -0
  87. data/tracks/idris/exercises/rna-transcription/RnaTranscription.ipkg +5 -0
  88. data/tracks/idris/exercises/rna-transcription/src/RnaTranscription.idr +17 -0
  89. data/tracks/idris/exercises/rna-transcription/src/Test/RnaTranscription.idr +27 -0
  90. data/tracks/idris/exercises/rna-transcription/src/example.idr +35 -0
  91. data/tracks/java/exercises/etl/.meta/version +1 -0
  92. data/tracks/java/exercises/gigasecond/.meta/version +1 -0
  93. data/tracks/java/exercises/isbn-verifier/README.md +1 -1
  94. data/tracks/java/exercises/nucleotide-count/.meta/src/reference/java/NucleotideCounter.java +7 -1
  95. data/tracks/java/exercises/nucleotide-count/.meta/version +1 -0
  96. data/tracks/java/exercises/nucleotide-count/src/test/java/NucleotideCounterTest.java +19 -54
  97. data/tracks/java/exercises/proverb/.meta/version +1 -0
  98. data/tracks/java/exercises/reverse-string/README.md +1 -1
  99. data/tracks/java/exercises/rna-transcription/README.md +1 -1
  100. data/tracks/java/exercises/sum-of-multiples/.meta/version +1 -0
  101. data/tracks/java/exercises/sum-of-multiples/src/test/java/SumOfMultiplesTest.java +13 -1
  102. data/tracks/kotlin/config/exercise_readme.go.tmpl +0 -3
  103. data/tracks/kotlin/docs/TESTS.md +1 -1
  104. data/tracks/objective-c/config.json +11 -0
  105. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.h +7 -0
  106. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureExample.m +26 -0
  107. data/tracks/objective-c/exercises/collatz-conjecture/CollatzConjectureTest.m +39 -0
  108. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +31 -1
  109. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/OCLint.xcscheme +3 -1
  110. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/xcshareddata/xcschemes/xobjectivecTest.xcscheme +3 -1
  111. data/tracks/ocaml/exercises/forth/example.ml +9 -9
  112. data/tracks/ocaml/tools/test-generator/Makefile +3 -9
  113. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +18 -16
  114. data/tracks/perl6/exercises/acronym/.meta/exercise-data.yaml +1 -1
  115. data/tracks/perl6/exercises/acronym/acronym.t +4 -14
  116. data/tracks/perl6/exercises/all-your-base/all-your-base.t +0 -2
  117. data/tracks/perl6/exercises/allergies/allergies.t +0 -2
  118. data/tracks/perl6/exercises/anagram/.meta/exercise-data.yaml +1 -1
  119. data/tracks/perl6/exercises/anagram/anagram.t +2 -40
  120. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +0 -1
  121. data/tracks/perl6/exercises/bob/bob.t +0 -2
  122. data/tracks/perl6/exercises/clock/.meta/exercise-data.yaml +15 -11
  123. data/tracks/perl6/exercises/clock/.meta/solutions/Clock.pm6 +5 -1
  124. data/tracks/perl6/exercises/clock/Clock.pm6 +1 -1
  125. data/tracks/perl6/exercises/clock/clock.t +314 -217
  126. data/tracks/perl6/exercises/etl/etl.t +0 -2
  127. data/tracks/perl6/exercises/flatten-array/flatten-array.t +0 -2
  128. data/tracks/perl6/exercises/grains/grains.t +0 -2
  129. data/tracks/perl6/exercises/hamming/.meta/exercise-data.yaml +2 -2
  130. data/tracks/perl6/exercises/hamming/hamming.t +63 -35
  131. data/tracks/perl6/exercises/hello-world/hello-world.t +2 -3
  132. data/tracks/perl6/exercises/leap/.meta/exercise-data.yaml +1 -1
  133. data/tracks/perl6/exercises/leap/leap.t +14 -8
  134. data/tracks/perl6/exercises/luhn/luhn.t +0 -2
  135. data/tracks/perl6/exercises/nucleotide-count/.meta/exercise-data.yaml +2 -2
  136. data/tracks/perl6/exercises/nucleotide-count/nucleotide-count.t +18 -10
  137. data/tracks/perl6/exercises/pangram/.meta/exercise-data.yaml +1 -1
  138. data/tracks/perl6/exercises/pangram/pangram.t +32 -14
  139. data/tracks/perl6/exercises/phone-number/.meta/exercise-data.yaml +4 -4
  140. data/tracks/perl6/exercises/phone-number/.meta/solutions/Phone.pm6 +1 -1
  141. data/tracks/perl6/exercises/phone-number/Phone.pm6 +1 -1
  142. data/tracks/perl6/exercises/phone-number/phone-number.t +59 -21
  143. data/tracks/perl6/exercises/raindrops/raindrops.t +0 -2
  144. data/tracks/perl6/exercises/rna-transcription/.meta/exercise-data.yaml +1 -1
  145. data/tracks/perl6/exercises/rna-transcription/README.md +1 -1
  146. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +17 -9
  147. data/tracks/perl6/exercises/roman-numerals/.meta/exercise-data.yaml +3 -3
  148. data/tracks/perl6/exercises/roman-numerals/.meta/solutions/RomanNumerals.pm6 +1 -1
  149. data/tracks/perl6/exercises/roman-numerals/RomanNumerals.pm6 +1 -1
  150. data/tracks/perl6/exercises/roman-numerals/roman-numerals.t +66 -24
  151. data/tracks/perl6/exercises/scrabble-score/.meta/exercise-data.yaml +1 -1
  152. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +35 -15
  153. data/tracks/perl6/exercises/space-age/.meta/exercise-data.yaml +1 -1
  154. data/tracks/perl6/exercises/space-age/space-age.t +34 -20
  155. data/tracks/perl6/exercises/two-fer/.meta/exercise-data.yaml +2 -2
  156. data/tracks/perl6/exercises/two-fer/two-fer.t +15 -11
  157. data/tracks/perl6/exercises/word-count/.meta/exercise-data.yaml +1 -1
  158. data/tracks/perl6/exercises/word-count/word-count.t +46 -26
  159. data/tracks/perl6/exercises/wordy/.meta/exercise-data.yaml +2 -2
  160. data/tracks/perl6/exercises/wordy/wordy.t +51 -21
  161. data/tracks/perl6/lib/Exercism/Generator.pm6 +1 -1
  162. data/tracks/perl6/t/generated-tests.t +1 -1
  163. data/tracks/perl6/templates/test.mustache +0 -1
  164. data/tracks/python/config.json +12 -0
  165. data/tracks/python/exercises/forth/example.py +1 -1
  166. data/tracks/python/exercises/forth/forth_test.py +43 -38
  167. data/tracks/python/exercises/spiral-matrix/README.md +42 -0
  168. data/tracks/python/exercises/spiral-matrix/example.py +11 -0
  169. data/tracks/python/exercises/spiral-matrix/spiral_matrix.py +2 -0
  170. data/tracks/python/exercises/spiral-matrix/spiral_matrix_test.py +40 -0
  171. data/tracks/racket/config/exercise_readme.go.tmpl +24 -4
  172. data/tracks/racket/exercises/accumulate/README.md +3 -6
  173. data/tracks/racket/exercises/acronym/README.md +3 -4
  174. data/tracks/racket/exercises/allergies/README.md +3 -4
  175. data/tracks/racket/exercises/anagram/README.md +3 -3
  176. data/tracks/racket/exercises/bob/README.md +5 -3
  177. data/tracks/racket/exercises/collatz-conjecture/README.md +3 -3
  178. data/tracks/racket/exercises/difference-of-squares/README.md +3 -3
  179. data/tracks/racket/exercises/etl/README.md +6 -4
  180. data/tracks/racket/exercises/gigasecond/README.md +3 -3
  181. data/tracks/racket/exercises/grains/README.md +3 -4
  182. data/tracks/racket/exercises/grep/README.md +15 -15
  183. data/tracks/racket/exercises/hamming/README.md +3 -3
  184. data/tracks/racket/exercises/hello-world/README.md +1 -1
  185. data/tracks/racket/exercises/leap/README.md +4 -4
  186. data/tracks/racket/exercises/list-ops/README.md +3 -4
  187. data/tracks/racket/exercises/meetup/README.md +19 -15
  188. data/tracks/racket/exercises/nucleotide-count/README.md +11 -25
  189. data/tracks/racket/exercises/perfect-numbers/README.md +5 -5
  190. data/tracks/racket/exercises/phone-number/README.md +7 -6
  191. data/tracks/racket/exercises/raindrops/README.md +3 -3
  192. data/tracks/racket/exercises/rna-transcription/README.md +4 -4
  193. data/tracks/racket/exercises/roman-numerals/README.md +4 -4
  194. data/tracks/racket/exercises/say/README.md +3 -3
  195. data/tracks/racket/exercises/scrabble-score/README.md +6 -4
  196. data/tracks/racket/exercises/word-count/README.md +4 -5
  197. data/tracks/scheme/config/exercise_readme.go.tmpl +0 -3
  198. data/tracks/scheme/docs/INSTALLATION.md +23 -14
  199. metadata +40 -9
  200. data/tracks/idris/docs/EXERCISE_README_INSERT.md +0 -0
  201. data/tracks/idris/exercises/hello-world/src/example.idr +0 -5
  202. data/tracks/kotlin/config/exercise-readme-insert.md +0 -1
  203. data/tracks/racket/docs/EXERCISE_README_INSERT.md +0 -23
  204. data/tracks/scheme/docs/EXERCISE_README_INSERT.md +0 -0
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "0810"
3
+ LastUpgradeVersion = "0920"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
26
26
  buildConfiguration = "Debug"
27
27
  selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
28
  selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ language = ""
29
30
  shouldUseLaunchSchemeArgsEnv = "YES">
30
31
  <Testables>
31
32
  </Testables>
@@ -36,6 +37,7 @@
36
37
  buildConfiguration = "Debug"
37
38
  selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
38
39
  selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
40
+ language = ""
39
41
  launchStyle = "0"
40
42
  useCustomWorkingDirectory = "NO"
41
43
  ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "0810"
3
+ LastUpgradeVersion = "0920"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -10,6 +10,7 @@
10
10
  buildConfiguration = "Debug"
11
11
  selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
12
12
  selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
13
+ language = ""
13
14
  shouldUseLaunchSchemeArgsEnv = "YES">
14
15
  <Testables>
15
16
  <TestableReference
@@ -30,6 +31,7 @@
30
31
  buildConfiguration = "Debug"
31
32
  selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
32
33
  selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
34
+ language = ""
33
35
  launchStyle = "0"
34
36
  useCustomWorkingDirectory = "NO"
35
37
  ignoresPersistentStateOnLaunch = "NO"
@@ -20,14 +20,14 @@ let handle_binary_op f = function
20
20
 
21
21
  let std_vocabulary: vocabulary =
22
22
  String.Map.empty
23
- |> Map.add ~key:"+" ~data:(handle_binary_op (+))
24
- |> Map.add ~key:"-" ~data:(handle_binary_op (-))
25
- |> Map.add ~key:"*" ~data:(handle_binary_op ( * ))
26
- |> Map.add ~key:"/" ~data:(function | x :: y :: xs -> if x = 0 then None else Some ((y/x) :: xs) | _ -> None)
27
- |> Map.add ~key:"DUP" ~data:(function | x :: xs -> Some (x :: x :: xs) | _ -> None)
28
- |> Map.add ~key:"DROP" ~data:(function | _ :: xs -> Some xs | _ -> None)
29
- |> Map.add ~key:"SWAP" ~data:(function | x :: y :: xs -> Some (y :: x :: xs) | _ -> None)
30
- |> Map.add ~key:"OVER" ~data:(function | x :: y :: xs -> Some (y :: x :: y :: xs) | _ -> None)
23
+ |> Map.set ~key:"+" ~data:(handle_binary_op (+))
24
+ |> Map.set ~key:"-" ~data:(handle_binary_op (-))
25
+ |> Map.set ~key:"*" ~data:(handle_binary_op ( * ))
26
+ |> Map.set ~key:"/" ~data:(function | x :: y :: xs -> if x = 0 then None else Some ((y/x) :: xs) | _ -> None)
27
+ |> Map.set ~key:"DUP" ~data:(function | x :: xs -> Some (x :: x :: xs) | _ -> None)
28
+ |> Map.set ~key:"DROP" ~data:(function | _ :: xs -> Some xs | _ -> None)
29
+ |> Map.set ~key:"SWAP" ~data:(function | x :: y :: xs -> Some (y :: x :: xs) | _ -> None)
30
+ |> Map.set ~key:"OVER" ~data:(function | x :: y :: xs -> Some (y :: x :: y :: xs) | _ -> None)
31
31
 
32
32
  let (<|>) o1 o2 = match o1 with
33
33
  | None -> o2
@@ -71,7 +71,7 @@ let rec handle_def vocabulary stack words: (vocabulary * stack) option =
71
71
  then None
72
72
  else
73
73
  let def = List.drop words 1 in
74
- let vocabulary = Map.add vocabulary ~key:new_vocab ~data:(fun stack -> Option.map ~f:(snd >|> List.rev) @@ evaluate_stack stack vocabulary def) in
74
+ let vocabulary = Map.set vocabulary ~key:new_vocab ~data:(fun stack -> Option.map ~f:(snd >|> List.rev) @@ evaluate_stack stack vocabulary def) in
75
75
  Some (vocabulary, stack)
76
76
 
77
77
  and evaluate_sentence_or_fail (vocabulary: vocabulary) (stack: stack) (sentence: sentence): (vocabulary * stack) option = match sentence with
@@ -2,19 +2,13 @@ test: test_gen.native
2
2
  @./all_tests.native
3
3
 
4
4
  canonical_data_checker.native: all_tests.native src/*.ml test/*.ml
5
- @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces canonical_data_checker.native
6
-
7
- test_gen.byte: all_tests.native src/*.ml test/*.ml
8
- @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces test_gen.byte
5
+ @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_let -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces canonical_data_checker.native
9
6
 
10
7
  test_gen.native: all_tests.native src/*.ml test/*.ml
11
- @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces test_gen.native
8
+ @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_let -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces test_gen.native
12
9
 
13
10
  all_tests.native: src/*.ml test/*.ml
14
- @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg oUnit -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,test all_tests.native
15
-
16
- debug.byte: debug.byte src/*.ml
17
- @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces debug.byte
11
+ @ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg oUnit -pkg ppx_let -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,test all_tests.native
18
12
 
19
13
  clean:
20
14
  rm -rf _build
@@ -16,24 +16,26 @@ let home_dir = Option.value_exn (Sys.getenv "HOME")
16
16
  let default_generated name = Option.value ~default:(home_dir ^ "/.x" ^ name ^ "-generated")
17
17
 
18
18
  let command =
19
+ let open Command.Let_syntax in
19
20
  Command.basic
20
21
  ~summary:"Generates test code from canonical data."
21
- Command.Spec.(
22
- empty
23
- +> flag "-l" (optional string) ~doc:"language to generate tests for"
24
- +> flag "-t" (optional_with_default "./templates" is_directory) ~doc:"string Directory containing templates."
25
- +> flag "-c" (optional_with_default "../../../problem-specifications/exercises" is_directory) ~doc:"string Directory containing canonical data."
26
- +> flag "-o" (optional string) ~doc:"string Directory to output generated tests."
27
- +> flag "-g" (optional string) ~doc:"string Directory to backup generated tests."
28
- +> flag "-f" (optional string) ~doc:"string Filter out files not matching this string."
29
- )
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)
22
+ ~readme: (fun () -> "Generates test code from canonical data.")
23
+ [%map_open
24
+ let language = flag "l" (optional string) ~doc:"language to generate tests for"
25
+ and templates_folder = flag "t" (optional_with_default "./templates" is_directory) ~doc:"string Directory containing templates."
26
+ and canonical_data_folder = flag "c" (optional_with_default "./templates" is_directory) ~doc:"string Directory containing templates."
27
+ and output_folder = flag "-o" (optional string) ~doc:"string Directory to output generated tests."
28
+ and generated_folder = flag "-g" (optional string) ~doc:"string Directory to backup generated tests."
29
+ and filter = flag "-f" (optional string) ~doc:"string Filter out files not matching this string."
30
+ in
31
+ fun () ->
32
+ let language = Option.value language ~default:"ocaml" in
33
+ let lc = default_language_config language in
34
+ let generated_folder = default_generated language generated_folder in
35
+ let templates_folder = templates_folder ^ "/" ^ language in
36
+ let output_folder = Option.value output_folder ~default:(lc.default_base_folder ^ "/exercises") in
37
+ Controller.run lc templates_folder canonical_data_folder output_folder generated_folder filter
38
+ ]
37
39
 
38
40
  let () =
39
41
  Command.run ~version:"0.1" command
@@ -1,6 +1,6 @@
1
1
  exercise: Acronym
2
2
  version: 2
3
- plan: 6
3
+ plan: 5
4
4
  tests: |-
5
5
 
6
6
  for $c-data<cases>»<cases>».Array.flat {
@@ -4,7 +4,7 @@ use Test;
4
4
  use JSON::Fast;
5
5
  use lib $?FILE.IO.dirname;
6
6
  use Acronym;
7
- plan 6;
7
+ plan 5;
8
8
 
9
9
  my Version:D $version = v2;
10
10
 
@@ -22,10 +22,9 @@ for $c-data<cases>»<cases>».Array.flat {
22
22
 
23
23
  =head2 Canonical Data
24
24
  =begin code
25
-
26
25
  {
27
26
  "exercise": "acronym",
28
- "version": "1.2.0",
27
+ "version": "1.3.0",
29
28
  "cases": [
30
29
  {
31
30
  "description": "Abbreviate a phrase",
@@ -55,15 +54,7 @@ for $c-data<cases>»<cases>».Array.flat {
55
54
  "expected": "FIFO"
56
55
  },
57
56
  {
58
- "description": "all caps words",
59
- "property": "abbreviate",
60
- "input": {
61
- "phrase": "PHP: Hypertext Preprocessor"
62
- },
63
- "expected": "PHP"
64
- },
65
- {
66
- "description": "non-acronym all caps word",
57
+ "description": "all caps word",
67
58
  "property": "abbreviate",
68
59
  "input": {
69
60
  "phrase": "GNU Image Manipulation Program"
@@ -71,7 +62,7 @@ for $c-data<cases>»<cases>».Array.flat {
71
62
  "expected": "GIMP"
72
63
  },
73
64
  {
74
- "description": "hyphenated",
65
+ "description": "punctuation without whitespace",
75
66
  "property": "abbreviate",
76
67
  "input": {
77
68
  "phrase": "Complementary metal-oxide semiconductor"
@@ -82,5 +73,4 @@ for $c-data<cases>»<cases>».Array.flat {
82
73
  }
83
74
  ]
84
75
  }
85
-
86
76
  =end code
@@ -35,7 +35,6 @@ for $c-data<cases>.values -> $case {
35
35
 
36
36
  =head2 Canonical Data
37
37
  =begin code
38
-
39
38
  {
40
39
  "exercise": "all-your-base",
41
40
  "version": "2.1.0",
@@ -263,5 +262,4 @@ for $c-data<cases>.values -> $case {
263
262
  }
264
263
  ]
265
264
  }
266
-
267
265
  =end code
@@ -43,7 +43,6 @@ for $c-data<cases>.values -> %case-set {
43
43
 
44
44
  =head2 Canonical Data
45
45
  =begin code
46
-
47
46
  {
48
47
  "exercise": "allergies",
49
48
  "version": "1.1.0",
@@ -217,5 +216,4 @@ for $c-data<cases>.values -> %case-set {
217
216
  }
218
217
  ]
219
218
  }
220
-
221
219
  =end code
@@ -1,6 +1,6 @@
1
1
  exercise: Anagram
2
2
  version: 3
3
- plan: 16
3
+ plan: 12
4
4
  tests: |-
5
5
  cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.Set, .<description> for $c-data<cases>.values;
6
6
 
@@ -4,7 +4,7 @@ use Test;
4
4
  use JSON::Fast;
5
5
  use lib $?FILE.IO.dirname;
6
6
  use Anagram;
7
- plan 16;
7
+ plan 12;
8
8
 
9
9
  my Version:D $version = v3;
10
10
 
@@ -19,10 +19,9 @@ cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.S
19
19
 
20
20
  =head2 Canonical Data
21
21
  =begin code
22
-
23
22
  {
24
23
  "exercise": "anagram",
25
- "version": "1.1.0",
24
+ "version": "1.2.0",
26
25
  "comments": [
27
26
  "The string argument cases possible matches are passed in as",
28
27
  "individual arguments rather than arrays. Languages can include",
@@ -39,24 +38,6 @@ cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.S
39
38
  },
40
39
  "expected": []
41
40
  },
42
- {
43
- "description": "detects simple anagram",
44
- "property": "anagrams",
45
- "input": {
46
- "subject": "ant",
47
- "candidates": ["tan", "stand", "at"]
48
- },
49
- "expected": ["tan"]
50
- },
51
- {
52
- "description": "does not detect false positives",
53
- "property": "anagrams",
54
- "input": {
55
- "subject": "galea",
56
- "candidates": ["eagle"]
57
- },
58
- "expected": []
59
- },
60
41
  {
61
42
  "description": "detects two anagrams",
62
43
  "property": "anagrams",
@@ -100,15 +81,6 @@ cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.S
100
81
  },
101
82
  "expected": ["gallery", "regally", "largely"]
102
83
  },
103
- {
104
- "description": "does not detect identical words",
105
- "property": "anagrams",
106
- "input": {
107
- "subject": "corn",
108
- "candidates": ["corn", "dark", "Corn", "rank", "CORN", "cron", "park"]
109
- },
110
- "expected": ["cron"]
111
- },
112
84
  {
113
85
  "description": "does not detect non-anagrams with identical checksum",
114
86
  "property": "anagrams",
@@ -145,15 +117,6 @@ cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.S
145
117
  },
146
118
  "expected": ["Carthorse"]
147
119
  },
148
- {
149
- "description": "does not detect a word as its own anagram",
150
- "property": "anagrams",
151
- "input": {
152
- "subject": "banana",
153
- "candidates": ["Banana"]
154
- },
155
- "expected": []
156
- },
157
120
  {
158
121
  "description": "does not detect a anagram if the original word is repeated",
159
122
  "property": "anagrams",
@@ -183,5 +146,4 @@ cmp-ok match-anagrams( |%(.<input><subject candidates>:p) ), '~~', .<expected>.S
183
146
  }
184
147
  ]
185
148
  }
186
-
187
149
  =end code
@@ -19,7 +19,6 @@ is .<input><phrase>.&::(.<property>), |.<expected description> for $c-data<cases
19
19
 
20
20
  =head2 Canonical Data
21
21
  =begin code
22
-
23
22
  {
24
23
  "exercise": "atbash-cipher",
25
24
  "version": "1.1.0",
@@ -28,7 +28,6 @@ is Bob.?hey(.<input><heyBob>), |.<expected description> for @($c-data<cases>);
28
28
 
29
29
  =head2 Canonical Data
30
30
  =begin code
31
-
32
31
  {
33
32
  "exercise": "bob",
34
33
  "version": "1.2.0",
@@ -235,5 +234,4 @@ is Bob.?hey(.<input><heyBob>), |.<expected description> for @($c-data<cases>);
235
234
  }
236
235
  ]
237
236
  }
238
-
239
237
  =end code
@@ -1,31 +1,31 @@
1
1
  exercise: Clock
2
- version: 2
3
- methods: time add-minutes
4
- plan: 52
2
+ version: 3
3
+ methods: time add-minutes subtract-minutes
4
+ plan: 53
5
5
  tests: |-
6
- for $c-data<cases>»<cases>».Array.flat -> %case {
6
+ for $c-data<cases>»<cases>»<>.flat -> %case {
7
7
  given %case<property> {
8
8
  when 'create' {
9
- is Clock.?new( |%(.<hour minute>:p) ).?time, |.<expected description> given %case;
9
+ is Clock.?new( |%(.<input><hour minute>:p) ).?time, |.<expected description> given %case;
10
10
  }
11
- when 'add' {
11
+ when 'add'|'subtract' {
12
12
  given %case {
13
- my $clock = Clock.?new: |%(.<hour minute>:p);
14
- $clock.?add-minutes: .<add>;
13
+ my $clock = Clock.?new: |%(.<input><hour minute>:p);
14
+ $clock.?add-minutes: .<input><value> if .<property> eq 'add';
15
+ $clock.?subtract-minutes: .<input><value> if .<property> eq 'subtract';
15
16
  is $clock.?time, |.<expected description>;
16
17
  }
17
18
  }
18
19
  when 'equal' {
19
20
  is-deeply ([eq] gather {
20
- take Clock.?new( |%(.<hour minute>:p) ).?time for %case<clock1 clock2>;
21
+ take Clock.?new( |%(.<hour minute>:p) ).?time for %case<input><clock1 clock2>;
21
22
  }), |%case<expected description>;
22
23
  }
23
- when %*ENV<EXERCISM>.so { bail-out "no case for property '%case<property>'" }
24
24
  }
25
25
  }
26
26
 
27
- todo 'optional test' unless %*ENV<EXERCISM>;
28
27
  is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes method can be chained';
28
+ is Clock.?new(:0hour,:0minute).?subtract-minutes(65).?time, '22:55', 'subtract-minutes method can be chained';
29
29
 
30
30
  unit: class
31
31
  example: |-
@@ -39,6 +39,10 @@ example: |-
39
39
  method add-minutes (Int:D $min) {
40
40
  $!minute += $min and return self;
41
41
  }
42
+
43
+ method subtract-minutes (Int:D $min) {
44
+ self.add-minutes(-$min);
45
+ }
42
46
  stub: |-
43
47
  has $.hour;
44
48
  has $.minute;
@@ -1,4 +1,4 @@
1
- unit class Clock:ver<2>;
1
+ unit class Clock:ver<3>;
2
2
 
3
3
  has Int:D $.hour = 0;
4
4
  has Int:D $.minute = 0;
@@ -10,3 +10,7 @@ method time {
10
10
  method add-minutes (Int:D $min) {
11
11
  $!minute += $min and return self;
12
12
  }
13
+
14
+ method subtract-minutes (Int:D $min) {
15
+ self.add-minutes(-$min);
16
+ }
@@ -1,4 +1,4 @@
1
- unit class Clock:ver<2>;
1
+ unit class Clock:ver<3>;
2
2
 
3
3
  has $.hour;
4
4
  has $.minute;
@@ -4,9 +4,9 @@ use Test;
4
4
  use JSON::Fast;
5
5
  use lib $?FILE.IO.dirname;
6
6
  use Clock;
7
- plan 52;
7
+ plan 53;
8
8
 
9
- my Version:D $version = v2;
9
+ my Version:D $version = v3;
10
10
 
11
11
  if Clock.^ver !~~ $version {
12
12
  warn "\nExercise version mismatch. Further tests may fail!"
@@ -15,46 +15,44 @@ if Clock.^ver !~~ $version {
15
15
  }
16
16
 
17
17
  subtest 'Class methods', {
18
- ok Clock.can($_), $_ for <time add-minutes>;
18
+ ok Clock.can($_), $_ for <time add-minutes subtract-minutes>;
19
19
  }
20
20
 
21
21
  my $c-data = from-json $=pod.pop.contents;
22
- for $c-data<cases>»<cases>».Array.flat -> %case {
22
+ for $c-data<cases>»<cases>»<>.flat -> %case {
23
23
  given %case<property> {
24
24
  when 'create' {
25
- is Clock.?new( |%(.<hour minute>:p) ).?time, |.<expected description> given %case;
25
+ is Clock.?new( |%(.<input><hour minute>:p) ).?time, |.<expected description> given %case;
26
26
  }
27
- when 'add' {
27
+ when 'add'|'subtract' {
28
28
  given %case {
29
- my $clock = Clock.?new: |%(.<hour minute>:p);
30
- $clock.?add-minutes: .<add>;
29
+ my $clock = Clock.?new: |%(.<input><hour minute>:p);
30
+ $clock.?add-minutes: .<input><value> if .<property> eq 'add';
31
+ $clock.?subtract-minutes: .<input><value> if .<property> eq 'subtract';
31
32
  is $clock.?time, |.<expected description>;
32
33
  }
33
34
  }
34
35
  when 'equal' {
35
36
  is-deeply ([eq] gather {
36
- take Clock.?new( |%(.<hour minute>:p) ).?time for %case<clock1 clock2>;
37
+ take Clock.?new( |%(.<hour minute>:p) ).?time for %case<input><clock1 clock2>;
37
38
  }), |%case<expected description>;
38
39
  }
39
- when %*ENV<EXERCISM>.so { bail-out "no case for property '%case<property>'" }
40
40
  }
41
41
  }
42
42
 
43
- todo 'optional test' unless %*ENV<EXERCISM>;
44
43
  is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes method can be chained';
44
+ is Clock.?new(:0hour,:0minute).?subtract-minutes(65).?time, '22:55', 'subtract-minutes method can be chained';
45
45
 
46
46
  =head2 Canonical Data
47
47
  =begin code
48
-
49
48
  {
50
49
  "exercise": "clock",
51
- "version": "1.0.1",
50
+ "version": "2.2.1",
52
51
  "comments": [
53
52
  "Most languages require constructing a clock with initial values,",
54
- "adding a positive or negative number of minutes, and testing equality",
55
- "in some language-native way. Some languages require separate add and",
56
- "subtract functions. Negative and out of range values are generally",
57
- "expected to wrap around rather than represent errors."
53
+ "adding or subtracting some number of minutes, and testing equality",
54
+ "in some language-native way. Negative and out of range values are",
55
+ "generally expected to wrap around rather than represent errors."
58
56
  ],
59
57
  "cases": [
60
58
  {
@@ -63,134 +61,172 @@ is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes met
63
61
  {
64
62
  "description": "on the hour",
65
63
  "property": "create",
66
- "hour": 8,
67
- "minute": 0,
64
+ "input": {
65
+ "hour": 8,
66
+ "minute": 0
67
+ },
68
68
  "expected": "08:00"
69
69
  },
70
70
  {
71
71
  "description": "past the hour",
72
72
  "property": "create",
73
- "hour": 11,
74
- "minute": 9,
73
+ "input": {
74
+ "hour": 11,
75
+ "minute": 9
76
+ },
75
77
  "expected": "11:09"
76
78
  },
77
79
  {
78
80
  "description": "midnight is zero hours",
79
81
  "property": "create",
80
- "hour": 24,
81
- "minute": 0,
82
+ "input": {
83
+ "hour": 24,
84
+ "minute": 0
85
+ },
82
86
  "expected": "00:00"
83
87
  },
84
88
  {
85
89
  "description": "hour rolls over",
86
90
  "property": "create",
87
- "hour": 25,
88
- "minute": 0,
91
+ "input": {
92
+ "hour": 25,
93
+ "minute": 0
94
+ },
89
95
  "expected": "01:00"
90
96
  },
91
97
  {
92
98
  "description": "hour rolls over continuously",
93
99
  "property": "create",
94
- "hour": 100,
95
- "minute": 0,
100
+ "input": {
101
+ "hour": 100,
102
+ "minute": 0
103
+ },
96
104
  "expected": "04:00"
97
105
  },
98
106
  {
99
107
  "description": "sixty minutes is next hour",
100
108
  "property": "create",
101
- "hour": 1,
102
- "minute": 60,
109
+ "input": {
110
+ "hour": 1,
111
+ "minute": 60
112
+ },
103
113
  "expected": "02:00"
104
114
  },
105
115
  {
106
116
  "description": "minutes roll over",
107
117
  "property": "create",
108
- "hour": 0,
109
- "minute": 160,
118
+ "input": {
119
+ "hour": 0,
120
+ "minute": 160
121
+ },
110
122
  "expected": "02:40"
111
123
  },
112
124
  {
113
125
  "description": "minutes roll over continuously",
114
126
  "property": "create",
115
- "hour": 0,
116
- "minute": 1723,
127
+ "input": {
128
+ "hour": 0,
129
+ "minute": 1723
130
+ },
117
131
  "expected": "04:43"
118
132
  },
119
133
  {
120
134
  "description": "hour and minutes roll over",
121
135
  "property": "create",
122
- "hour": 25,
123
- "minute": 160,
136
+ "input": {
137
+ "hour": 25,
138
+ "minute": 160
139
+ },
124
140
  "expected": "03:40"
125
141
  },
126
142
  {
127
143
  "description": "hour and minutes roll over continuously",
128
144
  "property": "create",
129
- "hour": 201,
130
- "minute": 3001,
145
+ "input": {
146
+ "hour": 201,
147
+ "minute": 3001
148
+ },
131
149
  "expected": "11:01"
132
150
  },
133
151
  {
134
152
  "description": "hour and minutes roll over to exactly midnight",
135
153
  "property": "create",
136
- "hour": 72,
137
- "minute": 8640,
154
+ "input": {
155
+ "hour": 72,
156
+ "minute": 8640
157
+ },
138
158
  "expected": "00:00"
139
159
  },
140
160
  {
141
161
  "description": "negative hour",
142
162
  "property": "create",
143
- "hour": -1,
144
- "minute": 15,
163
+ "input": {
164
+ "hour": -1,
165
+ "minute": 15
166
+ },
145
167
  "expected": "23:15"
146
168
  },
147
169
  {
148
170
  "description": "negative hour rolls over",
149
171
  "property": "create",
150
- "hour": -25,
151
- "minute": 0,
172
+ "input": {
173
+ "hour": -25,
174
+ "minute": 0
175
+ },
152
176
  "expected": "23:00"
153
177
  },
154
178
  {
155
179
  "description": "negative hour rolls over continuously",
156
180
  "property": "create",
157
- "hour": -91,
158
- "minute": 0,
181
+ "input": {
182
+ "hour": -91,
183
+ "minute": 0
184
+ },
159
185
  "expected": "05:00"
160
186
  },
161
187
  {
162
188
  "description": "negative minutes",
163
189
  "property": "create",
164
- "hour": 1,
165
- "minute": -40,
190
+ "input": {
191
+ "hour": 1,
192
+ "minute": -40
193
+ },
166
194
  "expected": "00:20"
167
195
  },
168
196
  {
169
197
  "description": "negative minutes roll over",
170
198
  "property": "create",
171
- "hour": 1,
172
- "minute": -160,
199
+ "input": {
200
+ "hour": 1,
201
+ "minute": -160
202
+ },
173
203
  "expected": "22:20"
174
204
  },
175
205
  {
176
206
  "description": "negative minutes roll over continuously",
177
207
  "property": "create",
178
- "hour": 1,
179
- "minute": -4820,
208
+ "input": {
209
+ "hour": 1,
210
+ "minute": -4820
211
+ },
180
212
  "expected": "16:40"
181
213
  },
182
214
  {
183
215
  "description": "negative hour and minutes both roll over",
184
216
  "property": "create",
185
- "hour": -25,
186
- "minute": -160,
217
+ "input": {
218
+ "hour": -25,
219
+ "minute": -160
220
+ },
187
221
  "expected": "20:20"
188
222
  },
189
223
  {
190
224
  "description": "negative hour and minutes both roll over continuously",
191
225
  "property": "create",
192
- "hour": -121,
193
- "minute": -5810,
226
+ "input": {
227
+ "hour": -121,
228
+ "minute": -5810
229
+ },
194
230
  "expected": "22:10"
195
231
  }
196
232
  ]
@@ -201,65 +237,81 @@ is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes met
201
237
  {
202
238
  "description": "add minutes",
203
239
  "property": "add",
204
- "hour": 10,
205
- "minute": 0,
206
- "add": 3,
240
+ "input": {
241
+ "hour": 10,
242
+ "minute": 0,
243
+ "value": 3
244
+ },
207
245
  "expected": "10:03"
208
246
  },
209
247
  {
210
248
  "description": "add no minutes",
211
249
  "property": "add",
212
- "hour": 6,
213
- "minute": 41,
214
- "add": 0,
250
+ "input": {
251
+ "hour": 6,
252
+ "minute": 41,
253
+ "value": 0
254
+ },
215
255
  "expected": "06:41"
216
256
  },
217
257
  {
218
258
  "description": "add to next hour",
219
259
  "property": "add",
220
- "hour": 0,
221
- "minute": 45,
222
- "add": 40,
260
+ "input": {
261
+ "hour": 0,
262
+ "minute": 45,
263
+ "value": 40
264
+ },
223
265
  "expected": "01:25"
224
266
  },
225
267
  {
226
268
  "description": "add more than one hour",
227
269
  "property": "add",
228
- "hour": 10,
229
- "minute": 0,
230
- "add": 61,
270
+ "input": {
271
+ "hour": 10,
272
+ "minute": 0,
273
+ "value": 61
274
+ },
231
275
  "expected": "11:01"
232
276
  },
233
277
  {
234
278
  "description": "add more than two hours with carry",
235
279
  "property": "add",
236
- "hour": 0,
237
- "minute": 45,
238
- "add": 160,
280
+ "input": {
281
+ "hour": 0,
282
+ "minute": 45,
283
+ "value": 160
284
+ },
239
285
  "expected": "03:25"
240
286
  },
241
287
  {
242
288
  "description": "add across midnight",
243
289
  "property": "add",
244
- "hour": 23,
245
- "minute": 59,
246
- "add": 2,
290
+ "input": {
291
+ "hour": 23,
292
+ "minute": 59,
293
+ "value": 2
294
+ },
247
295
  "expected": "00:01"
248
296
  },
249
297
  {
250
298
  "description": "add more than one day (1500 min = 25 hrs)",
251
299
  "property": "add",
252
- "hour": 5,
253
- "minute": 32,
254
- "add": 1500,
300
+ "input": {
301
+ "hour": 5,
302
+ "minute": 32,
303
+ "value": 1500
304
+ },
255
305
  "expected": "06:32"
256
306
  },
257
307
  {
258
308
  "description": "add more than two days",
259
309
  "property": "add",
260
- "hour": 1,
261
- "minute": 1,
262
- "add": 3500,
310
+ "input": {
311
+ "hour": 1,
312
+ "minute": 1,
313
+ "value": 3500
314
+ },
263
315
  "expected": "11:21"
264
316
  }
265
317
  ]
@@ -269,66 +321,82 @@ is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes met
269
321
  "cases": [
270
322
  {
271
323
  "description": "subtract minutes",
272
- "property": "add",
273
- "hour": 10,
274
- "minute": 3,
275
- "add": -3,
324
+ "property": "subtract",
325
+ "input": {
326
+ "hour": 10,
327
+ "minute": 3,
328
+ "value": 3
329
+ },
276
330
  "expected": "10:00"
277
331
  },
278
332
  {
279
333
  "description": "subtract to previous hour",
280
- "property": "add",
281
- "hour": 10,
282
- "minute": 3,
283
- "add": -30,
334
+ "property": "subtract",
335
+ "input": {
336
+ "hour": 10,
337
+ "minute": 3,
338
+ "value": 30
339
+ },
284
340
  "expected": "09:33"
285
341
  },
286
342
  {
287
343
  "description": "subtract more than an hour",
288
- "property": "add",
289
- "hour": 10,
290
- "minute": 3,
291
- "add": -70,
344
+ "property": "subtract",
345
+ "input": {
346
+ "hour": 10,
347
+ "minute": 3,
348
+ "value": 70
349
+ },
292
350
  "expected": "08:53"
293
351
  },
294
352
  {
295
353
  "description": "subtract across midnight",
296
- "property": "add",
297
- "hour": 0,
298
- "minute": 3,
299
- "add": -4,
354
+ "property": "subtract",
355
+ "input": {
356
+ "hour": 0,
357
+ "minute": 3,
358
+ "value": 4
359
+ },
300
360
  "expected": "23:59"
301
361
  },
302
362
  {
303
363
  "description": "subtract more than two hours",
304
- "property": "add",
305
- "hour": 0,
306
- "minute": 0,
307
- "add": -160,
364
+ "property": "subtract",
365
+ "input": {
366
+ "hour": 0,
367
+ "minute": 0,
368
+ "value": 160
369
+ },
308
370
  "expected": "21:20"
309
371
  },
310
372
  {
311
373
  "description": "subtract more than two hours with borrow",
312
- "property": "add",
313
- "hour": 6,
314
- "minute": 15,
315
- "add": -160,
374
+ "property": "subtract",
375
+ "input": {
376
+ "hour": 6,
377
+ "minute": 15,
378
+ "value": 160
379
+ },
316
380
  "expected": "03:35"
317
381
  },
318
382
  {
319
383
  "description": "subtract more than one day (1500 min = 25 hrs)",
320
- "property": "add",
321
- "hour": 5,
322
- "minute": 32,
323
- "add": -1500,
384
+ "property": "subtract",
385
+ "input": {
386
+ "hour": 5,
387
+ "minute": 32,
388
+ "value": 1500
389
+ },
324
390
  "expected": "04:32"
325
391
  },
326
392
  {
327
393
  "description": "subtract more than two days",
328
- "property": "add",
329
- "hour": 2,
330
- "minute": 20,
331
- "add": -3000,
394
+ "property": "subtract",
395
+ "input": {
396
+ "hour": 2,
397
+ "minute": 20,
398
+ "value": 3000
399
+ },
332
400
  "expected": "00:20"
333
401
  }
334
402
  ]
@@ -339,195 +407,225 @@ is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes met
339
407
  {
340
408
  "description": "clocks with same time",
341
409
  "property": "equal",
342
- "clock1": {
343
- "hour": 15,
344
- "minute": 37
345
- },
346
- "clock2": {
347
- "hour": 15,
348
- "minute": 37
410
+ "input": {
411
+ "clock1": {
412
+ "hour": 15,
413
+ "minute": 37
414
+ },
415
+ "clock2": {
416
+ "hour": 15,
417
+ "minute": 37
418
+ }
349
419
  },
350
420
  "expected": true
351
421
  },
352
422
  {
353
423
  "description": "clocks a minute apart",
354
424
  "property": "equal",
355
- "clock1": {
356
- "hour": 15,
357
- "minute": 36
358
- },
359
- "clock2": {
360
- "hour": 15,
361
- "minute": 37
425
+ "input": {
426
+ "clock1": {
427
+ "hour": 15,
428
+ "minute": 36
429
+ },
430
+ "clock2": {
431
+ "hour": 15,
432
+ "minute": 37
433
+ }
362
434
  },
363
435
  "expected": false
364
436
  },
365
437
  {
366
438
  "description": "clocks an hour apart",
367
439
  "property": "equal",
368
- "clock1": {
369
- "hour": 14,
370
- "minute": 37
371
- },
372
- "clock2": {
373
- "hour": 15,
374
- "minute": 37
440
+ "input": {
441
+ "clock1": {
442
+ "hour": 14,
443
+ "minute": 37
444
+ },
445
+ "clock2": {
446
+ "hour": 15,
447
+ "minute": 37
448
+ }
375
449
  },
376
450
  "expected": false
377
451
  },
378
452
  {
379
453
  "description": "clocks with hour overflow",
380
454
  "property": "equal",
381
- "clock1": {
382
- "hour": 10,
383
- "minute": 37
384
- },
385
- "clock2": {
386
- "hour": 34,
387
- "minute": 37
455
+ "input": {
456
+ "clock1": {
457
+ "hour": 10,
458
+ "minute": 37
459
+ },
460
+ "clock2": {
461
+ "hour": 34,
462
+ "minute": 37
463
+ }
388
464
  },
389
465
  "expected": true
390
466
  },
391
467
  {
392
468
  "description": "clocks with hour overflow by several days",
393
469
  "property": "equal",
394
- "clock1": {
395
- "hour": 3,
396
- "minute": 11
397
- },
398
- "clock2": {
399
- "hour": 99,
400
- "minute": 11
470
+ "input": {
471
+ "clock1": {
472
+ "hour": 3,
473
+ "minute": 11
474
+ },
475
+ "clock2": {
476
+ "hour": 99,
477
+ "minute": 11
478
+ }
401
479
  },
402
480
  "expected": true
403
481
  },
404
482
  {
405
483
  "description": "clocks with negative hour",
406
484
  "property": "equal",
407
- "clock1": {
408
- "hour": 22,
409
- "minute": 40
410
- },
411
- "clock2": {
412
- "hour": -2,
413
- "minute": 40
485
+ "input": {
486
+ "clock1": {
487
+ "hour": 22,
488
+ "minute": 40
489
+ },
490
+ "clock2": {
491
+ "hour": -2,
492
+ "minute": 40
493
+ }
414
494
  },
415
495
  "expected": true
416
496
  },
417
497
  {
418
498
  "description": "clocks with negative hour that wraps",
419
499
  "property": "equal",
420
- "clock1": {
421
- "hour": 17,
422
- "minute": 3
423
- },
424
- "clock2": {
425
- "hour": -31,
426
- "minute": 3
500
+ "input": {
501
+ "clock1": {
502
+ "hour": 17,
503
+ "minute": 3
504
+ },
505
+ "clock2": {
506
+ "hour": -31,
507
+ "minute": 3
508
+ }
427
509
  },
428
510
  "expected": true
429
511
  },
430
512
  {
431
513
  "description": "clocks with negative hour that wraps multiple times",
432
514
  "property": "equal",
433
- "clock1": {
434
- "hour": 13,
435
- "minute": 49
436
- },
437
- "clock2": {
438
- "hour": -83,
439
- "minute": 49
515
+ "input": {
516
+ "clock1": {
517
+ "hour": 13,
518
+ "minute": 49
519
+ },
520
+ "clock2": {
521
+ "hour": -83,
522
+ "minute": 49
523
+ }
440
524
  },
441
525
  "expected": true
442
526
  },
443
527
  {
444
528
  "description": "clocks with minute overflow",
445
529
  "property": "equal",
446
- "clock1": {
447
- "hour": 0,
448
- "minute": 1
449
- },
450
- "clock2": {
451
- "hour": 0,
452
- "minute": 1441
530
+ "input": {
531
+ "clock1": {
532
+ "hour": 0,
533
+ "minute": 1
534
+ },
535
+ "clock2": {
536
+ "hour": 0,
537
+ "minute": 1441
538
+ }
453
539
  },
454
540
  "expected": true
455
541
  },
456
542
  {
457
543
  "description": "clocks with minute overflow by several days",
458
544
  "property": "equal",
459
- "clock1": {
460
- "hour": 2,
461
- "minute": 2
462
- },
463
- "clock2": {
464
- "hour": 2,
465
- "minute": 4322
545
+ "input": {
546
+ "clock1": {
547
+ "hour": 2,
548
+ "minute": 2
549
+ },
550
+ "clock2": {
551
+ "hour": 2,
552
+ "minute": 4322
553
+ }
466
554
  },
467
555
  "expected": true
468
556
  },
469
557
  {
470
558
  "description": "clocks with negative minute",
471
559
  "property": "equal",
472
- "clock1": {
473
- "hour": 2,
474
- "minute": 40
475
- },
476
- "clock2": {
477
- "hour": 3,
478
- "minute": -20
560
+ "input": {
561
+ "clock1": {
562
+ "hour": 2,
563
+ "minute": 40
564
+ },
565
+ "clock2": {
566
+ "hour": 3,
567
+ "minute": -20
568
+ }
479
569
  },
480
570
  "expected": true
481
571
  },
482
572
  {
483
573
  "description": "clocks with negative minute that wraps",
484
574
  "property": "equal",
485
- "clock1": {
486
- "hour": 4,
487
- "minute": 10
488
- },
489
- "clock2": {
490
- "hour": 5,
491
- "minute": -1490
575
+ "input": {
576
+ "clock1": {
577
+ "hour": 4,
578
+ "minute": 10
579
+ },
580
+ "clock2": {
581
+ "hour": 5,
582
+ "minute": -1490
583
+ }
492
584
  },
493
585
  "expected": true
494
586
  },
495
587
  {
496
588
  "description": "clocks with negative minute that wraps multiple times",
497
589
  "property": "equal",
498
- "clock1": {
499
- "hour": 6,
500
- "minute": 15
501
- },
502
- "clock2": {
503
- "hour": 6,
504
- "minute": -4305
590
+ "input": {
591
+ "clock1": {
592
+ "hour": 6,
593
+ "minute": 15
594
+ },
595
+ "clock2": {
596
+ "hour": 6,
597
+ "minute": -4305
598
+ }
505
599
  },
506
600
  "expected": true
507
601
  },
508
602
  {
509
603
  "description": "clocks with negative hours and minutes",
510
604
  "property": "equal",
511
- "clock1": {
512
- "hour": 7,
513
- "minute": 32
514
- },
515
- "clock2": {
516
- "hour": -12,
517
- "minute": -268
605
+ "input": {
606
+ "clock1": {
607
+ "hour": 7,
608
+ "minute": 32
609
+ },
610
+ "clock2": {
611
+ "hour": -12,
612
+ "minute": -268
613
+ }
518
614
  },
519
615
  "expected": true
520
616
  },
521
617
  {
522
618
  "description": "clocks with negative hours and minutes that wrap",
523
619
  "property": "equal",
524
- "clock1": {
525
- "hour": 18,
526
- "minute": 7
527
- },
528
- "clock2": {
529
- "hour": -54,
530
- "minute": -11513
620
+ "input": {
621
+ "clock1": {
622
+ "hour": 18,
623
+ "minute": 7
624
+ },
625
+ "clock2": {
626
+ "hour": -54,
627
+ "minute": -11513
628
+ }
531
629
  },
532
630
  "expected": true
533
631
  }
@@ -535,5 +633,4 @@ is Clock.?new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes met
535
633
  }
536
634
  ]
537
635
  }
538
-
539
636
  =end code