trackler 2.1.0.24 → 2.1.0.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (336) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/CONTRIBUTING.md +5 -8
  4. data/README.md +7 -7
  5. data/common/CONTRIBUTING.md +0 -5
  6. data/common/exercises/accumulate/description.md +4 -1
  7. data/common/exercises/acronym/description.md +1 -1
  8. data/common/exercises/bank-account/description.md +2 -1
  9. data/common/exercises/book-store/description.md +2 -5
  10. data/common/exercises/bracket-push/description.md +2 -4
  11. data/common/exercises/change/description.md +2 -5
  12. data/common/exercises/circular-buffer/description.md +0 -2
  13. data/common/exercises/clock/description.md +0 -2
  14. data/common/exercises/collatz-conjecture/canonical-data.json +36 -0
  15. data/common/exercises/collatz-conjecture/description.md +25 -0
  16. data/common/exercises/collatz-conjecture/metadata.yml +4 -0
  17. data/common/exercises/counter/description.md +1 -2
  18. data/common/exercises/diamond/description.md +0 -4
  19. data/common/exercises/flatten-array/description.md +1 -1
  20. data/common/exercises/grade-school/description.md +2 -1
  21. data/common/exercises/grains/description.md +2 -1
  22. data/common/exercises/grep/description.md +3 -2
  23. data/common/exercises/kindergarten-garden/description.md +2 -1
  24. data/common/exercises/largest-series-product/description.md +2 -1
  25. data/common/exercises/matrix/description.md +2 -1
  26. data/common/exercises/nucleotide-codons/description.md +2 -1
  27. data/common/exercises/ocr-numbers/description.md +2 -1
  28. data/common/exercises/octal/description.md +3 -1
  29. data/common/exercises/pangram/description.md +2 -1
  30. data/common/exercises/perfect-numbers/description.md +2 -1
  31. data/common/exercises/poker/description.md +0 -2
  32. data/common/exercises/protein-translation/description.md +3 -2
  33. data/common/exercises/proverb/description.md +2 -1
  34. data/common/exercises/pythagorean-triplet/description.md +4 -2
  35. data/common/exercises/queen-attack/description.md +2 -1
  36. data/common/exercises/rectangles/description.md +1 -3
  37. data/common/exercises/rotational-cipher/description.md +0 -4
  38. data/common/exercises/scale-generator/description.md +0 -2
  39. data/common/exercises/secret-handshake/description.md +2 -2
  40. data/common/exercises/series/description.md +2 -1
  41. data/common/exercises/sieve/description.md +2 -1
  42. data/common/exercises/space-age/description.md +0 -2
  43. data/common/exercises/strain/description.md +4 -5
  44. data/common/exercises/sublist/description.md +3 -6
  45. data/common/exercises/sum-of-multiples/description.md +2 -1
  46. data/common/exercises/tournament/description.md +4 -3
  47. data/common/exercises/transpose/description.md +1 -3
  48. data/common/exercises/trinary/description.md +2 -1
  49. data/common/exercises/two-bucket/description.md +1 -3
  50. data/common/exercises/two-fer/canonical-data.json +24 -0
  51. data/common/exercises/two-fer/description.md +40 -0
  52. data/common/exercises/two-fer/metadata.yml +4 -0
  53. data/common/exercises/word-search/description.md +2 -4
  54. data/common/exercises/zebra-puzzle/description.md +1 -1
  55. data/lib/trackler.rb +10 -5
  56. data/lib/trackler/description.rb +2 -2
  57. data/lib/trackler/guaranteed_file.rb +15 -15
  58. data/lib/trackler/implementation.rb +5 -5
  59. data/lib/trackler/implementations.rb +2 -2
  60. data/lib/trackler/metadata.rb +2 -2
  61. data/lib/trackler/problem.rb +2 -96
  62. data/lib/trackler/problems.rb +3 -48
  63. data/lib/trackler/specification.rb +101 -0
  64. data/lib/trackler/specifications.rb +52 -0
  65. data/lib/trackler/track.rb +6 -4
  66. data/lib/trackler/version.rb +1 -1
  67. data/tracks/bash/LICENSE +21 -0
  68. data/tracks/bash/README.md +0 -5
  69. data/tracks/c/LICENSE +21 -0
  70. data/tracks/c/README.md +0 -5
  71. data/tracks/clojure/LICENSE +2 -2
  72. data/tracks/clojure/README.org +0 -5
  73. data/tracks/clojure/config.json +5 -0
  74. data/tracks/clojure/exercises/sublist/project.clj +4 -0
  75. data/tracks/clojure/exercises/sublist/src/example.clj +19 -0
  76. data/tracks/clojure/exercises/sublist/sublist.mustache +9 -0
  77. data/tracks/clojure/exercises/sublist/test/sublist_test.clj +40 -0
  78. data/tracks/cpp/LICENSE +2 -2
  79. data/tracks/cpp/README.md +0 -5
  80. data/tracks/csharp/LICENSE +2 -2
  81. data/tracks/csharp/README.md +0 -5
  82. data/tracks/delphi/LICENSE +2 -2
  83. data/tracks/delphi/README.md +0 -5
  84. data/tracks/ecmascript/LICENSE +2 -2
  85. data/tracks/ecmascript/README.md +0 -5
  86. data/tracks/elisp/.travis.yml +7 -3
  87. data/tracks/elisp/LICENSE +2 -2
  88. data/tracks/elisp/README.org +3 -6
  89. data/tracks/elisp/bin/test-examples +27 -0
  90. data/tracks/elisp/config.json +10 -0
  91. data/tracks/elisp/docs/LEARNING.org +0 -3
  92. data/tracks/elisp/exercises/grains/example.el +18 -0
  93. data/tracks/elisp/exercises/grains/grains-test.el +38 -0
  94. data/tracks/elisp/exercises/grains/grains.el +10 -0
  95. data/tracks/elisp/exercises/phone-number/example.el +34 -0
  96. data/tracks/elisp/exercises/phone-number/phone-number-test.el +43 -0
  97. data/tracks/elisp/exercises/phone-number/phone-number.el +9 -0
  98. data/tracks/elixir/LICENSE +2 -2
  99. data/tracks/elixir/README.md +0 -5
  100. data/tracks/elm/LICENSE +2 -2
  101. data/tracks/elm/README.md +0 -5
  102. data/tracks/erlang/LICENSE +2 -2
  103. data/tracks/erlang/README.md +0 -5
  104. data/tracks/erlang/SETUP.md +7 -0
  105. data/tracks/erlang/exercises/rotational-cipher/rebar.config +5 -5
  106. data/tracks/erlang/exercises/rotational-cipher/test/rotational_cipher_tests.erl +18 -18
  107. data/tracks/factor/LICENSE +2 -2
  108. data/tracks/fortran/.github/PULL_REQUEST_TEMPLATE.md +23 -0
  109. data/tracks/fortran/.gitignore +4 -0
  110. data/tracks/fortran/.travis.yml +17 -0
  111. data/tracks/fortran/LICENSE +21 -0
  112. data/tracks/fortran/Makefile +40 -0
  113. data/tracks/fortran/README.md +72 -0
  114. data/tracks/fortran/bin/fetch-configlet +32 -0
  115. data/tracks/fortran/config.json +32 -0
  116. data/tracks/{kotlin/SETUP.md → fortran/docs/ABOUT.md} +0 -0
  117. data/tracks/fortran/docs/INSTALLATION.md +0 -0
  118. data/tracks/fortran/docs/LEARNING.md +0 -0
  119. data/tracks/fortran/docs/RESOURCES.md +0 -0
  120. data/tracks/fortran/docs/TESTS.md +0 -0
  121. data/tracks/fortran/exercises/TRACK_HINTS.md +0 -0
  122. data/tracks/fortran/exercises/bob/bob.fun +114 -0
  123. data/tracks/fortran/exercises/bob/example.f90 +61 -0
  124. data/tracks/fortran/exercises/hello_world/example.f90 +9 -0
  125. data/tracks/fortran/exercises/hello_world/hello_world.fun +10 -0
  126. data/tracks/fortran/img/.keep +0 -0
  127. data/tracks/fsharp/LICENSE +2 -2
  128. data/tracks/fsharp/README.md +0 -5
  129. data/tracks/go/LICENSE +2 -2
  130. data/tracks/go/README.md +0 -5
  131. data/tracks/haskell/LICENSE +2 -2
  132. data/tracks/haskell/README.md +0 -5
  133. data/tracks/idris/LICENSE +2 -2
  134. data/tracks/idris/README.md +0 -5
  135. data/tracks/java/LICENSE +2 -2
  136. data/tracks/java/README.md +0 -7
  137. data/tracks/java/{SETUP.md → TRACK_HINTS.md} +0 -0
  138. data/tracks/java/config.json +5 -0
  139. data/tracks/java/exercises/_template/build.gradle +1 -0
  140. data/tracks/java/exercises/accumulate/build.gradle +1 -0
  141. data/tracks/java/exercises/acronym/build.gradle +1 -0
  142. data/tracks/java/exercises/all-your-base/build.gradle +1 -0
  143. data/tracks/java/exercises/allergies/build.gradle +1 -0
  144. data/tracks/java/exercises/anagram/build.gradle +1 -0
  145. data/tracks/java/exercises/atbash-cipher/build.gradle +1 -0
  146. data/tracks/java/exercises/beer-song/build.gradle +1 -0
  147. data/tracks/java/exercises/binary-search/build.gradle +1 -0
  148. data/tracks/java/exercises/binary/build.gradle +1 -0
  149. data/tracks/java/exercises/bob/build.gradle +1 -0
  150. data/tracks/java/exercises/book-store/build.gradle +1 -0
  151. data/tracks/java/exercises/bracket-push/build.gradle +1 -0
  152. data/tracks/java/exercises/change/build.gradle +1 -0
  153. data/tracks/java/exercises/clock/build.gradle +2 -1
  154. data/tracks/java/exercises/collatz-conjecture/build.gradle +18 -0
  155. data/tracks/java/exercises/collatz-conjecture/src/example/java/CollatzCalculator.java +19 -0
  156. data/tracks/java/exercises/collatz-conjecture/src/main/java/CollatzCalculator.java +7 -0
  157. data/tracks/java/exercises/collatz-conjecture/src/test/java/CollatzCalculatorTest.java +59 -0
  158. data/tracks/java/exercises/crypto-square/build.gradle +1 -0
  159. data/tracks/java/exercises/diamond/build.gradle +1 -0
  160. data/tracks/java/exercises/diamond/src/example/java/DiamondPrinter.java +4 -4
  161. data/tracks/java/exercises/diamond/src/test/java/DiamondPrinterTest.java +6 -2
  162. data/tracks/java/exercises/difference-of-squares/build.gradle +1 -0
  163. data/tracks/java/exercises/difference-of-squares/src/main/java/.keep +0 -0
  164. data/tracks/java/exercises/etl/build.gradle +1 -0
  165. data/tracks/java/exercises/flatten-array/build.gradle +1 -0
  166. data/tracks/java/exercises/gigasecond/build.gradle +1 -0
  167. data/tracks/java/exercises/grade-school/build.gradle +1 -0
  168. data/tracks/java/exercises/hamming/build.gradle +1 -0
  169. data/tracks/java/exercises/hexadecimal/build.gradle +1 -0
  170. data/tracks/java/exercises/isogram/build.gradle +1 -0
  171. data/tracks/java/exercises/kindergarten-garden/build.gradle +1 -0
  172. data/tracks/java/exercises/largest-series-product/build.gradle +1 -0
  173. data/tracks/java/exercises/linked-list/build.gradle +1 -0
  174. data/tracks/java/exercises/luhn/build.gradle +1 -0
  175. data/tracks/java/exercises/matrix/build.gradle +2 -1
  176. data/tracks/java/exercises/meetup/build.gradle +1 -0
  177. data/tracks/java/exercises/minesweeper/build.gradle +1 -0
  178. data/tracks/java/exercises/nth-prime/build.gradle +1 -0
  179. data/tracks/java/exercises/ocr-numbers/build.gradle +1 -0
  180. data/tracks/java/exercises/octal/build.gradle +1 -0
  181. data/tracks/java/exercises/pangram/build.gradle +1 -0
  182. data/tracks/java/exercises/pascals-triangle/build.gradle +1 -0
  183. data/tracks/java/exercises/perfect-numbers/build.gradle +1 -0
  184. data/tracks/java/exercises/phone-number/build.gradle +1 -0
  185. data/tracks/java/exercises/pig-latin/build.gradle +1 -0
  186. data/tracks/java/exercises/queen-attack/build.gradle +1 -0
  187. data/tracks/java/exercises/raindrops/build.gradle +1 -0
  188. data/tracks/java/exercises/rectangles/build.gradle +1 -0
  189. data/tracks/java/exercises/rna-transcription/build.gradle +1 -0
  190. data/tracks/java/exercises/robot-simulator/build.gradle +1 -0
  191. data/tracks/java/exercises/roman-numerals/build.gradle +1 -0
  192. data/tracks/java/exercises/run-length-encoding/build.gradle +1 -0
  193. data/tracks/java/exercises/saddle-points/build.gradle +1 -0
  194. data/tracks/java/exercises/scrabble-score/build.gradle +1 -0
  195. data/tracks/java/exercises/secret-handshake/build.gradle +1 -0
  196. data/tracks/java/exercises/series/build.gradle +1 -0
  197. data/tracks/java/exercises/settings.gradle +1 -0
  198. data/tracks/java/exercises/sieve/build.gradle +1 -0
  199. data/tracks/java/exercises/simple-cipher/build.gradle +1 -0
  200. data/tracks/java/exercises/simple-linked-list/build.gradle +1 -0
  201. data/tracks/java/exercises/space-age/build.gradle +1 -0
  202. data/tracks/java/exercises/strain/build.gradle +1 -0
  203. data/tracks/java/exercises/sublist/build.gradle +1 -0
  204. data/tracks/java/exercises/sum-of-multiples/build.gradle +1 -0
  205. data/tracks/java/exercises/triangle/build.gradle +1 -0
  206. data/tracks/java/exercises/trinary/build.gradle +1 -0
  207. data/tracks/java/exercises/twelve-days/build.gradle +2 -1
  208. data/tracks/java/exercises/word-count/build.gradle +1 -0
  209. data/tracks/java/exercises/wordy/build.gradle +1 -0
  210. data/tracks/javascript/LICENSE +2 -2
  211. data/tracks/javascript/README.md +0 -5
  212. data/tracks/julia/LICENSE +2 -2
  213. data/tracks/kotlin/LICENSE +2 -2
  214. data/tracks/kotlin/README.md +0 -7
  215. data/tracks/kotlin/TRACK_HINTS.md +1 -0
  216. data/tracks/kotlin/exercises/phone-number/src/example/kotlin/PhoneNumber.kt +1 -1
  217. data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +7 -8
  218. data/tracks/kotlin/exercises/rna-transcription/src/test/kotlin/RnaTranscriptionTest.kt +6 -6
  219. data/tracks/lfe/LICENSE +2 -2
  220. data/tracks/lfe/README.md +0 -5
  221. data/tracks/lisp/LICENSE +2 -2
  222. data/tracks/lisp/README.md +0 -5
  223. data/tracks/lua/LICENSE +2 -2
  224. data/tracks/lua/README.md +0 -5
  225. data/tracks/mips/LICENSE +2 -2
  226. data/tracks/mips/README.md +0 -5
  227. data/tracks/objective-c/LICENSE +2 -2
  228. data/tracks/objective-c/README.md +0 -5
  229. data/tracks/ocaml/LICENSE +2 -2
  230. data/tracks/ocaml/README.md +0 -5
  231. data/tracks/ocaml/config.json +54 -25
  232. data/tracks/ocaml/exercises/forth/.merlin +5 -0
  233. data/tracks/ocaml/exercises/forth/Makefile +11 -0
  234. data/tracks/ocaml/exercises/forth/example.ml +89 -0
  235. data/tracks/ocaml/exercises/forth/forth.mli +1 -0
  236. data/tracks/ocaml/exercises/forth/test.ml +147 -0
  237. data/tracks/ocaml/exercises/react/.merlin +5 -0
  238. data/tracks/ocaml/exercises/react/HINT.md +3 -0
  239. data/tracks/ocaml/exercises/react/Makefile +11 -0
  240. data/tracks/ocaml/exercises/react/example.ml +106 -0
  241. data/tracks/ocaml/exercises/react/react.mli +26 -0
  242. data/tracks/ocaml/exercises/react/test.ml +157 -0
  243. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +5 -2
  244. data/tracks/ocaml/tools/test-generator/templates/forth/template.ml +114 -0
  245. data/tracks/perl5/LICENSE +2 -2
  246. data/tracks/perl6/LICENSE +2 -2
  247. data/tracks/perl6/README.md +0 -5
  248. data/tracks/perl6/config.json +5 -0
  249. data/tracks/perl6/exercises/clock/Example.pm6 +2 -2
  250. data/tracks/perl6/exercises/flatten-array/Example.pm6 +13 -0
  251. data/tracks/perl6/exercises/flatten-array/FlattenArray.pm6 +4 -0
  252. data/tracks/perl6/exercises/flatten-array/example.yaml +6 -0
  253. data/tracks/perl6/exercises/flatten-array/flatten-array.t +80 -0
  254. data/tracks/php/LICENSE +2 -2
  255. data/tracks/php/README.md +0 -5
  256. data/tracks/powershell/.travis.yml +1 -0
  257. data/tracks/python/LICENSE +2 -2
  258. data/tracks/python/README.md +0 -5
  259. data/tracks/python/config.json +8 -0
  260. data/tracks/python/exercises/protein-translation/example.py +25 -0
  261. data/tracks/python/exercises/protein-translation/protein_translation.py +6 -0
  262. data/tracks/python/exercises/protein-translation/protein_translation_test.py +59 -0
  263. data/tracks/r/LICENSE +2 -2
  264. data/tracks/r/README.md +0 -5
  265. data/tracks/racket/LICENSE +2 -2
  266. data/tracks/racket/README.md +0 -5
  267. data/tracks/racket/config.json +5 -0
  268. data/tracks/racket/exercises/acronym/acronym-test.rkt +40 -0
  269. data/tracks/racket/exercises/acronym/acronym.rkt +3 -0
  270. data/tracks/racket/exercises/acronym/example.rkt +25 -0
  271. data/tracks/racket/exercises/grep/example.rkt +60 -26
  272. data/tracks/racket/exercises/grep/grep-test.rkt +154 -17
  273. data/tracks/racket/exercises/grep/grep.rkt +1 -18
  274. data/tracks/racket/exercises/grep/iliad.txt +9 -0
  275. data/tracks/racket/exercises/grep/midsummer-night.txt +7 -0
  276. data/tracks/racket/exercises/grep/paradise-lost.txt +8 -0
  277. data/tracks/ruby/README.md +4 -1
  278. data/tracks/ruby/exercises/acronym/.meta/.version +1 -1
  279. data/tracks/ruby/exercises/acronym/.meta/solutions/acronym.rb +1 -1
  280. data/tracks/ruby/exercises/acronym/acronym_test.rb +2 -7
  281. data/tracks/ruby/exercises/anagram/.meta/generator/anagram_case.rb +1 -1
  282. data/tracks/ruby/exercises/beer-song/.meta/generator/beer_song_case.rb +1 -1
  283. data/tracks/ruby/exercises/clock/.meta/generator/clock_case.rb +1 -1
  284. data/tracks/ruby/exercises/connect/.meta/generator/connect_case.rb +0 -3
  285. data/tracks/ruby/exercises/connect/.meta/generator/test_template.erb +1 -1
  286. data/tracks/ruby/exercises/difference-of-squares/.meta/.version +1 -1
  287. data/tracks/ruby/exercises/difference-of-squares/.meta/solutions/difference_of_squares.rb +1 -1
  288. data/tracks/ruby/exercises/difference-of-squares/difference_of_squares_test.rb +12 -17
  289. data/tracks/ruby/exercises/triangle/.meta/generator/triangle_case.rb +10 -2
  290. data/tracks/ruby/exercises/triangle/triangle_test.rb +17 -17
  291. data/tracks/ruby/exercises/wordy/.meta/generator/wordy_case.rb +1 -1
  292. data/tracks/ruby/lib/generator/case_values.rb +1 -1
  293. data/tracks/ruby/lib/generator/exercise_case.rb +16 -2
  294. data/tracks/ruby/lib/generator/exercise_case/assertion.rb +4 -4
  295. data/tracks/ruby/test/fixtures/xruby/exercises/alpha/.meta/generator/alpha_case.rb +1 -1
  296. data/tracks/ruby/test/generator/case_values_test.rb +28 -7
  297. data/tracks/ruby/test/generator/exercise_case/assertion_test.rb +7 -7
  298. data/tracks/ruby/test/generator/exercise_case_test.rb +21 -25
  299. data/tracks/ruby/test/wordy_cases_test.rb +4 -4
  300. data/tracks/rust/LICENSE +2 -2
  301. data/tracks/rust/README.md +0 -5
  302. data/tracks/rust/config.json +1 -0
  303. data/tracks/rust/exercises/etl/Cargo.toml +1 -1
  304. data/tracks/rust/exercises/etl/example.rs +2 -2
  305. data/tracks/rust/exercises/etl/tests/etl.rs +26 -32
  306. data/tracks/rust/exercises/forth/tests/forth.rs +20 -22
  307. data/tracks/rust/exercises/minesweeper/Cargo.toml +1 -1
  308. data/tracks/rust/exercises/minesweeper/example.rs +3 -0
  309. data/tracks/rust/exercises/minesweeper/tests/minesweeper.rs +44 -46
  310. data/tracks/rust/exercises/raindrops/Cargo.toml +1 -1
  311. data/tracks/rust/exercises/raindrops/tests/raindrops.rs +12 -0
  312. data/tracks/rust/exercises/rna-transcription/Cargo.toml +1 -1
  313. data/tracks/rust/exercises/rna-transcription/example.rs +13 -9
  314. data/tracks/rust/exercises/rna-transcription/tests/rna-transcription.rs +23 -5
  315. data/tracks/scala/LICENSE +2 -2
  316. data/tracks/scala/README.md +0 -5
  317. data/tracks/scheme/LICENSE +2 -2
  318. data/tracks/scheme/README.org +0 -6
  319. data/tracks/swift/Dangerfile +1 -1
  320. data/tracks/swift/LICENSE +2 -2
  321. data/tracks/swift/README.md +0 -6
  322. data/tracks/vbnet/.travis.yml +1 -0
  323. data/tracks/vimscript/.travis.yml +4 -0
  324. data/tracks/vimscript/.vintrc.yaml +5 -0
  325. data/tracks/vimscript/TRACK_HINTS.md +19 -1
  326. data/tracks/vimscript/bin/pre-push +18 -0
  327. data/tracks/vimscript/config.json +8 -1
  328. data/tracks/vimscript/docs/ABOUT.md +7 -6
  329. data/tracks/vimscript/docs/TESTS.md +4 -4
  330. data/tracks/vimscript/exercises/allergies/allergies.vader +68 -0
  331. data/tracks/vimscript/exercises/allergies/allergies.vim +29 -0
  332. data/tracks/vimscript/exercises/allergies/example.vim +23 -0
  333. data/tracks/vimscript/lib/generate.vim +89 -0
  334. metadata +81 -6
  335. data/tracks/java/exercises/difference-of-squares/src/main/java/DifferenceOfSquaresCalculator.java +0 -15
  336. data/tracks/ocaml/.vscode/launch.json +0 -13
@@ -0,0 +1,8 @@
1
+ Of Mans First Disobedience, and the Fruit
2
+ Of that Forbidden Tree, whose mortal tast
3
+ Brought Death into the World, and all our woe,
4
+ With loss of Eden, till one greater Man
5
+ Restore us, and regain the blissful Seat,
6
+ Sing Heav'nly Muse, that on the secret top
7
+ Of Oreb, or of Sinai, didst inspire
8
+ That Shepherd, who first taught the chosen Seed
@@ -56,7 +56,7 @@ rake test:clock -- -p
56
56
  ```
57
57
 
58
58
  To run a subset of the tests, use a regular expression. For example, if tests
59
- exist taht are named identical_to_4_places, and identical, then we can run both
59
+ exist that are named identical_to_4_places, and identical, then we can run both
60
60
  tests with
61
61
 
62
62
  ```sh
@@ -71,6 +71,9 @@ Note that flags which have an attached value, like above, must take the form
71
71
 
72
72
  Generated test suites use the `bin/generator` cli.
73
73
 
74
+ Before using the cli it is recommended you run `bundle install` from within
75
+ the xruby directory to install/update any required gems.
76
+
74
77
  While many of the exercises which have canonical data already have generators,
75
78
  some do not. To find out whether an exercise has a generator, run
76
79
 
@@ -1 +1 @@
1
- 3
1
+ 4
@@ -1,5 +1,5 @@
1
1
  module BookKeeping
2
- VERSION = 3
2
+ VERSION = 4
3
3
  end
4
4
 
5
5
  class Acronym
@@ -2,7 +2,7 @@
2
2
  require 'minitest/autorun'
3
3
  require_relative 'acronym'
4
4
 
5
- # Common test data version: 1.0.0 dcfe476
5
+ # Common test data version: 1.1.0 cae7ae1
6
6
  class AcronymTest < Minitest::Test
7
7
  def test_basic
8
8
  # skip
@@ -14,11 +14,6 @@ class AcronymTest < Minitest::Test
14
14
  assert_equal "ROR", Acronym.abbreviate('Ruby on Rails')
15
15
  end
16
16
 
17
- def test_camelcase
18
- skip
19
- assert_equal "HTML", Acronym.abbreviate('HyperText Markup Language')
20
- end
21
-
22
17
  def test_punctuation
23
18
  skip
24
19
  assert_equal "FIFO", Acronym.abbreviate('First In, First Out')
@@ -58,6 +53,6 @@ class AcronymTest < Minitest::Test
58
53
 
59
54
  def test_bookkeeping
60
55
  skip
61
- assert_equal 3, BookKeeping::VERSION
56
+ assert_equal 4, BookKeeping::VERSION
62
57
  end
63
58
  end
@@ -13,7 +13,7 @@ class AnagramCase < Generator::ExerciseCase
13
13
  end
14
14
 
15
15
  def show_comment
16
- "# #{comment}" unless comment.nil?
16
+ "# #{comment}" if respond_to?(:comment)
17
17
  end
18
18
 
19
19
  def detector
@@ -17,7 +17,7 @@ class BeerSongCase < Generator::ExerciseCase
17
17
  if property == 'verse'
18
18
  number
19
19
  else
20
- "%s, %s" % [self["beginning"], self["end"]]
20
+ "%s, %s" % [self.beginning, self.end]
21
21
  end
22
22
  end
23
23
  end
@@ -29,7 +29,7 @@ class ClockCase < Generator::ExerciseCase
29
29
  end
30
30
 
31
31
  def add_to_clock
32
- " + #{add}" if add
32
+ " + #{add}" if respond_to?(:add)
33
33
  end
34
34
 
35
35
  end
@@ -19,7 +19,4 @@ class ConnectCase < Generator::ExerciseCase
19
19
  string.inspect.tr('"', "'")
20
20
  end
21
21
 
22
- def ignore_method_length
23
- "# rubocop:disable MethodLength\n " if board.length > 8
24
- end
25
22
  end
@@ -5,7 +5,7 @@ require_relative 'connect'
5
5
  # Common test data version: <%= canonical_data_version %> <%= abbreviated_commit_hash %>
6
6
  class ConnectTest < Minitest::Test
7
7
  <% test_cases.each_with_index do |test_case, idx| %>
8
- <%= test_case.ignore_method_length%>def <%= test_case.name %>
8
+ def <%= test_case.name %>
9
9
  <%= test_case.skipped(idx) %><% test_case.test_body.each do |line| %>
10
10
  <%= line %><% end %>
11
11
  end
@@ -1,5 +1,5 @@
1
1
  module BookKeeping
2
- VERSION = 3
2
+ VERSION = 4
3
3
  end
4
4
 
5
5
  class Squares
@@ -2,16 +2,16 @@
2
2
  require 'minitest/autorun'
3
3
  require_relative 'difference_of_squares'
4
4
 
5
- # Common test data version: 1.0.0 1eb9535
5
+ # Common test data version: 1.1.0 7a1108b
6
6
  class DifferenceOfSquaresTest < Minitest::Test
7
- def test_square_of_sum_5
7
+ def test_square_of_sum_1
8
8
  # skip
9
- assert_equal 225, Squares.new(5).square_of_sum
9
+ assert_equal 1, Squares.new(1).square_of_sum
10
10
  end
11
11
 
12
- def test_square_of_sum_10
12
+ def test_square_of_sum_5
13
13
  skip
14
- assert_equal 3_025, Squares.new(10).square_of_sum
14
+ assert_equal 225, Squares.new(5).square_of_sum
15
15
  end
16
16
 
17
17
  def test_square_of_sum_100
@@ -19,14 +19,14 @@ class DifferenceOfSquaresTest < Minitest::Test
19
19
  assert_equal 25_502_500, Squares.new(100).square_of_sum
20
20
  end
21
21
 
22
- def test_sum_of_squares_5
22
+ def test_sum_of_squares_1
23
23
  skip
24
- assert_equal 55, Squares.new(5).sum_of_squares
24
+ assert_equal 1, Squares.new(1).sum_of_squares
25
25
  end
26
26
 
27
- def test_sum_of_squares_10
27
+ def test_sum_of_squares_5
28
28
  skip
29
- assert_equal 385, Squares.new(10).sum_of_squares
29
+ assert_equal 55, Squares.new(5).sum_of_squares
30
30
  end
31
31
 
32
32
  def test_sum_of_squares_100
@@ -34,9 +34,9 @@ class DifferenceOfSquaresTest < Minitest::Test
34
34
  assert_equal 338_350, Squares.new(100).sum_of_squares
35
35
  end
36
36
 
37
- def test_difference_of_squares_0
37
+ def test_difference_of_squares_1
38
38
  skip
39
- assert_equal 0, Squares.new(0).difference
39
+ assert_equal 0, Squares.new(1).difference
40
40
  end
41
41
 
42
42
  def test_difference_of_squares_5
@@ -44,11 +44,6 @@ class DifferenceOfSquaresTest < Minitest::Test
44
44
  assert_equal 170, Squares.new(5).difference
45
45
  end
46
46
 
47
- def test_difference_of_squares_10
48
- skip
49
- assert_equal 2_640, Squares.new(10).difference
50
- end
51
-
52
47
  def test_difference_of_squares_100
53
48
  skip
54
49
  assert_equal 25_164_150, Squares.new(100).difference
@@ -73,6 +68,6 @@ class DifferenceOfSquaresTest < Minitest::Test
73
68
 
74
69
  def test_bookkeeping
75
70
  skip
76
- assert_equal 3, BookKeeping::VERSION
71
+ assert_equal 4, BookKeeping::VERSION
77
72
  end
78
73
  end
@@ -24,11 +24,19 @@ class TriangleCase < Generator::ExerciseCase
24
24
  end
25
25
 
26
26
  def failure_message
27
- %Q("Expected '#{expected}', #{expected_type}.")
27
+ %Q("Expected '#{expected}', #{expected_triangle}.")
28
28
  end
29
29
 
30
30
  def expected_type
31
- "triangle is #{expected ? '' : 'not '}#{property}"
31
+ "triangle is #{type}"
32
+ end
33
+
34
+ def expected_triangle
35
+ "triangle #{sides} is #{type}"
36
+ end
37
+
38
+ def type
39
+ "#{expected ? '' : 'not ' }#{property}"
32
40
  end
33
41
 
34
42
  end
@@ -7,103 +7,103 @@ class TriangleTest < Minitest::Test
7
7
  def test_triangle_is_equilateral_if_all_sides_are_equal
8
8
  # skip
9
9
  triangle = Triangle.new([2, 2, 2])
10
- assert triangle.equilateral?, "Expected 'true', triangle is equilateral."
10
+ assert triangle.equilateral?, "Expected 'true', triangle [2, 2, 2] is equilateral."
11
11
  end
12
12
 
13
13
  def test_triangle_is_not_equilateral_if_any_side_is_unequal
14
14
  skip
15
15
  triangle = Triangle.new([2, 3, 2])
16
- refute triangle.equilateral?, "Expected 'false', triangle is not equilateral."
16
+ refute triangle.equilateral?, "Expected 'false', triangle [2, 3, 2] is not equilateral."
17
17
  end
18
18
 
19
19
  def test_triangle_is_not_equilateral_if_no_sides_are_equal
20
20
  skip
21
21
  triangle = Triangle.new([5, 4, 6])
22
- refute triangle.equilateral?, "Expected 'false', triangle is not equilateral."
22
+ refute triangle.equilateral?, "Expected 'false', triangle [5, 4, 6] is not equilateral."
23
23
  end
24
24
 
25
25
  def test_all_zero_sides_are_illegal_so_the_triangle_is_not_equilateral
26
26
  skip
27
27
  triangle = Triangle.new([0, 0, 0])
28
- refute triangle.equilateral?, "Expected 'false', triangle is not equilateral."
28
+ refute triangle.equilateral?, "Expected 'false', triangle [0, 0, 0] is not equilateral."
29
29
  end
30
30
 
31
31
  def test_equilateral_triangle_sides_may_be_floats
32
32
  skip
33
33
  triangle = Triangle.new([0.5, 0.5, 0.5])
34
- assert triangle.equilateral?, "Expected 'true', triangle is equilateral."
34
+ assert triangle.equilateral?, "Expected 'true', triangle [0.5, 0.5, 0.5] is equilateral."
35
35
  end
36
36
 
37
37
  def test_triangle_is_isosceles_if_last_two_sides_are_equal
38
38
  skip
39
39
  triangle = Triangle.new([3, 4, 4])
40
- assert triangle.isosceles?, "Expected 'true', triangle is isosceles."
40
+ assert triangle.isosceles?, "Expected 'true', triangle [3, 4, 4] is isosceles."
41
41
  end
42
42
 
43
43
  def test_triangle_is_isosceles_if_first_two_sides_are_equal
44
44
  skip
45
45
  triangle = Triangle.new([4, 4, 3])
46
- assert triangle.isosceles?, "Expected 'true', triangle is isosceles."
46
+ assert triangle.isosceles?, "Expected 'true', triangle [4, 4, 3] is isosceles."
47
47
  end
48
48
 
49
49
  def test_triangle_is_isosceles_if_first_and_last_sides_are_equal
50
50
  skip
51
51
  triangle = Triangle.new([4, 3, 4])
52
- assert triangle.isosceles?, "Expected 'true', triangle is isosceles."
52
+ assert triangle.isosceles?, "Expected 'true', triangle [4, 3, 4] is isosceles."
53
53
  end
54
54
 
55
55
  def test_equilateral_triangles_are_also_isosceles
56
56
  skip
57
57
  triangle = Triangle.new([4, 4, 4])
58
- assert triangle.isosceles?, "Expected 'true', triangle is isosceles."
58
+ assert triangle.isosceles?, "Expected 'true', triangle [4, 4, 4] is isosceles."
59
59
  end
60
60
 
61
61
  def test_triangle_is_not_isosceles_if_no_sides_are_equal
62
62
  skip
63
63
  triangle = Triangle.new([2, 3, 4])
64
- refute triangle.isosceles?, "Expected 'false', triangle is not isosceles."
64
+ refute triangle.isosceles?, "Expected 'false', triangle [2, 3, 4] is not isosceles."
65
65
  end
66
66
 
67
67
  def test_sides_that_violate_triangle_inequality_are_not_isosceles_even_if_two_are_equal
68
68
  skip
69
69
  triangle = Triangle.new([1, 1, 3])
70
- refute triangle.isosceles?, "Expected 'false', triangle is not isosceles."
70
+ refute triangle.isosceles?, "Expected 'false', triangle [1, 1, 3] is not isosceles."
71
71
  end
72
72
 
73
73
  def test_isosceles_triangle_sides_may_be_floats
74
74
  skip
75
75
  triangle = Triangle.new([0.5, 0.4, 0.5])
76
- assert triangle.isosceles?, "Expected 'true', triangle is isosceles."
76
+ assert triangle.isosceles?, "Expected 'true', triangle [0.5, 0.4, 0.5] is isosceles."
77
77
  end
78
78
 
79
79
  def test_triangle_is_scalene_if_no_sides_are_equal
80
80
  skip
81
81
  triangle = Triangle.new([5, 4, 6])
82
- assert triangle.scalene?, "Expected 'true', triangle is scalene."
82
+ assert triangle.scalene?, "Expected 'true', triangle [5, 4, 6] is scalene."
83
83
  end
84
84
 
85
85
  def test_triangle_is_not_scalene_if_all_sides_are_equal
86
86
  skip
87
87
  triangle = Triangle.new([4, 4, 4])
88
- refute triangle.scalene?, "Expected 'false', triangle is not scalene."
88
+ refute triangle.scalene?, "Expected 'false', triangle [4, 4, 4] is not scalene."
89
89
  end
90
90
 
91
91
  def test_triangle_is_not_scalene_if_two_sides_are_equal
92
92
  skip
93
93
  triangle = Triangle.new([4, 4, 3])
94
- refute triangle.scalene?, "Expected 'false', triangle is not scalene."
94
+ refute triangle.scalene?, "Expected 'false', triangle [4, 4, 3] is not scalene."
95
95
  end
96
96
 
97
97
  def test_sides_that_violate_triangle_inequality_are_not_scalene_even_if_they_are_all_different
98
98
  skip
99
99
  triangle = Triangle.new([7, 3, 2])
100
- refute triangle.scalene?, "Expected 'false', triangle is not scalene."
100
+ refute triangle.scalene?, "Expected 'false', triangle [7, 3, 2] is not scalene."
101
101
  end
102
102
 
103
103
  def test_scalene_triangle_sides_may_be_floats
104
104
  skip
105
105
  triangle = Triangle.new([0.5, 0.4, 0.6])
106
- assert triangle.scalene?, "Expected 'true', triangle is scalene."
106
+ assert triangle.scalene?, "Expected 'true', triangle [0.5, 0.4, 0.6] is scalene."
107
107
  end
108
108
 
109
109
  # Problems in exercism evolve over time, as we find better ways to ask
@@ -16,7 +16,7 @@ class WordyCase < Generator::ExerciseCase
16
16
  end
17
17
 
18
18
  def assertion
19
- return error_assertion unless expected
19
+ return error_assertion if expected == false
20
20
  return message_assertion if message
21
21
 
22
22
  "assert_equal(#{expected}, WordProblem.new(question).answer)"
@@ -7,7 +7,7 @@ module Generator
7
7
 
8
8
  def cases(exercise_data)
9
9
  extract_test_cases(data: JSON.parse(exercise_data)['cases'])
10
- .map { |test| @case_class.new(test) }
10
+ .map { |case_properties| @case_class.new(canonical: OpenStruct.new(case_properties)) }
11
11
  end
12
12
 
13
13
  private
@@ -1,17 +1,31 @@
1
1
  require 'ostruct'
2
2
 
3
3
  module Generator
4
- class ExerciseCase < OpenStruct
4
+ class ExerciseCase
5
5
  using Generator::Underscore
6
6
  include CaseHelpers
7
7
  include Assertion
8
8
 
9
+ attr_reader :canonical
10
+ def initialize(canonical:)
11
+ @canonical = canonical
12
+ end
13
+
9
14
  def name
10
- 'test_%s' % description.underscore
15
+ 'test_%s' % canonical.description.underscore
11
16
  end
12
17
 
13
18
  def skipped(index)
14
19
  index.zero? ? '# skip' : 'skip'
15
20
  end
21
+
22
+ def method_missing(sym, *args, &block)
23
+ return canonical.send(sym) if canonical.respond_to?(sym)
24
+ super(sym, *args, &block)
25
+ end
26
+
27
+ def respond_to?(sym, include_private = false)
28
+ canonical.respond_to?(sym) || super
29
+ end
16
30
  end
17
31
  end
@@ -14,7 +14,7 @@ module Generator
14
14
  # "#{assert} Luhn.valid?(#{input.inspect})"
15
15
  #
16
16
  def assert
17
- expected ? 'assert' : 'refute'
17
+ canonical.expected ? 'assert' : 'refute'
18
18
  end
19
19
 
20
20
  # generates assertions of the form
@@ -29,8 +29,8 @@ module Generator
29
29
  # assert_equal { "PigLatin.translate(#{input.inspect})" }
30
30
  #
31
31
  def assert_equal
32
- assertion = expected.nil? ? 'assert_nil' :
33
- "assert_equal #{expected.inspect},"
32
+ assertion = canonical.expected.nil? ? 'assert_nil' :
33
+ "assert_equal #{canonical.expected.inspect},"
34
34
  "#{assertion} #{yield}"
35
35
  end
36
36
 
@@ -43,7 +43,7 @@ module Generator
43
43
  # end
44
44
  #
45
45
  def raises_error?
46
- expected.to_i == -1
46
+ canonical.expected.to_i == -1
47
47
  end
48
48
 
49
49
  # generates assertions of the form
@@ -1,6 +1,6 @@
1
1
  class AlphaCase < Generator::ExerciseCase
2
2
  def name
3
- format('test_%s', description.downcase.gsub(/[ -]/, '_'))
3
+ format('test_%s', canonical.description.downcase.gsub(/[ -]/, '_'))
4
4
  end
5
5
 
6
6
  def workload
@@ -16,14 +16,35 @@ module Generator
16
16
  ).cases(canonical_data)
17
17
 
18
18
  expected = [
19
- ComplexCase.new(description: 'first generic verse', property: 'verse', number: 99,
20
- expected: '99 bottles of beer on the wall, YAAAR'),
21
- ComplexCase.new(description: 'last generic verse', property: 'verse', number: 3,
22
- expected: '3 bottles of beer on the wall, YAAAR'),
23
- ComplexCase.new(description: 'first two verses', property: 'verses', beginning: 99, end: 98,
24
- expected: "99 bottles of beer on the wall, YAR, PIRATES CAN'T COUNT")
19
+ ComplexCase.new(
20
+ canonical: {
21
+ 'description' => 'first generic verse',
22
+ 'property' => 'verse',
23
+ 'number' => 99,
24
+ 'expected' => '99 bottles of beer on the wall, YAAAR'
25
+ }
26
+ ),
27
+ ComplexCase.new(
28
+ canonical: {
29
+ 'description' => 'last generic verse',
30
+ 'property' => 'verse',
31
+ 'number' => 3,
32
+ 'expected' => '3 bottles of beer on the wall, YAAAR'
33
+ }
34
+ ),
35
+ ComplexCase.new(
36
+ canonical: {
37
+ 'description' => 'first two verses',
38
+ 'property' => 'verses',
39
+ 'beginning' => 99,
40
+ 'end' => 98,
41
+ 'expected' => "99 bottles of beer on the wall, YAR, PIRATES CAN'T COUNT"
42
+ }
43
+ )
25
44
  ]
26
- assert_equal expected, cases
45
+ assert expected.zip(cases).all? do |exp, cs|
46
+ assert_equal exp.canonical, cs.canonical
47
+ end
27
48
  end
28
49
  end
29
50
  end