1 | // |
2 | // BasicEventTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "BasicEventTest.h" |
12 | #include "DummyDelegate.h" |
13 | #include "Poco/CppUnit/TestCaller.h" |
14 | #include "Poco/CppUnit/TestSuite.h" |
15 | #include "Poco/Expire.h" |
16 | #include "Poco/Delegate.h" |
17 | #include "Poco/FunctionDelegate.h" |
18 | #include "Poco/Thread.h" |
19 | #include "Poco/Exception.h" |
20 | #include "Poco/StdFunctionDelegate.h" |
21 | |
22 | |
23 | using namespace Poco; |
24 | |
25 | |
26 | #define LARGEINC 100 |
27 | |
28 | |
29 | BasicEventTest::BasicEventTest(const std::string& rName): CppUnit::TestCase(rName) |
30 | { |
31 | } |
32 | |
33 | |
34 | BasicEventTest::~BasicEventTest() |
35 | { |
36 | } |
37 | |
38 | |
39 | void BasicEventTest::testNoDelegate() |
40 | { |
41 | int tmp = 0; |
42 | EventArgs args; |
43 | |
44 | assertTrue (_count == 0); |
45 | assertTrue (Void.empty()); |
46 | Void.notify(this); |
47 | assertTrue (_count == 0); |
48 | |
49 | Void += delegate(this, &BasicEventTest::onVoid); |
50 | assertTrue (!Void.empty()); |
51 | Void -= delegate(this, &BasicEventTest::onVoid); |
52 | assertTrue (Void.empty()); |
53 | Void.notify(this); |
54 | |
55 | assertTrue (_count == 0); |
56 | assertTrue (Simple.empty()); |
57 | Simple.notify(this, tmp); |
58 | assertTrue (_count == 0); |
59 | |
60 | Simple += delegate(this, &BasicEventTest::onSimple); |
61 | assertTrue (!Simple.empty()); |
62 | Simple -= delegate(this, &BasicEventTest::onSimple); |
63 | assertTrue (Simple.empty()); |
64 | Simple.notify(this, tmp); |
65 | assertTrue (_count == 0); |
66 | |
67 | Simple += delegate(this, &BasicEventTest::onSimpleNoSender); |
68 | Simple -= delegate(this, &BasicEventTest::onSimpleNoSender); |
69 | Simple.notify(this, tmp); |
70 | assertTrue (_count == 0); |
71 | |
72 | ConstSimple += delegate(this, &BasicEventTest::onConstSimple); |
73 | ConstSimple -= delegate(this, &BasicEventTest::onConstSimple); |
74 | ConstSimple.notify(this, tmp); |
75 | assertTrue (_count == 0); |
76 | |
77 | //Note: passing &args will not work due to & |
78 | EventArgs* pArgs = &args; |
79 | Complex += delegate(this, &BasicEventTest::onComplex); |
80 | Complex -= delegate(this, &BasicEventTest::onComplex); |
81 | Complex.notify(this, pArgs); |
82 | assertTrue (_count == 0); |
83 | |
84 | Complex2 += delegate(this, &BasicEventTest::onComplex2); |
85 | Complex2 -= delegate(this, &BasicEventTest::onComplex2); |
86 | Complex2.notify(this, args); |
87 | assertTrue (_count == 0); |
88 | |
89 | const EventArgs* pCArgs = &args; |
90 | ConstComplex += delegate(this, &BasicEventTest::onConstComplex); |
91 | ConstComplex -= delegate(this, &BasicEventTest::onConstComplex); |
92 | ConstComplex.notify(this, pCArgs); |
93 | assertTrue (_count == 0); |
94 | |
95 | Const2Complex += delegate(this, &BasicEventTest::onConst2Complex); |
96 | Const2Complex -= delegate(this, &BasicEventTest::onConst2Complex); |
97 | Const2Complex.notify(this, pArgs); |
98 | assertTrue (_count == 0); |
99 | |
100 | Simple += delegate(&BasicEventTest::onStaticSimple); |
101 | Simple += delegate(&BasicEventTest::onStaticSimple); |
102 | Simple += delegate(&BasicEventTest::onStaticSimple2); |
103 | Simple += delegate(&BasicEventTest::onStaticSimple3); |
104 | |
105 | Simple.notify(this, tmp); |
106 | assertTrue (_count == 3); |
107 | Simple -= delegate(BasicEventTest::onStaticSimple); |
108 | |
109 | Void += delegate(&BasicEventTest::onStaticVoid); |
110 | Void += delegate(&BasicEventTest::onStaticVoid); |
111 | |
112 | Void.notify(this); |
113 | assertTrue (_count == 5); |
114 | Void -= delegate(BasicEventTest::onStaticVoid); |
115 | } |
116 | |
117 | |
118 | void BasicEventTest::testSingleDelegate() |
119 | { |
120 | int tmp = 0; |
121 | std::string tmpStr; |
122 | EventArgs args; |
123 | |
124 | assertTrue (_count == 0); |
125 | |
126 | Void += delegate(this, &BasicEventTest::onVoid); |
127 | Void.notify(this); |
128 | assertTrue (_count == 1); |
129 | |
130 | Simple += delegate(this, &BasicEventTest::onSimple); |
131 | Simple.notify(this, tmp); |
132 | assertTrue (_count == 2); |
133 | |
134 | ConstSimple += delegate(this, &BasicEventTest::onConstSimple); |
135 | ConstSimple.notify(this, tmp); |
136 | assertTrue (_count == 3); |
137 | |
138 | tmpStr = "str" ; |
139 | SimpleString += delegate(this, &BasicEventTest::onString); |
140 | SimpleString.notify(this, tmpStr); |
141 | assertTrue (_str == "str" ); |
142 | |
143 | tmpStr = "strConst" ; |
144 | ConstString += delegate(this, &BasicEventTest::onConstString); |
145 | ConstString.notify(this, tmpStr); |
146 | assertTrue (_str == "strConst" ); |
147 | |
148 | EventArgs* pArgs = &args; |
149 | Complex += delegate(this, &BasicEventTest::onComplex); |
150 | Complex.notify(this, pArgs); |
151 | assertTrue (_count == 4); |
152 | |
153 | Complex2 += delegate(this, &BasicEventTest::onComplex2); |
154 | Complex2.notify(this, args); |
155 | assertTrue (_count == 5); |
156 | |
157 | const EventArgs* pCArgs = &args; |
158 | ConstComplex += delegate(this, &BasicEventTest::onConstComplex); |
159 | ConstComplex.notify(this, pCArgs); |
160 | assertTrue (_count == 6); |
161 | |
162 | Const2Complex += delegate(this, &BasicEventTest::onConst2Complex); |
163 | Const2Complex.notify(this, pArgs); |
164 | assertTrue (_count == 7); |
165 | // check if 2nd notify also works |
166 | Const2Complex.notify(this, pArgs); |
167 | assertTrue (_count == 8); |
168 | |
169 | } |
170 | |
171 | |
172 | void BasicEventTest::testDuplicateRegister() |
173 | { |
174 | int tmp = 0; |
175 | |
176 | assertTrue (_count == 0); |
177 | |
178 | Simple += delegate(this, &BasicEventTest::onSimple); |
179 | Simple += delegate(this, &BasicEventTest::onSimple); |
180 | Simple.notify(this, tmp); |
181 | assertTrue (_count == 2); |
182 | Simple -= delegate(this, &BasicEventTest::onSimple); |
183 | Simple.notify(this, tmp); |
184 | assertTrue (_count == 3); |
185 | } |
186 | |
187 | |
188 | void BasicEventTest::testNullMutex() |
189 | { |
190 | Poco::BasicEvent<int, NullMutex> ev; |
191 | int tmp = 0; |
192 | |
193 | assertTrue (_count == 0); |
194 | |
195 | ev += delegate(this, &BasicEventTest::onSimple); |
196 | ev += delegate(this, &BasicEventTest::onSimple); |
197 | ev.notify(this, tmp); |
198 | assertTrue (_count == 2); |
199 | ev -= delegate(this, &BasicEventTest::onSimple); |
200 | ev.notify(this, tmp); |
201 | assertTrue (_count == 3); |
202 | } |
203 | |
204 | |
205 | void BasicEventTest::testDuplicateUnregister() |
206 | { |
207 | // duplicate unregister shouldn't give an error, |
208 | int tmp = 0; |
209 | |
210 | assertTrue (_count == 0); |
211 | |
212 | Simple -= delegate(this, &BasicEventTest::onSimple); // should work |
213 | Simple.notify(this, tmp); |
214 | assertTrue (_count == 0); |
215 | |
216 | Simple += delegate(this, &BasicEventTest::onSimple); |
217 | Simple.notify(this, tmp); |
218 | assertTrue (_count == 1); |
219 | |
220 | Simple -= delegate(this, &BasicEventTest::onSimple); |
221 | Simple.notify(this, tmp); |
222 | assertTrue (_count == 1); |
223 | |
224 | Simple -= delegate(this, &BasicEventTest::onSimple); |
225 | Simple.notify(this, tmp); |
226 | assertTrue (_count == 1); |
227 | } |
228 | |
229 | |
230 | void BasicEventTest::testDisabling() |
231 | { |
232 | int tmp = 0; |
233 | |
234 | assertTrue (_count == 0); |
235 | |
236 | Simple += delegate(this, &BasicEventTest::onSimple); |
237 | Simple.disable(); |
238 | Simple.notify(this, tmp); |
239 | assertTrue (_count == 0); |
240 | Simple.enable(); |
241 | Simple.notify(this, tmp); |
242 | assertTrue (_count == 1); |
243 | |
244 | // unregister should also work with disabled event |
245 | Simple.disable(); |
246 | Simple -= delegate(this, &BasicEventTest::onSimple); |
247 | Simple.enable(); |
248 | Simple.notify(this, tmp); |
249 | assertTrue (_count == 1); |
250 | } |
251 | |
252 | |
253 | void BasicEventTest::testExpire() |
254 | { |
255 | int tmp = 0; |
256 | |
257 | assertTrue (_count == 0); |
258 | |
259 | Simple += delegate(this, &BasicEventTest::onSimple, 500); |
260 | Simple.notify(this, tmp); |
261 | assertTrue (_count == 1); |
262 | Poco::Thread::sleep(700); |
263 | Simple.notify(this, tmp); |
264 | assertTrue (_count == 1); |
265 | |
266 | Simple += delegate(&BasicEventTest::onStaticSimple, 400); |
267 | Simple += delegate(&BasicEventTest::onStaticSimple, 400); |
268 | Simple += delegate(&BasicEventTest::onStaticSimple2, 400); |
269 | Simple += delegate(&BasicEventTest::onStaticSimple3, 400); |
270 | Simple.notify(this, tmp); |
271 | assertTrue (_count == 4); |
272 | Poco::Thread::sleep(700); |
273 | Simple.notify(this, tmp); |
274 | assertTrue (_count == 4); |
275 | } |
276 | |
277 | |
278 | void BasicEventTest::testExpireReRegister() |
279 | { |
280 | int tmp = 0; |
281 | |
282 | assertTrue (_count == 0); |
283 | |
284 | Simple += delegate(this, &BasicEventTest::onSimple, 500); |
285 | Simple.notify(this, tmp); |
286 | assertTrue (_count == 1); |
287 | Poco::Thread::sleep(200); |
288 | Simple.notify(this, tmp); |
289 | assertTrue (_count == 2); |
290 | // renew registration |
291 | Simple += delegate(this, &BasicEventTest::onSimple, 600); |
292 | Poco::Thread::sleep(400); |
293 | Simple.notify(this, tmp); |
294 | assertTrue (_count == 3); |
295 | Poco::Thread::sleep(300); |
296 | Simple.notify(this, tmp); |
297 | assertTrue (_count == 3); |
298 | } |
299 | |
300 | |
301 | void BasicEventTest::testReturnParams() |
302 | { |
303 | DummyDelegate o1; |
304 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
305 | |
306 | int tmp = 0; |
307 | Simple.notify(this, tmp); |
308 | assertTrue (tmp == 1); |
309 | } |
310 | |
311 | |
312 | void BasicEventTest::testOverwriteDelegate() |
313 | { |
314 | DummyDelegate o1; |
315 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
316 | Simple += delegate(&o1, &DummyDelegate::onSimple2); |
317 | |
318 | int tmp = 0; // onsimple requires 0 as input |
319 | Simple.notify(this, tmp); |
320 | assertTrue (tmp == 2); |
321 | } |
322 | |
323 | |
324 | void BasicEventTest::testAsyncNotify() |
325 | { |
326 | Poco::BasicEvent<int>* pSimple= new Poco::BasicEvent<int>(); |
327 | (*pSimple) += delegate(this, &BasicEventTest::onAsync); |
328 | assertTrue (_count == 0); |
329 | int tmp = 0; |
330 | Poco::ActiveResult<int>retArg = pSimple->notifyAsync(this, tmp); |
331 | delete pSimple; // must work even when the event got deleted! |
332 | pSimple = NULL; |
333 | assertTrue (_count == 0); |
334 | retArg.wait(); |
335 | assertTrue (retArg.data() == tmp); |
336 | assertTrue (_count == LARGEINC); |
337 | } |
338 | |
339 | |
340 | void BasicEventTest::testLambda() |
341 | { |
342 | int count = 0; |
343 | auto f = StdFunctionDelegate<int>([&](const void *, int &args) { count += args; }); |
344 | |
345 | Simple += f; |
346 | int cparam = 1; |
347 | Simple.notify(this, cparam); |
348 | assertTrue (count == 1); |
349 | |
350 | Simple -= f; |
351 | assertTrue (Simple.empty()); |
352 | } |
353 | |
354 | |
355 | void BasicEventTest::onStaticVoid(const void* pSender) |
356 | { |
357 | BasicEventTest* p = const_cast<BasicEventTest*>(reinterpret_cast<const BasicEventTest*>(pSender)); |
358 | p->_count++; |
359 | } |
360 | |
361 | |
362 | void BasicEventTest::onVoid(const void* pSender) |
363 | { |
364 | _count++; |
365 | } |
366 | |
367 | |
368 | void BasicEventTest::onSimpleNoSender(int& i) |
369 | { |
370 | _count++; |
371 | } |
372 | |
373 | |
374 | void BasicEventTest::onSimple(const void* pSender, int& i) |
375 | { |
376 | _count++; |
377 | } |
378 | |
379 | |
380 | void BasicEventTest::onStaticSimple(const void* pSender, int& i) |
381 | { |
382 | BasicEventTest* p = const_cast<BasicEventTest*>(reinterpret_cast<const BasicEventTest*>(pSender)); |
383 | p->_count++; |
384 | } |
385 | |
386 | |
387 | void BasicEventTest::onStaticSimple2(void* pSender, int& i) |
388 | { |
389 | BasicEventTest* p = reinterpret_cast<BasicEventTest*>(pSender); |
390 | p->_count++; |
391 | } |
392 | |
393 | |
394 | void BasicEventTest::onStaticSimple3(int& i) |
395 | { |
396 | } |
397 | |
398 | |
399 | void BasicEventTest::onSimpleOther(const void* pSender, int& i) |
400 | { |
401 | _count+=100; |
402 | } |
403 | |
404 | |
405 | void BasicEventTest::onConstSimple(const void* pSender, const int& i) |
406 | { |
407 | _count++; |
408 | } |
409 | |
410 | |
411 | void BasicEventTest::(const void* pSender, std::string& str) |
412 | { |
413 | _str = str; |
414 | } |
415 | |
416 | |
417 | void BasicEventTest::onConstString(const void* pSender, const std::string& str) |
418 | { |
419 | _str = str; |
420 | } |
421 | |
422 | |
423 | void BasicEventTest::onComplex(const void* pSender, Poco::EventArgs* & i) |
424 | { |
425 | _count++; |
426 | } |
427 | |
428 | |
429 | void BasicEventTest::onComplex2(const void* pSender, Poco::EventArgs & i) |
430 | { |
431 | _count++; |
432 | } |
433 | |
434 | |
435 | void BasicEventTest::onConstComplex(const void* pSender, const Poco::EventArgs*& i) |
436 | { |
437 | _count++; |
438 | } |
439 | |
440 | |
441 | void BasicEventTest::onConst2Complex(const void* pSender, const Poco::EventArgs * const & i) |
442 | { |
443 | _count++; |
444 | } |
445 | |
446 | |
447 | void BasicEventTest::onAsync(const void* pSender, int& i) |
448 | { |
449 | Poco::Thread::sleep(700); |
450 | _count += LARGEINC ; |
451 | } |
452 | |
453 | |
454 | int BasicEventTest::getCount() const |
455 | { |
456 | return _count; |
457 | } |
458 | |
459 | |
460 | void BasicEventTest::setUp() |
461 | { |
462 | _count = 0; |
463 | // must clear events, otherwise repeating test executions will fail |
464 | // because tests are only created once, only setup is called before |
465 | // each test run |
466 | Void.clear(); |
467 | Simple.clear(); |
468 | ConstSimple.clear(); |
469 | Complex.clear(); |
470 | Complex2.clear(); |
471 | ConstComplex.clear(); |
472 | Const2Complex.clear(); |
473 | } |
474 | |
475 | |
476 | void BasicEventTest::tearDown() |
477 | { |
478 | } |
479 | |
480 | |
481 | CppUnit::Test* BasicEventTest::suite() |
482 | { |
483 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("BasicEventTest" ); |
484 | |
485 | CppUnit_addTest(pSuite, BasicEventTest, testNoDelegate); |
486 | CppUnit_addTest(pSuite, BasicEventTest, testSingleDelegate); |
487 | CppUnit_addTest(pSuite, BasicEventTest, testReturnParams); |
488 | CppUnit_addTest(pSuite, BasicEventTest, testDuplicateRegister); |
489 | CppUnit_addTest(pSuite, BasicEventTest, testDuplicateUnregister); |
490 | CppUnit_addTest(pSuite, BasicEventTest, testDisabling); |
491 | CppUnit_addTest(pSuite, BasicEventTest, testExpire); |
492 | CppUnit_addTest(pSuite, BasicEventTest, testExpireReRegister); |
493 | CppUnit_addTest(pSuite, BasicEventTest, testOverwriteDelegate); |
494 | CppUnit_addTest(pSuite, BasicEventTest, testAsyncNotify); |
495 | CppUnit_addTest(pSuite, BasicEventTest, testNullMutex); |
496 | CppUnit_addTest(pSuite, BasicEventTest, testLambda); |
497 | return pSuite; |
498 | } |
499 | |