Skip to content

Commit 32985cc

Browse files
authored
Merge pull request #59 from Samyak2/tests
Add unit tests for Results calculations
2 parents a52ad70 + cd15d15 commit 32985cc

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

Cargo.lock

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ clap = { version = "3.0.5", features = ["derive", "color", "suggestions"] }
2828
rand = "0.8.4"
2929
termion = "1.5.6"
3030
include-flate = {version ="0.1.4", features=["stable"]}
31+
approx = "0.5.1"

src/results.rs

+151
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ impl ToipeResults {
3232

3333
/// Percentage of letters that were typed correctly.
3434
pub fn accuracy(&self) -> f64 {
35+
if self.total_chars_typed == 0 {
36+
return 0.0;
37+
}
38+
3539
(self.total_chars_typed as isize - self.total_char_errors as isize) as f64
3640
/ self.total_chars_typed as f64
3741
}
@@ -51,3 +55,150 @@ impl ToipeResults {
5155
/ (self.duration().as_secs_f64() / 60.0)
5256
}
5357
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
use super::*;
62+
use approx::assert_ulps_eq;
63+
64+
#[test]
65+
fn sanity() {
66+
let started_at = Instant::now();
67+
let ended_at = started_at + Duration::new(10, 0);
68+
let results = ToipeResults {
69+
total_words: 0,
70+
total_chars_typed: 100,
71+
total_chars_in_text: 120,
72+
total_char_errors: 10,
73+
final_chars_typed_correctly: 80,
74+
final_uncorrected_errors: 2,
75+
started_at,
76+
ended_at,
77+
};
78+
79+
assert_eq!(results.duration(), Duration::new(10, 0));
80+
81+
assert_ulps_eq!(results.accuracy(), 0.9, max_ulps = 1);
82+
assert_ulps_eq!(results.wpm(), 84.0, max_ulps = 1);
83+
}
84+
85+
#[test]
86+
fn accuracy() {
87+
fn get_toipe_results(total_chars_typed: usize, total_char_errors: usize) -> ToipeResults {
88+
ToipeResults {
89+
total_words: 0,
90+
total_chars_typed,
91+
total_chars_in_text: 0,
92+
total_char_errors,
93+
final_chars_typed_correctly: 0,
94+
final_uncorrected_errors: 0,
95+
started_at: Instant::now(),
96+
ended_at: Instant::now(),
97+
}
98+
}
99+
100+
let max_ulps = 1;
101+
102+
// no errors
103+
assert_ulps_eq!(
104+
get_toipe_results(100, 0).accuracy(),
105+
1.0,
106+
max_ulps = max_ulps
107+
);
108+
// nothing typed
109+
assert_ulps_eq!(get_toipe_results(0, 0).accuracy(), 0.0, max_ulps = max_ulps);
110+
// all wrong
111+
assert_ulps_eq!(
112+
get_toipe_results(100, 100).accuracy(),
113+
0.0,
114+
max_ulps = max_ulps
115+
);
116+
// half correct
117+
assert_ulps_eq!(
118+
get_toipe_results(100, 50).accuracy(),
119+
0.5,
120+
max_ulps = max_ulps
121+
);
122+
// more errors than correct
123+
assert_ulps_eq!(
124+
get_toipe_results(100, 150).accuracy(),
125+
-0.5,
126+
max_ulps = max_ulps
127+
);
128+
}
129+
130+
#[test]
131+
fn wpm() {
132+
fn get_toipe_results(
133+
final_chars_typed_correctly: usize,
134+
final_uncorrected_errors: usize,
135+
duration: f64,
136+
) -> ToipeResults {
137+
let started_at = Instant::now();
138+
let seconds = duration.round();
139+
let nanoseconds = (duration - seconds) * 1_000_000_000.0;
140+
let ended_at = started_at + Duration::new(seconds as u64, nanoseconds as u32);
141+
ToipeResults {
142+
total_words: 0,
143+
total_chars_typed: 0,
144+
total_chars_in_text: 0,
145+
total_char_errors: 0,
146+
final_chars_typed_correctly,
147+
final_uncorrected_errors,
148+
started_at,
149+
ended_at,
150+
}
151+
}
152+
153+
let max_ulps = 1;
154+
assert_ulps_eq!(
155+
get_toipe_results(100, 5, 30.0).wpm(),
156+
30.0,
157+
max_ulps = max_ulps
158+
);
159+
assert_ulps_eq!(
160+
get_toipe_results(1000, 50, 30.0).wpm(),
161+
300.0,
162+
max_ulps = max_ulps
163+
);
164+
assert_ulps_eq!(
165+
get_toipe_results(200, 0, 30.0).wpm(),
166+
80.0,
167+
max_ulps = max_ulps
168+
);
169+
assert_ulps_eq!(
170+
get_toipe_results(200, 30, 30.0).wpm(),
171+
20.0,
172+
max_ulps = max_ulps
173+
);
174+
// too many errors - cancels out
175+
assert_ulps_eq!(
176+
get_toipe_results(200, 40, 30.0).wpm(),
177+
0.0,
178+
max_ulps = max_ulps
179+
);
180+
// no negative wpms
181+
assert_ulps_eq!(
182+
get_toipe_results(200, 50, 30.0).wpm(),
183+
0.0,
184+
max_ulps = max_ulps
185+
);
186+
assert_ulps_eq!(
187+
get_toipe_results(1, 0, 1.0).wpm(),
188+
12.0,
189+
max_ulps = max_ulps
190+
);
191+
// skdlhaslkd won't give you any score!
192+
assert_ulps_eq!(
193+
get_toipe_results(0, 10, 1.0).wpm(),
194+
0.0,
195+
max_ulps = max_ulps
196+
);
197+
assert_ulps_eq!(
198+
get_toipe_results(0, 0, 0.01).wpm(),
199+
0.0,
200+
max_ulps = max_ulps
201+
);
202+
// we don't consider the case of duration = 0 because that seems impossible
203+
}
204+
}

0 commit comments

Comments
 (0)