2
// PriorityEventTest.cpp
4
// $Id: //poco/1.2/Foundation/testsuite/src/PriorityEventTest.cpp#2 $
6
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9
// Permission is hereby granted, free of charge, to any person or organization
10
// obtaining a copy of the software and accompanying documentation covered by
11
// this license (the "Software") to use, reproduce, display, distribute,
12
// execute, and transmit the Software, and to prepare derivative works of the
13
// Software, and to permit third-parties to whom the Software is furnished to
14
// do so, all subject to the following:
16
// The copyright notices in the Software and this entire statement, including
17
// the above license grant, this restriction and the following disclaimer,
18
// must be included in all copies of the Software, in whole or in part, and
19
// all derivative works of the Software, unless such copies or derivative
20
// works are solely in the form of machine-executable object code generated by
21
// a source language processor.
23
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
26
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
27
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
28
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
// DEALINGS IN THE SOFTWARE.
33
#include "PriorityEventTest.h"
34
#include "DummyDelegate.h"
35
#include "CppUnit/TestCaller.h"
36
#include "CppUnit/TestSuite.h"
37
#include "Poco/PriorityDelegate.h"
38
#include "Poco/PriorityExpire.h"
39
#include "Poco/Thread.h"
40
#include "Poco/Exception.h"
49
PriorityEventTest::PriorityEventTest(const std::string& name): CppUnit::TestCase(name)
54
PriorityEventTest::~PriorityEventTest()
58
void PriorityEventTest::testNoDelegate()
64
Simple.notify(this, tmp);
67
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
68
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
69
Simple.notify(this, tmp);
72
ConstSimple += PriorityDelegate<PriorityEventTest, const int>(this, &PriorityEventTest::onConstSimple, 0);
73
ConstSimple -= PriorityDelegate<PriorityEventTest, const int>(this, &PriorityEventTest::onConstSimple, 0);
74
ConstSimple.notify(this, tmp);
77
//Note: passing &args will not work due to &
78
EventArgs* pArgs = &args;
79
Complex += PriorityDelegate<PriorityEventTest, Poco::EventArgs*>(this, &PriorityEventTest::onComplex, 0);
80
Complex -= PriorityDelegate<PriorityEventTest, Poco::EventArgs*>(this, &PriorityEventTest::onComplex, 0);
81
Complex.notify(this, pArgs);
84
Complex2 += PriorityDelegate<PriorityEventTest, Poco::EventArgs>(this, &PriorityEventTest::onComplex2, 0);
85
Complex2 -= PriorityDelegate<PriorityEventTest, Poco::EventArgs>(this, &PriorityEventTest::onComplex2, 0);
86
Complex2.notify(this, args);
89
const EventArgs* pCArgs = &args;
90
ConstComplex += PriorityDelegate<PriorityEventTest, const Poco::EventArgs*>(this, &PriorityEventTest::onConstComplex, 0);
91
ConstComplex -= PriorityDelegate<PriorityEventTest, const Poco::EventArgs*>(this, &PriorityEventTest::onConstComplex, 0);
92
ConstComplex.notify(this, pCArgs);
95
Const2Complex += PriorityDelegate<PriorityEventTest, const Poco::EventArgs* const>(this, &PriorityEventTest::onConst2Complex, 0);
96
Const2Complex -= PriorityDelegate<PriorityEventTest, const Poco::EventArgs* const>(this, &PriorityEventTest::onConst2Complex, 0);
97
Const2Complex.notify(this, pArgs);
101
void PriorityEventTest::testSingleDelegate()
106
assert (_count == 0);
108
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
109
// unregistering with a different priority --> different observer, is ignored
110
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 3);
111
Simple.notify(this, tmp);
112
assert (_count == 1);
114
ConstSimple += PriorityDelegate<PriorityEventTest, const int>(this, &PriorityEventTest::onConstSimple, 0);
115
ConstSimple -= PriorityDelegate<PriorityEventTest, const int>(this, &PriorityEventTest::onConstSimple, 3);
116
ConstSimple.notify(this, tmp);
117
assert (_count == 2);
119
EventArgs* pArgs = &args;
120
Complex += PriorityDelegate<PriorityEventTest, Poco::EventArgs*>(this, &PriorityEventTest::onComplex, 0);
121
Complex -= PriorityDelegate<PriorityEventTest, Poco::EventArgs*>(this, &PriorityEventTest::onComplex, 3);
122
Complex.notify(this, pArgs);
123
assert (_count == 3);
125
Complex2 += PriorityDelegate<PriorityEventTest, Poco::EventArgs>(this, &PriorityEventTest::onComplex2, 0);
126
Complex2 -= PriorityDelegate<PriorityEventTest, Poco::EventArgs>(this, &PriorityEventTest::onComplex2, 3);
127
Complex2.notify(this, args);
128
assert (_count == 4);
130
const EventArgs* pCArgs = &args;
131
ConstComplex += PriorityDelegate<PriorityEventTest, const Poco::EventArgs*>(this, &PriorityEventTest::onConstComplex, 0);
132
ConstComplex -= PriorityDelegate<PriorityEventTest, const Poco::EventArgs*>(this, &PriorityEventTest::onConstComplex, 3);
133
ConstComplex.notify(this, pCArgs);
134
assert (_count == 5);
136
Const2Complex += PriorityDelegate<PriorityEventTest, const Poco::EventArgs* const>(this, &PriorityEventTest::onConst2Complex, 0);
137
Const2Complex -= PriorityDelegate<PriorityEventTest, const Poco::EventArgs* const>(this, &PriorityEventTest::onConst2Complex, 3);
138
Const2Complex.notify(this, pArgs);
139
assert (_count == 6);
140
// check if 2nd notify also works
141
Const2Complex.notify(this, pArgs);
142
assert (_count == 7);
146
void PriorityEventTest::testDuplicateRegister()
150
assert (_count == 0);
152
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
153
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
154
Simple.notify(this, tmp);
155
assert (_count == 1);
156
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
157
Simple.notify(this, tmp);
158
assert (_count == 1);
160
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
161
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimpleOther, 1);
162
Simple.notify(this, tmp);
163
assert (_count == 2 + LARGEINC);
164
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimpleOther, 1);
165
Simple.notify(this, tmp);
166
assert (_count == 3 + LARGEINC);
169
void PriorityEventTest::testDuplicateUnregister()
171
// duplicate unregister shouldn't give an error,
174
assert (_count == 0);
176
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0); // should work
177
Simple.notify(this, tmp);
178
assert (_count == 0);
180
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
181
Simple.notify(this, tmp);
182
assert (_count == 1);
184
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
185
Simple.notify(this, tmp);
186
assert (_count == 1);
188
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
189
Simple.notify(this, tmp);
190
assert (_count == 1);
194
void PriorityEventTest::testDisabling()
198
assert (_count == 0);
200
Simple += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
202
Simple.notify(this, tmp);
203
assert (_count == 0);
205
Simple.notify(this, tmp);
206
assert (_count == 1);
208
// unregister should also work with disabled event
210
Simple -= PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 0);
212
Simple.notify(this, tmp);
213
assert (_count == 1);
216
void PriorityEventTest::testPriorityOrder()
221
assert (_count == 0);
223
Simple += PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1);
224
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0);
227
Simple.notify(this, tmp);
230
Simple -= PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0);
231
Simple -= PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1);
233
// now try with the wrong order
234
Simple += PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 0);
235
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 1);
240
Simple.notify(this, tmp);
241
failmsg ("Notify should not work");
243
catch (Poco::InvalidArgumentException&)
247
Simple -= PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 0);
248
Simple -= PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 1);
251
void PriorityEventTest::testPriorityOrderExpire()
253
// expire must not break order!
257
assert (_count == 0);
259
Simple += PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1), 500000);
260
Simple += PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0), 500000);
262
Simple.notify(this, tmp);
265
// both ways of unregistering should work
266
Simple -= PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0), 600000);
267
Simple -= PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1);
268
Simple.notify(this, tmp);
271
// now start mixing of expire and non expire
273
Simple += PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1), 500000);
274
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0);
276
Simple.notify(this, tmp);
279
Simple -= PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 1);
280
// it is not forbidden to unregister a non expiring event with an expire decorator (it is just stupid ;-))
281
Simple -= PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0), 600000);
282
Simple.notify(this, tmp);
285
// now try with the wrong order
286
Simple += PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 0), 500000);
287
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 1);
292
Simple.notify(this, tmp);
293
failmsg ("Notify should not work");
295
catch (Poco::InvalidArgumentException&)
299
Simple -= PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o2, &DummyDelegate::onSimple2, 0), 500000);
300
Simple -= PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 1);
304
void PriorityEventTest::testExpire()
308
assert (_count == 0);
310
Simple += PriorityExpire<int>(PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 1), 500);
311
Simple.notify(this, tmp);
312
assert (_count == 1);
313
Poco::Thread::sleep(700);
314
Simple.notify(this, tmp);
315
assert (_count == 1);
316
Simple -= PriorityExpire<int>(PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 1), 500);
320
void PriorityEventTest::testExpireReRegister()
324
assert (_count == 0);
326
Simple += PriorityExpire<int>(PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 1), 500);
327
Simple.notify(this, tmp);
328
assert (_count == 1);
329
Poco::Thread::sleep(200);
330
Simple.notify(this, tmp);
331
assert (_count == 2);
332
// renew registration
333
Simple += PriorityExpire<int>(PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onSimple, 1), 600);
334
Poco::Thread::sleep(400);
335
Simple.notify(this, tmp);
336
assert (_count == 3);
337
Poco::Thread::sleep(300);
338
Simple.notify(this, tmp);
339
assert (_count == 3);
343
void PriorityEventTest::testReturnParams()
346
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0);
349
Simple.notify(this, tmp);
353
void PriorityEventTest::testOverwriteDelegate()
356
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple2, 0);
357
// o1 can only have one entry per priority, thus the next line will replace the entry
358
Simple += PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple, 0);
360
int tmp = 0; // onsimple requires 0 as input
361
Simple.notify(this, tmp);
363
// now overwrite with onsimple2 with requires as input tmp = 1
364
Simple += PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple2, 0), 23000);
365
Simple.notify(this, tmp);
367
Simple -= PriorityExpire<int>(PriorityDelegate<DummyDelegate, int>(&o1, &DummyDelegate::onSimple2, 0), 23000);
370
void PriorityEventTest::testAsyncNotify()
372
Poco::PriorityEvent<int >* pSimple= new Poco::PriorityEvent<int>();
373
(*pSimple) += PriorityDelegate<PriorityEventTest, int>(this, &PriorityEventTest::onAsync, 0);
374
assert (_count == 0);
376
Poco::ActiveResult<int>retArg = pSimple->notifyAsync(this, tmp);
377
delete pSimple; // must work even when the event got deleted!
379
assert (_count == 0);
381
assert (retArg.data() == tmp);
382
assert (_count == LARGEINC);
386
void PriorityEventTest::onSimple(const void* pSender, int& i)
391
void PriorityEventTest::onSimpleOther(const void* pSender, int& i)
396
void PriorityEventTest::onConstSimple(const void* pSender, const int& i)
401
void PriorityEventTest::onComplex(const void* pSender, Poco::EventArgs* & i)
406
void PriorityEventTest::onComplex2(const void* pSender, Poco::EventArgs & i)
411
void PriorityEventTest::onConstComplex(const void* pSender, const Poco::EventArgs*& i)
416
void PriorityEventTest::onConst2Complex(const void* pSender, const Poco::EventArgs * const & i)
421
void PriorityEventTest::onAsync(const void* pSender, int& i)
423
Poco::Thread::sleep(700);
427
int PriorityEventTest::getCount() const
432
void PriorityEventTest::setUp()
435
// must clear events, otherwise repeating test executions will fail
436
// because tests are only created once, only setup is called before
442
ConstComplex.clear();
443
Const2Complex.clear();
447
void PriorityEventTest::tearDown()
452
CppUnit::Test* PriorityEventTest::suite()
454
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("PriorityEventTest");
456
CppUnit_addTest(pSuite, PriorityEventTest, testNoDelegate);
457
CppUnit_addTest(pSuite, PriorityEventTest, testSingleDelegate);
458
CppUnit_addTest(pSuite, PriorityEventTest, testReturnParams);
459
CppUnit_addTest(pSuite, PriorityEventTest, testDuplicateRegister);
460
CppUnit_addTest(pSuite, PriorityEventTest, testDuplicateUnregister);
461
CppUnit_addTest(pSuite, PriorityEventTest, testDisabling);
462
CppUnit_addTest(pSuite, PriorityEventTest, testPriorityOrder);
463
CppUnit_addTest(pSuite, PriorityEventTest, testPriorityOrderExpire);
464
CppUnit_addTest(pSuite, PriorityEventTest, testExpire);
465
CppUnit_addTest(pSuite, PriorityEventTest, testExpireReRegister);
466
CppUnit_addTest(pSuite, PriorityEventTest, testOverwriteDelegate);
467
CppUnit_addTest(pSuite, PriorityEventTest, testAsyncNotify);