source: filezilla/trunk/fuentes/tests/eventloop.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 3 years ago

First release to xenial

File size: 3.2 KB
Line 
1#include <libfilezilla.h>
2
3#include <event_handler.h>
4#include <event_loop.h>
5
6#include <cppunit/extensions/HelperMacros.h>
7
8class EventloopTest : public CppUnit::TestFixture
9{
10        CPPUNIT_TEST_SUITE(EventloopTest);
11        CPPUNIT_TEST(testSimple);
12        CPPUNIT_TEST(testFilter);
13        CPPUNIT_TEST(testCondition);
14        CPPUNIT_TEST_SUITE_END();
15
16public:
17        void setUp() {}
18        void tearDown() {}
19
20        void testSimple();
21        void testFilter();
22        void testCondition();
23};
24
25CPPUNIT_TEST_SUITE_REGISTRATION(EventloopTest);
26
27namespace {
28struct type1;
29typedef CEvent<type1> T1;
30
31struct type2;
32typedef CEvent<type2, int> T2;
33
34struct type3;
35typedef CEvent<type3> T3;
36
37struct type4;
38typedef CEvent<type4> T4;
39
40class target : public CEventHandler
41{
42public:
43        target(CEventLoop & l)
44        : CEventHandler(l)
45        {}
46
47        virtual ~target()
48        {
49                RemoveHandler();
50        }
51
52        void a()
53        {
54                ++a_;
55                SendEvent<T2>(5);
56        }
57
58        void b(int v)
59        {
60                ++b_;
61
62                CPPUNIT_ASSERT_EQUAL(v, 5);
63        }
64
65        void c()
66        {
67                SendEvent<T4>();
68        }
69
70        void d()
71        {
72                scoped_lock l(m_);
73                cond_.signal(l);
74        }
75
76        virtual void operator()(CEventBase const& ev) override {
77                CPPUNIT_ASSERT((Dispatch<T1, T2, T3, T4>(ev, this, &target::a, &target::b, &target::c, &target::d)));
78        }
79
80        int a_{};
81        int b_{};
82
83
84        mutex m_;
85        condition cond_;
86};
87}
88
89void EventloopTest::testSimple()
90{
91        CEventLoop loop;
92
93        target t(loop);
94
95        for (int i = 0; i < 1000; ++i) {
96                t.SendEvent<T1>();
97        }
98
99        t.SendEvent<T3>();
100
101        scoped_lock l(t.m_);
102        CPPUNIT_ASSERT(t.cond_.wait(l, 1000));
103
104        CPPUNIT_ASSERT_EQUAL(t.a_, 1000);
105        CPPUNIT_ASSERT_EQUAL(t.b_, 1000);
106}
107
108namespace {
109class target2 : public CEventHandler
110{
111public:
112        target2(CEventLoop & l)
113        : CEventHandler(l)
114        {}
115
116        virtual ~target2()
117        {
118                RemoveHandler();
119        }
120
121        void a()
122        {
123                {
124                        scoped_lock l(m_);
125                        CPPUNIT_ASSERT(cond2_.wait(l, 1000));
126                }
127
128                auto f = [&](CEventLoop::Events::value_type& ev) -> bool {
129                        if (ev.second->derived_type() == T1::type()) {
130                                ++c_;
131                                return true;
132                        }
133
134                        if (ev.second->derived_type() == T2::type()) {
135                                ++d_;
136                                std::get<0>(static_cast<T2&>(*ev.second).v_) += 4;
137                        }
138                        return false;
139
140                };
141                event_loop_.FilterEvents(f);
142                ++a_;
143        }
144
145        void b(int v)
146        {
147                b_ += v;
148        }
149
150        void c()
151        {
152                scoped_lock l(m_);
153                cond_.signal(l);
154        }
155
156        virtual void operator()(CEventBase const& ev) override {
157                CPPUNIT_ASSERT((Dispatch<T1, T2, T3>(ev, this, &target2::a, &target2::b, &target2::c)));
158        }
159
160        int a_{};
161        int b_{};
162        int c_{};
163        int d_{};
164
165        mutex m_;
166        condition cond_;
167        condition cond2_;
168};
169}
170
171void EventloopTest::testFilter()
172{
173        CEventLoop loop;
174
175        target2 t(loop);
176
177        for (int i = 0; i < 10; ++i) {
178                t.SendEvent<T1>();
179        }
180        t.SendEvent<T2>(3);
181        t.SendEvent<T2>(5);
182
183        t.SendEvent<T3>();
184
185        scoped_lock l(t.m_);
186        t.cond2_.signal(l);
187
188        CPPUNIT_ASSERT(t.cond_.wait(l, 1000));
189
190        CPPUNIT_ASSERT_EQUAL(t.a_, 1);
191        CPPUNIT_ASSERT_EQUAL(t.b_, 16);
192        CPPUNIT_ASSERT_EQUAL(t.c_, 9);
193        CPPUNIT_ASSERT_EQUAL(t.d_, 2);
194}
195
196void EventloopTest::testCondition()
197{
198        // Make sure condition::wait works correctly.
199
200        auto const t1 = CMonotonicClock::now();
201
202        mutex m;
203        condition c;
204
205        scoped_lock l(m);
206        CPPUNIT_ASSERT(!c.wait(l, 200));
207
208        auto const t2 = CMonotonicClock::now();
209
210        // Due to rounding errors things can be off for one millisecond, allow it.
211        CPPUNIT_ASSERT((t2 - t1) >= duration::from_milliseconds(199));
212}
Note: See TracBrowser for help on using the repository browser.