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
25using Poco::Util::AbstractConfiguration;
26using Poco::Util::MapConfiguration;
27using Poco::NumberFormatter;
28using Poco::AutoPtr;
29using Poco::Int64;
30using Poco::UInt64;
31
32
33AbstractConfigurationTest::AbstractConfigurationTest(const std::string& name): CppUnit::TestCase(name)
34{
35}
36
37
38AbstractConfigurationTest::~AbstractConfigurationTest()
39{
40}
41
42
43void 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
55void 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
83void 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
108void 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
136void 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
158void 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
187void 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
217void 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
227void 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
240void 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
256void 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
267void 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
278void 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
311void 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
324void 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
358void 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
397AbstractConfiguration::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
448void AbstractConfigurationTest::setUp()
449{
450 _changingKey.clear();
451 _changingValue.clear();
452 _changedKey.clear();
453 _changedValue.clear();
454 _removingKey.clear();
455 _removedKey.clear();
456}
457
458
459void AbstractConfigurationTest::tearDown()
460{
461}
462
463
464void AbstractConfigurationTest::onPropertyChanging(const void*, AbstractConfiguration::KeyValue& kv)
465{
466 _changingKey = kv.key();
467 _changingValue = kv.value();
468}
469
470
471void AbstractConfigurationTest::onPropertyChanged(const void*, const AbstractConfiguration::KeyValue& kv)
472{
473 _changedKey = kv.key();
474 _changedValue = kv.value();
475}
476
477
478void AbstractConfigurationTest::onPropertyRemoving(const void*, const std::string& key)
479{
480 _removingKey = key;
481}
482
483
484void AbstractConfigurationTest::onPropertyRemoved(const void*, const std::string& key)
485{
486 _removedKey = key;
487}
488
489