]> git.saurik.com Git - wxWidgets.git/blob - tests/events/propagation.cpp
add a unit test checking that events are really propagated as they're supposed to
[wxWidgets.git] / tests / events / propagation.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/events/propagation.cpp
3 // Purpose: Test events propagation
4 // Author: Vadim Zeitlin
5 // Created: 2009-01-16
6 // RCS-ID: $Id$
7 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #ifndef WX_PRECOMP
21 #endif // WX_PRECOMP
22
23 #include "wx/event.h"
24 #include "wx/scopeguard.h"
25
26 namespace
27 {
28
29 // this string will record the execution of all handlers
30 wxString g_str;
31
32 // a custom event
33 wxDEFINE_EVENT(TEST_EVT, wxCommandEvent);
34
35 // a custom event handler
36 class TestEvtHandler : public wxEvtHandler
37 {
38 public:
39 TestEvtHandler(char tag)
40 : m_tag(tag)
41 {
42 Connect(TEST_EVT, wxCommandEventHandler(TestEvtHandler::OnTest));
43 }
44
45 // override ProcessEvent() to confirm that it is called for all event
46 // handlers in the chain
47 virtual bool ProcessEvent(wxEvent& event)
48 {
49 if ( event.GetEventType() == TEST_EVT )
50 g_str += 'o'; // "o" == "overridden"
51
52 return wxEvtHandler::ProcessEvent(event);
53 }
54
55 private:
56 void OnTest(wxCommandEvent& event)
57 {
58 g_str += m_tag;
59
60 event.Skip();
61 }
62
63 const char m_tag;
64
65 DECLARE_NO_COPY_CLASS(TestEvtHandler)
66 };
67
68 // a window handling the test event
69 class TestWindow : public wxWindow
70 {
71 public:
72 TestWindow(wxWindow *parent, char tag)
73 : wxWindow(parent, wxID_ANY),
74 m_tag(tag)
75 {
76 Connect(TEST_EVT, wxCommandEventHandler(TestWindow::OnTest));
77 }
78
79 private:
80 void OnTest(wxCommandEvent& event)
81 {
82 g_str += m_tag;
83
84 event.Skip();
85 }
86
87 const char m_tag;
88
89 DECLARE_NO_COPY_CLASS(TestWindow)
90 };
91
92 int DoFilterEvent(wxEvent& event)
93 {
94 if ( event.GetEventType() == TEST_EVT )
95 g_str += 'a';
96
97 return -1;
98 }
99
100 bool DoProcessEvent(wxEvent& event)
101 {
102 if ( event.GetEventType() == TEST_EVT )
103 g_str += 'A';
104
105 return false;
106 }
107
108 } // anonymous namespace
109
110 // --------------------------------------------------------------------------
111 // test class
112 // --------------------------------------------------------------------------
113
114 class EventPropagationTestCase : public CppUnit::TestCase
115 {
116 public:
117 EventPropagationTestCase() {}
118
119 virtual void setUp();
120 virtual void tearDown();
121
122 private:
123 CPPUNIT_TEST_SUITE( EventPropagationTestCase );
124 CPPUNIT_TEST( OneHandler );
125 CPPUNIT_TEST( TwoHandlers );
126 CPPUNIT_TEST( WindowWithoutHandler );
127 CPPUNIT_TEST( WindowWithHandler );
128 CPPUNIT_TEST_SUITE_END();
129
130 void OneHandler();
131 void TwoHandlers();
132 void WindowWithoutHandler();
133 void WindowWithHandler();
134
135 DECLARE_NO_COPY_CLASS(EventPropagationTestCase)
136 };
137
138 // register in the unnamed registry so that these tests are run by default
139 CPPUNIT_TEST_SUITE_REGISTRATION( EventPropagationTestCase );
140
141 // also include in it's own registry so that these tests can be run alone
142 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EventPropagationTestCase, "EventPropagationTestCase" );
143
144 void EventPropagationTestCase::setUp()
145 {
146 SetFilterEventFunc(DoFilterEvent);
147 SetProcessEventFunc(DoProcessEvent);
148
149 g_str.clear();
150 }
151
152 void EventPropagationTestCase::tearDown()
153 {
154 SetFilterEventFunc(NULL);
155 SetProcessEventFunc(NULL);
156 }
157
158 void EventPropagationTestCase::OneHandler()
159 {
160 wxCommandEvent event(TEST_EVT);
161 TestEvtHandler h1('1');
162 h1.ProcessEvent(event);
163 CPPUNIT_ASSERT_EQUAL( "oa1A", g_str );
164 }
165
166 void EventPropagationTestCase::TwoHandlers()
167 {
168 wxCommandEvent event(TEST_EVT);
169 TestEvtHandler h1('1');
170 TestEvtHandler h2('2');
171 h1.SetNextHandler(&h2);
172 h2.SetPreviousHandler(&h1);
173 h1.ProcessEvent(event);
174 CPPUNIT_ASSERT_EQUAL( "oa1o2A", g_str );
175 }
176
177 void EventPropagationTestCase::WindowWithoutHandler()
178 {
179 wxCommandEvent event(TEST_EVT);
180 TestWindow * const parent = new TestWindow(wxTheApp->GetTopWindow(), 'p');
181 wxON_BLOCK_EXIT_OBJ0( *parent, wxWindow::Destroy );
182
183 TestWindow * const child = new TestWindow(parent, 'c');
184
185 child->ProcessEvent(event);
186 CPPUNIT_ASSERT_EQUAL( "acpA", g_str );
187 }
188
189 void EventPropagationTestCase::WindowWithHandler()
190 {
191 wxCommandEvent event(TEST_EVT);
192 TestWindow * const parent = new TestWindow(wxTheApp->GetTopWindow(), 'p');
193 wxON_BLOCK_EXIT_OBJ0( *parent, wxWindow::Destroy );
194
195 TestWindow * const child = new TestWindow(parent, 'c');
196
197 TestEvtHandler h1('1');
198 child->PushEventHandler(&h1);
199 wxON_BLOCK_EXIT_OBJ0( *child, wxWindow::PopEventHandler );
200 TestEvtHandler h2('2');
201 child->PushEventHandler(&h2);
202 wxON_BLOCK_EXIT_OBJ0( *child, wxWindow::PopEventHandler );
203
204 child->HandleWindowEvent(event);
205 CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str );
206 }
207