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
@@ -1,51 +1,50 @@
1
+ unit class LinkedList:ver<1>;
2
+
1
3
  class ListNode {
2
4
  has $.next is rw;
3
5
  has $.previous is rw;
4
6
  has $.value;
5
7
  }
6
8
 
7
- class LinkedList is export {
8
- has $!first;
9
- has $!last;
10
-
11
- method push($value) {
12
- my $next = ListNode.new( value => $value, previous => $!last );
13
- if ( $!last ) {
14
- $!last = $!last.next= $next ;
15
- }
16
- else {
17
- $!first = $!last = $next;
18
- }
19
- }
9
+ has $!first;
10
+ has $!last;
20
11
 
21
- method unshift($value) {
22
- my $next = ListNode.new( value => $value, next => $!first );
23
- if ( $!first ) {
24
- $!first = $!first.previous = $next ;
25
- }
26
- else {
27
- $!first = $!last = $next;
28
- }
12
+ method push-list($value) {
13
+ my $next = ListNode.new( value => $value, previous => $!last );
14
+ if ( $!last ) {
15
+ $!last = $!last.next= $next ;
16
+ }
17
+ else {
18
+ $!first = $!last = $next;
29
19
  }
20
+ }
30
21
 
31
- method shift() {
32
- my $f = $!first;
22
+ method unshift-list($value) {
23
+ my $next = ListNode.new( value => $value, next => $!first );
24
+ if ( $!first ) {
25
+ $!first = $!first.previous = $next ;
26
+ }
27
+ else {
28
+ $!first = $!last = $next;
29
+ }
30
+ }
33
31
 
34
- $!first = $!first.next;
32
+ method shift-list() {
33
+ my $f = $!first;
35
34
 
36
- unless $!first { $!last = $!first }
35
+ $!first = $!first.next;
37
36
 
38
- return $f.value;
39
- }
37
+ unless $!first { $!last = $!first }
40
38
 
41
- method pop() {
42
- my $f = $!last;
39
+ return $f.value;
40
+ }
43
41
 
44
- $!last = $!last.previous;
42
+ method pop-list() {
43
+ my $f = $!last;
45
44
 
46
- unless $!.last { $!first = $!last }
45
+ $!last = $!last.previous;
47
46
 
48
- return $f.value;
49
- }
50
- };
47
+ unless $!.last { $!first = $!last }
51
48
 
49
+ return $f.value;
50
+ }
@@ -0,0 +1 @@
1
+ unit class LinkedList:ver<1>;
@@ -1,35 +1,45 @@
1
1
  #!/usr/bin/env perl6
2
-
2
+ use v6;
3
3
  use Test;
4
+ use lib $?FILE.IO.dirname;
4
5
  use JSON::Tiny;
5
6
 
6
- use lib IO::Path.new($?FILE).parent.path;
7
-
8
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'LinkedList';
9
- require ::($module) <LinkedList>;
7
+ my $exercise = 'LinkedList';
8
+ my $version = v1;
9
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
10
+ plan 7;
10
11
 
11
- my @cases; # defined in INIT
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
+ }
12
20
 
13
- plan 0 + @cases;
21
+ subtest "Class method(s)", {
22
+ plan 4;
23
+ ok ::($exercise).can($_), $_ for <push-list pop-list shift-list unshift-list>;
24
+ }
14
25
 
15
- for @cases -> $c {
16
- subtest $c.<name>, sub {
17
- my $ll = LinkedList.new;
18
- for |$c.<set> -> %s {
19
- for %s {
20
- my $v = $_.value;
21
- given $_.key {
22
- when 'push' { $ll.push( $v ); pass 'push ' ~ $v }
23
- when 'unshift' { $ll.unshift( $v ); pass 'unshift ' ~ $v }
24
- when 'pop' { is $ll.pop, $v, 'pop' }
25
- when 'shift' { is $ll.shift, $v, 'shift' }
26
- }
27
- }
26
+ for my @cases -> $case {
27
+ subtest $case.<name>, sub {
28
+ my $linkedlist = ::($exercise).new;
29
+ for |$case.<set> -> %set {
30
+ for %set {
31
+ my $value = $_.value;
32
+ given $_.key {
33
+ when 'push' { $linkedlist.?push-list( $value ) }
34
+ when 'unshift' { $linkedlist.?unshift-list( $value ) }
35
+ when 'pop' { is $linkedlist.?pop-list, $value, 'pop' }
36
+ when 'shift' { is $linkedlist.?shift-list, $value, 'shift' }
28
37
  }
29
- };
38
+ }
39
+ }
40
+ }
30
41
  }
31
42
 
32
-
33
43
  done-testing;
34
44
 
35
45
  INIT {
@@ -1,19 +1,12 @@
1
- class Robot is export {
2
- has $.name is rw = self.reset_name;
1
+ unit class Robot:ver<1>;
3
2
 
4
- method rand_letter {
5
- ['A'..'Z'].pick;
6
- }
3
+ state %record;
7
4
 
8
- method rand_suffix {
9
- 100 + 900.rand.truncate;
10
- }
5
+ has Str:D $.name = self.reset-name;
11
6
 
12
- method new_name {
13
- self.rand_letter ~ self.rand_letter ~ self.rand_suffix;
14
- }
15
-
16
- method reset_name {
17
- self.name = self.new_name;
18
- }
7
+ method reset-name {
8
+ $!name = ('AA'..'ZZ').roll ~ ('000'..'999').roll;
9
+ self.reset-name if %record{$!name}:exists;
10
+ %record{$!name} = True;
11
+ return $!name;
19
12
  }
@@ -0,0 +1 @@
1
+ unit class Robot:ver<1>;
@@ -1,23 +1,48 @@
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 7;
7
- my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Robot';
8
- use-ok $module;
9
- require ::($module) <Robot>;
6
+ my $exercise = 'Robot';
7
+ my $version = v1;
8
+ my $module = %*ENV<EXERCISM> ?? 'Example' !! $exercise;
9
+ plan 8;
10
10
 
11
- ok Robot.can('name'), 'Robot class has name attribute';
12
- ok Robot.can('reset_name'), 'Robot class has reset_name method';
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 must match test.' if %*ENV<EXERCISM>;
18
+ }
13
19
 
14
- my $robot = Robot.new;
15
- my $name = $robot.name;
20
+ subtest 'Class method(s)', {
21
+ plan 2;
22
+ ok ::($exercise).can($_), $_ for <name reset-name>;
23
+ }
16
24
 
17
- like $name, /^^<[A..Z]>**2 <[0..9]>**3$$/, 'Name should match schema';
18
- is $name, $robot.name, 'Name should be persistent';
19
- ok $robot.name ne Robot.new.name, 'Robots should have different names';
25
+ srand 1;
26
+ my $robot = ::($exercise).?new;
27
+ my Str $name = $robot.?name;
20
28
 
21
- $robot.reset_name;
29
+ like $name, /^^<[A..Z]>**2 <[0..9]>**3$$/, 'Name matches schema';
30
+ srand 2;
31
+ is $robot.?name, $name, 'Name is persistent';
22
32
 
23
- ok $robot.name ne $name, 'reset_name should change the robot name';
33
+ srand 1;
34
+ isnt ::($exercise).new.?name, $name, 'New Robot cannot claim previous Robot name';
35
+
36
+ srand 1;
37
+ $robot.?reset-name;
38
+ $robot.?reset_name; # Allows next test to still pass for older solutions
39
+ isnt $robot.?name, $name, "'reset-name' cannot use previous Robot name";
40
+
41
+ diag "\nCreating 100 robots...";
42
+ push my @names, ::($exercise).new.name for 1..100;
43
+ is @names, @names.unique, 'All names are unique';
44
+ subtest 'Randomness', {
45
+ plan 2;
46
+ isnt @names, @names.sort, 'Names not ordered';
47
+ isnt @names, @names.sort.reverse, 'Names not reverse ordered';
48
+ }
@@ -362,6 +362,11 @@
362
362
  "topics": [
363
363
  "Arrays"
364
364
  ]
365
+ },
366
+ {
367
+ "slug": "luhn",
368
+ "difficulty": 4,
369
+ "topics": []
365
370
  }
366
371
  ]
367
372
  }
@@ -0,0 +1,26 @@
1
+ <?php
2
+
3
+ function isValid($candidate)
4
+ {
5
+ $sanitizedCandidate = str_replace(" ", "", $candidate) ;
6
+
7
+ if (strlen($sanitizedCandidate) <= 1 || !ctype_digit($sanitizedCandidate)) {
8
+ return false ;
9
+ }
10
+
11
+ $reversseCandidate = strrev($sanitizedCandidate) ;
12
+ $sum = 0 ;
13
+
14
+ for ($i = 1; $i < strlen($reversseCandidate); $i+=2) {
15
+ $digit = 2 * intval($reversseCandidate{$i}) ;
16
+
17
+ if ($digit > 9) {
18
+ $digit -= 9 ;
19
+ }
20
+
21
+ $sum += $digit ;
22
+ $sum += intval($reversseCandidate{$i-1}) ;
23
+ }
24
+
25
+ return $sum % 10 == 0 ;
26
+ }
@@ -0,0 +1,95 @@
1
+ <?php
2
+
3
+ require "luhn.php";
4
+
5
+ class LuhnValidatorTest extends PHPUnit\Framework\TestCase
6
+ {
7
+ public function testSingleDigitInvalid()
8
+ {
9
+ $this->assertFalse(isValid("1"));
10
+ }
11
+
12
+ public function testSingleZeroInvalid()
13
+ {
14
+ $this->markTestSkipped();
15
+
16
+ $this->assertFalse(isValid("0"));
17
+ }
18
+
19
+ public function testSimpleValidNumber()
20
+ {
21
+ $this->markTestSkipped();
22
+
23
+ $this->assertTrue(isValid("59"));
24
+ }
25
+
26
+ public function testSpaceHandling()
27
+ {
28
+ $this->markTestSkipped();
29
+
30
+ $this->assertTrue(isValid(" 5 9 "));
31
+ }
32
+
33
+ public function testValidCanadianSocialInsuranceNumber()
34
+ {
35
+ $this->markTestSkipped();
36
+
37
+ $this->assertTrue(isValid("046 454 286"));
38
+ }
39
+
40
+ public function testInvalidCanadianSocialInsuranceNumber()
41
+ {
42
+ $this->markTestSkipped();
43
+
44
+ $this->assertFalse(isValid("046 454 287"));
45
+ }
46
+
47
+ public function testInvalidCreditCard()
48
+ {
49
+ $this->markTestSkipped();
50
+
51
+ $this->assertFalse(isValid("8273 1232 7352 0569"));
52
+ }
53
+
54
+ public function testNonDigitCharacterInValidStringInvalidatesTheString()
55
+ {
56
+ $this->markTestSkipped();
57
+
58
+ $this->assertFalse(isValid("046a 454 286"));
59
+ }
60
+
61
+ public function testThatStringContainingSymbolsIsInvalid()
62
+ {
63
+ $this->markTestSkipped();
64
+
65
+ $this->assertFalse(isValid("055£ 444$ 285"));
66
+ }
67
+
68
+ public function testThatStringContainingPunctuationIsInvalid()
69
+ {
70
+ $this->markTestSkipped();
71
+
72
+ $this->assertFalse(isValid("055-444-285"));
73
+ }
74
+
75
+ public function testSpaceAndSingleZeroIsInvalid()
76
+ {
77
+ $this->markTestSkipped();
78
+
79
+ $this->assertFalse(isValid(" 0"));
80
+ }
81
+
82
+ public function testMultipleZerosIsValid()
83
+ {
84
+ $this->markTestSkipped();
85
+
86
+ $this->assertTrue(isValid(" 00000"));
87
+ }
88
+
89
+ public function testThatDoublingNineIsHandledCorrectly()
90
+ {
91
+ $this->markTestSkipped();
92
+
93
+ $this->assertTrue(isValid("091"));
94
+ }
95
+ }
@@ -2,13 +2,76 @@
2
2
 
3
3
  Exercism problems in PureScript.
4
4
 
5
- ## TODO
5
+ ## How to contribute
6
6
 
7
- _Document how to contribute to the PureScript track._
7
+ Thank you so much for contributing! :tada:
8
8
 
9
- ## Contributing Guide
9
+ - [Asking for help](#asking-for-help)
10
+ - [How to contribute](#how-to-contribute)
11
+ * [Reporting or fixing bugs](#reporting-or-fixing-bugs)
12
+ * [Reviewing issues and pull requests](#reviewing-issues-and-pull)
13
+ * [Porting exercises](#porting-exercises)
14
+ - [Repository structure and conventions](#repository-structure-and-conventions)
15
+ - [Writing a pull request](#writing-a-pull-request)
16
+
17
+
18
+ ### Asking for help
19
+
20
+ When in doubt just [open a GitHub issue][new-issue] and ask! In any case,
21
+ don't be afraid or shy! We promise to be friendly and as helpful as possible.
22
+
23
+ [new-issue]: https://github.com/exercism/xpurescript/issues/new
24
+
25
+
26
+ ### How to contribute
27
+
28
+ As a first step we recommend you read the [contributing guide][cont-guide].
29
+
30
+ [cont-guide]: https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md
31
+
32
+ #### Reporting or fixing bugs
33
+
34
+ Typical examples for a bug: A typo, a missing test case, an unclear or
35
+ ambiguous problem description.
36
+
37
+ - If you are unsure whether you have really found a bug [just ask](#asking-for-help).
38
+ - To report a bug you can [write an issue][new-issue]
39
+ - If you already have a fix for it you may [write a pull request](#writing-a-pull-request).
40
+
41
+ #### Reviewing issues and pull requests
42
+
43
+ If you have an opinion or feedback on work currently being done on this track
44
+ please do [write a comment][write-comment] for an [issue][issue] or a
45
+ [pull request][prs]. Feedback is extremely useful to us.
46
+
47
+ [write-comment]: https://help.github.com/articles/commenting-on-a-pull-request/
48
+ [issues]: https://github.com/exercism/xpurescript/issue
49
+ [prs]: https://github.com/exercism/xpurescript/pull
50
+
51
+ Please be detailed and include any links or arguments to support your
52
+ opinion.
53
+
54
+ #### Porting exercises
55
+
56
+ Here is the [list of missing exercises][missing]. See here for more
57
+ information about [porting an exercise][porting]. Of course you can also add a
58
+ totally new exercise, but it might be a good idea to first discuss it in one
59
+ of [our forums](#asking-for-help).
60
+
61
+ [missing]: http://exercism.io/languages/purescript/todo
62
+ [porting]: https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md#porting-an-exercise-to-another-language-track
63
+
64
+
65
+ ### Repository structure and conventions
66
+
67
+ [Here](https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md#track-anatomy)
68
+ is a general description of all the files and directories that are not
69
+ explicitly described below.
70
+
71
+
72
+ ### Writing a pull request
73
+ To fix a bug you should [create a pull request from a fork](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) [here](https://github.com/exercism/xpurescript/pull). See also [here](https://github.com/exercism/x-common/blob/master/CONTRIBUTING.md#git-basics) for more information.
10
74
 
11
- Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data)
12
75
 
13
76
  ## License
14
77
 
@@ -16,3 +16,4 @@ With this premise, a good, beginner friendly, starting point for those who don't
16
16
  - [Offical Python3 **Documentation** and **Reference**](https://docs.python.org/3/)
17
17
  - [Learn X in Y minutes (where X = Python3)](https://learnxinyminutes.com/docs/python3/)
18
18
  - [The Hitchhiker’s Guide to Python](http://docs.python-guide.org/en/latest/)
19
+ - [PyCharm EDU **IDE** and **Courses**](https://www.jetbrains.com/pycharm-edu/)
@@ -3,8 +3,9 @@ import unittest
3
3
  from acronym import abbreviate
4
4
 
5
5
 
6
- class AcronymTest(unittest.TestCase):
6
+ # test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
7
7
 
8
+ class AcronymTest(unittest.TestCase):
8
9
  def test_basic(self):
9
10
  self.assertEqual('PNG', abbreviate('Portable Network Graphics'))
10
11
 
@@ -20,6 +21,9 @@ class AcronymTest(unittest.TestCase):
20
21
  def test_all_caps_words(self):
21
22
  self.assertEqual('PHP', abbreviate('PHP: Hypertext Preprocessor'))
22
23
 
24
+ def test_non_acronym_all_caps_word(self):
25
+ self.assertEqual('GIMP', abbreviate('GNU Image Manipulation Program'))
26
+
23
27
  def test_hyphenated(self):
24
28
  self.assertEqual('CMOS', abbreviate('Complementary metal-oxide semiconductor'))
25
29
 
@@ -3,6 +3,8 @@ import unittest
3
3
  from atbash_cipher import decode, encode
4
4
 
5
5
 
6
+ # test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
7
+
6
8
  class AtbashCipherTest(unittest.TestCase):
7
9
 
8
10
  def test_encode_no(self):
@@ -48,6 +50,12 @@ class AtbashCipherTest(unittest.TestCase):
48
50
  decode("gvhgr mt123 gvhgr mt")
49
51
  )
50
52
 
53
+ def test_decode_all_the_letters(self):
54
+ ciphertext = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
55
+ plaintext = "thequickbrownfoxjumpsoverthelazydog"
56
+ self.assertMultiLineEqual(plaintext, decode(ciphertext))
57
+
58
+ # additional track specific test
51
59
  def test_encode_decode(self):
52
60
  self.assertMultiLineEqual(
53
61
  "testing123testing",
@@ -1,48 +1,14 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- from __future__ import unicode_literals
4
1
  import unittest
5
2
 
6
3
  import hello_world
7
4
 
8
5
 
9
- class HelloWorldTests(unittest.TestCase):
10
-
11
- def test_hello_without_name(self):
12
- self.assertEqual(
13
- 'Hello, World!',
14
- hello_world.hello()
15
- )
16
-
17
- def test_hello_with_sample_name(self):
18
- self.assertEqual(
19
- 'Hello, Alice!',
20
- hello_world.hello('Alice')
21
- )
6
+ # test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
22
7
 
23
- def test_hello_with_other_sample_name(self):
24
- self.assertEqual(
25
- 'Hello, Bob!',
26
- hello_world.hello('Bob')
27
- )
28
-
29
- def test_hello_with_umlaut_name(self):
30
- self.assertEqual(
31
- 'Hello, Jürgen!',
32
- hello_world.hello('Jürgen')
33
- )
34
-
35
- def test_hello_with_blank_name(self):
36
- self.assertEqual(
37
- 'Hello, World!',
38
- hello_world.hello('')
39
- )
8
+ class HelloWorldTests(unittest.TestCase):
40
9
 
41
- def test_hello_with_none_name(self):
42
- self.assertEqual(
43
- 'Hello, World!',
44
- hello_world.hello(None)
45
- )
10
+ def test_hello(self):
11
+ self.assertEqual('Hello, World!', hello_world.hello())
46
12
 
47
13
 
48
14
  if __name__ == '__main__':
@@ -1,6 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
- from __future__ import unicode_literals
3
-
4
1
  import unittest
5
2
 
6
3
  from run_length_encoding import encode, decode
@@ -8,30 +5,48 @@ from run_length_encoding import encode, decode
8
5
 
9
6
  class WordCountTests(unittest.TestCase):
10
7
 
11
- def test_encode(self):
12
- self.assertMultiLineEqual('2A3B4C', encode('AABBBCCCC'))
8
+ def test_encode_empty_string(self):
9
+ self.assertMultiLineEqual('', encode(''))
13
10
 
14
- def test_decode(self):
15
- self.assertMultiLineEqual('AABBBCCCC', decode('2A3B4C'))
11
+ def test_encode_single_characters_only_are_encoded_without_count(self):
12
+ self.assertMultiLineEqual('XYZ', encode('XYZ'))
13
+
14
+ def test_encode_string_with_no_single_characters(self):
15
+ self.assertMultiLineEqual('2A3B4C', encode('AABBBCCCC'))
16
16
 
17
- def test_encode_with_single(self):
17
+ def test_encode_single_characters_mixed_with_repeated_characters(self):
18
18
  self.assertMultiLineEqual(
19
19
  '12WB12W3B24WB',
20
20
  encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'))
21
21
 
22
- def test_decode_with_single(self):
22
+ def test_encode_multiple_whitespace_mixed_in_string(self):
23
+ self.assertMultiLineEqual('2 hs2q q2w2 ', encode(' hsqq qww '))
24
+
25
+ def test_encode_lowercase_characters(self):
26
+ self.assertMultiLineEqual('2a3b4c', encode('aabbbcccc'))
27
+
28
+ def test_decode_empty_string(self):
29
+ self.assertMultiLineEqual('', decode(''))
30
+
31
+ def test_decode_single_characters_only(self):
32
+ self.assertMultiLineEqual('XYZ', decode('XYZ'))
33
+
34
+ def test_decode_string_with_no_single_characters(self):
35
+ self.assertMultiLineEqual('AABBBCCCC', decode('2A3B4C'))
36
+
37
+ def test_decode_single_characters_with_repeated_characters(self):
23
38
  self.assertMultiLineEqual(
24
39
  'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB',
25
40
  decode('12WB12W3B24WB'))
26
41
 
27
- def test_combination(self):
28
- self.assertMultiLineEqual('zzz ZZ zZ', decode(encode('zzz ZZ zZ')))
42
+ def test_decode_multiple_whitespace_mixed_in_string(self):
43
+ self.assertMultiLineEqual(' hsqq qww ', decode('2 hs2q q2w2 '))
29
44
 
30
- def test_encode_unicode_s(self):
31
- self.assertMultiLineEqual('⏰3⚽2⭐⏰', encode('⏰⚽⚽⚽⭐⭐⏰'))
45
+ def test_decode_lower_case_string(self):
46
+ self.assertMultiLineEqual('aabbbcccc', decode('2a3b4c'))
32
47
 
33
- def test_decode_unicode(self):
34
- self.assertMultiLineEqual('⏰⚽⚽⚽⭐⭐⏰', decode('⏰3⚽2⭐⏰'))
48
+ def test_combination(self):
49
+ self.assertMultiLineEqual('zzz ZZ zZ', decode(encode('zzz ZZ zZ')))
35
50
 
36
51
 
37
52
  if __name__ == '__main__':