Add support for id ranges to XRC.
[wxWidgets.git] / tests / xml / xrctest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/xml/xrctest.cpp
3 // Purpose: XRC classes unit test
4 // Author: wxWidgets team
5 // Created: 2010-10-30
6 // RCS-ID: $Id$
7 // Copyright: (c) 2010 wxWidgets team
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 #include "wx/wx.h"
22 #endif // WX_PRECOMP
23
24 #include "wx/xml/xml.h"
25 #include "wx/sstream.h"
26 #include "wx/wfstream.h"
27 #include "wx/xrc/xmlres.h"
28
29 #include <stdarg.h>
30
31 // ----------------------------------------------------------------------------
32 // helpers to create/save some xrc
33 // ----------------------------------------------------------------------------
34
35 namespace
36 {
37
38 static const char *TEST_XRC_FILE = "test.xrc";
39
40 // I'm hard-wiring the xrc into this function for now
41 // If different xrcs are wanted for future tests, it'll be easy to refactor
42 void CreateXrc()
43 {
44 const char *xrcText =
45 "<?xml version=\"1.0\" ?>"
46 "<resource>"
47 " <object class=\"wxDialog\" name=\"dialog\">"
48 " <object class=\"wxBoxSizer\">"
49 " <orient>wxVERTICAL</orient>"
50 " <object class=\"sizeritem\">"
51 " <object class=\"wxPanel\" name=\"panel1\">"
52 " <object class=\"wxBoxSizer\">"
53 " <object class=\"sizeritem\">"
54 " <object class=\"wxBoxSizer\">"
55 " <orient>wxVERTICAL</orient>"
56 " <object class=\"sizeritem\">"
57 " <object class=\"wxButton\" name=\"FirstCol[0]\">"
58 " <label>0</label>"
59 " </object>"
60 " </object>"
61 " <object class=\"sizeritem\">"
62 " <object class=\"wxButton\" name=\"FirstCol[1]\">"
63 " <label>1</label>"
64 " </object>"
65 " </object>"
66 " <object class=\"sizeritem\">"
67 " <object class=\"wxButton\" name=\"FirstCol[2]\">"
68 " <label>2</label>"
69 " </object>"
70 " </object>"
71 " <object class=\"sizeritem\">"
72 " <object class=\"wxButton\" name=\"FirstCol[3]\">"
73 " <label>3</label>"
74 " </object>"
75 " </object>"
76 " </object>"
77 " </object>"
78 " <object class=\"sizeritem\">"
79 " <object class=\"wxBoxSizer\">"
80 " <orient>wxVERTICAL</orient>"
81 " <object class=\"sizeritem\">"
82 " <object class=\"wxButton\" name=\"SecondCol[start]\">"
83 " <label>0</label>"
84 " </object>"
85 " </object>"
86 " <object class=\"sizeritem\">"
87 " <object class=\"wxButton\" name=\"SecondCol[1]\">"
88 " <label>1</label>"
89 " </object>"
90 " </object>"
91 " <object class=\"sizeritem\">"
92 " <object class=\"wxButton\" name=\"SecondCol[2]\">"
93 " <label>2</label>"
94 " </object>"
95 " </object>"
96 " <object class=\"sizeritem\">"
97 " <object class=\"wxButton\" name=\"SecondCol[end]\">"
98 " <label>3</label>"
99 " </object>"
100 " </object>"
101 " </object>"
102 " </object>"
103 " <orient>wxHORIZONTAL</orient>"
104 " </object>"
105 " </object>"
106 " </object>"
107 " <object class=\"sizeritem\">"
108 " <object class=\"wxPanel\" name=\"ref_of_panel1\">"
109 " <object_ref ref=\"panel1\"/>"
110 " </object>"
111 " </object>"
112 " </object>"
113 " <title>test</title>"
114 " </object>"
115 " <ids-range name=\"FirstCol\" size=\"2\" start=\"10000\"/>"
116 " <ids-range name=\"SecondCol\" size=\"100\" />"
117 "</resource>"
118 ;
119
120 // afaict there's no elegant way to load xrc direct from a string
121 // So save it as a file, from which it can be loaded
122 wxStringInputStream sis(xrcText);
123 wxFFileOutputStream fos(TEST_XRC_FILE);
124 CPPUNIT_ASSERT(fos.IsOk());
125 fos.Write(sis);
126 CPPUNIT_ASSERT(fos.Close());
127 }
128
129 } // anon namespace
130
131
132 // ----------------------------------------------------------------------------
133 // test class
134 // ----------------------------------------------------------------------------
135
136 class XrcTestCase : public CppUnit::TestCase
137 {
138 public:
139 XrcTestCase() {}
140
141 virtual void setUp() { CreateXrc(); }
142 virtual void tearDown() { wxRemoveFile(TEST_XRC_FILE); }
143
144 private:
145 CPPUNIT_TEST_SUITE( XrcTestCase );
146 CPPUNIT_TEST( ObjectReferences );
147 CPPUNIT_TEST( IDRanges );
148 CPPUNIT_TEST_SUITE_END();
149
150 void ObjectReferences();
151 void IDRanges();
152
153 DECLARE_NO_COPY_CLASS(XrcTestCase)
154 };
155
156 // register in the unnamed registry so that these tests are run by default
157 CPPUNIT_TEST_SUITE_REGISTRATION( XrcTestCase );
158
159 // also include in it's own registry so that these tests can be run alone
160 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XrcTestCase, "XrcTestCase" );
161
162
163
164 void XrcTestCase::ObjectReferences()
165 {
166 wxXmlResource::Get()->InitAllHandlers();
167
168 for ( int n = 0; n < 2; ++n )
169 {
170 // Load the xrc file we're just created
171 CPPUNIT_ASSERT( wxXmlResource::Get()->Load(TEST_XRC_FILE) );
172
173 // In xrc there's now a dialog containing two panels, one an object
174 // reference of the other
175 wxDialog dlg;
176 CPPUNIT_ASSERT( wxXmlResource::Get()->LoadDialog(&dlg, NULL, "dialog") );
177 // Might as well test XRCCTRL too
178 wxPanel* panel1 = XRCCTRL(dlg,"panel1",wxPanel);
179 wxPanel* panel2 = XRCCTRL(dlg,"ref_of_panel1",wxPanel);
180 // Check that the object reference panel is a different object
181 CPPUNIT_ASSERT( panel2 != panel1 );
182
183 // Unload the xrc, so it can be reloaded and the test rerun
184 CPPUNIT_ASSERT( wxXmlResource::Get()->Unload(TEST_XRC_FILE) );
185 }
186 }
187
188 void XrcTestCase::IDRanges()
189 {
190 // Tests ID ranges
191 for ( int n = 0; n < 2; ++n )
192 {
193 // Load the xrc file we're just created
194 CPPUNIT_ASSERT( wxXmlResource::Get()->Load(TEST_XRC_FILE) );
195
196 // foo[start] should == foo[0]
197 CPPUNIT_ASSERT_EQUAL( XRCID("SecondCol[start]"), XRCID("SecondCol[0]") );
198 // foo[start] should be < foo[end]. Usually that means more negative
199 CPPUNIT_ASSERT( XRCID("SecondCol[start]") < XRCID("SecondCol[end]") );
200 // Check it works for the positive values in FirstCol too
201 CPPUNIT_ASSERT( XRCID("FirstCol[start]") < XRCID("FirstCol[end]") );
202
203 // Check that values are adjacent
204 CPPUNIT_ASSERT_EQUAL( XRCID("SecondCol[0]")+1, XRCID("SecondCol[1]") );
205 CPPUNIT_ASSERT_EQUAL( XRCID("SecondCol[1]")+1, XRCID("SecondCol[2]") );
206 // And for the positive range
207 CPPUNIT_ASSERT_EQUAL( XRCID("FirstCol[2]")+1, XRCID("FirstCol[3]") );
208
209 // Check that a large-enough range was created, despite the small
210 // 'size' parameter
211 CPPUNIT_ASSERT_EQUAL
212 (
213 4,
214 XRCID("FirstCol[end]") - XRCID("FirstCol[start]") + 1
215 );
216
217 // Check that the far-too-large size range worked off the scale too
218 CPPUNIT_ASSERT( XRCID("SecondCol[start]") < XRCID("SecondCol[90]") );
219 CPPUNIT_ASSERT( XRCID("SecondCol[90]") < XRCID("SecondCol[end]") );
220 CPPUNIT_ASSERT_EQUAL( XRCID("SecondCol[90]")+1, XRCID("SecondCol[91]") );
221
222 // Check that the positive range-start parameter worked, even after a
223 // reload
224 CPPUNIT_ASSERT_EQUAL( XRCID("FirstCol[start]"), 10000 );
225
226 // Unload the xrc, so it can be reloaded and the tests rerun
227 CPPUNIT_ASSERT( wxXmlResource::Get()->Unload(TEST_XRC_FILE) );
228 }
229 }