Files
poco/Util/testsuite/src/AbstractConfigurationTest.cpp
Aleksandar Fabijanic 238306a6ed C++11 support #1793 (#1795)
* * C++14 detection
* C++14 RWLock (disabled: std::shared_timed_mutex has separate read and write unlock)

* * C++11 Event - disable because
std::condition_variable nas no built-in concept of reset
std::condition_variable may be unblocked spuriously, must handle?

* * Fix std::condition_variable handling

* * C++11 semaphore

* * Use Semaphore max paramater

* * Implement manual reset Event and re-enable
* Disable std semaphore, C++ doesn't have native semaphore, better to use native ones for now

* * C++11 Thread (in progress)

* * Fix auto reset event

* * std::*mutex with timeout doesn't guarantee that the timeout will be respected
* Thread in unix has special member for signal handling

* * Workaround for AppleClang lack of thread_local

* * C++11 format

* * C++11 Logger

* * Fix Poco::format

* * std::function event delegate

* * Fix StdFunctionDelegate for GCC

* * C++11 move semantics

* * Fix format test

* * Add cpp11_changes files

* * Auto detect compiler C++11/14 support
* Option to force disable C++11/14

* * GCC/Clang need to enable C++11/14 support via command line switches

* * Fixes for VS2013 C++11 support

* * Makefile C++11/14 compiler detection (in progress)

* * Simple GCC version detection

* AppleClang version detection

* Fix gcc c++11 build script
Update c++11 status document

* Use predefined constant instead of --version

* Fix CC & CXX to gcc 4.8 for all matrix rows.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Restore apt-get update -qq

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Display g++ version and full g++ command line

* Fix typo

* Use command line/environment variables for CC & CXX

* Display GCCVERSION

* Use $(CXX) for setting GCCVERSION

* Do not use <cstdint>, otherwise NumberFormatter wo'nt compile

* restore silent mode on make

* Use predefined constants __clang_major__ and __clang_minor__

* Reverse clang++ options

* Add c++11/14 detection

* -std=c++14 is not valid for clang 3.4

* Run tests for both gcc 4.6 & gcc 4.8

* Restore Apple clang setup

* Align setup of std=c++11 from CLANGVERSION with check of clang version in Platform_POSIX.h

On Linux ubuntu at Travis, clang 3.4 does not support std=c++14

* Add OSX run with clang

* Add forgetted Linux guard on install

* Display clang's predefined constants on OSX

* Comment out Apple temporarly

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* export CC & CXX for OSX

* Test when clang is from Apple

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Remove typo

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Align test with comment

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Add Cygwin-clang

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Install CppUnit for running the unit tests on OSX. 

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Looking for libCppUnit.1.dylib

* Install libCppUnit*.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Exclude Redis for OSX. To be restored later on.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Remove some display lines

* Reenable tests

* Add run tests on cmake build with ctest -VV

* Split runtests.sh into ignored.sh and excluded.sh. ignored.sh will be
used for excluding tests from ctest.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Add ignored.sh to exclude CPPUNIT_IGNORE test on ctest

* Set proper path

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Exclude Data* from CTest. Run tests on ARM

* Add POCO_BASE for tests using test files under $POCO_BASE/component/testsuite

* Replace MB by KB otherwise Travis & AppVeyor are timing out.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Specialize runtests.sh & excluded.sh according to OSX or Linux

* Split OSX/Linux runtests.sh

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Removed invalid comment

* Make runtests.sh executable

* c++11 atomic<> default constructor is never initialized

* Initialize to 0 in any case.

* Comment out set -ev for now

* Comment out set -ev for now

* reset verbose mode

* reset verbose mode

*  catch SIGPIPE as returnfrom testrunner to avoid failure in networking tests

* Use source for export ignored tests to avoid the permission denied problem

* chmod 775

* Apply patches from @RangeIReale

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Add cpp11-appleclang

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Initialize AtomicCounter to 0 since the c++11 default constructor don't
do it.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* avoid SIGPIPE on send

* fix WbeSocketServer

* Remove SIGPIPE workaround

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Fix WebSocketServer

* Restore set -ev

* Restore set -ev

* Fix WebSocketServer responding loop

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Cleanup the exit test.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Add important comment.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Copy also cpp11-* so that mkrelease works!

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Avoid PocoDoc preprocessisng error.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* * Sync script and Platform_POSIX.h compiler versions

* VS2013 & VS2015 fixups.

Signed-off-by: Francis ANDRE <zosrothko@orange.fr>

* Backport to c++03 so that Travis and Appveyor be ok

Signed-off-by: Francis ANDRE <zosrothko@orange.fr>

* Add Copyright (c) 2016, Applied Informatics Software Engineering GmbH.
and Contributors.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* VS2013 fixup

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Backport to c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* VS2013 fixup

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Backport to c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* VS2013 fixup

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* BAckport c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* OSX: clang++ rejects return (*static_cast<Derived*>(this));
cannot cast protected base class 'cpp_ex4::StoplightContext<cpp_ex4::Stoplight>' to 'cpp_ex4::Stoplight'


Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* BAckport to c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Add generated file for now

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* deleted as source file name in lowercase.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Rename stoplight_sm.h to Stoplight_sm.h

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Rename stoplight_sm.h to Stoplight_sm.h

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Rename stoplight_sm.h to Stoplight_sm.h

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Put cmake and ctest on the DOS PATH

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Cygwin does not support timed_mutex

* Put installed CMake /CTest on the DOS PATH.

* Repackaging

* Build VS2013 & VS2014 first.

* Add std::string Foundation_API format(const std::string& fmt, const Any& value);

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Restore INLINES macros when compiling with c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Rename stoplight_sm.h to Stoplight_sm.h

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* VS2013 fixup.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Baclport to c++03

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* cpp_ex4::StoplightContext<cpp_ex4::Stoplight> is an inaccessible base of ˜cpp_ex4::Stoplight

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Undef _XOPEN_SOURCE under Cygwin otherwise ulong is undefined.
usr/include/mysql/my_global.h:997:9: error: 'ulong' does not name a type
 typedef ulong nesting_map;  /* Used for flags of nesting constructs */
         ^
In file included from src/SQLExecutor.cpp:38:0:

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Fix merge failure. Set -ev option on shell.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Removed

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Undefine _XOPEN_SOURCE so that typedef unsigned long ulong be defined.

Signed-off-by: FrancisANDRE <zosrothko@orange.fr>

* Remove __*VISIBLE defines as GNU forbids their usage outside the system includes

Signed-off-by: Francis ANDRE <zosrothko@orange.fr>

* Use c++03 as last c++ version.

Signed-off-by: Francis ANDRE <zosrothko@orange.fr>

* MySQL needs ulong which are not visible when compiling with
c++11 and above.

Signed-off-by: Francis ANDRE <zosrothko@orange.fr>

* Add BUILD_CC=gcc to avoid strip issue

* Remove reference to FSM

* make ?= operator does not work with

* Remove BUILD_CC

* Remove FSM since it is now in its own branch

* Don't build Cygwin64 with std=c++14 until this issue be fixed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77441

* enable c++11

* remove changes tracking file (moved to project)

* C++11: fixes for Travis CI (#1798)

* Use c++11 compliant compiler: g++ 5 & clang 3.5.0

* Fix typo on IntType

* Use Linux-clang config instead of Linux

* Check arm-linux-gnueabi-g++ version. Dump compiler constants

* Fix missing namespace qualifier

* Ignore ltdl for Cygwin platform

* Fix typo

* Commented out arm-linux-gnueabi-g++ since the version 4.7.0 which does
not support c++11 standard.

* Restore logic as in develop branch

* Add CXXFLAGS for launching the CXX compilation. CXXFLAGS defaulted to
-std=c++11

* Replace auto_ptr by unique_ptr

* Comment out failing tests until be fixed

* C++11: Fix AppVeyor CI yaml (#1812)

* C++11 support #1793: It's time. g++4.9, clang3.3 and VS2015 will become
minimum compiler versions.

* Comment out image with VS2017 since it crashes.

* New release of OpenSSL: 1_1_0f

* Refactor the download steps of OpenSSL

* C++11 support: Add VS2017 Win32 & x64 (#1816)

* Add VS2017.

* Use VSSetup to get VS150COMNTOOLS

* Fix VS150COMNTOOLS value

* Ignore Install-Module

* Install VSSetUp PS module.

* Fix typo missing $

* Split InstallPath againt "="

* Adjust VS150COMMONTOOLS path.

* Exit failed is VS commontools is undefined.

* Get the InstalledPath property value

* Replace mysql-5.7.17 by mysql-5.7.18

* Replace mysql-5.7.17 by mysql-5.7.18

* c++11 thread priority and affinity, and more (#1811)

* * c++11 thread priority and affinity
* AtomicCounter wasn't using std::atomic
* Buffer wasn't setting all fields on move
* Poco::Event is not directly available in c++11, keep using the native versions
* UnWindows.h define NOMINMAX to reduce conflicts
* Remove "-static" from Linux GCC parameters, this conflicts with c++11 classes (https://stackoverflow.com/questions/7090623/c0x-thread-static-linking-problem)
* Link "-lrt" before "-lpthread" on Linux, otherwise won't build on GCC 5+

* * Fixed std::thread POSIX handle

* * Fix OSX compilation

* raise cmake min version to 3.2.0

* Remove CMake jobs since it is already tested on Travis (#1832)

* Remove CMake jobs since it is already tested on Travis

* Add clang-3.7

* Ubuntu Trusty LLVM repo for gettign clang versions.

* Remove 3.3 & 3.4

* Add clang 3.8, clang 3.9 & clang 4.0

* Add CXXFLAGS=-stdlib=libc++

* use libstdc++ instead of libc++

* Remove for now -g compiler option to avoid this spurious error on clang
error: debug information for auto is not yet supported

* Use -ftemplate-backtrace-limit=0 to dump the recursive template stack.

* Cleanup

* Use good gcc version

* Fix gcc-5 & g++-5 name

* Use libc++ instead of libstdc++

* Restore installation of gcc-5

* Readd agt-get update for gcc-5/g++-5

* Reswitch from libc++ to libstdc++

* Increase template evaluation stack size up to 340 to avoid a stack
overflow in parsing 
TupleType t = std::make_tuple(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14...

* Add clang 3.4, 3.5, 3.6

* Adjust template evaluation stack for clang  3.4, 3.5, 3.6, 3.7

* Update notifications

* Add gcc-4.9

* Backport Travis CXXFLAGS to config/Linux-clang

* Remove CXXFLAGS from clang tests

* Test g++ first, then clang++ and then arm

* remove all non-c++11 code and POCO_ENABLE_CPP11 (default now)

* remove old file

* windows c++11 fixes

* fix conversion warning

* C++11: Use Mutex_POSIX for Cygwin since it does not support std::timed_mutex (#1864)

* Use Mutex_POSIX for Cygwin since it does not support std::timed_mutex

* Use Mutex_POSIX for Cygwin since it does not support std::timed_mutex

* Add Mutext_POSIX.cpp

* Json/parser (#1858)

* move parser implementation in separate file

* parser replacement, first attempt (wip)

* making tests pass (mostly done, 3 to go)

* add missing headers

* honor no-null-byte-in-string setting

* few more fixes

* add -std=c99

* fix cmake JSON build and formatting

* accept utf-8, fix tests

* skip calling isdigit()

* #740, #1860, license update, a warning fix

* var emtpy()->clear(); json array and object tidy up

* vs 2015 32-bit project update

* update VS2017 projects

* remove ProGen and all VS files older than 2015

* fixed GH #1865: AbstractEvent::hasDelegates() is not thread-safe

* merge develop

* add missing files

* add VS generated dir to gitignore

* add WEC2013.cmake

* fix exception message

* fix VS2017 ODBC project filter

* integrate PageCompiler changes from poco-1.7.9

* vs2015 openssl build

* added POCO_DEPRECATED macro

* added POCO_NO_DEPRECATED to disarm POCO_DEPRECATED macro

* PageCompiler: support <%@ include file="<path>" %> syntax for includes.

* remove '$Id$' headers

* remove '$Id$' headers

* remove old VMS and VxWorks build support

* Poco::NamedMutex and Poco::NamedEvent (System V Semaphores implementation): files are now opened with O_RDONLY | O_CREAT instead of O_WRONLY | O_CREAT, allowing sharing between different users. Furthermore, ftok() is called with 'p' as project ID argument.

* C++11 (#1887)

* Use Mutex_POSIX for Cygwin since it does not support std::timed_mutex

* Use Mutex_POSIX for Cygwin since it does not support std::timed_mutex

* Add Mutext_POSIX.cpp

* Remove clang 3.4, 3.5, 3.6, 3.7, 3.8, 3.9 since LLVM does not provide
anymore their packages for Ubuntu Trusy

* Remove ubuntu-toolchain-r/test/ubuntu since it is already installed

* Comment our the llvl-toolchain-trusty since its checksum is buggy
See https://bugs.llvm.org/show_bug.cgi?id=34572

* Display g++ version (#1889)

* merge change from develop|

* Support for PKCS#12 (#1876)

* rebuild openssl binaries; warning and stlye fixes

* fix vs2015 projects and openssl linking

* add PKCS12Container

* remove comments

* style

* add ECKey* and CryptoException

* EC key, unify RSA and EC under same inheritance, add constructor from PKCS12, couple of EC key tests

* simplify EVPPKey, ad EC tests

* EVPPKey test and fixes

* fix linux build

* PKCS12 tests and fixes

* linux build, fix crash

* fix leaks

* uncomment ifstream tests, some minor fixes

* fix stream tests and some tidy-up

* remove $Id

* add ECDSA

* update makefile

* align PKCS12 constructors signatures with X509

* EVPPKey EC curve name constructor

* ECDSA fixes and tests

* linux build, wrap tests in try/catch to get full exception message

* style

* update VS projects

* remove openssl, modify VS projects for git submodule directories

* add openssl submodule

* add _CRT_SECURE_NO_WARNINGS

* port crypto dev fixes from 1.8

* lock whole Event:set()

* fix openssl include path

* Add <memory> for std::unique_ptr (#1891)

* Missing include <iostream> (#1893)

* add file/stream load/save capabilities to EVPPKey

* add EVPTest

* add #include <typeinfo>

* fix posix compile

* update samples VS projects

* fix g++ test compile error
2017-09-20 22:13:19 -05:00

489 lines
14 KiB
C++

//
// AbstractConfigurationTest.cpp
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "AbstractConfigurationTest.h"
#include "Poco/CppUnit/TestCaller.h"
#include "Poco/Util/MapConfiguration.h"
#include "Poco/AutoPtr.h"
#include "Poco/Exception.h"
#include "Poco/Delegate.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Types.h"
#include <algorithm>
#undef min
#undef max
#include <limits>
using Poco::Util::AbstractConfiguration;
using Poco::Util::MapConfiguration;
using Poco::NumberFormatter;
using Poco::AutoPtr;
using Poco::Int64;
using Poco::UInt64;
AbstractConfigurationTest::AbstractConfigurationTest(const std::string& name): CppUnit::TestCase(name)
{
}
AbstractConfigurationTest::~AbstractConfigurationTest()
{
}
void AbstractConfigurationTest::testHasProperty()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->hasProperty("prop1"));
assert (pConf->hasProperty("prop2"));
assert (pConf->hasProperty("prop3.string1"));
assert (!pConf->hasProperty("prop3.string3"));
assert (!pConf->hasProperty("foobar"));
}
void AbstractConfigurationTest::testGetString()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getString("prop1") == "foo");
assert (pConf->getString("prop2") == "bar");
assert (pConf->getString("prop3.string1") == "foo");
assert (pConf->getString("prop3.string2") == "bar");
assert (pConf->getString("ref1") == "foobar");
assert (pConf->getRawString("ref1") == "${prop3.string1}${prop3.string2}");
try
{
std::string res = pConf->getString("foo");
fail("nonexistent property - must throw");
}
catch (Poco::NotFoundException&)
{
}
assert (pConf->getString("prop1", "FOO") == "foo");
assert (pConf->getString("prop2", "BAR") == "bar");
assert (pConf->getString("prop3.string1", "FOO") == "foo");
assert (pConf->getString("prop3.string2", "BAR") == "bar");
assert (pConf->getString("prop3.string3", "FOOBAR") == "FOOBAR");
}
void AbstractConfigurationTest::testGetInt()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getInt("prop4.int1") == 42);
assert (pConf->getInt("prop4.int2") == -42);
assert (pConf->getInt("prop4.hex") == 0x1f);
assert (pConf->getUInt("prop4.hex") == 0x1f);
assert (pConf->getInt("ref2") == 42);
try
{
pConf->getInt("prop1");
fail("not a number - must throw");
}
catch (Poco::SyntaxException&)
{
}
assert (pConf->getInt("prop4.int1", 100) == 42);
assert (pConf->getInt("prop4.int2", 100) == -42);
assert (pConf->getInt("prop4.int3", 100) == 100);
}
void AbstractConfigurationTest::testGetInt64()
{
#if defined(POCO_HAVE_INT64)
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getInt64("prop4.bigint1") == std::numeric_limits<Int64>::max());
assert (pConf->getInt64("prop4.bigint2") == std::numeric_limits<Int64>::min());
assert (pConf->getUInt64("prop4.biguint") == std::numeric_limits<UInt64>::max());
assert (pConf->getInt64("prop4.hex") == 0x1f);
assert (pConf->getUInt64("prop4.hex") == 0x1f);
assert (pConf->getInt64("ref2") == 42);
try
{
Int64 x = pConf->getInt64("prop1");
fail("not a number - must throw");
}
catch (Poco::SyntaxException&)
{
}
assert (pConf->getInt64("prop4.bigint1", 100) == std::numeric_limits<Int64>::max());
assert (pConf->getInt64("prop4.bigint2", 100) == std::numeric_limits<Int64>::min());
assert (pConf->getUInt64("prop4.biguint", 100) == std::numeric_limits<UInt64>::max());
#endif
}
void AbstractConfigurationTest::testGetDouble()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getDouble("prop4.double1") == 1);
assert (pConf->getDouble("prop4.double2") == -1.5);
try
{
pConf->getDouble("prop1");
fail("not a number - must throw");
}
catch (Poco::SyntaxException&)
{
}
assert (pConf->getDouble("prop4.double1", 123.5) == 1);
assert (pConf->getDouble("prop4.double2", 123.5) == -1.5);
assert (pConf->getDouble("prop4.double3", 123.5) == 123.5);
}
void AbstractConfigurationTest::testGetBool()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getBool("prop4.bool1"));
assert (!pConf->getBool("prop4.bool2"));
assert (pConf->getBool("prop4.bool3"));
assert (!pConf->getBool("prop4.bool4"));
assert (pConf->getBool("prop4.bool5"));
assert (!pConf->getBool("prop4.bool6"));
assert (pConf->getBool("prop4.bool7"));
assert (!pConf->getBool("prop4.bool8"));
try
{
pConf->getBool("prop1");
fail("not a boolean - must throw");
}
catch (Poco::SyntaxException&)
{
}
assert (pConf->getBool("prop4.bool1", false));
assert (!pConf->getBool("prop4.bool2", true));
assert (pConf->getBool("prop4.boolx", true));
assert (!pConf->getBool("prop4.booly", false));
}
void AbstractConfigurationTest::testExpand()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
assert (pConf->getString("ref1") == "foobar");
assert (pConf->getInt("ref2") == 42);
try
{
std::string s = pConf->getString("ref3");
fail("circular reference - must throw");
}
catch (Poco::CircularReferenceException&)
{
}
assert (pConf->getString("ref5") == "${refx}");
assert (pConf->getString("ref6") == "${refx}");
assert (pConf->expand("answer=${prop4.int1}") == "answer=42");
assert (pConf->expand("bool5='${prop4.bool5}'") == "bool5='Yes'");
assert (pConf->expand("undef='${undef}'") == "undef='${undef}'");
assert (pConf->expand("deep='${ref1}'") == "deep='foobar'");
assert (pConf->expand("deep='${ref7}'") == "deep='foobar'");
assert (pConf->getString("dollar.atend") == "foo$");
assert (pConf->getString("dollar.middle") == "foo$bar");
}
void AbstractConfigurationTest::testSetString()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->setString("set.string1", "foobar");
pConf->setString("set.string2", "");
assert (pConf->getString("set.string1") == "foobar");
assert (pConf->getString("set.string2") == "");
}
void AbstractConfigurationTest::testSetInt()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->setInt("set.int1", 42);
pConf->setInt("set.int2", -100);
pConf->setInt("set.uint", 42U);
assert (pConf->getInt("set.int1") == 42);
assert (pConf->getInt("set.int2") == -100);
assert (pConf->getInt("set.uint") == 42U);
}
void AbstractConfigurationTest::testSetInt64()
{
#if defined(POCO_HAVE_INT64)
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->setInt64("set.bigint1", std::numeric_limits<Int64>::max());
pConf->setInt64("set.bigint2", std::numeric_limits<Int64>::min());
pConf->setInt64("set.biguint", std::numeric_limits<UInt64>::max());
assert (pConf->getInt64("set.bigint1") == std::numeric_limits<Int64>::max());
assert (pConf->getInt64("set.bigint2") == std::numeric_limits<Int64>::min());
assert (pConf->getInt64("set.biguint") == std::numeric_limits<UInt64>::max());
#endif //defined(POCO_HAVE_INT64)
}
void AbstractConfigurationTest::testSetDouble()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->setDouble("set.double1", 1.5);
pConf->setDouble("set.double2", -1.5);
assert (pConf->getDouble("set.double1") == 1.5);
assert (pConf->getDouble("set.double2") == -1.5);
}
void AbstractConfigurationTest::testSetBool()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->setBool("set.bool1", true);
pConf->setBool("set.bool2", false);
assert (pConf->getBool("set.bool1"));
assert (!pConf->getBool("set.bool2"));
}
void AbstractConfigurationTest::testChangeEvents()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->propertyChanging += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanging);
pConf->propertyChanged += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanged);
pConf->setString("set.string1", "foobar");
assert (_changingKey == "set.string1");
assert (_changingValue == "foobar");
assert (_changedKey == "set.string1");
assert (_changedValue == "foobar");
pConf->setInt("set.int1", 42);
assert (_changingKey == "set.int1");
assert (_changingValue == "42");
assert (_changedKey == "set.int1");
assert (_changedValue == "42");
pConf->setDouble("set.double1", 1.5);
assert (_changingKey == "set.double1");
assert (_changingValue == "1.5");
assert (_changedKey == "set.double1");
assert (_changedValue == "1.5");
pConf->setBool("set.bool1", true);
assert (_changingKey == "set.bool1");
assert (_changingValue == "true");
assert (_changedKey == "set.bool1");
assert (_changedValue == "true");
}
void AbstractConfigurationTest::testRemoveEvents()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
pConf->propertyRemoving += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoving);
pConf->propertyRemoved += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoved);
pConf->remove("prop4.bool1");
assert (_removingKey == "prop4.bool1");
assert (_removedKey == "prop4.bool1");
}
void AbstractConfigurationTest::testKeys()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
AbstractConfiguration::Keys keys;
pConf->keys(keys);
assert (keys.size() == 13);
assert (std::find(keys.begin(), keys.end(), "prop1") != keys.end());
assert (std::find(keys.begin(), keys.end(), "prop2") != keys.end());
assert (std::find(keys.begin(), keys.end(), "prop3") != keys.end());
assert (std::find(keys.begin(), keys.end(), "prop4") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref1") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref2") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref3") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref4") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref5") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref6") != keys.end());
assert (std::find(keys.begin(), keys.end(), "ref7") != keys.end());
assert (std::find(keys.begin(), keys.end(), "dollar") != keys.end());
pConf->keys("prop1", keys);
assert (keys.empty());
pConf->keys("prop3", keys);
assert (keys.size() == 2);
assert (std::find(keys.begin(), keys.end(), "string1") != keys.end());
assert (std::find(keys.begin(), keys.end(), "string2") != keys.end());
assert (!pConf->hasProperty("nonexistent.sub"));
pConf->keys("nonexistent.sub", keys);
assert (keys.empty());
}
void AbstractConfigurationTest::testRemove()
{
AutoPtr<AbstractConfiguration> pConf = createConfiguration();
AbstractConfiguration::Keys keys;
assert (pConf->hasProperty("prop1"));
assert (pConf->hasProperty("prop4.bool1"));
assert (pConf->hasProperty("prop4.bool2"));
assert (pConf->hasProperty("prop4.bool3"));
pConf->keys(keys);
assert (keys.size() == 13);
pConf->keys("prop4", keys);
assert (keys.size() == 17);
pConf->remove("prop4.bool1");
assert (!pConf->hasProperty("prop4.bool1"));
assert (pConf->hasProperty("prop4.bool2"));
assert (pConf->hasProperty("prop4.bool3"));
pConf->keys(keys);
assert (keys.size() == 13);
pConf->keys("prop4", keys);
assert (keys.size() == 16);
pConf->remove("prop4");
assert (!pConf->hasProperty("prop4.bool1"));
assert (!pConf->hasProperty("prop4.bool2"));
assert (!pConf->hasProperty("prop4.bool3"));
assert (pConf->hasProperty("prop1"));
pConf->keys(keys);
assert (keys.size() == 12);
pConf->keys("prop4", keys);
assert (keys.size() == 0);
assert (!pConf->hasProperty("nonexistent.sub.value"));
pConf->remove("nonexistent.sub.value");
assert (!pConf->hasProperty("nonexistent.sub.value"));
}
Poco::AutoPtr<AbstractConfiguration> AbstractConfigurationTest::createConfiguration() const
{
Poco::AutoPtr<AbstractConfiguration> pConfig = allocConfiguration();
pConfig->setString("prop1", "foo");
pConfig->setString("prop2", "bar");
pConfig->setString("prop3.string1", "foo");
pConfig->setString("prop3.string2", "bar");
pConfig->setString("prop4.int1", "42");
pConfig->setString("prop4.int2", "-42");
pConfig->setString("prop4.uint", NumberFormatter::format(std::numeric_limits<unsigned>::max()));
#if defined(POCO_HAVE_INT64)
pConfig->setString("prop4.bigint1", NumberFormatter::format(std::numeric_limits<Int64>::max()));
pConfig->setString("prop4.bigint2", NumberFormatter::format(std::numeric_limits<Int64>::min()));
pConfig->setString("prop4.biguint", NumberFormatter::format(std::numeric_limits<UInt64>::max()));
#else /// just to make sure property count is consistent
pConfig->setString("prop4.bigint1", 0));
pConfig->setString("prop4.bigint2", 0));
pConfig->setString("prop4.biguint", 0));
#endif
pConfig->setString("prop4.hex", "0x1f");
pConfig->setString("prop4.double1", "1");
pConfig->setString("prop4.double2", "-1.5");
pConfig->setString("prop4.bool1", "1");
pConfig->setString("prop4.bool2", "0");
pConfig->setString("prop4.bool3", "True");
pConfig->setString("prop4.bool4", "FALSE");
pConfig->setString("prop4.bool5", "Yes");
pConfig->setString("prop4.bool6", "no");
pConfig->setString("prop4.bool7", "ON");
pConfig->setString("prop4.bool8", "Off");
pConfig->setString("prop5.string1", "foo");
pConfig->setString("prop5.string2", "bar");
pConfig->setString("prop5.sub1.string1", "FOO");
pConfig->setString("prop5.sub1.string2", "BAR");
pConfig->setString("prop5.sub2.string1", "Foo");
pConfig->setString("prop5.sub2.string2", "Bar");
pConfig->setString("ref1", "${prop3.string1}${prop3.string2}");
pConfig->setString("ref2", "${prop4.int1}");
pConfig->setString("ref3", "${ref4}");
pConfig->setString("ref4", "${ref3}");
pConfig->setString("ref5", "${refx}");
pConfig->setString("ref6", "${refx");
pConfig->setString("ref7", "${ref1}");
pConfig->setString("dollar.atend", "foo$");
pConfig->setString("dollar.middle", "foo$bar");
return pConfig;
}
void AbstractConfigurationTest::setUp()
{
_changingKey.clear();
_changingValue.clear();
_changedKey.clear();
_changedValue.clear();
_removingKey.clear();
_removedKey.clear();
}
void AbstractConfigurationTest::tearDown()
{
}
void AbstractConfigurationTest::onPropertyChanging(const void*, AbstractConfiguration::KeyValue& kv)
{
_changingKey = kv.key();
_changingValue = kv.value();
}
void AbstractConfigurationTest::onPropertyChanged(const void*, const AbstractConfiguration::KeyValue& kv)
{
_changedKey = kv.key();
_changedValue = kv.value();
}
void AbstractConfigurationTest::onPropertyRemoving(const void*, const std::string& key)
{
_removingKey = key;
}
void AbstractConfigurationTest::onPropertyRemoved(const void*, const std::string& key)
{
_removedKey = key;
}