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,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the SpaceAge exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function age( planet, seconds ) {
|
|
7
|
+
|
|
8
|
+
// Seconds in one Earth lunar year
|
|
9
|
+
var baseSeconds = 31557600;
|
|
10
|
+
|
|
11
|
+
// Relative factor for each planet compared to Earth
|
|
12
|
+
var planets = {
|
|
13
|
+
Earth : 1,
|
|
14
|
+
Mercury : 0.2408467,
|
|
15
|
+
Venus : 0.61519726,
|
|
16
|
+
Mars : 1.8808158,
|
|
17
|
+
Jupiter : 11.862615,
|
|
18
|
+
Saturn : 29.447498,
|
|
19
|
+
Uranus : 84.016846,
|
|
20
|
+
Neptune : 164.79132
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// age in seconds divded by planet's relative solar year, rounded to two decimals
|
|
24
|
+
return numberFormat( seconds / ( planets[ planet ] * baseSeconds ), '.00' );
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'SpaceAge' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My SpaceAge class", function(){
|
|
10
|
+
|
|
11
|
+
it( 'age on Earth', function(){
|
|
12
|
+
expect( SUT.age( planet='Earth', seconds='1000000000' ) ).toBe( '31.69' );
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it( 'age on Mercury', function(){
|
|
16
|
+
expect( SUT.age( planet='Mercury', seconds='2134835688' ) ).toBe( '280.88' );
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it( 'age on Venus', function(){
|
|
20
|
+
expect( SUT.age( planet='Venus', seconds='189839836' ) ).toBe( '9.78' );
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it( 'age on Mars', function(){
|
|
24
|
+
expect( SUT.age( planet='Mars', seconds='2329871239' ) ).toBe( '39.25' );
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it( 'age on Jupiter', function(){
|
|
28
|
+
expect( SUT.age( planet='Jupiter', seconds='901876382' ) ).toBe( '2.41' );
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it( 'age on Saturn', function(){
|
|
32
|
+
expect( SUT.age( planet='Saturn', seconds='3000000000' ) ).toBe( '3.23' );
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it( 'age on Uranus', function(){
|
|
36
|
+
expect( SUT.age( planet='Uranus', seconds='3210123456' ) ).toBe( '1.21' );
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it( 'age on Neptune', function(){
|
|
40
|
+
expect( SUT.age( planet='Neptune', seconds='8210123456' ) ).toBe( '1.58' );
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
}
|
|
@@ -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,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the SumOfMultiples exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function sum( array factors, limit ) {
|
|
7
|
+
var i = 0;
|
|
8
|
+
var accumulator = {};
|
|
9
|
+
// Loop to our limit
|
|
10
|
+
while( ++i < limit ) {
|
|
11
|
+
// For each of the factors
|
|
12
|
+
if( factors.reduce( function( isFactor, factor ){
|
|
13
|
+
// If at least one of our factors divides into this number
|
|
14
|
+
return isFactor || i % factor == 0;
|
|
15
|
+
}, false ) ) {
|
|
16
|
+
// Add it to our distinct list
|
|
17
|
+
accumulator[ i ] = true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Total the key names
|
|
22
|
+
return accumulator
|
|
23
|
+
.keyArray()
|
|
24
|
+
.sum();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
component extends="testbox.system.BaseSpec" {
|
|
2
|
+
|
|
3
|
+
function beforeAll(){
|
|
4
|
+
SUT = createObject( 'SumOfMultiples' );
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function run(){
|
|
8
|
+
|
|
9
|
+
describe( "My SumOfMultiples class", function(){
|
|
10
|
+
|
|
11
|
+
it( 'multiples of 3 or 5 up to 1', function(){
|
|
12
|
+
expect( SUT.sum( factors=[3, 5], limit='1' ) ).toBe( '0' );
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it( 'multiples of 3 or 5 up to 4', function(){
|
|
16
|
+
expect( SUT.sum( factors=[3, 5], limit='4' ) ).toBe( '3' );
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it( 'multiples of 3 or 5 up to 10', function(){
|
|
20
|
+
expect( SUT.sum( factors=[3, 5], limit='10' ) ).toBe( '23' );
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it( 'multiples of 3 or 5 up to 100', function(){
|
|
24
|
+
expect( SUT.sum( factors=[3, 5], limit='100' ) ).toBe( '2318' );
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it( 'multiples of 3 or 5 up to 1000', function(){
|
|
28
|
+
expect( SUT.sum( factors=[3, 5], limit='1000' ) ).toBe( '233168' );
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it( 'multiples of 7, 13 or 17 up to 20', function(){
|
|
32
|
+
expect( SUT.sum( factors=[7, 13, 17], limit='20' ) ).toBe( '51' );
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it( 'multiples of 4 or 6 up to 15', function(){
|
|
36
|
+
expect( SUT.sum( factors=[4, 6], limit='15' ) ).toBe( '30' );
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it( 'multiples of 5, 6 or 8 up to 150', function(){
|
|
40
|
+
expect( SUT.sum( factors=[5, 6, 8], limit='150' ) ).toBe( '4419' );
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it( 'multiples of 5 or 25 up to 51', function(){
|
|
44
|
+
expect( SUT.sum( factors=[5, 25], limit='51' ) ).toBe( '275' );
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it( 'multiples of 43 or 47 up to 10000', function(){
|
|
48
|
+
expect( SUT.sum( factors=[43, 47], limit='10000' ) ).toBe( '2203160' );
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it( 'multiples of 1 up to 100', function(){
|
|
52
|
+
expect( SUT.sum( factors=[1], limit='100' ) ).toBe( '4950' );
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it( 'multiples of an empty list up to 10000', function(){
|
|
56
|
+
expect( SUT.sum( factors=[], limit='10000' ) ).toBe( '0' );
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -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,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Here is an example solution for the Triangle exercise
|
|
3
|
+
*/
|
|
4
|
+
component {
|
|
5
|
+
|
|
6
|
+
function equilateral( array sides ) {
|
|
7
|
+
// Is triangle and all 3 sides the same
|
|
8
|
+
return isTriangle( sides ) && countSides( sides ) == 1;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isosceles( array sides ) {
|
|
12
|
+
// Is triangle and at least two sides the same
|
|
13
|
+
return isTriangle( sides ) && countSides( sides ) < 3;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function scalene( array sides ) {
|
|
17
|
+
// Is triangle and all 3 sides different
|
|
18
|
+
return isTriangle( sides ) && countSides( sides ) == 3;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private function countSides( array sides ) {
|
|
22
|
+
var distinctSides = {};
|
|
23
|
+
|
|
24
|
+
// Keep track of distinct sides
|
|
25
|
+
sides.each( function( side ){
|
|
26
|
+
distinctSides[ side ] = true;
|
|
27
|
+
} );
|
|
28
|
+
|
|
29
|
+
// Count 'em up
|
|
30
|
+
return distinctSides.count();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private function isTriangle( array sides ) {
|
|
34
|
+
// Any sides of 0 are invalid
|
|
35
|
+
if( sides[ 1 ] == 0 || sides[ 2 ] == 0 || sides[ 3 ] == 0 ) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// sides 1 and 2 must be at least the size of side 3
|
|
39
|
+
if( sides[ 1 ] + sides[ 2 ] < sides[ 3 ] ) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
// sides 1 and 3 must be at least the size of side 2
|
|
43
|
+
if( sides[ 1 ] + sides[ 3 ] < sides[ 2 ] ) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
// sides 2 and 3 must be at least the size of side 1
|
|
47
|
+
if( sides[ 2 ] + sides[ 3 ] < sides[ 1 ] ) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
// If we made it here, it's a triangle!
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
}
|