diff options
Diffstat (limited to 'lib/jsoncpp/src/test_lib_json')
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/jsontest.cpp | 598 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/jsontest.h | 252 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/main.cpp | 244 | ||||
-rw-r--r-- | lib/jsoncpp/src/test_lib_json/sconscript | 10 |
4 files changed, 1104 insertions, 0 deletions
diff --git a/lib/jsoncpp/src/test_lib_json/jsontest.cpp b/lib/jsoncpp/src/test_lib_json/jsontest.cpp new file mode 100644 index 0000000000..dfd2b5c77d --- /dev/null +++ b/lib/jsoncpp/src/test_lib_json/jsontest.cpp @@ -0,0 +1,598 @@ +#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC +#include "jsontest.h" +#include <stdio.h> +#include <string> + +#if defined(_MSC_VER) +// Used to install a report hook that prevent dialog on assertion and error. +# include <crtdbg.h> +#endif // if defined(_MSC_VER) + +#if defined(_WIN32) +// Used to prevent dialog on memory fault. +// Limits headers included by Windows.h +# define WIN32_LEAN_AND_MEAN +# define NOSERVICE +# define NOMCX +# define NOIME +# define NOSOUND +# define NOCOMM +# define NORPC +# define NOGDI +# define NOUSER +# define NODRIVERS +# define NOLOGERROR +# define NOPROFILER +# define NOMEMMGR +# define NOLFILEIO +# define NOOPENFILE +# define NORESOURCE +# define NOATOM +# define NOLANGUAGE +# define NOLSTRING +# define NODBCS +# define NOKEYBOARDINFO +# define NOGDICAPMASKS +# define NOCOLOR +# define NOGDIOBJ +# define NODRAWTEXT +# define NOTEXTMETRIC +# define NOSCALABLEFONT +# define NOBITMAP +# define NORASTEROPS +# define NOMETAFILE +# define NOSYSMETRICS +# define NOSYSTEMPARAMSINFO +# define NOMSG +# define NOWINSTYLES +# define NOWINOFFSETS +# define NOSHOWWINDOW +# define NODEFERWINDOWPOS +# define NOVIRTUALKEYCODES +# define NOKEYSTATES +# define NOWH +# define NOMENUS +# define NOSCROLL +# define NOCLIPBOARD +# define NOICONS +# define NOMB +# define NOSYSCOMMANDS +# define NOMDI +# define NOCTLMGR +# define NOWINMESSAGES +# include <windows.h> +#endif // if defined(_WIN32) + +namespace JsonTest { + + +// class TestResult +// ////////////////////////////////////////////////////////////////// + +TestResult::TestResult() + : predicateId_( 1 ) + , lastUsedPredicateId_( 0 ) + , messageTarget_( 0 ) +{ + // The root predicate has id 0 + rootPredicateNode_.id_ = 0; + rootPredicateNode_.next_ = 0; + predicateStackTail_ = &rootPredicateNode_; +} + + +void +TestResult::setTestName( const std::string &name ) +{ + name_ = name; +} + +TestResult & +TestResult::addFailure( const char *file, unsigned int line, + const char *expr ) +{ + /// Walks the PredicateContext stack adding them to failures_ if not already added. + unsigned int nestingLevel = 0; + PredicateContext *lastNode = rootPredicateNode_.next_; + for ( ; lastNode != 0; lastNode = lastNode->next_ ) + { + if ( lastNode->id_ > lastUsedPredicateId_ ) // new PredicateContext + { + lastUsedPredicateId_ = lastNode->id_; + addFailureInfo( lastNode->file_, lastNode->line_, lastNode->expr_, + nestingLevel ); + // Link the PredicateContext to the failure for message target when + // popping the PredicateContext. + lastNode->failure_ = &( failures_.back() ); + } + ++nestingLevel; + } + + // Adds the failed assertion + addFailureInfo( file, line, expr, nestingLevel ); + messageTarget_ = &( failures_.back() ); + return *this; +} + + +void +TestResult::addFailureInfo( const char *file, unsigned int line, + const char *expr, unsigned int nestingLevel ) +{ + Failure failure; + failure.file_ = file; + failure.line_ = line; + if ( expr ) + { + failure.expr_ = expr; + } + failure.nestingLevel_ = nestingLevel; + failures_.push_back( failure ); +} + + +TestResult & +TestResult::popPredicateContext() +{ + PredicateContext *lastNode = &rootPredicateNode_; + while ( lastNode->next_ != 0 && lastNode->next_->next_ != 0 ) + { + lastNode = lastNode->next_; + } + // Set message target to popped failure + PredicateContext *tail = lastNode->next_; + if ( tail != 0 && tail->failure_ != 0 ) + { + messageTarget_ = tail->failure_; + } + // Remove tail from list + predicateStackTail_ = lastNode; + lastNode->next_ = 0; + return *this; +} + + +bool +TestResult::failed() const +{ + return !failures_.empty(); +} + + +unsigned int +TestResult::getAssertionNestingLevel() const +{ + unsigned int level = 0; + const PredicateContext *lastNode = &rootPredicateNode_; + while ( lastNode->next_ != 0 ) + { + lastNode = lastNode->next_; + ++level; + } + return level; +} + + +void +TestResult::printFailure( bool printTestName ) const +{ + if ( failures_.empty() ) + { + return; + } + + if ( printTestName ) + { + printf( "* Detail of %s test failure:\n", name_.c_str() ); + } + + // Print in reverse to display the callstack in the right order + Failures::const_iterator itEnd = failures_.end(); + for ( Failures::const_iterator it = failures_.begin(); it != itEnd; ++it ) + { + const Failure &failure = *it; + std::string indent( failure.nestingLevel_ * 2, ' ' ); + if ( failure.file_ ) + { + printf( "%s%s(%d): ", indent.c_str(), failure.file_, failure.line_ ); + } + if ( !failure.expr_.empty() ) + { + printf( "%s\n", failure.expr_.c_str() ); + } + else if ( failure.file_ ) + { + printf( "\n" ); + } + if ( !failure.message_.empty() ) + { + std::string reindented = indentText( failure.message_, indent + " " ); + printf( "%s\n", reindented.c_str() ); + } + } +} + + +std::string +TestResult::indentText( const std::string &text, + const std::string &indent ) +{ + std::string reindented; + std::string::size_type lastIndex = 0; + while ( lastIndex < text.size() ) + { + std::string::size_type nextIndex = text.find( '\n', lastIndex ); + if ( nextIndex == std::string::npos ) + { + nextIndex = text.size() - 1; + } + reindented += indent; + reindented += text.substr( lastIndex, nextIndex - lastIndex + 1 ); + lastIndex = nextIndex + 1; + } + return reindented; +} + + +TestResult & +TestResult::addToLastFailure( const std::string &message ) +{ + if ( messageTarget_ != 0 ) + { + messageTarget_->message_ += message; + } + return *this; +} + + +TestResult & +TestResult::operator << ( bool value ) +{ + return addToLastFailure( value ? "true" : "false" ); +} + + +TestResult & +TestResult::operator << ( int value ) +{ + char buffer[32]; + sprintf( buffer, "%d", value ); + return addToLastFailure( buffer ); +} + + +TestResult & +TestResult::operator << ( unsigned int value ) +{ + char buffer[32]; + sprintf( buffer, "%u", value ); + return addToLastFailure( buffer ); +} + + +TestResult & +TestResult::operator << ( double value ) +{ + char buffer[32]; + sprintf( buffer, "%16g", value ); + return addToLastFailure( buffer ); +} + + +TestResult & +TestResult::operator << ( const char *value ) +{ + return addToLastFailure( value ? value + : "<NULL>" ); +} + + +TestResult & +TestResult::operator << ( const std::string &value ) +{ + return addToLastFailure( value ); +} + + + +// class TestCase +// ////////////////////////////////////////////////////////////////// + +TestCase::TestCase() + : result_( 0 ) +{ +} + + +void +TestCase::run( TestResult &result ) +{ + result_ = &result; + runTestCase(); +} + + + +// class Runner +// ////////////////////////////////////////////////////////////////// + +Runner::Runner() +{ +} + + +Runner & +Runner::add( TestCaseFactory factory ) +{ + tests_.push_back( factory ); + return *this; +} + + +unsigned int +Runner::testCount() const +{ + return static_cast<unsigned int>( tests_.size() ); +} + + +std::string +Runner::testNameAt( unsigned int index ) const +{ + TestCase *test = tests_[index](); + std::string name = test->testName(); + delete test; + return name; +} + + +void +Runner::runTestAt( unsigned int index, TestResult &result ) const +{ + TestCase *test = tests_[index](); + result.setTestName( test->testName() ); + printf( "Testing %s: ", test->testName() ); + fflush( stdout ); +#if JSON_USE_EXCEPTION + try + { +#endif // if JSON_USE_EXCEPTION + test->run( result ); +#if JSON_USE_EXCEPTION + } + catch ( const std::exception &e ) + { + result.addFailure( __FILE__, __LINE__, + "Unexpected exception caugth:" ) << e.what(); + } +#endif // if JSON_USE_EXCEPTION + delete test; + const char *status = result.failed() ? "FAILED" + : "OK"; + printf( "%s\n", status ); + fflush( stdout ); +} + + +bool +Runner::runAllTest( bool printSummary ) const +{ + unsigned int count = testCount(); + std::deque<TestResult> failures; + for ( unsigned int index = 0; index < count; ++index ) + { + TestResult result; + runTestAt( index, result ); + if ( result.failed() ) + { + failures.push_back( result ); + } + } + + if ( failures.empty() ) + { + if ( printSummary ) + { + printf( "All %d tests passed\n", count ); + } + return true; + } + else + { + for ( unsigned int index = 0; index < failures.size(); ++index ) + { + TestResult &result = failures[index]; + result.printFailure( count > 1 ); + } + + if ( printSummary ) + { + unsigned int failedCount = static_cast<unsigned int>( failures.size() ); + unsigned int passedCount = count - failedCount; + printf( "%d/%d tests passed (%d failure(s))\n", passedCount, count, failedCount ); + } + return false; + } +} + + +bool +Runner::testIndex( const std::string &testName, + unsigned int &indexOut ) const +{ + unsigned int count = testCount(); + for ( unsigned int index = 0; index < count; ++index ) + { + if ( testNameAt(index) == testName ) + { + indexOut = index; + return true; + } + } + return false; +} + + +void +Runner::listTests() const +{ + unsigned int count = testCount(); + for ( unsigned int index = 0; index < count; ++index ) + { + printf( "%s\n", testNameAt( index ).c_str() ); + } +} + + +int +Runner::runCommandLine( int argc, const char *argv[] ) const +{ + typedef std::deque<std::string> TestNames; + Runner subrunner; + for ( int index = 1; index < argc; ++index ) + { + std::string opt = argv[index]; + if ( opt == "--list-tests" ) + { + listTests(); + return 0; + } + else if ( opt == "--test-auto" ) + { + preventDialogOnCrash(); + } + else if ( opt == "--test" ) + { + ++index; + if ( index < argc ) + { + unsigned int testNameIndex; + if ( testIndex( argv[index], testNameIndex ) ) + { + subrunner.add( tests_[testNameIndex] ); + } + else + { + fprintf( stderr, "Test '%s' does not exist!\n", argv[index] ); + return 2; + } + } + else + { + printUsage( argv[0] ); + return 2; + } + } + else + { + printUsage( argv[0] ); + return 2; + } + } + bool succeeded; + if ( subrunner.testCount() > 0 ) + { + succeeded = subrunner.runAllTest( subrunner.testCount() > 1 ); + } + else + { + succeeded = runAllTest( true ); + } + return succeeded ? 0 + : 1; +} + + +#if defined(_MSC_VER) +// Hook MSVCRT assertions to prevent dialog from appearing +static int +msvcrtSilentReportHook( int reportType, char *message, int *returnValue ) +{ + // The default CRT handling of error and assertion is to display + // an error dialog to the user. + // Instead, when an error or an assertion occurs, we force the + // application to terminate using abort() after display + // the message on stderr. + if ( reportType == _CRT_ERROR || + reportType == _CRT_ASSERT ) + { + // calling abort() cause the ReportHook to be called + // The following is used to detect this case and let's the + // error handler fallback on its default behaviour ( + // display a warning message) + static volatile bool isAborting = false; + if ( isAborting ) + { + return TRUE; + } + isAborting = true; + + fprintf( stderr, "CRT Error/Assert:\n%s\n", message ); + fflush( stderr ); + abort(); + } + // Let's other reportType (_CRT_WARNING) be handled as they would by default + return FALSE; +} +#endif // if defined(_MSC_VER) + + +void +Runner::preventDialogOnCrash() +{ +#if defined(_MSC_VER) + // Install a hook to prevent MSVCRT error and assertion from + // popping a dialog. + _CrtSetReportHook( &msvcrtSilentReportHook ); +#endif // if defined(_MSC_VER) + + // @todo investiguate this handler (for buffer overflow) + // _set_security_error_handler + +#if defined(_WIN32) + // Prevents the system from popping a dialog for debugging if the + // application fails due to invalid memory access. + SetErrorMode( SEM_FAILCRITICALERRORS + | SEM_NOGPFAULTERRORBOX + | SEM_NOOPENFILEERRORBOX ); +#endif // if defined(_WIN32) +} + +void +Runner::printUsage( const char *appName ) +{ + printf( + "Usage: %s [options]\n" + "\n" + "If --test is not specified, then all the test cases be run.\n" + "\n" + "Valid options:\n" + "--list-tests: print the name of all test cases on the standard\n" + " output and exit.\n" + "--test TESTNAME: executes the test case with the specified name.\n" + " May be repeated.\n" + "--test-auto: prevent dialog prompting for debugging on crash.\n" + , appName ); +} + + + +// Assertion functions +// ////////////////////////////////////////////////////////////////// + +TestResult & +checkStringEqual( TestResult &result, + const std::string &expected, const std::string &actual, + const char *file, unsigned int line, const char *expr ) +{ + if ( expected != actual ) + { + result.addFailure( file, line, expr ); + result << "Expected: '" << expected << "'\n"; + result << "Actual : '" << actual << "'"; + } + return result; +} + + +} // namespace JsonTest diff --git a/lib/jsoncpp/src/test_lib_json/jsontest.h b/lib/jsoncpp/src/test_lib_json/jsontest.h new file mode 100644 index 0000000000..b2553baea1 --- /dev/null +++ b/lib/jsoncpp/src/test_lib_json/jsontest.h @@ -0,0 +1,252 @@ +#ifndef JSONTEST_H_INCLUDED +# define JSONTEST_H_INCLUDED + +# include <json/config.h> +# include <stdio.h> +# include <deque> +# include <string> + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// Mini Unit Testing framework +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + + + +/** \brief Unit testing framework. + * \warning: all assertions are non-aborting, test case execution will continue + * even if an assertion namespace. + * This constraint is for portability: the framework needs to compile + * on Visual Studio 6 and must not require exception usage. + */ +namespace JsonTest { + + + class Failure + { + public: + const char *file_; + unsigned int line_; + std::string expr_; + std::string message_; + unsigned int nestingLevel_; + }; + + + /// Context used to create the assertion callstack on failure. + /// Must be a POD to allow inline initialisation without stepping + /// into the debugger. + struct PredicateContext + { + typedef unsigned int Id; + Id id_; + const char *file_; + unsigned int line_; + const char *expr_; + PredicateContext *next_; + /// Related Failure, set when the PredicateContext is converted + /// into a Failure. + Failure *failure_; + }; + + class TestResult + { + public: + TestResult(); + + /// \internal Implementation detail for assertion macros + /// Not encapsulated to prevent step into when debugging failed assertions + /// Incremented by one on assertion predicate entry, decreased by one + /// by addPredicateContext(). + PredicateContext::Id predicateId_; + + /// \internal Implementation detail for predicate macros + PredicateContext *predicateStackTail_; + + void setTestName( const std::string &name ); + + /// Adds an assertion failure. + TestResult &addFailure( const char *file, unsigned int line, + const char *expr = 0 ); + + /// Removes the last PredicateContext added to the predicate stack + /// chained list. + /// Next messages will be targed at the PredicateContext that was removed. + TestResult &popPredicateContext(); + + bool failed() const; + + void printFailure( bool printTestName ) const; + + TestResult &operator << ( bool value ); + TestResult &operator << ( int value ); + TestResult &operator << ( unsigned int value ); + TestResult &operator << ( double value ); + TestResult &operator << ( const char *value ); + TestResult &operator << ( const std::string &value ); + + private: + TestResult &addToLastFailure( const std::string &message ); + unsigned int getAssertionNestingLevel() const; + /// Adds a failure or a predicate context + void addFailureInfo( const char *file, unsigned int line, + const char *expr, unsigned int nestingLevel ); + static std::string indentText( const std::string &text, + const std::string &indent ); + + typedef std::deque<Failure> Failures; + Failures failures_; + std::string name_; + PredicateContext rootPredicateNode_; + PredicateContext::Id lastUsedPredicateId_; + /// Failure which is the target of the messages added using operator << + Failure *messageTarget_; + }; + + + class TestCase + { + public: + TestCase(); + + void run( TestResult &result ); + + virtual const char *testName() const = 0; + + protected: + TestResult *result_; + + private: + virtual void runTestCase() = 0; + }; + + /// Function pointer type for TestCase factory + typedef TestCase *(*TestCaseFactory)(); + + class Runner + { + public: + Runner(); + + /// Adds a test to the suite + Runner &add( TestCaseFactory factory ); + + /// Runs test as specified on the command-line + /// If no command-line arguments are provided, run all tests. + /// If --list-tests is provided, then print the list of all test cases + /// If --test <testname> is provided, then run test testname. + int runCommandLine( int argc, const char *argv[] ) const; + + /// Runs all the test cases + bool runAllTest( bool printSummary ) const; + + /// Returns the number of test case in the suite + unsigned int testCount() const; + + /// Returns the name of the test case at the specified index + std::string testNameAt( unsigned int index ) const; + + /// Runs the test case at the specified index using the specified TestResult + void runTestAt( unsigned int index, TestResult &result ) const; + + static void printUsage( const char *appName ); + + private: // prevents copy construction and assignment + Runner( const Runner &other ); + Runner &operator =( const Runner &other ); + + private: + void listTests() const; + bool testIndex( const std::string &testName, unsigned int &index ) const; + static void preventDialogOnCrash(); + + private: + typedef std::deque<TestCaseFactory> Factories; + Factories tests_; + }; + + template<typename T> + TestResult & + checkEqual( TestResult &result, const T &expected, const T &actual, + const char *file, unsigned int line, const char *expr ) + { + if ( expected != actual ) + { + result.addFailure( file, line, expr ); + result << "Expected: " << expected << "\n"; + result << "Actual : " << actual; + } + return result; + } + + TestResult & + checkStringEqual( TestResult &result, + const std::string &expected, const std::string &actual, + const char *file, unsigned int line, const char *expr ); + +} // namespace JsonTest + + +/// \brief Asserts that the given expression is true. +/// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y; +/// JSONTEST_ASSERT( x == y ); +#define JSONTEST_ASSERT( expr ) \ + if ( condition ) \ + { \ + } \ + else \ + result_->addFailure( __FILE__, __LINE__, #expr ) + +/// \brief Asserts that the given predicate is true. +/// The predicate may do other assertions and be a member function of the fixture. +#define JSONTEST_ASSERT_PRED( expr ) \ + { \ + JsonTest::PredicateContext _minitest_Context = { \ + result_->predicateId_, __FILE__, __LINE__, #expr }; \ + result_->predicateStackTail_->next_ = &_minitest_Context; \ + result_->predicateId_ += 1; \ + result_->predicateStackTail_ = &_minitest_Context; \ + (expr); \ + result_->popPredicateContext(); \ + } \ + *result_ + +/// \brief Asserts that two values are equals. +#define JSONTEST_ASSERT_EQUAL( expected, actual ) \ + JsonTest::checkEqual( *result_, expected, actual, \ + __FILE__, __LINE__, \ + #expected " == " #actual ) + +/// \brief Asserts that two values are equals. +#define JSONTEST_ASSERT_STRING_EQUAL( expected, actual ) \ + JsonTest::checkStringEqual( *result_, \ + std::string(expected), std::string(actual), \ + #expected " == " #actual ) + +/// \brief Begin a fixture test case. +#define JSONTEST_FIXTURE( FixtureType, name ) \ + class Test##FixtureType##name : public FixtureType \ + { \ + public: \ + static JsonTest::TestCase *factory() \ + { \ + return new Test##FixtureType##name(); \ + } \ + public: /* overidden from TestCase */ \ + virtual const char *testName() const \ + { \ + return #FixtureType "/" #name; \ + } \ + virtual void runTestCase(); \ + }; \ + \ + void Test##FixtureType##name::runTestCase() + +#define JSONTEST_FIXTURE_FACTORY( FixtureType, name ) \ + &Test##FixtureType##name::factory + +#define JSONTEST_REGISTER_FIXTURE( runner, FixtureType, name ) \ + (runner).add( JSONTEST_FIXTURE_FACTORY( FixtureType, name ) ) + +#endif // ifndef JSONTEST_H_INCLUDED diff --git a/lib/jsoncpp/src/test_lib_json/main.cpp b/lib/jsoncpp/src/test_lib_json/main.cpp new file mode 100644 index 0000000000..b80776d630 --- /dev/null +++ b/lib/jsoncpp/src/test_lib_json/main.cpp @@ -0,0 +1,244 @@ +#include <json/json.h> +#include "jsontest.h" + + +// TODO: +// - boolean value returns that they are integral. Should not be. +// - unsigned integer in integer range are not considered to be valid integer. Should check range. + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// Json Library test cases +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + + +struct ValueTest : JsonTest::TestCase +{ + Json::Value null_; + Json::Value emptyArray_; + Json::Value emptyObject_; + Json::Value integer_; + Json::Value unsignedInteger_; + Json::Value smallUnsignedInteger_; + Json::Value real_; + Json::Value array1_; + Json::Value object1_; + Json::Value emptyString_; + Json::Value string1_; + Json::Value string_; + Json::Value true_; + Json::Value false_; + + ValueTest() + : emptyArray_( Json::arrayValue ) + , emptyObject_( Json::objectValue ) + , integer_( 123456789 ) + , smallUnsignedInteger_( Json::Value::UInt( Json::Value::maxInt ) ) + , unsignedInteger_( 34567890u ) + , real_( 1234.56789 ) + , emptyString_( "" ) + , string1_( "a" ) + , string_( "sometext with space" ) + , true_( true ) + , false_( false ) + { + array1_.append( 1234 ); + object1_["id"] = 1234; + } + + struct IsCheck + { + /// Initialize all checks to \c false by default. + IsCheck(); + + bool isObject_; + bool isArray_; + bool isBool_; + bool isDouble_; + bool isInt_; + bool isUInt_; + bool isIntegral_; + bool isNumeric_; + bool isString_; + bool isNull_; + }; + + void checkConstMemberCount( const Json::Value &value, unsigned int expectedCount ); + + void checkMemberCount( Json::Value &value, unsigned int expectedCount ); + + void checkIs( const Json::Value &value, const IsCheck &check ); +}; + + +JSONTEST_FIXTURE( ValueTest, size ) +{ + JSONTEST_ASSERT_PRED( checkMemberCount(emptyArray_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(emptyObject_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(array1_, 1) ); + JSONTEST_ASSERT_PRED( checkMemberCount(object1_, 1) ); + JSONTEST_ASSERT_PRED( checkMemberCount(null_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(integer_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(real_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(emptyString_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(string_, 0) ); + JSONTEST_ASSERT_PRED( checkMemberCount(true_, 0) ); +} + + +JSONTEST_FIXTURE( ValueTest, isObject ) +{ + IsCheck checks; + checks.isObject_ = true; + JSONTEST_ASSERT_PRED( checkIs( emptyObject_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( object1_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isArray ) +{ + IsCheck checks; + checks.isArray_ = true; + JSONTEST_ASSERT_PRED( checkIs( emptyArray_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( array1_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isNull ) +{ + IsCheck checks; + checks.isNull_ = true; + checks.isObject_ = true; + checks.isArray_ = true; + JSONTEST_ASSERT_PRED( checkIs( null_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isString ) +{ + IsCheck checks; + checks.isString_ = true; + JSONTEST_ASSERT_PRED( checkIs( emptyString_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( string_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( string1_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isBool ) +{ + IsCheck checks; + checks.isBool_ = true; + checks.isIntegral_ = true; + checks.isNumeric_ = true; + JSONTEST_ASSERT_PRED( checkIs( false_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( true_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isDouble ) +{ + IsCheck checks; + checks.isDouble_ = true; + checks.isNumeric_ = true; + JSONTEST_ASSERT_PRED( checkIs( real_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isInt ) +{ + IsCheck checks; + checks.isInt_ = true; + checks.isNumeric_ = true; + checks.isIntegral_ = true; + JSONTEST_ASSERT_PRED( checkIs( integer_, checks ) ); +} + + +JSONTEST_FIXTURE( ValueTest, isUInt ) +{ + IsCheck checks; + checks.isUInt_ = true; + checks.isNumeric_ = true; + checks.isIntegral_ = true; + JSONTEST_ASSERT_PRED( checkIs( unsignedInteger_, checks ) ); + JSONTEST_ASSERT_PRED( checkIs( smallUnsignedInteger_, checks ) ); +} + + +void +ValueTest::checkConstMemberCount( const Json::Value &value, unsigned int expectedCount ) +{ + unsigned int count = 0; + Json::Value::const_iterator itEnd = value.end(); + for ( Json::Value::const_iterator it = value.begin(); it != itEnd; ++it ) + { + ++count; + } + JSONTEST_ASSERT_EQUAL( expectedCount, count ) << "Json::Value::const_iterator"; +} + +void +ValueTest::checkMemberCount( Json::Value &value, unsigned int expectedCount ) +{ + JSONTEST_ASSERT_EQUAL( expectedCount, value.size() ); + + unsigned int count = 0; + Json::Value::iterator itEnd = value.end(); + for ( Json::Value::iterator it = value.begin(); it != itEnd; ++it ) + { + ++count; + } + JSONTEST_ASSERT_EQUAL( expectedCount, count ) << "Json::Value::iterator"; + + JSONTEST_ASSERT_PRED( checkConstMemberCount(value, expectedCount) ); +} + + +ValueTest::IsCheck::IsCheck() + : isObject_( false ) + , isArray_( false ) + , isBool_( false ) + , isDouble_( false ) + , isInt_( false ) + , isUInt_( false ) + , isIntegral_( false ) + , isNumeric_( false ) + , isString_( false ) + , isNull_( false ) +{ +} + + +void +ValueTest::checkIs( const Json::Value &value, const IsCheck &check ) +{ + JSONTEST_ASSERT_EQUAL( check.isObject_, value.isObject() ); + JSONTEST_ASSERT_EQUAL( check.isArray_, value.isArray() ); + JSONTEST_ASSERT_EQUAL( check.isBool_, value.isBool() ); + JSONTEST_ASSERT_EQUAL( check.isDouble_, value.isDouble() ); + JSONTEST_ASSERT_EQUAL( check.isInt_, value.isInt() ); + JSONTEST_ASSERT_EQUAL( check.isUInt_, value.isUInt() ); + JSONTEST_ASSERT_EQUAL( check.isIntegral_, value.isIntegral() ); + JSONTEST_ASSERT_EQUAL( check.isNumeric_, value.isNumeric() ); + JSONTEST_ASSERT_EQUAL( check.isString_, value.isString() ); + JSONTEST_ASSERT_EQUAL( check.isNull_, value.isNull() ); +} + + + +int main( int argc, const char *argv[] ) +{ + JsonTest::Runner runner; + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, size ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isObject ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isArray ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isBool ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isInt ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isUInt ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isDouble ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isString ); + JSONTEST_REGISTER_FIXTURE( runner, ValueTest, isNull ); + return runner.runCommandLine( argc, argv ); +} diff --git a/lib/jsoncpp/src/test_lib_json/sconscript b/lib/jsoncpp/src/test_lib_json/sconscript new file mode 100644 index 0000000000..915fd01c0a --- /dev/null +++ b/lib/jsoncpp/src/test_lib_json/sconscript @@ -0,0 +1,10 @@ +Import( 'env_testing buildUnitTests' ) + +buildUnitTests( env_testing, Split( """ + main.cpp + jsontest.cpp + """ ), + 'test_lib_json' ) + +# For 'check' to work, 'libs' must be built first. +env_testing.Depends('test_lib_json', '#libs') |