1 module mocked.tests.alien;
2 
3 import dshould;
4 import mocked;
5 import unit_threaded.attrs : ShouldFail;
6 
7 version (unittest)
8 {
9     class Templated(T)
10     {
11     }
12 
13     interface IM
14     {
15         void bar();
16     }
17 
18     class ConstructorArg
19     {
20         int a;
21 
22         this(int i)
23         {
24             this.a = i;
25         }
26 
27         int getA()
28         {
29             return this.a;
30         }
31     }
32 
33     class SimpleObject
34     {
35         this()
36         {
37         }
38 
39         void print()
40         {
41             import std.stdio : writeln;
42 
43             writeln(toString());
44         }
45     }
46 
47     interface IRM
48     {
49         IM get();
50         void set(IM im);
51     }
52 
53     interface IFace
54     {
55         void foo(string s);
56     }
57 
58     class Smthng : IFace
59     {
60         void foo(string)
61         {
62         }
63     }
64 
65     class HasMember
66     {
67         int member;
68     }
69 
70     interface VirtualFinal
71     {
72         int makeVir();
73     }
74 
75     class Dependency
76     {
77         private int[] arr = [1, 2];
78         private int index = 0;
79         public int foo()
80         {
81             return arr[index++];
82         }
83     }
84 
85     class TakesFloat
86     {
87         public void foo(float)
88         {
89         }
90     }
91 
92     class TestClass
93     {
94         string test()
95         {
96             return "test";
97         }
98 
99         string test1()
100         {
101             return "test 1";
102         }
103 
104         string test2()
105         {
106             return "test 2";
107         }
108 
109         int test_int(int i)
110         {
111             return i;
112         }
113     }
114 }
115 
116 @("nontemplated mock")
117 unittest
118 {
119     Mocker().mock!(Object)();
120 }
121 
122 @("templated mock")
123 unittest
124 {
125     static assert(is(typeof(Mocker().mock!(Templated!(int))())));
126 }
127 
128 @("interface mock")
129 unittest
130 {
131     static assert(is(typeof(Mocker().mock!IM())));
132 }
133 
134 @("constructor argument")
135 unittest
136 {
137     Mocker mocker;
138 
139     static assert(is(typeof(mocker.mock!(ConstructorArg)(4))));
140 }
141 
142 @("unexpected call")
143 unittest
144 {
145     Mocker mocker;
146     TestClass cl = mocker.mock!(TestClass);
147 
148     cl.test.should.throwA!UnexpectedCallError;
149     mocker.verify;
150 }
151 
152 @ShouldFail("expect")
153 unittest
154 {
155     Mocker mocker;
156     auto cl = mocker.mock!(TestClass);
157     cl.expect.test().repeat(0).returns("mrow?");
158 
159     cl.test;
160 }
161 
162 @("repeat single")
163 unittest
164 {
165     Mocker mocker;
166     auto cl = mocker.mock!(TestClass);
167     cl.expect.test().repeat(2).returns("foom?");
168 
169     cl.test;
170     cl.test;
171 
172     cl.test.should.throwAn!UnexpectedCallError;
173 }
174 
175 @ShouldFail("repository match counts")
176 unittest
177 {
178     Mocker mocker;
179     auto cl = mocker.mock!TestClass;
180 
181     cl.expect.test().repeat(2).returns("mew.");
182 
183     mocker.verify();
184 }
185 
186 @("delegate payload")
187 unittest
188 {
189     bool calledPayload = false;
190     Mocker mocker;
191     auto obj = mocker.mock!SimpleObject;
192 
193     obj.expect.print().action({ calledPayload = true; });
194 
195     obj.print;
196 
197     calledPayload.should.be(true);
198 }
199 
200 @("delegate payload with mismatching parameters")
201 unittest
202 {
203     Mocker mocker;
204     auto obj = mocker.mock!SimpleObject;
205 
206     static assert(!is(typeof(obj.expect.print().action((int) {}))));
207 }
208 
209 @("exception payload")
210 unittest
211 {
212     Mocker mocker;
213     auto obj = mocker.mock!(SimpleObject);
214 
215     enum string msg = "divide by cucumber error";
216     obj.expect.print().throws(new Exception(msg));
217 
218     obj.print.should.throwAn!Exception.where.msg.should.equal(msg);
219 }
220 
221 @("passthrough")
222 unittest
223 {
224     Mocker mocker;
225     auto cl = mocker.mock!(TestClass);
226     cl.expect.test().passThrough;
227 
228     string str = cl.test;
229     str.should.equal("test");
230 }
231 
232 @("class with constructor init check")
233 unittest
234 {
235     Mocker mocker;
236     auto obj = mocker.mock!ConstructorArg(4);
237 
238     obj.expect.getA().passThrough;
239 
240     obj.getA().should.equal(4);
241 }
242 
243 @("associative arrays")
244 unittest
245 {
246     Mocker mocker;
247 
248     auto mock = mocker.mock!(Object);
249     mock.expect.toHash.passThrough().repeatAny;
250     mock.expect.opEquals.passThrough().repeatAny;
251 
252     auto obj = mock.get;
253 
254     int[Object] i;
255     i[obj] = 5;
256     int j = i[obj];
257 }
258 
259 @("mock interface")
260 unittest
261 {
262     Mocker mocker;
263     auto obj = mocker.mock!IFace;
264 
265     obj.expect.foo("hallo");
266 
267     obj.get.foo("hallo");
268 
269     mocker.verify;
270 }
271 
272 @("cast mock to interface")
273 unittest
274 {
275     Mocker mocker;
276     auto obj = mocker.mock!Smthng;
277 
278     obj.expect.foo("hallo");
279 
280     obj.get.foo("hallo");
281 
282     mocker.verify;
283 }
284 
285 @("cast mock to interface")
286 unittest
287 {
288     Mocker mocker;
289     auto obj = mocker.mock!Smthng;
290 
291     obj.expect.foo("hallo");
292 
293     obj.foo("hallo");
294 
295     mocker.verify;
296 }
297 
298 @("return user-defined type")
299 unittest
300 {
301     Mocker mocker;
302 
303     auto objBuilder = mocker.mock!IRM;
304     auto obj = objBuilder.get;
305 
306     auto imBuilder = mocker.mock!IM;
307     auto im = imBuilder.get;
308 
309     objBuilder.expect.get().returns(im);
310     objBuilder.expect.set(im);
311 
312     obj.get.should.be(im);
313     obj.set(im);
314     mocker.verify;
315 }
316 
317 @("return user-defined type")
318 unittest
319 {
320     Mocker mocker;
321     mocker.mock!HasMember;
322 }
323 
324 @("returning different values on the same expectation")
325 unittest
326 {
327     Mocker mocker;
328     auto dependency = mocker.mock!Dependency;
329 
330     //mocker.ordered;
331     dependency.expect.foo.returns(1);
332     dependency.expect.foo.returns(2);
333 
334     dependency.foo.should.equal(1);
335     dependency.foo.should.equal(2);
336 
337     mocker.verify;
338 }
339 
340 @("customArgsComparator")
341 unittest
342 {
343     import std.math : abs;
344 
345     enum float argument = 1.0f;
346 
347     auto mocker = configure!(Comparator!((float a, float b) => abs(a - b) < 0.1f));
348     auto dependency = mocker.mock!TakesFloat;
349     dependency.expect.foo(argument).repeat(2);
350 
351     // custom comparison example - treat similar floats as equals
352     dependency.foo(1.01);
353     dependency.foo(1.02);
354 }