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.
- 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
|
}
|