trackler 2.1.0.0 → 2.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/connect/description.md +2 -1
- data/common/exercises/crypto-square/canonical-data.json +2 -2
- data/common/exercises/two-bucket/canonical-data.json +27 -1
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/exercises/perfect-numbers/src/example.c +8 -4
- data/tracks/clojure/config.json +5 -0
- data/tracks/clojure/exercises/secret-handshake/project.clj +4 -0
- data/tracks/clojure/exercises/secret-handshake/src/example.clj +19 -0
- data/tracks/clojure/exercises/secret-handshake/test/secret_handshake_test.clj +55 -0
- data/tracks/cpp/.travis.yml +4 -3
- data/tracks/cpp/README.md +1 -1
- data/tracks/cpp/config.json +171 -67
- data/tracks/cpp/docs/ABOUT.md +2 -2
- data/tracks/cpp/docs/INSTALLATION.md +22 -28
- data/tracks/cpp/docs/TESTS.md +1 -1
- data/tracks/cpp/exercises/anagram/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/beer-song/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/binary/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/bob/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/clock/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/clock/clock_test.cpp +188 -64
- data/tracks/cpp/exercises/clock/example.cpp +17 -12
- data/tracks/cpp/exercises/clock/example.h +1 -0
- data/tracks/cpp/exercises/crypto-square/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/difference-of-squares/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/etl/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/etl/etl_test.cpp +5 -5
- data/tracks/cpp/exercises/food-chain/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/gigasecond/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/gigasecond/example.cpp +2 -6
- data/tracks/cpp/exercises/gigasecond/example.h +2 -2
- data/tracks/cpp/exercises/gigasecond/gigasecond_test.cpp +26 -8
- data/tracks/cpp/exercises/grade-school/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/grade-school/grade_school_test.cpp +5 -6
- data/tracks/cpp/exercises/grains/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/hamming/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/hello-world/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/hexadecimal/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/leap/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/meetup/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/meetup/meetup_test.cpp +1 -1
- data/tracks/cpp/exercises/nth-prime/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/nucleotide-count/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/nucleotide-count/nucleotide_count_test.cpp +3 -4
- data/tracks/cpp/exercises/phone-number/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/prime-factors/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/queen-attack/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/raindrops/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/rna-transcription/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/robot-name/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/roman-numerals/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/say/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/scrabble-score/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/series/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/series/series_test.cpp +11 -11
- data/tracks/cpp/exercises/sieve/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/space-age/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/sum-of-multiples/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/triangle/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/trinary/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/word-count/CMakeLists.txt +2 -9
- data/tracks/cpp/exercises/word-count/word_count_test.cpp +14 -15
- data/tracks/go/README.md +27 -13
- data/tracks/go/config.json +1 -0
- data/tracks/go/exercises/connect/.meta/gen.go +1 -3
- data/tracks/go/exercises/connect/cases_test.go +2 -1
- data/tracks/go/exercises/custom-set/.meta/gen.go +122 -101
- data/tracks/go/exercises/custom-set/cases_test.go +13 -4
- data/tracks/go/exercises/custom-set/custom_set_test.go +2 -2
- data/tracks/go/exercises/hamming/.meta/gen.go +1 -3
- data/tracks/go/exercises/hamming/cases_test.go +7 -1
- data/tracks/go/exercises/hamming/example.go +1 -1
- data/tracks/go/exercises/hamming/hamming_test.go +1 -1
- data/tracks/go/exercises/hello-world/{hello_example_test.go → example_helloworld_test.go} +0 -0
- data/tracks/go/exercises/house/house_test.go +8 -8
- data/tracks/go/exercises/meetup/.meta/gen.go +1 -3
- data/tracks/go/exercises/meetup/cases_test.go +2 -1
- data/tracks/go/exercises/palindrome-products/example.go +1 -1
- data/tracks/go/exercises/palindrome-products/palindrome_products_test.go +1 -1
- data/tracks/go/exercises/pascals-triangle/pascals_triangle_test.go +24 -4
- data/tracks/go/exercises/rna-transcription/.meta/gen.go +1 -3
- data/tracks/go/exercises/rna-transcription/cases_test.go +2 -1
- data/tracks/go/exercises/roman-numerals/.meta/gen.go +1 -3
- data/tracks/go/exercises/roman-numerals/cases_test.go +2 -1
- data/tracks/go/exercises/roman-numerals/example.go +1 -1
- data/tracks/go/exercises/transpose/.meta/gen.go +1 -3
- data/tracks/go/exercises/transpose/cases_test.go +2 -1
- data/tracks/go/exercises/transpose/transpose_test.go +5 -0
- data/tracks/go/exercises/word-count/.meta/gen.go +1 -3
- data/tracks/go/exercises/word-count/cases_test.go +2 -1
- data/tracks/go/gen/gen.go +3 -2
- data/tracks/java/config.json +5 -0
- data/tracks/java/exercises/saddle-points/build.gradle +17 -0
- data/tracks/java/exercises/saddle-points/src/example/java/Matrix.java +44 -0
- data/tracks/java/exercises/saddle-points/src/example/java/MatrixCoordinate.java +31 -0
- data/tracks/java/exercises/saddle-points/src/main/java/Matrix.java +5 -0
- data/tracks/java/exercises/saddle-points/src/main/java/MatrixCoordinate.java +31 -0
- data/tracks/java/exercises/saddle-points/src/test/java/MatrixTest.java +82 -0
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/javascript/.travis.yml +3 -1
- data/tracks/javascript/Makefile +2 -8
- data/tracks/javascript/SETUP.md +1 -2
- data/tracks/javascript/docs/INSTALLATION.md +3 -4
- data/tracks/javascript/docs/TESTS.md +14 -26
- data/tracks/javascript/exercises/hamming/example.js +7 -11
- data/tracks/javascript/exercises/hello-world/HINTS.md +3 -3
- data/tracks/javascript/exercises/robot-simulator/example.js +72 -73
- data/tracks/perl6/config.json +5 -0
- data/tracks/perl6/exercises/clock/Clock.pm6 +4 -0
- data/tracks/perl6/exercises/clock/Example.pm6 +12 -0
- data/tracks/perl6/exercises/clock/clock.t +534 -0
- data/tracks/perl6/exercises/clock/example.yaml +16 -0
- data/tracks/perl6/exercises/robot-name/Example.pm +11 -4
- data/tracks/php/exercises/hello-world/hello-world.php +1 -1
- data/tracks/php/exercises/hello-world/hello-world_test.php +1 -11
- data/tracks/php/exercises/robot-name/robot-name_test.php +1 -0
- data/tracks/purescript/config.json +7 -0
- data/tracks/purescript/exercises/largest-series-product/bower.json +16 -0
- data/tracks/purescript/exercises/largest-series-product/examples/src/LargestSeriesProduct.purs +31 -0
- data/tracks/purescript/exercises/largest-series-product/src/LargestSeriesProduct.purs +3 -0
- data/tracks/purescript/exercises/largest-series-product/test/Main.purs +73 -0
- data/tracks/python/exercises/sublist/sublist_test.py +94 -55
- data/tracks/ruby/README.md +38 -25
- data/tracks/ruby/exercises/hamming/example.tt +6 -4
- data/tracks/ruby/exercises/hamming/hamming_test.rb +4 -5
- data/tracks/ruby/exercises/linked-list/linked_list_test.rb +16 -0
- data/tracks/ruby/exercises/luhn/luhn_test.rb +5 -5
- data/tracks/ruby/exercises/ocr-numbers/.meta/.version +1 -0
- data/tracks/ruby/exercises/ocr-numbers/example.rb +42 -61
- data/tracks/ruby/exercises/ocr-numbers/example.tt +21 -0
- data/tracks/ruby/exercises/ocr-numbers/ocr_numbers_test.rb +63 -138
- data/tracks/ruby/lib/generator/exercise_cases.rb +43 -0
- data/tracks/ruby/lib/generator/underscore.rb +9 -0
- data/tracks/ruby/lib/hamming_cases.rb +9 -14
- data/tracks/ruby/lib/luhn_cases.rb +2 -18
- data/tracks/ruby/lib/ocr_numbers_cases.rb +20 -0
- data/tracks/ruby/lib/pig_latin_cases.rb +2 -12
- data/tracks/ruby/test/generator/underscore_test.rb +23 -0
- data/tracks/scala/config.json +316 -316
- metadata +26 -10
- data/tracks/cpp/exercises/etl/require_equal_containers.h +0 -88
- data/tracks/cpp/exercises/grade-school/require_equal_containers.h +0 -88
- data/tracks/cpp/exercises/nucleotide-count/require_equal_containers.h +0 -88
- data/tracks/cpp/exercises/series/require_equal_containers.h +0 -88
- data/tracks/cpp/exercises/word-count/require_equal_containers.h +0 -88
- data/tracks/javascript/exercises/acronym/package.json +0 -12
- data/tracks/javascript/package.json +0 -12
@@ -0,0 +1,16 @@
|
|
1
|
+
exercise: Clock
|
2
|
+
version: 1
|
3
|
+
methods: time add-minutes
|
4
|
+
plan: 54
|
5
|
+
tests: |
|
6
|
+
is ::($exercise).new(hour => .<hour>, minute => .<minute>).?time, |.<expected description> for @($c-data<cases>[0]<cases>);
|
7
|
+
for @($c-data<cases>[1]<cases>) {
|
8
|
+
my $clock = ::($exercise).new(hour => .<hour>, minute => .<minute>);
|
9
|
+
$clock.?add-minutes(.<add>);
|
10
|
+
is $clock.?time, |.<expected description>;
|
11
|
+
}
|
12
|
+
is ::($exercise).new(hour => .<clock1><hour>, minute => .<clock1><minute>).?time eq
|
13
|
+
::($exercise).new(hour => .<clock2><hour>, minute => .<clock2><minute>).?time,
|
14
|
+
|.<expected description> for @($c-data<cases>[2]<cases>);
|
15
|
+
todo 'optional test' unless %*ENV<EXERCISM>;
|
16
|
+
is ::($exercise).new(:0hour,:0minute).?add-minutes(65).?time, '01:05', 'add-minutes method can be chained';
|
@@ -1,11 +1,18 @@
|
|
1
1
|
unit class Robot:ver<1>;
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
has Str:D $.name = self.reset-name;
|
3
|
+
subset Name of Str where * ~~ /^<[A..Z]>**2 <[0..9]>**3$/;
|
4
|
+
has Name $.name = self.reset-name;
|
6
5
|
|
7
6
|
method reset-name {
|
8
|
-
|
7
|
+
state Promise:D $promise = start ('AA000'..'ZZ999').pick: *;
|
8
|
+
state Bool:D %record{Name:D};
|
9
|
+
state Int:D $i = 0;
|
10
|
+
|
11
|
+
if $promise.status ~~ 'Kept' {
|
12
|
+
($!name = $promise.result[$i++]) or die 'All names used.';
|
13
|
+
} else {
|
14
|
+
$!name = ('A'..'Z').roll(2).join ~ (^10).roll(3).join;
|
15
|
+
}
|
9
16
|
self.reset-name if %record{$!name}:exists;
|
10
17
|
%record{$!name} = True;
|
11
18
|
return $!name;
|
@@ -4,18 +4,8 @@ require "hello-world.php";
|
|
4
4
|
|
5
5
|
class HelloWorldTest extends PHPUnit\Framework\TestCase
|
6
6
|
{
|
7
|
-
public function
|
7
|
+
public function testHelloWorld()
|
8
8
|
{
|
9
9
|
$this->assertEquals('Hello, World!', helloWorld());
|
10
10
|
}
|
11
|
-
|
12
|
-
public function testSampleName()
|
13
|
-
{
|
14
|
-
$this->assertEquals('Hello, Alice!', helloWorld('Alice'));
|
15
|
-
}
|
16
|
-
|
17
|
-
public function testAnotherSampleName()
|
18
|
-
{
|
19
|
-
$this->assertEquals('Hello, Bob!', helloWorld('Bob'));
|
20
|
-
}
|
21
11
|
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"name": "largest-series-product",
|
3
|
+
"ignore": [
|
4
|
+
"**/.*",
|
5
|
+
"node_modules",
|
6
|
+
"bower_components",
|
7
|
+
"output"
|
8
|
+
],
|
9
|
+
"dependencies": {
|
10
|
+
"purescript-prelude": "^3.0.0"
|
11
|
+
},
|
12
|
+
"devDependencies": {
|
13
|
+
"purescript-psci-support": "^3.0.0",
|
14
|
+
"purescript-test-unit": "^11.0.0"
|
15
|
+
}
|
16
|
+
}
|
data/tracks/purescript/exercises/largest-series-product/examples/src/LargestSeriesProduct.purs
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module LargestSeriesProduct
|
2
|
+
( largestProduct
|
3
|
+
) where
|
4
|
+
|
5
|
+
import Prelude
|
6
|
+
import Data.Array (drop, length, take, (:))
|
7
|
+
import Data.Foldable (maximum, product)
|
8
|
+
import Data.Int (fromString)
|
9
|
+
import Data.Maybe (Maybe(..))
|
10
|
+
import Data.String (singleton, toCharArray)
|
11
|
+
import Data.Traversable (sequence)
|
12
|
+
|
13
|
+
spans :: forall a. Int -> Array a -> Array (Array a)
|
14
|
+
spans n a
|
15
|
+
| length a < n = []
|
16
|
+
| otherwise = take n a : spans n (drop 1 a)
|
17
|
+
|
18
|
+
toIntArray :: String -> Maybe (Array Int)
|
19
|
+
toIntArray = toCharArray
|
20
|
+
>>> map (singleton >>> fromString)
|
21
|
+
>>> sequence
|
22
|
+
|
23
|
+
largestProduct :: String -> Int -> Maybe Int
|
24
|
+
largestProduct digits span
|
25
|
+
| span == 0 = Just 1
|
26
|
+
| span < 0 = Nothing
|
27
|
+
| otherwise = do
|
28
|
+
is <- toIntArray digits
|
29
|
+
spans span is
|
30
|
+
# map product
|
31
|
+
# maximum
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Test.Main where
|
2
|
+
|
3
|
+
import Prelude
|
4
|
+
import Control.Monad.Eff (Eff)
|
5
|
+
import Data.Maybe (Maybe(..))
|
6
|
+
import Test.Unit.Assert as Assert
|
7
|
+
import Test.Unit (suite, test)
|
8
|
+
import Test.Unit.Main (runTest)
|
9
|
+
import LargestSeriesProduct (largestProduct)
|
10
|
+
|
11
|
+
main :: Eff _ Unit
|
12
|
+
main = runTest do
|
13
|
+
suite "LargestSeriesProduct.largestProduct" do
|
14
|
+
|
15
|
+
test "finds the largest product if span equals length" $
|
16
|
+
Assert.equal (Just 18)
|
17
|
+
(largestProduct "29" 2)
|
18
|
+
|
19
|
+
test "can find the largest product of 2 with numbers in order" $
|
20
|
+
Assert.equal (Just 72)
|
21
|
+
(largestProduct "0123456789" 2)
|
22
|
+
|
23
|
+
test "can find the largest product of 2" $
|
24
|
+
Assert.equal (Just 48)
|
25
|
+
(largestProduct "576802143" 2)
|
26
|
+
|
27
|
+
test "can find the largest product of 3 with numbers in order" $
|
28
|
+
Assert.equal (Just 504)
|
29
|
+
(largestProduct "0123456789" 3)
|
30
|
+
|
31
|
+
test "can find the largest product of 3" $
|
32
|
+
Assert.equal (Just 270)
|
33
|
+
(largestProduct "1027839564" 3)
|
34
|
+
|
35
|
+
test "can find the largest product of 5 with numbers in order" $
|
36
|
+
Assert.equal (Just 15120)
|
37
|
+
(largestProduct "0123456789" 5)
|
38
|
+
|
39
|
+
test "can get the largest product of a big number" $
|
40
|
+
Assert.equal (Just 23520)
|
41
|
+
(largestProduct "73167176531330624919225119674426574742355349194934" 6)
|
42
|
+
|
43
|
+
test "reports zero if the only digits are zero" $
|
44
|
+
Assert.equal (Just 0)
|
45
|
+
(largestProduct "0000" 2)
|
46
|
+
|
47
|
+
test "reports zero if all spans include zero" $
|
48
|
+
Assert.equal (Just 0)
|
49
|
+
(largestProduct "99099" 3)
|
50
|
+
|
51
|
+
test "rejects span longer than string length" $
|
52
|
+
Assert.equal Nothing
|
53
|
+
(largestProduct "123" 4)
|
54
|
+
|
55
|
+
test "reports 1 for empty string and empty product (0 span)" $
|
56
|
+
Assert.equal (Just 1)
|
57
|
+
(largestProduct "" 0)
|
58
|
+
|
59
|
+
test "reports 1 for nonempty string and empty product (0 span)" $
|
60
|
+
Assert.equal (Just 1)
|
61
|
+
(largestProduct "123" 0)
|
62
|
+
|
63
|
+
test "rejects empty string and nonzero span" $
|
64
|
+
Assert.equal Nothing
|
65
|
+
(largestProduct "" 1)
|
66
|
+
|
67
|
+
test "rejects invalid character in digits" $
|
68
|
+
Assert.equal Nothing
|
69
|
+
(largestProduct "1234a5" 2)
|
70
|
+
|
71
|
+
test "rejects negative span" $
|
72
|
+
Assert.equal Nothing
|
73
|
+
(largestProduct "12345" (-1))
|
@@ -3,94 +3,133 @@ import unittest
|
|
3
3
|
from sublist import check_lists, SUBLIST, SUPERLIST, EQUAL, UNEQUAL
|
4
4
|
|
5
5
|
|
6
|
+
# test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
|
7
|
+
|
6
8
|
class SublistTest(unittest.TestCase):
|
7
|
-
def
|
9
|
+
def test_unique_return_values(self):
|
8
10
|
self.assertEqual(len(set([SUBLIST, SUPERLIST, EQUAL, UNEQUAL])), 4)
|
9
11
|
|
10
12
|
def test_empty_lists(self):
|
11
|
-
self.assertEqual(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def
|
17
|
-
self.assertEqual(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
self.assertEqual(
|
14
|
+
check_lists([], []),
|
15
|
+
EQUAL
|
16
|
+
)
|
17
|
+
|
18
|
+
def test_empty_list_within_non_empty_list(self):
|
19
|
+
self.assertEqual(
|
20
|
+
check_lists([], [1, 2, 3]),
|
21
|
+
SUBLIST
|
22
|
+
)
|
23
|
+
|
24
|
+
def test_non_empty_list_contains_empty_list(self):
|
25
|
+
self.assertEqual(
|
26
|
+
check_lists([1, 2, 3], []),
|
27
|
+
SUPERLIST
|
28
|
+
)
|
29
|
+
|
30
|
+
def test_list_equals_itself(self):
|
31
|
+
self.assertEqual(
|
32
|
+
check_lists([1, 2, 3], [1, 2, 3]),
|
33
|
+
EQUAL
|
34
|
+
)
|
23
35
|
|
24
36
|
def test_different_lists(self):
|
25
|
-
|
26
|
-
|
27
|
-
|
37
|
+
self.assertEqual(
|
38
|
+
check_lists([1, 2, 3], [2, 3, 4]),
|
39
|
+
UNEQUAL
|
40
|
+
)
|
28
41
|
|
29
42
|
def test_false_start(self):
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
self.assertEqual(
|
44
|
+
check_lists([1, 2, 5], [0, 1, 2, 3, 1, 2, 5, 6]),
|
45
|
+
SUBLIST
|
46
|
+
)
|
33
47
|
|
34
48
|
def test_consecutive(self):
|
35
|
-
|
36
|
-
|
37
|
-
|
49
|
+
self.assertEqual(
|
50
|
+
check_lists([1, 1, 2], [0, 1, 1, 1, 2, 1, 2]),
|
51
|
+
SUBLIST
|
52
|
+
)
|
38
53
|
|
39
54
|
def test_sublist_at_start(self):
|
40
|
-
|
41
|
-
|
42
|
-
|
55
|
+
self.assertEqual(
|
56
|
+
check_lists([0, 1, 2], [0, 1, 2, 3, 4, 5]),
|
57
|
+
SUBLIST
|
58
|
+
)
|
43
59
|
|
44
60
|
def test_sublist_in_middle(self):
|
45
|
-
|
46
|
-
|
47
|
-
|
61
|
+
self.assertEqual(
|
62
|
+
check_lists([2, 3, 4], [0, 1, 2, 3, 4, 5]),
|
63
|
+
SUBLIST
|
64
|
+
)
|
48
65
|
|
49
66
|
def test_sublist_at_end(self):
|
50
|
-
|
51
|
-
|
52
|
-
|
67
|
+
self.assertEqual(
|
68
|
+
check_lists([3, 4, 5], [0, 1, 2, 3, 4, 5]),
|
69
|
+
SUBLIST
|
70
|
+
)
|
53
71
|
|
54
72
|
def test_at_start_of_superlist(self):
|
55
|
-
|
56
|
-
|
57
|
-
|
73
|
+
self.assertEqual(
|
74
|
+
check_lists([0, 1, 2, 3, 4, 5], [0, 1, 2]),
|
75
|
+
SUPERLIST
|
76
|
+
)
|
58
77
|
|
59
78
|
def test_in_middle_of_superlist(self):
|
60
|
-
|
61
|
-
|
62
|
-
|
79
|
+
self.assertEqual(
|
80
|
+
check_lists([0, 1, 2, 3, 4, 5], [2, 3]),
|
81
|
+
SUPERLIST
|
82
|
+
)
|
63
83
|
|
64
84
|
def test_at_end_of_superlist(self):
|
65
|
-
|
66
|
-
|
67
|
-
|
85
|
+
self.assertEqual(
|
86
|
+
check_lists([0, 1, 2, 3, 4, 5], [3, 4, 5]),
|
87
|
+
SUPERLIST
|
88
|
+
)
|
89
|
+
|
90
|
+
def test_first_list_missing_element_from_second_list(self):
|
91
|
+
self.assertEqual(
|
92
|
+
check_lists([1, 3], [1, 2, 3]),
|
93
|
+
UNEQUAL
|
94
|
+
)
|
95
|
+
|
96
|
+
def test_second_list_missing_element_from_first_list(self):
|
97
|
+
self.assertEqual(
|
98
|
+
check_lists([1, 2, 3], [1, 3]),
|
99
|
+
UNEQUAL
|
100
|
+
)
|
101
|
+
|
102
|
+
def test_order_matters_to_a_list(self):
|
103
|
+
self.assertEqual(
|
104
|
+
check_lists([1, 2, 3], [3, 2, 1]),
|
105
|
+
UNEQUAL
|
106
|
+
)
|
107
|
+
|
108
|
+
def test_same_digits_but_different_numbers(self):
|
109
|
+
self.assertEqual(
|
110
|
+
check_lists([1, 0, 1], [10, 1]),
|
111
|
+
UNEQUAL
|
112
|
+
)
|
113
|
+
|
114
|
+
# additional track specific test
|
115
|
+
def test_inner_spaces(self):
|
116
|
+
self.assertEqual(
|
117
|
+
check_lists(['a c'], ['a', 'c']),
|
118
|
+
UNEQUAL
|
119
|
+
)
|
68
120
|
|
121
|
+
# additional track specific test
|
69
122
|
def test_large_lists(self):
|
70
123
|
l1 = list(range(1000)) * 1000 + list(range(1000, 1100))
|
71
124
|
l2 = list(range(900, 1050))
|
72
125
|
self.assertEqual(check_lists(l1, l2), SUPERLIST)
|
73
126
|
|
127
|
+
# additional track specific test
|
74
128
|
def test_spread_sublist(self):
|
75
129
|
multiples_of_3 = list(range(3, 200, 3))
|
76
130
|
multiples_of_15 = list(range(15, 200, 15))
|
77
131
|
self.assertEqual(check_lists(multiples_of_15, multiples_of_3), UNEQUAL)
|
78
132
|
|
79
|
-
def test_double_digits(self):
|
80
|
-
l1 = [1, 0, 1]
|
81
|
-
l2 = [10, 1]
|
82
|
-
self.assertEqual(check_lists(l1, l2), UNEQUAL)
|
83
|
-
|
84
|
-
def test_inner_spaces(self):
|
85
|
-
l1 = ['a c']
|
86
|
-
l2 = ['a', 'c']
|
87
|
-
self.assertEqual(check_lists(l1, l2), UNEQUAL)
|
88
|
-
|
89
|
-
def test_avoid_sets(self):
|
90
|
-
self.assertEqual(check_lists([1, 3], [1, 2, 3]), UNEQUAL)
|
91
|
-
self.assertEqual(check_lists([1, 2, 3], [1, 3]), UNEQUAL)
|
92
|
-
self.assertEqual(check_lists([1, 2, 3], [3, 2, 1]), UNEQUAL)
|
93
|
-
|
94
133
|
|
95
134
|
if __name__ == '__main__':
|
96
135
|
unittest.main()
|
data/tracks/ruby/README.md
CHANGED
@@ -114,54 +114,48 @@ the exercise, which lives in the x-common repository.
|
|
114
114
|
This change will need to be submitted as a pull request to the x-common repository. This pull
|
115
115
|
request needs to be merged before you can regenerate the exercise.
|
116
116
|
|
117
|
-
Changes that don't have to do directly with the test inputs and outputs, will
|
118
|
-
made to `
|
119
|
-
exercise with
|
117
|
+
Changes that don't have to do directly with the test inputs and outputs, will
|
118
|
+
most likely be made to `lib/$PROBLEM_cases.rb` but may also be made to
|
119
|
+
`exercises/$PROBLEM/example.tt`. Then you can regenerate the exercise with
|
120
|
+
`bin/generate $PROBLEM`.
|
120
121
|
|
121
122
|
#### Implementing a Generator
|
122
123
|
|
123
|
-
You will need to implement
|
124
|
+
You will need to implement two files and a directory to create a generator:
|
124
125
|
|
125
|
-
1. `exercises/$PROBLEM/example.tt` - the Erb template for the test file, `$PROBLEM_test.rb`.
|
126
|
-
1. `exercises/$PROBLEM/.meta/.version` - used to keep track of the version of the test files as the data changes.
|
127
126
|
1. `lib/$PROBLEM_cases.rb` - the logic for turning the data into tests.
|
127
|
+
1. `exercises/$PROBLEM/example.tt` - the Erb template for the test file, `$PROBLEM_test.rb`.
|
128
|
+
1. `exercises/$PROBLEM/.meta/` - metadata directory, currently contains version file
|
128
129
|
|
129
130
|
You will not need to touch the top-level script, `bin/generate`.
|
130
131
|
|
131
132
|
The `bin/generate` command relies on some common logic implemented in `lib/generator.rb`.
|
132
133
|
You probably won't need to touch that, either.
|
133
134
|
|
134
|
-
|
135
|
+
`lib/$PROBLEM_cases.rb` contains a derived class of `ExerciseCase` (in `lib/generator/exercise_cases.rb`)
|
136
|
+
which wraps the JSON for a single test case. The default version looks something like this:
|
135
137
|
|
136
138
|
```
|
137
|
-
|
138
|
-
|
139
|
-
class ProblemNameCase < OpenStruct
|
140
|
-
def name
|
141
|
-
'test_%s' % description.gsub(/[ -]/, '_')
|
142
|
-
end
|
139
|
+
class ProblemNameCase < ExerciseCase
|
143
140
|
|
144
141
|
def workload
|
145
142
|
# Example workload:
|
146
|
-
"
|
143
|
+
"#{assert} Problem.call(#{input.inspect})"
|
147
144
|
end
|
148
145
|
|
149
|
-
def skipped
|
150
|
-
index.zero? ? '# skip' : 'skip'
|
151
|
-
end
|
152
146
|
end
|
153
147
|
```
|
154
148
|
|
155
|
-
Instead of `ProblemName` use the name of the actual problem. This is important, since
|
149
|
+
Instead of `ProblemName` use the CamelCased name of the actual problem. This is important, since
|
156
150
|
the generator script will infer the name of the class from the argument that is passed.
|
157
151
|
|
158
|
-
This class must
|
159
|
-
|
160
|
-
- `name` - Returns the name of the test (i.e `test_one_equals_one`)
|
161
|
-
- `workload` - Returns the main syntax for the test. This includes the assertion and any setup required for the test. This will vary depending on the test generator and its underlying implementation
|
162
|
-
- `skipped` - Returns skip syntax (i.e. `skip` or `# skip`)
|
152
|
+
This class must provide the methods used by `example.tt`. The base class provides methods
|
153
|
+
for the default template for everything except `workload`.
|
163
154
|
|
164
|
-
|
155
|
+
`workload` generates the code for the body of a test, including the assertion
|
156
|
+
and any setup required. The base class provides a variety of assertion and
|
157
|
+
helper methods. Beyond that, you can implement any helper methods that you need
|
158
|
+
as private methods in your derived class. See below for more information about [the intention of workload](#workload-philosophy)
|
165
159
|
|
166
160
|
Below this class, implement a small loop that will generate all the test cases by reading the
|
167
161
|
`canonical-data.json` file, and looping through the test cases.
|
@@ -198,7 +192,8 @@ end
|
|
198
192
|
|
199
193
|
Finally, you need to create a text template, `example.tt`, as the bases for the test suite.
|
200
194
|
|
201
|
-
Start with the following boilerplate, and adjust as necessary
|
195
|
+
Start with the following boilerplate, and adjust as necessary. Remember, however, to strive
|
196
|
+
to keep logic out of views.
|
202
197
|
|
203
198
|
```
|
204
199
|
#!/usr/bin/env ruby
|
@@ -216,12 +211,30 @@ class ProblemNameTest < Minitest::Test
|
|
216
211
|
|
217
212
|
<% end %>
|
218
213
|
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
|
214
|
+
|
219
215
|
def test_bookkeeping
|
220
216
|
skip
|
221
217
|
assert_equal <%= version %>, BookKeeping::VERSION
|
222
218
|
end
|
223
219
|
end
|
224
220
|
```
|
221
|
+
### Workload philosophy.
|
222
|
+
|
223
|
+
Prioritize educational value over expert comprehension and make sure that
|
224
|
+
things are clear to people who may not be familiar with Minitest and even Ruby.
|
225
|
+
|
226
|
+
Provide the information the student needs to derive the code to pass the test
|
227
|
+
in a clear and consistent manner. Illustrate the purpose of the individual
|
228
|
+
elements of the assertion by using meaningful variable names.
|
229
|
+
|
230
|
+
Example output from the `workload` method:
|
231
|
+
```ruby
|
232
|
+
detector = Anagram.new('allergy')
|
233
|
+
anagrams = detector.match(["gallery", "ballerina", "regally", "clergy", "largely", "leading"])
|
234
|
+
expected = ["gallery", "largely", "regally"]
|
235
|
+
assert_equal expected, anagrams.sort
|
236
|
+
```
|
237
|
+
|
225
238
|
|
226
239
|
## Pull Requests
|
227
240
|
|