blob: 057b920e1746048fa4f4ccd21a70e381d7e848c4 [file] [log] [blame]
Junxiao Shi1a2a8562014-01-23 10:07:59 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include <util/event-emitter.hpp>
8#include <boost/bind.hpp>
9#include <boost/test/unit_test.hpp>
10namespace ndn {
11
12class EventEmitterTester : boost::noncopyable
13{
14public:
15 EventEmitterTester();
16
17 int m_hit;
18 int m_a1;
19 int m_a2;
20 int m_a3;
21 int m_a4;
22
23 void
24 clear();
25
26 void
27 f0();
28
29 void
30 f1(int a1);
31
32 void
33 f2(int a1, int a2);
34
35 void
36 f3(int a1, int a2, int a3);
37
38 void
39 f4(int a1, int a2, int a3, int a4);
40};
41
42EventEmitterTester::EventEmitterTester()
43{
44 this->clear();
45}
46
47void
48EventEmitterTester::clear()
49{
50 m_hit = 0;
51 m_a1 = 0;
52 m_a2 = 0;
53 m_a3 = 0;
54 m_a4 = 0;
55}
56
57void
58EventEmitterTester::f0()
59{
60 ++m_hit;
61}
62
63void
64EventEmitterTester::f1(int a1)
65{
66 ++m_hit;
67 m_a1 = a1;
68}
69
70void
71EventEmitterTester::f2(int a1, int a2)
72{
73 ++m_hit;
74 m_a1 = a1;
75 m_a2 = a2;
76}
77
78void
79EventEmitterTester::f3(int a1, int a2, int a3)
80{
81 ++m_hit;
82 m_a1 = a1;
83 m_a2 = a2;
84 m_a3 = a3;
85}
86
87void
88EventEmitterTester::f4(int a1, int a2, int a3, int a4)
89{
90 ++m_hit;
91 m_a1 = a1;
92 m_a2 = a2;
93 m_a3 = a3;
94 m_a4 = a4;
95}
96
97static int g_EventEmitterTest_RefObject_copyCount;
98
99class EventEmitterTest_RefObject
100{
101public:
102 EventEmitterTest_RefObject() {}
103
104 EventEmitterTest_RefObject(const EventEmitterTest_RefObject& other);
105};
106
107EventEmitterTest_RefObject::EventEmitterTest_RefObject(const EventEmitterTest_RefObject& other)
108{
109 ++g_EventEmitterTest_RefObject_copyCount;
110}
111
112void
113EventEmitterTest_RefObject_byVal(EventEmitterTest_RefObject a1) {}
114
115void
116EventEmitterTest_RefObject_byRef(const EventEmitterTest_RefObject& a1) {}
117
118
119BOOST_AUTO_TEST_SUITE(UtilEventEmitter)
120
121BOOST_AUTO_TEST_CASE(ZeroListener)
122{
123 EventEmitter<> ee;
124 BOOST_CHECK_NO_THROW(ee());
125}
126
127BOOST_AUTO_TEST_CASE(TwoListeners)
128{
129 EventEmitterTester eet1;
130 EventEmitterTester eet2;
131 EventEmitter<> ee;
132 ee += boost::bind(&EventEmitterTester::f0, &eet1);
133 ee += boost::bind(&EventEmitterTester::f0, &eet2);
134 ee();
135
136 BOOST_CHECK_EQUAL(eet1.m_hit, 1);
137 BOOST_CHECK_EQUAL(eet2.m_hit, 1);
138}
139
140BOOST_AUTO_TEST_CASE(ZeroArgument)
141{
142 EventEmitterTester eet;
143 EventEmitter<> ee;
144 ee += boost::bind(&EventEmitterTester::f0, &eet);
145 ee();
146
147 BOOST_CHECK_EQUAL(eet.m_hit, 1);
148}
149
150BOOST_AUTO_TEST_CASE(OneArgument)
151{
152 EventEmitterTester eet;
153 EventEmitter<int> ee;
154 ee += boost::bind(&EventEmitterTester::f1, &eet, _1);
155 ee(11);
156
157 BOOST_CHECK_EQUAL(eet.m_hit, 1);
158 BOOST_CHECK_EQUAL(eet.m_a1, 11);
159}
160
161BOOST_AUTO_TEST_CASE(TwoArguments)
162{
163 EventEmitterTester eet;
164 EventEmitter<int,int> ee;
165 ee += boost::bind(&EventEmitterTester::f2, &eet, _1, _2);
166 ee(21, 22);
167
168 BOOST_CHECK_EQUAL(eet.m_hit, 1);
169 BOOST_CHECK_EQUAL(eet.m_a1, 21);
170 BOOST_CHECK_EQUAL(eet.m_a2, 22);
171}
172
173BOOST_AUTO_TEST_CASE(ThreeArguments)
174{
175 EventEmitterTester eet;
176 EventEmitter<int,int,int> ee;
177 ee += boost::bind(&EventEmitterTester::f3, &eet, _1, _2, _3);
178 ee(31, 32, 33);
179
180 BOOST_CHECK_EQUAL(eet.m_hit, 1);
181 BOOST_CHECK_EQUAL(eet.m_a1, 31);
182 BOOST_CHECK_EQUAL(eet.m_a2, 32);
183 BOOST_CHECK_EQUAL(eet.m_a3, 33);
184}
185
186BOOST_AUTO_TEST_CASE(FourArguments)
187{
188 EventEmitterTester eet;
189 EventEmitter<int,int,int,int> ee;
190 ee += boost::bind(&EventEmitterTester::f4, &eet, _1, _2, _3, _4);
191 ee(41, 42, 43, 44);
192
193 BOOST_CHECK_EQUAL(eet.m_hit, 1);
194 BOOST_CHECK_EQUAL(eet.m_a1, 41);
195 BOOST_CHECK_EQUAL(eet.m_a2, 42);
196 BOOST_CHECK_EQUAL(eet.m_a3, 43);
197 BOOST_CHECK_EQUAL(eet.m_a4, 44);
198}
199
200// EventEmitter passes arguments by reference,
201// but it also allows a handler that accept arguments by value
202BOOST_AUTO_TEST_CASE(HandlerByVal)
203{
204 EventEmitterTest_RefObject refObject;
205 g_EventEmitterTest_RefObject_copyCount = 0;
206
207 EventEmitter<EventEmitterTest_RefObject> ee;
208 ee += &EventEmitterTest_RefObject_byVal;
209 ee(refObject);
210
211 BOOST_CHECK_EQUAL(g_EventEmitterTest_RefObject_copyCount, 1);
212}
213
214// EventEmitter passes arguments by reference, and no copying
215// is necessary when handler accepts arguments by reference
216BOOST_AUTO_TEST_CASE(HandlerByRef)
217{
218 EventEmitterTest_RefObject refObject;
219 g_EventEmitterTest_RefObject_copyCount = 0;
220
221 EventEmitter<EventEmitterTest_RefObject> ee;
222 ee += &EventEmitterTest_RefObject_byRef;
223 ee(refObject);
224
225 BOOST_CHECK_EQUAL(g_EventEmitterTest_RefObject_copyCount, 0);
226}
227
228BOOST_AUTO_TEST_SUITE_END()
229};//namespace ndn