manual/
manual.rs

1// This example demonstrates everything that can be done with Simulacrum at the
2// at the lowest level API.
3
4extern crate simulacrum;
5
6use simulacrum::*;
7
8trait CoolTrait {
9    // Shared self
10    fn foo(&self);
11
12    // Mutable self
13    fn bar(&mut self);
14
15    // One parameter and returning a value
16    fn goop(&mut self, flag: bool) -> u32;
17
18    // Multiple parameters
19    fn zing(&self, first: i32, second: bool);
20
21    // Static reference
22    fn boop(&self, name: &'static str);
23
24    // Shared reference
25    fn store(&self, val: &i64);
26
27    // Mutable reference
28    fn toggle(&self, bit: &mut bool);
29}
30
31pub struct CoolTraitMock {
32    e: Expectations
33}
34
35impl CoolTraitMock {
36    pub fn new() -> Self {
37        Self {
38            e: Expectations::new()
39        }
40    }
41
42    pub fn then(&mut self) -> &mut Self {
43        self.e.then();
44        self
45    }
46
47    pub fn expect_foo(&mut self) -> Method<(), ()> {
48        self.e.expect::<(), ()>("foo")
49    }
50
51    pub fn expect_bar(&mut self) -> Method<(), ()> {
52        self.e.expect::<(), ()>("bar")
53    }
54
55    pub fn expect_goop(&mut self) -> Method<bool, u32> {
56        self.e.expect::<bool, u32>("goop")
57    }
58
59    pub fn expect_zing(&mut self) -> Method<(i32, bool), ()> {
60        self.e.expect::<(i32, bool), ()>("zing")
61    }
62
63    pub fn expect_boop(&mut self) -> Method<&'static str, ()> {
64        self.e.expect::<&'static str, ()>("boop")
65    }
66
67    pub fn expect_store(&mut self) -> Method<*const i64, ()> {
68        self.e.expect::<*const i64, ()>("store")
69    }
70
71    pub fn expect_toggle(&mut self) -> Method<*mut bool, ()> {
72        self.e.expect::<*mut bool, ()>("toggle")
73    }
74}
75
76impl CoolTrait for CoolTraitMock {
77    fn foo(&self) {
78        self.e.was_called::<(), ()>("foo", ())
79    }
80
81    fn bar(&mut self) {
82        self.e.was_called::<(), ()>("bar", ())
83    }
84
85    fn goop(&mut self, flag: bool) -> u32 {
86        self.e.was_called_returning::<bool, u32>("goop", flag)
87    }
88
89    fn zing(&self, first: i32, second: bool) {
90        self.e.was_called::<(i32, bool), ()>("zing", (first, second))
91    }
92
93    fn boop(&self, name: &'static str) {
94        self.e.was_called::<&'static str, ()>("boop", name)
95    }
96
97    fn store(&self, val: &i64) {
98        self.e.was_called::<*const i64, ()>("store", val)
99    }
100
101    fn toggle(&self, bit: &mut bool) {
102        self.e.was_called::<*mut bool, ()>("toggle", bit)
103    }
104}
105
106fn main() {
107    // Create a mock object
108    let mut m = CoolTraitMock::new();
109
110    // Set up expectations for it
111    m.expect_bar().called_never();
112    m.expect_foo().called_once();
113    m.then().expect_goop().called_once().with(true).returning(|_| 5);
114    m.then().expect_zing().called_once().with(params!(13, false));
115    m.expect_boop().called_times(2);
116    m.expect_store().called_once().with(deref(777));
117    m.expect_toggle().called_once().with(deref(true))
118                                   .modifying(|&mut arg| { unsafe { *arg = false } });
119
120    // Execute test code
121    m.foo();
122    assert_eq!(m.goop(true), 5);
123    m.zing(13, false);
124    m.boop("hey");
125    m.boop("yo");
126    m.store(&777);
127    let mut b = true;
128    m.toggle(&mut b);
129    assert_eq!(b, false);
130
131    // When the mock object is dropped, its expectations will be evaluated
132}