Skip to content

Commit fe5bce0

Browse files
committed
add modern tests
1 parent 54ba7b2 commit fe5bce0

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

Cargo.lock

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

tests/tests.rs

+94
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,101 @@
11
use speculate::*;
2+
use std::{
3+
sync::mpsc,
4+
thread::{self, JoinHandle},
5+
};
26

37
#[test]
48
fn test_spec() {
59
assert!(spec(|| 2 + 2, || 4, |x| x + 2) == 6);
610
assert!(spec(|| 2 + 2, || 1, |x| x + 2) == 6);
711
}
12+
13+
/// Spawns a thread to collect results sent over a channel.
14+
///
15+
/// # Arguments
16+
///
17+
/// * `receiver` - The receiving end of a channel from which to receive results.
18+
/// * `sender` - The sending end of a channel to which collected results will be sent.
19+
/// * `size` - The expected number of results to collect.
20+
///
21+
/// The function expects the `receiver` to receive `Option<(usize, T)>` messages,
22+
/// where `Some((idx, val))` indicates a result `val` at index `idx`, and `None` indicates
23+
/// that no more results will be sent.
24+
fn spawn_result_collector<T: 'static + Send + Default + Clone>(
25+
receiver: mpsc::Receiver<Option<(usize, T)>>,
26+
sender: mpsc::Sender<Vec<T>>,
27+
size: usize,
28+
) -> JoinHandle<()> {
29+
thread::spawn(move || {
30+
let mut results = vec![T::default(); size];
31+
for received in receiver {
32+
match received {
33+
Some((idx, val)) => results[idx] = val,
34+
None => break,
35+
}
36+
}
37+
let _res = sender.send(results);
38+
})
39+
}
40+
41+
#[test]
42+
fn test_specfold_correct_prediction() {
43+
let (tx, rx) = mpsc::channel::<Option<(usize, isize)>>();
44+
let (res_tx, res_rx) = mpsc::channel::<Vec<isize>>();
45+
let tx_clone = tx.clone();
46+
// Spawn the result collector thread
47+
48+
let loop_body = move |idx: usize, val: isize| -> isize {
49+
let res = idx as isize + val;
50+
tx.send(Some((idx, res))).unwrap();
51+
res
52+
};
53+
let loop_results = vec![0, 0, 1, 3, 6];
54+
let predictor = move |idx: usize| loop_results[idx];
55+
56+
spawn_result_collector(rx, res_tx, 5);
57+
specfold(5, loop_body, predictor);
58+
tx_clone.send(None).unwrap();
59+
let expected_results = vec![0, 1, 3, 6, 10];
60+
assert!(res_rx.recv().unwrap() == expected_results);
61+
}
62+
63+
#[test]
64+
fn test_specfold_incorrect_prediction() {
65+
let (tx, rx) = mpsc::channel::<Option<(usize, isize)>>();
66+
let (res_tx, res_rx) = mpsc::channel::<Vec<isize>>();
67+
let tx_clone = tx.clone();
68+
69+
let loop_body = move |idx: usize, val: isize| -> isize {
70+
let res = idx as isize + val + 5;
71+
tx.send(Some((idx, res))).unwrap();
72+
res
73+
};
74+
75+
let predictor = move |_| 0;
76+
spawn_result_collector(rx, res_tx, 1);
77+
specfold(1, loop_body, predictor);
78+
tx_clone.send(None).unwrap();
79+
let expected_results = vec![5];
80+
assert!(res_rx.recv().unwrap() == expected_results);
81+
}
82+
83+
#[test]
84+
fn test_specfold_no_tasks() {
85+
let (tx, rx) = mpsc::channel::<Option<(usize, isize)>>();
86+
let (res_tx, res_rx) = mpsc::channel::<Vec<isize>>();
87+
let tx_clone = tx.clone();
88+
89+
let loop_body = move |idx: usize, val: isize| -> isize {
90+
let res = idx as isize + val + 5;
91+
tx.send(Some((idx, res))).unwrap();
92+
res
93+
};
94+
95+
let predictor = move |_| 0;
96+
spawn_result_collector(rx, res_tx, 0);
97+
specfold(0, loop_body, predictor);
98+
tx_clone.send(None).unwrap();
99+
let expected_results = vec![];
100+
assert!(res_rx.recv().unwrap() == expected_results);
101+
}

0 commit comments

Comments
 (0)