Skip to content

Commit 03ae9ec

Browse files
committed
Add tests for Bowling exercise
These tests basically follow the canonical tests, with some exceptions. Exceptions ------ I've changed the descriptions to try to clarify what condition/rule/logic each test is trying to cover. I've reordered the tests. The new order: - Simplest case (all zeroes) - Open frames - Spares in non-final frame - Spares in final frame - Strikes in non-final frame - Strikes in final frame - Errors I've left out some tests, for a couple of reasons: - Won't work in Rust (e.g., passing a signed int to a function that expects unsigned -- won't compile) - Duplicative (e.g., multiple open frame tests that all exercise the same logic) I've altered test inputs from the canonical inputs. This is mostly in the tests around bonus points for strikes/spares. The canonical tests include rolls that aren't relevant to the logic being tested. I have left those rolls out so that the students can focus on the important inputs.
1 parent b445bd9 commit 03ae9ec

File tree

4 files changed

+273
-0
lines changed

4 files changed

+273
-0
lines changed

exercises/bowling/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
5+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6+
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
7+
Cargo.lock

exercises/bowling/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[package]
2+
name = "bowling"
3+
version = "0.0.0"

exercises/bowling/example.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

exercises/bowling/tests/bowling.rs

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#[test]
2+
fn twenty_zero_pin_rolls_is_zero() {
3+
let game = BowlingGame::new();
4+
5+
for x in (0..20) {
6+
game.roll(0);
7+
}
8+
9+
assert_eq!(game.score().unwrap(), 0);
10+
}
11+
12+
#[test]
13+
fn twenty_one_pin_rolls_is_twenty() {
14+
let game = BowlingGame::new();
15+
16+
for x in (0..20) {
17+
game.roll(1);
18+
}
19+
20+
assert_eq!(game.score().unwrap(), 20);
21+
}
22+
23+
#[test]
24+
fn ten_frames_without_a_strike_or_spare() {
25+
let game = BowlingGame::new();
26+
27+
for x in (0..20) {
28+
game.roll(4);
29+
}
30+
31+
assert_eq!(game.score().unwrap(), 80);
32+
}
33+
34+
#[test]
35+
fn spare_in_the_first_frame_followed_by_zeros() {
36+
let game = BowlingGame::new();
37+
38+
game.roll(4);
39+
game.roll(6);
40+
41+
for x in (0..18) {
42+
game.roll(0);
43+
}
44+
45+
assert_eq!(game.score().unwrap(), 10);
46+
}
47+
48+
#[test]
49+
fn points_scored_in_the_roll_after_a_spare_are_counted_twice_as_a_bonus() {
50+
let game = BowlingGame::new();
51+
52+
game.roll(5);
53+
game.roll(5);
54+
game.roll(3);
55+
56+
for x in (0..17) {
57+
game.roll(0);
58+
}
59+
60+
assert_eq!(game.score().unwrap(), 16);
61+
}
62+
63+
#[test]
64+
fn consecutive_spares_each_get_their_bonus_points() {
65+
let game = BowlingGame::new();
66+
67+
game.roll(5);
68+
game.roll(5);
69+
game.roll(3);
70+
game.roll(7);
71+
game.roll(4);
72+
73+
for x in (0..15) {
74+
game.roll(0);
75+
}
76+
77+
assert_eq!(game.score().unwrap(), 31);
78+
}
79+
80+
#[test]
81+
fn if_the_last_frame_is_a_spare_you_get_one_extra_roll_that_is_scored_once() {
82+
let game = BowlingGame::new();
83+
84+
for x in (0..17) {
85+
game.roll(0);
86+
}
87+
88+
game.roll(5);
89+
game.roll(5);
90+
game.roll(7);
91+
92+
assert_eq!(game.score().unwrap(), 17);
93+
}
94+
95+
#[test]
96+
fn a_strike_earns_ten_points_in_a_frame_with_a_single_roll() {
97+
let game = BowlingGame::new();
98+
99+
game.roll(10);
100+
101+
for x in (0..17) {
102+
game.roll(0);
103+
}
104+
105+
assert_eq!(game.score().unwrap(), 0);
106+
}
107+
108+
#[test]
109+
fn points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus() {
110+
let game = BowlingGame::new();
111+
112+
game.roll(10);
113+
game.roll(5);
114+
game.roll(3);
115+
116+
for x in (0..15) {
117+
game.roll(0);
118+
}
119+
120+
assert_eq!(game.score().unwrap(), 26);
121+
}
122+
123+
#[test]
124+
fn points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_with_consecutive_strikes() {
125+
let game = BowlingGame::new();
126+
127+
game.roll(10);
128+
game.roll(10);
129+
game.roll(10);
130+
game.roll(5);
131+
game.roll(3);
132+
133+
for x in (0..11) {
134+
game.roll(0);
135+
}
136+
137+
assert_eq!(game.score().unwrap(), 81);
138+
}
139+
140+
#[test]
141+
fn if_the_last_frame_is_a_strike_you_get_two_extra_rolls() {
142+
let game = BowlingGame::new();
143+
144+
for x in (0..17) {
145+
game.roll(0);
146+
}
147+
148+
game.roll(10);
149+
game.roll(7);
150+
game.roll(1);
151+
152+
assert_eq!(game.score().unwrap(), 18);
153+
}
154+
155+
#[test]
156+
fn strikes_in_extra_rolls_after_a_strike_in_the_final_frame_do_not_get_the_bonus() {
157+
let game = BowlingGame::new();
158+
159+
for x in (0..17) {
160+
game.roll(0);
161+
}
162+
163+
game.roll(10);
164+
game.roll(10);
165+
game.roll(10);
166+
167+
assert_eq!(game.score().unwrap(), 30);
168+
}
169+
170+
fn all_strikes_is_a_perfect_score_of_300() {
171+
let game = BowlingGame::new();
172+
173+
for x in (0..11) {
174+
game.roll(10);
175+
}
176+
177+
assert_eq!(game.score().unwrap(), 300);
178+
}
179+
180+
fn you_can_not_roll_more_than_ten_pins_in_a_single_roll() {
181+
let game = BowlingGame::new();
182+
183+
for x in (0..19) {
184+
game.roll(0);
185+
}
186+
187+
game.roll(11);
188+
189+
assert!(game.score().is_err());
190+
}
191+
192+
fn you_can_not_roll_more_than_ten_pins_in_a_single_frame() {
193+
let game = BowlingGame::new();
194+
195+
for x in (0..18) {
196+
game.roll(0);
197+
}
198+
199+
game.roll(5);
200+
game.roll(6);
201+
202+
assert!(game.score().is_err());
203+
}
204+
205+
fn you_can_not_score_a_game_with_no_rolls() {
206+
let game = BowlingGame::new();
207+
208+
assert!(game.score().is_err());
209+
}
210+
211+
fn you_can_not_score_an_incomplete_game() {
212+
let game = BowlingGame::new();
213+
214+
for x in (0..18) {
215+
game.roll(0);
216+
}
217+
218+
assert!(game.score().is_err());
219+
}
220+
221+
fn you_can_not_score_a_game_with_more_than_ten_frames() {
222+
let game = BowlingGame::new();
223+
224+
for x in (0..21) {
225+
game.roll(0);
226+
}
227+
228+
assert!(game.score().is_err());
229+
}
230+
231+
fn if_the_last_frame_is_a_spare_you_can_not_create_a_score_before_extra_roll_is_taken() {
232+
let game = BowlingGame::new();
233+
234+
for x in (0..17) {
235+
game.roll(0);
236+
}
237+
238+
game.roll(5);
239+
game.roll(5);
240+
241+
assert!(game.score().is_err());
242+
}
243+
244+
fn if_the_last_frame_is_a_strike_you_can_not_create_a_score_before_extra_rolls_are_taken() {
245+
let game = BowlingGame::new();
246+
247+
for x in (0..17) {
248+
game.roll(0);
249+
}
250+
251+
game.roll(10);
252+
253+
assert!(game.score().is_err());
254+
255+
game.roll(10);
256+
257+
assert!(game.score().is_err());
258+
259+
game.roll(10);
260+
261+
assert!(game.score().is_ok());
262+
}

0 commit comments

Comments
 (0)