1
exercism fetch scala bowling

src/test/scala/BowlingSuite.scala

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import org.scalatest.{Matchers, FunSuite}

/** @version 1.0.1 */
class BowlingTest extends FunSuite with Matchers {

  test("should be able to score a game with all zeros") {
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(0))
  }

  test("should be able to score a game with no strikes or spares") {
    pending
    val score = List(3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(90))
  }

  test("a spare followed by zeros is worth ten points") {
    pending
    val score = List(6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(10))
  }

  test("points scored in the roll after a spare are counted twice") {
    pending
    val score = List(6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(16))
  }

  test("consecutive spares each get a one roll bonus") {
    pending
    val score = List(5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(31))
  }

  test("a spare in the last frame gets a one roll bonus that is counted once") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(17))
  }

  test("a strike earns ten points in a frame with a single roll") {
    pending
    val score = List(10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(10))
  }

  test("points scored in the two rolls after a strike are counted twice as a bonus") {
    pending
    val score = List(10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(26))
  }

  test("consecutive strikes each get the two roll bonus") {
    pending
    val score = List(10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(81))
  }

  test("a strike in the last frame gets a two roll bonus that is counted once") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(18))
  }

  test("rolling a spare with the two roll bonus does not get a bonus roll") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(20))
  }

  test("strikes with the two roll bonus do not get bonus rolls") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(30))
  }

  test("a strike with the one roll bonus after a spare in the last frame does not get a bonus") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(20))
  }

  test("all strikes is a perfect game") {
    pending
    val score = List(10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(300))
  }

  test("rolls cannot score negative points") {
    pending
    val score = List().foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(-1).score()
    score.isLeft should be (true)
  }

  test("a roll cannot score more than 10 points") {
    pending
    val score = List().foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(11).score()
    score.isLeft should be (true)
  }

  test("two rolls in a frame cannot score more than 10 points") {
    pending
    val score = List(5).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(6).score()
    score.isLeft should be (true)
  }

  test("bonus roll after a strike in the last frame cannot score more than 10 points") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(11).score()
    score.isLeft should be (true)
  }

  test("two bonus rolls after a strike in the last frame cannot score more than 10 points") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(6).score()
    score.isLeft should be (true)
  }

  test("two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score should be (Right(26))
  }

  test("the second bonus rolls after a strike in the last frame cannot be a strike if the first one is not a strike") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(10).score()
    score.isLeft should be (true)
  }

  test("second bonus roll after a strike in the last frame cannot score more than 10 points") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(11).score()
    score.isLeft should be (true)
  }

  test("an unstarted game cannot be scored") {
    pending
    val score = List().foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score.isLeft should be (true)
  }

  test("an incomplete game cannot be scored") {
    pending
    val score = List(0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score.isLeft should be (true)
  }

  test("cannot roll if game already has ten frames") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).roll(0).score()
    score.isLeft should be (true)
  }

  test("bonus rolls for a strike in the last frame must be rolled before score can be calculated") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score.isLeft should be (true)
  }

  test("both bonus rolls for a strike in the last frame must be rolled before score can be calculated") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score.isLeft should be (true)
  }

  test("bonus roll for a spare in the last frame must be rolled before score can be calculated") {
    pending
    val score = List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3).foldLeft(Bowling())((acc, roll) => acc.roll(roll)).score()
    score.isLeft should be (true)
  }
}