trackler 2.1.0.18 → 2.1.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +4 -4
  2. data/common/bin/transfer_blurb_to_description.rb +56 -0
  3. data/common/exercises/accumulate/description.md +2 -0
  4. data/common/exercises/acronym/canonical-data.json +1 -7
  5. data/common/exercises/acronym/description.md +2 -0
  6. data/common/exercises/all-your-base/description.md +2 -0
  7. data/common/exercises/allergies/description.md +2 -0
  8. data/common/exercises/alphametics/description.md +2 -0
  9. data/common/exercises/anagram/description.md +2 -0
  10. data/common/exercises/atbash-cipher/description.md +2 -0
  11. data/common/exercises/bank-account/description.md +2 -0
  12. data/common/exercises/beer-song/description.md +2 -0
  13. data/common/exercises/binary/description.md +2 -0
  14. data/common/exercises/binary-search/description.md +2 -0
  15. data/common/exercises/binary-search-tree/description.md +2 -0
  16. data/common/exercises/bob/description.md +2 -0
  17. data/common/exercises/book-store/description.md +2 -0
  18. data/common/exercises/bowling/description.md +2 -0
  19. data/common/exercises/bracket-push/description.md +2 -0
  20. data/common/exercises/change/description.md +2 -0
  21. data/common/exercises/circular-buffer/description.md +2 -0
  22. data/common/exercises/clock/description.md +2 -0
  23. data/common/exercises/connect/description.md +2 -0
  24. data/common/exercises/counter/description.md +2 -0
  25. data/common/exercises/crypto-square/description.md +2 -0
  26. data/common/exercises/custom-set/description.md +2 -0
  27. data/common/exercises/diamond/description.md +2 -0
  28. data/common/exercises/difference-of-squares/description.md +2 -0
  29. data/common/exercises/diffie-hellman/description.md +2 -0
  30. data/common/exercises/dominoes/description.md +2 -0
  31. data/common/exercises/dot-dsl/description.md +2 -0
  32. data/common/exercises/error-handling/description.md +2 -0
  33. data/common/exercises/etl/description.md +2 -0
  34. data/common/exercises/flatten-array/description.md +2 -0
  35. data/common/exercises/food-chain/description.md +2 -0
  36. data/common/exercises/forth/description.md +2 -0
  37. data/common/exercises/gigasecond/description.md +2 -0
  38. data/common/exercises/go-counting/description.md +2 -0
  39. data/common/exercises/grade-school/description.md +2 -0
  40. data/common/exercises/grains/description.md +2 -0
  41. data/common/exercises/grep/description.md +2 -0
  42. data/common/exercises/hamming/description.md +2 -0
  43. data/common/exercises/hangman/description.md +2 -0
  44. data/common/exercises/hello-world/description.md +2 -0
  45. data/common/exercises/hexadecimal/description.md +2 -0
  46. data/common/exercises/house/description.md +2 -0
  47. data/common/exercises/isogram/description.md +2 -0
  48. data/common/exercises/kindergarten-garden/description.md +2 -0
  49. data/common/exercises/largest-series-product/description.md +2 -0
  50. data/common/exercises/leap/description.md +2 -0
  51. data/common/exercises/ledger/description.md +2 -0
  52. data/common/exercises/lens-person/description.md +2 -0
  53. data/common/exercises/linked-list/description.md +2 -0
  54. data/common/exercises/list-ops/description.md +2 -0
  55. data/common/exercises/luhn/description.md +2 -0
  56. data/common/exercises/markdown/description.md +2 -0
  57. data/common/exercises/matrix/description.md +2 -0
  58. data/common/exercises/meetup/description.md +2 -0
  59. data/common/exercises/minesweeper/description.md +2 -0
  60. data/common/exercises/nth-prime/description.md +2 -0
  61. data/common/exercises/nucleotide-codons/description.md +2 -0
  62. data/common/exercises/nucleotide-count/description.md +2 -0
  63. data/common/exercises/ocr-numbers/description.md +2 -0
  64. data/common/exercises/octal/description.md +2 -0
  65. data/common/exercises/paasio/description.md +2 -0
  66. data/common/exercises/palindrome-products/description.md +2 -0
  67. data/common/exercises/parallel-letter-frequency/description.md +2 -0
  68. data/common/exercises/pascals-triangle/description.md +2 -0
  69. data/common/exercises/perfect-numbers/description.md +2 -0
  70. data/common/exercises/phone-number/description.md +2 -0
  71. data/common/exercises/pig-latin/description.md +2 -0
  72. data/common/exercises/point-mutations/description.md +2 -0
  73. data/common/exercises/poker/canonical-data.json +317 -0
  74. data/common/exercises/poker/description.md +2 -0
  75. data/common/exercises/pov/description.md +2 -0
  76. data/common/exercises/prime-factors/description.md +2 -0
  77. data/common/exercises/protein-translation/description.md +2 -0
  78. data/common/exercises/proverb/description.md +2 -0
  79. data/common/exercises/pythagorean-triplet/description.md +2 -0
  80. data/common/exercises/queen-attack/description.md +2 -0
  81. data/common/exercises/rail-fence-cipher/description.md +2 -0
  82. data/common/exercises/raindrops/description.md +2 -0
  83. data/common/exercises/react/description.md +2 -0
  84. data/common/exercises/rectangles/description.md +2 -0
  85. data/common/exercises/rna-transcription/description.md +2 -0
  86. data/common/exercises/robot-name/description.md +2 -0
  87. data/common/exercises/robot-simulator/description.md +2 -0
  88. data/common/exercises/roman-numerals/description.md +2 -0
  89. data/common/exercises/rotational-cipher/description.md +2 -0
  90. data/common/exercises/run-length-encoding/description.md +2 -0
  91. data/common/exercises/saddle-points/description.md +2 -0
  92. data/common/exercises/say/description.md +2 -0
  93. data/common/exercises/scale-generator/description.md +2 -0
  94. data/common/exercises/scrabble-score/description.md +2 -0
  95. data/common/exercises/secret-handshake/description.md +2 -0
  96. data/common/exercises/series/description.md +2 -0
  97. data/common/exercises/sgf-parsing/description.md +2 -0
  98. data/common/exercises/sieve/description.md +2 -0
  99. data/common/exercises/simple-cipher/description.md +2 -0
  100. data/common/exercises/simple-linked-list/description.md +2 -0
  101. data/common/exercises/space-age/description.md +2 -0
  102. data/common/exercises/strain/description.md +2 -0
  103. data/common/exercises/sublist/description.md +2 -0
  104. data/common/exercises/sum-of-multiples/description.md +2 -0
  105. data/common/exercises/transpose/description.md +2 -0
  106. data/common/exercises/tree-building/description.md +2 -0
  107. data/common/exercises/triangle/description.md +2 -0
  108. data/common/exercises/trinary/description.md +2 -0
  109. data/common/exercises/twelve-days/description.md +2 -0
  110. data/common/exercises/two-bucket/description.md +2 -0
  111. data/common/exercises/variable-length-quantity/description.md +2 -0
  112. data/common/exercises/word-count/description.md +2 -0
  113. data/common/exercises/word-search/description.md +2 -0
  114. data/common/exercises/wordy/description.md +2 -0
  115. data/common/exercises/zebra-puzzle/description.md +2 -0
  116. data/common/exercises/zipper/description.md +2 -0
  117. data/fixtures/tracks/fake/{hello-world → exercises/hello-world}/example.ext +0 -0
  118. data/fixtures/tracks/fake/{hello-world → exercises/hello-world}/hello_test.ext +0 -0
  119. data/fixtures/tracks/fake/{hello-world → exercises/hello-world}/world_test.ext +0 -0
  120. data/fixtures/tracks/fake/{one → exercises/one}/.dot +0 -0
  121. data/fixtures/tracks/fake/{one → exercises/one}/Fakefile +0 -0
  122. data/fixtures/tracks/fake/{one → exercises/one}/HINTS.md +0 -0
  123. data/fixtures/tracks/fake/{one → exercises/one}/example.ext +0 -0
  124. data/fixtures/tracks/fake/{one → exercises/one}/one_test.ext +0 -0
  125. data/fixtures/tracks/fake/{one → exercises/one}/sub/src/ExampleFile.ext +0 -0
  126. data/fixtures/tracks/fake/{one → exercises/one}/sub/src/stubfile.ext +0 -0
  127. data/fixtures/tracks/fake/{three → exercises/three}/example.ext +0 -0
  128. data/fixtures/tracks/fake/{three → exercises/three}/three_test.ext +0 -0
  129. data/fixtures/tracks/fake/{two → exercises/two}/example.ext +0 -0
  130. data/fixtures/tracks/fake/{two → exercises/two}/two_test.ext +0 -0
  131. data/lib/trackler/implementation.rb +29 -35
  132. data/lib/trackler/implementations.rb +7 -1
  133. data/lib/trackler/track.rb +4 -3
  134. data/lib/trackler/version.rb +1 -1
  135. data/lib/trackler.rb +1 -1
  136. data/tracks/ecmascript/.github/stale.yml +6 -0
  137. data/tracks/ecmascript/README.md +17 -9
  138. data/tracks/go/README.md +7 -4
  139. data/tracks/go/config.json +5 -2
  140. data/tracks/go/exercises/atbash-cipher/.meta/gen.go +0 -2
  141. data/tracks/go/exercises/bob/.meta/gen.go +0 -2
  142. data/tracks/go/exercises/bowling/.meta/gen.go +0 -2
  143. data/tracks/go/exercises/bracket-push/.meta/gen.go +0 -2
  144. data/tracks/go/exercises/change/.meta/gen.go +0 -2
  145. data/tracks/go/exercises/clock/.meta/gen.go +0 -2
  146. data/tracks/go/exercises/clock/example_clock_test.go +34 -20
  147. data/tracks/go/exercises/connect/.meta/gen.go +0 -2
  148. data/tracks/go/exercises/custom-set/.meta/gen.go +0 -2
  149. data/tracks/go/exercises/forth/.meta/gen.go +0 -2
  150. data/tracks/go/exercises/gigasecond/.meta/gen.go +0 -2
  151. data/tracks/go/exercises/hamming/.meta/gen.go +0 -2
  152. data/tracks/go/exercises/largest-series-product/.meta/gen.go +0 -2
  153. data/tracks/go/exercises/leap/.meta/gen.go +0 -2
  154. data/tracks/go/exercises/luhn/.meta/gen.go +0 -2
  155. data/tracks/go/exercises/meetup/.meta/gen.go +0 -2
  156. data/tracks/go/exercises/phone-number/.meta/gen.go +0 -2
  157. data/tracks/go/exercises/raindrops/.meta/gen.go +0 -2
  158. data/tracks/go/exercises/rna-transcription/.meta/gen.go +0 -2
  159. data/tracks/go/exercises/roman-numerals/.meta/gen.go +0 -2
  160. data/tracks/go/exercises/scrabble-score/.meta/gen.go +0 -2
  161. data/tracks/go/exercises/transpose/.meta/gen.go +0 -2
  162. data/tracks/go/exercises/variable-length-quantity/.meta/gen.go +113 -0
  163. data/tracks/go/exercises/variable-length-quantity/cases_test.go +161 -0
  164. data/tracks/go/exercises/variable-length-quantity/example.go +54 -11
  165. data/tracks/go/exercises/variable-length-quantity/variable_length_quantity_test.go +19 -31
  166. data/tracks/go/exercises/word-count/.meta/gen.go +0 -2
  167. data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +3 -16
  168. data/tracks/java/exercises/diamond/src/test/java/DiamondPrinterTest.java +1 -1
  169. data/tracks/java/exercises/hello-world/HINT.md +7 -0
  170. data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +1 -1
  171. data/tracks/java/exercises/linked-list/src/test/java/DoublyLinkedListTest.java +48 -38
  172. data/tracks/java/exercises/luhn/src/main/java/LuhnValidator.java +7 -0
  173. data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +1 -1
  174. data/tracks/java/exercises/perfect-numbers/src/test/java/NaturalNumberTest.java +1 -1
  175. data/tracks/java/exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java +1 -1
  176. data/tracks/java/exercises/rectangles/src/test/java/RectangleCounterTest.java +1 -1
  177. data/tracks/java/exercises/secret-handshake/src/main/java/HandshakeCalculator.java +5 -1
  178. data/tracks/java/exercises/sum-of-multiples/src/main/java/SumOfMultiples.java +10 -2
  179. data/tracks/java/exercises/triangle/src/example/java/Triangle.java +5 -5
  180. data/tracks/java/exercises/triangle/src/example/java/TriangleException.java +1 -3
  181. data/tracks/java/exercises/triangle/src/main/java/Triangle.java +11 -0
  182. data/tracks/java/exercises/triangle/src/main/java/TriangleException.java +1 -3
  183. data/tracks/javascript/.github/stale.yml +6 -0
  184. data/tracks/javascript/config.json +14 -0
  185. data/tracks/kotlin/docs/INSTALLATION.md +1 -1
  186. data/tracks/lisp/docs/INSTALLATION.md +1 -0
  187. data/tracks/perl6/README.md +9 -4
  188. data/tracks/perl6/config.json +5 -0
  189. data/tracks/perl6/exercises/luhn/Example.pm6 +15 -0
  190. data/tracks/perl6/exercises/luhn/Luhn.pm6 +4 -0
  191. data/tracks/perl6/exercises/luhn/example.yaml +6 -0
  192. data/tracks/perl6/exercises/luhn/luhn.t +122 -0
  193. data/tracks/python/exercises/acronym/acronym_test.py +1 -4
  194. data/tracks/r/exercises/hamming/test_hamming.R +15 -14
  195. data/tracks/ruby/lib/generator/command_line/generator_optparser.rb +3 -1
  196. data/tracks/ruby/lib/generator/exercise_case/assertion.rb +33 -5
  197. data/tracks/ruby/lib/generator/exercise_case/case_helpers.rb +39 -0
  198. data/tracks/ruby/lib/generator/exercise_case.rb +3 -37
  199. data/tracks/ruby/lib/generator/template_values.rb +2 -0
  200. data/tracks/ruby/test/generator/command_line/generator_optparser_test.rb +11 -2
  201. data/tracks/ruby/test/generator/exercise_case/case_helpers_test.rb +43 -0
  202. data/tracks/ruby/test/generator/underscore_test.rb +4 -0
  203. data/tracks/scala/config.json +10 -0
  204. data/tracks/scala/exercises/beer-song/build.sbt +3 -0
  205. data/tracks/scala/exercises/beer-song/example.scala +11 -0
  206. data/tracks/{java/exercises/luhn/src/main/java → scala/exercises/beer-song/src/main/scala}/.keep +0 -0
  207. data/tracks/scala/exercises/beer-song/src/test/scala/BeerSongTest.scala +52 -0
  208. data/tracks/vimscript/.travis.yml +13 -2
  209. data/tracks/vimscript/TRACK_HINTS.md +67 -0
  210. data/tracks/vimscript/bin/ci +21 -0
  211. data/tracks/vimscript/config.json +22 -8
  212. data/tracks/vimscript/docs/ABOUT.md +44 -0
  213. data/tracks/vimscript/docs/INSTALLATION.md +55 -0
  214. data/tracks/vimscript/docs/LEARNING.md +16 -0
  215. data/tracks/vimscript/docs/RESOURCES.md +24 -0
  216. data/tracks/vimscript/docs/TESTS.md +67 -0
  217. data/tracks/vimscript/exercises/bob/bob.vader +63 -0
  218. data/tracks/vimscript/exercises/bob/bob.vim +8 -0
  219. data/tracks/vimscript/exercises/bob/example.vim +23 -0
  220. data/tracks/vimscript/exercises/hamming/example.vim +18 -0
  221. data/tracks/vimscript/exercises/hamming/hamming.vader +20 -0
  222. data/tracks/vimscript/exercises/hamming/hamming.vim +13 -0
  223. data/tracks/vimscript/exercises/hello-world/example.vim +4 -0
  224. data/tracks/vimscript/exercises/hello-world/hello_world.vader +8 -0
  225. data/tracks/vimscript/exercises/hello-world/hello_world.vim +20 -0
  226. data/tracks/vimscript/exercises/leap/example.vim +3 -0
  227. data/tracks/vimscript/exercises/leap/leap.vader +11 -0
  228. data/tracks/vimscript/exercises/leap/leap.vim +9 -0
  229. metadata +47 -18
  230. data/tracks/vimscript/SETUP.md +0 -0
@@ -82,24 +82,37 @@
82
82
  "slug": "hello-world",
83
83
  "difficulty": 1,
84
84
  "topics": [
85
+ "Control-flow (conditionals)",
86
+ "Optional values",
87
+ "Strings",
88
+ "Text formatting"
85
89
  ]
86
90
  },
87
91
  {
88
92
  "slug": "leap",
89
93
  "difficulty": 1,
90
94
  "topics": [
95
+ "Booleans",
96
+ "Integers",
97
+ "Logic"
91
98
  ]
92
99
  },
93
100
  {
94
101
  "slug": "hamming",
95
102
  "difficulty": 1,
96
103
  "topics": [
104
+ "Control-flow (loops)",
105
+ "Control-flow (conditionals)",
106
+ "Equality",
107
+ "Strings"
97
108
  ]
98
109
  },
99
110
  {
100
111
  "slug": "rna-transcription",
101
112
  "difficulty": 1,
102
113
  "topics": [
114
+ "Strings",
115
+ "Transforming"
103
116
  ]
104
117
  },
105
118
  {
@@ -131,6 +144,7 @@
131
144
  "slug": "gigasecond",
132
145
  "difficulty": 1,
133
146
  "topics": [
147
+ "Time"
134
148
  ]
135
149
  },
136
150
  {
@@ -12,7 +12,7 @@ Choose your operating system:
12
12
  * [Linux](#linux)
13
13
 
14
14
  ... or ...
15
- * if you prefer to not use a package maanger, you can [install manually](#install-manually).
15
+ * if you prefer to not use a package manager, you can [install manually](#install-manually).
16
16
 
17
17
  Optionally, you can also use a [Java IDE](#java-ides).
18
18
 
@@ -20,6 +20,7 @@ curl -O http://beta.quicklisp.org/quicklisp.lisp
20
20
  Now launch lisp, and copy-paste the following expressions to finish QuickLisp installation:
21
21
 
22
22
  ```lisp
23
+ > (load "quicklisp.lisp") ;; this will load the downloaded lisp file
23
24
  > (quicklisp-quickstart:install) ;; this will install quicklisp
24
25
  > (ql:add-to-init-file) ;; this will add quicklisp setup to your init file (recommended)
25
26
  ```
@@ -4,6 +4,15 @@
4
4
 
5
5
  Exercism exercises in Perl 6
6
6
 
7
+ ## Contributing Guide
8
+
9
+ Please see the [contributing guide](https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md).
10
+
11
+ ## Code of Conduct
12
+
13
+ Help us keep Exercism welcoming. Please read and abide by the
14
+ [Code of Conduct](https://github.com/exercism/exercism.io/blob/master/CODE_OF_CONDUCT.md).
15
+
7
16
  ## Adding and Updating Exercises
8
17
 
9
18
  Please use `exercise-gen.pl6` in the `bin/` directory when either adding or updating an exercise.
@@ -16,10 +25,6 @@ When adding a new exercise, ensure that the exercise is included in the `exercis
16
25
  Set `EXERCISM` as an environment variable (e.g. `export EXERCISM=1` in bash), and run either `prove -re perl6`
17
26
  to run all tests in all subdirectories, or `prove -e perl6 /path/to/test.t` to run an individual test file.
18
27
 
19
- ## Contributing Guide
20
-
21
- Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data)
22
-
23
28
  ## License
24
29
 
25
30
  The MIT License (MIT)
@@ -64,6 +64,11 @@
64
64
  "slug": "scrabble-score",
65
65
  "topics": []
66
66
  },
67
+ {
68
+ "difficulty": 1,
69
+ "slug": "luhn",
70
+ "topics": []
71
+ },
67
72
  {
68
73
  "difficulty": 1,
69
74
  "slug": "word-count",
@@ -0,0 +1,15 @@
1
+ unit module Luhn:ver<1>;
2
+
3
+ sub is-luhn-valid ($input is copy) is export {
4
+ $input ~~ s:g/\s+//;
5
+ return False if $input.chars < 2 || $input ~~ /\D/;
6
+ my @num = $input.split('', :skip-empty);
7
+ @num.unshift: 0 if @num % 2;
8
+ my $sum;
9
+ for @num -> $a, $b {
10
+ $sum += $a * 2;
11
+ $sum -= 9 if $a * 2 > 9;
12
+ $sum += $b;
13
+ }
14
+ return ($sum %% 10).so;
15
+ }
@@ -0,0 +1,4 @@
1
+ unit module Luhn:ver<1>;
2
+
3
+ sub is-luhn-valid ($input) is export {
4
+ }
@@ -0,0 +1,6 @@
1
+ exercise: Luhn
2
+ version: 1
3
+ plan: 15
4
+ imports: '&is-luhn-valid'
5
+ tests: |
6
+ is .<input>.&is-luhn-valid, |.<expected description> for @($c-data<cases>);
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env perl6
2
+ use v6;
3
+ use Test;
4
+ use lib my $dir = $?FILE.IO.dirname;
5
+ use JSON::Tiny;
6
+
7
+ my $exercise = 'Luhn';
8
+ my $version = v1;
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
10
+ plan 15;
11
+
12
+ use-ok $module or bail-out;
13
+ require ::($module);
14
+
15
+ if ::($exercise).^ver !~~ $version {
16
+ warn "\nExercise version mismatch. Further tests may fail!"
17
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
18
+ ~ "Test is $($version.gist).\n";
19
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
20
+ }
21
+
22
+ require ::($module) <&is-luhn-valid>;
23
+
24
+ my $c-data;
25
+ is .<input>.&is-luhn-valid, |.<expected description> for @($c-data<cases>);
26
+
27
+ if %*ENV<EXERCISM> && (my $c-data-file =
28
+ "$dir/../../x-common/exercises/{$dir.IO.resolve.basename}/canonical-data.json".IO.resolve) ~~ :f
29
+ { is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data' } else { skip }
30
+
31
+ done-testing;
32
+
33
+ INIT {
34
+ $c-data := from-json q:to/END/;
35
+
36
+ {
37
+ "exercise": "luhn",
38
+ "version": "1.0.0",
39
+ "cases": [
40
+ {
41
+ "description": "single digit strings can not be valid",
42
+ "property": "valid",
43
+ "input": "1",
44
+ "expected": false
45
+ },
46
+ {
47
+ "description": "A single zero is invalid",
48
+ "property": "valid",
49
+ "input": "0",
50
+ "expected": false
51
+ },
52
+ {
53
+ "description": "a simple valid SIN that remains valid if reversed",
54
+ "property": "valid",
55
+ "input": "059",
56
+ "expected": true
57
+ },
58
+ {
59
+ "description": "a simple valid SIN that becomes invalid if reversed",
60
+ "property": "valid",
61
+ "input": "59",
62
+ "expected": true
63
+ },
64
+ {
65
+ "description": "a valid Canadian SIN",
66
+ "property": "valid",
67
+ "input": "055 444 285",
68
+ "expected": true
69
+ },
70
+ {
71
+ "description": "invalid Canadian SIN",
72
+ "property": "valid",
73
+ "input": "055 444 286",
74
+ "expected": false
75
+ },
76
+ {
77
+ "description": "invalid credit card",
78
+ "property": "valid",
79
+ "input": "8273 1232 7352 0569",
80
+ "expected": false
81
+ },
82
+ {
83
+ "description": "valid strings with a non-digit included become invalid",
84
+ "property": "valid",
85
+ "input": "055a 444 285",
86
+ "expected": false
87
+ },
88
+ {
89
+ "description": "valid strings with punctuation included become invalid",
90
+ "property": "valid",
91
+ "input": "055-444-285",
92
+ "expected": false
93
+ },
94
+ {
95
+ "description": "valid strings with symbols included become invalid",
96
+ "property": "valid",
97
+ "input": "055£ 444$ 285",
98
+ "expected": false
99
+ },
100
+ {
101
+ "description": "single zero with space is invalid",
102
+ "property": "valid",
103
+ "input": " 0",
104
+ "expected": false
105
+ },
106
+ {
107
+ "description": "more than a single zero is valid",
108
+ "property": "valid",
109
+ "input": "0000 0",
110
+ "expected": true
111
+ },
112
+ {
113
+ "description": "input digit 9 is correctly converted to output digit 9",
114
+ "property": "valid",
115
+ "input": "091",
116
+ "expected": true
117
+ }
118
+ ]
119
+ }
120
+
121
+ END
122
+ }
@@ -3,7 +3,7 @@ import unittest
3
3
  from acronym import abbreviate
4
4
 
5
5
 
6
- # test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
6
+ # test cases adapted from `x-common//canonical-data.json` @ version: 1.1.0
7
7
 
8
8
  class AcronymTest(unittest.TestCase):
9
9
  def test_basic(self):
@@ -12,9 +12,6 @@ class AcronymTest(unittest.TestCase):
12
12
  def test_lowercase_words(self):
13
13
  self.assertEqual(abbreviate('Ruby on Rails'), 'ROR')
14
14
 
15
- def test_camelcase(self):
16
- self.assertEqual(abbreviate('HyperText Markup Language'), 'HTML')
17
-
18
15
  def test_punctuation(self):
19
16
  self.assertEqual(abbreviate('First In, First Out'), 'FIFO')
20
17
 
@@ -2,86 +2,87 @@ source('./hamming.R')
2
2
  library(testthat)
3
3
 
4
4
  test_that("identical strands", {
5
- strand1 <-"A"
5
+ strand1 <- "A"
6
6
  strand2 <- "A"
7
7
  expect_equal(hamming(strand1, strand2), 0)
8
8
  })
9
9
 
10
10
  test_that("long identical strands", {
11
- strand1 <-"GGACTGA"
11
+ strand1 <- "GGACTGA"
12
12
  strand2 <- "GGACTGA"
13
13
  expect_equal(hamming(strand1, strand2), 0)
14
14
  })
15
15
 
16
16
  test_that("complete distance in single nucleotide strands", {
17
- strand1 <-"A"
17
+ strand1 <- "A"
18
18
  strand2 <- "G"
19
19
  expect_equal(hamming(strand1, strand2), 1)
20
20
  })
21
21
 
22
22
  test_that("complete distance in small strands", {
23
- strand1 <-"AG"
23
+ strand1 <- "AG"
24
24
  strand2 <- "CT"
25
25
  expect_equal(hamming(strand1, strand2), 2)
26
26
  })
27
27
 
28
28
  test_that("small distance in small strands", {
29
- strand1 <-"AT"
29
+ strand1 <- "AT"
30
30
  strand2 <- "CT"
31
31
  expect_equal(hamming(strand1, strand2), 1)
32
32
  })
33
33
 
34
34
  test_that("small distance", {
35
- strand1 <-"GGACG"
35
+ strand1 <- "GGACG"
36
36
  strand2 <- "GGTCG"
37
37
  expect_equal(hamming(strand1, strand2), 1)
38
38
  })
39
39
 
40
40
  test_that("small distance in long strands", {
41
- strand1 <-"ACCAGGG"
41
+ strand1 <- "ACCAGGG"
42
42
  strand2 <- "ACTATGG"
43
43
  expect_equal(hamming(strand1, strand2), 2)
44
44
  })
45
45
 
46
46
  test_that("non-unique character in first strand", {
47
- strand1 <-"AGA"
47
+ strand1 <- "AGA"
48
48
  strand2 <- "AGG"
49
49
  expect_equal(hamming(strand1, strand2), 1)
50
50
  })
51
51
 
52
52
  test_that("non-unique character in second strand", {
53
- strand1 <-"AGG"
53
+ strand1 <- "AGG"
54
54
  strand2 <- "AGA"
55
55
  expect_equal(hamming(strand1, strand2), 1)
56
56
  })
57
57
 
58
58
  test_that("same nucleotides in different positions", {
59
- strand1 <-"TAG"
59
+ strand1 <- "TAG"
60
60
  strand2 <- "GAT"
61
61
  expect_equal(hamming(strand1, strand2), 2)
62
62
  })
63
63
 
64
64
  test_that("large distance", {
65
- strand1 <-"GATACA"
65
+ strand1 <- "GATACA"
66
66
  strand2 <- "GCATAA"
67
67
  expect_equal(hamming(strand1, strand2), 4)
68
68
  })
69
69
 
70
70
  test_that("empty strands", {
71
- strand1 <-""
71
+ strand1 <- ""
72
72
  strand2 <- ""
73
73
  expect_equal(hamming(strand1, strand2), 0)
74
74
  })
75
75
 
76
76
  test_that("disallow first strand longer", {
77
- strand1 <-"AATG"
77
+ strand1 <- "AATG"
78
78
  strand2 <- "AAA"
79
79
  expect_error(hamming(strand1, strand2))
80
80
  })
81
81
 
82
82
  test_that("disallow second strand longer", {
83
- strand1 <-"ATA"
83
+ strand1 <- "ATA"
84
84
  strand2 <- "AGTG"
85
85
  expect_error(hamming(strand1, strand2))
86
86
  })
87
87
 
88
+ print("All tests passed!")
@@ -83,7 +83,9 @@ module Generator
83
83
 
84
84
  def validate_cases
85
85
  return true if available_generators.include?(options[:slug])
86
- $stderr.puts "A generator does not currently exist for #{options[:slug]}!"
86
+ warning = "A generator does not currently exist for #{options[:slug]}!"
87
+ expected_location = "Expecting it to be at: #{Files::GeneratorCases.source_filepath(@paths.track, options[:slug])}"
88
+ $stderr.puts [warning, expected_location].join("\n")
87
89
  false
88
90
  end
89
91
  end
@@ -1,31 +1,59 @@
1
1
  module Generator
2
- class ExerciseCase < OpenStruct
2
+ class ExerciseCase
3
3
  module Assertion
4
4
 
5
+ # generates assertions of the form
6
+ #
7
+ # assert whatever
8
+ # refute whatever
9
+ #
10
+ # depending on whether 'expected' is true or false
11
+ #
12
+ # call as
13
+ #
5
14
  # "#{assert} Luhn.valid?(#{input.inspect})"
15
+ #
6
16
  def assert
7
17
  expected ? 'assert' : 'refute'
8
18
  end
9
19
 
10
- # e.g.,
20
+ # generates assertions of the form
21
+ #
22
+ # assert_nil whatever
23
+ # assert_equal expected, whatever
24
+ #
25
+ # depending on whether 'expected' is nil or not
26
+ #
27
+ # call as
28
+ #
11
29
  # assert_equal { "PigLatin.translate(#{input.inspect})" }
30
+ #
12
31
  def assert_equal
13
- assertion = expected.nil? ? 'assert_nil' : "assert_equal #{expected.inspect},"
32
+ assertion = expected.nil? ? 'assert_nil' :
33
+ "assert_equal #{expected.inspect},"
14
34
  "#{assertion} #{yield}"
15
35
  end
16
36
 
17
- # e.g.,
37
+ # a helper function, used to build statements such as
38
+ #
18
39
  # if raises_error?
19
40
  # assert_raises(ArgumentError) { test_case }
20
41
  # else
21
42
  # assert_equal { test_case }
22
43
  # end
44
+ #
23
45
  def raises_error?
24
46
  expected.to_i == -1
25
47
  end
26
48
 
27
- # e.g.,
49
+ # generates assertions of the form
50
+ #
51
+ # assert_raises(SomeError) { whatever }
52
+ #
53
+ # call as
54
+ #
28
55
  # assert_raises(ArgumentError) { test_case }
56
+ #
29
57
  def assert_raises(error)
30
58
  "assert_raises(#{error}) { #{yield} }"
31
59
  end
@@ -0,0 +1,39 @@
1
+ module Generator
2
+ class ExerciseCase
3
+ module CaseHelpers
4
+ protected
5
+
6
+ # indent multi line workloads
7
+ #
8
+ # indent_lines(
9
+ # [
10
+ # "string = #{input.inspect}",
11
+ # "#{assert} Isogram.is_isogram?(string)"
12
+ # ], 4
13
+ # )
14
+ def indent_lines(code, depth, separator = "\n")
15
+ code.join(separator + ' ' * depth)
16
+ end
17
+
18
+ # indent multi line workloads with (unindented) blank lines
19
+ #
20
+ # indent_text(4, text)
21
+ def indent_text(depth, text)
22
+ text.lines.reduce do |obj, line|
23
+ obj << (line == "\n" ? line : ' ' * depth + line)
24
+ end
25
+ end
26
+
27
+ # generate heredoc (as part of workload) with optional indentation
28
+ #
29
+ # indent_heredoc(["foo", "bar"], 'TEXT', 1)
30
+ def indent_heredoc(lines, delimiter, depth = 0, delimiter_method = nil)
31
+ [
32
+ "<<-#{delimiter}#{delimiter_method}",
33
+ lines.map { |line| ' ' * depth + line }.join("\n"),
34
+ delimiter
35
+ ].join("\n")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,51 +1,17 @@
1
1
  require 'ostruct'
2
- require 'json'
3
2
 
4
3
  module Generator
5
4
  class ExerciseCase < OpenStruct
6
5
  using Generator::Underscore
6
+ include CaseHelpers
7
7
  include Assertion
8
8
 
9
9
  def name
10
10
  'test_%s' % description.underscore
11
11
  end
12
12
 
13
- def skipped(idx)
14
- idx.zero? ? '# skip' : 'skip'
15
- end
16
-
17
- protected
18
-
19
- # indent multi line workloads
20
- #
21
- # indent_lines(
22
- # [
23
- # "string = #{input.inspect}",
24
- # "#{assert} Isogram.is_isogram?(string)"
25
- # ], 4
26
- # )
27
- def indent_lines(code, depth, separator = "\n")
28
- code.join(separator + ' ' * depth)
29
- end
30
-
31
- # indent multi line workloads with (unindented) blank lines
32
- #
33
- # indent_text(4, text)
34
- def indent_text(depth, text)
35
- text.lines.reduce do |obj, line|
36
- obj << (line == "\n" ? line : ' ' * depth + line)
37
- end
38
- end
39
-
40
- # generate heredoc (as part of workload) with optional indentation
41
- #
42
- # indent_heredoc(["foo", "bar"], 'TEXT', 1)
43
- def indent_heredoc(lines, delimiter, depth = 0, delimiter_method = nil)
44
- [
45
- "<<-#{delimiter}#{delimiter_method}",
46
- lines.map { |line| ' ' * depth + line }.join("\n"),
47
- delimiter
48
- ].join("\n")
13
+ def skipped(index)
14
+ index.zero? ? '# skip' : 'skip'
49
15
  end
50
16
  end
51
17
  end
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module Generator
2
4
  # Contains methods accessible to the ERB template
3
5
  class TemplateValues
@@ -111,9 +111,18 @@ module Generator
111
111
  end
112
112
 
113
113
  def test_validate_missing_generator
114
- args = %w(nonexistent)
114
+ args = %w(non-existent)
115
115
  Files::GeneratorCases.stub :available, [] do
116
- assert_output(nil, /A generator does not currently exist fo/) do
116
+ assert_output(nil, /A generator does not currently exist for non-existent/) do
117
+ refute GeneratorOptparser.new(args, FixturePaths).options_valid?
118
+ end
119
+ end
120
+ end
121
+
122
+ def test_missing_generator_tells_you_where_it_looked
123
+ args = %w(non-existent)
124
+ Files::GeneratorCases.stub :available, [] do
125
+ assert_output(nil, %r{exercises/non-existent/\.meta/generator/non_existent_case\.rb}) do
117
126
  refute GeneratorOptparser.new(args, FixturePaths).options_valid?
118
127
  end
119
128
  end
@@ -0,0 +1,43 @@
1
+ require_relative '../../test_helper'
2
+
3
+ module Generator
4
+ class ExerciseCase
5
+ class CaseHelpersTest < Minitest::Test
6
+ class MultiLineCase
7
+ include CaseHelpers
8
+
9
+ def workload
10
+ indent_lines(['foo', 'bar'], 1)
11
+ end
12
+ end
13
+ def test_indent_multiline_workloads
14
+ expected = "foo\n bar"
15
+ assert_equal expected, MultiLineCase.new.workload
16
+ end
17
+
18
+ class BlankLineCase
19
+ include CaseHelpers
20
+
21
+ def workload
22
+ indent_text(2, "foo\n\nbar\n")
23
+ end
24
+ end
25
+ def test_indent_multiline_workloads_with_blank_lines
26
+ expected = "foo\n\n bar\n"
27
+ assert_equal expected, BlankLineCase.new.workload
28
+ end
29
+
30
+ class HeredocCase
31
+ include CaseHelpers
32
+
33
+ def workload
34
+ indent_heredoc(["foo", "bar"], 'TEXT', 1)
35
+ end
36
+ end
37
+ def test_heredoc
38
+ expected = "<<-TEXT\n foo\n bar\nTEXT"
39
+ assert_equal expected, HeredocCase.new.workload
40
+ end
41
+ end
42
+ end
43
+ end
@@ -19,5 +19,9 @@ module Generator
19
19
  'unreadable_but_correctly_sized_inputs_return_?'
20
20
  )
21
21
  end
22
+
23
+ def test_fixnum_underscore
24
+ assert_equal '1_000_000', 1000000.underscore
25
+ end
22
26
  end
23
27
  end
@@ -245,6 +245,16 @@
245
245
  "Sequences"
246
246
  ]
247
247
  },
248
+ {
249
+ "slug": "beer-song",
250
+ "difficulty": 3,
251
+ "topics": [
252
+ "Text formatting",
253
+ "Algorithms",
254
+ "Control-flow",
255
+ "Strings"
256
+ ]
257
+ },
248
258
  {
249
259
  "slug":"matrix",
250
260
  "difficulty":4,
@@ -0,0 +1,3 @@
1
+ name := "beer-song"
2
+ scalaVersion := "2.12.2"
3
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
@@ -0,0 +1,11 @@
1
+ object Example {
2
+ def verses(upper: Int, lower: Int): String =
3
+ upper to lower by -1 map verse mkString "\n"
4
+
5
+ def verse(n: Int): String = n match {
6
+ case 0 => "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
7
+ case 1 => "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"
8
+ case 2 => "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"
9
+ case _ => s"$n bottles of beer on the wall, $n bottles of beer.\nTake one down and pass it around, ${n - 1} bottles of beer on the wall.\n"
10
+ }
11
+ }