trackler 2.0.6.40 → 2.0.6.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/exercises/book-store/canonical-data.json +7 -1
- data/common/exercises/rotational-cipher/{cannonical-data.json → canonical-data.json} +0 -0
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +9 -0
- data/tracks/c/exercises/triangle/makefile +16 -0
- data/tracks/c/exercises/triangle/src/example.c +33 -0
- data/tracks/c/exercises/triangle/src/example.h +15 -0
- data/tracks/c/exercises/triangle/src/triangle.h +10 -0
- data/tracks/c/exercises/triangle/test/test_triangle.c +121 -0
- data/tracks/c/exercises/triangle/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/triangle/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/triangle/test/vendor/unity_internals.h +701 -0
- data/tracks/clojure/.gitignore +1 -0
- data/tracks/clojure/_src/clock_generator.clj +5 -0
- data/tracks/clojure/_src/generator.clj +72 -0
- data/tracks/clojure/config.json +6 -0
- data/tracks/clojure/exercises/clock/clock.mustache +34 -0
- data/tracks/clojure/exercises/clock/project.clj +4 -0
- data/tracks/clojure/exercises/clock/src/example.clj +19 -0
- data/tracks/clojure/exercises/clock/test/clock_test.clj +177 -0
- data/tracks/clojure/project.clj +4 -1
- data/tracks/csharp/exercises/poker/Example.cs +1 -1
- data/tracks/csharp/exercises/poker/PokerTest.cs +10 -0
- data/tracks/erlang/docs/INSTALLATION.md +14 -3
- data/tracks/erlang/docs/LEARNING.md +1 -0
- data/tracks/go/exercises/gigasecond/gigasecond_test.go +5 -2
- data/tracks/go/exercises/grade-school/example.go +2 -0
- data/tracks/go/exercises/grade-school/grade_school_test.go +8 -0
- data/tracks/go/exercises/hamming/hamming_test.go +1 -1
- data/tracks/go/exercises/hello-world/hello_test.go +6 -4
- data/tracks/haskell/exercises/accumulate/src/Accumulate.hs +1 -1
- data/tracks/haskell/exercises/anagram/src/Anagram.hs +1 -1
- data/tracks/java/bin/journey-test.sh +21 -4
- data/tracks/java/exercises/allergies/src/example/java/Allergen.java +20 -0
- data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +10 -3
- data/tracks/java/exercises/luhn/src/example/java/LuhnValidator.java +19 -11
- data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +43 -1
- data/tracks/java/exercises/meetup/src/example/java/MeetupSchedule.java +8 -0
- data/tracks/java/exercises/meetup/src/test/java/MeetupTest.java +91 -91
- data/tracks/java/exercises/perfect-numbers/src/example/java/Classification.java +5 -0
- data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +29 -0
- data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +5 -0
- data/tracks/java/exercises/secret-handshake/src/example/java/Signal.java +5 -0
- data/tracks/java/exercises/sublist/src/example/java/Relationship.java +5 -0
- data/tracks/java/exercises/triangle/src/example/java/TriangleException.java +5 -0
- data/tracks/java/exercises/triangle/src/example/java/TriangleKind.java +5 -0
- data/tracks/julia/config.json +10 -1
- data/tracks/julia/exercises/atbash-cipher/runtests.jl +36 -36
- data/tracks/julia/exercises/pangram/example.jl +2 -0
- data/tracks/julia/exercises/pangram/pangram.jl +4 -0
- data/tracks/julia/exercises/pangram/runtests.jl +40 -0
- data/tracks/perl5/exercises/bob/Example.pm +1 -1
- data/tracks/perl5/exercises/bob/bob.t +27 -31
- data/tracks/php/exercises/accumulate/accumulate_test.php +1 -1
- data/tracks/php/exercises/acronym/acronym_test.php +1 -1
- data/tracks/php/exercises/allergies/allergies_test.php +1 -1
- data/tracks/php/exercises/anagram/anagram_test.php +1 -1
- data/tracks/php/exercises/atbash-cipher/atbash-cipher_test.php +1 -1
- data/tracks/php/exercises/beer-song/beer-song_test.php +1 -1
- data/tracks/php/exercises/binary/binary_test.php +2 -2
- data/tracks/php/exercises/bob/bob_test.php +1 -1
- data/tracks/php/exercises/book-store/book-store_test.php +1 -1
- data/tracks/php/exercises/bowling/bowling_test.php +1 -1
- data/tracks/php/exercises/bracket-push/bracket-push_test.php +1 -1
- data/tracks/php/exercises/change/change_test.php +3 -3
- data/tracks/php/exercises/clock/clock_test.php +1 -1
- data/tracks/php/exercises/connect/connect_test.php +1 -1
- data/tracks/php/exercises/difference-of-squares/difference-of-squares_test.php +1 -1
- data/tracks/php/exercises/etl/etl_test.php +1 -1
- data/tracks/php/exercises/gigasecond/gigasecond_test.php +1 -1
- data/tracks/php/exercises/grains/grains_test.php +1 -1
- data/tracks/php/exercises/hamming/hamming_test.php +2 -2
- data/tracks/php/exercises/hello-world/hello-world_test.php +1 -1
- data/tracks/php/exercises/isogram/isogram_test.php +1 -1
- data/tracks/php/exercises/largest-series-product/largest-series-product_test.php +1 -1
- data/tracks/php/exercises/leap/leap_test.php +1 -1
- data/tracks/php/exercises/markdown/markdown_test.php +1 -1
- data/tracks/php/exercises/minesweeper/minesweeper_test.php +7 -7
- data/tracks/php/exercises/nucleotide-count/nucleotide-count_test.php +1 -1
- data/tracks/php/exercises/ocr-numbers/ocr-numbers_test.php +1 -1
- data/tracks/php/exercises/pangram/pangram_test.php +1 -1
- data/tracks/php/exercises/phone-number/phone-number_test.php +1 -1
- data/tracks/php/exercises/pig-latin/pig-latin_test.php +1 -1
- data/tracks/php/exercises/raindrops/raindrops_test.php +1 -1
- data/tracks/php/exercises/rna-transcription/rna-transcription_test.php +1 -1
- data/tracks/php/exercises/robot-name/robot-name_test.php +1 -1
- data/tracks/php/exercises/robot-simulator/robot-simulator_test.php +1 -1
- data/tracks/php/exercises/roman-numerals/roman-numerals_test.php +1 -1
- data/tracks/php/exercises/sieve/sieve_test.php +1 -1
- data/tracks/php/exercises/space-age/space-age_test.php +1 -1
- data/tracks/php/exercises/triangle/triangle_test.php +1 -1
- data/tracks/php/exercises/trinary/trinary_test.php +1 -1
- data/tracks/php/exercises/variable-length-quantity/variable-length-quantity_test.php +3 -3
- data/tracks/php/exercises/word-count/word-count_test.php +1 -1
- data/tracks/php/exercises/wordy/wordy_test.php +3 -3
- data/tracks/python/config.json +3 -13
- data/tracks/python/exercises/rectangles/rectangles_count_test.py +15 -22
- data/tracks/scala/config.json +684 -665
- data/tracks/scala/exercises/binary-search/build.sbt +3 -0
- data/tracks/scala/exercises/binary-search/example.scala +23 -0
- data/tracks/scala/exercises/binary-search/src/main/scala/BinarySearch.scala +0 -0
- data/tracks/scala/exercises/binary-search/src/test/scala/BinarySearchTest.scala +63 -0
- data/tracks/scala/exercises/strain/build.sbt +3 -0
- data/tracks/scala/exercises/strain/example.scala +22 -0
- data/tracks/scala/exercises/strain/src/main/scala/Strain.scala +0 -0
- data/tracks/scala/exercises/strain/src/test/scala/StrainTest.scala +78 -0
- data/tracks/scala/testgen/src/main/scala/AllYourBaseTestGenerator.scala +13 -20
- data/tracks/scala/testgen/src/main/scala/BinarySearchTestGenerator.scala +48 -0
- data/tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala +24 -32
- data/tracks/scala/testgen/src/main/scala/CustomSetTestGenerator.scala +148 -112
- data/tracks/scala/testgen/src/main/scala/TestBuilder.scala +86 -0
- metadata +30 -3
- data/tracks/java/exercises/allergies/src/example/java/Allergen.java +0 -1
- data/tracks/java/exercises/meetup/src/example/java/MeetupSchedule.java +0 -1
- data/tracks/java/exercises/perfect-numbers/src/example/java/Classification.java +0 -1
- data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +0 -1
- data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +0 -1
- data/tracks/java/exercises/secret-handshake/src/example/java/Signal.java +0 -1
- data/tracks/java/exercises/sublist/src/example/java/Relationship.java +0 -1
- data/tracks/java/exercises/triangle/src/example/java/TriangleException.java +0 -1
- data/tracks/java/exercises/triangle/src/example/java/TriangleKind.java +0 -1
@@ -0,0 +1,23 @@
|
|
1
|
+
import scala.annotation.tailrec
|
2
|
+
|
3
|
+
object BinarySearch {
|
4
|
+
def search[T](seq: Seq[T], value: T)(implicit ord: T => Ordered[T]): Option[Int]
|
5
|
+
= searchInternal(seq, value, 0, seq.size - 1)
|
6
|
+
|
7
|
+
@tailrec
|
8
|
+
def searchInternal[T](seq: Seq[T], value: T,
|
9
|
+
start: Int, end: Int)(implicit ord: T => Ordered[T]): Option[Int] = {
|
10
|
+
if (end < start || start < 0)
|
11
|
+
None
|
12
|
+
else {
|
13
|
+
val middle = Math.floor(0.5 * (start + end)).asInstanceOf[Int]
|
14
|
+
val elem = seq(middle)
|
15
|
+
if (elem == value)
|
16
|
+
Some(middle)
|
17
|
+
else if (value < elem)
|
18
|
+
searchInternal(seq, value, start, middle - 1)
|
19
|
+
else
|
20
|
+
searchInternal(seq, value, middle + 1, end)
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import org.scalatest.{FunSuite, Matchers}
|
2
|
+
|
3
|
+
class BinarySearchTest extends FunSuite with Matchers {
|
4
|
+
|
5
|
+
test("finds a value in an array with one element") {
|
6
|
+
val result = BinarySearch.search(Array(6), 6)
|
7
|
+
result should be (Some(0))
|
8
|
+
}
|
9
|
+
|
10
|
+
test("finds a value in the middle of an array") {
|
11
|
+
pending
|
12
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 6)
|
13
|
+
result should be (Some(3))
|
14
|
+
}
|
15
|
+
|
16
|
+
test("finds a value at the beginning of an array") {
|
17
|
+
pending
|
18
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 1)
|
19
|
+
result should be (Some(0))
|
20
|
+
}
|
21
|
+
|
22
|
+
test("finds a value at the end of an array") {
|
23
|
+
pending
|
24
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 11)
|
25
|
+
result should be (Some(6))
|
26
|
+
}
|
27
|
+
|
28
|
+
test("finds a value in an array of odd length") {
|
29
|
+
pending
|
30
|
+
val result = BinarySearch.search(Array(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634), 144)
|
31
|
+
result should be (Some(9))
|
32
|
+
}
|
33
|
+
|
34
|
+
test("finds a value in an array of even length") {
|
35
|
+
pending
|
36
|
+
val result = BinarySearch.search(Array(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377), 21)
|
37
|
+
result should be (Some(5))
|
38
|
+
}
|
39
|
+
|
40
|
+
test("identifies that a value is not included in the array") {
|
41
|
+
pending
|
42
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 7)
|
43
|
+
result should be (None)
|
44
|
+
}
|
45
|
+
|
46
|
+
test("a value smaller than the array's smallest value is not included") {
|
47
|
+
pending
|
48
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 0)
|
49
|
+
result should be (None)
|
50
|
+
}
|
51
|
+
|
52
|
+
test("a value larger than the array's largest value is not included") {
|
53
|
+
pending
|
54
|
+
val result = BinarySearch.search(Array(1, 3, 4, 6, 8, 9, 11), 13)
|
55
|
+
result should be (None)
|
56
|
+
}
|
57
|
+
|
58
|
+
test("nothing is included in an empty array") {
|
59
|
+
pending
|
60
|
+
val result = BinarySearch.search(Array[Int](), 1)
|
61
|
+
result should be (None)
|
62
|
+
}
|
63
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import scala.annotation.tailrec
|
2
|
+
|
3
|
+
object Strain {
|
4
|
+
def keep[A](seq: Seq[A], func: A => Boolean): Seq[A] =
|
5
|
+
recurse(seq, func, List()).reverse
|
6
|
+
|
7
|
+
def discard[A](seq: Seq[A], func: A => Boolean): Seq[A] = {
|
8
|
+
val notFunc: A => Boolean = a => !func(a)
|
9
|
+
recurse(seq, notFunc, List()).reverse
|
10
|
+
}
|
11
|
+
|
12
|
+
@tailrec
|
13
|
+
private def recurse[A](seq: Seq[A], func: A => Boolean, acc: Seq[A]): Seq[A] =
|
14
|
+
seq match {
|
15
|
+
case Nil => acc
|
16
|
+
case x::xs =>
|
17
|
+
if (func(x))
|
18
|
+
recurse(xs, func, x +: acc)
|
19
|
+
else
|
20
|
+
recurse(xs, func, acc)
|
21
|
+
}
|
22
|
+
}
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import org.scalatest.{Matchers, FlatSpec}
|
2
|
+
|
3
|
+
class StrainTest extends FlatSpec with Matchers {
|
4
|
+
|
5
|
+
it should "handle empty keep" in {
|
6
|
+
val result = Strain.keep[Int](List(), x => x < 10)
|
7
|
+
result should be(List.empty)
|
8
|
+
}
|
9
|
+
|
10
|
+
it should "keep everything" in {
|
11
|
+
pending
|
12
|
+
val expectedList = List("a", "b", "c")
|
13
|
+
val result = Strain.keep[String](expectedList, _ => true)
|
14
|
+
result should be(expectedList)
|
15
|
+
}
|
16
|
+
|
17
|
+
it should "keep first and last" in {
|
18
|
+
pending
|
19
|
+
val result = Strain.keep[Int](List(1, 2, 3), x => x % 2 != 0)
|
20
|
+
result should be(List(1, 3))
|
21
|
+
}
|
22
|
+
|
23
|
+
it should "keep neither first or last" in {
|
24
|
+
pending
|
25
|
+
val result = Strain.keep[Int](List(1, 2, 3, 4, 5), x => x % 2 == 0)
|
26
|
+
result should be(List(2, 4))
|
27
|
+
}
|
28
|
+
|
29
|
+
it should "keep strings" in {
|
30
|
+
pending
|
31
|
+
val words = List("apple", "zebra", "banana", "zombies", "cherimoya", "zelot")
|
32
|
+
val result = Strain.keep[String](words, s => s.startsWith("z"))
|
33
|
+
result should be(List("zebra", "zombies", "zelot"))
|
34
|
+
}
|
35
|
+
|
36
|
+
it should "keep sequences" in {
|
37
|
+
pending
|
38
|
+
val sequences = Seq(Seq(1, 2, 3), Seq(5, 5, 5), Seq(5, 1, 2), Seq(2, 1, 2),
|
39
|
+
Seq(1, 5, 2), Seq(2, 2, 1), Seq(1, 2, 5))
|
40
|
+
val expected = Seq(Seq(5, 5, 5), Seq(5, 1, 2), Seq(1, 5, 2), Seq(1, 2, 5))
|
41
|
+
val result = Strain.keep[Seq[Int]](sequences, seq => seq.contains(5))
|
42
|
+
result should be (expected)
|
43
|
+
}
|
44
|
+
|
45
|
+
it should "handle empty discard" in {
|
46
|
+
pending
|
47
|
+
val result = Strain.discard[Int](List(), x => x < 10)
|
48
|
+
result should be (List.empty)
|
49
|
+
}
|
50
|
+
|
51
|
+
it should "discard first and last" in {
|
52
|
+
pending
|
53
|
+
val result = Strain.discard[Int](List(1, 2, 3), x => x % 2 != 0)
|
54
|
+
result should be (List(2))
|
55
|
+
}
|
56
|
+
|
57
|
+
it should "discard neither first or last" in {
|
58
|
+
pending
|
59
|
+
val result = Strain.discard[Int](List(1, 2, 3, 4, 5), x => x % 2 == 0)
|
60
|
+
result should be (List(1, 3, 5))
|
61
|
+
}
|
62
|
+
|
63
|
+
it should "discard strings" in {
|
64
|
+
pending
|
65
|
+
val words = List("apple", "zebra", "banana", "zombies", "cherimoya", "zelot")
|
66
|
+
val result = Strain.discard[String](words, s => s.startsWith("z"))
|
67
|
+
result should be (List("apple", "banana", "cherimoya"))
|
68
|
+
}
|
69
|
+
|
70
|
+
it should "discard sequences" in {
|
71
|
+
pending
|
72
|
+
val sequences = Seq(Seq(1, 2, 3), Seq(5, 5, 5), Seq(5, 1, 2), Seq(2, 1, 2),
|
73
|
+
Seq(1, 5, 2), Seq(2, 2, 1), Seq(1, 2, 5))
|
74
|
+
val expected = Seq(Seq(1, 2, 3), Seq(2, 1, 2), Seq(2, 2, 1))
|
75
|
+
val result = Strain.discard[Seq[Int]](sequences, seq => seq.contains(5))
|
76
|
+
result should be (expected)
|
77
|
+
}
|
78
|
+
}
|
@@ -2,35 +2,28 @@ import play.api.libs.json.Json
|
|
2
2
|
|
3
3
|
import scala.io.Source
|
4
4
|
|
5
|
+
|
5
6
|
class AllYourBaseTestGenerator {
|
6
|
-
implicit val testCaseReader = Json.reads[
|
7
|
+
implicit val testCaseReader = Json.reads[AllYourBaseTestCase]
|
7
8
|
|
8
9
|
private val filename = "all-your-base.json"
|
9
10
|
private val fileContents = Source.fromFile(filename).getLines.mkString
|
10
11
|
private val json = Json.parse(fileContents)
|
11
12
|
|
12
13
|
def write {
|
13
|
-
|
14
|
-
print(System.lineSeparator())
|
15
|
-
print("class AllYourBaseTest extends FunSuite with Matchers {" + System.lineSeparator())
|
16
|
-
|
17
|
-
writeTestCases()
|
14
|
+
val testCases: List[AllYourBaseTestCase] = (json \ "cases").get.as[List[AllYourBaseTestCase]]
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
implicit def testCaseToGen(tc: AllYourBaseTestCase): TestCaseGen = {
|
17
|
+
val callSUT =
|
18
|
+
s"AllYourBase.rebase(${tc.input_base}, ${toListString(tc.input_digits)}, ${tc.output_base})"
|
19
|
+
val expected = toListString(tc.output_digits)
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
testCases.foreach(tc => {
|
26
|
-
print("\ttest(\"" + tc.description + "\") {" + System.lineSeparator())
|
27
|
-
println("pending")
|
28
|
-
println("AllYourBase.rebase(" + tc.input_base + ", " + toListString(tc.input_digits) +
|
29
|
-
"," + System.lineSeparator() + tc.output_base + ") should be (" + toListString(tc.output_digits) + ")")
|
21
|
+
TestCaseGen(tc.description, callSUT, expected)
|
22
|
+
}
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
val testBuilder = new TestBuilder("AllYourBaseTest")
|
25
|
+
testBuilder.addTestCases(testCases)
|
26
|
+
testBuilder.toFile
|
34
27
|
}
|
35
28
|
|
36
29
|
private def toListString(a: Array[Int]): String =
|
@@ -44,7 +37,7 @@ class AllYourBaseTestGenerator {
|
|
44
37
|
}
|
45
38
|
}
|
46
39
|
|
47
|
-
case class
|
40
|
+
case class AllYourBaseTestCase(description: String,
|
48
41
|
input_base: Int, input_digits: Array[Int],
|
49
42
|
output_base: Int, output_digits: Option[Array[Int]])
|
50
43
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import play.api.libs.json.Json
|
2
|
+
|
3
|
+
import scala.io.Source
|
4
|
+
|
5
|
+
class BinarySearchTestGenerator {
|
6
|
+
implicit val testCaseReader = Json.reads[BinarySearchTestCase]
|
7
|
+
|
8
|
+
private val filename = "binarysearch.json"
|
9
|
+
private val fileContents = Source.fromFile(filename).getLines.mkString
|
10
|
+
private val json = Json.parse(fileContents)
|
11
|
+
|
12
|
+
def write {
|
13
|
+
val testCases = (json \ "cases").get.as[List[BinarySearchTestCase]]
|
14
|
+
|
15
|
+
implicit def testCaseToGen(tc: BinarySearchTestCase): TestCaseGen = {
|
16
|
+
val elements = tc.array.map(elem => elem.toString).mkString(", ")
|
17
|
+
val elementStr =
|
18
|
+
if (elements.isEmpty)
|
19
|
+
"Array[Int]()"
|
20
|
+
else
|
21
|
+
s"Array(${elements})"
|
22
|
+
|
23
|
+
val callSUT =
|
24
|
+
s"BinarySearch.search(${elementStr}, ${tc.value})"
|
25
|
+
val expected =
|
26
|
+
if (tc.expected == -1)
|
27
|
+
"None"
|
28
|
+
else
|
29
|
+
s"Some(${tc.expected})"
|
30
|
+
|
31
|
+
TestCaseGen(tc.description, callSUT, expected)
|
32
|
+
}
|
33
|
+
|
34
|
+
val testBuilder = new TestBuilder("BinarySearchTest")
|
35
|
+
testBuilder.addTestCases(testCases)
|
36
|
+
testBuilder.toFile
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
case class BinarySearchTestCase(description: String,
|
41
|
+
array: Array[Int],
|
42
|
+
value: Int, expected: Int)
|
43
|
+
|
44
|
+
object BinarySearchTestGenerator {
|
45
|
+
def main(args: Array[String]): Unit = {
|
46
|
+
new BinarySearchTestGenerator().write
|
47
|
+
}
|
48
|
+
}
|
@@ -10,39 +10,31 @@ class BowlingTestGenerator {
|
|
10
10
|
private val json = Json.parse(fileContents)
|
11
11
|
|
12
12
|
def write {
|
13
|
-
print("import org.scalatest.{FunSuite, Matchers}" + System.lineSeparator())
|
14
|
-
print(System.lineSeparator())
|
15
|
-
print("class BowlingSuite extends FunSuite with Matchers {" + System.lineSeparator())
|
16
|
-
|
17
|
-
writeTestCases()
|
18
|
-
|
19
|
-
print("}" + System.lineSeparator())
|
20
|
-
}
|
21
|
-
|
22
|
-
private def writeTestCases(): Unit = {
|
23
|
-
println("// " + (json \ "score" \ "description").get.as[List[String]].mkString(" "))
|
24
|
-
|
25
13
|
val testCases = (json \ "score" \ "cases").get.as[List[BowlingTestCase]]
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
}
|
14
|
+
val description = (json \ "score" \ "description").get.as[List[String]].mkString(" ")
|
15
|
+
|
16
|
+
implicit def testCaseToGen(tc: BowlingTestCase): TestCaseGen = {
|
17
|
+
val callSUT =
|
18
|
+
s"${tc.rolls}.foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()"
|
19
|
+
val expected = ""
|
20
|
+
val result = s"val score = $callSUT"
|
21
|
+
val (matchRight, matchLeft) =
|
22
|
+
if (tc.expected == -1)
|
23
|
+
("""fail("Unexpected score returned. Failure expected")""", "")
|
24
|
+
else
|
25
|
+
(s"assert(n == ${tc.expected})", s"""fail("${tc.description}")""")
|
26
|
+
val checkResult =
|
27
|
+
s"""score match {
|
28
|
+
case Right(n) => $matchRight
|
29
|
+
case Left(_) => $matchLeft
|
30
|
+
}"""
|
31
|
+
|
32
|
+
TestCaseGen(tc.description, callSUT, expected, result, checkResult)
|
33
|
+
}
|
34
|
+
|
35
|
+
val testBuilder = new TestBuilder("BowlingTest")
|
36
|
+
testBuilder.addTestCases(testCases, Some(description))
|
37
|
+
testBuilder.toFile
|
46
38
|
}
|
47
39
|
}
|
48
40
|
|