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
23using namespace Poco;
24
25
26#define LARGEINC 100
27
28
29BasicEventTest::BasicEventTest(const std::string& rName): CppUnit::TestCase(rName)
30{
31}
32
33
34BasicEventTest::~BasicEventTest()
35{
36}
37
38
39void 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
118void 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
172void 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
188void 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
205void 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
230void 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
253void 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
278void 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
301void 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
312void 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
324void 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
340void 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
355void BasicEventTest::onStaticVoid(const void* pSender)
356{
357 BasicEventTest* p = const_cast<BasicEventTest*>(reinterpret_cast<const BasicEventTest*>(pSender));
358 p->_count++;
359}
360
361
362void BasicEventTest::onVoid(const void* pSender)
363{
364 _count++;
365}
366
367
368void BasicEventTest::onSimpleNoSender(int& i)
369{
370 _count++;
371}
372
373
374void BasicEventTest::onSimple(const void* pSender, int& i)
375{
376 _count++;
377}
378
379
380void 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
387void BasicEventTest::onStaticSimple2(void* pSender, int& i)
388{
389 BasicEventTest* p = reinterpret_cast<BasicEventTest*>(pSender);
390 p->_count++;
391}
392
393
394void BasicEventTest::onStaticSimple3(int& i)
395{
396}
397
398
399void BasicEventTest::onSimpleOther(const void* pSender, int& i)
400{
401 _count+=100;
402}
403
404
405void BasicEventTest::onConstSimple(const void* pSender, const int& i)
406{
407 _count++;
408}
409
410
411void BasicEventTest::onString(const void* pSender, std::string& str)
412{
413 _str = str;
414}
415
416
417void BasicEventTest::onConstString(const void* pSender, const std::string& str)
418{
419 _str = str;
420}
421
422
423void BasicEventTest::onComplex(const void* pSender, Poco::EventArgs* & i)
424{
425 _count++;
426}
427
428
429void BasicEventTest::onComplex2(const void* pSender, Poco::EventArgs & i)
430{
431 _count++;
432}
433
434
435void BasicEventTest::onConstComplex(const void* pSender, const Poco::EventArgs*& i)
436{
437 _count++;
438}
439
440
441void BasicEventTest::onConst2Complex(const void* pSender, const Poco::EventArgs * const & i)
442{
443 _count++;
444}
445
446
447void BasicEventTest::onAsync(const void* pSender, int& i)
448{
449 Poco::Thread::sleep(700);
450 _count += LARGEINC ;
451}
452
453
454int BasicEventTest::getCount() const
455{
456 return _count;
457}
458
459
460void 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
476void BasicEventTest::tearDown()
477{
478}
479
480
481CppUnit::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