trackler 2.2.1.52 → 2.2.1.53
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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/leap/canonical-data.json +2 -2
- data/tracks/cfml/tasks/FormatConfig.cfc +6 -4
- data/tracks/cfml/tasks/GenerateReadme.cfc +197 -0
- data/tracks/cfml/tasks/ScaffoldExercise.cfc +6 -0
- data/tracks/csharp/config.json +1 -1
- data/tracks/delphi/exercises/leap/uLeapTests.pas +1 -1
- data/tracks/fsharp/exercises/clock/Clock.fs +1 -1
- data/tracks/fsharp/exercises/clock/ClockTest.fs +239 -61
- data/tracks/fsharp/exercises/clock/Example.fs +3 -3
- data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +29 -26
- data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +30 -15
- data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
- data/tracks/fsharp/exercises/rectangles/Example.fs +1 -1
- data/tracks/fsharp/exercises/rectangles/Rectangles.fs +1 -1
- data/tracks/fsharp/exercises/rectangles/RectanglesTest.fs +66 -43
- data/tracks/fsharp/generators/Generators.fs +85 -1
- data/tracks/java/scripts/canonical_data_check.sh +8 -0
- data/tracks/kotlin/.gitignore +1 -0
- data/tracks/kotlin/exercises/acronym/.meta/version +1 -0
- data/tracks/kotlin/exercises/acronym/src/test/kotlin/AcronymTest.kt +9 -10
- data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -1
- data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +20 -20
- data/tracks/kotlin/exercises/allergies/.meta/version +1 -0
- data/tracks/kotlin/exercises/allergies/src/test/kotlin/AllergiesTest.kt +19 -72
- data/tracks/kotlin/exercises/anagram/.meta/src/reference/kotlin/Anagram.kt +7 -4
- data/tracks/kotlin/exercises/anagram/.meta/version +1 -0
- data/tracks/kotlin/exercises/anagram/src/test/kotlin/AnagramTest.kt +76 -29
- data/tracks/kotlin/exercises/atbash-cipher/.meta/version +1 -0
- data/tracks/kotlin/exercises/atbash-cipher/src/test/kotlin/AtbashTest.kt +6 -3
- data/tracks/kotlin/exercises/beer-song/.meta/version +1 -0
- data/tracks/kotlin/exercises/beer-song/src/test/kotlin/BeerSongTest.kt +21 -46
- data/tracks/kotlin/exercises/binary-search/.meta/version +1 -0
- data/tracks/kotlin/exercises/binary-search/src/test/kotlin/BinarySearchTest.kt +30 -19
- data/tracks/kotlin/exercises/bob/.meta/src/reference/kotlin/Bob.kt +8 -7
- data/tracks/kotlin/exercises/bob/.meta/version +1 -0
- data/tracks/kotlin/exercises/bob/src/test/kotlin/BobTest.kt +57 -15
- data/tracks/kotlin/exercises/bracket-push/.meta/version +1 -0
- data/tracks/kotlin/exercises/bracket-push/src/test/kotlin/BracketPushTest.kt +3 -1
- data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -1
- data/tracks/kotlin/exercises/difference-of-squares/.meta/version +1 -0
- data/tracks/kotlin/exercises/difference-of-squares/src/test/kotlin/SquaresTest.kt +10 -23
- data/tracks/kotlin/exercises/etl/.meta/src/reference/kotlin/ETL.kt +7 -1
- data/tracks/kotlin/exercises/etl/.meta/version +1 -0
- data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +10 -10
- data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -0
- data/tracks/kotlin/exercises/flatten-array/src/test/kotlin/FlattenerTest.kt +8 -16
- data/tracks/kotlin/exercises/gigasecond/.meta/version +1 -0
- data/tracks/kotlin/exercises/gigasecond/src/test/kotlin/GigasecondTest.kt +1 -1
- data/tracks/kotlin/exercises/hamming/.meta/src/reference/kotlin/Hamming.kt +1 -1
- data/tracks/kotlin/exercises/hamming/.meta/version +1 -1
- data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +4 -4
- data/tracks/kotlin/exercises/hello-world/.meta/version +1 -0
- data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +1 -1
- data/tracks/kotlin/exercises/isogram/.meta/version +1 -0
- data/tracks/kotlin/exercises/isogram/src/test/kotlin/IsogramTest.kt +5 -8
- data/tracks/kotlin/exercises/largest-series-product/.meta/src/reference/kotlin/Series.kt +2 -3
- data/tracks/kotlin/exercises/largest-series-product/.meta/version +1 -0
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesTest.kt +97 -0
- data/tracks/kotlin/exercises/leap/.meta/version +1 -0
- data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +8 -26
- data/tracks/kotlin/exercises/list-ops/.meta/version +1 -1
- data/tracks/kotlin/exercises/luhn/.meta/version +1 -0
- data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +0 -3
- data/tracks/kotlin/exercises/nth-prime/.meta/version +1 -0
- data/tracks/kotlin/exercises/nth-prime/src/test/kotlin/PrimeTest.kt +0 -2
- data/tracks/kotlin/exercises/nucleotide-count/.meta/src/reference/kotlin/{DNA.kt → Dna.kt} +3 -8
- data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -0
- data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/DnaTest.kt +48 -0
- data/tracks/kotlin/exercises/pangram/.meta/src/reference/kotlin/{Pangrams.kt → Pangram.kt} +1 -1
- data/tracks/kotlin/exercises/pangram/.meta/version +1 -1
- data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +15 -9
- data/tracks/kotlin/exercises/pascals-triangle/.meta/version +1 -0
- data/tracks/kotlin/exercises/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt +32 -14
- data/tracks/kotlin/exercises/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt +1 -1
- data/tracks/kotlin/exercises/perfect-numbers/.meta/version +1 -0
- data/tracks/kotlin/exercises/perfect-numbers/src/test/kotlin/{PerfectNumbersTest.kt → NaturalNumberTest.kt} +25 -7
- data/tracks/kotlin/exercises/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt +15 -7
- data/tracks/kotlin/exercises/phone-number/.meta/version +1 -0
- data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +46 -29
- data/tracks/kotlin/exercises/pig-latin/.meta/src/reference/kotlin/PigLatin.kt +2 -2
- data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -0
- data/tracks/kotlin/exercises/pig-latin/src/test/kotlin/PigLatinTest.kt +21 -10
- data/tracks/kotlin/exercises/raindrops/.meta/version +1 -0
- data/tracks/kotlin/exercises/raindrops/src/test/kotlin/RaindropsTest.kt +19 -26
- data/tracks/kotlin/exercises/react/.meta/version +1 -0
- data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +11 -4
- data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -1
- data/tracks/kotlin/exercises/roman-numerals/.meta/version +1 -0
- data/tracks/kotlin/exercises/roman-numerals/src/test/kotlin/RomanNumeralTest.kt +1 -2
- data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -1
- data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +7 -7
- data/tracks/kotlin/exercises/scrabble-score/.meta/src/reference/kotlin/{Scrabble.kt → ScrabbleScore.kt} +1 -1
- data/tracks/kotlin/exercises/scrabble-score/.meta/version +1 -0
- data/tracks/kotlin/exercises/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt +9 -7
- data/tracks/kotlin/exercises/sieve/.meta/version +1 -0
- data/tracks/kotlin/exercises/sieve/src/test/kotlin/SieveTest.kt +8 -0
- data/tracks/kotlin/exercises/space-age/.meta/version +1 -0
- data/tracks/kotlin/exercises/space-age/src/test/kotlin/SpaceAgeTest.kt +1 -16
- data/tracks/kotlin/exercises/sum-of-multiples/.meta/version +1 -0
- data/tracks/kotlin/exercises/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt +7 -7
- data/tracks/kotlin/exercises/triangle/.meta/version +1 -0
- data/tracks/kotlin/exercises/two-fer/.meta/version +1 -0
- data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +0 -1
- data/tracks/kotlin/exercises/word-count/.meta/src/reference/kotlin/WordCount.kt +6 -2
- data/tracks/kotlin/exercises/word-count/.meta/version +1 -0
- data/tracks/kotlin/exercises/word-count/src/test/kotlin/WordCountTest.kt +31 -9
- data/tracks/kotlin/scripts/canonical_data_check.sh +8 -0
- data/tracks/perl6/exercises/leap/leap.t +2 -2
- data/tracks/php/config.json +16 -0
- data/tracks/php/exercises/crypto-square/crypto-square_test.php +50 -0
- data/tracks/php/exercises/crypto-square/example.php +32 -0
- data/tracks/php/exercises/meetup/README.md +21 -0
- data/tracks/php/exercises/meetup/example.php +19 -0
- data/tracks/php/exercises/meetup/meetup_test.php +577 -0
- data/tracks/python/README.md +7 -5
- data/tracks/python/config.json +36 -27
- data/tracks/python/docs/TESTS.md +36 -12
- data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +1 -1
- data/tracks/python/exercises/diffie-hellman/.meta/hints.md +16 -0
- data/tracks/python/exercises/diffie-hellman/README.md +15 -2
- data/tracks/python/exercises/error-handling/README.md +23 -0
- data/tracks/python/exercises/error-handling/error_handling.py +14 -0
- data/tracks/python/exercises/error-handling/error_handling_test.py +66 -0
- data/tracks/python/exercises/error-handling/example.py +21 -0
- data/tracks/python/exercises/forth/forth_test.py +1 -1
- data/tracks/python/exercises/isogram/isogram_test.py +5 -3
- data/tracks/python/exercises/leap/leap_test.py +2 -2
- data/tracks/python/exercises/rotational-cipher/rotational_cipher_test.py +4 -4
- data/tracks/python/exercises/simple-cipher/.meta/hints.md +16 -0
- data/tracks/python/exercises/simple-cipher/README.md +17 -0
- data/tracks/python/exercises/sum-of-multiples/sum_of_multiples_test.py +4 -1
- data/tracks/python/exercises/twelve-days/example.py +3 -3
- data/tracks/python/exercises/twelve-days/twelve_days.py +2 -2
- metadata +53 -9
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesInvalidInputTest.kt +0 -30
- data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesValidInputTest.kt +0 -34
- data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/NucleotideTest.kt +0 -87
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.0
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dna(strand: String) {
|
|
2
|
+
|
|
2
3
|
init {
|
|
3
4
|
require(strand.matches(Regex("^[$nucleotides]*$")), { "DNA sequence contains invalid nucleotides sequence." })
|
|
4
5
|
}
|
|
5
6
|
|
|
6
|
-
companion object
|
|
7
|
+
companion object Dna {
|
|
7
8
|
val nucleotides = "ATCG"
|
|
8
9
|
val emptyNucleotideCounts = nucleotides.map { it to 0 }.toMap()
|
|
9
10
|
}
|
|
@@ -12,10 +13,4 @@ class DNA(strand: String) {
|
|
|
12
13
|
emptyNucleotideCounts + strand.groupBy { it }.mapValues { it.value.size }
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
fun count(nucleotide: Char): Int {
|
|
16
|
-
require(nucleotide in nucleotides, { "$nucleotide is not a nucleotide" })
|
|
17
|
-
|
|
18
|
-
return nucleotideCounts[nucleotide] ?: 0
|
|
19
|
-
}
|
|
20
16
|
}
|
|
21
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.0
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import org.junit.Test
|
|
2
|
+
import org.junit.Ignore
|
|
3
|
+
import kotlin.test.assertEquals
|
|
4
|
+
|
|
5
|
+
class DnaTest {
|
|
6
|
+
|
|
7
|
+
@Test
|
|
8
|
+
fun emptyDnaStringHasNoNucleotides() {
|
|
9
|
+
val dna = Dna("")
|
|
10
|
+
val expected = mapOf('A' to 0, 'C' to 0, 'G' to 0, 'T' to 0)
|
|
11
|
+
|
|
12
|
+
assertEquals(expected, dna.nucleotideCounts)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@Ignore
|
|
16
|
+
@Test
|
|
17
|
+
fun canCountOneNucleotideInSingleCharacterInput() {
|
|
18
|
+
val dna = Dna("G")
|
|
19
|
+
val expected = mapOf('A' to 0, 'C' to 0, 'G' to 1, 'T' to 0)
|
|
20
|
+
|
|
21
|
+
assertEquals(expected, dna.nucleotideCounts)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Ignore
|
|
25
|
+
@Test
|
|
26
|
+
fun canCountRepeatedNucleotide() {
|
|
27
|
+
val dna = Dna("GGGGGGG")
|
|
28
|
+
val expected = mapOf('A' to 0, 'C' to 0, 'G' to 7, 'T' to 0)
|
|
29
|
+
|
|
30
|
+
assertEquals(expected, dna.nucleotideCounts)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Ignore
|
|
34
|
+
@Test
|
|
35
|
+
fun canCountMultipleNucleotides() {
|
|
36
|
+
val dna = Dna("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC")
|
|
37
|
+
val expected = mapOf('A' to 20, 'C' to 12, 'G' to 17, 'T' to 21)
|
|
38
|
+
|
|
39
|
+
assertEquals(expected, dna.nucleotideCounts)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Ignore
|
|
43
|
+
@Test(expected = IllegalArgumentException::class)
|
|
44
|
+
fun validatesNucleotides() {
|
|
45
|
+
Dna("AGXXACT")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.3.0
|
|
@@ -7,55 +7,61 @@ class PangramTest {
|
|
|
7
7
|
|
|
8
8
|
@Test
|
|
9
9
|
fun emptySentence() {
|
|
10
|
-
assertFalse(
|
|
10
|
+
assertFalse(Pangram.isPangram(""))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@Ignore
|
|
14
|
+
@Test
|
|
15
|
+
fun perfectLowercasePangram() {
|
|
16
|
+
assertTrue(Pangram.isPangram("abcdefghijklmnopqrstuvwxyz"))
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
@Ignore
|
|
14
20
|
@Test
|
|
15
21
|
fun lowercasePangram() {
|
|
16
|
-
assertTrue(
|
|
22
|
+
assertTrue(Pangram.isPangram("the quick brown fox jumps over the lazy dog"))
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
@Ignore
|
|
20
26
|
@Test
|
|
21
27
|
fun missingCharacterX() {
|
|
22
|
-
assertFalse(
|
|
28
|
+
assertFalse(Pangram.isPangram("a quick movement of the enemy will jeopardize five gunboats"))
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
@Ignore
|
|
26
32
|
@Test
|
|
27
33
|
fun anotherMissingCharacterX() {
|
|
28
|
-
assertFalse(
|
|
34
|
+
assertFalse(Pangram.isPangram("five boxing wizards jump quickly at it"))
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
@Ignore
|
|
32
38
|
@Test
|
|
33
39
|
fun withUnderscores() {
|
|
34
|
-
assertTrue(
|
|
40
|
+
assertTrue(Pangram.isPangram("the_quick_brown_fox_jumps_over_the_lazy_dog"))
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
@Ignore
|
|
38
44
|
@Test
|
|
39
45
|
fun withNumbers() {
|
|
40
|
-
assertTrue(
|
|
46
|
+
assertTrue(Pangram.isPangram("the 1 quick brown fox jumps over the 2 lazy dogs"))
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
@Ignore
|
|
44
50
|
@Test
|
|
45
51
|
fun missingLettersReplacedByNumbers() {
|
|
46
|
-
assertFalse(
|
|
52
|
+
assertFalse(Pangram.isPangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog"))
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
@Ignore
|
|
50
56
|
@Test
|
|
51
57
|
fun mixedCaseAndPunctuation() {
|
|
52
|
-
assertTrue(
|
|
58
|
+
assertTrue(Pangram.isPangram("\"Five quacking Zephyrs jolt my wax bed.\""))
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
@Ignore
|
|
56
62
|
@Test
|
|
57
63
|
fun mixedCaseDuplicatedCharacters() {
|
|
58
|
-
assertFalse(
|
|
64
|
+
assertFalse(Pangram.isPangram("the quick brown fox jumps over with lazy FX"))
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.1.0
|
|
@@ -4,40 +4,57 @@ import kotlin.test.assertEquals
|
|
|
4
4
|
|
|
5
5
|
class PascalsTriangleTest {
|
|
6
6
|
|
|
7
|
+
@Test
|
|
8
|
+
fun zeroRows() {
|
|
9
|
+
val expectedOutput = emptyList<List<Int>>()
|
|
10
|
+
|
|
11
|
+
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(0))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@Ignore
|
|
15
|
+
@Test
|
|
16
|
+
fun oneRow() {
|
|
17
|
+
val expectedOutput = listOf(
|
|
18
|
+
listOf(1)
|
|
19
|
+
)
|
|
7
20
|
|
|
21
|
+
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(1))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Ignore
|
|
8
25
|
@Test
|
|
9
|
-
fun
|
|
26
|
+
fun twoRows() {
|
|
10
27
|
val expectedOutput = listOf(
|
|
11
28
|
listOf(1),
|
|
12
|
-
listOf(1, 1)
|
|
13
|
-
listOf(1, 2, 1),
|
|
14
|
-
listOf(1, 3, 3, 1)
|
|
29
|
+
listOf(1, 1)
|
|
15
30
|
)
|
|
16
31
|
|
|
17
|
-
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(
|
|
32
|
+
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(2))
|
|
18
33
|
}
|
|
19
34
|
|
|
20
35
|
@Ignore
|
|
21
36
|
@Test
|
|
22
|
-
fun
|
|
37
|
+
fun threeRows() {
|
|
23
38
|
val expectedOutput = listOf(
|
|
24
39
|
listOf(1),
|
|
25
40
|
listOf(1, 1),
|
|
26
|
-
listOf(1, 2, 1)
|
|
27
|
-
listOf(1, 3, 3, 1),
|
|
28
|
-
listOf(1, 4, 6, 4, 1),
|
|
29
|
-
listOf(1, 5, 10, 10, 5, 1)
|
|
41
|
+
listOf(1, 2, 1)
|
|
30
42
|
)
|
|
31
43
|
|
|
32
|
-
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(
|
|
44
|
+
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(3))
|
|
33
45
|
}
|
|
34
46
|
|
|
35
47
|
@Ignore
|
|
36
48
|
@Test
|
|
37
|
-
fun
|
|
38
|
-
val expectedOutput =
|
|
49
|
+
fun fourRows() {
|
|
50
|
+
val expectedOutput = listOf(
|
|
51
|
+
listOf(1),
|
|
52
|
+
listOf(1, 1),
|
|
53
|
+
listOf(1, 2, 1),
|
|
54
|
+
listOf(1, 3, 3, 1)
|
|
55
|
+
)
|
|
39
56
|
|
|
40
|
-
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(
|
|
57
|
+
assertEquals(expectedOutput, PascalsTriangle.computeTriangle(4))
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
@Ignore
|
|
@@ -45,4 +62,5 @@ class PascalsTriangleTest {
|
|
|
45
62
|
fun validatesNotNegativeRows() {
|
|
46
63
|
PascalsTriangle.computeTriangle(-1)
|
|
47
64
|
}
|
|
65
|
+
|
|
48
66
|
}
|
|
@@ -4,7 +4,7 @@ enum class Classification {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
fun classify(naturalNumber: Int): Classification {
|
|
7
|
-
require(naturalNumber
|
|
7
|
+
require(naturalNumber > 0, { "$naturalNumber is not a natural number" })
|
|
8
8
|
|
|
9
9
|
val aliquotSum = naturalNumber.aliquotSum()
|
|
10
10
|
return when {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.1
|
|
@@ -31,7 +31,7 @@ class NaturalNumberTest {
|
|
|
31
31
|
@Ignore
|
|
32
32
|
@Test
|
|
33
33
|
fun mediumAbundantNumberIsClassifiedCorrectly() {
|
|
34
|
-
assertEquals(Classification.ABUNDANT, classify(
|
|
34
|
+
assertEquals(Classification.ABUNDANT, classify(30))
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
@Ignore
|
|
@@ -42,14 +42,20 @@ class NaturalNumberTest {
|
|
|
42
42
|
|
|
43
43
|
@Ignore
|
|
44
44
|
@Test
|
|
45
|
-
fun
|
|
46
|
-
assertEquals(Classification.DEFICIENT, classify(
|
|
45
|
+
fun smallestPrimeDeficientNumberIsClassifiedCorrectly() {
|
|
46
|
+
assertEquals(Classification.DEFICIENT, classify(2))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Ignore
|
|
50
|
+
@Test
|
|
51
|
+
fun smallestNonPrimeDeficientNumberIsClassifiedCorrectly() {
|
|
52
|
+
assertEquals(Classification.DEFICIENT, classify(4))
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
@Ignore
|
|
50
56
|
@Test
|
|
51
57
|
fun mediumNumberIsClassifiedCorrectly() {
|
|
52
|
-
assertEquals(Classification.DEFICIENT, classify(
|
|
58
|
+
assertEquals(Classification.DEFICIENT, classify(32))
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
@Ignore
|
|
@@ -58,10 +64,22 @@ class NaturalNumberTest {
|
|
|
58
64
|
assertEquals(Classification.DEFICIENT, classify(33550337))
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
@Ignore
|
|
68
|
+
@Test
|
|
69
|
+
fun edgeCaseWithNoFactorsOtherThanItselfIsClassifiedCorrectly() {
|
|
70
|
+
assertEquals(Classification.DEFICIENT, classify(1))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Ignore
|
|
74
|
+
@Test(expected = RuntimeException::class)
|
|
75
|
+
fun zeroIsNotANaturalNumber() {
|
|
76
|
+
classify(0)
|
|
77
|
+
}
|
|
78
|
+
|
|
61
79
|
@Ignore
|
|
62
80
|
@Test(expected = RuntimeException::class)
|
|
63
|
-
fun
|
|
64
|
-
|
|
81
|
+
fun negativeNumberIsNotANaturalNumber() {
|
|
82
|
+
classify(-1)
|
|
65
83
|
}
|
|
66
84
|
|
|
67
|
-
}
|
|
85
|
+
}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
data class PhoneNumber(private val rawNumber: String) {
|
|
2
|
+
|
|
2
3
|
companion object {
|
|
3
|
-
private val
|
|
4
|
+
private val invalidChars = Regex("[^\\d() -.]")
|
|
5
|
+
private val digitsValidationRegex = Regex("^1?([2-9]\\d{2}[2-9]\\d{6})$")
|
|
4
6
|
}
|
|
5
|
-
private val cleanedNumber = rawNumber.replace(Regex("[^\\d]"), "")
|
|
6
7
|
|
|
7
|
-
val number
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
val number: String?
|
|
9
|
+
|
|
10
|
+
init {
|
|
11
|
+
val containsInvalidChar = invalidChars.containsMatchIn(rawNumber)
|
|
12
|
+
|
|
13
|
+
if (containsInvalidChar) {
|
|
14
|
+
number = null
|
|
15
|
+
} else {
|
|
16
|
+
val digits = rawNumber.replace(Regex("[^\\d]"), "")
|
|
17
|
+
number = digitsValidationRegex.matchEntire(digits)?.groupValues?.last()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
11
20
|
|
|
12
|
-
override fun toString() = "($areaCode) $exchangeCode-$subscriberNumber"
|
|
13
21
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.0
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import org.junit.Test
|
|
2
1
|
import org.junit.Ignore
|
|
2
|
+
import org.junit.Test
|
|
3
3
|
import kotlin.test.assertEquals
|
|
4
|
-
import kotlin.test.
|
|
4
|
+
import kotlin.test.assertNull
|
|
5
5
|
|
|
6
6
|
class PhoneNumberTest {
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
@Test
|
|
10
9
|
fun cleansNumber() {
|
|
11
10
|
val expectedNumber = "2234567890"
|
|
@@ -25,62 +24,80 @@ class PhoneNumberTest {
|
|
|
25
24
|
|
|
26
25
|
@Ignore
|
|
27
26
|
@Test
|
|
28
|
-
fun
|
|
27
|
+
fun cleansNumberWithMultipleSpaces() {
|
|
29
28
|
val expectedNumber = "2234567890"
|
|
30
|
-
val actualNumber = PhoneNumber("
|
|
29
|
+
val actualNumber = PhoneNumber("223 456 7890 ").number
|
|
31
30
|
|
|
32
31
|
assertEquals(expectedNumber, actualNumber)
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
@Ignore
|
|
36
|
-
@Test
|
|
37
|
-
fun
|
|
38
|
-
|
|
35
|
+
@Test
|
|
36
|
+
fun invalidWhen9Digits() {
|
|
37
|
+
assertNull(PhoneNumber("123456789").number)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Ignore
|
|
41
|
+
@Test
|
|
42
|
+
fun invalidWhen11DigitsAndFirstIsNot1() {
|
|
43
|
+
assertNull(PhoneNumber("22234567890").number)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Ignore
|
|
47
|
+
@Test
|
|
48
|
+
fun validWhen11DigitsAndFirstIs1() {
|
|
49
|
+
val expectedNumber = "2234567890"
|
|
50
|
+
val actualNumber = PhoneNumber("12234567890").number
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
assertEquals(expectedNumber, actualNumber)
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
@Ignore
|
|
44
|
-
@Test
|
|
45
|
-
fun
|
|
46
|
-
val
|
|
56
|
+
@Test
|
|
57
|
+
fun validWhen11DigitsAndFirstIs1WithPunctuation() {
|
|
58
|
+
val expectedNumber = "2234567890"
|
|
59
|
+
val actualNumber = PhoneNumber("+1 (223) 456-7890").number
|
|
47
60
|
|
|
48
|
-
|
|
61
|
+
assertEquals(expectedNumber, actualNumber)
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
@Ignore
|
|
52
|
-
@Test
|
|
53
|
-
fun
|
|
54
|
-
val
|
|
65
|
+
@Test
|
|
66
|
+
fun invalidWhenMoreThan11Digits() {
|
|
67
|
+
val expectedNumber = null
|
|
68
|
+
val actualNumber = PhoneNumber("321234567890").number
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
assertEquals(expectedNumber, actualNumber)
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
@Ignore
|
|
60
74
|
@Test
|
|
61
|
-
fun
|
|
62
|
-
val
|
|
63
|
-
val
|
|
75
|
+
fun invalidWithLetters() {
|
|
76
|
+
val expectedNumber = null
|
|
77
|
+
val actualNumber = PhoneNumber("123-abc-7890").number
|
|
64
78
|
|
|
65
|
-
assertEquals(
|
|
79
|
+
assertEquals(expectedNumber, actualNumber)
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
@Ignore
|
|
69
83
|
@Test
|
|
70
|
-
fun
|
|
71
|
-
val
|
|
72
|
-
val
|
|
84
|
+
fun invalidWithInvalidPunctuation() {
|
|
85
|
+
val expectedNumber = null
|
|
86
|
+
val actualNumber = PhoneNumber("123-@:!-7890").number
|
|
73
87
|
|
|
74
|
-
assertEquals(
|
|
88
|
+
assertEquals(expectedNumber, actualNumber)
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
@Ignore
|
|
78
92
|
@Test
|
|
79
|
-
fun
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
fun invalidWhenAreaCodeStartsWith0or1() {
|
|
94
|
+
assertNull(PhoneNumber("(123) 456-7890").number)
|
|
95
|
+
}
|
|
82
96
|
|
|
83
|
-
|
|
97
|
+
@Ignore
|
|
98
|
+
@Test
|
|
99
|
+
fun invalidWhenExchangeCodeStartsWith0or1() {
|
|
100
|
+
assertNull(PhoneNumber("(223) 056-7890").number)
|
|
84
101
|
}
|
|
85
102
|
|
|
86
103
|
}
|