mock_it/
when.rs

1use crate::rule::Rule;
2use std::sync::{Arc, Mutex};
3
4pub struct When<I, O> {
5    input: I,
6    rules: Arc<Mutex<Vec<Rule<I, O>>>>,
7}
8
9impl<I, O> When<I, O> {
10    pub(crate) fn new(input: I, rules: Arc<Mutex<Vec<Rule<I, O>>>>) -> Self {
11        When { input, rules }
12    }
13}
14
15impl<I: PartialEq, O> When<I, O> {
16    /// Use the when return value when the mock is called with the specified
17    /// input
18    pub fn will_return(self, value: O) {
19        let mut rules_locked = self.rules.lock().unwrap();
20        let when_value = rules_locked
21            .iter()
22            .enumerate()
23            .find(|(_i, value)| value.input == self.input);
24
25        let rule = Rule::new(self.input, value);
26        match when_value {
27            Some((index, _value)) => {
28                let _old_rule = std::mem::replace(&mut rules_locked[index], rule);
29                ()
30            }
31            None => rules_locked.push(rule),
32        }
33    }
34}
35
36impl<I: PartialEq, O: Default> When<I, O> {
37    /// Use `Default::default` when the mock is called with the specified input
38    pub fn will_return_default(self) {
39        self.will_return(O::default())
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::When;
46    use crate::rule::Rule;
47    use std::sync::{Arc, Mutex};
48
49    /// When `Given::will_return` is called with an output, the corresponding
50    /// rule is added to the rules list
51    #[test]
52    fn add_rule_to_list() {
53        let rules = Arc::new(Mutex::new(Vec::new()));
54        let when = When::new("hello", rules.clone());
55
56        when.will_return(true);
57
58        let rules = rules.lock().unwrap();
59        assert_eq!(*rules, vec![Rule::new("hello", true)]);
60    }
61
62    #[test]
63    fn when_input_already_match_another_rule_replace_old_rule() {
64        let rules = Arc::new(Mutex::new(Vec::new()));
65        let when = When::new("sameinput", rules.clone());
66
67        let assert_rule = |input, output| {
68            let rules_locked = rules.lock().unwrap();
69            let rule = rules_locked.get(0).unwrap();
70            assert_eq!(rules_locked.len(), 1, "Rules should have only one rule.");
71            assert_eq!(rule.input, input);
72            assert_eq!(rule.output, output);
73        };
74
75        when.will_return("rule1");
76        assert_rule("sameinput", "rule1");
77
78        let when = When::new("sameinput", rules.clone());
79        when.will_return("rule2");
80        assert_rule("sameinput", "rule2");
81    }
82
83    /// When `Given::will_return_default` is called, a rule is made with the
84    /// default of the output type
85    #[test]
86    fn add_default() {
87        let rules = Arc::new(Mutex::new(Vec::new()));
88        let when: When<&str, bool> = When::new("hello", rules.clone());
89
90        when.will_return_default();
91
92        let rules = rules.lock().unwrap();
93        assert_eq!(*rules, vec![Rule::new("hello", false)]);
94    }
95}