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
@@ -1,4 +1,5 @@
1
1
  require 'pathname'
2
+ require 'forwardable'
2
3
  require_relative 'file_bundle'
3
4
 
4
5
  module Trackler
@@ -10,14 +11,22 @@ module Trackler
10
11
  "/\.meta/"
11
12
  ]
12
13
 
13
- attr_reader :track, :problem
14
+ extend Forwardable
15
+ def_delegators :@problem, :name, :blurb, :description, :source_markdown, :slug, :source, :metadata, :root, :active?, :deprecated?, :source_url, :description_url, :canonical_data_url, :metadata_url
16
+
14
17
  def initialize(track, problem)
15
18
  @track = track
16
19
  @problem = problem
17
20
  end
18
21
 
19
- def file_bundle
20
- @file_bundle ||= FileBundle.new(implementation_dir, regexes_to_ignore)
22
+ def initialize_copy(original)
23
+ super
24
+ @files = original.files.dup
25
+ end
26
+
27
+ def problem
28
+ warn "DEPRECATION WARNING: The `problem` method is deprecated, Implementation can do everything that Problem can, so call the method directly."
29
+ @problem
21
30
  end
22
31
 
23
32
  def exists?
@@ -63,52 +72,44 @@ module Trackler
63
72
 
64
73
  private
65
74
 
75
+ attr_reader :track
76
+
66
77
  def regexes_to_ignore
67
- (IGNORE_PATTERNS + [@track.ignore_pattern]).map do |pattern|
78
+ (IGNORE_PATTERNS + [track.ignore_pattern]).map do |pattern|
68
79
  Regexp.new(pattern, Regexp::IGNORECASE)
69
80
  end
70
81
  end
71
82
 
83
+ def file_bundle
84
+ @file_bundle ||= FileBundle.new(implementation_dir, regexes_to_ignore)
85
+ end
86
+
72
87
  def implementation_dir
73
88
  @implementation_dir ||= track.dir.join(exercise_dir)
74
89
  end
75
90
 
76
91
  def exercise_dir
77
- if File.exist?(track.dir.join('exercises'))
78
- File.join('exercises', problem.slug)
79
- else
80
- problem.slug
81
- end
92
+ File.join('exercises', slug)
82
93
  end
83
94
 
84
95
  def assemble_readme
85
96
  <<-README
86
- # #{readme_title}
87
-
88
- #{problem.blurb}
97
+ # #{name}
89
98
 
90
99
  #{readme_body}
91
100
 
92
- #{readme_source}
101
+ #{source_markdown}
93
102
 
94
103
  #{incomplete_solutions_body}
95
104
  README
96
105
  end
97
106
 
98
- def readme_title
99
- problem.name
100
- end
101
-
102
107
  def readme_body
103
- [
104
- problem.description,
105
- implementation_hints,
106
- track.hints,
107
- ].reject(&:empty?).join("\n").strip
108
- end
109
-
110
- def readme_source
111
- problem.source_markdown
108
+ [
109
+ description,
110
+ implementation_hints,
111
+ track.hints,
112
+ ].reject(&:empty?).join("\n").strip
112
113
  end
113
114
 
114
115
  def incomplete_solutions_body
@@ -119,15 +120,8 @@ It's possible to submit an incomplete solution so you can see how others have co
119
120
  end
120
121
 
121
122
  def implementation_hints
122
- read File.join(implementation_dir, 'HINTS.md')
123
- end
124
-
125
- def read(f)
126
- if File.exist?(f)
127
- File.read(f)
128
- else
129
- ""
130
- end
123
+ hints_file = File.join(implementation_dir, 'HINTS.md')
124
+ File.exist?(hints_file) ? File.read(hints_file) : ''
131
125
  end
132
126
  end
133
127
  end
@@ -21,6 +21,12 @@ module Trackler
21
21
  by_slug[slug]
22
22
  end
23
23
 
24
+ def length
25
+ all.length
26
+ end
27
+
28
+ alias_method :size, :length
29
+
24
30
  private
25
31
 
26
32
  def all
@@ -38,7 +44,7 @@ module Trackler
38
44
  Implementation.new(track, Problem.new(k, root, track))
39
45
  }
40
46
  all.each do |impl|
41
- hash[impl.problem.slug] = impl
47
+ hash[impl.slug] = impl
42
48
  end
43
49
  hash
44
50
  end
@@ -36,11 +36,11 @@ module Trackler
36
36
  end
37
37
 
38
38
  def upcoming?
39
- !active? && problems.length > 0
39
+ !active? && implementations.length > 0
40
40
  end
41
41
 
42
42
  def planned?
43
- !active? && problems.length.zero?
43
+ !active? && implementations.length.zero?
44
44
  end
45
45
 
46
46
  def implementations
@@ -48,7 +48,8 @@ module Trackler
48
48
  end
49
49
 
50
50
  def problems
51
- @problems ||= implementations.map(&:problem)
51
+ warn "DEPRECATION WARNING: A track only has implementations, call track.implementations instead"
52
+ implementations
52
53
  end
53
54
 
54
55
  def checklist_issue
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.1.0.18"
2
+ VERSION = "2.1.0.19"
3
3
  end
data/lib/trackler.rb CHANGED
@@ -38,7 +38,7 @@ module Trackler
38
38
  @implementations = Hash.new { |h, k| h[k] = [] }
39
39
  tracks.each do |track|
40
40
  track.implementations.each do |implementation|
41
- @implementations[implementation.problem.slug] << implementation
41
+ @implementations[implementation.slug] << implementation
42
42
  end
43
43
  end
44
44
  @implementations
@@ -0,0 +1,6 @@
1
+ # Issues or Pull Requests with these labels will never be considered stale
2
+ exemptLabels:
3
+ - pinned
4
+ - security
5
+ - good first patch
6
+ - first-timers only
@@ -4,24 +4,33 @@
4
4
 
5
5
  Exercism exercises in ECMAScript 6
6
6
 
7
+
7
8
  ## Running the Unit Test Suite
8
9
 
9
- [Node.js](https://nodejs.org) must be installed. We recommend using the latest stable version (v7 at the moment.)
10
+ [Node.js](https://nodejs.org) must be installed. Follow [these instructions](http://exercism.io/languages/ecmascript/installing) for installing nodejs.
11
+ We recommend using the latest stable version (v7 at the moment).
10
12
 
11
- % npm install
13
+ Use `npm` to install all required dependencies:
12
14
 
13
- Then, the `make` command will install other dependencies as needed.
15
+ % npm install
14
16
 
15
- ### Linting Your Code
16
- This project uses [eslint](https://github.com/eslint/eslint) to help you write quality JavaScript code by checking for common formatting errors, enforcing style rules, and suggesting changes that conform to best practices.
17
+ #### Linting Your Code
18
+ This project uses [eslint](https://github.com/eslint/eslint) to help you write quality
19
+ ECMAScript code by checking for common formatting errors, enforcing style rules,
20
+ and suggesting changes that conform to best practices.
17
21
 
18
22
  % npm run lint-test
19
23
 
24
+ #### Test All Assignments
25
+ The make script will test all exercises:
20
26
 
21
- ### All Assignments
22
- The make script will build and test all exercises.
27
+ % make test
28
+
29
+ #### Test Specific Assignment
30
+ Pass the exercise name to make script to run the tests for a specific exercise:
31
+
32
+ % make test-assignment ASSIGNMENT=hello-world
23
33
 
24
- % make
25
34
 
26
35
  ## Contributing Guide
27
36
 
@@ -32,4 +41,3 @@ Please see the [contributing guide](https://github.com/exercism/x-api/blob/maste
32
41
  The MIT License (MIT)
33
42
 
34
43
  Copyright (c) 2014 Katrina Owen, _@kytrinyx.com
35
-
data/tracks/go/README.md CHANGED
@@ -138,10 +138,13 @@ are useful if they let the solver try a change and see a performance effect.
138
138
 
139
139
  ### Testable examples
140
140
 
141
- Some exercises can contain [Example tests](https://blog.golang.org/examples) that document the exercise API. These
142
- examples are run alongside the standard exercise tests and will verify that the
143
- exercise API is working as expected. They are not required by all exercises and
144
- are most useful when clarifying the API of the exercise.
141
+ Some exercises can contain [Example tests](https://blog.golang.org/examples)
142
+ that document the exercise API. These examples are run alongside the standard
143
+ exercise tests and will verify that the exercise API is working as expected.
144
+ They are not required by all exercises and are not intended to replace the
145
+ data-driven tests. They are most useful for providing examples of how an
146
+ exercise's API is used. Have a look at the example tests in the [clock exercise](https://github.com/exercism/xgo/blob/master/exercises/clock/example_clock_test.go)
147
+ to see them in action.
145
148
 
146
149
  ### Stub files
147
150
 
@@ -222,9 +222,12 @@
222
222
  ]
223
223
  },
224
224
  {
225
- "difficulty": 1,
225
+ "difficulty": 5,
226
226
  "slug": "sum-of-multiples",
227
- "topics": []
227
+ "topics": [
228
+ "Control-flow (loops)",
229
+ "Mathematics"
230
+ ]
228
231
  },
229
232
  {
230
233
  "difficulty": 1,
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -2,39 +2,53 @@ package clock
2
2
 
3
3
  import "fmt"
4
4
 
5
- func ExampleClock() {
6
- // Create a clock
5
+ func ExampleClock_new() {
6
+ // a new clock
7
7
  clock1 := New(10, 30)
8
8
  fmt.Println(clock1.String())
9
9
 
10
- // Add 30 minutes to it
11
- clock1 = clock1.Add(30)
12
- fmt.Println(clock1.String())
10
+ // Output: 10:30
11
+ }
13
12
 
14
- // Subtract an hour and a half from it
15
- clock1 = clock1.Add(-90)
16
- fmt.Println(clock1.String())
13
+ func ExampleClock_Add_add() {
14
+ // create a clock
15
+ clock := New(10, 30)
16
+
17
+ // add 30 minutes to it
18
+ clock = clock.Add(30)
19
+ fmt.Println(clock.String())
20
+
21
+ // Output: 11:00
22
+ }
23
+
24
+ func ExampleClock_Add_subtract() {
25
+ // create a clock
26
+ clock := New(10, 30)
27
+
28
+ // subtract an hour and a half from it
29
+ clock = clock.Add(-90)
30
+ fmt.Println(clock.String())
31
+
32
+ // Output: 09:00
33
+ }
34
+
35
+ func ExampleClock_compare() {
36
+ // a new clock
37
+ clock1 := New(10, 30)
17
38
 
18
- // Create a second clock
19
- clock2 := New(9, 30)
20
- fmt.Println(clock2.String())
39
+ // a second clock, same as the first
40
+ clock2 := New(10, 30)
21
41
 
22
- // Are the clocks equal?
42
+ // are the clocks equal?
23
43
  fmt.Println(clock2 == clock1)
24
44
 
25
- // Change the second clock
45
+ // change the second clock
26
46
  clock2 = clock2.Add(30)
27
- fmt.Println(clock2.String())
28
47
 
29
- // Are the clocks equal now?
48
+ // are the clocks equal now?
30
49
  fmt.Println(clock2 == clock1)
31
50
 
32
51
  // Output:
33
- // 10:30
34
- // 11:00
35
- // 09:30
36
- // 09:30
37
52
  // true
38
- // 10:00
39
53
  // false
40
54
  }
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -1,5 +1,3 @@
1
- // +build ignore
2
-
3
1
  package main
4
2
 
5
3
  import (
@@ -0,0 +1,113 @@
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "text/template"
6
+
7
+ "../../../gen"
8
+ )
9
+
10
+ func main() {
11
+ t := template.New("").Funcs(template.FuncMap{
12
+ "GroupComment": GroupComment,
13
+ "byteSlice": byteSlice,
14
+ "lengthSlice": lengthSlice,
15
+ })
16
+ t, err := t.Parse(tmpl)
17
+ if err != nil {
18
+ log.Fatal(err)
19
+ }
20
+ var j js
21
+ if err := gen.Gen("variable-length-quantity", &j, t); err != nil {
22
+ log.Fatal(err)
23
+ }
24
+ }
25
+
26
+ // byteSlice converts a slice of uint32 to a byte slice.
27
+ func byteSlice(ns []uint32) []byte {
28
+ b := make([]byte, len(ns))
29
+ for i, n := range ns {
30
+ b[i] = byte(n)
31
+ }
32
+ return b
33
+ }
34
+
35
+ // lengthSlice returns the length of given slice.
36
+ func lengthSlice(ns []uint32) int {
37
+ return len(ns)
38
+ }
39
+
40
+ // The JSON structure we expect to be able to unmarshal into
41
+ type js struct {
42
+ Groups []TestGroup `json:"Cases"`
43
+ }
44
+
45
+ type TestGroup struct {
46
+ Description string
47
+ Cases []OneCase
48
+ }
49
+
50
+ type OneCase struct {
51
+ Description string
52
+ Property string // "encode" or "decode"
53
+ Input []uint32 // supports both []byte and []uint32 in JSON.
54
+ Expected []uint32 // supports []byte, []uint32, or null in JSON.
55
+ }
56
+
57
+ // PropertyMatch returns true when given test case c has .Property field matching property;
58
+ // this serves as a filter to put test cases with "like" property into the same group.
59
+ func (c OneCase) PropertyMatch(property string) bool { return c.Property == property }
60
+
61
+ // GroupComment looks in each of the test case groups to find the
62
+ // group for which every test case has the .Property matching given property;
63
+ // it returns the .Description field for the matching property group,
64
+ // or a 'Note: ...' if no test group consistently matches given property.
65
+ func GroupComment(groups []TestGroup, property string) string {
66
+ for _, group := range groups {
67
+ propertyGroupMatch := true
68
+ for _, testcase := range group.Cases {
69
+ if !testcase.PropertyMatch(property) {
70
+ propertyGroupMatch = false
71
+ break
72
+ }
73
+ }
74
+ if propertyGroupMatch {
75
+ return group.Description
76
+ }
77
+ }
78
+ return "Note: Apparent inconsistent use of \"property\": \"" + property + "\" within test case group!"
79
+ }
80
+
81
+ // template applied to above data structure generates the Go test cases
82
+ var tmpl = `package variablelengthquantity
83
+
84
+ {{.Header}}
85
+
86
+ // {{GroupComment .J.Groups "encode"}}
87
+ var encodeTestCases = []struct {
88
+ description string
89
+ input []uint32
90
+ output []byte
91
+ }{ {{range .J.Groups}} {{range .Cases}}
92
+ {{if .PropertyMatch "encode"}} {
93
+ {{printf "%q" .Description}},
94
+ {{printf "%#v" .Input }},
95
+ {{byteSlice .Expected | printf "%#v" }},
96
+ },{{- end}}{{end}}{{end}}
97
+ }
98
+
99
+ // {{GroupComment .J.Groups "decode"}}
100
+ var decodeTestCases = []struct {
101
+ description string
102
+ input []byte
103
+ output []uint32 // nil slice indicates error expected.
104
+ size int
105
+ }{ {{range .J.Groups}} {{range .Cases}}
106
+ {{if .PropertyMatch "decode"}} {
107
+ {{printf "%q" .Description}},
108
+ {{byteSlice .Input | printf "%#v" }},
109
+ {{printf "%#v" .Expected }},
110
+ {{lengthSlice .Input}},
111
+ },{{- end}}{{end}}{{end}}
112
+ }
113
+ `