trackler 2.2.1.40 → 2.2.1.41
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.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/dot-dsl/metadata.yml +1 -0
- data/problem-specifications/exercises/etl/metadata.yml +1 -0
- data/problem-specifications/exercises/isogram/canonical-data.json +3 -3
- data/problem-specifications/exercises/ocr-numbers/metadata.yml +1 -0
- data/problem-specifications/exercises/pascals-triangle/metadata.yml +1 -0
- data/problem-specifications/exercises/pov/metadata.yml +1 -0
- data/problem-specifications/exercises/rna-transcription/metadata.yml +1 -0
- data/problem-specifications/exercises/sgf-parsing/metadata.yml +1 -0
- data/tracks/c/exercises/all-your-base/src/example.c +14 -14
- data/tracks/c/exercises/all-your-base/src/example.h +2 -2
- data/tracks/ceylon/exercises/hamming/source/hamming/HammingTest.ceylon +1 -1
- data/tracks/ceylon/exercises/rna-transcription/source/rnatranscription/{RNAtest.ceylon → RNATest.ceylon} +0 -0
- data/tracks/cfml/.git +1 -0
- data/tracks/cfml/.gitignore +5 -0
- data/tracks/cfml/.travis.yml +18 -0
- data/tracks/cfml/CONTRIBUTING.md +10 -0
- data/tracks/cfml/LICENSE +21 -0
- data/tracks/cfml/README.md +92 -0
- data/tracks/cfml/bin/fetch-configlet +32 -0
- data/tracks/cfml/config/exercise_readme.go.tmpl +16 -0
- data/tracks/cfml/config/maintainers.json +13 -0
- data/tracks/cfml/config.json +223 -0
- data/tracks/cfml/docs/ABOUT.md +10 -0
- data/tracks/cfml/docs/EXERCISE_README_INSERT.md +15 -0
- data/tracks/cfml/docs/INSTALLATION.md +35 -0
- data/tracks/cfml/docs/LEARNING.md +37 -0
- data/tracks/cfml/docs/RESOURCES.md +29 -0
- data/tracks/cfml/docs/SNIPPET.txt +8 -0
- data/tracks/cfml/docs/TESTS.md +13 -0
- data/tracks/cfml/exercises/acronym/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/acronym/Acronym.cfc +13 -0
- data/tracks/cfml/exercises/acronym/AcronymTest.cfc +43 -0
- data/tracks/cfml/exercises/acronym/Solution.cfc +22 -0
- data/tracks/cfml/exercises/acronym/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/acronym/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/acronym/box.json +8 -0
- data/tracks/cfml/exercises/acronym/index.cfm +37 -0
- data/tracks/cfml/exercises/atbash-cipher/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/atbash-cipher/AtbashCipher.cfc +14 -0
- data/tracks/cfml/exercises/atbash-cipher/AtbashCipherTest.cfc +71 -0
- data/tracks/cfml/exercises/atbash-cipher/Solution.cfc +56 -0
- data/tracks/cfml/exercises/atbash-cipher/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/atbash-cipher/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/atbash-cipher/box.json +8 -0
- data/tracks/cfml/exercises/atbash-cipher/index.cfm +37 -0
- data/tracks/cfml/exercises/bob/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/bob/Bob.cfc +13 -0
- data/tracks/cfml/exercises/bob/BobTest.cfc +115 -0
- data/tracks/cfml/exercises/bob/Solution.cfc +27 -0
- data/tracks/cfml/exercises/bob/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/bob/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/bob/box.json +8 -0
- data/tracks/cfml/exercises/bob/index.cfm +37 -0
- data/tracks/cfml/exercises/diamond/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/diamond/Diamond.cfc +13 -0
- data/tracks/cfml/exercises/diamond/DiamondTest.cfc +35 -0
- data/tracks/cfml/exercises/diamond/Solution.cfc +35 -0
- data/tracks/cfml/exercises/diamond/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/diamond/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/diamond/box.json +8 -0
- data/tracks/cfml/exercises/diamond/index.cfm +37 -0
- data/tracks/cfml/exercises/difference-of-squares/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/difference-of-squares/DifferenceOfSquares.cfc +18 -0
- data/tracks/cfml/exercises/difference-of-squares/DifferenceOfSquaresTest.cfc +63 -0
- data/tracks/cfml/exercises/difference-of-squares/Solution.cfc +28 -0
- data/tracks/cfml/exercises/difference-of-squares/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/difference-of-squares/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/difference-of-squares/box.json +8 -0
- data/tracks/cfml/exercises/difference-of-squares/index.cfm +37 -0
- data/tracks/cfml/exercises/flatten-array/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/flatten-array/FlattenArray.cfc +13 -0
- data/tracks/cfml/exercises/flatten-array/FlattenArrayTest.cfc +42 -0
- data/tracks/cfml/exercises/flatten-array/Solution.cfc +26 -0
- data/tracks/cfml/exercises/flatten-array/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/flatten-array/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/flatten-array/box.json +8 -0
- data/tracks/cfml/exercises/flatten-array/index.cfm +37 -0
- data/tracks/cfml/exercises/gigasecond/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/gigasecond/Gigasecond.cfc +13 -0
- data/tracks/cfml/exercises/gigasecond/GigasecondTest.cfc +39 -0
- data/tracks/cfml/exercises/gigasecond/Solution.cfc +16 -0
- data/tracks/cfml/exercises/gigasecond/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/gigasecond/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/gigasecond/box.json +8 -0
- data/tracks/cfml/exercises/gigasecond/index.cfm +37 -0
- data/tracks/cfml/exercises/grains/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/grains/Grains.cfc +14 -0
- data/tracks/cfml/exercises/grains/GrainsTest.cfc +63 -0
- data/tracks/cfml/exercises/grains/Solution.cfc +22 -0
- data/tracks/cfml/exercises/grains/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/grains/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/grains/box.json +8 -0
- data/tracks/cfml/exercises/grains/index.cfm +37 -0
- data/tracks/cfml/exercises/hamming/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/hamming/Hamming.cfc +13 -0
- data/tracks/cfml/exercises/hamming/HammingTest.cfc +75 -0
- data/tracks/cfml/exercises/hamming/Solution.cfc +25 -0
- data/tracks/cfml/exercises/hamming/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/hamming/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/hamming/box.json +8 -0
- data/tracks/cfml/exercises/hamming/index.cfm +37 -0
- data/tracks/cfml/exercises/hello-world/HelloWorld.cfc +13 -0
- data/tracks/cfml/exercises/hello-world/HelloWorldTest.cfc +18 -0
- data/tracks/cfml/exercises/hello-world/Solution.cfc +13 -0
- data/tracks/cfml/exercises/hello-world/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/hello-world/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/hello-world/box.json +8 -0
- data/tracks/cfml/exercises/hello-world/index.cfm +37 -0
- data/tracks/cfml/exercises/isogram/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/isogram/Isogram.cfc +13 -0
- data/tracks/cfml/exercises/isogram/IsogramTest.cfc +55 -0
- data/tracks/cfml/exercises/isogram/Solution.cfc +23 -0
- data/tracks/cfml/exercises/isogram/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/isogram/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/isogram/box.json +8 -0
- data/tracks/cfml/exercises/isogram/index.cfm +37 -0
- data/tracks/cfml/exercises/largest-series-product/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/largest-series-product/LargestSeriesProduct.cfc +13 -0
- data/tracks/cfml/exercises/largest-series-product/LargestSeriesProductTest.cfc +75 -0
- data/tracks/cfml/exercises/largest-series-product/Solution.cfc +41 -0
- data/tracks/cfml/exercises/largest-series-product/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/largest-series-product/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/largest-series-product/box.json +8 -0
- data/tracks/cfml/exercises/largest-series-product/index.cfm +37 -0
- data/tracks/cfml/exercises/leap/Leap.cfc +15 -0
- data/tracks/cfml/exercises/leap/LeapTest.cfc +39 -0
- data/tracks/cfml/exercises/leap/README.md +33 -0
- data/tracks/cfml/exercises/leap/Solution.cfc +19 -0
- data/tracks/cfml/exercises/leap/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/leap/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/leap/box.json +8 -0
- data/tracks/cfml/exercises/leap/index.cfm +37 -0
- data/tracks/cfml/exercises/luhn/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/luhn/Luhn.cfc +13 -0
- data/tracks/cfml/exercises/luhn/LuhnTest.cfc +67 -0
- data/tracks/cfml/exercises/luhn/Solution.cfc +38 -0
- data/tracks/cfml/exercises/luhn/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/luhn/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/luhn/box.json +8 -0
- data/tracks/cfml/exercises/luhn/index.cfm +37 -0
- data/tracks/cfml/exercises/nth-prime/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/nth-prime/NthPrime.cfc +13 -0
- data/tracks/cfml/exercises/nth-prime/NthPrimeTest.cfc +35 -0
- data/tracks/cfml/exercises/nth-prime/Solution.cfc +33 -0
- data/tracks/cfml/exercises/nth-prime/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/nth-prime/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/nth-prime/box.json +8 -0
- data/tracks/cfml/exercises/nth-prime/index.cfm +37 -0
- data/tracks/cfml/exercises/pangram/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/pangram/Pangram.cfc +13 -0
- data/tracks/cfml/exercises/pangram/PangramTest.cfc +55 -0
- data/tracks/cfml/exercises/pangram/Solution.cfc +21 -0
- data/tracks/cfml/exercises/pangram/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/pangram/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/pangram/box.json +8 -0
- data/tracks/cfml/exercises/pangram/index.cfm +37 -0
- data/tracks/cfml/exercises/pig-latin/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/pig-latin/PigLatin.cfc +13 -0
- data/tracks/cfml/exercises/pig-latin/PigLatinTest.cfc +115 -0
- data/tracks/cfml/exercises/pig-latin/Solution.cfc +30 -0
- data/tracks/cfml/exercises/pig-latin/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/pig-latin/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/pig-latin/box.json +8 -0
- data/tracks/cfml/exercises/pig-latin/index.cfm +37 -0
- data/tracks/cfml/exercises/raindrops/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/raindrops/Raindrops.cfc +13 -0
- data/tracks/cfml/exercises/raindrops/RaindropsTest.cfc +87 -0
- data/tracks/cfml/exercises/raindrops/Solution.cfc +33 -0
- data/tracks/cfml/exercises/raindrops/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/raindrops/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/raindrops/box.json +8 -0
- data/tracks/cfml/exercises/raindrops/index.cfm +37 -0
- data/tracks/cfml/exercises/rna-transcription/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/rna-transcription/RnaTranscription.cfc +13 -0
- data/tracks/cfml/exercises/rna-transcription/RnaTranscriptionTest.cfc +47 -0
- data/tracks/cfml/exercises/rna-transcription/Solution.cfc +35 -0
- data/tracks/cfml/exercises/rna-transcription/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/rna-transcription/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/rna-transcription/box.json +8 -0
- data/tracks/cfml/exercises/rna-transcription/index.cfm +37 -0
- data/tracks/cfml/exercises/saddle-points/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/saddle-points/SaddlePoints.cfc +13 -0
- data/tracks/cfml/exercises/saddle-points/SaddlePointsTest.cfc +35 -0
- data/tracks/cfml/exercises/saddle-points/Solution.cfc +59 -0
- data/tracks/cfml/exercises/saddle-points/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/saddle-points/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/saddle-points/box.json +8 -0
- data/tracks/cfml/exercises/saddle-points/index.cfm +37 -0
- data/tracks/cfml/exercises/scrabble-score/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/scrabble-score/ScrabbleScore.cfc +13 -0
- data/tracks/cfml/exercises/scrabble-score/ScrabbleScoreTest.cfc +59 -0
- data/tracks/cfml/exercises/scrabble-score/Solution.cfc +50 -0
- data/tracks/cfml/exercises/scrabble-score/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/scrabble-score/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/scrabble-score/box.json +8 -0
- data/tracks/cfml/exercises/scrabble-score/index.cfm +37 -0
- data/tracks/cfml/exercises/secret-handshake/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/secret-handshake/SecretHandshake.cfc +13 -0
- data/tracks/cfml/exercises/secret-handshake/SecretHandshakeTest.cfc +63 -0
- data/tracks/cfml/exercises/secret-handshake/Solution.cfc +31 -0
- data/tracks/cfml/exercises/secret-handshake/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/secret-handshake/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/secret-handshake/box.json +8 -0
- data/tracks/cfml/exercises/secret-handshake/index.cfm +37 -0
- data/tracks/cfml/exercises/space-age/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/space-age/Solution.cfc +28 -0
- data/tracks/cfml/exercises/space-age/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/space-age/SpaceAge.cfc +13 -0
- data/tracks/cfml/exercises/space-age/SpaceAgeTest.cfc +47 -0
- data/tracks/cfml/exercises/space-age/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/space-age/box.json +8 -0
- data/tracks/cfml/exercises/space-age/index.cfm +37 -0
- data/tracks/cfml/exercises/sum-of-multiples/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/sum-of-multiples/Solution.cfc +27 -0
- data/tracks/cfml/exercises/sum-of-multiples/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/sum-of-multiples/SumOfMultiples.cfc +13 -0
- data/tracks/cfml/exercises/sum-of-multiples/SumOfMultiplesTest.cfc +63 -0
- data/tracks/cfml/exercises/sum-of-multiples/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/sum-of-multiples/box.json +8 -0
- data/tracks/cfml/exercises/sum-of-multiples/index.cfm +37 -0
- data/tracks/cfml/exercises/triangle/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/triangle/Solution.cfc +53 -0
- data/tracks/cfml/exercises/triangle/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/triangle/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/triangle/Triangle.cfc +18 -0
- data/tracks/cfml/exercises/triangle/TriangleTest.cfc +95 -0
- data/tracks/cfml/exercises/triangle/box.json +8 -0
- data/tracks/cfml/exercises/triangle/index.cfm +37 -0
- data/tracks/cfml/exercises/word-count/.meta/HINTS.md +0 -0
- data/tracks/cfml/exercises/word-count/Solution.cfc +22 -0
- data/tracks/cfml/exercises/word-count/SolutionTest.cfc +7 -0
- data/tracks/cfml/exercises/word-count/TestRunner.cfc +103 -0
- data/tracks/cfml/exercises/word-count/WordCount.cfc +13 -0
- data/tracks/cfml/exercises/word-count/WordCountTest.cfc +55 -0
- data/tracks/cfml/exercises/word-count/box.json +8 -0
- data/tracks/cfml/exercises/word-count/index.cfm +37 -0
- data/tracks/cfml/img/icon.png +0 -0
- data/tracks/cfml/tasks/GenerateTests.cfc +179 -0
- data/tracks/cfml/tasks/ScaffoldExercise.cfc +85 -0
- data/tracks/cfml/tasks/TestAllSolutions.cfc +24 -0
- data/tracks/cfml/tasks/exercise_template/.meta/HINTS.md +0 -0
- data/tracks/cfml/tasks/exercise_template/@@name@@.cfc +13 -0
- data/tracks/cfml/tasks/exercise_template/@@name@@Test.cfc +15 -0
- data/tracks/cfml/tasks/exercise_template/Solution.cfc +6 -0
- data/tracks/cfml/tasks/exercise_template/SolutionTest.cfc +7 -0
- data/tracks/cfml/tasks/exercise_template/TestRunner.cfc +103 -0
- data/tracks/cfml/tasks/exercise_template/box.json +8 -0
- data/tracks/cfml/tasks/exercise_template/index.cfm +37 -0
- data/tracks/coldfusion/docs/ABOUT.md +8 -6
- data/tracks/csharp/docs/GENERATORS.md +7 -0
- data/tracks/csharp/exercises/clock/ClockTest.cs +15 -15
- data/tracks/csharp/exercises/nucleotide-count/Example.cs +10 -11
- data/tracks/csharp/exercises/nucleotide-count/NucleotideCount.cs +2 -7
- data/tracks/csharp/exercises/nucleotide-count/NucleotideCountTest.cs +37 -47
- data/tracks/csharp/exercises/pig-latin/Example.cs +1 -1
- data/tracks/csharp/exercises/pig-latin/PigLatinTest.cs +19 -7
- data/tracks/csharp/exercises/sum-of-multiples/SumOfMultiplesTest.cs +7 -1
- data/tracks/csharp/exercises/tournament/Example.cs +1 -1
- data/tracks/csharp/exercises/tournament/TournamentTest.cs +151 -68
- data/tracks/csharp/exercises/triangle/Example.cs +26 -8
- data/tracks/csharp/exercises/triangle/Triangle.cs +16 -1
- data/tracks/csharp/exercises/triangle/TriangleTest.cs +44 -30
- data/tracks/csharp/generators/Exercise.cs +6 -1
- data/tracks/csharp/generators/Exercises/Clock.cs +17 -1
- data/tracks/csharp/generators/Exercises/NucleotideCount.cs +61 -0
- data/tracks/csharp/generators/Exercises/Tournament.cs +66 -0
- data/tracks/csharp/generators/Exercises/Triangle.cs +36 -0
- data/tracks/dart/config.json +15 -2
- data/tracks/dart/exercises/raindrops/lib/example.dart +23 -0
- data/tracks/dart/exercises/raindrops/lib/raindrops.dart +3 -0
- data/tracks/dart/exercises/raindrops/pubspec.lock +281 -0
- data/tracks/dart/exercises/raindrops/pubspec.yaml +3 -0
- data/tracks/dart/exercises/raindrops/test/raindrops_test.dart +94 -0
- data/tracks/delphi/exercises/pig-latin/uPigLatinExample.pas +1 -25
- data/tracks/haskell/config.json +9 -0
- data/tracks/haskell/exercises/acronym/README.md +0 -1
- data/tracks/haskell/exercises/all-your-base/README.md +1 -1
- data/tracks/haskell/exercises/allergies/README.md +0 -1
- data/tracks/haskell/exercises/alphametics/README.md +2 -2
- data/tracks/haskell/exercises/atbash-cipher/README.md +2 -1
- data/tracks/haskell/exercises/beer-song/README.md +1 -1
- data/tracks/haskell/exercises/binary/README.md +2 -0
- data/tracks/haskell/exercises/bowling/README.md +20 -6
- data/tracks/haskell/exercises/collatz-conjecture/README.md +1 -1
- data/tracks/haskell/exercises/connect/README.md +1 -1
- data/tracks/haskell/exercises/crypto-square/README.md +4 -4
- data/tracks/haskell/exercises/diamond/README.md +113 -0
- data/tracks/haskell/exercises/diamond/examples/success-standard/package.yaml +16 -0
- data/tracks/haskell/exercises/diamond/examples/success-standard/src/Diamond.hs +16 -0
- data/tracks/haskell/exercises/diamond/package.yaml +20 -0
- data/tracks/haskell/exercises/diamond/src/Diamond.hs +4 -0
- data/tracks/haskell/exercises/diamond/stack.yaml +1 -0
- data/tracks/haskell/exercises/diamond/test/Tests.hs +109 -0
- data/tracks/haskell/exercises/etl/README.md +3 -1
- data/tracks/haskell/exercises/food-chain/README.md +1 -1
- data/tracks/haskell/exercises/go-counting/README.md +1 -1
- data/tracks/haskell/exercises/grade-school/README.md +0 -1
- data/tracks/haskell/exercises/grains/README.md +0 -1
- data/tracks/haskell/exercises/house/README.md +1 -2
- data/tracks/haskell/exercises/isogram/README.md +2 -1
- data/tracks/haskell/exercises/kindergarten-garden/README.md +3 -3
- data/tracks/haskell/exercises/leap/README.md +1 -1
- data/tracks/haskell/exercises/linked-list/README.md +10 -10
- data/tracks/haskell/exercises/luhn/README.md +7 -7
- data/tracks/haskell/exercises/matrix/README.md +6 -4
- data/tracks/haskell/exercises/meetup/README.md +1 -2
- data/tracks/haskell/exercises/nucleotide-count/README.md +8 -22
- data/tracks/haskell/exercises/ocr-numbers/README.md +6 -6
- data/tracks/haskell/exercises/octal/README.md +6 -2
- data/tracks/haskell/exercises/palindrome-products/README.md +12 -6
- data/tracks/haskell/exercises/pangram/README.md +1 -1
- data/tracks/haskell/exercises/pascals-triangle/README.md +2 -2
- data/tracks/haskell/exercises/phone-number/README.md +3 -2
- data/tracks/haskell/exercises/pov/README.md +3 -3
- data/tracks/haskell/exercises/pythagorean-triplet/README.md +3 -3
- data/tracks/haskell/exercises/queen-attack/README.md +1 -1
- data/tracks/haskell/exercises/rna-transcription/README.md +1 -1
- data/tracks/haskell/exercises/roman-numerals/README.md +1 -1
- data/tracks/haskell/exercises/run-length-encoding/README.md +4 -4
- data/tracks/haskell/exercises/saddle-points/README.md +1 -1
- data/tracks/haskell/exercises/scrabble-score/README.md +3 -1
- data/tracks/haskell/exercises/secret-handshake/README.md +1 -1
- data/tracks/haskell/exercises/sgf-parsing/README.md +4 -4
- data/tracks/haskell/exercises/simple-cipher/README.md +1 -1
- data/tracks/haskell/exercises/spiral-matrix/README.md +2 -2
- data/tracks/haskell/exercises/triangle/README.md +9 -6
- data/tracks/haskell/exercises/trinary/README.md +1 -1
- data/tracks/haskell/exercises/word-count/README.md +1 -2
- data/tracks/haskell/exercises/wordy/README.md +0 -5
- data/tracks/java/config.json +56 -9
- data/tracks/java/exercises/binary-search-tree/src/test/java/BSTTest.java +4 -4
- data/tracks/javascript/exercises/two-bucket/example.js +66 -69
- data/tracks/javascript/exercises/two-bucket/two-bucket.spec.js +18 -18
- data/tracks/julia/config.json +1 -0
- data/tracks/julia/docs/ABOUT.md +3 -8
- data/tracks/prolog/README.md +1 -1
- data/tracks/purescript/.travis.yml +1 -0
- data/tracks/purescript/README.md +9 -0
- data/tracks/purescript/bin/check-bower.sh +42 -0
- data/tracks/purescript/bin/test-separate.sh +46 -0
- data/tracks/python/README.md +2 -2
- data/tracks/python/exercises/all-your-base/all_your_base.py +2 -0
- data/tracks/python/exercises/atbash-cipher/atbash_cipher.py +2 -2
- data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +2 -2
- data/tracks/python/exercises/complex-numbers/example.py +2 -2
- data/tracks/python/exercises/gigasecond/gigasecond.py +1 -1
- data/tracks/python/exercises/hamming/hamming.py +1 -1
- data/tracks/python/exercises/hexadecimal/hexadecimal.py +1 -1
- data/tracks/python/exercises/leap/leap.py +1 -1
- data/tracks/python/exercises/meetup/meetup.py +1 -1
- data/tracks/python/exercises/phone-number/example.py +4 -2
- data/tracks/python/exercises/phone-number/phone_number_test.py +47 -16
- data/tracks/python/exercises/pig-latin/pig_latin.py +1 -1
- data/tracks/python/exercises/scrabble-score/scrabble_score.py +1 -1
- data/tracks/python/exercises/wordy/wordy.py +1 -1
- data/tracks/scala/exercises/meetup/example.scala +29 -10
- data/tracks/scala/exercises/meetup/src/main/scala/Meetup.scala +23 -0
- data/tracks/scala/exercises/meetup/src/test/scala/MeetupTest.scala +273 -183
- data/tracks/sml/config.json +13 -0
- data/tracks/sml/exercises/anagram/README.md +21 -5
- data/tracks/sml/exercises/anagram/anagram.sml +2 -6
- data/tracks/sml/exercises/anagram/example.sml +29 -24
- data/tracks/sml/exercises/anagram/test.sml +56 -50
- data/tracks/sml/exercises/anagram/testlib.sml +159 -0
- data/tracks/sml/exercises/diamond/README.md +89 -0
- data/tracks/sml/exercises/diamond/diamond.sml +2 -0
- data/tracks/sml/exercises/diamond/example.sml +25 -0
- data/tracks/sml/exercises/diamond/test.sml +27 -0
- data/tracks/sml/exercises/diamond/testlib.sml +159 -0
- data/tracks/sml/exercises/raindrops/raindrops.sml +2 -2
- data/tracks/sml/exercises/raindrops/test.sml +66 -95
- data/tracks/sml/exercises/raindrops/testlib.sml +159 -0
- metadata +265 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!---
|
|
2
|
+
|
|
3
|
+
This file will only be used if you want to start up a web server in this directory. You can do so by running:
|
|
4
|
+
|
|
5
|
+
$> box
|
|
6
|
+
CommandBox> install
|
|
7
|
+
CommandBox> server start
|
|
8
|
+
|
|
9
|
+
However, this is not necessary unless you really just want to use the HTML reporters on TestBox.
|
|
10
|
+
Ideally, you'll skip the need for this file entirely and just run the tests directly frm the CLI like this:
|
|
11
|
+
|
|
12
|
+
CommandBox> task run TestRunner
|
|
13
|
+
|
|
14
|
+
--->
|
|
15
|
+
<cfsetting showDebugOutput="false">
|
|
16
|
+
<cfparam name="url.reporter" default="simple">
|
|
17
|
+
<cfscript>
|
|
18
|
+
// get a list of all CFCs in this folder whose name looks like "XXXTest.cfc"
|
|
19
|
+
// And turn it into compnent path relative to the web root
|
|
20
|
+
url.bundles = directoryList(
|
|
21
|
+
path=expandPath( '/' ),
|
|
22
|
+
filter='*Test.cfc' )
|
|
23
|
+
.map( function( path ) {
|
|
24
|
+
return path
|
|
25
|
+
.replaceNoCase( expandPath( '/' ), '' )
|
|
26
|
+
.left( -4 )
|
|
27
|
+
} )
|
|
28
|
+
.toList();
|
|
29
|
+
</cfscript>
|
|
30
|
+
|
|
31
|
+
<!--- Ensure TestBox --->
|
|
32
|
+
<cfif fileExists( "/testbox/system/runners/HTMLRunner.cfm" )>
|
|
33
|
+
<!--- Include the TestBox HTML Runner --->
|
|
34
|
+
<cfinclude template="/testbox/system/runners/HTMLRunner.cfm">
|
|
35
|
+
<cfelse>
|
|
36
|
+
Oops, you don't have TestBox installed yet! Please run <b>box install</b> from the root of your excercise folder and refresh this page.
|
|
37
|
+
</cfif>
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'Pangram' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My Pangram class", function(){
|
|
10
|
+
|
|
11
|
+
describe( 'Check if the given string is an pangram', function(){
|
|
12
|
+
|
|
13
|
+
it( 'sentence empty', function(){
|
|
14
|
+
expect( SUT.isPangram( input='' ) ).toBeFalse();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it( 'pangram with only lower case', function(){
|
|
18
|
+
expect( SUT.isPangram( input='the quick brown fox jumps over the lazy dog' ) ).toBeTrue();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it( 'missing character ''x''', function(){
|
|
22
|
+
expect( SUT.isPangram( input='a quick movement of the enemy will jeopardize five gunboats' ) ).toBeFalse();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it( 'another missing character ''x''', function(){
|
|
26
|
+
expect( SUT.isPangram( input='the quick brown fish jumps over the lazy dog' ) ).toBeFalse();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it( 'pangram with underscores', function(){
|
|
30
|
+
expect( SUT.isPangram( input='the_quick_brown_fox_jumps_over_the_lazy_dog' ) ).toBeTrue();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it( 'pangram with numbers', function(){
|
|
34
|
+
expect( SUT.isPangram( input='the 1 quick brown fox jumps over the 2 lazy dogs' ) ).toBeTrue();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it( 'missing letters replaced by numbers', function(){
|
|
38
|
+
expect( SUT.isPangram( input='7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog' ) ).toBeFalse();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it( 'pangram with mixed case and punctuation', function(){
|
|
42
|
+
expect( SUT.isPangram( input='"Five quacking Zephyrs jolt my wax bed."' ) ).toBeTrue();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it( 'upper and lower case versions of the same character should not be counted separately', function(){
|
|
46
|
+
expect( SUT.isPangram( input='the quick brown fox jumps over with lazy FX' ) ).toBeFalse();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the Pangram exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function isPangram( input ) {
|
|
7
|
+
// Lowercase input to simplify search
|
|
8
|
+
input = input.lCase();
|
|
9
|
+
var i = 96;
|
|
10
|
+
// ASCII codes 97-122 are a-z
|
|
11
|
+
while( ++i <= 122 ) {
|
|
12
|
+
// If any letter is missing, then quit
|
|
13
|
+
if( !input.find( chr( i ) ) ) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// If we made it through, then all letters were found!
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I am a CommandBox task runner which you can use to test your implementation of this exercise against the
|
|
3
|
+
* provided test suite. To use me, open the CommandBox CLI and run this:
|
|
4
|
+
*
|
|
5
|
+
* CommandBox> task run TestRunner
|
|
6
|
+
*
|
|
7
|
+
* To start up a test watcher that will automatically rerun the test suite every time you save a file change, run this:
|
|
8
|
+
*
|
|
9
|
+
* CommandBox> task run TestRunner --watcher
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
component {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @solution Runs the tests against the solution
|
|
16
|
+
* @watcher Start up a file watch that re-runs the tests on file changes. Use Ctrl-C to stop
|
|
17
|
+
*/
|
|
18
|
+
function run( boolean solution=false, boolean watcher=false ) {
|
|
19
|
+
|
|
20
|
+
ensureTestBox();
|
|
21
|
+
|
|
22
|
+
if( watcher ) {
|
|
23
|
+
|
|
24
|
+
// Tabula rasa
|
|
25
|
+
command( 'cls' ).run();
|
|
26
|
+
|
|
27
|
+
// Start watcher
|
|
28
|
+
watch()
|
|
29
|
+
.paths( '*.cfc' )
|
|
30
|
+
.inDirectory( getCWD() )
|
|
31
|
+
.withDelay( 500 )
|
|
32
|
+
.onChange( function() {
|
|
33
|
+
|
|
34
|
+
// Clear the screen
|
|
35
|
+
command( 'cls' )
|
|
36
|
+
.run();
|
|
37
|
+
|
|
38
|
+
// This is neccessary so changes to tests get picked up right away.
|
|
39
|
+
pagePoolClear();
|
|
40
|
+
|
|
41
|
+
runTests( solution );
|
|
42
|
+
|
|
43
|
+
} )
|
|
44
|
+
.start();
|
|
45
|
+
|
|
46
|
+
} else {
|
|
47
|
+
runTests( solution );
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Make sure the TestBox framework is installed
|
|
54
|
+
*/
|
|
55
|
+
private function ensureTestBox() {
|
|
56
|
+
var excerciseRoot = getCWD();
|
|
57
|
+
var testBoxRoot = excerciseRoot & '/testbox';
|
|
58
|
+
|
|
59
|
+
if( !directoryExists( testBoxRoot ) ) {
|
|
60
|
+
|
|
61
|
+
print.boldYellowLine( 'Installing some missing dependencies for you!' ).toConsole();
|
|
62
|
+
command( 'install' )
|
|
63
|
+
.inWorkingDirectory( excerciseRoot )
|
|
64
|
+
.run();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Bootstrap TestBox framework
|
|
68
|
+
filesystemUtil.createMapping( '/testbox', testBoxRoot );
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Invoke TestBox to run the test suite
|
|
73
|
+
*/
|
|
74
|
+
private function runTests( boolean solution=false ) {
|
|
75
|
+
|
|
76
|
+
// Create TestBox and run the tests
|
|
77
|
+
testData = new testbox.system.TestBox()
|
|
78
|
+
.runRaw( directory = {
|
|
79
|
+
// Find all CFCs...
|
|
80
|
+
mapping = filesystemUtil.makePathRelative( getCWD() ),
|
|
81
|
+
// ... in this directory ...
|
|
82
|
+
recurse = false,
|
|
83
|
+
// ... whose name ends in "test"
|
|
84
|
+
filter = function( path ) {
|
|
85
|
+
return path.reFind( ( solution ? 'Solution' : '' ) & 'Test.cfc$' );
|
|
86
|
+
}
|
|
87
|
+
} )
|
|
88
|
+
.getMemento();
|
|
89
|
+
|
|
90
|
+
// Print out the results with ANSI formatting for the CLI
|
|
91
|
+
getInstance( 'CLIRenderer@testbox-commands' )
|
|
92
|
+
.render( print, testData, true );
|
|
93
|
+
|
|
94
|
+
print.toConsole();
|
|
95
|
+
|
|
96
|
+
// Set proper exit code
|
|
97
|
+
if( testData.totalFail || testData.totalError ) {
|
|
98
|
+
setExitCode( 1 );
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!---
|
|
2
|
+
|
|
3
|
+
This file will only be used if you want to start up a web server in this directory. You can do so by running:
|
|
4
|
+
|
|
5
|
+
$> box
|
|
6
|
+
CommandBox> install
|
|
7
|
+
CommandBox> server start
|
|
8
|
+
|
|
9
|
+
However, this is not necessary unless you really just want to use the HTML reporters on TestBox.
|
|
10
|
+
Ideally, you'll skip the need for this file entirely and just run the tests directly frm the CLI like this:
|
|
11
|
+
|
|
12
|
+
CommandBox> task run TestRunner
|
|
13
|
+
|
|
14
|
+
--->
|
|
15
|
+
<cfsetting showDebugOutput="false">
|
|
16
|
+
<cfparam name="url.reporter" default="simple">
|
|
17
|
+
<cfscript>
|
|
18
|
+
// get a list of all CFCs in this folder whose name looks like "XXXTest.cfc"
|
|
19
|
+
// And turn it into compnent path relative to the web root
|
|
20
|
+
url.bundles = directoryList(
|
|
21
|
+
path=expandPath( '/' ),
|
|
22
|
+
filter='*Test.cfc' )
|
|
23
|
+
.map( function( path ) {
|
|
24
|
+
return path
|
|
25
|
+
.replaceNoCase( expandPath( '/' ), '' )
|
|
26
|
+
.left( -4 )
|
|
27
|
+
} )
|
|
28
|
+
.toList();
|
|
29
|
+
</cfscript>
|
|
30
|
+
|
|
31
|
+
<!--- Ensure TestBox --->
|
|
32
|
+
<cfif fileExists( "/testbox/system/runners/HTMLRunner.cfm" )>
|
|
33
|
+
<!--- Include the TestBox HTML Runner --->
|
|
34
|
+
<cfinclude template="/testbox/system/runners/HTMLRunner.cfm">
|
|
35
|
+
<cfelse>
|
|
36
|
+
Oops, you don't have TestBox installed yet! Please run <b>box install</b> from the root of your excercise folder and refresh this page.
|
|
37
|
+
</cfif>
|
|
File without changes
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'PigLatin' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My PigLatin class", function(){
|
|
10
|
+
|
|
11
|
+
describe( 'ay is added to words that start with vowels', function(){
|
|
12
|
+
|
|
13
|
+
it( 'word beginning with a', function(){
|
|
14
|
+
expect( SUT.translate( input='apple' ) ).toBe( 'appleay' );
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it( 'word beginning with e', function(){
|
|
18
|
+
expect( SUT.translate( input='ear' ) ).toBe( 'earay' );
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it( 'word beginning with i', function(){
|
|
22
|
+
expect( SUT.translate( input='igloo' ) ).toBe( 'iglooay' );
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it( 'word beginning with o', function(){
|
|
26
|
+
expect( SUT.translate( input='object' ) ).toBe( 'objectay' );
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it( 'word beginning with u', function(){
|
|
30
|
+
expect( SUT.translate( input='under' ) ).toBe( 'underay' );
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it( 'word beginning with a vowel and followed by a qu', function(){
|
|
34
|
+
expect( SUT.translate( input='equal' ) ).toBe( 'equalay' );
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe( 'first letter and ay are moved to the end of words that start with consonants', function(){
|
|
40
|
+
|
|
41
|
+
it( 'word beginning with p', function(){
|
|
42
|
+
expect( SUT.translate( input='pig' ) ).toBe( 'igpay' );
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it( 'word beginning with k', function(){
|
|
46
|
+
expect( SUT.translate( input='koala' ) ).toBe( 'oalakay' );
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it( 'word beginning with y', function(){
|
|
50
|
+
expect( SUT.translate( input='yellow' ) ).toBe( 'ellowyay' );
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it( 'word beginning with x', function(){
|
|
54
|
+
expect( SUT.translate( input='xenon' ) ).toBe( 'enonxay' );
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it( 'word beginning with q without a following u', function(){
|
|
58
|
+
expect( SUT.translate( input='qat' ) ).toBe( 'atqay' );
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe( 'some letter clusters are treated like a single consonant', function(){
|
|
64
|
+
|
|
65
|
+
it( 'word beginning with ch', function(){
|
|
66
|
+
expect( SUT.translate( input='chair' ) ).toBe( 'airchay' );
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it( 'word beginning with qu', function(){
|
|
70
|
+
expect( SUT.translate( input='queen' ) ).toBe( 'eenquay' );
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it( 'word beginning with qu and a preceding consonant', function(){
|
|
74
|
+
expect( SUT.translate( input='square' ) ).toBe( 'aresquay' );
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it( 'word beginning with th', function(){
|
|
78
|
+
expect( SUT.translate( input='therapy' ) ).toBe( 'erapythay' );
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it( 'word beginning with thr', function(){
|
|
82
|
+
expect( SUT.translate( input='thrush' ) ).toBe( 'ushthray' );
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it( 'word beginning with sch', function(){
|
|
86
|
+
expect( SUT.translate( input='school' ) ).toBe( 'oolschay' );
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe( 'some letter clusters are treated like a single vowel', function(){
|
|
92
|
+
|
|
93
|
+
it( 'word beginning with yt', function(){
|
|
94
|
+
expect( SUT.translate( input='yttria' ) ).toBe( 'yttriaay' );
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it( 'word beginning with xr', function(){
|
|
98
|
+
expect( SUT.translate( input='xray' ) ).toBe( 'xrayay' );
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe( 'phrases are translated', function(){
|
|
104
|
+
|
|
105
|
+
it( 'a whole phrase', function(){
|
|
106
|
+
expect( SUT.translate( input='quick fast run' ) ).toBe( 'ickquay astfay unray' );
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the PigLatin exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function translate( input ) {
|
|
7
|
+
var response = '';
|
|
8
|
+
|
|
9
|
+
// Loop over each work
|
|
10
|
+
return input
|
|
11
|
+
.listToArray( ' ' )
|
|
12
|
+
.map( function( word ) {
|
|
13
|
+
|
|
14
|
+
// Vowel sounds
|
|
15
|
+
if( word.reFindNoCase( '^(a|e|i|o|u|yt|xr)' ) ) {
|
|
16
|
+
return word & 'ay';
|
|
17
|
+
// Consonate sounds
|
|
18
|
+
} else if( word.reFindNoCase( '^(ch|squ|qu|thr|th|sch)' ) ) {
|
|
19
|
+
return word.reReplaceNoCase( '^(ch|squ|qu|thr|th|sch)(.*)', '\2\1ay' );
|
|
20
|
+
// Everything else
|
|
21
|
+
} else {
|
|
22
|
+
return word.right( -1 ) & word.left( 1 ) & 'ay';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
} )
|
|
26
|
+
.toList( ' ' );
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I am a CommandBox task runner which you can use to test your implementation of this exercise against the
|
|
3
|
+
* provided test suite. To use me, open the CommandBox CLI and run this:
|
|
4
|
+
*
|
|
5
|
+
* CommandBox> task run TestRunner
|
|
6
|
+
*
|
|
7
|
+
* To start up a test watcher that will automatically rerun the test suite every time you save a file change, run this:
|
|
8
|
+
*
|
|
9
|
+
* CommandBox> task run TestRunner --watcher
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
component {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @solution Runs the tests against the solution
|
|
16
|
+
* @watcher Start up a file watch that re-runs the tests on file changes. Use Ctrl-C to stop
|
|
17
|
+
*/
|
|
18
|
+
function run( boolean solution=false, boolean watcher=false ) {
|
|
19
|
+
|
|
20
|
+
ensureTestBox();
|
|
21
|
+
|
|
22
|
+
if( watcher ) {
|
|
23
|
+
|
|
24
|
+
// Tabula rasa
|
|
25
|
+
command( 'cls' ).run();
|
|
26
|
+
|
|
27
|
+
// Start watcher
|
|
28
|
+
watch()
|
|
29
|
+
.paths( '*.cfc' )
|
|
30
|
+
.inDirectory( getCWD() )
|
|
31
|
+
.withDelay( 500 )
|
|
32
|
+
.onChange( function() {
|
|
33
|
+
|
|
34
|
+
// Clear the screen
|
|
35
|
+
command( 'cls' )
|
|
36
|
+
.run();
|
|
37
|
+
|
|
38
|
+
// This is neccessary so changes to tests get picked up right away.
|
|
39
|
+
pagePoolClear();
|
|
40
|
+
|
|
41
|
+
runTests( solution );
|
|
42
|
+
|
|
43
|
+
} )
|
|
44
|
+
.start();
|
|
45
|
+
|
|
46
|
+
} else {
|
|
47
|
+
runTests( solution );
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Make sure the TestBox framework is installed
|
|
54
|
+
*/
|
|
55
|
+
private function ensureTestBox() {
|
|
56
|
+
var excerciseRoot = getCWD();
|
|
57
|
+
var testBoxRoot = excerciseRoot & '/testbox';
|
|
58
|
+
|
|
59
|
+
if( !directoryExists( testBoxRoot ) ) {
|
|
60
|
+
|
|
61
|
+
print.boldYellowLine( 'Installing some missing dependencies for you!' ).toConsole();
|
|
62
|
+
command( 'install' )
|
|
63
|
+
.inWorkingDirectory( excerciseRoot )
|
|
64
|
+
.run();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Bootstrap TestBox framework
|
|
68
|
+
filesystemUtil.createMapping( '/testbox', testBoxRoot );
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Invoke TestBox to run the test suite
|
|
73
|
+
*/
|
|
74
|
+
private function runTests( boolean solution=false ) {
|
|
75
|
+
|
|
76
|
+
// Create TestBox and run the tests
|
|
77
|
+
testData = new testbox.system.TestBox()
|
|
78
|
+
.runRaw( directory = {
|
|
79
|
+
// Find all CFCs...
|
|
80
|
+
mapping = filesystemUtil.makePathRelative( getCWD() ),
|
|
81
|
+
// ... in this directory ...
|
|
82
|
+
recurse = false,
|
|
83
|
+
// ... whose name ends in "test"
|
|
84
|
+
filter = function( path ) {
|
|
85
|
+
return path.reFind( ( solution ? 'Solution' : '' ) & 'Test.cfc$' );
|
|
86
|
+
}
|
|
87
|
+
} )
|
|
88
|
+
.getMemento();
|
|
89
|
+
|
|
90
|
+
// Print out the results with ANSI formatting for the CLI
|
|
91
|
+
getInstance( 'CLIRenderer@testbox-commands' )
|
|
92
|
+
.render( print, testData, true );
|
|
93
|
+
|
|
94
|
+
print.toConsole();
|
|
95
|
+
|
|
96
|
+
// Set proper exit code
|
|
97
|
+
if( testData.totalFail || testData.totalError ) {
|
|
98
|
+
setExitCode( 1 );
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!---
|
|
2
|
+
|
|
3
|
+
This file will only be used if you want to start up a web server in this directory. You can do so by running:
|
|
4
|
+
|
|
5
|
+
$> box
|
|
6
|
+
CommandBox> install
|
|
7
|
+
CommandBox> server start
|
|
8
|
+
|
|
9
|
+
However, this is not necessary unless you really just want to use the HTML reporters on TestBox.
|
|
10
|
+
Ideally, you'll skip the need for this file entirely and just run the tests directly frm the CLI like this:
|
|
11
|
+
|
|
12
|
+
CommandBox> task run TestRunner
|
|
13
|
+
|
|
14
|
+
--->
|
|
15
|
+
<cfsetting showDebugOutput="false">
|
|
16
|
+
<cfparam name="url.reporter" default="simple">
|
|
17
|
+
<cfscript>
|
|
18
|
+
// get a list of all CFCs in this folder whose name looks like "XXXTest.cfc"
|
|
19
|
+
// And turn it into compnent path relative to the web root
|
|
20
|
+
url.bundles = directoryList(
|
|
21
|
+
path=expandPath( '/' ),
|
|
22
|
+
filter='*Test.cfc' )
|
|
23
|
+
.map( function( path ) {
|
|
24
|
+
return path
|
|
25
|
+
.replaceNoCase( expandPath( '/' ), '' )
|
|
26
|
+
.left( -4 )
|
|
27
|
+
} )
|
|
28
|
+
.toList();
|
|
29
|
+
</cfscript>
|
|
30
|
+
|
|
31
|
+
<!--- Ensure TestBox --->
|
|
32
|
+
<cfif fileExists( "/testbox/system/runners/HTMLRunner.cfm" )>
|
|
33
|
+
<!--- Include the TestBox HTML Runner --->
|
|
34
|
+
<cfinclude template="/testbox/system/runners/HTMLRunner.cfm">
|
|
35
|
+
<cfelse>
|
|
36
|
+
Oops, you don't have TestBox installed yet! Please run <b>box install</b> from the root of your excercise folder and refresh this page.
|
|
37
|
+
</cfif>
|
|
File without changes
|