1 /*****************************************************************************
2 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
3 * @file
4 * @author Jim E. Brooks http://www.palomino3d.org
5 * @brief Test of ConfBin class.
6 *//*
7 * LEGAL: COPYRIGHT (C) 2004 JIM E. BROOKS
8 * THIS SOURCE CODE IS RELEASED UNDER THE TERMS
9 * OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
10 *****************************************************************************/
11
12 #define TESTING 1
13 #include "test.hh"
14 #include "base/module.hh"
15 #include "base/conf_bin.hh"
16 using namespace base;
17
18 INTERN const char FNAME[] = "/tmp/base_config_file_test.cfg";
19 INTERN const char PROGNAME[] = "test";
20
21 /*****************************************************************************
22 * Test.
23 *****************************************************************************/
24 bool
Test1(void)25 Test1( void )
26 {
27 // ------------------------------------------------------------------------
28 // First series of tests are for when no configuration file exists yet.
29 // ------------------------------------------------------------------------
30
31 unlink( FNAME ); // ensure configuration file doesn't exist
32
33 ConfBin config( PROGNAME, FNAME );
34
35 int right_highscore = 536000;
36 string right_game = "pacman";
37 double right_offset = 1.2345;
38 int highscore;
39 string game;
40 double offset;
41
42 // Test writing.
43 if ( ! config.Write( "highscore", right_highscore ) )
44 {
45 CDEBUG << "FAIL: Write(highscore) \n";
46 return Fail();
47 }
48
49 if ( ! config.Write( "game", right_game ) )
50 {
51 CDEBUG << "FAIL: Write(game) \n";
52 return Fail();
53 }
54
55 if ( ! config.Write( "offset", right_offset ) )
56 {
57 CDEBUG << "FAIL: Write(highscore) \n";
58 return Fail();
59 }
60
61 // Test reading.
62 if ( config.Read( "highscore", highscore ) && highscore == right_highscore )
63 { CDEBUG << "(ok) highscore = " << highscore << std::endl; }
64 else
65 { CDEBUG << "FAIL: Read(highscore)\n"; return Fail(); }
66
67 if ( config.Read( "game", game ) && game == right_game )
68 { CDEBUG << "(ok) game = " << game << std::endl; }
69 else
70 { CDEBUG << "FAIL: Read(game)\n"; return Fail(); }
71
72 if ( config.Read( "offset", offset ) && offset == right_offset )
73 { CDEBUG << "(ok) offset = " << offset << std::endl; }
74 else
75 { CDEBUG << "FAIL: Read(offset)\n"; return Fail(); }
76
77 return true;
78 }
79
80 /*****************************************************************************
81 * Test.
82 *****************************************************************************/
83 bool
Test2(void)84 Test2( void )
85 {
86 // ------------------------------------------------------------------------
87 // Second series of tests are for when a configuration file DOES exist.
88 // ------------------------------------------------------------------------
89
90 ConfBin config( PROGNAME, FNAME );
91
92 int right_highscore = 536000;
93 string right_game = "pacman";
94 double right_offset = 1.2345;
95 int highscore;
96 string game;
97 double offset;
98
99 // Test reading.
100 if ( config.Read( "highscore", highscore ) && highscore == right_highscore )
101 { CDEBUG << "(ok) highscore = " << highscore << std::endl; }
102 else
103 { CDEBUG << "FAIL: Read(highscore)\n"; return Fail(); }
104
105 if ( config.Read( "game", game ) && game == right_game )
106 { CDEBUG << "(ok) game[] = " << game << std::endl; }
107 else
108 { CDEBUG << "FAIL: Read(game)\n"; return Fail(); }
109
110 if ( config.Read( "offset", offset ) && offset == right_offset )
111 { CDEBUG << "(ok) offset = " << offset << std::endl; }
112 else
113 { CDEBUG << "FAIL: Read(offset)\n"; return Fail(); }
114
115 return true;
116 }
117
118 /*****************************************************************************
119 *
120 *****************************************************************************/
121 bool
Test3(void)122 Test3( void )
123 {
124 // ------------------------------------------------------------------------
125 // Test giving different values using the same key/type.
126 // ------------------------------------------------------------------------
127
128 ConfBin config( PROGNAME, FNAME );
129
130 CDEBUG << "Testing changing value of same key..." << std::endl;
131
132 const char key_highscore[] = "highscore_changing";
133 int right_highscore = 1234;
134 int highscore;
135
136 //
137 right_highscore = 0xabcd;
138 if ( ! config.Write( key_highscore, right_highscore ) )
139 {
140 CDEBUG << "FAIL: Write(highscore) \n";
141 return Fail();
142 }
143 if ( ! config.Read( key_highscore, highscore ) || highscore != right_highscore )
144 { CDEBUG << "FAIL: Read(highscore)\n"; return Fail(); }
145
146 //
147 right_highscore = 0;
148 if ( ! config.Write( key_highscore, right_highscore ) )
149 {
150 CDEBUG << "FAIL: Write(highscore) \n";
151 return Fail();
152 }
153 if ( ! config.Read( key_highscore, highscore ) || highscore != right_highscore )
154 { CDEBUG << "FAIL: Read(highscore)"; return Fail(); }
155
156 //
157 right_highscore = 123467;
158 if ( ! config.Write( key_highscore, right_highscore ) )
159 {
160 CDEBUG << "FAIL: Write(highscore) \n";
161 return Fail();
162 }
163 if ( ! config.Read( key_highscore, highscore ) || highscore != right_highscore )
164 { CDEBUG << "FAIL: Read(highscore)\n"; return Fail(); }
165
166 CDEBUG << "ok." << std::endl;
167
168 return true;
169 }
170
171 /*****************************************************************************
172 * Test.
173 *****************************************************************************/
174 bool
Test4(void)175 Test4( void )
176 {
177 // ------------------------------------------------------------------------
178 // Delete test.
179 // ------------------------------------------------------------------------
180
181 ConfBin config( PROGNAME, FNAME );
182
183 // int right_highscore = 536000;
184 string right_game = "pacman";
185 double right_offset = 1.2345;
186 int highscore;
187 string game;
188 double offset;
189
190 // Test deleting
191 if ( config.Remove( "highscore" ) )
192 { CDEBUG << "(ok) deleted highscore \n"; }
193 else
194 { CDEBUG << "FAIL: Remove(highscore)\n"; return Fail(); }
195
196
197 // Test reading.
198 if ( config.Read( "highscore", highscore ) ) // deleted
199 { CDEBUG << "FAIL: highscore should be deleted\n"; return Fail(); }
200
201 if ( config.Read( "game", game ) && game == right_game )
202 { CDEBUG << "(ok) game[] = " << game << std::endl; }
203 else
204 { CDEBUG << "FAIL: Read(game)\n"; return Fail(); }
205
206 if ( config.Read( "offset", offset ) && offset == right_offset )
207 { CDEBUG << "(ok) offset = " << offset << std::endl; }
208 else
209 { CDEBUG << "FAIL: Read(offset)\n"; return Fail(); }
210
211 return true;
212 }
213
214 /*****************************************************************************
215 * Test.
216 *****************************************************************************/
217 bool
Test5(void)218 Test5( void )
219 {
220 // ------------------------------------------------------------------------
221 // Corner cases, bad args.
222 // ------------------------------------------------------------------------
223
224 ConfBin config( PROGNAME, FNAME );
225
226 string s;
227
228 // Test a string containing whitespace.
229 const char ws_key[] = "_key_whitespace";
230 string ws_val = "\tthis string has whitespace\n";
231 config.Write( ws_key, ws_val );
232 if ( config.Read( ws_key, s ) && s == ws_val )
233 { CDEBUG << "(ok) reading string with whitespace" << std::endl; }
234 else
235 { CDEBUG << "FAIL: reading string with whitespace" << std::endl; return Fail(); }
236
237 // Test a empty string value.
238 const char empty_string_key[] = "_key_empty_string";
239 config.Write( empty_string_key, "" );
240 s = "dummy";
241 if ( config.Read( empty_string_key, s ) && s == "" )
242 { CDEBUG << "(ok) reading empty string" << std::endl; }
243 else
244 { CDEBUG << "FAIL: reading empty string" << std::endl; return Fail(); }
245
246 const char key_big[] =
247 "AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCC"
248 "DDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
249 "GGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIII"
250 "KKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMM"
251 "NNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP";
252 string val_string_big =
253 "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"
254 "SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"
255 "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
256 "WWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYY";
257
258 // NULL args aren't tested -- let 'em die.
259 // This won't succeed but it shouldn't cause a crash.
260 string str;
261 config.Write( key_big, val_string_big );
262 if ( config.Read( key_big, str ) )
263 { CDEBUG << "(ok) too big " << str << std::endl; }
264
265 return true;
266 }
267
268 /*****************************************************************************
269 * Test.
270 *****************************************************************************/
271 bool
Test6(void)272 Test6( void )
273 {
274 // ------------------------------------------------------------------------
275 // Test Access() and more interesting keys/values.
276 // ------------------------------------------------------------------------
277
278 ConfBin config( PROGNAME, FNAME );
279
280 int right_int1 = -1;
281 int right_int2 = 0x88889999;
282 int right_int3 = 0;
283 string right_str = "ABCDzxcv123409~!@#$%&*\"*(){}[];',.//<>?";
284 double right_float = 123456.430000;
285
286 int val_int1 = 0xdead;
287 int val_int2 = 0xdead;
288 int val_int3 = 0xdead;
289 string val_str = "";
290 double val_float = 0;
291
292 PERSISTENT const char key_int1[] = "___int1____";
293 PERSISTENT const char key_int2[] = "___int 2____";
294 PERSISTENT const char key_int3[] = "___int3____";
295 PERSISTENT const char key_str[] = "___String____";
296 PERSISTENT const char key_float[] = "___Float#1____";
297
298 int res;
299
300 CDEBUG << "Testing Access()..." << std::endl;
301
302 // Test writing by Access().
303 if ( ! config.Access( ConfBin::eAccess_WRITE, key_int1, right_int1 ) )
304 { CDEBUG << "FAIL: Access(WRITE,int1)\n"; return Fail(); }
305
306 if ( ! config.Access( ConfBin::eAccess_WRITE, key_int2, right_int2 ) )
307 { CDEBUG << "FAIL: Access(WRITE,int2)\n"; return Fail(); }
308
309 if ( ! config.Access( ConfBin::eAccess_WRITE, key_int3, right_int3 ) )
310 { CDEBUG << "FAIL: Access(WRITE,int3)\n"; return Fail(); }
311
312 if ( ! config.Access( ConfBin::eAccess_WRITE, key_str, right_str ) )
313 { CDEBUG << "FAIL: Access(WRITE,str)\n"; return Fail(); }
314
315 if ( ! config.Access( ConfBin::eAccess_WRITE, key_float, right_float ) )
316 { CDEBUG << "FAIL: Access(WRITE,float)\n"; return Fail(); }
317
318 // Test reading by Access().
319 res = config.Access( ConfBin::eAccess_READ, key_int1, val_int1 );
320 if ( ! res || val_int1 != right_int1 )
321 { CDEBUG << "FAIL: Access(WRITE,int1)\n"; return Fail(); }
322
323 res = config.Access( ConfBin::eAccess_READ, key_int2, val_int2 );
324 if ( ! res || val_int2 != right_int2 )
325 { CDEBUG << "FAIL: Access(WRITE,int2)\n"; return Fail(); }
326
327 res = config.Access( ConfBin::eAccess_READ, key_int3, val_int3 );
328 if ( ! res || val_int3 != right_int3 )
329 { CDEBUG << "FAIL: Access(WRITE,int3)\n"; return Fail(); }
330
331 res = config.Access( ConfBin::eAccess_READ, key_str, val_str );
332 if ( ! res || val_str != right_str )
333 { CDEBUG << "FAIL: Access(WRITE,str)\n"; return Fail(); }
334
335 res = config.Access( ConfBin::eAccess_READ, key_float, val_float );
336 if ( ! res || val_float < right_float - 0.2 || val_float > right_float + 0.2 )
337 { CDEBUG << "FAIL: Access(WRITE,float)\n"; return Fail(); }
338
339 CDEBUG << "ok." << std::endl;
340
341 return true;
342 }
343
344 /*****************************************************************************
345 * Test.
346 *****************************************************************************/
347 bool
Test7(void)348 Test7( void )
349 {
350 // ------------------------------------------------------------------------
351 // Corner cases, bad args.
352 // ------------------------------------------------------------------------
353
354 try
355 {
356 int i;
357 CDEBUG << "--- THIS SHOULD PRINT ERRORS due to bad filename ---" << std::endl;
358 ConfBin config( PROGNAME, "/a/b/c/doesnt_exist" );
359 if ( config.IfValid() ) { CDEBUG << "IfValid() is wrong \n"; return Fail(); }
360 if ( config.Write( "abc", (int)123 ) ) { CDEBUG << "Write() is wrong \n"; return Fail(); }
361 if ( config.Read( "abc", i ) ) { CDEBUG << "Read() is wrong \n"; return Fail(); }
362 if ( config.Remove( "abc" ) ) { CDEBUG << "Remove() is wrong \n"; return Fail(); }
363 CDEBUG << "--- ---\n" << std::endl;
364 }
365 catch (...)
366 {
367 return true;
368 }
369 return false;
370 }
371
372 /*****************************************************************************
373 * Called if all other tests passed else no cleanup.
374 *****************************************************************************/
375 bool
Cleanup(void)376 Cleanup( void )
377 {
378 unlink( FNAME );
379 return true;
380 }
381
382 /*****************************************************************************
383 * main.
384 *****************************************************************************/
385 int
main(int argc,char ** argv)386 main( int argc, char** argv )
387 {
388 RUN_TEST( "ConfBin", TEST_ERROR_MODE_CATCH, // this test expects an exception
389 Test1()
390 and Test2()
391 and Test3()
392 and Test4()
393 and Test5()
394 and Test6()
395 and Test7()
396 and Cleanup() )
397 }
398