1 | // |
2 | // AbstractConfigurationTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "AbstractConfigurationTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/Util/MapConfiguration.h" |
14 | #include "Poco/AutoPtr.h" |
15 | #include "Poco/Exception.h" |
16 | #include "Poco/Delegate.h" |
17 | #include "Poco/NumberFormatter.h" |
18 | #include "Poco/Types.h" |
19 | #include <algorithm> |
20 | #undef min |
21 | #undef max |
22 | #include <limits> |
23 | |
24 | |
25 | using Poco::Util::AbstractConfiguration; |
26 | using Poco::Util::MapConfiguration; |
27 | using Poco::NumberFormatter; |
28 | using Poco::AutoPtr; |
29 | using Poco::Int64; |
30 | using Poco::UInt64; |
31 | |
32 | |
33 | AbstractConfigurationTest::AbstractConfigurationTest(const std::string& name): CppUnit::TestCase(name) |
34 | { |
35 | } |
36 | |
37 | |
38 | AbstractConfigurationTest::~AbstractConfigurationTest() |
39 | { |
40 | } |
41 | |
42 | |
43 | void AbstractConfigurationTest::testHasProperty() |
44 | { |
45 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
46 | |
47 | assertTrue (pConf->hasProperty("prop1" )); |
48 | assertTrue (pConf->hasProperty("prop2" )); |
49 | assertTrue (pConf->hasProperty("prop3.string1" )); |
50 | assertTrue (!pConf->hasProperty("prop3.string3" )); |
51 | assertTrue (!pConf->hasProperty("foobar" )); |
52 | } |
53 | |
54 | |
55 | void AbstractConfigurationTest::testGetString() |
56 | { |
57 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
58 | |
59 | assertTrue (pConf->getString("prop1" ) == "foo" ); |
60 | assertTrue (pConf->getString("prop2" ) == "bar" ); |
61 | assertTrue (pConf->getString("prop3.string1" ) == "foo" ); |
62 | assertTrue (pConf->getString("prop3.string2" ) == "bar" ); |
63 | assertTrue (pConf->getString("ref1" ) == "foobar" ); |
64 | assertTrue (pConf->getRawString("ref1" ) == "${prop3.string1}${prop3.string2}" ); |
65 | |
66 | try |
67 | { |
68 | std::string res = pConf->getString("foo" ); |
69 | fail("nonexistent property - must throw" ); |
70 | } |
71 | catch (Poco::NotFoundException&) |
72 | { |
73 | } |
74 | |
75 | assertTrue (pConf->getString("prop1" , "FOO" ) == "foo" ); |
76 | assertTrue (pConf->getString("prop2" , "BAR" ) == "bar" ); |
77 | assertTrue (pConf->getString("prop3.string1" , "FOO" ) == "foo" ); |
78 | assertTrue (pConf->getString("prop3.string2" , "BAR" ) == "bar" ); |
79 | assertTrue (pConf->getString("prop3.string3" , "FOOBAR" ) == "FOOBAR" ); |
80 | } |
81 | |
82 | |
83 | void AbstractConfigurationTest::testGetInt() |
84 | { |
85 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
86 | |
87 | assertTrue (pConf->getInt("prop4.int1" ) == 42); |
88 | assertTrue (pConf->getInt("prop4.int2" ) == -42); |
89 | assertTrue (pConf->getInt("prop4.hex" ) == 0x1f); |
90 | assertTrue (pConf->getUInt("prop4.hex" ) == 0x1f); |
91 | assertTrue (pConf->getInt("ref2" ) == 42); |
92 | |
93 | try |
94 | { |
95 | pConf->getInt("prop1" ); |
96 | fail("not a number - must throw" ); |
97 | } |
98 | catch (Poco::SyntaxException&) |
99 | { |
100 | } |
101 | |
102 | assertTrue (pConf->getInt("prop4.int1" , 100) == 42); |
103 | assertTrue (pConf->getInt("prop4.int2" , 100) == -42); |
104 | assertTrue (pConf->getInt("prop4.int3" , 100) == 100); |
105 | } |
106 | |
107 | |
108 | void AbstractConfigurationTest::testGetInt64() |
109 | { |
110 | #if defined(POCO_HAVE_INT64) |
111 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
112 | |
113 | assertTrue (pConf->getInt64("prop4.bigint1" ) == std::numeric_limits<Int64>::max()); |
114 | assertTrue (pConf->getInt64("prop4.bigint2" ) == std::numeric_limits<Int64>::min()); |
115 | assertTrue (pConf->getUInt64("prop4.biguint" ) == std::numeric_limits<UInt64>::max()); |
116 | assertTrue (pConf->getInt64("prop4.hex" ) == 0x1f); |
117 | assertTrue (pConf->getUInt64("prop4.hex" ) == 0x1f); |
118 | assertTrue (pConf->getInt64("ref2" ) == 42); |
119 | |
120 | try |
121 | { |
122 | POCO_UNUSED Int64 x = pConf->getInt64("prop1" ); |
123 | fail("not a number - must throw" ); |
124 | } |
125 | catch (Poco::SyntaxException&) |
126 | { |
127 | } |
128 | |
129 | assertTrue (pConf->getInt64("prop4.bigint1" , 100) == std::numeric_limits<Int64>::max()); |
130 | assertTrue (pConf->getInt64("prop4.bigint2" , 100) == std::numeric_limits<Int64>::min()); |
131 | assertTrue (pConf->getUInt64("prop4.biguint" , 100) == std::numeric_limits<UInt64>::max()); |
132 | #endif |
133 | } |
134 | |
135 | |
136 | void AbstractConfigurationTest::testGetDouble() |
137 | { |
138 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
139 | |
140 | assertTrue (pConf->getDouble("prop4.double1" ) == 1); |
141 | assertTrue (pConf->getDouble("prop4.double2" ) == -1.5); |
142 | |
143 | try |
144 | { |
145 | pConf->getDouble("prop1" ); |
146 | fail("not a number - must throw" ); |
147 | } |
148 | catch (Poco::SyntaxException&) |
149 | { |
150 | } |
151 | |
152 | assertTrue (pConf->getDouble("prop4.double1" , 123.5) == 1); |
153 | assertTrue (pConf->getDouble("prop4.double2" , 123.5) == -1.5); |
154 | assertTrue (pConf->getDouble("prop4.double3" , 123.5) == 123.5); |
155 | } |
156 | |
157 | |
158 | void AbstractConfigurationTest::testGetBool() |
159 | { |
160 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
161 | |
162 | assertTrue (pConf->getBool("prop4.bool1" )); |
163 | assertTrue (!pConf->getBool("prop4.bool2" )); |
164 | assertTrue (pConf->getBool("prop4.bool3" )); |
165 | assertTrue (!pConf->getBool("prop4.bool4" )); |
166 | assertTrue (pConf->getBool("prop4.bool5" )); |
167 | assertTrue (!pConf->getBool("prop4.bool6" )); |
168 | assertTrue (pConf->getBool("prop4.bool7" )); |
169 | assertTrue (!pConf->getBool("prop4.bool8" )); |
170 | |
171 | try |
172 | { |
173 | pConf->getBool("prop1" ); |
174 | fail("not a boolean - must throw" ); |
175 | } |
176 | catch (Poco::SyntaxException&) |
177 | { |
178 | } |
179 | |
180 | assertTrue (pConf->getBool("prop4.bool1" , false)); |
181 | assertTrue (!pConf->getBool("prop4.bool2" , true)); |
182 | assertTrue (pConf->getBool("prop4.boolx" , true)); |
183 | assertTrue (!pConf->getBool("prop4.booly" , false)); |
184 | } |
185 | |
186 | |
187 | void AbstractConfigurationTest::testExpand() |
188 | { |
189 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
190 | |
191 | assertTrue (pConf->getString("ref1" ) == "foobar" ); |
192 | assertTrue (pConf->getInt("ref2" ) == 42); |
193 | |
194 | try |
195 | { |
196 | std::string s = pConf->getString("ref3" ); |
197 | fail("circular reference - must throw" ); |
198 | } |
199 | catch (Poco::CircularReferenceException&) |
200 | { |
201 | } |
202 | |
203 | assertTrue (pConf->getString("ref5" ) == "${refx}" ); |
204 | assertTrue (pConf->getString("ref6" ) == "${refx}" ); |
205 | |
206 | assertTrue (pConf->expand("answer=${prop4.int1}" ) == "answer=42" ); |
207 | assertTrue (pConf->expand("bool5='${prop4.bool5}'" ) == "bool5='Yes'" ); |
208 | assertTrue (pConf->expand("undef='${undef}'" ) == "undef='${undef}'" ); |
209 | assertTrue (pConf->expand("deep='${ref1}'" ) == "deep='foobar'" ); |
210 | assertTrue (pConf->expand("deep='${ref7}'" ) == "deep='foobar'" ); |
211 | |
212 | assertTrue (pConf->getString("dollar.atend" ) == "foo$" ); |
213 | assertTrue (pConf->getString("dollar.middle" ) == "foo$bar" ); |
214 | } |
215 | |
216 | |
217 | void AbstractConfigurationTest::testSetString() |
218 | { |
219 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
220 | |
221 | pConf->setString("set.string1" , "foobar" ); |
222 | pConf->setString("set.string2" , "" ); |
223 | assertTrue (pConf->getString("set.string1" ) == "foobar" ); |
224 | assertTrue (pConf->getString("set.string2" ) == "" ); |
225 | } |
226 | |
227 | void AbstractConfigurationTest::testSetInt() |
228 | { |
229 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
230 | |
231 | pConf->setInt("set.int1" , 42); |
232 | pConf->setInt("set.int2" , -100); |
233 | pConf->setInt("set.uint" , 42U); |
234 | assertTrue (pConf->getInt("set.int1" ) == 42); |
235 | assertTrue (pConf->getInt("set.int2" ) == -100); |
236 | assertTrue (pConf->getInt("set.uint" ) == 42U); |
237 | } |
238 | |
239 | |
240 | void AbstractConfigurationTest::testSetInt64() |
241 | { |
242 | #if defined(POCO_HAVE_INT64) |
243 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
244 | |
245 | pConf->setInt64("set.bigint1" , std::numeric_limits<Int64>::max()); |
246 | pConf->setInt64("set.bigint2" , std::numeric_limits<Int64>::min()); |
247 | pConf->setInt64("set.biguint" , std::numeric_limits<UInt64>::max()); |
248 | |
249 | assertTrue (pConf->getInt64("set.bigint1" ) == std::numeric_limits<Int64>::max()); |
250 | assertTrue (pConf->getInt64("set.bigint2" ) == std::numeric_limits<Int64>::min()); |
251 | assertTrue (pConf->getInt64("set.biguint" ) == std::numeric_limits<UInt64>::max()); |
252 | #endif //defined(POCO_HAVE_INT64) |
253 | } |
254 | |
255 | |
256 | void AbstractConfigurationTest::testSetDouble() |
257 | { |
258 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
259 | |
260 | pConf->setDouble("set.double1" , 1.5); |
261 | pConf->setDouble("set.double2" , -1.5); |
262 | assertTrue (pConf->getDouble("set.double1" ) == 1.5); |
263 | assertTrue (pConf->getDouble("set.double2" ) == -1.5); |
264 | } |
265 | |
266 | |
267 | void AbstractConfigurationTest::testSetBool() |
268 | { |
269 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
270 | |
271 | pConf->setBool("set.bool1" , true); |
272 | pConf->setBool("set.bool2" , false); |
273 | assertTrue (pConf->getBool("set.bool1" )); |
274 | assertTrue (!pConf->getBool("set.bool2" )); |
275 | } |
276 | |
277 | |
278 | void AbstractConfigurationTest::testChangeEvents() |
279 | { |
280 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
281 | |
282 | pConf->propertyChanging += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanging); |
283 | pConf->propertyChanged += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanged); |
284 | |
285 | pConf->setString("set.string1" , "foobar" ); |
286 | assertTrue (_changingKey == "set.string1" ); |
287 | assertTrue (_changingValue == "foobar" ); |
288 | assertTrue (_changedKey == "set.string1" ); |
289 | assertTrue (_changedValue == "foobar" ); |
290 | |
291 | pConf->setInt("set.int1" , 42); |
292 | assertTrue (_changingKey == "set.int1" ); |
293 | assertTrue (_changingValue == "42" ); |
294 | assertTrue (_changedKey == "set.int1" ); |
295 | assertTrue (_changedValue == "42" ); |
296 | |
297 | pConf->setDouble("set.double1" , 1.5); |
298 | assertTrue (_changingKey == "set.double1" ); |
299 | assertTrue (_changingValue == "1.5" ); |
300 | assertTrue (_changedKey == "set.double1" ); |
301 | assertTrue (_changedValue == "1.5" ); |
302 | |
303 | pConf->setBool("set.bool1" , true); |
304 | assertTrue (_changingKey == "set.bool1" ); |
305 | assertTrue (_changingValue == "true" ); |
306 | assertTrue (_changedKey == "set.bool1" ); |
307 | assertTrue (_changedValue == "true" ); |
308 | } |
309 | |
310 | |
311 | void AbstractConfigurationTest::testRemoveEvents() |
312 | { |
313 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
314 | |
315 | pConf->propertyRemoving += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoving); |
316 | pConf->propertyRemoved += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoved); |
317 | |
318 | pConf->remove("prop4.bool1" ); |
319 | assertTrue (_removingKey == "prop4.bool1" ); |
320 | assertTrue (_removedKey == "prop4.bool1" ); |
321 | } |
322 | |
323 | |
324 | void AbstractConfigurationTest::testKeys() |
325 | { |
326 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
327 | |
328 | AbstractConfiguration::Keys keys; |
329 | pConf->keys(keys); |
330 | assertTrue (keys.size() == 13); |
331 | assertTrue (std::find(keys.begin(), keys.end(), "prop1" ) != keys.end()); |
332 | assertTrue (std::find(keys.begin(), keys.end(), "prop2" ) != keys.end()); |
333 | assertTrue (std::find(keys.begin(), keys.end(), "prop3" ) != keys.end()); |
334 | assertTrue (std::find(keys.begin(), keys.end(), "prop4" ) != keys.end()); |
335 | assertTrue (std::find(keys.begin(), keys.end(), "ref1" ) != keys.end()); |
336 | assertTrue (std::find(keys.begin(), keys.end(), "ref2" ) != keys.end()); |
337 | assertTrue (std::find(keys.begin(), keys.end(), "ref3" ) != keys.end()); |
338 | assertTrue (std::find(keys.begin(), keys.end(), "ref4" ) != keys.end()); |
339 | assertTrue (std::find(keys.begin(), keys.end(), "ref5" ) != keys.end()); |
340 | assertTrue (std::find(keys.begin(), keys.end(), "ref6" ) != keys.end()); |
341 | assertTrue (std::find(keys.begin(), keys.end(), "ref7" ) != keys.end()); |
342 | assertTrue (std::find(keys.begin(), keys.end(), "dollar" ) != keys.end()); |
343 | |
344 | pConf->keys("prop1" , keys); |
345 | assertTrue (keys.empty()); |
346 | |
347 | pConf->keys("prop3" , keys); |
348 | assertTrue (keys.size() == 2); |
349 | assertTrue (std::find(keys.begin(), keys.end(), "string1" ) != keys.end()); |
350 | assertTrue (std::find(keys.begin(), keys.end(), "string2" ) != keys.end()); |
351 | |
352 | assertTrue (!pConf->hasProperty("nonexistent.sub" )); |
353 | pConf->keys("nonexistent.sub" , keys); |
354 | assertTrue (keys.empty()); |
355 | } |
356 | |
357 | |
358 | void AbstractConfigurationTest::testRemove() |
359 | { |
360 | AutoPtr<AbstractConfiguration> pConf = createConfiguration(); |
361 | AbstractConfiguration::Keys keys; |
362 | |
363 | assertTrue (pConf->hasProperty("prop1" )); |
364 | assertTrue (pConf->hasProperty("prop4.bool1" )); |
365 | assertTrue (pConf->hasProperty("prop4.bool2" )); |
366 | assertTrue (pConf->hasProperty("prop4.bool3" )); |
367 | pConf->keys(keys); |
368 | assertTrue (keys.size() == 13); |
369 | pConf->keys("prop4" , keys); |
370 | assertTrue (keys.size() == 17); |
371 | |
372 | pConf->remove("prop4.bool1" ); |
373 | assertTrue (!pConf->hasProperty("prop4.bool1" )); |
374 | assertTrue (pConf->hasProperty("prop4.bool2" )); |
375 | assertTrue (pConf->hasProperty("prop4.bool3" )); |
376 | pConf->keys(keys); |
377 | assertTrue (keys.size() == 13); |
378 | pConf->keys("prop4" , keys); |
379 | assertTrue (keys.size() == 16); |
380 | |
381 | pConf->remove("prop4" ); |
382 | assertTrue (!pConf->hasProperty("prop4.bool1" )); |
383 | assertTrue (!pConf->hasProperty("prop4.bool2" )); |
384 | assertTrue (!pConf->hasProperty("prop4.bool3" )); |
385 | assertTrue (pConf->hasProperty("prop1" )); |
386 | pConf->keys(keys); |
387 | assertTrue (keys.size() == 12); |
388 | pConf->keys("prop4" , keys); |
389 | assertTrue (keys.size() == 0); |
390 | |
391 | assertTrue (!pConf->hasProperty("nonexistent.sub.value" )); |
392 | pConf->remove("nonexistent.sub.value" ); |
393 | assertTrue (!pConf->hasProperty("nonexistent.sub.value" )); |
394 | } |
395 | |
396 | |
397 | AbstractConfiguration::Ptr AbstractConfigurationTest::createConfiguration() const |
398 | { |
399 | AbstractConfiguration::Ptr pConfig = allocConfiguration(); |
400 | |
401 | pConfig->setString("prop1" , "foo" ); |
402 | pConfig->setString("prop2" , "bar" ); |
403 | pConfig->setString("prop3.string1" , "foo" ); |
404 | pConfig->setString("prop3.string2" , "bar" ); |
405 | pConfig->setString("prop4.int1" , "42" ); |
406 | pConfig->setString("prop4.int2" , "-42" ); |
407 | pConfig->setString("prop4.uint" , NumberFormatter::format(std::numeric_limits<unsigned>::max())); |
408 | #if defined(POCO_HAVE_INT64) |
409 | pConfig->setString("prop4.bigint1" , NumberFormatter::format(std::numeric_limits<Int64>::max())); |
410 | pConfig->setString("prop4.bigint2" , NumberFormatter::format(std::numeric_limits<Int64>::min())); |
411 | pConfig->setString("prop4.biguint" , NumberFormatter::format(std::numeric_limits<UInt64>::max())); |
412 | #else /// just to make sure property count is consistent |
413 | pConfig->setString("prop4.bigint1" , 0); |
414 | pConfig->setString("prop4.bigint2" , 0); |
415 | pConfig->setString("prop4.biguint" , 0); |
416 | #endif |
417 | pConfig->setString("prop4.hex" , "0x1f" ); |
418 | pConfig->setString("prop4.double1" , "1" ); |
419 | pConfig->setString("prop4.double2" , "-1.5" ); |
420 | pConfig->setString("prop4.bool1" , "1" ); |
421 | pConfig->setString("prop4.bool2" , "0" ); |
422 | pConfig->setString("prop4.bool3" , "True" ); |
423 | pConfig->setString("prop4.bool4" , "FALSE" ); |
424 | pConfig->setString("prop4.bool5" , "Yes" ); |
425 | pConfig->setString("prop4.bool6" , "no" ); |
426 | pConfig->setString("prop4.bool7" , "ON" ); |
427 | pConfig->setString("prop4.bool8" , "Off" ); |
428 | pConfig->setString("prop5.string1" , "foo" ); |
429 | pConfig->setString("prop5.string2" , "bar" ); |
430 | pConfig->setString("prop5.sub1.string1" , "FOO" ); |
431 | pConfig->setString("prop5.sub1.string2" , "BAR" ); |
432 | pConfig->setString("prop5.sub2.string1" , "Foo" ); |
433 | pConfig->setString("prop5.sub2.string2" , "Bar" ); |
434 | pConfig->setString("ref1" , "${prop3.string1}${prop3.string2}" ); |
435 | pConfig->setString("ref2" , "${prop4.int1}" ); |
436 | pConfig->setString("ref3" , "${ref4}" ); |
437 | pConfig->setString("ref4" , "${ref3}" ); |
438 | pConfig->setString("ref5" , "${refx}" ); |
439 | pConfig->setString("ref6" , "${refx" ); |
440 | pConfig->setString("ref7" , "${ref1}" ); |
441 | pConfig->setString("dollar.atend" , "foo$" ); |
442 | pConfig->setString("dollar.middle" , "foo$bar" ); |
443 | |
444 | return pConfig; |
445 | } |
446 | |
447 | |
448 | void AbstractConfigurationTest::setUp() |
449 | { |
450 | _changingKey.clear(); |
451 | _changingValue.clear(); |
452 | _changedKey.clear(); |
453 | _changedValue.clear(); |
454 | _removingKey.clear(); |
455 | _removedKey.clear(); |
456 | } |
457 | |
458 | |
459 | void AbstractConfigurationTest::tearDown() |
460 | { |
461 | } |
462 | |
463 | |
464 | void AbstractConfigurationTest::onPropertyChanging(const void*, AbstractConfiguration::KeyValue& kv) |
465 | { |
466 | _changingKey = kv.key(); |
467 | _changingValue = kv.value(); |
468 | } |
469 | |
470 | |
471 | void AbstractConfigurationTest::onPropertyChanged(const void*, const AbstractConfiguration::KeyValue& kv) |
472 | { |
473 | _changedKey = kv.key(); |
474 | _changedValue = kv.value(); |
475 | } |
476 | |
477 | |
478 | void AbstractConfigurationTest::onPropertyRemoving(const void*, const std::string& key) |
479 | { |
480 | _removingKey = key; |
481 | } |
482 | |
483 | |
484 | void AbstractConfigurationTest::onPropertyRemoved(const void*, const std::string& key) |
485 | { |
486 | _removedKey = key; |
487 | } |
488 | |
489 | |