-
Notifications
You must be signed in to change notification settings - Fork 13
/
arbitrary_self.rs
206 lines (168 loc) · 5.02 KB
/
arbitrary_self.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#![allow(
clippy::new_without_default,
clippy::needless_arbitrary_self_type,
clippy::boxed_local,
clippy::redundant_clone
)]
use std::{boxed::Box, pin::Pin, rc::Rc, sync::Arc};
#[faux::create]
pub struct Owned {}
#[faux::methods]
impl Owned {
pub fn new() -> Self {
Owned {}
}
//normal receivers
pub fn by_ref(&self) {}
pub fn by_mut_ref(&mut self) {}
pub fn by_value(self) {}
#[allow(unused_mut)]
pub fn by_mut_value(mut self) {}
//self with a type
pub fn by_value2(self: Self) {}
pub fn by_ref2(self: &Self) {}
pub fn by_mut_ref2(self: &mut Self) {}
#[allow(unused_mut)]
pub fn by_mut_value2(mut self: Self) {}
pub fn by_box(self: std::boxed::Box<Self>) {}
// the following two will compile
// but they will only work if self is the *only*
// reference to the object. Otherwise they will panic
// with a message about using the self_type argument instead
pub fn by_rc(self: Rc<Self>) {}
pub fn by_arc(self: Arc<Self>) {}
pub fn by_pinmut(self: Pin<&mut Self>) {}
pub fn by_pinmut2(self: Pin<&mut Owned>) {}
pub fn by_pinrc(self: Pin<Rc<Self>>) {}
pub fn by_pinrc2(self: Pin<Rc<Owned>>) {}
pub fn by_pinarc(self: Pin<Arc<Self>>) {}
pub fn by_pinarc2(self: Pin<Arc<Owned>>) {}
pub fn by_pinbox(self: Pin<Box<Self>>) {}
pub fn by_pinbox2(self: Pin<Box<Owned>>) {}
}
#[faux::create(self_type = "Rc")]
pub struct ByRc {}
#[faux::methods(self_type = "Rc")]
impl ByRc {
pub fn new() -> Self {
ByRc {}
}
pub fn new_rc() -> Rc<Self> {
Rc::new(ByRc {})
}
pub fn new_rc2() -> Rc<ByRc> {
Rc::new(ByRc {})
}
pub fn by_rc(self: Rc<Self>) {}
pub fn by_rc2(self: std::rc::Rc<ByRc>) {}
pub fn by_ref(&self) {}
}
#[faux::create(self_type = "Arc")]
pub struct ByArc {}
#[faux::methods(self_type = "Arc")]
impl ByArc {
pub fn new() -> ByArc {
ByArc {}
}
pub fn new_arc() -> Arc<Self> {
Arc::new(ByArc {})
}
pub fn new_arc2() -> Arc<ByArc> {
Arc::new(ByArc {})
}
pub fn by_arc(self: Arc<Self>) {}
pub fn by_arc2(self: std::sync::Arc<ByArc>) {}
pub fn by_ref(&self) {}
}
#[faux::create(self_type = "Box")]
pub struct ByBox {}
#[faux::methods(self_type = "Box")]
impl ByBox {
pub fn new() -> ByBox {
ByBox {}
}
pub fn new_box() -> Box<Self> {
Box::new(ByBox {})
}
pub fn new_box2() -> Box<ByBox> {
Box::new(ByBox {})
}
pub fn by_box(self: Box<Self>) {}
pub fn by_box2(self: std::boxed::Box<ByBox>) {}
pub fn by_ref(&self) {}
pub fn by_mut_ref(&mut self) {}
pub fn by_value(self) {}
}
#[test]
fn by_rc_from_owned() {
// getting and invoking real instances/methods works
let real_rcd = Rc::new(Owned::new());
real_rcd.by_rc();
// mocking also works BUT
// mocks need a `&mut` when mocking a method
// so prepare the mock before wrapping it around an Rc
let mut faux_owned = Owned::faux();
faux::when!(faux_owned.by_rc).then(|_| {});
let faux_rcd = Rc::new(faux_owned);
faux_rcd.by_rc();
}
#[test]
#[should_panic]
fn by_rc_from_owned_panics_if_cloned() {
let rcd = Rc::new(Owned::new());
let clone = rcd.clone();
// panics because faux cannot get the owned value from the Rc.
clone.by_rc();
// rcd.by_rc(); would also have panicked
}
#[test]
fn by_rc() {
let rcd = Rc::new(ByRc::new());
let clone = rcd.clone();
// cloning the Rc works when self_type = Rc was specified in the mock
clone.by_rc();
rcd.by_rc();
// or get it already wrapped
let rcd = ByRc::new_rc();
rcd.by_rc();
// mocking must be done prior to wrapping it in an Rc
let mut owned = ByRc::faux();
faux::when!(owned.by_rc).then(|_| {});
let rcd = Rc::new(owned);
rcd.by_rc();
}
#[test]
fn by_box_from_owned() {
let real_boxed = Box::new(Owned::new());
real_boxed.by_box();
// can be boxed right away because a &mut can be obtained from a Box
let mut faux_boxed = Box::new(Owned::faux());
faux::when!(faux_boxed.by_box).then(|_| {});
faux_boxed.by_box();
}
#[test]
fn by_box() {
let real_boxed = ByBox::new_box();
real_boxed.by_box();
// can be boxed right away because a &mut can be obtained from a Box
let mut faux_boxed = Box::new(ByBox::faux());
faux::when!(faux_boxed.by_box).then(|_| {});
faux_boxed.by_box();
}
#[test]
fn by_pin_from_owned() {
let mut owned = Owned::new();
Pin::new(&mut owned).by_pinmut();
Pin::new(&mut owned).by_pinmut2();
Pin::new(Rc::new(Owned::new())).by_pinrc();
Pin::new(Rc::new(Owned::new())).by_pinrc2();
Pin::new(Arc::new(Owned::new())).by_pinarc();
Pin::new(Arc::new(Owned::new())).by_pinarc2();
Pin::new(Box::new(Owned::new())).by_pinbox();
Pin::new(Box::new(Owned::new())).by_pinbox2();
let mut faux = Owned::faux();
let mut faux_pinmut = Pin::new(&mut faux);
faux::when!(faux_pinmut.by_pinmut).then(|_| {});
faux::when!(faux_pinmut.by_pinmut2).then(|_| {});
faux_pinmut.by_pinmut();
}