trackler 2.0.8.28 → 2.0.8.29

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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/common/CONTRIBUTING.md +4 -1
  3. data/common/README.md +52 -0
  4. data/lib/trackler/version.rb +1 -1
  5. data/tracks/ecmascript/config.json +7 -0
  6. data/tracks/ecmascript/exercises/perfect-numbers/example.js +68 -0
  7. data/tracks/ecmascript/exercises/perfect-numbers/gulpfile.js +89 -0
  8. data/tracks/ecmascript/exercises/perfect-numbers/package.json +28 -0
  9. data/tracks/ecmascript/exercises/perfect-numbers/perfect-numbers.spec.js +75 -0
  10. data/tracks/erlang/exercises/accumulate/src/accumulate.app.src +1 -1
  11. data/tracks/erlang/exercises/all-your-base/src/all_your_base.app.src +1 -1
  12. data/tracks/erlang/exercises/allergies/src/allergies.app.src +1 -1
  13. data/tracks/erlang/exercises/anagram/src/anagram.app.src +1 -1
  14. data/tracks/erlang/exercises/atbash-cipher/src/atbash_cipher.app.src +1 -1
  15. data/tracks/erlang/exercises/bank-account/src/bank_account.app.src +1 -1
  16. data/tracks/erlang/exercises/beer-song/src/beer_song.app.src +1 -1
  17. data/tracks/erlang/exercises/bob/src/bob.app.src +1 -1
  18. data/tracks/erlang/exercises/circular-buffer/src/circular_buffer.app.src +1 -1
  19. data/tracks/erlang/exercises/clock/src/clock.app.src +1 -1
  20. data/tracks/erlang/exercises/difference-of-squares/src/difference_of_squares.app.src +1 -1
  21. data/tracks/erlang/exercises/etl/src/etl.app.src +1 -1
  22. data/tracks/erlang/exercises/gigasecond/src/gigasecond.app.src +1 -1
  23. data/tracks/erlang/exercises/grade-school/src/grade_school.app.src +1 -1
  24. data/tracks/erlang/exercises/grains/src/grains.app.src +1 -1
  25. data/tracks/erlang/exercises/hamming/src/hamming.app.src +1 -1
  26. data/tracks/erlang/exercises/hello-world/src/hello_world.app.src +1 -1
  27. data/tracks/erlang/exercises/largest-series-product/src/largest_series_product.app.src +1 -1
  28. data/tracks/erlang/exercises/leap/src/leap.app.src +1 -1
  29. data/tracks/erlang/exercises/luhn/src/luhn.app.src +1 -1
  30. data/tracks/erlang/exercises/meetup/src/meetup.app.src +1 -1
  31. data/tracks/erlang/exercises/nucleotide-count/src/nucleotide_count.app.src +1 -1
  32. data/tracks/erlang/exercises/parallel-letter-frequency/src/parallel_letter_frequency.app.src +1 -1
  33. data/tracks/erlang/exercises/phone-number/src/phone_number.app.src +1 -1
  34. data/tracks/erlang/exercises/rna-transcription/src/rna_transcription.app.src +1 -1
  35. data/tracks/erlang/exercises/robot-simulator/src/robot_simulator.app.src +1 -1
  36. data/tracks/erlang/exercises/roman-numerals/src/roman_numerals.app.src +1 -1
  37. data/tracks/erlang/exercises/rotational-cipher/src/rotational_cipher.app.src +1 -1
  38. data/tracks/erlang/exercises/scrabble-score/src/scrabble_score.app.src +1 -1
  39. data/tracks/erlang/exercises/series/src/series.app.src +1 -1
  40. data/tracks/erlang/exercises/space-age/src/space_age.app.src +1 -1
  41. data/tracks/erlang/exercises/strain/src/strain.app.src +1 -1
  42. data/tracks/erlang/exercises/sum-of-multiples/src/sum_of_multiples.app.src +1 -1
  43. data/tracks/erlang/exercises/triangle/src/triangle.app.src +1 -1
  44. data/tracks/erlang/exercises/word-count/src/word_count.app.src +1 -1
  45. data/tracks/erlang/exercises/zipper/src/zipper.app.src +1 -1
  46. data/tracks/go/exercises/hello-world/hello_world.go +10 -1
  47. data/tracks/haskell/exercises/simple-linked-list/examples/success-standard/package.yaml +1 -0
  48. data/tracks/haskell/exercises/simple-linked-list/examples/success-standard/src/LinkedList.hs +1 -0
  49. data/tracks/haskell/exercises/simple-linked-list/package.yaml +1 -0
  50. data/tracks/haskell/exercises/simple-linked-list/src/LinkedList.hs +1 -1
  51. data/tracks/haskell/exercises/simple-linked-list/test/Tests.hs +37 -1
  52. data/tracks/java/exercises/diamond/src/test/java/DiamondPrinterTest.java +13 -6
  53. data/tracks/java/exercises/secret-handshake/src/test/java/HandshakeCalculatorTest.java +21 -13
  54. data/tracks/objective-c/exercises/atbash-cipher/AtbashCipherExample.m +1 -1
  55. data/tracks/objective-c/exercises/beer-song/BeerSongExample.m +1 -1
  56. data/tracks/objective-c/exercises/beer-song/BeerSongTest.m +4 -4
  57. data/tracks/objective-c/exercises/binary-search/BinarySearchExample.m +1 -1
  58. data/tracks/objective-c/exercises/flatten-array/FlattenArrayExample.h +2 -1
  59. data/tracks/objective-c/exercises/flatten-array/FlattenArrayExample.m +12 -25
  60. data/tracks/objective-c/exercises/flatten-array/FlattenArrayTest.m +32 -80
  61. data/tracks/objective-c/exercises/sublist/SublistTest.m +47 -70
  62. data/tracks/perl6/exercises/allergies/Allergies.pm6 +1 -0
  63. data/tracks/perl6/exercises/allergies/Example.pm +3 -1
  64. data/tracks/perl6/exercises/allergies/allergies.t +187 -137
  65. data/tracks/perl6/exercises/anagram/Anagram.pm6 +1 -0
  66. data/tracks/perl6/exercises/anagram/Example.pm +15 -15
  67. data/tracks/perl6/exercises/anagram/anagram.t +164 -15
  68. data/tracks/perl6/exercises/atbash-cipher/AtbashCipher.pm6 +1 -0
  69. data/tracks/perl6/exercises/atbash-cipher/Example.pm +2 -0
  70. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +109 -86
  71. data/tracks/perl6/exercises/grains/Example.pm +10 -9
  72. data/tracks/perl6/exercises/grains/Grains.pm6 +1 -0
  73. data/tracks/perl6/exercises/grains/grains.t +126 -18
  74. data/tracks/perl6/exercises/leap/Example.pm +9 -9
  75. data/tracks/perl6/exercises/leap/Leap.pm6 +4 -0
  76. data/tracks/perl6/exercises/leap/leap.t +61 -17
  77. data/tracks/perl6/exercises/phone-number/Example.pm +4 -28
  78. data/tracks/perl6/exercises/phone-number/PhoneNumber.pm6 +4 -0
  79. data/tracks/perl6/exercises/phone-number/phone-number.t +102 -65
  80. data/tracks/perl6/exercises/raindrops/Example.pm +10 -8
  81. data/tracks/perl6/exercises/raindrops/Raindrops.pm6 +4 -0
  82. data/tracks/perl6/exercises/raindrops/raindrops.t +153 -20
  83. data/tracks/perl6/exercises/rna-transcription/Example.pm +5 -7
  84. data/tracks/perl6/exercises/rna-transcription/RNA.pm6 +4 -0
  85. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +107 -11
  86. data/tracks/perl6/exercises/scrabble-score/Example.pm +14 -19
  87. data/tracks/perl6/exercises/scrabble-score/Scrabble.pm6 +4 -0
  88. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +106 -15
  89. data/tracks/perl6/exercises/space-age/Example.pm +29 -13
  90. data/tracks/perl6/exercises/space-age/SpaceAge.pm6 +22 -0
  91. data/tracks/perl6/exercises/space-age/space-age.t +90 -52
  92. data/tracks/perl6/exercises/word-count/Example.pm +4 -8
  93. data/tracks/perl6/exercises/word-count/WordCount.pm6 +4 -0
  94. data/tracks/perl6/exercises/word-count/word-count.t +149 -16
  95. data/tracks/perl6/exercises/wordy/Example.pm +13 -13
  96. data/tracks/perl6/exercises/wordy/Wordy.pm6 +4 -0
  97. data/tracks/perl6/exercises/wordy/wordy.t +140 -97
  98. data/tracks/purescript/config.json +7 -0
  99. data/tracks/purescript/exercises/atbash-cipher/bower.json +18 -0
  100. data/tracks/purescript/exercises/atbash-cipher/examples/src/AtbashCipher.purs +41 -0
  101. data/tracks/purescript/exercises/atbash-cipher/src/AtbashCipher.purs +4 -0
  102. data/tracks/purescript/exercises/atbash-cipher/test/Main.purs +64 -0
  103. data/tracks/python/exercises/run-length-encoding/run_length_encoding_test.py +2 -0
  104. data/tracks/swift/exercises/grade-school/Tests/GradeSchoolTests/GradeSchoolTests.swift +1 -1
  105. metadata +22 -2
@@ -0,0 +1 @@
1
+ unit module AtbashCipher:ver<1>;
@@ -1,3 +1,5 @@
1
+ unit module AtbashCipher:ver<1>;
2
+
1
3
  sub encode($input) is export {
2
4
  decode($input.lc.trans( ['a'..'z', 0..9] => '', :complement ) )
3
5
  .comb(5)
@@ -1,119 +1,142 @@
1
1
  #!/usr/bin/env perl6
2
-
2
+ use v6;
3
3
  use Test;
4
+ use lib my $dir = $?FILE.IO.dirname;
4
5
  use JSON::Tiny;
5
6
 
6
- use lib $?FILE.IO.dirname;
7
-
8
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Cipher';
9
- require ::($module) <&encode &decode>;
10
-
11
- plan 2;
12
-
13
- my %cases;
14
- subtest 'encode' => {
15
- my @cases = |%cases.<encode>.<cases>;
7
+ my $exercise = 'AtbashCipher';
8
+ my $version = v1;
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
10
+ plan 5;
16
11
 
17
- plan +@cases;
18
-
19
- is encode( .<phrase> ), .<expected>, .<description>
20
- for @cases;
21
- };
12
+ use-ok $module or bail-out;
13
+ require ::($module);
14
+ if ::($exercise).^ver !~~ $version {
15
+ warn "\nExercise version mismatch. Further tests may fail!"
16
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
17
+ ~ "Test is $($version.gist).\n";
18
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
19
+ }
22
20
 
23
- subtest 'decode' => {
24
- my @cases = |%cases.<decode>.<cases>;
21
+ my @subs;
22
+ BEGIN { @subs = <&encode &decode> };
23
+ subtest 'Subroutine(s)', {
24
+ plan 2;
25
+ eval-lives-ok "use $module; ::('$_').defined or die '$_ is not defined.'", $_ for @subs;
26
+ } or bail-out 'All subroutines must be defined and exported.';
27
+ require ::($module) @subs.eager;
25
28
 
29
+ for @(my $c-data.<cases>) {
30
+ my $test = .<description> ~~ 'encode' ?? 'encode' !! 'decode';
31
+ subtest $test => {
32
+ my @cases = |.<cases>;
26
33
  plan +@cases;
34
+ is &::($test)(.<phrase>), |.<expected description> for @cases;
35
+ }
36
+ }
27
37
 
28
- is decode( .<phrase> ), .<expected>, .<description>
29
- for @cases;
30
- };
38
+ if %*ENV<EXERCISM> && (my $c-data-file = "$dir/../../x-common/exercises/{$dir.IO.basename}/canonical-data.json".IO.resolve) ~~ :f {
39
+ is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data'
40
+ } else { skip }
31
41
 
32
42
  done-testing;
33
43
 
34
44
  INIT {
35
- %cases := from-json 「
45
+ $c-data := from-json 「
36
46
  {
37
- "#": [
47
+ "exercise": "atbash-cipher",
48
+ "version": "1.0.0",
49
+ "comments": [
38
50
  "The tests are divided into two groups: ",
39
51
  "* Encoding from English to atbash cipher",
40
52
  "* Decoding from atbash cipher to all-lowercase-mashed-together English"
41
53
  ],
42
- "encode": {
43
- "description": ["Test encoding from English to atbash"],
44
- "cases": [
45
- {
46
- "description": "encode yes",
47
- "phrase": "yes",
48
- "expected": "bvh"
49
- },
50
- {
51
- "description": "encode no",
52
- "phrase": "no",
53
- "expected": "ml"
54
- },
55
- {
56
- "description": "encode OMG",
57
- "phrase": "OMG",
58
- "expected": "lnt"
59
- },
60
- {
61
- "description": "encode spaces",
62
- "phrase": "O M G",
63
- "expected": "lnt"
64
- },
65
- {
66
- "description": "encode mindblowingly",
67
- "phrase": "mindblowingly",
68
- "expected": "nrmwy oldrm tob"
69
- },
70
- {
71
- "description": "encode numbers",
72
- "phrase": "Testing,1 2 3, testing.",
73
- "expected": "gvhgr mt123 gvhgr mt"
74
- },
75
- {
76
- "description": "encode deep thought",
77
- "phrase": "Truth is fiction.",
78
- "expected": "gifgs rhurx grlm"
79
- },
80
- {
81
- "description": "encode all the letters",
82
- "phrase": "The quick brown fox jumps over the lazy dog.",
83
- "expected": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
84
- },
85
- {
86
- "description": "encode ignores non ascii",
87
- "phrase": "non ascii éignored",
88
- "expected": "mlmzh xrrrt mlivw"
89
- }
90
- ]
91
- },
92
- "decode": {
93
- "description": ["Test decoding from atbash to English"],
94
- "cases": [
95
- {
54
+ "cases": [
55
+ {
56
+ "description": "encode",
57
+ "comments": [ "Test encoding from English to atbash" ],
58
+ "cases": [
59
+ {
60
+ "description": "encode yes",
61
+ "property": "encode",
62
+ "phrase": "yes",
63
+ "expected": "bvh"
64
+ },
65
+ {
66
+ "description": "encode no",
67
+ "property": "encode",
68
+ "phrase": "no",
69
+ "expected": "ml"
70
+ },
71
+ {
72
+ "description": "encode OMG",
73
+ "property": "encode",
74
+ "phrase": "OMG",
75
+ "expected": "lnt"
76
+ },
77
+ {
78
+ "description": "encode spaces",
79
+ "property": "encode",
80
+ "phrase": "O M G",
81
+ "expected": "lnt"
82
+ },
83
+ {
84
+ "description": "encode mindblowingly",
85
+ "property": "encode",
86
+ "phrase": "mindblowingly",
87
+ "expected": "nrmwy oldrm tob"
88
+ },
89
+ {
90
+ "description": "encode numbers",
91
+ "property": "encode",
92
+ "phrase": "Testing,1 2 3, testing.",
93
+ "expected": "gvhgr mt123 gvhgr mt"
94
+ },
95
+ {
96
+ "description": "encode deep thought",
97
+ "property": "encode",
98
+ "phrase": "Truth is fiction.",
99
+ "expected": "gifgs rhurx grlm"
100
+ },
101
+ {
102
+ "description": "encode all the letters",
103
+ "property": "encode",
104
+ "phrase": "The quick brown fox jumps over the lazy dog.",
105
+ "expected": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
106
+ }
107
+ ]
108
+ },
109
+ {
110
+ "description": "decode",
111
+ "comments": [ "Test decoding from atbash to English" ],
112
+ "cases": [
113
+ {
96
114
  "description": "decode exercism",
115
+ "property": "decode",
97
116
  "phrase": "vcvix rhn",
98
117
  "expected": "exercism"
99
- },
100
- {
118
+ },
119
+ {
101
120
  "description": "decode a sentence",
121
+ "property": "decode",
102
122
  "phrase": "zmlyh gzxov rhlug vmzhg vkkrm thglm v",
103
123
  "expected": "anobstacleisoftenasteppingstone"
104
- },
105
- {
124
+ },
125
+ {
106
126
  "description": "decode numbers",
127
+ "property": "decode",
107
128
  "phrase": "gvhgr mt123 gvhgr mt",
108
129
  "expected": "testing123testing"
109
- },
110
- {
130
+ },
131
+ {
111
132
  "description": "decode all the letters",
133
+ "property": "decode",
112
134
  "phrase": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
113
135
  "expected": "thequickbrownfoxjumpsoverthelazydog"
114
- }
115
- ]
116
- }
136
+ }
137
+ ]
138
+ }
139
+ ]
117
140
  }
118
141
 
119
142
  }
@@ -1,11 +1,12 @@
1
- class Grains is export {
2
- method square($number) {
3
- 2**($number-1);
4
- }
1
+ unit module Grains:ver<1>;
5
2
 
6
- method total {
7
- my $total;
8
- for 1..64 { $total += self.square($_) }
9
- $total;
10
- }
3
+ sub grains-on-square ($number) is export {
4
+ die if $number < 1 or $number > 64;
5
+ 2**($number-1);
6
+ }
7
+
8
+ sub total-grains is export {
9
+ my Int $total;
10
+ for 1..64 { $total += grains-on-square($_) }
11
+ $total;
11
12
  }
@@ -0,0 +1 @@
1
+ unit module Grains:ver<1>;
@@ -1,21 +1,129 @@
1
1
  #!/usr/bin/env perl6
2
2
  use v6;
3
3
  use Test;
4
- use lib IO::Path.new($?FILE).parent.path;
5
-
6
- plan 11;
7
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Grains';
8
- use-ok $module;
9
- require ::($module) <Grains>;
10
-
11
- ok Grains.can('square'), 'Grains class has square method';
12
- ok Grains.can('total'), 'Grains class has total method';
13
-
14
- is Grains.square(1), 1, 'test square 1';
15
- is Grains.square(2), 2, 'test square 2';
16
- is Grains.square(3), 4, 'test square 3';
17
- is Grains.square(4), 8, 'test square 4';
18
- is Grains.square(16), 32768, 'test square 16';
19
- is Grains.square(32), 2147483648, 'test square 32';
20
- is Grains.square(64), 9223372036854775808, 'test square 64';
21
- is Grains.total, 18446744073709551615, 'test total';
4
+ use lib my $dir = $?FILE.IO.dirname;
5
+ use JSON::Tiny;
6
+
7
+ my $exercise = 'Grains';
8
+ my $version = v1;
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
10
+ plan 14;
11
+
12
+ use-ok $module or bail-out;
13
+ require ::($module);
14
+ if ::($exercise).^ver !~~ $version {
15
+ warn "\nExercise version mismatch. Further tests may fail!"
16
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
17
+ ~ "Test is $($version.gist).\n";
18
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
19
+ }
20
+
21
+ my @subs;
22
+ BEGIN { @subs = <&grains-on-square &total-grains> };
23
+ subtest 'Subroutine(s)', {
24
+ plan 2;
25
+ eval-lives-ok "use $module; ::('$_').defined or die '$_ is not defined.'", $_ for @subs;
26
+ } or bail-out 'All subroutines must be defined and exported.';
27
+ require ::($module) @subs.eager;
28
+
29
+ for @(my $c-data.<cases>.[0].<cases>) {
30
+ if .<expected> == -1 {
31
+ throws-like { grains-on-square(.<input>) }, Exception, .<description>;
32
+ } else {
33
+ is grains-on-square(.<input>), |.<expected description>;
34
+ }
35
+ }
36
+
37
+ is total-grains, |$c-data.<cases>.[1].<expected description>;
38
+
39
+ if %*ENV<EXERCISM> && (my $c-data-file = "$dir/../../x-common/exercises/{$dir.IO.basename}/canonical-data.json".IO.resolve) ~~ :f {
40
+ is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data'
41
+ } else { skip }
42
+
43
+ done-testing;
44
+
45
+ INIT {
46
+ $c-data := from-json 「
47
+ {
48
+ "exercise": "grains",
49
+ "version": "1.0.0",
50
+ "comments": [
51
+ "The final tests of square test error conditions",
52
+ "The expection for these tests is -1, indicating an error",
53
+ "In these cases you should expect an error as is idiomatic for your language"
54
+ ],
55
+ "cases": [
56
+ {
57
+ "description": "returns the number of grains on the square",
58
+ "cases": [
59
+ {
60
+ "description": "1",
61
+ "property": "square",
62
+ "input": 1,
63
+ "expected": 1
64
+ },
65
+ {
66
+ "description": "2",
67
+ "property": "square",
68
+ "input": 2,
69
+ "expected": 2
70
+ },
71
+ {
72
+ "description": "3",
73
+ "property": "square",
74
+ "input": 3,
75
+ "expected": 4
76
+ },
77
+ {
78
+ "description": "4",
79
+ "property": "square",
80
+ "input": 4,
81
+ "expected": 8
82
+ },
83
+ {
84
+ "description": "16",
85
+ "property": "square",
86
+ "input": 16,
87
+ "expected": 32768
88
+ },
89
+ {
90
+ "description": "32",
91
+ "property": "square",
92
+ "input": 32,
93
+ "expected": 2147483648
94
+ },
95
+ {
96
+ "description": "64",
97
+ "property": "square",
98
+ "input": 64,
99
+ "expected": 9223372036854775808
100
+ },
101
+ {
102
+ "description": "square 0 raises an exception",
103
+ "property": "square",
104
+ "input": 0,
105
+ "expected": -1
106
+ },
107
+ {
108
+ "description": "negative square raises an exception",
109
+ "property": "square",
110
+ "input": -1,
111
+ "expected": -1
112
+ },
113
+ {
114
+ "description": "square greater than 64 raises an exception",
115
+ "property": "square",
116
+ "input": 65,
117
+ "expected": -1
118
+ }
119
+ ]
120
+ },
121
+ {
122
+ "description": "returns the total number of grains on the board",
123
+ "property": "total",
124
+ "expected": 18446744073709551615
125
+ }
126
+ ]
127
+ }
128
+
129
+ }
@@ -1,11 +1,11 @@
1
- class Leap is export {
2
- method is_leap ($year) {
3
- self.is_divisible($year, 400)
4
- || self.is_divisible($year, 4)
5
- && !self.is_divisible($year, 100);
6
- }
1
+ unit module Leap:ver<1>;
7
2
 
8
- method is_divisible($year, $number) {
9
- $year % $number == 0 ?? True !! False;
10
- }
3
+ sub is-leap-year ($year) is export {
4
+ is-divisible($year, 400)
5
+ || is-divisible($year, 4)
6
+ && !is-divisible($year, 100);
7
+ }
8
+
9
+ sub is-divisible($year, $number) {
10
+ $year % $number == 0 ?? True !! False;
11
11
  }
@@ -0,0 +1,4 @@
1
+ unit module Leap:ver<1>;
2
+
3
+ sub is-leap-year ($year) is export {
4
+ }
@@ -1,26 +1,70 @@
1
1
  #!/usr/bin/env perl6
2
2
  use v6;
3
3
  use Test;
4
- use lib IO::Path.new($?FILE).parent.path;
4
+ use lib my $dir = $?FILE.IO.dirname;
5
+ use JSON::Tiny;
5
6
 
6
- plan 8;
7
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Leap';
8
- use-ok $module;
9
- require ::($module) <Leap>;
7
+ my $exercise = 'Leap';
8
+ my $version = v1;
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
10
+ plan 7;
10
11
 
11
- ok Leap.can('is_leap'), 'Leap class has is_leap() method';
12
+ use-ok $module or bail-out;
13
+ require ::($module);
14
+ if ::($exercise).^ver !~~ $version {
15
+ warn "\nExercise version mismatch. Further tests may fail!"
16
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
17
+ ~ "Test is $($version.gist).\n";
18
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
19
+ }
20
+
21
+ my @subs;
22
+ BEGIN { @subs = <&is-leap-year> };
23
+ subtest 'Subroutine(s)', {
24
+ plan 1;
25
+ eval-lives-ok "use $module; ::('$_').defined or die '$_ is not defined.'", $_ for @subs;
26
+ } or bail-out 'All subroutines must be defined and exported.';
27
+ require ::($module) @subs.eager;
28
+
29
+ is .<input>.&is-leap-year, |.<expected description> for @(my $c-data.<cases>);
12
30
 
13
- ok my $leap = Leap.new, 'Create new Leap object';
31
+ if %*ENV<EXERCISM> && (my $c-data-file = "$dir/../../x-common/exercises/{$dir.IO.basename}/canonical-data.json".IO.resolve) ~~ :f {
32
+ is-deeply $c-data, from-json($c-data-file.slurp), 'canonical-data'
33
+ } else { skip }
14
34
 
15
- my %year = (
16
- 1996 => True,
17
- 1997 => False,
18
- 1998 => False,
19
- 1900 => False,
20
- 2400 => True,
21
- );
35
+ done-testing;
22
36
 
23
- for %year.sort -> $y {
24
- is $leap.is_leap($y.key), $y.value,
25
- [ flat( $y.key, 'is', 'not' xx !$y.value, 'a leap year' ) ].join( ' ' )
37
+ INIT {
38
+ $c-data := from-json 「
39
+ {
40
+ "exercise": "leap",
41
+ "version": "1.0.0",
42
+ "cases": [
43
+ {
44
+ "description": "year not divisible by 4: common year",
45
+ "property": "leapYear",
46
+ "input": 2015,
47
+ "expected": false
48
+ },
49
+ {
50
+ "description": "year divisible by 4, not divisible by 100: leap year",
51
+ "property": "leapYear",
52
+ "input": 2016,
53
+ "expected": true
54
+ },
55
+ {
56
+ "description": "year divisible by 100, not divisible by 400: common year",
57
+ "property": "leapYear",
58
+ "input": 2100,
59
+ "expected": false
60
+ },
61
+ {
62
+ "description": "year divisible by 400: leap year",
63
+ "property": "leapYear",
64
+ "input": 2000,
65
+ "expected": true
66
+ }
67
+ ]
68
+ }
69
+
26
70
  }