Avoid creating children of wxButton in MiscGUIFuncsTestCase.
[wxWidgets.git] / tests / misc / guifuncs.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/misc/misctests.cpp
3 // Purpose: test miscellaneous GUI functions
4 // Author: Vadim Zeitlin
5 // Created: 2008-09-22
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ----------------------------------------------------------------------------
11 // headers
12 // ----------------------------------------------------------------------------
13
14 #include "testprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/defs.h"
21
22 #ifndef WX_PRECOMP
23 #include "wx/gdicmn.h"
24 #include "wx/filefn.h"
25 #endif // !PCH
26
27 #include "wx/app.h"
28 #include "wx/button.h"
29 #include "wx/clipbrd.h"
30 #include "wx/dataobj.h"
31
32 // ----------------------------------------------------------------------------
33 // test class
34 // ----------------------------------------------------------------------------
35
36 class MiscGUIFuncsTestCase : public CppUnit::TestCase
37 {
38 public:
39 MiscGUIFuncsTestCase() { }
40
41 private:
42 CPPUNIT_TEST_SUITE( MiscGUIFuncsTestCase );
43 CPPUNIT_TEST( DisplaySize );
44 CPPUNIT_TEST( URLDataObject );
45 CPPUNIT_TEST( ParseFileDialogFilter );
46 CPPUNIT_TEST( FindWindowAtPoint );
47 CPPUNIT_TEST_SUITE_END();
48
49 void DisplaySize();
50 void URLDataObject();
51 void ParseFileDialogFilter();
52 void FindWindowAtPoint();
53
54 DECLARE_NO_COPY_CLASS(MiscGUIFuncsTestCase)
55 };
56
57 // register in the unnamed registry so that these tests are run by default
58 CPPUNIT_TEST_SUITE_REGISTRATION( MiscGUIFuncsTestCase );
59
60 // also include in its own registry so that these tests can be run alone
61 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MiscGUIFuncsTestCase, "MiscGUIFuncsTestCase" );
62
63 void MiscGUIFuncsTestCase::DisplaySize()
64 {
65 // test that different (almost) overloads return the same results
66 int w, h;
67 wxDisplaySize(&w, &h);
68 wxSize sz = wxGetDisplaySize();
69
70 CPPUNIT_ASSERT_EQUAL( w, sz.x );
71 CPPUNIT_ASSERT_EQUAL( h, sz.y );
72
73 // test that passing NULL works as expected, e.g. doesn't crash
74 wxDisplaySize(NULL, NULL);
75 wxDisplaySize(&w, NULL);
76 wxDisplaySize(NULL, &h);
77
78 CPPUNIT_ASSERT_EQUAL( w, sz.x );
79 CPPUNIT_ASSERT_EQUAL( h, sz.y );
80
81 // test that display PPI is something reasonable
82 sz = wxGetDisplayPPI();
83 CPPUNIT_ASSERT( sz.x < 1000 && sz.y < 1000 );
84 }
85
86 void MiscGUIFuncsTestCase::URLDataObject()
87 {
88 // this tests for buffer overflow, see #11102
89 const char * const
90 url = "http://something.long.to.overwrite.plenty.memory.example.com";
91 wxURLDataObject * const dobj = new wxURLDataObject(url);
92 CPPUNIT_ASSERT_EQUAL( url, dobj->GetURL() );
93
94 wxClipboardLocker lockClip;
95 CPPUNIT_ASSERT( wxTheClipboard->SetData(dobj) );
96 wxTheClipboard->Flush();
97 }
98
99 void MiscGUIFuncsTestCase::ParseFileDialogFilter()
100 {
101 wxArrayString descs,
102 filters;
103
104 CPPUNIT_ASSERT_EQUAL
105 (
106 1,
107 wxParseCommonDialogsFilter("Image files|*.jpg;*.png", descs, filters)
108 );
109
110 CPPUNIT_ASSERT_EQUAL( "Image files", descs[0] );
111 CPPUNIT_ASSERT_EQUAL( "*.jpg;*.png", filters[0] );
112
113 CPPUNIT_ASSERT_EQUAL
114 (
115 2,
116 wxParseCommonDialogsFilter
117 (
118 "All files (*.*)|*.*|Python source (*.py)|*.py",
119 descs, filters
120 )
121 );
122
123 CPPUNIT_ASSERT_EQUAL( "*.*", filters[0] );
124 CPPUNIT_ASSERT_EQUAL( "*.py", filters[1] );
125
126 // Test some invalid ones too.
127 WX_ASSERT_FAILS_WITH_ASSERT
128 (
129 wxParseCommonDialogsFilter
130 (
131 "All files (*.*)|*.*|Python source (*.py)|*.py|",
132 descs, filters
133 )
134 );
135 }
136
137 namespace
138 {
139
140 // This class is used as a test window here. We can't use a real wxButton
141 // because we can't create other windows as its children in wxGTK.
142 class TestButton : public wxWindow
143 {
144 public:
145 TestButton(wxWindow* parent, const wxString& label, const wxPoint& pos)
146 : wxWindow(parent, wxID_ANY, pos, wxSize(100, 50))
147 {
148 SetLabel(label);
149 }
150 };
151
152 // Helper function returning the label of the window at the given point or
153 // "NONE" if there is no window there.
154 wxString GetLabelOfWindowAtPoint(wxWindow* parent, int x, int y)
155 {
156 wxWindow* const
157 win = wxFindWindowAtPoint(parent->ClientToScreen(wxPoint(x, y)));
158 return win ? win->GetLabel() : wxString("NONE");
159 }
160
161 } // anonymous namespace
162
163 void MiscGUIFuncsTestCase::FindWindowAtPoint()
164 {
165 wxWindow* const parent = wxTheApp->GetTopWindow();
166 CPPUNIT_ASSERT( parent );
167
168 // Set a label to allow distinguishing it from the other windows in the
169 // assertion messages.
170 parent->SetLabel("parent");
171
172 CPPUNIT_ASSERT_EQUAL_MESSAGE
173 (
174 "No window for a point outside of the window",
175 "NONE",
176 GetLabelOfWindowAtPoint(parent, 900, 900)
177 );
178
179 wxWindow* btn1 = new TestButton(parent, "1", wxPoint(10, 10));
180 CPPUNIT_ASSERT_EQUAL_MESSAGE
181 (
182 "Point over a child control corresponds to it",
183 btn1->GetLabel(),
184 GetLabelOfWindowAtPoint(parent, 11, 11)
185 );
186
187 CPPUNIT_ASSERT_EQUAL_MESSAGE
188 (
189 "Point outside of any child control returns the TLW itself",
190 parent->GetLabel(),
191 GetLabelOfWindowAtPoint(parent, 5, 5)
192 );
193
194 wxWindow* btn2 = new TestButton(parent, "2", wxPoint(10, 90));
195 btn2->Disable();
196 CPPUNIT_ASSERT_EQUAL_MESSAGE
197 (
198 "Point over a disabled child control still corresponds to it",
199 btn2->GetLabel(),
200 GetLabelOfWindowAtPoint(parent, 11, 91)
201 );
202
203 btn2->Hide();
204 CPPUNIT_ASSERT_EQUAL_MESSAGE
205 (
206 "Point over a hidden child control doesn't take it into account",
207 parent->GetLabel(),
208 GetLabelOfWindowAtPoint(parent, 11, 91)
209 );
210
211 btn2->Show();
212 wxWindow* btn3 = new TestButton(btn2, "3", wxPoint(0, 0));
213 btn3->Disable();
214 CPPUNIT_ASSERT_EQUAL_MESSAGE
215 (
216 "Point over recursive disabled child controls corresponds to deepest child",
217 btn3->GetLabel(),
218 GetLabelOfWindowAtPoint(parent, 11, 91)
219 );
220
221 wxDELETE(btn1);
222 wxDELETE(btn3); // delete child before parent
223 wxDELETE(btn2);
224 }