trackler 2.2.1.44 → 2.2.1.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/isbn-verifier/canonical-data.json +88 -0
  4. data/problem-specifications/exercises/isbn-verifier/description.md +35 -0
  5. data/problem-specifications/exercises/isbn-verifier/metadata.yml +4 -0
  6. data/problem-specifications/exercises/robot-simulator/canonical-data.json +125 -32
  7. data/problem-specifications/exercises/sum-of-multiples/description.md +0 -3
  8. data/problem-specifications/exercises/two-bucket/canonical-data.json +3 -3
  9. data/tracks/c/config.json +235 -237
  10. data/tracks/c/exercises/acronym/README.md +0 -1
  11. data/tracks/c/exercises/all-your-base/README.md +1 -1
  12. data/tracks/c/exercises/allergies/README.md +0 -1
  13. data/tracks/c/exercises/atbash-cipher/README.md +2 -1
  14. data/tracks/c/exercises/beer-song/README.md +1 -1
  15. data/tracks/c/exercises/binary/README.md +2 -0
  16. data/tracks/c/exercises/grains/README.md +0 -1
  17. data/tracks/c/exercises/isogram/README.md +2 -1
  18. data/tracks/c/exercises/leap/README.md +1 -1
  19. data/tracks/c/exercises/meetup/README.md +1 -2
  20. data/tracks/c/exercises/nucleotide-count/README.md +8 -22
  21. data/tracks/c/exercises/palindrome-products/README.md +12 -6
  22. data/tracks/c/exercises/pangram/README.md +1 -1
  23. data/tracks/c/exercises/pascals-triangle/README.md +1 -1
  24. data/tracks/c/exercises/perfect-numbers/README.md +2 -2
  25. data/tracks/c/exercises/phone-number/README.md +3 -2
  26. data/tracks/c/exercises/roman-numerals/README.md +1 -1
  27. data/tracks/c/exercises/scrabble-score/README.md +3 -1
  28. data/tracks/c/exercises/space-age/README.md +2 -1
  29. data/tracks/c/exercises/triangle/README.md +9 -6
  30. data/tracks/c/exercises/word-count/README.md +1 -2
  31. data/tracks/csharp/exercises/accumulate/Accumulate.csproj +2 -2
  32. data/tracks/csharp/exercises/acronym/Acronym.csproj +2 -2
  33. data/tracks/csharp/exercises/all-your-base/AllYourBase.csproj +2 -2
  34. data/tracks/csharp/exercises/allergies/Allergies.csproj +2 -2
  35. data/tracks/csharp/exercises/alphametics/Alphametics.csproj +2 -2
  36. data/tracks/csharp/exercises/anagram/Anagram.csproj +2 -2
  37. data/tracks/csharp/exercises/atbash-cipher/AtbashCipher.csproj +2 -2
  38. data/tracks/csharp/exercises/bank-account/BankAccount.csproj +2 -2
  39. data/tracks/csharp/exercises/beer-song/BeerSong.csproj +2 -2
  40. data/tracks/csharp/exercises/binary-search/BinarySearch.csproj +2 -2
  41. data/tracks/csharp/exercises/binary-search-tree/BinarySearchTree.csproj +2 -2
  42. data/tracks/csharp/exercises/bob/Bob.csproj +2 -2
  43. data/tracks/csharp/exercises/book-store/BookStore.csproj +2 -2
  44. data/tracks/csharp/exercises/bowling/Bowling.csproj +2 -2
  45. data/tracks/csharp/exercises/bracket-push/BracketPush.csproj +2 -2
  46. data/tracks/csharp/exercises/change/Change.csproj +2 -2
  47. data/tracks/csharp/exercises/circular-buffer/CircularBuffer.csproj +2 -2
  48. data/tracks/csharp/exercises/clock/Clock.csproj +2 -2
  49. data/tracks/csharp/exercises/collatz-conjecture/CollatzConjecture.csproj +2 -2
  50. data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.csproj +2 -2
  51. data/tracks/csharp/exercises/connect/Connect.cs +1 -1
  52. data/tracks/csharp/exercises/connect/Connect.csproj +2 -2
  53. data/tracks/csharp/exercises/connect/ConnectTest.cs +120 -85
  54. data/tracks/csharp/exercises/connect/Example.cs +11 -7
  55. data/tracks/csharp/exercises/crypto-square/CryptoSquare.csproj +2 -2
  56. data/tracks/csharp/exercises/custom-set/CustomSet.csproj +2 -2
  57. data/tracks/csharp/exercises/diamond/Diamond.csproj +2 -2
  58. data/tracks/csharp/exercises/difference-of-squares/DifferenceOfSquares.csproj +2 -2
  59. data/tracks/csharp/exercises/diffie-hellman/DiffieHellman.csproj +2 -2
  60. data/tracks/csharp/exercises/dominoes/Dominoes.csproj +2 -2
  61. data/tracks/csharp/exercises/dot-dsl/DotDsl.csproj +2 -2
  62. data/tracks/csharp/exercises/error-handling/ErrorHandling.csproj +2 -2
  63. data/tracks/csharp/exercises/etl/Etl.csproj +2 -2
  64. data/tracks/csharp/exercises/flatten-array/FlattenArray.csproj +2 -2
  65. data/tracks/csharp/exercises/food-chain/FoodChain.csproj +2 -2
  66. data/tracks/csharp/exercises/forth/Forth.csproj +2 -2
  67. data/tracks/csharp/exercises/gigasecond/Gigasecond.csproj +2 -2
  68. data/tracks/csharp/exercises/go-counting/GoCounting.csproj +2 -2
  69. data/tracks/csharp/exercises/grade-school/GradeSchool.csproj +2 -2
  70. data/tracks/csharp/exercises/grains/Grains.csproj +2 -2
  71. data/tracks/csharp/exercises/grep/Grep.csproj +2 -2
  72. data/tracks/csharp/exercises/hamming/Hamming.csproj +2 -2
  73. data/tracks/csharp/exercises/hangman/Hangman.csproj +2 -2
  74. data/tracks/csharp/exercises/hello-world/HelloWorld.csproj +2 -2
  75. data/tracks/csharp/exercises/house/House.csproj +2 -2
  76. data/tracks/csharp/exercises/isogram/Isogram.csproj +2 -2
  77. data/tracks/csharp/exercises/kindergarten-garden/KindergartenGarden.csproj +2 -2
  78. data/tracks/csharp/exercises/largest-series-product/LargestSeriesProduct.csproj +2 -2
  79. data/tracks/csharp/exercises/leap/Leap.csproj +2 -2
  80. data/tracks/csharp/exercises/ledger/Ledger.csproj +2 -2
  81. data/tracks/csharp/exercises/linked-list/LinkedList.csproj +2 -2
  82. data/tracks/csharp/exercises/list-ops/ListOps.csproj +2 -2
  83. data/tracks/csharp/exercises/luhn/Luhn.csproj +2 -2
  84. data/tracks/csharp/exercises/markdown/Markdown.csproj +2 -2
  85. data/tracks/csharp/exercises/matrix/Matrix.csproj +2 -2
  86. data/tracks/csharp/exercises/meetup/Meetup.csproj +2 -2
  87. data/tracks/csharp/exercises/minesweeper/Minesweeper.csproj +2 -2
  88. data/tracks/csharp/exercises/nth-prime/NthPrime.csproj +2 -2
  89. data/tracks/csharp/exercises/nucleotide-count/NucleotideCount.csproj +2 -2
  90. data/tracks/csharp/exercises/ocr-numbers/OcrNumbers.csproj +2 -2
  91. data/tracks/csharp/exercises/palindrome-products/PalindromeProducts.csproj +2 -2
  92. data/tracks/csharp/exercises/pangram/Pangram.csproj +2 -2
  93. data/tracks/csharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.csproj +2 -2
  94. data/tracks/csharp/exercises/pascals-triangle/PascalsTriangle.csproj +2 -2
  95. data/tracks/csharp/exercises/perfect-numbers/PerfectNumbers.csproj +2 -2
  96. data/tracks/csharp/exercises/phone-number/PhoneNumber.csproj +2 -2
  97. data/tracks/csharp/exercises/pig-latin/PigLatin.csproj +2 -2
  98. data/tracks/csharp/exercises/poker/Poker.csproj +2 -2
  99. data/tracks/csharp/exercises/pov/Pov.csproj +2 -2
  100. data/tracks/csharp/exercises/prime-factors/PrimeFactors.csproj +2 -2
  101. data/tracks/csharp/exercises/protein-translation/ProteinTranslation.csproj +2 -2
  102. data/tracks/csharp/exercises/proverb/Proverb.csproj +2 -2
  103. data/tracks/csharp/exercises/pythagorean-triplet/PythagoreanTriplet.csproj +2 -2
  104. data/tracks/csharp/exercises/queen-attack/QueenAttack.csproj +2 -2
  105. data/tracks/csharp/exercises/rail-fence-cipher/RailFenceCipher.csproj +2 -2
  106. data/tracks/csharp/exercises/raindrops/Raindrops.csproj +2 -2
  107. data/tracks/csharp/exercises/react/React.csproj +2 -2
  108. data/tracks/csharp/exercises/rectangles/Rectangles.csproj +2 -2
  109. data/tracks/csharp/exercises/rna-transcription/RnaTranscription.csproj +2 -2
  110. data/tracks/csharp/exercises/robot-name/RobotName.csproj +2 -2
  111. data/tracks/csharp/exercises/robot-simulator/RobotSimulator.csproj +2 -2
  112. data/tracks/csharp/exercises/roman-numerals/RomanNumerals.csproj +2 -2
  113. data/tracks/csharp/exercises/rotational-cipher/RotationalCipher.csproj +2 -2
  114. data/tracks/csharp/exercises/run-length-encoding/RunLengthEncoding.csproj +2 -2
  115. data/tracks/csharp/exercises/saddle-points/SaddlePoints.csproj +2 -2
  116. data/tracks/csharp/exercises/say/Say.csproj +2 -2
  117. data/tracks/csharp/exercises/scale-generator/ScaleGenerator.csproj +2 -2
  118. data/tracks/csharp/exercises/scrabble-score/ScrabbleScore.csproj +2 -2
  119. data/tracks/csharp/exercises/secret-handshake/SecretHandshake.csproj +2 -2
  120. data/tracks/csharp/exercises/series/Series.csproj +2 -2
  121. data/tracks/csharp/exercises/series/SeriesTest.cs +17 -17
  122. data/tracks/csharp/exercises/sgf-parsing/SgfParsing.csproj +2 -2
  123. data/tracks/csharp/exercises/sieve/Sieve.csproj +2 -2
  124. data/tracks/csharp/exercises/simple-cipher/SimpleCipher.csproj +2 -2
  125. data/tracks/csharp/exercises/simple-linked-list/SimpleLinkedList.csproj +2 -2
  126. data/tracks/csharp/exercises/space-age/SpaceAge.csproj +2 -2
  127. data/tracks/csharp/exercises/spiral-matrix/SpiralMatrix.csproj +2 -2
  128. data/tracks/csharp/exercises/strain/Strain.csproj +2 -2
  129. data/tracks/csharp/exercises/sublist/Sublist.csproj +2 -2
  130. data/tracks/csharp/exercises/sum-of-multiples/SumOfMultiples.csproj +2 -2
  131. data/tracks/csharp/exercises/tournament/Tournament.csproj +2 -2
  132. data/tracks/csharp/exercises/transpose/Transpose.csproj +2 -2
  133. data/tracks/csharp/exercises/tree-building/TreeBuilding.csproj +2 -2
  134. data/tracks/csharp/exercises/triangle/Triangle.cs +0 -11
  135. data/tracks/csharp/exercises/triangle/Triangle.csproj +2 -2
  136. data/tracks/csharp/exercises/triangle/TriangleTest.cs +17 -17
  137. data/tracks/csharp/exercises/twelve-days/TwelveDays.csproj +2 -2
  138. data/tracks/csharp/exercises/two-bucket/TwoBucket.csproj +2 -2
  139. data/tracks/csharp/exercises/two-fer/TwoFer.csproj +2 -2
  140. data/tracks/csharp/exercises/variable-length-quantity/VariableLengthQuantity.csproj +2 -2
  141. data/tracks/csharp/exercises/word-count/WordCount.csproj +2 -2
  142. data/tracks/csharp/exercises/word-search/WordSearch.csproj +2 -2
  143. data/tracks/csharp/exercises/wordy/Wordy.csproj +2 -2
  144. data/tracks/csharp/exercises/zebra-puzzle/ZebraPuzzle.csproj +2 -2
  145. data/tracks/csharp/exercises/zipper/Zipper.csproj +2 -2
  146. data/tracks/csharp/generators/Exercises/Connect.cs +47 -0
  147. data/tracks/csharp/generators/Exercises/Triangle.cs +1 -1
  148. data/tracks/dart/config/maintainers.json +27 -1
  149. data/tracks/dart/pubspec.yaml +3 -0
  150. data/tracks/dart/tool/create-exercise +144 -5
  151. data/tracks/elm/.gitattributes +1 -0
  152. data/tracks/elm/bin/install-elm-format +9 -3
  153. data/tracks/elm/config.json +30 -0
  154. data/tracks/elm/exercises/all-your-base/AllYourBase.elm +1 -0
  155. data/tracks/elm/exercises/all-your-base/AllYourBase.example.elm +68 -0
  156. data/tracks/elm/exercises/all-your-base/README.md +65 -0
  157. data/tracks/elm/exercises/all-your-base/elm-package.json +15 -0
  158. data/tracks/elm/exercises/all-your-base/tests/Tests.elm +53 -0
  159. data/tracks/elm/exercises/all-your-base/tests/elm-package.json +16 -0
  160. data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.elm +2 -0
  161. data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.example.elm +19 -0
  162. data/tracks/elm/exercises/collatz-conjecture/elm-package.json +15 -0
  163. data/tracks/elm/exercises/collatz-conjecture/package.json +14 -0
  164. data/tracks/elm/exercises/collatz-conjecture/tests/Tests.elm +38 -0
  165. data/tracks/elm/exercises/collatz-conjecture/tests/elm-package.json +16 -0
  166. data/tracks/elm/exercises/isogram/Isogram.elm +1 -0
  167. data/tracks/elm/exercises/isogram/Isogram.example.elm +76 -0
  168. data/tracks/elm/exercises/isogram/README.md +50 -0
  169. data/tracks/elm/exercises/isogram/elm-package.json +14 -0
  170. data/tracks/elm/exercises/isogram/package.json +14 -0
  171. data/tracks/elm/exercises/isogram/tests/Tests.elm +46 -0
  172. data/tracks/elm/exercises/isogram/tests/elm-package.json +16 -0
  173. data/tracks/fsharp/.gitignore +2 -1
  174. data/tracks/fsharp/exercises/accumulate/Accumulate.fsproj +3 -2
  175. data/tracks/fsharp/exercises/acronym/Acronym.fs +1 -1
  176. data/tracks/fsharp/exercises/acronym/Acronym.fsproj +3 -2
  177. data/tracks/fsharp/exercises/acronym/AcronymTest.fs +13 -38
  178. data/tracks/fsharp/exercises/acronym/Example.fs +1 -1
  179. data/tracks/fsharp/exercises/all-your-base/AllYourBase.fsproj +3 -2
  180. data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +64 -61
  181. data/tracks/fsharp/exercises/all-your-base/Example.fs +4 -1
  182. data/tracks/fsharp/exercises/allergies/Allergies.fs +2 -2
  183. data/tracks/fsharp/exercises/allergies/Allergies.fsproj +3 -2
  184. data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +28 -37
  185. data/tracks/fsharp/exercises/allergies/Example.fs +3 -3
  186. data/tracks/fsharp/exercises/alphametics/Alphametics.fsproj +3 -2
  187. data/tracks/fsharp/exercises/anagram/Anagram.fsproj +3 -2
  188. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fs +4 -2
  189. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fsproj +3 -2
  190. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +38 -42
  191. data/tracks/fsharp/exercises/atbash-cipher/Example.fs +5 -3
  192. data/tracks/fsharp/exercises/bank-account/BankAccount.fsproj +3 -2
  193. data/tracks/fsharp/exercises/beer-song/BeerSong.fsproj +3 -2
  194. data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +36 -32
  195. data/tracks/fsharp/exercises/beer-song/Example.fs +2 -2
  196. data/tracks/fsharp/exercises/binary-search/BinarySearch.fsproj +3 -2
  197. data/tracks/fsharp/exercises/binary-search-tree/BinarySearchTree.fsproj +3 -2
  198. data/tracks/fsharp/exercises/bob/Bob.fs +1 -1
  199. data/tracks/fsharp/exercises/bob/Bob.fsproj +3 -2
  200. data/tracks/fsharp/exercises/bob/BobTest.fs +64 -20
  201. data/tracks/fsharp/exercises/bob/Example.fs +3 -4
  202. data/tracks/fsharp/exercises/book-store/BookStore.fs +1 -1
  203. data/tracks/fsharp/exercises/book-store/BookStore.fsproj +3 -2
  204. data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +32 -25
  205. data/tracks/fsharp/exercises/book-store/Example.fs +1 -1
  206. data/tracks/fsharp/exercises/bowling/Bowling.fsproj +3 -2
  207. data/tracks/fsharp/exercises/bracket-push/BracketPush.fs +1 -1
  208. data/tracks/fsharp/exercises/bracket-push/BracketPush.fsproj +3 -2
  209. data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +24 -25
  210. data/tracks/fsharp/exercises/bracket-push/Example.fs +1 -1
  211. data/tracks/fsharp/exercises/change/Change.fs +1 -1
  212. data/tracks/fsharp/exercises/change/Change.fsproj +3 -2
  213. data/tracks/fsharp/exercises/change/ChangeTest.fs +42 -18
  214. data/tracks/fsharp/exercises/change/Example.fs +7 -4
  215. data/tracks/fsharp/exercises/circular-buffer/CircularBuffer.fsproj +3 -2
  216. data/tracks/fsharp/exercises/clock/Clock.fsproj +3 -2
  217. data/tracks/fsharp/exercises/connect/Connect.fsproj +3 -2
  218. data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fs +1 -40
  219. data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fsproj +3 -2
  220. data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +16 -40
  221. data/tracks/fsharp/exercises/crypto-square/Example.fs +13 -16
  222. data/tracks/fsharp/exercises/custom-set/CustomSet.fs +12 -12
  223. data/tracks/fsharp/exercises/custom-set/CustomSet.fsproj +3 -2
  224. data/tracks/fsharp/exercises/diamond/Diamond.fsproj +3 -2
  225. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fs +2 -2
  226. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fsproj +3 -2
  227. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +24 -20
  228. data/tracks/fsharp/exercises/difference-of-squares/Example.fs +3 -3
  229. data/tracks/fsharp/exercises/diffie-hellman/DiffieHellman.fsproj +3 -2
  230. data/tracks/fsharp/exercises/dominoes/Dominoes.fsproj +3 -2
  231. data/tracks/fsharp/exercises/dot-dsl/DotDsl.fsproj +3 -2
  232. data/tracks/fsharp/exercises/error-handling/ErrorHandling.fsproj +3 -2
  233. data/tracks/fsharp/exercises/etl/Etl.fsproj +3 -2
  234. data/tracks/fsharp/exercises/food-chain/FoodChain.fsproj +3 -2
  235. data/tracks/fsharp/exercises/forth/Forth.fsproj +3 -2
  236. data/tracks/fsharp/exercises/gigasecond/Example.fs +1 -3
  237. data/tracks/fsharp/exercises/gigasecond/Gigasecond.fs +1 -1
  238. data/tracks/fsharp/exercises/gigasecond/Gigasecond.fsproj +3 -2
  239. data/tracks/fsharp/exercises/gigasecond/GigasecondTest.fs +21 -12
  240. data/tracks/fsharp/exercises/go-counting/GoCounting.fsproj +3 -2
  241. data/tracks/fsharp/exercises/grade-school/GradeSchool.fsproj +3 -2
  242. data/tracks/fsharp/exercises/grains/Grains.fsproj +3 -2
  243. data/tracks/fsharp/exercises/grep/Grep.fsproj +3 -2
  244. data/tracks/fsharp/exercises/hamming/Hamming.fsproj +3 -2
  245. data/tracks/fsharp/exercises/hangman/Hangman.fsproj +3 -2
  246. data/tracks/fsharp/exercises/hello-world/HelloWorld.fsproj +3 -2
  247. data/tracks/fsharp/exercises/hello-world/HelloWorldTest.fs +6 -3
  248. data/tracks/fsharp/exercises/house/House.fsproj +3 -2
  249. data/tracks/fsharp/exercises/isogram/Example.fs +1 -1
  250. data/tracks/fsharp/exercises/isogram/Isogram.fs +1 -1
  251. data/tracks/fsharp/exercises/isogram/Isogram.fsproj +3 -2
  252. data/tracks/fsharp/exercises/isogram/IsogramTest.fs +16 -40
  253. data/tracks/fsharp/exercises/kindergarten-garden/Example.fs +6 -4
  254. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fs +3 -5
  255. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fsproj +3 -2
  256. data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGardenTest.fs +100 -47
  257. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProduct.fsproj +3 -2
  258. data/tracks/fsharp/exercises/leap/Example.fs +2 -2
  259. data/tracks/fsharp/exercises/leap/Leap.fs +2 -2
  260. data/tracks/fsharp/exercises/leap/Leap.fsproj +3 -2
  261. data/tracks/fsharp/exercises/leap/LeapTest.fs +19 -15
  262. data/tracks/fsharp/exercises/ledger/Ledger.fsproj +3 -2
  263. data/tracks/fsharp/exercises/lens-person/LensPerson.fsproj +3 -2
  264. data/tracks/fsharp/exercises/linked-list/LinkedList.fsproj +3 -2
  265. data/tracks/fsharp/exercises/list-ops/ListOps.fsproj +3 -2
  266. data/tracks/fsharp/exercises/luhn/Luhn.fsproj +3 -2
  267. data/tracks/fsharp/exercises/luhn/LuhnTest.fs +30 -65
  268. data/tracks/fsharp/exercises/markdown/Markdown.fsproj +3 -2
  269. data/tracks/fsharp/exercises/matrix/Matrix.fsproj +3 -2
  270. data/tracks/fsharp/exercises/meetup/Meetup.fsproj +3 -2
  271. data/tracks/fsharp/exercises/minesweeper/Example.fs +9 -11
  272. data/tracks/fsharp/exercises/minesweeper/Minesweeper.fsproj +3 -2
  273. data/tracks/fsharp/exercises/minesweeper/MinesweeperTest.fs +117 -80
  274. data/tracks/fsharp/exercises/nth-prime/NthPrime.fsproj +3 -2
  275. data/tracks/fsharp/exercises/nucleotide-count/NucleotideCount.fsproj +3 -2
  276. data/tracks/fsharp/exercises/ocr-numbers/OcrNumbers.fsproj +3 -2
  277. data/tracks/fsharp/exercises/palindrome-products/PalindromeProducts.fsproj +3 -2
  278. data/tracks/fsharp/exercises/pangram/Pangram.fsproj +3 -2
  279. data/tracks/fsharp/exercises/pangram/PangramTest.fs +15 -27
  280. data/tracks/fsharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.fsproj +3 -2
  281. data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangle.fsproj +3 -2
  282. data/tracks/fsharp/exercises/perfect-numbers/PerfectNumbers.fsproj +3 -2
  283. data/tracks/fsharp/exercises/phone-number/PhoneNumber.fsproj +3 -2
  284. data/tracks/fsharp/exercises/pig-latin/Example.fs +1 -1
  285. data/tracks/fsharp/exercises/pig-latin/PigLatin.fsproj +3 -2
  286. data/tracks/fsharp/exercises/pig-latin/PigLatinTest.fs +64 -26
  287. data/tracks/fsharp/exercises/poker/Poker.fsproj +3 -2
  288. data/tracks/fsharp/exercises/pov/Pov.fsproj +3 -2
  289. data/tracks/fsharp/exercises/prime-factors/PrimeFactors.fsproj +3 -2
  290. data/tracks/fsharp/exercises/protein-translation/ProteinTranslation.fsproj +3 -2
  291. data/tracks/fsharp/exercises/proverb/Proverb.fsproj +3 -2
  292. data/tracks/fsharp/exercises/pythagorean-triplet/PythagoreanTriplet.fsproj +3 -2
  293. data/tracks/fsharp/exercises/queen-attack/Example.fs +3 -1
  294. data/tracks/fsharp/exercises/queen-attack/QueenAttack.fs +2 -0
  295. data/tracks/fsharp/exercises/queen-attack/QueenAttack.fsproj +3 -2
  296. data/tracks/fsharp/exercises/queen-attack/QueenAttackTest.fs +50 -20
  297. data/tracks/fsharp/exercises/rail-fence-cipher/RailFenceCipher.fsproj +3 -2
  298. data/tracks/fsharp/exercises/raindrops/Raindrops.fsproj +3 -2
  299. data/tracks/fsharp/exercises/raindrops/RaindropsTest.fs +77 -37
  300. data/tracks/fsharp/exercises/react/React.fsproj +3 -2
  301. data/tracks/fsharp/exercises/rectangles/Rectangles.fsproj +3 -2
  302. data/tracks/fsharp/exercises/rna-transcription/Example.fs +15 -7
  303. data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fs +2 -2
  304. data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fsproj +3 -2
  305. data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +29 -14
  306. data/tracks/fsharp/exercises/robot-name/RobotName.fsproj +3 -2
  307. data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fsproj +3 -2
  308. data/tracks/fsharp/exercises/roman-numerals/Example.fs +2 -2
  309. data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fs +2 -2
  310. data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fsproj +3 -2
  311. data/tracks/fsharp/exercises/roman-numerals/RomanNumeralsTest.fs +79 -26
  312. data/tracks/fsharp/exercises/run-length-encoding/RunLengthEncoding.fsproj +3 -2
  313. data/tracks/fsharp/exercises/saddle-points/SaddlePoints.fsproj +3 -2
  314. data/tracks/fsharp/exercises/say/Say.fsproj +3 -2
  315. data/tracks/fsharp/exercises/scale-generator/ScaleGenerator.fsproj +3 -2
  316. data/tracks/fsharp/exercises/scrabble-score/ScrabbleScore.fsproj +3 -2
  317. data/tracks/fsharp/exercises/scrabble-score/ScrabbleScoreTest.fs +33 -17
  318. data/tracks/fsharp/exercises/secret-handshake/SecretHandshake.fsproj +3 -2
  319. data/tracks/fsharp/exercises/series/Series.fsproj +3 -2
  320. data/tracks/fsharp/exercises/sgf-parsing/SgfParsing.fsproj +3 -2
  321. data/tracks/fsharp/exercises/sieve/Sieve.fsproj +3 -2
  322. data/tracks/fsharp/exercises/simple-cipher/SimpleCipher.fsproj +3 -2
  323. data/tracks/fsharp/exercises/simple-linked-list/SimpleLinkedList.fsproj +3 -2
  324. data/tracks/fsharp/exercises/space-age/SpaceAge.fsproj +3 -2
  325. data/tracks/fsharp/exercises/strain/Strain.fsproj +3 -2
  326. data/tracks/fsharp/exercises/sublist/Sublist.fsproj +3 -2
  327. data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiples.fsproj +3 -2
  328. data/tracks/fsharp/exercises/tournament/Tournament.fsproj +3 -2
  329. data/tracks/fsharp/exercises/transpose/Transpose.fsproj +3 -2
  330. data/tracks/fsharp/exercises/tree-building/TreeBuilding.fsproj +3 -2
  331. data/tracks/fsharp/exercises/triangle/Triangle.fsproj +3 -2
  332. data/tracks/fsharp/exercises/twelve-days/TwelveDays.fsproj +3 -2
  333. data/tracks/fsharp/exercises/two-bucket/TwoBucket.fsproj +3 -2
  334. data/tracks/fsharp/exercises/two-fer/TwoFer.fsproj +3 -2
  335. data/tracks/fsharp/exercises/variable-length-quantity/VariableLengthQuantity.fsproj +3 -2
  336. data/tracks/fsharp/exercises/word-count/WordCount.fsproj +3 -2
  337. data/tracks/fsharp/exercises/word-search/WordSearch.fsproj +3 -2
  338. data/tracks/fsharp/exercises/wordy/Wordy.fsproj +3 -2
  339. data/tracks/fsharp/exercises/zebra-puzzle/ZebraPuzzle.fsproj +3 -2
  340. data/tracks/fsharp/exercises/zipper/Zipper.fsproj +3 -2
  341. data/tracks/fsharp/generators/Common.fs +96 -0
  342. data/tracks/fsharp/generators/Exercise.fs +250 -0
  343. data/tracks/fsharp/generators/Generators.fs +210 -0
  344. data/tracks/fsharp/generators/Generators.fsproj +32 -0
  345. data/tracks/fsharp/generators/Generators.sln +24 -0
  346. data/tracks/fsharp/generators/Input.fs +99 -0
  347. data/tracks/fsharp/generators/Options.fs +31 -0
  348. data/tracks/fsharp/generators/Output.fs +224 -0
  349. data/tracks/fsharp/generators/Program.fs +35 -0
  350. data/tracks/fsharp/generators/Properties/launchSettings.json +8 -0
  351. data/tracks/fsharp/generators/Templates/_AssertEmpty.liquid +1 -0
  352. data/tracks/fsharp/generators/Templates/_AssertEqual.liquid +1 -0
  353. data/tracks/fsharp/generators/Templates/_TestClass.liquid +13 -0
  354. data/tracks/fsharp/generators/Templates/_TestMethod.liquid +3 -0
  355. data/tracks/fsharp/generators/Templates/_TestMethodBody.liquid +4 -0
  356. data/tracks/go/.travis.yml +3 -3
  357. data/tracks/groovy/CONTRIBUTING.md +2 -2
  358. data/tracks/groovy/config.json +12 -0
  359. data/tracks/groovy/exercises/scrabble-score/Example.groovy +18 -0
  360. data/tracks/groovy/exercises/scrabble-score/README.md +63 -0
  361. data/tracks/groovy/exercises/scrabble-score/ScrabbleScore.groovy +7 -0
  362. data/tracks/groovy/exercises/scrabble-score/ScrabbleScoreSpec.groovy +45 -0
  363. data/tracks/groovy/exercises/two-fer/TwoFer.groovy +2 -2
  364. data/tracks/haskell/exercises/change/README.md +1 -1
  365. data/tracks/haskell/exercises/lens-person/README.md +1 -1
  366. data/tracks/haskell/exercises/palindrome-products/README.md +5 -12
  367. data/tracks/haskell/exercises/sum-of-multiples/README.md +0 -3
  368. data/tracks/idris/config.json +12 -0
  369. data/tracks/idris/exercises/accumulate/Accumulate.ipkg +5 -0
  370. data/tracks/idris/exercises/accumulate/Makefile +23 -0
  371. data/tracks/idris/exercises/accumulate/README.md +32 -0
  372. data/tracks/idris/exercises/accumulate/src/Example.idr +6 -0
  373. data/tracks/idris/exercises/accumulate/src/Test/Accumulate.idr +35 -0
  374. data/tracks/java/config/maintainers.json +4 -7
  375. data/tracks/java/config.json +99 -22
  376. data/tracks/java/exercises/binary-search-tree/.meta/src/reference/java/{BST.java → BinarySearchTree.java} +1 -1
  377. data/tracks/java/exercises/binary-search-tree/src/test/java/{BSTTest.java → BinarySearchTreeTest.java} +34 -36
  378. data/tracks/java/exercises/robot-simulator/src/main/java/GridPosition.java +19 -15
  379. data/tracks/java/exercises/saddle-points/.meta/src/reference/java/MatrixCoordinate.java +7 -1
  380. data/tracks/java/exercises/saddle-points/src/main/java/MatrixCoordinate.java +7 -1
  381. data/tracks/java/exercises/settings.gradle +1 -0
  382. data/tracks/java/exercises/tournament/.meta/src/reference/java/Result.java +5 -0
  383. data/tracks/java/exercises/tournament/.meta/src/reference/java/TeamResult.java +41 -0
  384. data/tracks/java/exercises/tournament/.meta/src/reference/java/Tournament.java +62 -0
  385. data/tracks/java/exercises/tournament/README.md +78 -0
  386. data/tracks/java/exercises/tournament/build.gradle +18 -0
  387. data/tracks/java/{.Rhistory → exercises/tournament/src/main/java/.keep} +0 -0
  388. data/tracks/java/exercises/tournament/src/test/java/TournamentTest.java +160 -0
  389. data/tracks/php/config.json +14 -0
  390. data/tracks/php/exercises/collatz-conjecture/collatz-conjecture_test.php +44 -0
  391. data/tracks/php/exercises/collatz-conjecture/example.php +18 -0
  392. data/tracks/python/exercises/circular-buffer/circular_buffer.py +1 -1
  393. data/tracks/python/exercises/clock/clock.py +1 -1
  394. data/tracks/python/exercises/etl/etl.py +1 -1
  395. data/tracks/python/exercises/grade-school/grade_school.py +1 -1
  396. data/tracks/python/exercises/grains/grains.py +2 -2
  397. data/tracks/python/exercises/kindergarten-garden/kindergarten_garden.py +1 -1
  398. data/tracks/python/exercises/linked-list/linked_list.py +1 -1
  399. data/tracks/python/exercises/rectangles/rectangles.py +1 -1
  400. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples.py +1 -1
  401. data/tracks/rust/exercises/bob/tests/bob.rs +1 -0
  402. data/tracks/rust/exercises/crypto-square/tests/crypto-square.rs +7 -0
  403. data/tracks/rust/exercises/gigasecond/tests/gigasecond.rs +1 -1
  404. data/tracks/rust/exercises/phone-number/Cargo.lock +1 -1
  405. data/tracks/rust/exercises/phone-number/Cargo.toml +1 -1
  406. data/tracks/rust/exercises/phone-number/example.rs +17 -23
  407. data/tracks/rust/exercises/phone-number/tests/phone-number.rs +31 -40
  408. data/tracks/rust/exercises/say/tests/say.rs +2 -0
  409. data/tracks/rust/exercises/sum-of-multiples/README.md +0 -3
  410. data/tracks/scala/config.json +11 -0
  411. data/tracks/scala/exercises/collatz-conjecture/README.md +43 -0
  412. data/tracks/scala/exercises/collatz-conjecture/build.sbt +3 -0
  413. data/tracks/scala/exercises/collatz-conjecture/example.scala +17 -0
  414. data/tracks/scala/exercises/collatz-conjecture/src/main/scala/.keep +0 -0
  415. data/tracks/scala/exercises/collatz-conjecture/src/test/scala/CollatzConjectureTest.scala +34 -0
  416. data/tracks/scala/testgen/src/main/scala/CollatzConjectureTestGenerator.scala +35 -0
  417. data/tracks/scheme/config.json +8 -0
  418. data/tracks/scheme/exercises/word-count/README.md +19 -0
  419. data/tracks/scheme/exercises/word-count/example.scm +27 -0
  420. data/tracks/scheme/exercises/word-count/word-count-test.scm +90 -0
  421. data/tracks/scheme/exercises/word-count/word-count.scm +5 -0
  422. data/tracks/sml/README.md +20 -1
  423. data/tracks/sml/bin/generate +74 -20
  424. data/tracks/sml/exercises/binary/README.md +23 -5
  425. data/tracks/sml/exercises/binary/binary.sml +2 -0
  426. data/tracks/sml/exercises/binary/example.sml +10 -21
  427. data/tracks/sml/exercises/binary/test.sml +55 -30
  428. data/tracks/sml/exercises/binary/testlib.sml +159 -0
  429. data/tracks/sml/exercises/flatten-array/HINTS.md +8 -0
  430. data/tracks/sml/exercises/flatten-array/README.md +31 -6
  431. data/tracks/sml/exercises/flatten-array/example.sml +3 -4
  432. data/tracks/sml/exercises/flatten-array/flatten-array.sml +4 -5
  433. data/tracks/sml/exercises/flatten-array/test.sml +76 -52
  434. data/tracks/sml/exercises/flatten-array/testlib.sml +159 -0
  435. data/tracks/sml/exercises/nth-prime/HINTS.md +9 -0
  436. data/tracks/sml/exercises/nth-prime/README.md +32 -5
  437. data/tracks/sml/exercises/nth-prime/example.sml +28 -46
  438. data/tracks/sml/exercises/nth-prime/nth-prime.sml +1 -1
  439. data/tracks/sml/exercises/nth-prime/test.sml +19 -63
  440. data/tracks/sml/exercises/nth-prime/testlib.sml +159 -0
  441. data/tracks/sml/exercises/raindrops/README.md +21 -5
  442. data/tracks/typescript/config.json +14 -0
  443. data/tracks/typescript/exercises/triangle/README.md +55 -0
  444. data/tracks/typescript/exercises/triangle/package.json +36 -0
  445. data/tracks/typescript/exercises/triangle/triangle.example.ts +56 -0
  446. data/tracks/typescript/exercises/triangle/triangle.test.ts +79 -0
  447. data/tracks/typescript/exercises/triangle/triangle.ts +12 -0
  448. data/tracks/typescript/exercises/triangle/tsconfig.json +22 -0
  449. data/tracks/typescript/exercises/triangle/tslint.json +127 -0
  450. data/tracks/typescript/exercises/triangle/yarn.lock +2305 -0
  451. metadata +85 -6
  452. data/tracks/d/exercises/crypto-square/.dub/dub.json +0 -6
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -14,9 +14,10 @@
14
14
 
15
15
  <ItemGroup>
16
16
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
17
- <PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
18
- <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
17
+ <PackageReference Include="xunit" Version="2.3.0" />
18
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
19
19
  <PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
20
+ <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0" />
20
21
  </ItemGroup>
21
22
 
22
23
  </Project>
@@ -0,0 +1,96 @@
1
+ [<AutoOpen>]
2
+ module Generators.Common
3
+
4
+ open System
5
+ open System.IO
6
+ open Serilog
7
+ open Newtonsoft.Json.Linq
8
+
9
+ type CanonicalDataCase =
10
+ { Properties: Map<string, obj>
11
+ DescriptionPath: string list } with
12
+ member this.Description = string this.Properties.["description"]
13
+ member this.Property = string this.Properties.["property"]
14
+ member this.Expected = this.Properties.["expected"]
15
+
16
+ type CanonicalData =
17
+ { Exercise: string
18
+ Version: string
19
+ Cases: CanonicalDataCase list }
20
+
21
+ type TestMethod =
22
+ { Skip: bool
23
+ Name: string
24
+ Body: string }
25
+
26
+ type TestMethodBody =
27
+ { Arrange: string list
28
+ Assert: string }
29
+
30
+ type TestMethodBodyAssert =
31
+ { Sut: string
32
+ Expected: string }
33
+
34
+ type TestClass =
35
+ { Version: string
36
+ ExerciseName: string
37
+ TestModuleName: string
38
+ TestedModuleName: string
39
+ Namespaces: string list
40
+ Methods: string list }
41
+
42
+ module Logging =
43
+ let setupLogger() =
44
+ Log.Logger <- LoggerConfiguration()
45
+ .WriteTo.LiterateConsole()
46
+ .CreateLogger();
47
+
48
+ let isInt64 (value: obj) =
49
+ match value with
50
+ | :? int64 -> true
51
+ | _ -> false
52
+
53
+ module Option =
54
+ let ofNonNegativeInt (value: obj) =
55
+ match value with
56
+ | :? int64 as i -> if i < 0L then None else Some value
57
+ | :? int32 as i -> if i < 0 then None else Some value
58
+ | _ -> None
59
+
60
+ module String =
61
+ open Humanizer
62
+
63
+ let equals (x: string) (y: string) = String.Equals(x, y, StringComparison.OrdinalIgnoreCase)
64
+
65
+ let humanize (str: string) = str.Humanize()
66
+
67
+ let camelize (str: string) = str.Camelize()
68
+
69
+ let upperCaseFirst (str: string) =
70
+ match str with
71
+ | "" -> str
72
+ | _ -> sprintf "%c%s" (Char.ToUpper(str.[0])) str.[1..]
73
+
74
+
75
+ module Json =
76
+ let rec parentsAndSelf (currentToken: JToken) =
77
+ let rec helper acc (token: JToken) =
78
+ match token with
79
+ | null -> acc
80
+ | _ -> helper (token::acc) token.Parent
81
+
82
+ helper [] currentToken
83
+
84
+ module Dict =
85
+
86
+ open System.Collections.Generic
87
+
88
+ let toSeq d = d |> Seq.map (fun (KeyValue(k,v)) -> (k, v))
89
+
90
+ let toMap d = d |> toSeq |> Map.ofSeq
91
+
92
+ let ofMap (m: Map<'k,'v>) = new Dictionary<'k,'v>(m) :> IDictionary<'k,'v>
93
+
94
+ let ofList (l: ('k * 'v) list) = new Dictionary<'k,'v>(l |> Map.ofList) :> IDictionary<'k,'v>
95
+
96
+ let ofSeq (s: ('k * 'v) seq) = new Dictionary<'k,'v>(s |> Map.ofSeq) :> IDictionary<'k,'v>
@@ -0,0 +1,250 @@
1
+ module Generators.Exercise
2
+
3
+ open System
4
+ open System.Globalization
5
+ open System.Collections.Generic
6
+ open System.IO
7
+ open System.Reflection
8
+ open Newtonsoft.Json.Linq
9
+ open Humanizer
10
+ open Serilog
11
+ open Input
12
+ open Output
13
+
14
+ [<AbstractClass>]
15
+ type Exercise() =
16
+ // Allow changes in canonical data
17
+ abstract member MapCanonicalData : CanonicalData -> CanonicalData
18
+ abstract member MapCanonicalDataCase : CanonicalDataCase -> CanonicalDataCase
19
+ abstract member MapCanonicalDataCaseProperty : CanonicalDataCase * string * obj -> obj
20
+
21
+ // Convert canonical data to representation used when rendering
22
+ abstract member ToTestClass : CanonicalData -> TestClass
23
+ abstract member ToTestMethod : int -> CanonicalDataCase -> TestMethod
24
+ abstract member ToTestMethodBody : CanonicalDataCase -> TestMethodBody
25
+ abstract member ToTestMethodBodyAssert : CanonicalDataCase -> TestMethodBodyAssert
26
+ abstract member ToTestMethodBodyAssertTemplate : CanonicalDataCase -> string
27
+
28
+ // Rendering of canonical data
29
+ abstract member Render : CanonicalData -> string
30
+ abstract member RenderTestMethod : int -> CanonicalDataCase -> string
31
+ abstract member RenderTestMethodBody : CanonicalDataCase -> string
32
+ abstract member RenderTestMethodName : CanonicalDataCase -> string
33
+
34
+ // Generic value/identifier rendering methods
35
+ abstract member RenderValue : CanonicalDataCase * string * obj -> string
36
+ abstract member RenderValueOrIdentifier: CanonicalDataCase * string * obj -> string
37
+ abstract member RenderValueWithoutIdentifier: CanonicalDataCase * string * obj -> string
38
+ abstract member RenderValueWithIdentifier: CanonicalDataCase * string * obj -> string
39
+ abstract member RenderIdentifier: CanonicalDataCase * string * obj -> string
40
+ abstract member RenderIdentifierWithTypeAnnotation: CanonicalDataCase * string * obj -> string
41
+
42
+ // Canonical-data specific rendering methods
43
+ abstract member RenderExpected : CanonicalDataCase * string * obj -> string
44
+ abstract member RenderInput : CanonicalDataCase * string * obj -> string
45
+ abstract member RenderArrange : CanonicalDataCase -> string list
46
+ abstract member RenderAssert : CanonicalDataCase -> string
47
+ abstract member RenderSut : CanonicalDataCase -> string
48
+ abstract member RenderSutParameters : CanonicalDataCase -> string list
49
+ abstract member RenderSutParameter : CanonicalDataCase * string * obj -> string
50
+ abstract member RenderSutProperty : CanonicalDataCase -> string
51
+
52
+ // Utility methods to customize rendered output
53
+ abstract member PropertiesUsedAsSutParameter : CanonicalDataCase -> string list
54
+ abstract member PropertiesWithIdentifier : CanonicalDataCase -> string list
55
+ abstract member IdentifierTypeAnnotation: CanonicalDataCase * string * obj -> string option
56
+ abstract member UseFullMethodName : CanonicalDataCase -> bool
57
+ abstract member AdditionalNamespaces : string list
58
+
59
+ member this.Name = this.GetType().Name.Kebaberize()
60
+ member this.TestModuleName = this.GetType().Name.Pascalize() |> sprintf "%sTest"
61
+ member this.TestedModuleName = this.GetType().Name.Pascalize()
62
+
63
+ member this.WriteToFile contents =
64
+ let testClassPath = Path.Combine("..", "exercises", this.Name, sprintf "%s.fs" this.TestModuleName)
65
+
66
+ Directory.CreateDirectory(Path.GetDirectoryName(testClassPath)) |> ignore
67
+ File.WriteAllText(testClassPath, contents)
68
+
69
+ Log.Information("Generated tests for {Exercise} exercise in {TestClassPath}", this.Name, testClassPath);
70
+
71
+ member this.Regenerate(canonicalData) =
72
+ canonicalData
73
+ |> this.MapCanonicalData
74
+ |> this.Render
75
+ |> this.WriteToFile
76
+
77
+ // Allow changes in canonical data
78
+
79
+ default this.MapCanonicalData canonicalData =
80
+ { canonicalData with Cases = List.map this.MapCanonicalDataCase canonicalData.Cases }
81
+
82
+ default this.MapCanonicalDataCase canonicalDataCase =
83
+ let updatedProperties =
84
+ canonicalDataCase.Properties
85
+ |> Map.map (fun key value -> this.MapCanonicalDataCaseProperty (canonicalDataCase, key, value))
86
+
87
+ { canonicalDataCase with Properties = updatedProperties }
88
+
89
+ default this.MapCanonicalDataCaseProperty (canonicalDataCase, key, value) = value
90
+
91
+ // Convert canonical data to representation used when rendering
92
+
93
+ default this.ToTestClass canonicalData =
94
+ { Version = canonicalData.Version
95
+ ExerciseName = this.Name
96
+ TestModuleName = this.TestModuleName
97
+ TestedModuleName = this.TestedModuleName
98
+ Namespaces = ["FsUnit.Xunit"; "Xunit"] @ this.AdditionalNamespaces
99
+ Methods = List.mapi this.RenderTestMethod canonicalData.Cases }
100
+
101
+ default this.ToTestMethod index canonicalDataCase =
102
+ { Skip = index > 0
103
+ Name = this.RenderTestMethodName canonicalDataCase
104
+ Body = this.RenderTestMethodBody canonicalDataCase }
105
+
106
+ default this.ToTestMethodBody canonicalDataCase =
107
+ { Arrange = this.RenderArrange canonicalDataCase
108
+ Assert = this.RenderAssert canonicalDataCase }
109
+
110
+ default this.ToTestMethodBodyAssert canonicalDataCase =
111
+ { Sut = this.RenderSut canonicalDataCase
112
+ Expected = this.RenderValueOrIdentifier (canonicalDataCase, "expected", canonicalDataCase.Expected) }
113
+
114
+ default this.ToTestMethodBodyAssertTemplate canonicalDataCase =
115
+ match canonicalDataCase.Expected with
116
+ | :? JArray as jArray when jArray.Count = 0 && not (List.contains "expected" (this.PropertiesWithIdentifier canonicalDataCase)) -> "AssertEmpty"
117
+ | _ -> "AssertEqual"
118
+
119
+ // Rendering of canonical data
120
+
121
+ default this.Render canonicalData =
122
+ canonicalData
123
+ |> this.ToTestClass
124
+ |> renderPartialTemplate "TestClass"
125
+
126
+ default this.RenderTestMethod index canonicalDataCase =
127
+ canonicalDataCase
128
+ |> this.ToTestMethod index
129
+ |> renderPartialTemplate "TestMethod"
130
+
131
+ default this.RenderTestMethodBody canonicalDataCase =
132
+ canonicalDataCase
133
+ |> this.ToTestMethodBody
134
+ |> renderPartialTemplate "TestMethodBody"
135
+
136
+ default this.RenderTestMethodName canonicalDataCase =
137
+ match this.UseFullMethodName canonicalDataCase with
138
+ | false ->
139
+ String.upperCaseFirst canonicalDataCase.Description
140
+ | true ->
141
+ canonicalDataCase.DescriptionPath
142
+ |> String.concat " - "
143
+ |> String.upperCaseFirst
144
+
145
+ // Generic value/identifier rendering methods
146
+
147
+ default this.RenderValue (canonicalDataCase, key, value) = formatValue value
148
+
149
+ default this.RenderValueOrIdentifier (canonicalDataCase, key, value) =
150
+ let properties = this.PropertiesWithIdentifier canonicalDataCase
151
+
152
+ match List.contains key properties with
153
+ | true -> this.RenderIdentifier (canonicalDataCase, key, value)
154
+ | false -> this.RenderValueWithoutIdentifier (canonicalDataCase, key, value)
155
+
156
+ default this.RenderValueWithoutIdentifier (canonicalDataCase, key, value) =
157
+ match key with
158
+ | "expected" -> this.RenderExpected (canonicalDataCase, key, value)
159
+ | _ -> this.RenderInput (canonicalDataCase, key, value)
160
+
161
+ default this.RenderValueWithIdentifier (canonicalDataCase, key, value) =
162
+ let identifier = this.RenderIdentifierWithTypeAnnotation (canonicalDataCase, key, value)
163
+ let value = this.RenderValueWithoutIdentifier (canonicalDataCase, key, value)
164
+ sprintf "let %s = %s" identifier value
165
+
166
+ default this.RenderIdentifier (canonicalDataCase, key, value) = String.camelize key
167
+
168
+ default this.RenderIdentifierWithTypeAnnotation (canonicalDataCase, key, value) =
169
+ let identifier = this.RenderIdentifier (canonicalDataCase, key, value)
170
+
171
+ match this.IdentifierTypeAnnotation (canonicalDataCase, key, value) with
172
+ | Some identifierType ->
173
+ identifier |> addTypeAnnotation identifierType
174
+ | None ->
175
+ identifier
176
+
177
+ // Canonical-data specific rendering methods
178
+
179
+ default this.RenderExpected (canonicalDataCase, key, value) = this.RenderValue (canonicalDataCase, key, value)
180
+
181
+ default this.RenderInput (canonicalDataCase, key, value) = this.RenderValue (canonicalDataCase, key, value)
182
+
183
+ default this.RenderArrange canonicalDataCase =
184
+ let renderArrangeProperty property: string option =
185
+ match Map.tryFind property canonicalDataCase.Properties with
186
+ | None -> None
187
+ | Some value -> Some (this.RenderValueWithIdentifier (canonicalDataCase, property, value))
188
+
189
+ canonicalDataCase
190
+ |> this.PropertiesWithIdentifier
191
+ |> List.choose renderArrangeProperty
192
+
193
+ default this.RenderAssert canonicalDataCase =
194
+ let template = this.ToTestMethodBodyAssertTemplate canonicalDataCase
195
+
196
+ canonicalDataCase
197
+ |> this.ToTestMethodBodyAssert
198
+ |> renderPartialTemplate template
199
+
200
+ default this.RenderSut canonicalDataCase =
201
+ let parameters = this.RenderSutParameters canonicalDataCase
202
+ let property = this.RenderSutProperty canonicalDataCase
203
+ property :: parameters |> String.concat " "
204
+
205
+ default this.RenderSutParameters canonicalDataCase =
206
+ let sutParameterProperties = this.PropertiesUsedAsSutParameter canonicalDataCase
207
+
208
+ canonicalDataCase.Properties
209
+ |> Map.filter (fun key value -> List.contains key sutParameterProperties)
210
+ |> Map.fold (fun acc key value -> this.RenderSutParameter (canonicalDataCase, key, value) :: acc) []
211
+ |> List.rev
212
+
213
+ default this.RenderSutParameter (canonicalDataCase, key, value) =
214
+ this.RenderValueOrIdentifier (canonicalDataCase, key, value)
215
+
216
+ default this.RenderSutProperty canonicalDataCase = string canonicalDataCase.Property
217
+
218
+ default this.PropertiesUsedAsSutParameter canonicalDataCase =
219
+ canonicalDataCase.Properties
220
+ |> Map.toList
221
+ |> List.map fst
222
+ |> List.except ["property"; "expected"; "description"]
223
+
224
+ // Utility methods to customize rendered output
225
+
226
+ default this.PropertiesWithIdentifier canonicalDataCase = []
227
+
228
+ default this.IdentifierTypeAnnotation (canonicalDataCase, key, value ) = None
229
+
230
+ default this.UseFullMethodName canonicalDataCase = false
231
+
232
+ default this.AdditionalNamespaces = []
233
+
234
+ let createExercises filteredExercises =
235
+
236
+ let isConcreteExercise (exerciseType: Type) =
237
+ not exerciseType.IsAbstract && typeof<Exercise>.IsAssignableFrom(exerciseType)
238
+
239
+ let isFilteredExercises (exerciseType: Type) =
240
+ Seq.isEmpty filteredExercises ||
241
+ Seq.exists (String.equals exerciseType.Name) filteredExercises ||
242
+ Seq.exists (String.equals (exerciseType.Name.Kebaberize())) filteredExercises
243
+
244
+ let includeExercise (exerciseType: Type) = isConcreteExercise exerciseType && isFilteredExercises exerciseType
245
+
246
+ let assemblyTypes = Assembly.GetEntryAssembly().GetTypes()
247
+
248
+ seq { for exerciseType in assemblyTypes do
249
+ if includeExercise exerciseType then
250
+ yield Activator.CreateInstance(exerciseType) :?> Exercise }
@@ -0,0 +1,210 @@
1
+ module Generators.Generators
2
+
3
+ open System
4
+ open System.Globalization
5
+ open Newtonsoft.Json.Linq
6
+ open Output
7
+ open Exercise
8
+
9
+ type Acronym() =
10
+ inherit Exercise()
11
+
12
+ type AtbashCipher() =
13
+ inherit Exercise()
14
+
15
+ type AllYourBase() =
16
+ inherit Exercise()
17
+
18
+ override this.RenderExpected (canonicalDataCase, key, value) = value |> Option.ofObj |> formatValue
19
+
20
+ override this.PropertiesWithIdentifier canonicalDataCase = ["expected"; "input_base"; "input_digits"; "output_base"]
21
+
22
+ type Allergies() =
23
+ inherit Exercise()
24
+
25
+ let toAllergen (jToken: JToken) = sprintf "Allergen.%s" (jToken.ToString() |> String.humanize)
26
+
27
+ override this.RenderTestMethodBody canonicalDataCase =
28
+ if (canonicalDataCase.Property = "allergicTo") then
29
+ let renderAssertion (jToken: JToken) =
30
+ let updatedProperties =
31
+ canonicalDataCase.Properties
32
+ |> Map.add "substance" (jToken.["substance"] |> toAllergen |> box)
33
+ |> Map.add "expected" (jToken.["result"].ToObject<bool>() |> box)
34
+
35
+ { canonicalDataCase with Properties = updatedProperties }
36
+ |> this.RenderAssert
37
+ |> indent 1
38
+
39
+ canonicalDataCase.Expected :?> JArray
40
+ |> Seq.map renderAssertion
41
+ |> String.concat "\n"
42
+ else
43
+ base.RenderTestMethodBody canonicalDataCase
44
+
45
+ override this.RenderExpected (canonicalDataCase, key, value) =
46
+ if (canonicalDataCase.Property = "list") then
47
+ canonicalDataCase.Expected :?> JArray
48
+ |> Seq.map toAllergen
49
+ |> formatList
50
+ else
51
+ base.RenderExpected (canonicalDataCase, key, value)
52
+
53
+ override this.RenderInput (canonicalDataCase, key, value) =
54
+ match key with
55
+ | "substance" -> string value
56
+ | _ -> base.RenderInput (canonicalDataCase, key, value)
57
+
58
+ type BeerSong() =
59
+ inherit Exercise()
60
+
61
+ override this.PropertiesWithIdentifier canonicalDataCase = ["expected"]
62
+
63
+ type Bob() =
64
+ inherit Exercise()
65
+
66
+ type BookStore() =
67
+ inherit Exercise()
68
+
69
+ let formatFloat (value:obj) = value :?> float |> sprintf "%.2f"
70
+
71
+ override this.RenderExpected (canonicalDataCase, key, value) = formatFloat value
72
+
73
+ override this.PropertiesUsedAsSutParameter canonicalDataCase =
74
+ base.PropertiesUsedAsSutParameter canonicalDataCase
75
+ |> List.except ["targetgrouping"; "expected"; "description"]
76
+
77
+ type BracketPush() =
78
+ inherit Exercise()
79
+
80
+ type Change() =
81
+ inherit Exercise()
82
+
83
+ override this.MapCanonicalDataCaseProperty (canonicalDataCase, key, value) =
84
+ match key with
85
+ | "expected" ->
86
+ match value with
87
+ | :? JArray -> Option.ofObj value |> box
88
+ | _ -> value |> Option.ofNonNegativeInt |> box
89
+ | _ -> base.MapCanonicalDataCaseProperty (canonicalDataCase, key, value)
90
+
91
+ override this.PropertiesWithIdentifier canonicalDataCase = ["coins"; "target"; "expected"]
92
+
93
+ override this.IdentifierTypeAnnotation (canonicalDataCase, key, value) =
94
+ match key with
95
+ | "expected" ->
96
+ match canonicalDataCase.Properties.["target"] :?> int64 with
97
+ | 0L -> Some "int list option"
98
+ | _ -> None
99
+ | _ -> None
100
+
101
+ type CryptoSquare() =
102
+ inherit Exercise()
103
+
104
+ type DifferenceOfSquares() =
105
+ inherit Exercise()
106
+
107
+ type Gigasecond() =
108
+ inherit Exercise()
109
+
110
+ override this.RenderExpected (canonicalDataCase, key, value) = value :?> DateTime |> formatDateTime |> parenthesize
111
+
112
+ override this.RenderInput (canonicalDataCase, key, value) =
113
+ match key with
114
+ | "input" -> DateTime.Parse(string value, CultureInfo.InvariantCulture) |> formatDateTime |> parenthesize
115
+ | _ -> base.RenderInput (canonicalDataCase, key, value)
116
+
117
+ override this.AdditionalNamespaces = [typeof<DateTime>.Namespace]
118
+
119
+ type HelloWorld() =
120
+ inherit Exercise()
121
+
122
+ type Isogram() =
123
+ inherit Exercise()
124
+
125
+ type KindergartenGarden() =
126
+ inherit Exercise()
127
+
128
+ let toPlant (jToken: JToken) = sprintf "Plant.%s" (jToken.ToString() |> String.humanize)
129
+
130
+ override this.RenderExpected (canonicalDataCase, key, value) =
131
+ value :?> JArray
132
+ |> Seq.map toPlant
133
+ |> formatList
134
+
135
+ override this.RenderSutProperty canonicalDataCase =
136
+ match Map.containsKey "students" canonicalDataCase.Properties with
137
+ | true -> "plantsForCustomStudents"
138
+ | false -> "plantsForDefaultStudents"
139
+
140
+ override this.PropertiesWithIdentifier canonicalDataCase = ["student"; "students"; "diagram"; "expected"]
141
+
142
+ override this.UseFullMethodName canonicalDataCase = true
143
+
144
+ type Leap() =
145
+ inherit Exercise()
146
+
147
+ type Luhn() =
148
+ inherit Exercise()
149
+
150
+ type Minesweeper() =
151
+ inherit Exercise()
152
+
153
+ override this.RenderValueWithoutIdentifier (canonicalDataCase, key, value) =
154
+ value :?> JArray
155
+ |> normalizeJArray
156
+ |> Seq.map formatValue
157
+ |> formatMultiLineList
158
+
159
+ override this.PropertiesWithIdentifier canonicalDataCase = ["input"; "expected"]
160
+
161
+ override this.IdentifierTypeAnnotation (canonicalDataCase, key, value) =
162
+ match value :?> JArray |> Seq.isEmpty with
163
+ | true -> Some "string list"
164
+ | false -> None
165
+
166
+ type Pangram() =
167
+ inherit Exercise()
168
+
169
+ type PigLatin() =
170
+ inherit Exercise()
171
+
172
+ type QueenAttack() =
173
+ inherit Exercise()
174
+
175
+ override this.MapCanonicalDataCaseProperty (canonicalDataCase, key, value) =
176
+ match canonicalDataCase.Property, key, value with
177
+ | "create", "expected", _ -> value :?> int64 <> -1L |> box
178
+ | _ -> base.MapCanonicalDataCaseProperty (canonicalDataCase, key, value)
179
+
180
+ override this.RenderInput (canonicalDataCase, key, value) =
181
+ let parsePositionTuple (tupleValue: obj) =
182
+ let parts =
183
+ (tupleValue :?> JToken)
184
+ .SelectToken("position")
185
+ .ToObject<string>()
186
+ .TrimStart('(')
187
+ .TrimEnd(')')
188
+ .Split(',')
189
+ formatValue (int parts.[0], int parts.[1])
190
+
191
+ match key with
192
+ | "queen" | "white_queen" | "black_queen" -> parsePositionTuple value
193
+ | _ -> base.RenderInput (canonicalDataCase, key, value)
194
+
195
+ override this.PropertiesWithIdentifier canonicalDataCase = ["white_queen"; "black_queen"]
196
+
197
+ type Raindrops() =
198
+ inherit Exercise()
199
+
200
+ type RnaTranscription() =
201
+ inherit Exercise()
202
+
203
+ override this.RenderExpected (canonicalDataCase, key, value) =
204
+ value |> Option.ofObj |> formatValue |> backwardPipe
205
+
206
+ type RomanNumerals() =
207
+ inherit Exercise()
208
+
209
+ type ScrabbleScore() =
210
+ inherit Exercise()
@@ -0,0 +1,32 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+
3
+ <PropertyGroup>
4
+ <OutputType>Exe</OutputType>
5
+ <TargetFramework>netcoreapp2.0</TargetFramework>
6
+ </PropertyGroup>
7
+
8
+ <ItemGroup>
9
+ <Compile Include="Common.fs" />
10
+ <Compile Include="Options.fs" />
11
+ <Compile Include="Input.fs" />
12
+ <Compile Include="Output.fs" />
13
+ <Compile Include="Exercise.fs" />
14
+ <Compile Include="Generators.fs" />
15
+ <Compile Include="Program.fs" />
16
+ </ItemGroup>
17
+
18
+ <ItemGroup>
19
+ <EmbeddedResource Include="Templates\*.liquid" />
20
+ </ItemGroup>
21
+
22
+ <ItemGroup>
23
+ <PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
24
+ <PackageReference Include="DotLiquid" Version="2.0.183" />
25
+ <PackageReference Include="Humanizer" Version="2.2.0" />
26
+ <PackageReference Include="LibGit2Sharp.Portable" Version="0.24.10" />
27
+ <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
28
+ <PackageReference Include="serilog" Version="2.5.0" />
29
+ <PackageReference Include="serilog.sinks.literate" Version="3.0.0" />
30
+ </ItemGroup>
31
+
32
+ </Project>