trackler 2.0.8.20 → 2.0.8.21

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/csharp/.travis.yml +1 -4
  4. data/tracks/csharp/exercises/accumulate/HINTS.md +3 -0
  5. data/tracks/csharp/exercises/allergies/HINTS.md +3 -0
  6. data/tracks/csharp/exercises/alphametics/HINTS.md +5 -0
  7. data/tracks/csharp/exercises/bank-account/HINTS.md +3 -0
  8. data/tracks/csharp/exercises/beer-song/HINTS.md +2 -0
  9. data/tracks/csharp/exercises/clock/HINTS.md +4 -0
  10. data/tracks/csharp/exercises/custom-set/HINTS.md +4 -0
  11. data/tracks/csharp/exercises/difference-of-squares/HINTS.md +4 -0
  12. data/tracks/csharp/exercises/diffie-hellman/HINTS.md +3 -0
  13. data/tracks/csharp/exercises/food-chain/HINTS.md +2 -0
  14. data/tracks/csharp/exercises/forth/HINTS.md +2 -0
  15. data/tracks/csharp/exercises/hangman/HINTS.md +3 -0
  16. data/tracks/csharp/exercises/leap/Example.cs +2 -2
  17. data/tracks/csharp/exercises/leap/Leap.cs +2 -2
  18. data/tracks/csharp/exercises/leap/LeapTest.cs +4 -4
  19. data/tracks/csharp/exercises/sgf-parsing/HINTS.md +2 -0
  20. data/tracks/csharp/exercises/simple-linked-list/HINTS.md +3 -0
  21. data/tracks/csharp/exercises/sublist/HINTS.md +3 -0
  22. data/tracks/csharp/exercises/twelve-days/HINTS.md +2 -0
  23. data/tracks/csharp/exercises/variable-length-quantity/HINTS.md +3 -0
  24. data/tracks/csharp/exercises/wordy/HINTS.md +2 -0
  25. data/tracks/csharp/generators/BooleanTestMethod.cs +36 -0
  26. data/tracks/csharp/generators/Exercises/Exercise.cs +13 -2
  27. data/tracks/csharp/generators/Exercises/LeapExercise.cs +3 -26
  28. data/tracks/csharp/generators/Program.cs +7 -8
  29. data/tracks/csharp/generators/TestClassNameTransformer.cs +9 -0
  30. data/tracks/csharp/generators/TestClassRenderer.cs +1 -1
  31. data/tracks/csharp/generators/TestedClassNameTransformer.cs +11 -0
  32. data/tracks/csharp/generators/TestedMethodNameTransformer.cs +9 -0
  33. data/tracks/csharp/generators/To.cs +3 -0
  34. data/tracks/elixir/config.json +8 -0
  35. data/tracks/elixir/exercises/ocr-numbers/example.exs +47 -0
  36. data/tracks/elixir/exercises/ocr-numbers/ocr_numbers.exs +10 -0
  37. data/tracks/elixir/exercises/ocr-numbers/ocr_numbers_test.exs +254 -0
  38. data/tracks/go/exercises/say/example.go +2 -0
  39. data/tracks/go/exercises/say/say_test.go +8 -0
  40. data/tracks/go/exercises/scrabble-score/scrabble_score_test.go +6 -4
  41. data/tracks/go/exercises/secret-handshake/secret_handshake_test.go +4 -1
  42. data/tracks/go/exercises/sieve/example.go +2 -0
  43. data/tracks/go/exercises/sieve/sieve_test.go +8 -0
  44. data/tracks/go/exercises/simple-cipher/example.go +3 -1
  45. data/tracks/go/exercises/simple-cipher/simple_cipher_test.go +8 -0
  46. data/tracks/go/exercises/sum-of-multiples/example.go +2 -0
  47. data/tracks/go/exercises/sum-of-multiples/sum_of_multiples_test.go +8 -0
  48. data/tracks/go/exercises/tournament/tournament_test.go +3 -1
  49. data/tracks/go/exercises/transpose/example.go +2 -0
  50. data/tracks/go/exercises/transpose/transpose_test.go +8 -0
  51. data/tracks/go/exercises/tree-building/tree_test.go +6 -6
  52. data/tracks/go/exercises/triangle/triangle_test.go +6 -6
  53. data/tracks/haskell/exercises/atbash-cipher/src/Atbash.hs +2 -2
  54. data/tracks/haskell/exercises/largest-series-product/src/Series.hs +1 -1
  55. data/tracks/haskell/exercises/linked-list/src/Deque.hs +4 -4
  56. data/tracks/haskell/exercises/list-ops/src/ListOps.hs +7 -7
  57. data/tracks/haskell/exercises/luhn/src/Luhn.hs +10 -5
  58. data/tracks/haskell/exercises/matrix/src/Matrix.hs +10 -10
  59. data/tracks/haskell/exercises/minesweeper/src/Minesweeper.hs +1 -1
  60. data/tracks/haskell/exercises/nth-prime/src/Prime.hs +2 -1
  61. data/tracks/haskell/exercises/nucleotide-count/src/DNA.hs +1 -1
  62. data/tracks/haskell/exercises/ocr-numbers/src/OCR.hs +1 -1
  63. data/tracks/haskell/exercises/pascals-triangle/src/Triangle.hs +1 -1
  64. data/tracks/haskell/exercises/phone-number/src/Phone.hs +1 -1
  65. data/tracks/haskell/exercises/pig-latin/src/PigLatin.hs +1 -1
  66. data/tracks/haskell/exercises/prime-factors/src/PrimeFactors.hs +1 -1
  67. data/tracks/kotlin/exercises/_template/build.gradle +1 -1
  68. data/tracks/kotlin/exercises/accumulate/build.gradle +1 -1
  69. data/tracks/kotlin/exercises/acronym/build.gradle +1 -1
  70. data/tracks/kotlin/exercises/allergies/build.gradle +1 -1
  71. data/tracks/kotlin/exercises/anagram/build.gradle +1 -1
  72. data/tracks/kotlin/exercises/atbash-cipher/build.gradle +1 -1
  73. data/tracks/kotlin/exercises/beer-song/build.gradle +1 -1
  74. data/tracks/kotlin/exercises/binary/build.gradle +1 -1
  75. data/tracks/kotlin/exercises/binary-search/build.gradle +1 -1
  76. data/tracks/kotlin/exercises/bob/build.gradle +1 -1
  77. data/tracks/kotlin/exercises/bracket-push/build.gradle +1 -1
  78. data/tracks/kotlin/exercises/change/build.gradle +1 -1
  79. data/tracks/kotlin/exercises/difference-of-squares/build.gradle +1 -1
  80. data/tracks/kotlin/exercises/etl/build.gradle +1 -1
  81. data/tracks/kotlin/exercises/flatten-array/build.gradle +1 -1
  82. data/tracks/kotlin/exercises/gigasecond/build.gradle +1 -1
  83. data/tracks/kotlin/exercises/grade-school/build.gradle +1 -1
  84. data/tracks/kotlin/exercises/hamming/build.gradle +1 -1
  85. data/tracks/kotlin/exercises/hello-world/build.gradle +1 -1
  86. data/tracks/kotlin/exercises/hexadecimal/build.gradle +1 -1
  87. data/tracks/kotlin/exercises/isogram/build.gradle +1 -1
  88. data/tracks/kotlin/exercises/largest-series-product/build.gradle +1 -1
  89. data/tracks/kotlin/exercises/leap/build.gradle +1 -1
  90. data/tracks/kotlin/exercises/linked-list/build.gradle +1 -1
  91. data/tracks/kotlin/exercises/luhn/build.gradle +1 -1
  92. data/tracks/kotlin/exercises/nth-prime/build.gradle +1 -1
  93. data/tracks/kotlin/exercises/nucleotide-count/build.gradle +1 -1
  94. data/tracks/kotlin/exercises/pangram/build.gradle +1 -1
  95. data/tracks/kotlin/exercises/pascals-triangle/build.gradle +1 -1
  96. data/tracks/kotlin/exercises/perfect-numbers/build.gradle +1 -1
  97. data/tracks/kotlin/exercises/phone-number/build.gradle +1 -1
  98. data/tracks/kotlin/exercises/pig-latin/build.gradle +1 -1
  99. data/tracks/kotlin/exercises/raindrops/build.gradle +1 -1
  100. data/tracks/kotlin/exercises/react/build.gradle +1 -1
  101. data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +9 -9
  102. data/tracks/kotlin/exercises/rna-transcription/build.gradle +1 -1
  103. data/tracks/kotlin/exercises/robot-name/build.gradle +1 -1
  104. data/tracks/kotlin/exercises/roman-numerals/build.gradle +1 -1
  105. data/tracks/kotlin/exercises/scrabble-score/build.gradle +1 -1
  106. data/tracks/kotlin/exercises/series/build.gradle +1 -1
  107. data/tracks/kotlin/exercises/sieve/build.gradle +1 -1
  108. data/tracks/kotlin/exercises/simple-cipher/build.gradle +1 -1
  109. data/tracks/kotlin/exercises/space-age/build.gradle +1 -1
  110. data/tracks/kotlin/exercises/strain/build.gradle +1 -1
  111. data/tracks/kotlin/exercises/triangle/build.gradle +1 -1
  112. data/tracks/kotlin/exercises/word-count/build.gradle +1 -1
  113. data/tracks/perl6/.gitmodules +3 -0
  114. data/tracks/perl6/.travis.yml +1 -0
  115. data/tracks/perl6/config.json +8 -11
  116. data/tracks/perl6/exercises/accumulate/Accumulate.pm6 +1 -0
  117. data/tracks/perl6/exercises/accumulate/Example.pm +8 -8
  118. data/tracks/perl6/exercises/accumulate/accumulate.t +27 -12
  119. data/tracks/perl6/exercises/all-your-base/AllYourBase.pm6 +1 -0
  120. data/tracks/perl6/exercises/all-your-base/Example.pm +46 -0
  121. data/tracks/perl6/exercises/all-your-base/all-your-base.t +163 -0
  122. data/tracks/perl6/exercises/bob/Bob.pm6 +13 -0
  123. data/tracks/perl6/exercises/bob/Example.pm +9 -9
  124. data/tracks/perl6/exercises/bob/bob.t +201 -34
  125. data/tracks/perl6/exercises/grade-school/Example.pm +13 -12
  126. data/tracks/perl6/exercises/grade-school/GradeSchool.pm6 +4 -0
  127. data/tracks/perl6/exercises/grade-school/grade-school.t +38 -19
  128. data/tracks/perl6/exercises/hello-world/Example.pm +3 -3
  129. data/tracks/perl6/exercises/hello-world/HelloWorld.pm6 +2 -2
  130. data/tracks/perl6/exercises/hello-world/hello-world.t +41 -10
  131. data/tracks/perl6/exercises/linked-list/Example.pm6 +33 -34
  132. data/tracks/perl6/exercises/linked-list/LinkedList.pm6 +1 -0
  133. data/tracks/perl6/exercises/linked-list/linked-list.t +32 -22
  134. data/tracks/perl6/exercises/robot-name/Example.pm +8 -15
  135. data/tracks/perl6/exercises/robot-name/Robot.pm6 +1 -0
  136. data/tracks/perl6/exercises/robot-name/robot-name.t +39 -14
  137. data/tracks/php/config.json +5 -0
  138. data/tracks/php/exercises/luhn/example.php +26 -0
  139. data/tracks/php/exercises/luhn/luhn_test.php +95 -0
  140. data/tracks/purescript/README.md +67 -4
  141. data/tracks/python/docs/LEARNING.md +1 -0
  142. data/tracks/python/exercises/acronym/acronym_test.py +5 -1
  143. data/tracks/python/exercises/atbash-cipher/atbash_cipher_test.py +8 -0
  144. data/tracks/python/exercises/hello-world/hello_world_test.py +4 -38
  145. data/tracks/python/exercises/run-length-encoding/run_length_encoding_test.py +30 -15
  146. metadata +38 -2
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env perl6
2
+ use v6;
3
+ use Test;
4
+ use lib $?FILE.IO.dirname;
5
+
6
+ my $exercise = 'AllYourBase';
7
+ my $version = v1;
8
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
9
+ plan 23;
10
+
11
+ use-ok $module or bail-out;
12
+ require ::($module);
13
+ if ::($exercise).^ver !~~ $version {
14
+ warn "\nExercise version mismatch. Further tests may fail!"
15
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
16
+ ~ "Test is $($version.gist).\n";
17
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
18
+ }
19
+
20
+ my @subs;
21
+ BEGIN { @subs = <&convert-base> }
22
+ subtest 'Subroutine(s)', {
23
+ plan 1;
24
+ eval-lives-ok "use $module; ::('$_').defined or die '$_ is not defined.'", $_ for @subs;
25
+ } or bail-out 'All subroutines must be defined and exported.';
26
+ require ::($module) @subs.eager;
27
+
28
+ is convert-base(|.<input_base input_digits output_base>), |.<expected description> for @(my %cases.<valid>);
29
+
30
+ my $exception = 'Exception';
31
+ for @(%cases<invalid>) {
32
+ $exception = 'X::AllYourBase::Invalid' ~ (.<description> ~~ /«digit»/ ?? 'Digit' !! 'Base') if %*ENV<EXERCISM>;
33
+ throws-like {convert-base |.<input_base input_digits output_base>}, ::($exception), .<description>;
34
+ }
35
+
36
+ done-testing;
37
+
38
+ INIT {
39
+ require JSON::Tiny <&from-json>;
40
+ %cases := from-json 「
41
+ {
42
+ "valid":[
43
+ { "description" : "single bit one to decimal"
44
+ , "input_base" : 2
45
+ , "input_digits" : [1]
46
+ , "output_base" : 10
47
+ , "expected" : [1]
48
+ },
49
+ { "description" : "binary to single decimal"
50
+ , "input_base" : 2
51
+ , "input_digits" : [1, 0, 1]
52
+ , "output_base" : 10
53
+ , "expected" : [5]
54
+ },
55
+ { "description" : "single decimal to binary"
56
+ , "input_base" : 10
57
+ , "input_digits" : [5]
58
+ , "output_base" : 2
59
+ , "expected" : [1, 0, 1]
60
+ },
61
+ { "description" : "binary to multiple decimal"
62
+ , "input_base" : 2
63
+ , "input_digits" : [1, 0, 1, 0, 1, 0]
64
+ , "output_base" : 10
65
+ , "expected" : [4, 2]
66
+ },
67
+ { "description" : "decimal to binary"
68
+ , "input_base" : 10
69
+ , "input_digits" : [4, 2]
70
+ , "output_base" : 2
71
+ , "expected" : [1, 0, 1, 0, 1, 0]
72
+ },
73
+ { "description" : "trinary to hexadecimal"
74
+ , "input_base" : 3
75
+ , "input_digits" : [1, 1, 2, 0]
76
+ , "output_base" : 16
77
+ , "expected" : [2, 10]
78
+ },
79
+ { "description" : "hexadecimal to trinary"
80
+ , "input_base" : 16
81
+ , "input_digits" : [2, 10]
82
+ , "output_base" : 3
83
+ , "expected" : [1, 1, 2, 0]
84
+ },
85
+ { "description" : "15-bit integer"
86
+ , "input_base" : 97
87
+ , "input_digits" : [3,46,60]
88
+ , "output_base" : 73
89
+ , "expected" : [6,10,45]
90
+ },
91
+ { "description" : "empty list outputs empty list"
92
+ , "input_base" : 2
93
+ , "input_digits" : []
94
+ , "output_base" : 10
95
+ , "expected" : []
96
+ },
97
+ { "description" : "single zero outputs 0"
98
+ , "input_base" : 10
99
+ , "input_digits" : [0]
100
+ , "output_base" : 2
101
+ , "expected" : [0]
102
+ },
103
+ { "description" : "multiple zeros outputs 0"
104
+ , "input_base" : 10
105
+ , "input_digits" : [0, 0, 0]
106
+ , "output_base" : 2
107
+ , "expected" : [0]
108
+ },
109
+ { "description" : "leading zeros are stripped"
110
+ , "input_base" : 7
111
+ , "input_digits" : [0, 6, 0]
112
+ , "output_base" : 10
113
+ , "expected" : [4, 2]
114
+ } ],
115
+ "invalid":[
116
+ { "description" : "negative digit is invalid"
117
+ , "input_base" : 2
118
+ , "input_digits" : [1, -1, 1, 0, 1, 0]
119
+ , "output_base" : 10
120
+ },
121
+ { "description" : "invalid positive digit"
122
+ , "input_base" : 2
123
+ , "input_digits" : [1, 2, 1, 0, 1, 0]
124
+ , "output_base" : 10
125
+ },
126
+ { "description" : "first base is one"
127
+ , "input_base" : 1
128
+ , "input_digits" : []
129
+ , "output_base" : 10
130
+ },
131
+ { "description" : "second base is one"
132
+ , "input_base" : 2
133
+ , "input_digits" : [1, 0, 1, 0, 1, 0]
134
+ , "output_base" : 1
135
+ },
136
+ { "description" : "first base is zero"
137
+ , "input_base" : 0
138
+ , "input_digits" : []
139
+ , "output_base" : 10
140
+ },
141
+ { "description" : "second base is zero"
142
+ , "input_base" : 10
143
+ , "input_digits" : [7]
144
+ , "output_base" : 0
145
+ },
146
+ { "description" : "first base is negative"
147
+ , "input_base" : -2
148
+ , "input_digits" : [1]
149
+ , "output_base" : 10
150
+ },
151
+ { "description" : "second base is negative"
152
+ , "input_base" : 2
153
+ , "input_digits" : [1]
154
+ , "output_base" : -7
155
+ },
156
+ { "description" : "both bases are negative"
157
+ , "input_base" : -2
158
+ , "input_digits" : [1]
159
+ , "output_base" : -7
160
+ } ]
161
+ }
162
+
163
+ }
@@ -0,0 +1,13 @@
1
+ #`[
2
+ Declare class 'Bob' with version and unit-scope the class
3
+ i.e. everything in this file is part of 'Bob'.
4
+ ]
5
+ unit class Bob:ver<1>;
6
+
7
+ method hey ($msg) {
8
+ #`[
9
+ Remove the comments and write some code here to pass the test suite.
10
+ You can experiment with the code outside of this block,
11
+ but no changes are needed for the test suite to pass.
12
+ ]
13
+ }
@@ -1,10 +1,10 @@
1
- class Bob is export {
2
- method hey ($input) {
3
- given $input {
4
- when /^\s*$/ { 'Fine. Be that way!' }
5
- when /<:Upper>/ and $input.uc eq $input { 'Whoa, chill out!' }
6
- when /'?'$/ { 'Sure.' }
7
- default { 'Whatever.' }
8
- }
9
- }
1
+ unit class Bob:ver<1>;
2
+
3
+ method hey ($msg) {
4
+ given $msg.trim {
5
+ when !* { 'Fine. Be that way!' }
6
+ when /<:Upper>/ and $_.uc eq * { 'Whoa, chill out!' }
7
+ when /'?'$/ { 'Sure.' }
8
+ default { 'Whatever.' }
9
+ }
10
10
  }
@@ -1,38 +1,205 @@
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 21;
7
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Bob';
8
- use-ok $module;
9
- require ::($module) <Bob>;
10
-
11
- ok Bob.can('hey'), 'Class Bob has hey() method';
12
-
13
- my @cases =
14
- # input expected output title
15
- ['Tom-ay-to, tom-aaaah-to.', 'Whatever.', 'stating something'],
16
- ['WATCH OUT!', 'Whoa, chill out!', 'shouting'],
17
- ['Does this cryogenic chamber make me look fat?', 'Sure.', 'question'],
18
- ['You are, what, like 15?', 'Sure.', 'numeric question'],
19
- ["Let's go make out behind the gym!", 'Whatever.', 'talking forcefully'],
20
- ["It's OK if you don't want to go to the DMV.", 'Whatever.', 'using acronyms in regular speech'],
21
- ['WHAT THE HELL WERE YOU THINKING?', 'Whoa, chill out!', 'forceful questions'],
22
- ['1, 2, 3 GO!', 'Whoa, chill out!', 'shouting numbers'],
23
- ['1, 2, 3', 'Whatever.', 'only numbers'],
24
- ['4?', 'Sure.', 'question with only numbers'],
25
- ['ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!', 'Whoa, chill out!', 'shouting with special characters'],
26
- ["ÜMLÄÜTS!", 'Whoa, chill out!', 'shouting with umlauts'],
27
- ["\xdcML\xc4\xdcTS!", 'Whoa, chill out!', 'shouting with umlauts'],
28
- ["ÜMLäÜTS!", 'Whatever.', 'speaking calmly with umlauts'],
29
- ['I HATE YOU', 'Whoa, chill out!', 'shouting with no exclamation mark'],
30
- ['Ending with ? means a question.', 'Whatever.', 'statement containing question mark'],
31
- ["Wait! Hang on. Are you going to be OK?", 'Sure.', 'prattling on'],
32
- ['', 'Fine. Be that way!', 'silence'],
33
- [' ', 'Fine. Be that way!', 'prolonged silence'],
34
- ;
35
-
36
- for @cases -> ( $string, $expected, $msg ) {
37
- is Bob.hey($string), $expected, $msg;
4
+ use lib my $dir = $?FILE.IO.dirname; # Look for the module inside the same directory as this test file.
5
+ use JSON::Tiny;
6
+
7
+ my $exercise = 'Bob'; # The name of this exercise.
8
+ my $version = v1; # The version we will be matching against the exercise.
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise; # %*ENV<EXERCISM> is for tests not directly for the exercise, don't worry about these :)
10
+ plan 28; # This is how many tests we expect to run.
11
+
12
+ # Check that the module can be use-d.
13
+ use-ok $module or bail-out;
14
+ require ::($module);
15
+
16
+ # If the exercise is updated, we want to make sure other people testing
17
+ # your code don't think you've made a mistake if things have changed!
18
+ if ::($exercise).^ver !~~ $version {
19
+ warn "\nExercise version mismatch. Further tests may fail!"
20
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
21
+ ~ "Test is $($version.gist).\n";
22
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
23
+ }
24
+
25
+ # Check that the Class 'Bob' can use all of the methods
26
+ # needed in the tests (only 'hey' for this one).
27
+ subtest 'Class method(s)', {
28
+ plan 1;
29
+ ok ::($exercise).can($_), $_ for <hey>;
30
+ }
31
+
32
+ # Go through all of the cases (hiding at the bottom of this file)
33
+ # and check that Bob gives us the correct response for each one.
34
+ is ::($exercise).?hey(.<input>), |.<expected description> for @(my $c-data.<cases>);
35
+
36
+ # Ignore this for your exercise! Tells Exercism folks when exercise cases become out of date.
37
+ if %*ENV<EXERCISM> && (my $c-data-file = "$dir/../../x-common/exercises/{$dir.IO.basename}/canonical-data.json".IO.resolve) ~~ :f {
38
+ is $c-data, from-json($c-data-file.slurp), 'canonical-data'
39
+ } else { skip }
40
+
41
+ # There are no more tests after this :)
42
+ done-testing;
43
+
44
+ # 'INIT' is a phaser, it makes sure that the test data is available before everything else
45
+ # starts running (otherwise we'd have to shove all of this into the middle of the file!)
46
+ INIT {
47
+ $c-data := from-json 「
48
+ {
49
+ "exercise": "bob",
50
+ "version": "1.0.0",
51
+ "cases": [
52
+ {
53
+ "description": "stating something",
54
+ "property": "response",
55
+ "input": "Tom-ay-to, tom-aaaah-to.",
56
+ "expected": "Whatever."
57
+ },
58
+ {
59
+ "description": "shouting",
60
+ "property": "response",
61
+ "input": "WATCH OUT!",
62
+ "expected": "Whoa, chill out!"
63
+ },
64
+ {
65
+ "description": "shouting gibberish",
66
+ "property": "response",
67
+ "input": "FCECDFCAAB",
68
+ "expected": "Whoa, chill out!"
69
+ },
70
+ {
71
+ "description": "asking a question",
72
+ "property": "response",
73
+ "input": "Does this cryogenic chamber make me look fat?",
74
+ "expected": "Sure."
75
+ },
76
+ {
77
+ "description": "asking a numeric question",
78
+ "property": "response",
79
+ "input": "You are, what, like 15?",
80
+ "expected": "Sure."
81
+ },
82
+ {
83
+ "description": "asking gibberish",
84
+ "property": "response",
85
+ "input": "fffbbcbeab?",
86
+ "expected": "Sure."
87
+ },
88
+ {
89
+ "description": "talking forcefully",
90
+ "property": "response",
91
+ "input": "Let's go make out behind the gym!",
92
+ "expected": "Whatever."
93
+ },
94
+ {
95
+ "description": "using acronyms in regular speech",
96
+ "property": "response",
97
+ "input": "It's OK if you don't want to go to the DMV.",
98
+ "expected": "Whatever."
99
+ },
100
+ {
101
+ "description": "forceful question",
102
+ "property": "response",
103
+ "input": "WHAT THE HELL WERE YOU THINKING?",
104
+ "expected": "Whoa, chill out!"
105
+ },
106
+ {
107
+ "description": "shouting numbers",
108
+ "property": "response",
109
+ "input": "1, 2, 3 GO!",
110
+ "expected": "Whoa, chill out!"
111
+ },
112
+ {
113
+ "description": "only numbers",
114
+ "property": "response",
115
+ "input": "1, 2, 3",
116
+ "expected": "Whatever."
117
+ },
118
+ {
119
+ "description": "question with only numbers",
120
+ "property": "response",
121
+ "input": "4?",
122
+ "expected": "Sure."
123
+ },
124
+ {
125
+ "description": "shouting with special characters",
126
+ "property": "response",
127
+ "input": "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
128
+ "expected": "Whoa, chill out!"
129
+ },
130
+ {
131
+ "description": "shouting with no exclamation mark",
132
+ "property": "response",
133
+ "input": "I HATE YOU",
134
+ "expected": "Whoa, chill out!"
135
+ },
136
+ {
137
+ "description": "statement containing question mark",
138
+ "property": "response",
139
+ "input": "Ending with ? means a question.",
140
+ "expected": "Whatever."
141
+ },
142
+ {
143
+ "description": "non-letters with question",
144
+ "property": "response",
145
+ "input": ":) ?",
146
+ "expected": "Sure."
147
+ },
148
+ {
149
+ "description": "prattling on",
150
+ "property": "response",
151
+ "input": "Wait! Hang on. Are you going to be OK?",
152
+ "expected": "Sure."
153
+ },
154
+ {
155
+ "description": "silence",
156
+ "property": "response",
157
+ "input": "",
158
+ "expected": "Fine. Be that way!"
159
+ },
160
+ {
161
+ "description": "prolonged silence",
162
+ "property": "response",
163
+ "input": " ",
164
+ "expected": "Fine. Be that way!"
165
+ },
166
+ {
167
+ "description": "alternate silence",
168
+ "property": "response",
169
+ "input": "\t\t\t\t\t\t\t\t\t\t",
170
+ "expected": "Fine. Be that way!"
171
+ },
172
+ {
173
+ "description": "multiple line question",
174
+ "property": "response",
175
+ "input": "\nDoes this cryogenic chamber make me look fat?\nno",
176
+ "expected": "Whatever."
177
+ },
178
+ {
179
+ "description": "starting with whitespace",
180
+ "property": "response",
181
+ "input": " hmmmmmmm...",
182
+ "expected": "Whatever."
183
+ },
184
+ {
185
+ "description": "ending with whitespace",
186
+ "property": "response",
187
+ "input": "Okay if like my spacebar quite a bit? ",
188
+ "expected": "Sure."
189
+ },
190
+ {
191
+ "description": "other whitespace",
192
+ "property": "response",
193
+ "input": "\n\r \t",
194
+ "expected": "Fine. Be that way!"
195
+ },
196
+ {
197
+ "description": "non-question ending with whitespace",
198
+ "property": "response",
199
+ "input": "This is a statement ending with whitespace ",
200
+ "expected": "Whatever."
201
+ }
202
+ ]
203
+ }
204
+
38
205
  }
@@ -1,17 +1,18 @@
1
- use v6;
1
+ unit module GradeSchool:ver<1>;
2
2
 
3
- unit class GradeSchool::Roster is export;
4
- has %!roster;
3
+ class Roster is export {
4
+ has %!roster;
5
5
 
6
- method add-student (Str:D :$name!, Int:D :$grade!) {
7
- %!roster.append($grade, $name);
8
- }
6
+ method add-student (Str:D :$name!, Int:D :$grade!) {
7
+ %!roster.append($grade, $name);
8
+ }
9
9
 
10
- method list-grade (Int:D $grade --> Seq:D) {
11
- %!roster{$grade}.sort;
12
- }
10
+ method list-grade (Int:D $grade --> Seq:D) {
11
+ %!roster{$grade}.sort;
12
+ }
13
13
 
14
- method list-all {
15
- my @list.append("Grade $_", %!roster{$_}.sort) for %!roster.keys.sort;
16
- return @list;
14
+ method list-all {
15
+ my @list.append("Grade $_", %!roster{$_}.sort) for %!roster.keys.sort;
16
+ return @list;
17
+ }
17
18
  }
@@ -0,0 +1,4 @@
1
+ unit module GradeSchool:ver<1>;
2
+
3
+ class Roster is export {
4
+ }
@@ -1,32 +1,51 @@
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 $?FILE.IO.dirname;
5
5
 
6
- plan 10;
7
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'GradeSchool';
8
- use-ok $module;
9
- require ::($module) <Roster>;
6
+ my $exercise = 'GradeSchool';
7
+ my $version = v1;
8
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
9
+ plan 11;
10
10
 
11
- subtest 'Can use all methods', {
12
- plan 3;
13
- ok Roster.can($_), $_ for <add-student list-grade list-all>;
14
- } or fail 'Missing method(s)';
11
+ use-ok $module or bail-out;
12
+ require ::($module);
13
+ if ::($exercise).^ver !~~ $version {
14
+ warn "\nExercise version mismatch. Further tests may fail!"
15
+ ~ "\n$exercise is $(::($exercise).^ver.gist). "
16
+ ~ "Test is $($version.gist).\n";
17
+ bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
18
+ }
19
+
20
+ my @classes;
21
+ BEGIN { @classes = <Roster> };
22
+ subtest 'Class(es)', {
23
+ plan 1;
24
+ eval-lives-ok "use $module; ::('$_').new or die 'Could not use .new method on class $_.\'", $_ for @classes;
25
+ } or bail-out 'All classes must be defined and exported.';
26
+ require ::($module) @classes.eager;
27
+
28
+ for @classes -> $class {
29
+ subtest "$class class method(s)", {
30
+ plan 3;
31
+ ok ::($class).can($_), $_ for <add-student list-grade list-all>;
32
+ }
33
+ }
15
34
 
16
35
  my $roster = Roster.new;
17
36
 
18
- ok $roster.add-student(:name('Jim'), :2grade), 'Add Jim to grade 2';
19
- is $roster.list-grade(2), <Jim>, 'List grade 2';
20
- ok $roster.add-student(:name('Zoe'), :2grade), 'Add Zoe to grade 2';
21
- ok $roster.add-student(:name('Barb'), :1grade), 'Add Barb to grade 1';
22
- is $roster.list-grade(2), <Jim Zoe>, 'List grade 2';
23
- is $roster.list-grade(1), <Barb>, 'List grade 1';
37
+ ok $roster.?add-student(:name('Jim'), :2grade), 'Add Jim to grade 2';
38
+ is $roster.?list-grade(2), <Jim>, 'List grade 2';
39
+ ok $roster.?add-student(:name('Zoe'), :2grade), 'Add Zoe to grade 2';
40
+ ok $roster.?add-student(:name('Barb'), :1grade), 'Add Barb to grade 1';
41
+ is $roster.?list-grade(2), <Jim Zoe>, 'List grade 2';
42
+ is $roster.?list-grade(1), <Barb>, 'List grade 1';
24
43
 
25
44
  subtest 'Additional students', {
26
45
  plan 6;
27
- ok $roster.add-student(:name($_), :1grade), "Add $_ to grade 1" for <Charlie Anna>;
28
- ok $roster.add-student(:name('Alex'), :2grade), 'Add Alex to grade 2';
29
- ok $roster.add-student(:name($_), :3grade), "Add $_ to grade 3" for <Tom Dick Harry>;
46
+ ok $roster.?add-student(:name($_), :1grade), "Add $_ to grade 1" for <Charlie Anna>;
47
+ ok $roster.?add-student(:name('Alex'), :2grade), 'Add Alex to grade 2';
48
+ ok $roster.?add-student(:name($_), :3grade), "Add $_ to grade 3" for <Tom Dick Harry>;
30
49
  }
31
50
 
32
- is $roster.list-all, ('Grade 1', <Anna Barb Charlie>, 'Grade 2', <Alex Jim Zoe>, 'Grade 3', <Dick Harry Tom>), 'List all';
51
+ is $roster.?list-all, ('Grade 1', <Anna Barb Charlie>, 'Grade 2', <Alex Jim Zoe>, 'Grade 3', <Dick Harry Tom>), 'List all';
@@ -1,5 +1,5 @@
1
- unit module HelloWorld:ver<1>;
1
+ unit module HelloWorld:ver<2>;
2
2
 
3
- sub hello (Str $name? --> Str:D) is export {
4
- 'Hello, ' ~ ($name ?? $name !! 'World') ~ '!'
3
+ sub hello is export {
4
+ 'Hello, World!'
5
5
  }
@@ -7,9 +7,9 @@
7
7
  and test suite line up. If the test is updated, it will indicate
8
8
  to others who test your code that some tests may no longer pass.
9
9
  )
10
- unit module HelloWorld:ver<1>;
10
+ unit module HelloWorld:ver<2>;
11
11
 
12
- sub hello ($name?) is export {
12
+ sub hello is export {
13
13
  # Write your solution to pass the test suite here.
14
14
  # Be sure to remove all stock comments once you are done!
15
15
  }
@@ -1,15 +1,20 @@
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; # Look for the module inside the same directory as this test file.
5
+ use JSON::Tiny;
5
6
 
6
- my $exercise = 'HelloWorld';
7
- my $version = v1;
8
- my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
9
- plan 6;
7
+ my $exercise = 'HelloWorld'; # The name of this exercise.
8
+ my $version = v2; # The version we will be matching against the exercise.
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise; # %*ENV<EXERCISM> is for tests not directly for the exercise, don't worry about these :)
10
+ plan 4; # This is how many tests we expect to run.
10
11
 
12
+ # Check that the module can be use-d.
11
13
  use-ok $module or bail-out;
12
14
  require ::($module);
15
+
16
+ # If the exercise is updated, we want to make sure other people testing
17
+ # your code don't think you've made a mistake if things have changed!
13
18
  if ::($exercise).^ver !~~ $version {
14
19
  warn "\nExercise version mismatch. Further tests may fail!"
15
20
  ~ "\n$exercise is $(::($exercise).^ver.gist). "
@@ -17,6 +22,8 @@ if ::($exercise).^ver !~~ $version {
17
22
  bail-out 'Example version must match test version.' if %*ENV<EXERCISM>;
18
23
  }
19
24
 
25
+ # Check that the Module 'HelloWorld' can use all of the subroutines
26
+ # needed in the tests (only '&hello' for this one).
20
27
  my @subs;
21
28
  BEGIN { @subs = <&hello> };
22
29
  subtest 'Subroutine(s)', {
@@ -25,8 +32,32 @@ subtest 'Subroutine(s)', {
25
32
  } or bail-out 'All subroutines must be defined and exported.';
26
33
  require ::($module) @subs.eager;
27
34
 
28
- is hello, 'Hello, World!', 'No argument';
29
- is ''.&hello, 'Hello, World!', 'Empty string';
30
- todo 'optional test', 2 unless %*ENV<EXERCISM>;
31
- is 'Camelia'.&hello, 'Hello, Camelia!', 'Camelia';
32
- is '楽土'.&hello, 'Hello, 楽土!', 'Rakudo';
35
+ # Go through the cases (hiding at the bottom of this file)
36
+ # and check that &hello gives us the correct response.
37
+ is hello, |.<expected description> for @(my $c-data.<cases>);
38
+
39
+ # Ignore this for your exercise! Tells Exercism folks when exercise cases become out of date.
40
+ if %*ENV<EXERCISM> && (my $c-data-file = "$dir/../../x-common/exercises/{$dir.IO.basename}/canonical-data.json".IO.resolve) ~~ :f {
41
+ is $c-data, from-json($c-data-file.slurp), 'canonical-data'
42
+ } else { skip }
43
+
44
+ # There are no more tests after this :)
45
+ done-testing;
46
+
47
+ # 'INIT' is a phaser, it makes sure that the test data is available before everything else
48
+ # starts running (otherwise we'd have to shove the test data into the middle of the file!)
49
+ INIT {
50
+ $c-data := from-json 「
51
+ {
52
+ "exercise": "hello-world",
53
+ "version": "1.0.0",
54
+ "cases": [
55
+ {
56
+ "description": "Say Hi!",
57
+ "property": "hello",
58
+ "expected": "Hello, World!"
59
+ }
60
+ ]
61
+ }
62
+
63
+ }