trackler 2.2.1.52 → 2.2.1.53

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/leap/canonical-data.json +2 -2
  4. data/tracks/cfml/tasks/FormatConfig.cfc +6 -4
  5. data/tracks/cfml/tasks/GenerateReadme.cfc +197 -0
  6. data/tracks/cfml/tasks/ScaffoldExercise.cfc +6 -0
  7. data/tracks/csharp/config.json +1 -1
  8. data/tracks/delphi/exercises/leap/uLeapTests.pas +1 -1
  9. data/tracks/fsharp/exercises/clock/Clock.fs +1 -1
  10. data/tracks/fsharp/exercises/clock/ClockTest.fs +239 -61
  11. data/tracks/fsharp/exercises/clock/Example.fs +3 -3
  12. data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +29 -26
  13. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +30 -15
  14. data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
  15. data/tracks/fsharp/exercises/rectangles/Example.fs +1 -1
  16. data/tracks/fsharp/exercises/rectangles/Rectangles.fs +1 -1
  17. data/tracks/fsharp/exercises/rectangles/RectanglesTest.fs +66 -43
  18. data/tracks/fsharp/generators/Generators.fs +85 -1
  19. data/tracks/java/scripts/canonical_data_check.sh +8 -0
  20. data/tracks/kotlin/.gitignore +1 -0
  21. data/tracks/kotlin/exercises/acronym/.meta/version +1 -0
  22. data/tracks/kotlin/exercises/acronym/src/test/kotlin/AcronymTest.kt +9 -10
  23. data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -1
  24. data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +20 -20
  25. data/tracks/kotlin/exercises/allergies/.meta/version +1 -0
  26. data/tracks/kotlin/exercises/allergies/src/test/kotlin/AllergiesTest.kt +19 -72
  27. data/tracks/kotlin/exercises/anagram/.meta/src/reference/kotlin/Anagram.kt +7 -4
  28. data/tracks/kotlin/exercises/anagram/.meta/version +1 -0
  29. data/tracks/kotlin/exercises/anagram/src/test/kotlin/AnagramTest.kt +76 -29
  30. data/tracks/kotlin/exercises/atbash-cipher/.meta/version +1 -0
  31. data/tracks/kotlin/exercises/atbash-cipher/src/test/kotlin/AtbashTest.kt +6 -3
  32. data/tracks/kotlin/exercises/beer-song/.meta/version +1 -0
  33. data/tracks/kotlin/exercises/beer-song/src/test/kotlin/BeerSongTest.kt +21 -46
  34. data/tracks/kotlin/exercises/binary-search/.meta/version +1 -0
  35. data/tracks/kotlin/exercises/binary-search/src/test/kotlin/BinarySearchTest.kt +30 -19
  36. data/tracks/kotlin/exercises/bob/.meta/src/reference/kotlin/Bob.kt +8 -7
  37. data/tracks/kotlin/exercises/bob/.meta/version +1 -0
  38. data/tracks/kotlin/exercises/bob/src/test/kotlin/BobTest.kt +57 -15
  39. data/tracks/kotlin/exercises/bracket-push/.meta/version +1 -0
  40. data/tracks/kotlin/exercises/bracket-push/src/test/kotlin/BracketPushTest.kt +3 -1
  41. data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -1
  42. data/tracks/kotlin/exercises/difference-of-squares/.meta/version +1 -0
  43. data/tracks/kotlin/exercises/difference-of-squares/src/test/kotlin/SquaresTest.kt +10 -23
  44. data/tracks/kotlin/exercises/etl/.meta/src/reference/kotlin/ETL.kt +7 -1
  45. data/tracks/kotlin/exercises/etl/.meta/version +1 -0
  46. data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +10 -10
  47. data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -0
  48. data/tracks/kotlin/exercises/flatten-array/src/test/kotlin/FlattenerTest.kt +8 -16
  49. data/tracks/kotlin/exercises/gigasecond/.meta/version +1 -0
  50. data/tracks/kotlin/exercises/gigasecond/src/test/kotlin/GigasecondTest.kt +1 -1
  51. data/tracks/kotlin/exercises/hamming/.meta/src/reference/kotlin/Hamming.kt +1 -1
  52. data/tracks/kotlin/exercises/hamming/.meta/version +1 -1
  53. data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +4 -4
  54. data/tracks/kotlin/exercises/hello-world/.meta/version +1 -0
  55. data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +1 -1
  56. data/tracks/kotlin/exercises/isogram/.meta/version +1 -0
  57. data/tracks/kotlin/exercises/isogram/src/test/kotlin/IsogramTest.kt +5 -8
  58. data/tracks/kotlin/exercises/largest-series-product/.meta/src/reference/kotlin/Series.kt +2 -3
  59. data/tracks/kotlin/exercises/largest-series-product/.meta/version +1 -0
  60. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesTest.kt +97 -0
  61. data/tracks/kotlin/exercises/leap/.meta/version +1 -0
  62. data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +8 -26
  63. data/tracks/kotlin/exercises/list-ops/.meta/version +1 -1
  64. data/tracks/kotlin/exercises/luhn/.meta/version +1 -0
  65. data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +0 -3
  66. data/tracks/kotlin/exercises/nth-prime/.meta/version +1 -0
  67. data/tracks/kotlin/exercises/nth-prime/src/test/kotlin/PrimeTest.kt +0 -2
  68. data/tracks/kotlin/exercises/nucleotide-count/.meta/src/reference/kotlin/{DNA.kt → Dna.kt} +3 -8
  69. data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -0
  70. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/DnaTest.kt +48 -0
  71. data/tracks/kotlin/exercises/pangram/.meta/src/reference/kotlin/{Pangrams.kt → Pangram.kt} +1 -1
  72. data/tracks/kotlin/exercises/pangram/.meta/version +1 -1
  73. data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +15 -9
  74. data/tracks/kotlin/exercises/pascals-triangle/.meta/version +1 -0
  75. data/tracks/kotlin/exercises/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt +32 -14
  76. data/tracks/kotlin/exercises/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt +1 -1
  77. data/tracks/kotlin/exercises/perfect-numbers/.meta/version +1 -0
  78. data/tracks/kotlin/exercises/perfect-numbers/src/test/kotlin/{PerfectNumbersTest.kt → NaturalNumberTest.kt} +25 -7
  79. data/tracks/kotlin/exercises/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt +15 -7
  80. data/tracks/kotlin/exercises/phone-number/.meta/version +1 -0
  81. data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +46 -29
  82. data/tracks/kotlin/exercises/pig-latin/.meta/src/reference/kotlin/PigLatin.kt +2 -2
  83. data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -0
  84. data/tracks/kotlin/exercises/pig-latin/src/test/kotlin/PigLatinTest.kt +21 -10
  85. data/tracks/kotlin/exercises/raindrops/.meta/version +1 -0
  86. data/tracks/kotlin/exercises/raindrops/src/test/kotlin/RaindropsTest.kt +19 -26
  87. data/tracks/kotlin/exercises/react/.meta/version +1 -0
  88. data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +11 -4
  89. data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -1
  90. data/tracks/kotlin/exercises/roman-numerals/.meta/version +1 -0
  91. data/tracks/kotlin/exercises/roman-numerals/src/test/kotlin/RomanNumeralTest.kt +1 -2
  92. data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -1
  93. data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +7 -7
  94. data/tracks/kotlin/exercises/scrabble-score/.meta/src/reference/kotlin/{Scrabble.kt → ScrabbleScore.kt} +1 -1
  95. data/tracks/kotlin/exercises/scrabble-score/.meta/version +1 -0
  96. data/tracks/kotlin/exercises/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt +9 -7
  97. data/tracks/kotlin/exercises/sieve/.meta/version +1 -0
  98. data/tracks/kotlin/exercises/sieve/src/test/kotlin/SieveTest.kt +8 -0
  99. data/tracks/kotlin/exercises/space-age/.meta/version +1 -0
  100. data/tracks/kotlin/exercises/space-age/src/test/kotlin/SpaceAgeTest.kt +1 -16
  101. data/tracks/kotlin/exercises/sum-of-multiples/.meta/version +1 -0
  102. data/tracks/kotlin/exercises/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt +7 -7
  103. data/tracks/kotlin/exercises/triangle/.meta/version +1 -0
  104. data/tracks/kotlin/exercises/two-fer/.meta/version +1 -0
  105. data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +0 -1
  106. data/tracks/kotlin/exercises/word-count/.meta/src/reference/kotlin/WordCount.kt +6 -2
  107. data/tracks/kotlin/exercises/word-count/.meta/version +1 -0
  108. data/tracks/kotlin/exercises/word-count/src/test/kotlin/WordCountTest.kt +31 -9
  109. data/tracks/kotlin/scripts/canonical_data_check.sh +8 -0
  110. data/tracks/perl6/exercises/leap/leap.t +2 -2
  111. data/tracks/php/config.json +16 -0
  112. data/tracks/php/exercises/crypto-square/crypto-square_test.php +50 -0
  113. data/tracks/php/exercises/crypto-square/example.php +32 -0
  114. data/tracks/php/exercises/meetup/README.md +21 -0
  115. data/tracks/php/exercises/meetup/example.php +19 -0
  116. data/tracks/php/exercises/meetup/meetup_test.php +577 -0
  117. data/tracks/python/README.md +7 -5
  118. data/tracks/python/config.json +36 -27
  119. data/tracks/python/docs/TESTS.md +36 -12
  120. data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +1 -1
  121. data/tracks/python/exercises/diffie-hellman/.meta/hints.md +16 -0
  122. data/tracks/python/exercises/diffie-hellman/README.md +15 -2
  123. data/tracks/python/exercises/error-handling/README.md +23 -0
  124. data/tracks/python/exercises/error-handling/error_handling.py +14 -0
  125. data/tracks/python/exercises/error-handling/error_handling_test.py +66 -0
  126. data/tracks/python/exercises/error-handling/example.py +21 -0
  127. data/tracks/python/exercises/forth/forth_test.py +1 -1
  128. data/tracks/python/exercises/isogram/isogram_test.py +5 -3
  129. data/tracks/python/exercises/leap/leap_test.py +2 -2
  130. data/tracks/python/exercises/rotational-cipher/rotational_cipher_test.py +4 -4
  131. data/tracks/python/exercises/simple-cipher/.meta/hints.md +16 -0
  132. data/tracks/python/exercises/simple-cipher/README.md +17 -0
  133. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples_test.py +4 -1
  134. data/tracks/python/exercises/twelve-days/example.py +3 -3
  135. data/tracks/python/exercises/twelve-days/twelve_days.py +2 -2
  136. metadata +53 -9
  137. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesInvalidInputTest.kt +0 -30
  138. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesValidInputTest.kt +0 -34
  139. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/NucleotideTest.kt +0 -87
@@ -62,6 +62,7 @@ then
62
62
  fi
63
63
 
64
64
  track_exercise_slugs=$(jq '.exercises[] | select(has("deprecated") | not) | .slug' $config_file_path | tr -d "\"")
65
+ update_needed_count=0
65
66
 
66
67
  for slug in $track_exercise_slugs
67
68
  do
@@ -88,6 +89,7 @@ do
88
89
  if ! [ -f "$track_exercise_version_file_path" ]
89
90
  then
90
91
  echo "$slug: needs update or version file (v$canonical_data_version)."
92
+ update_needed_count=$((update_needed_count + 1))
91
93
  continue
92
94
  fi
93
95
 
@@ -98,7 +100,13 @@ do
98
100
  # echo "$slug: up-to-date."
99
101
  continue
100
102
  else
103
+ update_needed_count=$((update_needed_count + 1))
101
104
  echo "$slug: needs update (v$track_data_version -> v$canonical_data_version)."
102
105
  fi
103
106
 
104
107
  done
108
+
109
+ if [ $update_needed_count -eq 1 ]
110
+ then
111
+ echo "All exercises are up to date!"
112
+ fi
@@ -7,3 +7,4 @@ build
7
7
  .gradle
8
8
  .idea
9
9
  *.iml
10
+ out/
@@ -4,7 +4,6 @@ import kotlin.test.assertEquals
4
4
 
5
5
  class AcronymTest {
6
6
 
7
-
8
7
  @Test
9
8
  fun fromTitleCasedPhrases() {
10
9
  val phrase = "Portable Network Graphics"
@@ -20,14 +19,6 @@ class AcronymTest {
20
19
  assertEquals(expected, Acronym.generate(phrase))
21
20
  }
22
21
 
23
- @Ignore
24
- @Test
25
- fun fromInconsistentlyCasedPhrases() {
26
- val phrase = "HyperText Markup Language"
27
- val expected = "HTML"
28
- assertEquals(expected, Acronym.generate(phrase))
29
- }
30
-
31
22
  @Ignore
32
23
  @Test
33
24
  fun fromPhrasesWithPunctuation() {
@@ -38,12 +29,20 @@ class AcronymTest {
38
29
 
39
30
  @Ignore
40
31
  @Test
41
- fun fromOtherPhrasesWithPunctuation() {
32
+ fun fromAllCapsWord() {
42
33
  val phrase = "PHP: Hypertext Preprocessor"
43
34
  val expected = "PHP"
44
35
  assertEquals(expected, Acronym.generate(phrase))
45
36
  }
46
37
 
38
+ @Ignore
39
+ @Test
40
+ fun fromNonAcronymAllCapsWord() {
41
+ val phrase = "GNU Image Manipulation Program"
42
+ val expected = "GIMP"
43
+ assertEquals(expected, Acronym.generate(phrase))
44
+ }
45
+
47
46
  @Ignore
48
47
  @Test
49
48
  fun fromPhrasesWithPunctuationAndSentenceCasing() {
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -168,69 +168,69 @@ class BaseConverterTest {
168
168
 
169
169
  @Ignore
170
170
  @Test
171
- fun testNegativeDigit() {
171
+ fun testFirstBaseIsOne() {
172
172
  expectedException.expect(IllegalArgumentException::class.java)
173
- expectedException.expectMessage("Digits may not be negative.")
173
+ expectedException.expectMessage("Bases must be at least 2.")
174
174
 
175
- BaseConverter(2, intArrayOf(1, -1, 1, 0, 1, 0))
175
+ BaseConverter(1, intArrayOf())
176
176
  }
177
177
 
178
178
  @Ignore
179
179
  @Test
180
- fun testInvalidPositiveDigit() {
180
+ fun testFirstBaseIsZero() {
181
181
  expectedException.expect(IllegalArgumentException::class.java)
182
- expectedException.expectMessage("All digits must be strictly less than the base.")
182
+ expectedException.expectMessage("Bases must be at least 2.")
183
183
 
184
- BaseConverter(2, intArrayOf(1, 2, 1, 0, 1, 0))
184
+ BaseConverter(0, intArrayOf())
185
185
  }
186
186
 
187
187
  @Ignore
188
188
  @Test
189
- fun testFirstBaseIsOne() {
189
+ fun testFirstBaseIsNegative() {
190
190
  expectedException.expect(IllegalArgumentException::class.java)
191
191
  expectedException.expectMessage("Bases must be at least 2.")
192
192
 
193
- BaseConverter(1, intArrayOf())
193
+ BaseConverter(-2, intArrayOf())
194
194
  }
195
195
 
196
196
  @Ignore
197
197
  @Test
198
- fun testSecondBaseIsOne() {
199
- val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))
200
-
198
+ fun testNegativeDigit() {
201
199
  expectedException.expect(IllegalArgumentException::class.java)
202
- expectedException.expectMessage("Bases must be at least 2.")
200
+ expectedException.expectMessage("Digits may not be negative.")
203
201
 
204
- baseConverter.convertToBase(1)
202
+ BaseConverter(2, intArrayOf(1, -1, 1, 0, 1, 0))
205
203
  }
206
204
 
207
205
  @Ignore
208
206
  @Test
209
- fun testFirstBaseIsZero() {
207
+ fun testInvalidPositiveDigit() {
210
208
  expectedException.expect(IllegalArgumentException::class.java)
211
- expectedException.expectMessage("Bases must be at least 2.")
209
+ expectedException.expectMessage("All digits must be strictly less than the base.")
212
210
 
213
- BaseConverter(0, intArrayOf())
211
+ BaseConverter(2, intArrayOf(1, 2, 1, 0, 1, 0))
214
212
  }
215
213
 
216
214
  @Ignore
217
215
  @Test
218
- fun testSecondBaseIsZero() {
216
+ fun testSecondBaseIsOne() {
219
217
  val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))
220
218
 
221
219
  expectedException.expect(IllegalArgumentException::class.java)
222
220
  expectedException.expectMessage("Bases must be at least 2.")
223
221
 
224
- baseConverter.convertToBase(0)
222
+ baseConverter.convertToBase(1)
225
223
  }
226
224
 
227
225
  @Ignore
228
226
  @Test
229
- fun testFirstBaseIsNegative() {
227
+ fun testSecondBaseIsZero() {
228
+ val baseConverter = BaseConverter(2, intArrayOf(1, 0, 1, 0, 1, 0))
229
+
230
230
  expectedException.expect(IllegalArgumentException::class.java)
231
231
  expectedException.expectMessage("Bases must be at least 2.")
232
232
 
233
- BaseConverter(-2, intArrayOf())
233
+ baseConverter.convertToBase(0)
234
234
  }
235
235
 
236
236
  @Ignore
@@ -1,18 +1,18 @@
1
1
  import org.junit.Test
2
2
  import org.junit.Ignore
3
3
  import kotlin.test.assertEquals
4
+ import kotlin.test.assertFalse
5
+ import kotlin.test.assertTrue
4
6
 
5
7
  class AllergiesTest {
6
8
 
7
-
8
9
  @Test
9
10
  fun noAllergiesMeansNotAllergicToAnything() {
10
11
  val allergies = Allergies(0)
11
12
 
12
- assertEquals(false, allergies.isAllergicTo(Allergen.EGGS))
13
- assertEquals(false, allergies.isAllergicTo(Allergen.PEANUTS))
14
- assertEquals(false, allergies.isAllergicTo(Allergen.STRAWBERRIES))
15
- assertEquals(false, allergies.isAllergicTo(Allergen.CATS))
13
+ assertFalse(allergies.isAllergicTo(Allergen.PEANUTS))
14
+ assertFalse(allergies.isAllergicTo(Allergen.CATS))
15
+ assertFalse(allergies.isAllergicTo(Allergen.STRAWBERRIES))
16
16
  }
17
17
 
18
18
  @Ignore
@@ -20,71 +20,17 @@ class AllergiesTest {
20
20
  fun allergicToEggs() {
21
21
  val allergies = Allergies(1)
22
22
 
23
- assertEquals(true, allergies.isAllergicTo(Allergen.EGGS))
24
- }
25
-
26
- @Ignore
27
- @Test
28
- fun allergicToPeanuts() {
29
- val allergies = Allergies(2)
30
-
31
- assertEquals(true, allergies.isAllergicTo(Allergen.PEANUTS))
32
- }
33
-
34
- @Ignore
35
- @Test
36
- fun allergicToShellfish() {
37
- val allergies = Allergies(4)
38
-
39
- assertEquals(true, allergies.isAllergicTo(Allergen.SHELLFISH))
40
- }
41
-
42
- @Ignore
43
- @Test
44
- fun allergicToStrawberries() {
45
- val allergies = Allergies(8)
46
-
47
- assertEquals(true, allergies.isAllergicTo(Allergen.STRAWBERRIES))
23
+ assertTrue(allergies.isAllergicTo(Allergen.EGGS))
48
24
  }
49
25
 
50
26
  @Ignore
51
27
  @Test
52
- fun allergicToTomatoes() {
53
- val allergies = Allergies(16)
54
-
55
- assertEquals(true, allergies.isAllergicTo(Allergen.TOMATOES))
56
- }
57
-
58
- @Ignore
59
- @Test
60
- fun allergicToChocolate() {
61
- val allergies = Allergies(32)
62
-
63
- assertEquals(true, allergies.isAllergicTo(Allergen.CHOCOLATE))
64
- }
65
-
66
- @Ignore
67
- @Test
68
- fun allergicToPollen() {
69
- val allergies = Allergies(64)
70
-
71
- assertEquals(true, allergies.isAllergicTo(Allergen.POLLEN))
72
- }
73
-
74
- @Ignore
75
- @Test
76
- fun allergicToCats() {
77
- val allergies = Allergies(128)
78
-
79
- assertEquals(true, allergies.isAllergicTo(Allergen.CATS))
80
- }
81
-
82
- @Ignore
83
- @Test
84
- fun isAllergicToEggsInAdditionToOtherStuff() {
28
+ fun allergicToEggsAndOtherThings() {
85
29
  val allergies = Allergies(5)
86
30
 
87
- assertEquals(true, allergies.isAllergicTo(Allergen.EGGS))
31
+ assertTrue(allergies.isAllergicTo(Allergen.EGGS))
32
+ assertTrue(allergies.isAllergicTo(Allergen.SHELLFISH))
33
+ assertFalse(allergies.isAllergicTo(Allergen.STRAWBERRIES))
88
34
  }
89
35
 
90
36
  @Ignore
@@ -92,12 +38,12 @@ class AllergiesTest {
92
38
  fun noAllergies() {
93
39
  val allergies = Allergies(0)
94
40
 
95
- assertEquals(0, allergies.getList().size)
41
+ assertTrue(allergies.getList().isEmpty())
96
42
  }
97
43
 
98
44
  @Ignore
99
45
  @Test
100
- fun isAllergicToJustEggs() {
46
+ fun allergicToJustEggs() {
101
47
  val allergies = Allergies(1)
102
48
  val expectedAllergens = listOf(Allergen.EGGS)
103
49
 
@@ -106,7 +52,7 @@ class AllergiesTest {
106
52
 
107
53
  @Ignore
108
54
  @Test
109
- fun isAllergicToJustPeanuts() {
55
+ fun allergicToJustPeanuts() {
110
56
  val allergies = Allergies(2)
111
57
  val expectedAllergens = listOf(Allergen.PEANUTS)
112
58
 
@@ -115,7 +61,7 @@ class AllergiesTest {
115
61
 
116
62
  @Ignore
117
63
  @Test
118
- fun isAllergicToJustStrawberries() {
64
+ fun allergicToJustStrawberries() {
119
65
  val allergies = Allergies(8)
120
66
  val expectedAllergens = listOf(Allergen.STRAWBERRIES)
121
67
 
@@ -124,7 +70,7 @@ class AllergiesTest {
124
70
 
125
71
  @Ignore
126
72
  @Test
127
- fun isAllergicToEggsAndPeanuts() {
73
+ fun allergicToEggsAndPeanuts() {
128
74
  val allergies = Allergies(3)
129
75
  val expectedAllergens = listOf(
130
76
  Allergen.EGGS,
@@ -136,7 +82,7 @@ class AllergiesTest {
136
82
 
137
83
  @Ignore
138
84
  @Test
139
- fun isAllergicToEggsAndShellfish() {
85
+ fun allergicToEggsAndShellfish() {
140
86
  val allergies = Allergies(5)
141
87
  val expectedAllergens = listOf(
142
88
  Allergen.EGGS,
@@ -148,7 +94,7 @@ class AllergiesTest {
148
94
 
149
95
  @Ignore
150
96
  @Test
151
- fun isAllergicToLotsOfStuff() {
97
+ fun allergicToLotsOfStuff() {
152
98
  val allergies = Allergies(248)
153
99
  val expectedAllergens = listOf(
154
100
  Allergen.STRAWBERRIES,
@@ -163,7 +109,7 @@ class AllergiesTest {
163
109
 
164
110
  @Ignore
165
111
  @Test
166
- fun isAllergicToEverything() {
112
+ fun allergicToEverything() {
167
113
  val allergies = Allergies(255)
168
114
  val expectedAllergens = listOf(
169
115
  Allergen.EGGS,
@@ -195,4 +141,5 @@ class AllergiesTest {
195
141
 
196
142
  assertEquals(expectedAllergens, allergies.getList())
197
143
  }
144
+
198
145
  }
@@ -1,8 +1,11 @@
1
- class Anagram(val word: String) {
1
+ class Anagram(private val word: String) {
2
+
2
3
  fun match(anagrams: Collection<String>) =
3
- anagrams.filter({ doesMatch(it) }).filterNot({ it.equals(word, ignoreCase = true) })
4
+ anagrams.filter { containSameChars(it.toLowerCase()) }
5
+ .filterNot { it.equals(word, ignoreCase = true) }
6
+ .toSet()
4
7
 
5
- private fun doesMatch(anagram: String) =
6
- anagram.toLowerCase().toCharArray().sorted() == word.toLowerCase().toCharArray().sorted()
8
+ private fun containSameChars(candidate: String) =
9
+ candidate.toLowerCase().toCharArray().sorted() == word.toLowerCase().toCharArray().sorted()
7
10
 
8
11
  }
@@ -4,81 +4,128 @@ import kotlin.test.assertEquals
4
4
 
5
5
  class AnagramTest {
6
6
 
7
-
8
7
  @Test
9
8
  fun noMatches() {
10
9
  val detector = Anagram("diaper")
11
- assertEquals(listOf(), detector.match(listOf("hello", "world", "zombies", "pants")))
10
+ assertEquals(emptySet(), detector.match(listOf("hello", "world", "zombies", "pants")))
12
11
  }
13
12
 
14
13
  @Ignore
15
14
  @Test
16
- fun simpleAnagram() {
15
+ fun detectsSimpleAnagram() {
17
16
  val detector = Anagram("ant")
18
17
  val anagram = detector.match(listOf("tan", "stand", "at"))
19
- assertEquals(listOf("tan"), anagram)
18
+ assertEquals(setOf("tan"), anagram)
19
+ }
20
+
21
+ @Ignore
22
+ @Test
23
+ fun doesNotDetectFalsePositives() {
24
+ val detector = Anagram("galea")
25
+ val anagrams = detector.match(listOf("eagle"))
26
+ assertEquals(emptySet(), anagrams)
20
27
  }
21
28
 
22
29
  @Ignore
23
30
  @Test
24
- fun detectMultipleAnagrams() {
31
+ fun detectsTwoAnagrams() {
25
32
  val detector = Anagram("master")
26
33
  val anagrams = detector.match(listOf("stream", "pigeon", "maters"))
27
- assertEquals(listOf("maters", "stream"), anagrams.sorted())
34
+ assertEquals(setOf("maters", "stream"), anagrams)
28
35
  }
29
36
 
30
37
  @Ignore
31
38
  @Test
32
- fun doesNotConfuseDifferentDuplicates() {
33
- val detector = Anagram("galea")
34
- val anagrams = detector.match(listOf("eagle"))
35
- assertEquals(listOf(), anagrams)
39
+ fun doesNotDetectAnagramSubsets() {
40
+ val detector = Anagram("good")
41
+ assertEquals(emptySet(), detector.match(listOf("dog", "goody")))
36
42
  }
37
43
 
38
44
  @Ignore
39
45
  @Test
40
- fun identicalWordIsNotAnagram() {
46
+ fun detectsLongerAnagram() {
47
+ val detector = Anagram("listen")
48
+ val anagrams = detector.match(listOf("enlists", "google", "inlets", "banana"))
49
+ assertEquals(setOf("inlets"), anagrams)
50
+ }
51
+
52
+ @Ignore
53
+ @Test
54
+ fun detectsThreeAnagrams() {
55
+ val detector = Anagram("allergy")
56
+ val anagrams = detector.match(listOf("gallery", "ballerina", "regally", "clergy", "largely", "leading"))
57
+ assertEquals(setOf("gallery", "largely", "regally"), anagrams)
58
+ }
59
+
60
+ @Ignore
61
+ @Test
62
+ fun doesNotDetectIdenticalWordAsAnagram() {
41
63
  val detector = Anagram("corn")
42
64
  val anagrams = detector.match(listOf("corn", "dark", "Corn", "rank", "CORN", "cron", "park"))
43
- assertEquals(listOf("cron"), anagrams)
65
+ assertEquals(setOf("cron"), anagrams)
44
66
  }
45
67
 
46
68
  @Ignore
47
69
  @Test
48
- fun eliminateAnagramsWithSameChecksum() {
70
+ fun doesNotDetectNonAnagramsWithIdenticalChecksums() {
49
71
  val detector = Anagram("mass")
50
- assertEquals(listOf(), detector.match(listOf("last")))
72
+ assertEquals(emptySet(), detector.match(listOf("last")))
51
73
  }
52
74
 
53
75
  @Ignore
54
76
  @Test
55
- fun eliminateAnagramSubsets() {
56
- val detector = Anagram("good")
57
- assertEquals(listOf(), detector.match(listOf("dog", "goody")))
77
+ fun detectsAnagramsCaseInsensitively() {
78
+ val detector = Anagram("Orchestra")
79
+ val anagrams = detector.match(listOf("cashregister", "Carthorse", "radishes"))
80
+ assertEquals(setOf("Carthorse"), anagrams)
58
81
  }
59
82
 
60
83
  @Ignore
61
84
  @Test
62
- fun detectAnagrams() {
63
- val detector = Anagram("listen")
64
- val anagrams = detector.match(listOf("enlists", "google", "inlets", "banana"))
65
- assertEquals(listOf("inlets"), anagrams)
85
+ fun detectsAnagramsUsingCaseInsensitiveSubject() {
86
+ val detector = Anagram("Orchestra")
87
+ val anagrams = detector.match(listOf("cashregister", "carthorse", "radishes"))
88
+ assertEquals(setOf("carthorse"), anagrams)
66
89
  }
67
90
 
68
91
  @Ignore
69
92
  @Test
70
- fun multipleAnagrams() {
71
- val detector = Anagram("allergy")
72
- val anagrams = detector.match(listOf("gallery", "ballerina", "regally", "clergy", "largely", "leading"))
73
- assertEquals(listOf("gallery", "largely", "regally"), anagrams.sorted())
93
+ fun detectsAnagramsUsingCaseInsensitiveCandidates() {
94
+ val detector = Anagram("orchestra")
95
+ val anagrams = detector.match(listOf("cashregister", "Carthorse", "radishes"))
96
+ assertEquals(setOf("Carthorse"), anagrams)
74
97
  }
75
98
 
76
99
  @Ignore
77
100
  @Test
78
- fun anagramsAreCaseInsensitive() {
79
- val detector = Anagram("Orchestra")
80
- val anagrams = detector.match(listOf("cashregister", "Carthorse", "radishes"))
81
- assertEquals(listOf("Carthorse"), anagrams)
101
+ fun doesNotDetectIdenticalWordWithMixedCasingAsAnagram() {
102
+ val detector = Anagram("banana")
103
+ val anagrams = detector.match(listOf("Banana"))
104
+ assertEquals(emptySet(), anagrams)
105
+ }
106
+
107
+ @Ignore
108
+ @Test
109
+ fun doesNotDetectAnAnagramIfTheOriginalWordIsRepeated() {
110
+ val detector = Anagram("go")
111
+ val anagrams = detector.match(listOf("go Go GO"))
112
+ assertEquals(emptySet(), anagrams)
113
+ }
114
+
115
+ @Ignore
116
+ @Test
117
+ fun anagramsMustUseAllLettersExactlyOnce() {
118
+ val detector = Anagram("tapper")
119
+ val anagrams = detector.match(listOf("patter"))
120
+ assertEquals(emptySet(), anagrams)
121
+ }
122
+
123
+ @Ignore
124
+ @Test
125
+ fun doesNotDetectIdenticalUppercasedWordAsAnagram() {
126
+ val detector = Anagram("BANANA")
127
+ val anagrams = detector.match(listOf("Banana"))
128
+ assertEquals(emptySet(), anagrams)
82
129
  }
83
130
 
84
131
  }