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,115 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'Bob' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My Bob class", function(){
|
|
10
|
+
|
|
11
|
+
it( 'stating something', function(){
|
|
12
|
+
expect( SUT.response( input='Tom-ay-to, tom-aaaah-to.' ) ).toBe( 'Whatever.' );
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it( 'shouting', function(){
|
|
16
|
+
expect( SUT.response( input='WATCH OUT!' ) ).toBe( 'Whoa, chill out!' );
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it( 'shouting gibberish', function(){
|
|
20
|
+
expect( SUT.response( input='FCECDFCAAB' ) ).toBe( 'Whoa, chill out!' );
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it( 'asking a question', function(){
|
|
24
|
+
expect( SUT.response( input='Does this cryogenic chamber make me look fat?' ) ).toBe( 'Sure.' );
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it( 'asking a numeric question', function(){
|
|
28
|
+
expect( SUT.response( input='You are, what, like 15?' ) ).toBe( 'Sure.' );
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it( 'asking gibberish', function(){
|
|
32
|
+
expect( SUT.response( input='fffbbcbeab?' ) ).toBe( 'Sure.' );
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it( 'talking forcefully', function(){
|
|
36
|
+
expect( SUT.response( input='Let''s go make out behind the gym!' ) ).toBe( 'Whatever.' );
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it( 'using acronyms in regular speech', function(){
|
|
40
|
+
expect( SUT.response( input='It''s OK if you don''t want to go to the DMV.' ) ).toBe( 'Whatever.' );
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it( 'forceful question', function(){
|
|
44
|
+
expect( SUT.response( input='WHAT THE HELL WERE YOU THINKING?' ) ).toBe( 'Whoa, chill out!' );
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it( 'shouting numbers', function(){
|
|
48
|
+
expect( SUT.response( input='1, 2, 3 GO!' ) ).toBe( 'Whoa, chill out!' );
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it( 'only numbers', function(){
|
|
52
|
+
expect( SUT.response( input='1, 2, 3' ) ).toBe( 'Whatever.' );
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it( 'question with only numbers', function(){
|
|
56
|
+
expect( SUT.response( input='4?' ) ).toBe( 'Sure.' );
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it( 'shouting with special characters', function(){
|
|
60
|
+
expect( SUT.response( input='ZOMG THE %^*@##$(*^ ZOMBIES ARE COMING!!11!!1!' ) ).toBe( 'Whoa, chill out!' );
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it( 'shouting with no exclamation mark', function(){
|
|
64
|
+
expect( SUT.response( input='I HATE YOU' ) ).toBe( 'Whoa, chill out!' );
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it( 'statement containing question mark', function(){
|
|
68
|
+
expect( SUT.response( input='Ending with ? means a question.' ) ).toBe( 'Whatever.' );
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it( 'non-letters with question', function(){
|
|
72
|
+
expect( SUT.response( input=':) ?' ) ).toBe( 'Sure.' );
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it( 'prattling on', function(){
|
|
76
|
+
expect( SUT.response( input='Wait! Hang on. Are you going to be OK?' ) ).toBe( 'Sure.' );
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it( 'silence', function(){
|
|
80
|
+
expect( SUT.response( input='' ) ).toBe( 'Fine. Be that way!' );
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it( 'prolonged silence', function(){
|
|
84
|
+
expect( SUT.response( input=' ' ) ).toBe( 'Fine. Be that way!' );
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it( 'alternate silence', function(){
|
|
88
|
+
expect( SUT.response( input=' ' ) ).toBe( 'Fine. Be that way!' );
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it( 'multiple line question', function(){
|
|
92
|
+
expect( SUT.response( input='#chr( 10 )#Does this cryogenic chamber make me look fat?#chr( 10 )#no' ) ).toBe( 'Whatever.' );
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it( 'starting with whitespace', function(){
|
|
96
|
+
expect( SUT.response( input=' hmmmmmmm...' ) ).toBe( 'Whatever.' );
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it( 'ending with whitespace', function(){
|
|
100
|
+
expect( SUT.response( input='Okay if like my spacebar quite a bit? ' ) ).toBe( 'Sure.' );
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it( 'other whitespace', function(){
|
|
104
|
+
expect( SUT.response( input='#chr( 10 )##chr( 13 )# ' ) ).toBe( 'Fine. Be that way!' );
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it( 'non-question ending with whitespace', function(){
|
|
108
|
+
expect( SUT.response( input='This is a statement ending with whitespace ' ) ).toBe( 'Whatever.' );
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the Bob exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function response( input ) {
|
|
7
|
+
input = input
|
|
8
|
+
.trim()
|
|
9
|
+
.reReplaceNoCase( '[^a-z?]', '' );
|
|
10
|
+
|
|
11
|
+
if( !input.len() ) {
|
|
12
|
+
return 'Fine. Be that way!';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if( input.reFindNoCase( '[a-z]' ) && compare( input, input.uCase() ) == 0 ) {
|
|
16
|
+
return 'Whoa, chill out!';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if( input.right( 1 ) == '?' ) {
|
|
20
|
+
return 'Sure.';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return 'Whatever.';
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
@@ -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,35 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'Diamond' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My Diamond class", function(){
|
|
10
|
+
|
|
11
|
+
it( 'Degenerate case with a single ''A'' row', function(){
|
|
12
|
+
expect( SUT.rows( input='A' ) ).toBe( ["A"] );
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it( 'Degenerate case with no row containing 3 distinct groups of spaces', function(){
|
|
16
|
+
expect( SUT.rows( input='B' ) ).toBe( [" A ","B B"," A "] );
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it( 'Smallest non-degenerate case with odd diamond side length', function(){
|
|
20
|
+
expect( SUT.rows( input='C' ) ).toBe( [" A "," B B ","C C"," B B "," A "] );
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it( 'Smallest non-degenerate case with even diamond side length', function(){
|
|
24
|
+
expect( SUT.rows( input='D' ) ).toBe( [" A "," B B "," C C ","D D"," C C "," B B "," A "] );
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it( 'Largest possible diamond', function(){
|
|
28
|
+
expect( SUT.rows( input='Z' ) ).toBe( [" A "," B B "," C C "," D D "," E E "," F F "," G G "," H H "," I I "," J J "," K K "," L L "," M M "," N N "," O O "," P P "," Q Q "," R R "," S S "," T T "," U U "," V V "," W W "," X X "," Y Y ","Z Z"," Y Y "," X X "," W W "," V V "," U U "," T T "," S S "," R R "," Q Q "," P P "," O O "," N N "," M M "," L L "," K K "," J J "," I I "," H H "," G G "," F F "," E E "," D D "," C C "," B B "," A "] );
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the Diamond exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
array function rows( input ) {
|
|
7
|
+
// Offset from ASCII code for "A"
|
|
8
|
+
var numChars = asc( input.uCase() ) - 64;
|
|
9
|
+
var width = ( numChars * 2 ) - 1;
|
|
10
|
+
var overTheHill = false;
|
|
11
|
+
var result = [];
|
|
12
|
+
|
|
13
|
+
// Loop from 1 up to last char and back again
|
|
14
|
+
for( var i=1; i>0; ( overTheHill ? i-- : i++ ) ) {
|
|
15
|
+
|
|
16
|
+
// First and last rows
|
|
17
|
+
if( i == 1 ) {
|
|
18
|
+
var sidePadding = repeatString( ' ', ( width - i ) / 2 );
|
|
19
|
+
result.append( sidePadding & chr( 64 + i ) & sidePadding );
|
|
20
|
+
// All other rows
|
|
21
|
+
} else {
|
|
22
|
+
var sidePadding = repeatString( ' ', ( ( width - 1 ) / 2 ) - (i-1) );
|
|
23
|
+
var interiorPadding = repeatString( ' ', ( 2 * ( i - 2 ) ) + 1 );
|
|
24
|
+
result.append( sidePadding & chr( 64 + i ) & interiorPadding & chr( 64 + i ) & sidePadding );
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Toggle the loop in reverse
|
|
28
|
+
if( i >= numChars ) {
|
|
29
|
+
overTheHill = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
@@ -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,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Your implmentation of the DifferenceOfSquares exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function squareOfSum( number ) {
|
|
7
|
+
// Implement me here
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function sumOfSquares( number ) {
|
|
11
|
+
// Implement me here
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function differenceOfSquares( number ) {
|
|
15
|
+
// Implement me here
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'DifferenceOfSquares' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My DifferenceOfSquares class", function(){
|
|
10
|
+
|
|
11
|
+
describe( 'Square the sum of the numbers up to the given number', function(){
|
|
12
|
+
|
|
13
|
+
it( 'square of sum 1', function(){
|
|
14
|
+
expect( SUT.squareOfSum( number='1' ) ).toBe( '1' );
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it( 'square of sum 5', function(){
|
|
18
|
+
expect( SUT.squareOfSum( number='5' ) ).toBe( '225' );
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it( 'square of sum 100', function(){
|
|
22
|
+
expect( SUT.squareOfSum( number='100' ) ).toBe( '25502500' );
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe( 'Sum the squares of the numbers up to the given number', function(){
|
|
28
|
+
|
|
29
|
+
it( 'sum of squares 1', function(){
|
|
30
|
+
expect( SUT.sumOfSquares( number='1' ) ).toBe( '1' );
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it( 'sum of squares 5', function(){
|
|
34
|
+
expect( SUT.sumOfSquares( number='5' ) ).toBe( '55' );
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it( 'sum of squares 100', function(){
|
|
38
|
+
expect( SUT.sumOfSquares( number='100' ) ).toBe( '338350' );
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe( 'Subtract sum of squares from square of sums', function(){
|
|
44
|
+
|
|
45
|
+
it( 'difference of squares 1', function(){
|
|
46
|
+
expect( SUT.differenceOfSquares( number='1' ) ).toBe( '0' );
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it( 'difference of squares 5', function(){
|
|
50
|
+
expect( SUT.differenceOfSquares( number='5' ) ).toBe( '170' );
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it( 'difference of squares 100', function(){
|
|
54
|
+
expect( SUT.differenceOfSquares( number='100' ) ).toBe( '25164150' );
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the DifferenceOfSquares exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function squareOfSum( number ) {
|
|
7
|
+
var i = 0
|
|
8
|
+
var accumulator = 0;
|
|
9
|
+
while( ++i <= number ) {
|
|
10
|
+
accumulator += i;
|
|
11
|
+
}
|
|
12
|
+
return accumulator^2;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function sumOfSquares( number ) {
|
|
16
|
+
var i = 0
|
|
17
|
+
var accumulator = 0;
|
|
18
|
+
while( ++i <= number ) {
|
|
19
|
+
accumulator += i^2;
|
|
20
|
+
}
|
|
21
|
+
return accumulator;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function differenceOfSquares( number ) {
|
|
25
|
+
return squareOfSum( number ) - sumOfSquares( number );
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|