trackler 2.2.1.54 → 2.2.1.55
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/dominoes/description.md +3 -3
- data/problem-specifications/exercises/two-fer/description.md +0 -28
- data/tracks/c/config.json +12 -0
- data/tracks/c/exercises/queen-attack/README.md +65 -0
- data/tracks/c/exercises/queen-attack/makefile +15 -0
- data/tracks/c/exercises/queen-attack/src/example.c +25 -0
- data/tracks/c/exercises/queen-attack/src/queen_attack.h +19 -0
- data/tracks/c/exercises/queen-attack/test/test_queen_attack.c +190 -0
- data/tracks/c/exercises/queen-attack/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/queen-attack/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/queen-attack/test/vendor/unity_internals.h +701 -0
- data/tracks/common-lisp/exercises/acronym/README.md +1 -1
- data/tracks/delphi/exercises/two-fer/README.md +0 -28
- data/tracks/ecmascript/config.json +41 -0
- data/tracks/ecmascript/exercises/accumulate/package.json +5 -3
- data/tracks/ecmascript/exercises/acronym/package.json +5 -3
- data/tracks/ecmascript/exercises/all-your-base/package.json +5 -3
- data/tracks/ecmascript/exercises/allergies/package.json +5 -3
- data/tracks/ecmascript/exercises/alphametics/package.json +5 -3
- data/tracks/ecmascript/exercises/anagram/package.json +5 -3
- data/tracks/ecmascript/exercises/atbash-cipher/package.json +5 -3
- data/tracks/ecmascript/exercises/beer-song/package.json +5 -3
- data/tracks/ecmascript/exercises/binary-search-tree/package.json +5 -3
- data/tracks/ecmascript/exercises/binary-search/package.json +5 -3
- data/tracks/ecmascript/exercises/binary/package.json +5 -3
- data/tracks/ecmascript/exercises/bob/package.json +5 -3
- data/tracks/ecmascript/exercises/bowling/package.json +2 -2
- data/tracks/ecmascript/exercises/bracket-push/package.json +5 -3
- data/tracks/ecmascript/exercises/change/README.md +44 -0
- data/tracks/ecmascript/exercises/change/change.spec.js +80 -0
- data/tracks/ecmascript/exercises/change/example.js +120 -0
- data/tracks/ecmascript/exercises/change/package.json +69 -0
- data/tracks/ecmascript/exercises/circular-buffer/package.json +5 -3
- data/tracks/ecmascript/exercises/clock/package.json +5 -3
- data/tracks/ecmascript/exercises/collatz-conjecture/package.json +6 -4
- data/tracks/ecmascript/exercises/connect/package.json +5 -3
- data/tracks/ecmascript/exercises/crypto-square/package.json +5 -3
- data/tracks/ecmascript/exercises/custom-set/package.json +5 -3
- data/tracks/ecmascript/exercises/diamond/package.json +5 -3
- data/tracks/ecmascript/exercises/difference-of-squares/package.json +5 -3
- data/tracks/ecmascript/exercises/diffie-hellman/package.json +5 -3
- data/tracks/ecmascript/exercises/etl/package.json +5 -3
- data/tracks/ecmascript/exercises/flatten-array/package.json +5 -3
- data/tracks/ecmascript/exercises/food-chain/package.json +5 -3
- data/tracks/ecmascript/exercises/gigasecond/package.json +5 -3
- data/tracks/ecmascript/exercises/grade-school/package.json +5 -3
- data/tracks/ecmascript/exercises/grains/package.json +5 -3
- data/tracks/ecmascript/exercises/hamming/package.json +5 -3
- data/tracks/ecmascript/exercises/hello-world/package.json +5 -3
- data/tracks/ecmascript/exercises/hexadecimal/package.json +5 -3
- data/tracks/ecmascript/exercises/isbn-verifier/README.md +62 -0
- data/tracks/ecmascript/exercises/isbn-verifier/example.js +17 -0
- data/tracks/ecmascript/exercises/isbn-verifier/isbn-verifier.spec.js +81 -0
- data/tracks/ecmascript/exercises/isbn-verifier/package.json +71 -0
- data/tracks/ecmascript/exercises/isogram/package.json +5 -3
- data/tracks/ecmascript/exercises/kindergarten-garden/package.json +5 -3
- data/tracks/ecmascript/exercises/largest-series-product/package.json +5 -3
- data/tracks/ecmascript/exercises/leap/package.json +5 -3
- data/tracks/ecmascript/exercises/linked-list/package.json +5 -3
- data/tracks/ecmascript/exercises/list-ops/package.json +5 -3
- data/tracks/ecmascript/exercises/luhn/package.json +5 -3
- data/tracks/ecmascript/exercises/matrix/package.json +5 -3
- data/tracks/ecmascript/exercises/meetup/package.json +5 -3
- data/tracks/ecmascript/exercises/minesweeper/package.json +5 -3
- data/tracks/ecmascript/exercises/nth-prime/package.json +5 -3
- data/tracks/ecmascript/exercises/ocr-numbers/package.json +5 -3
- data/tracks/ecmascript/exercises/octal/package.json +5 -3
- data/tracks/ecmascript/exercises/palindrome-products/package.json +5 -3
- data/tracks/ecmascript/exercises/pangram/package.json +5 -3
- data/tracks/ecmascript/exercises/pascals-triangle/package.json +5 -3
- data/tracks/ecmascript/exercises/perfect-numbers/package.json +5 -3
- data/tracks/ecmascript/exercises/phone-number/package.json +5 -3
- data/tracks/ecmascript/exercises/pig-latin/package.json +5 -3
- data/tracks/ecmascript/exercises/prime-factors/package.json +5 -3
- data/tracks/ecmascript/exercises/proverb/package.json +5 -3
- data/tracks/ecmascript/exercises/pythagorean-triplet/package.json +5 -3
- data/tracks/ecmascript/exercises/queen-attack/package.json +5 -3
- data/tracks/ecmascript/exercises/raindrops/package.json +5 -3
- data/tracks/ecmascript/exercises/rna-transcription/package.json +5 -3
- data/tracks/ecmascript/exercises/robot-name/package.json +5 -3
- data/tracks/ecmascript/exercises/robot-simulator/package.json +5 -3
- data/tracks/ecmascript/exercises/roman-numerals/package.json +5 -3
- data/tracks/ecmascript/exercises/run-length-encoding/package.json +5 -3
- data/tracks/ecmascript/exercises/saddle-points/package.json +5 -3
- data/tracks/ecmascript/exercises/say/package.json +5 -3
- data/tracks/ecmascript/exercises/scrabble-score/package.json +5 -3
- data/tracks/ecmascript/exercises/secret-handshake/package.json +5 -3
- data/tracks/ecmascript/exercises/series/package.json +5 -3
- data/tracks/ecmascript/exercises/sieve/package.json +5 -3
- data/tracks/ecmascript/exercises/simple-cipher/package.json +5 -3
- data/tracks/ecmascript/exercises/simple-linked-list/package.json +5 -3
- data/tracks/ecmascript/exercises/space-age/package.json +5 -3
- data/tracks/ecmascript/exercises/strain/package.json +5 -3
- data/tracks/ecmascript/exercises/sublist/package.json +5 -3
- data/tracks/ecmascript/exercises/sum-of-multiples/package.json +5 -3
- data/tracks/ecmascript/exercises/transpose/README.md +94 -0
- data/tracks/ecmascript/exercises/transpose/example.js +12 -0
- data/tracks/ecmascript/exercises/transpose/package.json +71 -0
- data/tracks/ecmascript/exercises/transpose/transpose.spec.js +67 -0
- data/tracks/ecmascript/exercises/triangle/package.json +5 -3
- data/tracks/ecmascript/exercises/trinary/package.json +5 -3
- data/tracks/ecmascript/exercises/twelve-days/package.json +5 -3
- data/tracks/ecmascript/exercises/two-bucket/package.json +5 -3
- data/tracks/ecmascript/exercises/two-fer/package.json +5 -3
- data/tracks/ecmascript/exercises/word-count/package.json +5 -3
- data/tracks/ecmascript/exercises/word-search/package.json +5 -3
- data/tracks/ecmascript/exercises/wordy/package.json +5 -3
- data/tracks/ecmascript/package-lock.json +6219 -0
- data/tracks/ecmascript/package.json +5 -3
- data/tracks/erlang/exercises/collatz-conjecture/src/collatz_conjecture.erl +3 -4
- data/tracks/erlang/exercises/collatz-conjecture/src/example.erl +3 -3
- data/tracks/erlang/exercises/collatz-conjecture/test/collatz_conjecture_tests.erl +13 -9
- data/tracks/erlang/exercises/hello-world/src/hello_world.erl +2 -2
- data/tracks/erlang/exercises/leap/src/example.erl +1 -1
- data/tracks/erlang/exercises/leap/src/leap.erl +3 -3
- data/tracks/erlang/exercises/leap/test/leap_tests.erl +9 -9
- data/tracks/erlang/testgen/src/testgen.erl +16 -13
- data/tracks/erlang/testgen/src/tgen.erl +65 -38
- data/tracks/erlang/testgen/src/tgen_collatz-conjecture.erl +38 -0
- data/tracks/erlang/testgen/src/tgen_hello-world.erl +11 -19
- data/tracks/erlang/testgen/src/tgen_leap.erl +31 -0
- data/tracks/erlang/testgen/src/tgs.erl +80 -0
- data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +78 -23
- data/tracks/fsharp/exercises/anagram/AnagramTest.fs +66 -34
- data/tracks/fsharp/exercises/connect/ConnectTest.fs +81 -68
- data/tracks/fsharp/exercises/connect/Example.fs +9 -5
- data/tracks/fsharp/exercises/food-chain/Example.fs +5 -9
- data/tracks/fsharp/exercises/food-chain/FoodChain.fs +2 -2
- data/tracks/fsharp/exercises/food-chain/FoodChainTest.fs +143 -75
- data/tracks/fsharp/exercises/hamming/Example.fs +8 -4
- data/tracks/fsharp/exercises/hamming/Hamming.fs +1 -1
- data/tracks/fsharp/exercises/hamming/HammingTest.fs +53 -13
- data/tracks/fsharp/exercises/house/Example.fs +5 -6
- data/tracks/fsharp/exercises/house/House.fs +3 -1
- data/tracks/fsharp/exercises/house/HouseTest.fs +272 -96
- data/tracks/fsharp/exercises/meetup/Example.fs +1 -1
- data/tracks/fsharp/exercises/meetup/Meetup.fs +1 -1
- data/tracks/fsharp/exercises/meetup/MeetupTest.fs +384 -73
- data/tracks/fsharp/exercises/ocr-numbers/Example.fs +43 -35
- data/tracks/fsharp/exercises/ocr-numbers/OcrNumbersTest.fs +160 -125
- data/tracks/fsharp/exercises/two-fer/Example.fs +4 -2
- data/tracks/fsharp/exercises/two-fer/TwoFer.fs +1 -1
- data/tracks/fsharp/exercises/two-fer/TwoFerTest.fs +7 -4
- data/tracks/fsharp/generators/Common.fs +6 -2
- data/tracks/fsharp/generators/Exercise.fs +14 -13
- data/tracks/fsharp/generators/Generators.fs +145 -2
- data/tracks/fsharp/generators/Options.fs +4 -6
- data/tracks/fsharp/generators/Output.fs +2 -2
- data/tracks/fsharp/generators/Program.fs +4 -3
- data/tracks/java/exercises/saddle-points/README.md +1 -1
- data/tracks/java/exercises/two-fer/README.md +0 -28
- data/tracks/javascript/exercises/beer-song/example.js +18 -14
- data/tracks/kotlin/exercises/saddle-points/README.md +1 -1
- data/tracks/kotlin/exercises/two-fer/README.md +0 -28
- data/tracks/lua/config.json +12 -0
- data/tracks/lua/exercises/collatz-conjecture/README.md +43 -0
- data/tracks/lua/exercises/collatz-conjecture/collatz-conjecture_spec.lua +33 -0
- data/tracks/lua/exercises/collatz-conjecture/example.lua +16 -0
- data/tracks/python/config.json +4 -1
- data/tracks/python/exercises/binary-search/binary_search_test.py +2 -0
- data/tracks/python/exercises/change/change_test.py +2 -0
- data/tracks/python/exercises/circular-buffer/circular_buffer_test.py +56 -50
- data/tracks/python/exercises/forth/example.py +3 -1
- data/tracks/python/exercises/forth/forth_test.py +43 -26
- data/tracks/python/exercises/nth-prime/nth_prime.py +1 -1
- data/tracks/python/exercises/rna-transcription/README.md +5 -0
- data/tracks/python/exercises/rna-transcription/example.py +1 -1
- data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +7 -4
- data/tracks/python/exercises/robot-simulator/robot_simulator_test.py +9 -7
- data/tracks/python/exercises/saddle-points/saddle_points_test.py +15 -5
- data/tracks/python/exercises/simple-cipher/simple_cipher.py +7 -1
- data/tracks/python/exercises/word-count/example.py +6 -4
- data/tracks/python/exercises/word-count/word_count_test.py +49 -22
- data/tracks/python/exercises/word-search/word_search_test.py +104 -12
- data/tracks/rust/.travis.yml +2 -0
- data/tracks/rust/README.md +5 -0
- data/tracks/rust/_test/check-exercises.sh +0 -6
- data/tracks/rust/_test/ensure-lib-src-rs-exist.sh +19 -0
- data/tracks/rust/_test/ensure-stubs-compile.sh +26 -0
- data/tracks/rust/config.json +12 -0
- data/tracks/rust/config/exercise-readme-insert.md +3 -2
- data/tracks/rust/docs/ABOUT.md +2 -2
- data/tracks/rust/docs/LEARNING.md +1 -1
- data/tracks/rust/docs/RESOURCES.md +1 -1
- data/tracks/rust/docs/TESTS.md +2 -2
- data/tracks/rust/exercises/accumulate/README.md +3 -2
- data/tracks/rust/exercises/acronym/README.md +3 -2
- data/tracks/rust/exercises/all-your-base/README.md +3 -2
- data/tracks/rust/exercises/allergies/README.md +3 -2
- data/tracks/rust/exercises/alphametics/README.md +3 -2
- data/tracks/rust/exercises/anagram/README.md +3 -2
- data/tracks/rust/exercises/atbash-cipher/README.md +3 -2
- data/tracks/rust/exercises/beer-song/README.md +3 -2
- data/tracks/rust/exercises/beer-song/src/lib.rs +2 -2
- data/tracks/rust/exercises/binary-search/README.md +3 -2
- data/tracks/rust/exercises/bob/README.md +3 -2
- data/tracks/rust/exercises/bob/src/lib.rs +1 -1
- data/tracks/rust/exercises/bowling/README.md +3 -2
- data/tracks/rust/exercises/bracket-push/HINTS.md +1 -1
- data/tracks/rust/exercises/bracket-push/README.md +4 -3
- data/tracks/rust/exercises/circular-buffer/README.md +3 -2
- data/tracks/rust/exercises/clock/README.md +3 -2
- data/tracks/rust/exercises/collatz-conjecture/README.md +3 -2
- data/tracks/rust/exercises/collatz-conjecture/src/lib.rs +1 -1
- data/tracks/rust/exercises/crypto-square/README.md +3 -2
- data/tracks/rust/exercises/custom-set/README.md +3 -2
- data/tracks/rust/exercises/decimal/.meta/ALLOWED_TO_NOT_COMPILE +2 -0
- data/tracks/rust/exercises/decimal/README.md +3 -2
- data/tracks/rust/exercises/difference-of-squares/README.md +3 -2
- data/tracks/rust/exercises/difference-of-squares/src/lib.rs +3 -3
- data/tracks/rust/exercises/dominoes/README.md +3 -2
- data/tracks/rust/exercises/etl/README.md +3 -2
- data/tracks/rust/exercises/forth/README.md +3 -2
- data/tracks/rust/exercises/forth/src/lib.rs +3 -0
- data/tracks/rust/exercises/gigasecond/README.md +3 -2
- data/tracks/rust/exercises/grade-school/README.md +3 -2
- data/tracks/rust/exercises/grains/README.md +3 -2
- data/tracks/rust/exercises/hamming/README.md +3 -2
- data/tracks/rust/exercises/hello-world/GETTING_STARTED.md +1 -1
- data/tracks/rust/exercises/hello-world/README.md +3 -2
- data/tracks/rust/exercises/hexadecimal/README.md +3 -2
- data/tracks/rust/exercises/isogram/.gitignore +8 -0
- data/tracks/rust/exercises/isogram/Cargo.toml +3 -0
- data/tracks/rust/exercises/isogram/README.md +52 -0
- data/tracks/rust/exercises/isogram/example.rs +12 -0
- data/tracks/rust/exercises/isogram/src/lib.rs +0 -0
- data/tracks/rust/exercises/isogram/tests/isogram.rs +72 -0
- data/tracks/rust/exercises/largest-series-product/README.md +3 -2
- data/tracks/rust/exercises/leap/README.md +3 -2
- data/tracks/rust/exercises/leap/src/lib.rs +1 -1
- data/tracks/rust/exercises/luhn-from/README.md +3 -2
- data/tracks/rust/exercises/luhn-trait/.meta/description.md +2 -2
- data/tracks/rust/exercises/luhn-trait/README.md +5 -4
- data/tracks/rust/exercises/luhn/README.md +3 -2
- data/tracks/rust/exercises/minesweeper/README.md +3 -2
- data/tracks/rust/exercises/nth-prime/README.md +3 -2
- data/tracks/rust/exercises/nucleotide-codons/README.md +3 -2
- data/tracks/rust/exercises/nucleotide-count/README.md +3 -2
- data/tracks/rust/exercises/ocr-numbers/README.md +3 -2
- data/tracks/rust/exercises/pangram/README.md +3 -2
- data/tracks/rust/exercises/parallel-letter-frequency/HINTS.md +1 -1
- data/tracks/rust/exercises/parallel-letter-frequency/README.md +4 -3
- data/tracks/rust/exercises/pascals-triangle/README.md +3 -2
- data/tracks/rust/exercises/perfect-numbers/README.md +3 -2
- data/tracks/rust/exercises/phone-number/README.md +3 -2
- data/tracks/rust/exercises/pig-latin/README.md +3 -2
- data/tracks/rust/exercises/poker/README.md +3 -2
- data/tracks/rust/exercises/prime-factors/README.md +3 -2
- data/tracks/rust/exercises/protein-translation/README.md +3 -2
- data/tracks/rust/exercises/proverb/README.md +3 -2
- data/tracks/rust/exercises/proverb/src/lib.rs +1 -1
- data/tracks/rust/exercises/pythagorean-triplet/README.md +3 -2
- data/tracks/rust/exercises/queen-attack/README.md +3 -2
- data/tracks/rust/exercises/raindrops/README.md +3 -2
- data/tracks/rust/exercises/raindrops/src/lib.rs +1 -1
- data/tracks/rust/exercises/react/README.md +3 -2
- data/tracks/rust/exercises/rectangles/README.md +3 -2
- data/tracks/rust/exercises/rna-transcription/README.md +3 -2
- data/tracks/rust/exercises/robot-name/README.md +3 -2
- data/tracks/rust/exercises/robot-simulator/README.md +3 -2
- data/tracks/rust/exercises/roman-numerals/README.md +3 -2
- data/tracks/rust/exercises/rotational-cipher/README.md +3 -2
- data/tracks/rust/exercises/run-length-encoding/README.md +3 -2
- data/tracks/rust/exercises/say/README.md +3 -2
- data/tracks/rust/exercises/scrabble-score/README.md +3 -2
- data/tracks/rust/exercises/sieve/README.md +3 -2
- data/tracks/rust/exercises/space-age/README.md +3 -2
- data/tracks/rust/exercises/sublist/README.md +3 -2
- data/tracks/rust/exercises/sum-of-multiples/README.md +3 -2
- data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +1 -1
- data/tracks/rust/exercises/tournament/README.md +3 -2
- data/tracks/rust/exercises/triangle/HINTS.md +2 -2
- data/tracks/rust/exercises/triangle/README.md +5 -4
- data/tracks/rust/exercises/variable-length-quantity/README.md +3 -2
- data/tracks/rust/exercises/word-count/README.md +3 -2
- data/tracks/rust/exercises/wordy/README.md +3 -2
- metadata +38 -3
- data/tracks/ecmascript/yarn.lock +0 -3144
@@ -9,7 +9,7 @@
|
|
9
9
|
"url": "https://github.com/exercism/xecmascript"
|
10
10
|
},
|
11
11
|
"devDependencies": {
|
12
|
-
"babel-jest": "^
|
12
|
+
"babel-jest": "^21.2.0",
|
13
13
|
"babel-plugin-transform-builtin-extend": "^1.1.2",
|
14
14
|
"babel-preset-env": "^1.4.0",
|
15
15
|
"eslint": "^3.19.0",
|
@@ -17,7 +17,7 @@
|
|
17
17
|
"eslint-plugin-import": "^2.2.0",
|
18
18
|
"eslint-plugin-jsx-a11y": "^5.0.1",
|
19
19
|
"eslint-plugin-react": "^7.0.1",
|
20
|
-
"jest": "^
|
20
|
+
"jest": "^21.2.1"
|
21
21
|
},
|
22
22
|
"jest": {
|
23
23
|
"modulePathIgnorePatterns": [
|
@@ -37,7 +37,9 @@
|
|
37
37
|
]
|
38
38
|
}
|
39
39
|
],
|
40
|
-
[
|
40
|
+
[
|
41
|
+
"transform-regenerator"
|
42
|
+
]
|
41
43
|
]
|
42
44
|
},
|
43
45
|
"scripts": {
|
@@ -3,15 +3,15 @@
|
|
3
3
|
-export([steps/1,
|
4
4
|
test_version/0]).
|
5
5
|
|
6
|
-
steps(N) when N =< 0 -> {error, "Only
|
6
|
+
steps(N) when N =< 0 -> {error, "Only positive numbers are allowed"};
|
7
7
|
steps(N) ->
|
8
8
|
steps(N, 0).
|
9
9
|
|
10
10
|
test_version() ->
|
11
|
-
|
11
|
+
2.
|
12
12
|
|
13
13
|
|
14
14
|
|
15
15
|
steps(1, Acc) -> Acc;
|
16
16
|
steps(N, Acc) when N rem 2 =:= 0 -> steps(N div 2, Acc + 1);
|
17
|
-
steps(N, Acc) -> steps(3 * N + 1, Acc + 1).
|
17
|
+
steps(N, Acc) -> steps(3 * N + 1, Acc + 1).
|
@@ -1,24 +1,28 @@
|
|
1
|
-
-module(
|
1
|
+
-module(collatz_conjecture_tests).
|
2
2
|
|
3
3
|
-define(TESTED_MODULE, (sut(collatz_conjecture))).
|
4
|
-
-define(TEST_VERSION,
|
4
|
+
-define(TEST_VERSION, 2).
|
5
5
|
-include("exercism.hrl").
|
6
6
|
|
7
7
|
|
8
8
|
zero_steps_for_one_test() ->
|
9
|
-
|
9
|
+
?assertMatch(0, ?TESTED_MODULE:steps(1)).
|
10
10
|
|
11
11
|
divide_if_even_test() ->
|
12
|
-
|
12
|
+
?assertMatch(4, ?TESTED_MODULE:steps(16)).
|
13
13
|
|
14
14
|
even_and_odd_steps_test() ->
|
15
|
-
|
15
|
+
?assertMatch(9, ?TESTED_MODULE:steps(12)).
|
16
16
|
|
17
17
|
large_number_of_even_and_odd_steps_test() ->
|
18
|
-
|
19
|
-
|
18
|
+
?assertMatch(152, ?TESTED_MODULE:steps(1000000)).
|
19
|
+
|
20
20
|
zero_is_an_error_test() ->
|
21
|
-
|
21
|
+
?assertMatch({error,
|
22
|
+
"Only positive numbers are allowed"},
|
23
|
+
?TESTED_MODULE:steps(0)).
|
22
24
|
|
23
25
|
negative_value_is_an_error_test() ->
|
24
|
-
|
26
|
+
?assertMatch({error,
|
27
|
+
"Only positive numbers are allowed"},
|
28
|
+
?TESTED_MODULE:steps(-15)).
|
@@ -1,18 +1,18 @@
|
|
1
1
|
-module(leap_tests).
|
2
2
|
|
3
3
|
-define(TESTED_MODULE, (sut(leap))).
|
4
|
-
-define(TEST_VERSION,
|
4
|
+
-define(TEST_VERSION, 3).
|
5
5
|
-include("exercism.hrl").
|
6
6
|
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
year_not_divisible_by_4_common_year_test() ->
|
9
|
+
?assertNot(?TESTED_MODULE:leap_year(2015)).
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
year_divisible_by_4_not_divisible_by_100_leap_year_test() ->
|
12
|
+
?assert(?TESTED_MODULE:leap_year(2020)).
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
year_divisible_by_100_not_divisible_by_400_common_year_test() ->
|
15
|
+
?assertNot(?TESTED_MODULE:leap_year(2100)).
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
year_divisible_by_400_leap_year_test() ->
|
18
|
+
?assert(?TESTED_MODULE:leap_year(2000)).
|
@@ -84,19 +84,22 @@ execute(#{command := "generate", spec_path := SpecPath, out_path := OutPath, exe
|
|
84
84
|
Generators1 = lists:map(fun (Generator) -> Generator#tgen{dest = iolist_to_binary([OutPath, $/, Generator#tgen.name])} end, Generators0),
|
85
85
|
Contents = lists:map(fun tgen:generate/1, Generators1),
|
86
86
|
lists:map(
|
87
|
-
fun
|
88
|
-
(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
87
|
+
fun (Xs = [#{exercise := ExName}|_]) ->
|
88
|
+
io:format("Writing ~s", [ExName]),
|
89
|
+
lists:map(fun
|
90
|
+
(#{exercise := GName, name := Name, folder := Folder, content := Content}) ->
|
91
|
+
Path = lists:flatten(io_lib:format("~s/~s/~s/~s.erl", [OutPath, GName, Folder, Name])),
|
92
|
+
case file:open(Path, [write]) of
|
93
|
+
{ok, IODevice} ->
|
94
|
+
io:format(IODevice, "~s", [Content]),
|
95
|
+
file:close(IODevice);
|
96
|
+
{error, Reason} ->
|
97
|
+
io:format("Can not open ~p for writing because of ~p.~n", [Path, Reason])
|
98
|
+
end
|
99
|
+
end, Xs),
|
100
|
+
io:format(", finished~n");
|
101
|
+
({error, Reason, Path}) ->
|
102
|
+
io:format("Can not open ~p for reading because of ~p.~n", [Path, Reason])
|
100
103
|
end, Contents);
|
101
104
|
execute(#{command := "check"}) ->
|
102
105
|
io:format("This command has not been implemented yet");
|
@@ -29,9 +29,11 @@
|
|
29
29
|
}.
|
30
30
|
|
31
31
|
-callback available() -> boolean().
|
32
|
-
-callback
|
33
|
-
-callback
|
34
|
-
|
32
|
+
-callback version() -> pos_integer().
|
33
|
+
-callback generate_test(exercise_json()) ->
|
34
|
+
{ok,
|
35
|
+
erl_syntax:syntax_tree() | [erl_syntax:syntax_tree()],
|
36
|
+
[{string() | binary(), non_neg_integer()}]}.
|
35
37
|
|
36
38
|
|
37
39
|
-spec check(string()) -> {true, atom()} | false.
|
@@ -49,15 +51,9 @@ generate(Generator = #tgen{}) ->
|
|
49
51
|
io:format("Generating ~s", [Generator#tgen.name]),
|
50
52
|
case file:read_file(Generator#tgen.path) of
|
51
53
|
{ok, Content} ->
|
52
|
-
|
53
|
-
TestfilePath = iolist_to_binary([Generator#tgen.dest, "/test/", ModName, ".erl"]),
|
54
|
+
Files = process_json(Generator, Content),
|
54
55
|
io:format(", finished~n"),
|
55
|
-
|
56
|
-
name => Generator#tgen.name,
|
57
|
-
module => ModName,
|
58
|
-
impl => TestModule,
|
59
|
-
path => TestfilePath
|
60
|
-
};
|
56
|
+
Files;
|
61
57
|
{error, Reason} ->
|
62
58
|
io:format(", failed (~p)~n", [Reason]),
|
63
59
|
{error, Reason, Generator#tgen.path}
|
@@ -69,13 +65,16 @@ process_json(#tgen{name = GName, module = Module}, Content) ->
|
|
69
65
|
case jsx:decode(Content, [return_maps, {labels, attempt_atom}]) of
|
70
66
|
_JSON = #{exercise := GName, cases := Cases} ->
|
71
67
|
% io:format("Parsed JSON: ~p~n", [JSON]),
|
72
|
-
{
|
73
|
-
{ok, Test,
|
74
|
-
{[Test|Tests],
|
75
|
-
end, {[],
|
76
|
-
|
77
|
-
|
78
|
-
{
|
68
|
+
{TestImpls0, Props} = lists:foldl(fun (Spec, {Tests, OldProperties}) ->
|
69
|
+
{ok, Test, Properties} = Module:generate_test(Spec),
|
70
|
+
{[Test|Tests], combine(OldProperties, Properties)}
|
71
|
+
end, {[], []}, Cases),
|
72
|
+
TestImpls1 = lists:reverse(TestImpls0),
|
73
|
+
{TestModuleName, TestModuleContent} = generate_test_module(binary_to_list(GName), TestImpls1, Module:version()),
|
74
|
+
{StubModuleName, StubModuleContent} = generate_stub_module(binary_to_list(GName), Props, Module:version()),
|
75
|
+
|
76
|
+
[#{exercise => GName, name => TestModuleName, folder => "test", content => io_lib:format("~s", [TestModuleContent])},
|
77
|
+
#{exercise => GName, name => StubModuleName, folder => "src", content => io_lib:format("~s", [StubModuleContent])}];
|
79
78
|
#{exercise := Name} ->
|
80
79
|
io:format("Name in JSON (~p) and name for generator (~p) do not line up", [Name, GName])
|
81
80
|
end.
|
@@ -92,34 +91,50 @@ slugify(Name) when is_binary(Name) ->
|
|
92
91
|
list_to_binary(slugify(binary_to_list(Name)));
|
93
92
|
slugify(Name) when is_list(Name) ->
|
94
93
|
lists:filtermap(fun
|
95
|
-
(C) when (($a =< C) and (C =< $z)) or (C == $_) -> {true, C};
|
94
|
+
(C) when (($0 =< C) and (C =< $9)) or (($a =< C) and (C =< $z)) or (C == $_) -> {true, C};
|
96
95
|
(C) when (($A =< C) and (C =< $Z)) -> {true, C - $A + $a};
|
97
96
|
(C) when (C == $\s) or (C == $-)-> {true, $_};
|
98
97
|
(_) -> false
|
99
98
|
end, Name).
|
100
99
|
|
101
|
-
|
100
|
+
generate_stub_module(ModuleName, Props, Version) ->
|
101
|
+
SluggedModName = slugify(ModuleName),
|
102
|
+
VersionName = "test_version",
|
103
|
+
Props1 = Props ++ [{VersionName, []}],
|
104
|
+
|
105
|
+
Funs = lists:map(fun
|
106
|
+
({Name, []}) ->
|
107
|
+
tgs:simple_fun(Name, [tgs:atom(undefined)]);
|
108
|
+
({Name, Args}) when is_list(Args) ->
|
109
|
+
tgs:simple_fun(Name, Args, [tgs:atom(undefined)])
|
110
|
+
end, Props) ++ [
|
111
|
+
tgs:simple_fun(VersionName, [tgs:value(Version)])],
|
112
|
+
|
113
|
+
Abstract = [
|
114
|
+
tgs:module(SluggedModName),
|
115
|
+
nl,
|
116
|
+
tgs:export(Props1),
|
117
|
+
nl,
|
118
|
+
nl
|
119
|
+
] ++ inter(nl, Funs),
|
120
|
+
|
121
|
+
{SluggedModName, lists:flatten(
|
122
|
+
lists:map(
|
123
|
+
fun (nl) -> io_lib:format("~n", []);
|
124
|
+
(Tree) -> io_lib:format("~s~n", [erl_prettypr:format(Tree)])
|
125
|
+
end, Abstract))}.
|
126
|
+
|
127
|
+
generate_test_module(ModuleName, Tests, Version) ->
|
102
128
|
SluggedModName = slugify(ModuleName),
|
103
129
|
|
104
130
|
Abstract = [
|
105
|
-
|
106
|
-
erl_syntax:text("module"),
|
107
|
-
[erl_syntax:atom(SluggedModName ++ "_tests")]),
|
131
|
+
tgs:module(SluggedModName ++ "_tests"),
|
108
132
|
nl,
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
erl_syntax:text("sut"), [
|
115
|
-
erl_syntax:atom(SluggedModName)]))]),
|
116
|
-
erl_syntax:attribute(
|
117
|
-
erl_syntax:text("define"), [
|
118
|
-
erl_syntax:text("TEST_VERSION"),
|
119
|
-
erl_syntax:text(Version)]),
|
120
|
-
erl_syntax:attribute(
|
121
|
-
erl_syntax:text("include"), [
|
122
|
-
erl_syntax:abstract("exercism.hrl")]),
|
133
|
+
tgs:define("TESTED_MODULE",
|
134
|
+
tgs:parens(
|
135
|
+
tgs:call_fun("sut", [tgs:atom(SluggedModName)]))),
|
136
|
+
tgs:define("TEST_VERSION", tgs:value(Version)),
|
137
|
+
tgs:include("exercism.hrl"),
|
123
138
|
nl,
|
124
139
|
nl] ++ inter(nl, Tests),
|
125
140
|
|
@@ -131,4 +146,16 @@ generate_module(ModuleName, Tests, Version) ->
|
|
131
146
|
|
132
147
|
inter(_, []) -> [];
|
133
148
|
inter(_, [X]) -> [X];
|
134
|
-
inter(Delim, [X|Xs]) -> [X, Delim|Xs].
|
149
|
+
inter(Delim, [X|Xs]) -> [X, Delim|inter(Delim, Xs)].
|
150
|
+
|
151
|
+
combine(List, []) -> List;
|
152
|
+
combine(List, [{Name, Arity}|Xs]) when is_list(Name) ->
|
153
|
+
combine(List, [{list_to_binary(Name), Arity}|Xs]);
|
154
|
+
combine(List, [{Name, _} = X|Xs]) when is_binary(Name) ->
|
155
|
+
List1 = insert(List, X),
|
156
|
+
combine(List1, Xs).
|
157
|
+
|
158
|
+
insert([], X) -> [X];
|
159
|
+
insert([X|_] = Xs, X) -> Xs;
|
160
|
+
insert([X|XS], Y) when X < Y -> [X|insert(XS, Y)];
|
161
|
+
insert([X|XS], Y) when X > Y -> [Y, X|XS].
|
@@ -0,0 +1,38 @@
|
|
1
|
+
-module('tgen_collatz-conjecture').
|
2
|
+
|
3
|
+
-behaviour(tgen).
|
4
|
+
|
5
|
+
-export([
|
6
|
+
available/0,
|
7
|
+
version/0,
|
8
|
+
generate_test/1
|
9
|
+
]).
|
10
|
+
|
11
|
+
-spec available() -> true.
|
12
|
+
available() ->
|
13
|
+
true.
|
14
|
+
|
15
|
+
version() -> 2.
|
16
|
+
|
17
|
+
generate_test(#{description := Desc, expected := #{error := Message}, property := Prop, number := Num}) ->
|
18
|
+
TestName = tgen:to_test_name(Desc),
|
19
|
+
Property = binary_to_list(Prop),
|
20
|
+
|
21
|
+
Fn = tgs:simple_fun(TestName, [
|
22
|
+
tgs:call_macro("assertMatch", [
|
23
|
+
tgs:value({error, binary_to_list(Message)}),
|
24
|
+
tgs:call_macro("TESTED_MODULE:" ++ Property, [
|
25
|
+
tgs:value(Num)])])]),
|
26
|
+
|
27
|
+
{ok, Fn, [{Prop, ["N"]}]};
|
28
|
+
generate_test(#{description := Desc, expected := Exp, property := Prop, number := Num}) ->
|
29
|
+
TestName = tgen:to_test_name(Desc),
|
30
|
+
Property = binary_to_list(Prop),
|
31
|
+
|
32
|
+
Fn = tgs:simple_fun(TestName, [
|
33
|
+
tgs:call_macro("assertMatch", [
|
34
|
+
tgs:value(Exp),
|
35
|
+
tgs:call_macro("TESTED_MODULE:" ++ Property, [
|
36
|
+
tgs:value(Num)])])]),
|
37
|
+
|
38
|
+
{ok, Fn, [{Prop, ["N"]}]}.
|
@@ -4,32 +4,24 @@
|
|
4
4
|
|
5
5
|
-export([
|
6
6
|
available/0,
|
7
|
-
|
8
|
-
|
9
|
-
generate_test/2
|
7
|
+
version/0,
|
8
|
+
generate_test/1
|
10
9
|
]).
|
11
10
|
|
12
11
|
-spec available() -> true.
|
13
12
|
available() ->
|
14
13
|
true.
|
15
14
|
|
16
|
-
|
17
|
-
{ok, Name}.
|
15
|
+
version() -> 2.
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
generate_test(#{description := Desc, expected := Exp, property := Prop}, State) ->
|
17
|
+
generate_test(#{description := Desc, expected := Exp, property := Prop}) ->
|
22
18
|
TestName = tgen:to_test_name(Desc),
|
23
19
|
Expected = binary_to_list(Exp),
|
24
20
|
Property = binary_to_list(Prop),
|
25
|
-
|
26
|
-
Fn =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
erl_syntax:application(
|
33
|
-
erl_syntax:text("?TESTED_MODULE:" ++ Property), [])])])]),
|
34
|
-
|
35
|
-
{ok, Fn, State}.
|
21
|
+
|
22
|
+
Fn = tgs:simple_fun(TestName, [
|
23
|
+
tgs:call_macro("assertEqual", [
|
24
|
+
tgs:value(Expected),
|
25
|
+
tgs:call_macro("TESTED_MODULE:" ++ Property, [])])]),
|
26
|
+
|
27
|
+
{ok, Fn, [{Prop, []}]}.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
-module('tgen_leap').
|
2
|
+
|
3
|
+
-behaviour(tgen).
|
4
|
+
|
5
|
+
-export([
|
6
|
+
available/0,
|
7
|
+
version/0,
|
8
|
+
generate_test/1
|
9
|
+
]).
|
10
|
+
|
11
|
+
-spec available() -> true.
|
12
|
+
available() ->
|
13
|
+
true.
|
14
|
+
|
15
|
+
version() -> 3.
|
16
|
+
|
17
|
+
generate_test(#{description := Desc, expected := Exp, property := <<"leapYear">>, input := In}) ->
|
18
|
+
TestName = tgen:to_test_name(Desc),
|
19
|
+
Property = "leap_year",
|
20
|
+
|
21
|
+
Assert = case Exp of
|
22
|
+
true -> "assert";
|
23
|
+
false -> "assertNot"
|
24
|
+
end,
|
25
|
+
|
26
|
+
Fn = tgs:simple_fun(TestName, [
|
27
|
+
tgs:call_macro(Assert, [
|
28
|
+
tgs:call_macro("TESTED_MODULE:" ++ Property, [
|
29
|
+
tgs:value(In)])])]),
|
30
|
+
|
31
|
+
{ok, Fn, [{Property, ["Year"]}]}.
|