macros_high/
macros_high.rs

1// This is the highest-level macro available in stable Simulacrum.
2//
3// It creates a Mock struct and impls a Trait - all you have to do is copy over
4// the trait interface and annotate it.
5//
6// Note that if you want additional control, like not mocking certain parameters,
7// you should use the mid-level macros shown in the `macros_mid.rs` example. For
8// even more control, you can use the `simulacrum` crate directly.
9
10extern crate simulacrum;
11
12use simulacrum::*;
13
14trait CoolTrait {
15    // Shared self
16    fn foo(&self);
17
18    // Mutable self
19    fn bar(&mut self);
20
21    // One parameter and returning a value
22    fn goop(&mut self, flag: bool) -> u32;
23
24    // Multiple parameters
25    fn zing(&self, first: i32, second: bool);
26
27    // Static reference
28    fn boop(&self, name: &'static str);
29
30    // Shared reference
31    fn store(&self, val: &i64);
32
33    // Mutable reference
34    fn toggle(&self, bit: &mut bool);
35
36    // Unsafe
37    unsafe fn ohno(&self);
38}
39
40create_mock! {
41    impl CoolTrait for CoolTraitMock (self) {
42        expect_foo("foo"):
43        fn foo(&self);
44
45        expect_bar("bar"):
46        fn bar(&mut self);
47
48        expect_goop("goop"):
49        fn goop(&mut self, flag: bool) -> u32;
50
51        expect_zing("zing"):
52        fn zing(&self, first: i32, second: bool);
53
54        // &'static params are a special case - other lifetimes can't be mocked.
55        expect_boop("boop"):
56        fn boop(&self, name: &'static str);
57
58        // & params are mocked as *const and &mut are mocked as *mut.
59        expect_store("store"):
60        fn store(&self, val: &i64);
61
62        expect_toggle("toggle"): 
63        fn toggle(&self, bit: &mut bool);
64
65        expect_ohno("ohno"):
66        unsafe fn ohno(&self);
67    }
68}
69
70fn main() {
71    // Create a mock object
72    let mut m = CoolTraitMock::new();
73
74    // Set up expectations for it
75    m.expect_bar().called_never();
76    m.expect_foo().called_once();
77    m.then().expect_goop().called_once().with(true).returning(|_| 5);
78    m.then().expect_zing().called_once().with(params!(13, false));
79    m.expect_boop().called_times(2);
80    m.expect_store().called_once().with(deref(777));
81    m.expect_toggle().called_once().with(deref(true))
82                                   .modifying(|&mut arg| { unsafe { *arg = false } });
83    m.expect_ohno().called_once();
84
85    // Execute test code
86    m.foo();
87    assert_eq!(m.goop(true), 5);
88    m.zing(13, false);
89    m.boop("hey");
90    m.boop("yo");
91    m.store(&777);
92    let mut b = true;
93    m.toggle(&mut b);
94    assert_eq!(b, false);
95    unsafe {
96        m.ohno();
97    }
98
99    // When the mock object is dropped, its expectations will be evaluated
100}