|
|
#include <string> |
|
|
#include <iostream> |
|
|
#include <iomanip> |
|
|
#include <vector> |
|
|
#include <sstream> |
|
|
#include <memory> |
|
|
#include <cstring> |
|
|
#include <time.h> |
|
|
|
|
|
#include "xmlrpc-c/girerr.hpp" |
|
|
using girerr::error; |
|
|
#include "xmlrpc-c/base.hpp" |
|
|
#include "xmlrpc-c/oldcppwrapper.hpp" |
|
|
#include "xmlrpc-c/registry.hpp" |
|
|
#include "c_util.h" |
|
|
|
|
|
#include "tools.hpp" |
|
|
|
|
|
#include "value.hpp" |
|
|
|
|
|
using namespace xmlrpc_c; |
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
class intTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "intTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_int int1(7); |
|
|
TEST(static_cast<int>(int1) == 7); |
|
|
value_int int2(-7); |
|
|
TEST(static_cast<int>(int2) == -7); |
|
|
value val1(int1); |
|
|
TEST(val1.type() == value::TYPE_INT); |
|
|
value_int int3(val1); |
|
|
TEST(static_cast<int>(int3) == 7); |
|
|
try { |
|
|
value_int int4(value_double(3.7)); |
|
|
TEST_FAILED("invalid cast double-int suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
value const int1x(toValue(7)); |
|
|
TEST(int1x.type() == value::TYPE_INT); |
|
|
TEST(static_cast<int>(value_int(int1x)) == 7); |
|
|
|
|
|
int test1x; |
|
|
fromValue(test1x, int1x); |
|
|
TEST(test1x == 7); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class doubleTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "doubleTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_double double1(3.14); |
|
|
TEST(static_cast<double>(double1) == 3.14); |
|
|
value val1(double1); |
|
|
TEST(val1.type() == value::TYPE_DOUBLE); |
|
|
value_double double2(val1); |
|
|
TEST(static_cast<double>(double2) == 3.14); |
|
|
try { |
|
|
value_double double4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-double suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
value const double1x(toValue(3.14)); |
|
|
TEST(double1x.type() == value::TYPE_DOUBLE); |
|
|
TEST(static_cast<double>(value_double(double1x)) == 3.14); |
|
|
|
|
|
double test1x; |
|
|
fromValue(test1x, double1x); |
|
|
TEST(test1x == 3.14); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class booleanTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "booleanTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_boolean boolean1(true); |
|
|
TEST(static_cast<bool>(boolean1) == true); |
|
|
value_boolean boolean2(false); |
|
|
TEST(static_cast<bool>(boolean2) == false); |
|
|
value val1(boolean1); |
|
|
TEST(val1.type() == value::TYPE_BOOLEAN); |
|
|
value_boolean boolean3(val1); |
|
|
TEST(static_cast<bool>(boolean3) == true); |
|
|
try { |
|
|
value_boolean boolean4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-boolean suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
value const boolean1x(toValue(true)); |
|
|
TEST(boolean1x.type() == value::TYPE_BOOLEAN); |
|
|
TEST(static_cast<bool>(value_boolean(boolean1x)) == true); |
|
|
|
|
|
bool test1x; |
|
|
fromValue(test1x, boolean1x); |
|
|
TEST(test1x == true); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#if XMLRPC_HAVE_TIMEVAL |
|
|
|
|
|
static struct timeval |
|
|
makeTv(time_t const secs, |
|
|
unsigned int const usecs) { |
|
|
|
|
|
struct timeval retval; |
|
|
|
|
|
retval.tv_sec = secs; |
|
|
retval.tv_usec = usecs; |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
static bool |
|
|
tvIsEqual(struct timeval const comparand, |
|
|
struct timeval const comparator) { |
|
|
return |
|
|
comparand.tv_sec == comparator.tv_sec && |
|
|
comparand.tv_usec == comparator.tv_usec; |
|
|
} |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if XMLRPC_HAVE_TIMESPEC |
|
|
|
|
|
static struct timespec |
|
|
makeTs(time_t const secs, |
|
|
unsigned int const usecs) { |
|
|
|
|
|
struct timespec retval; |
|
|
|
|
|
retval.tv_sec = secs; |
|
|
retval.tv_nsec = usecs * 1000; |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
static bool |
|
|
tsIsEqual(struct timespec const comparand, |
|
|
struct timespec const comparator) { |
|
|
return |
|
|
comparand.tv_sec == comparator.tv_sec && |
|
|
comparand.tv_nsec == comparator.tv_nsec; |
|
|
} |
|
|
#endif |
|
|
|
|
|
static xmlrpc_datetime const |
|
|
makeXd(time_t const secs, |
|
|
unsigned int const usecs) { |
|
|
|
|
|
struct tm const tm = *gmtime(&secs); |
|
|
|
|
|
xmlrpc_datetime retval; |
|
|
|
|
|
retval.Y = 1900 + tm.tm_year; |
|
|
retval.M = 1 + tm.tm_mon; |
|
|
retval.D = tm.tm_mday; |
|
|
retval.h = tm.tm_hour; |
|
|
retval.m = tm.tm_min; |
|
|
retval.s = tm.tm_sec; |
|
|
retval.u = usecs; |
|
|
|
|
|
return retval; |
|
|
} |
|
|
|
|
|
static bool |
|
|
xdIsEqual(xmlrpc_datetime const comparand, |
|
|
xmlrpc_datetime const comparator) { |
|
|
return |
|
|
comparand.Y == comparator.Y && |
|
|
comparand.M == comparator.M && |
|
|
comparand.D == comparator.D && |
|
|
comparand.h == comparator.h && |
|
|
comparand.m == comparator.m && |
|
|
comparand.s == comparator.s && |
|
|
comparand.u == comparator.u; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class datetimeTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "datetimeTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
time_t const testTime(900684535); |
|
|
string const testTime8601("19980717T140855,000000Z"); |
|
|
value_datetime datetime1("19980717T14:08:55"); |
|
|
TEST(static_cast<time_t>(datetime1) == testTime); |
|
|
value_datetime datetime2(testTime); |
|
|
TEST(static_cast<time_t>(datetime2) == testTime); |
|
|
value val1(datetime1); |
|
|
TEST(val1.type() == value::TYPE_DATETIME); |
|
|
value_datetime datetime3(val1); |
|
|
TEST(static_cast<time_t>(datetime3) == testTime); |
|
|
#if XMLRPC_HAVE_TIMEVAL |
|
|
struct timeval const testTimeTv(makeTv(testTime, 0)); |
|
|
value_datetime datetime4(testTimeTv); |
|
|
TEST(static_cast<time_t>(datetime4) == testTime); |
|
|
TEST(tvIsEqual(static_cast<timeval>(datetime4), testTimeTv)); |
|
|
#endif |
|
|
#if XMLRPC_HAVE_TIMESPEC |
|
|
struct timespec const testTimeTs(makeTs(testTime, 0)); |
|
|
value_datetime datetime5(testTimeTs); |
|
|
TEST(static_cast<time_t>(datetime5) == testTime); |
|
|
TEST(tsIsEqual(static_cast<timespec>(datetime5), testTimeTs)); |
|
|
#endif |
|
|
xmlrpc_datetime const testTimeXd(makeXd(testTime, 5)); |
|
|
value_datetime datetime6(testTimeXd); |
|
|
TEST(static_cast<time_t>(datetime6) == testTime); |
|
|
TEST(xdIsEqual(static_cast<xmlrpc_datetime>(datetime6), testTimeXd)); |
|
|
|
|
|
string const iso8601Value(datetime1.iso8601Value()); |
|
|
TEST(iso8601Value == testTime8601); |
|
|
|
|
|
try { |
|
|
value_datetime datetime4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-datetime suceeded"); |
|
|
} catch (error const&) {} |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class stringTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "stringTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_string string1("hello world"); |
|
|
TEST(static_cast<string>(string1) == "hello world"); |
|
|
value_string string2("embedded\0null"); |
|
|
TEST(static_cast<string>(string2) == "embedded\0null"); |
|
|
value val1(string1); |
|
|
TEST(val1.type() == value::TYPE_STRING); |
|
|
value_string string3(val1); |
|
|
TEST(static_cast<string>(string3) == "hello world"); |
|
|
try { |
|
|
value_string string4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-string succeeded"); |
|
|
} catch (error const&) {} |
|
|
value_string string5("hello world", value_string::nlCode_all); |
|
|
TEST(static_cast<string>(string5) == "hello world"); |
|
|
value_string string6("hello\nthere\rworld\r\n\n", |
|
|
value_string::nlCode_all); |
|
|
TEST(static_cast<string>(string6) == "hello\nthere\nworld\n\n"); |
|
|
TEST(string6.crlfValue() == "hello\r\nthere\r\nworld\r\n\r\n"); |
|
|
value_string string7("hello\nthere\rworld\r\n\n", |
|
|
value_string::nlCode_lf); |
|
|
TEST(static_cast<string>(string7) == "hello\nthere\rworld\r\n\n"); |
|
|
|
|
|
value const string1x(toValue("hello world")); |
|
|
TEST(string1x.type() == value::TYPE_STRING); |
|
|
TEST(static_cast<string>(value_string(string1x)) == "hello world"); |
|
|
|
|
|
string test1x; |
|
|
fromValue(test1x, string1x); |
|
|
TEST(test1x == "hello world"); |
|
|
|
|
|
value const string2x(toValue(string("hello world"))); |
|
|
TEST(string2x.type() == value::TYPE_STRING); |
|
|
TEST(static_cast<string>(value_string(string2x)) == "hello world"); |
|
|
|
|
|
string1.validate(); |
|
|
|
|
|
value_string badString("hello \x18 there"); |
|
|
|
|
|
try { |
|
|
badString.validate(); |
|
|
TEST_FAILED("'validate' of string containging a control " |
|
|
"character succeeded"); |
|
|
} catch (error const&) {} |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class bytestringTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "bytestringTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
unsigned char bytestringArray[] = {0x10, 0x11, 0x12, 0x13, 0x14}; |
|
|
cbytestring |
|
|
bytestringData(&bytestringArray[0], &bytestringArray[4]); |
|
|
value_bytestring bytestring1(bytestringData); |
|
|
|
|
|
cbytestring const dataReadBack1(bytestring1.vectorUcharValue()); |
|
|
TEST(dataReadBack1 == bytestringData); |
|
|
value val1(bytestring1); |
|
|
TEST(val1.type() == value::TYPE_BYTESTRING); |
|
|
value_bytestring bytestring2(val1); |
|
|
vector<unsigned char> const dataReadBack2( |
|
|
bytestring2.vectorUcharValue()); |
|
|
TEST(dataReadBack2 == bytestringData); |
|
|
try { |
|
|
value_bytestring bytestring4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-bytestring suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
value const bytestring1x(toValue(bytestringData)); |
|
|
TEST(bytestring1x.type() == value::TYPE_BYTESTRING); |
|
|
vector<unsigned char> const dataReadBack1x( |
|
|
value_bytestring(bytestring1x).vectorUcharValue()); |
|
|
TEST(dataReadBack1x == bytestringData); |
|
|
|
|
|
vector<unsigned char> test1x; |
|
|
fromValue(test1x, bytestring1x); |
|
|
TEST(test1x == bytestringData); |
|
|
|
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class nilTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "nilTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_nil nil1; |
|
|
value val1(nil1); |
|
|
TEST(val1.type() == value::TYPE_NIL); |
|
|
value_nil nil2(val1); |
|
|
try { |
|
|
value_nil nil4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-nil suceeded"); |
|
|
} catch (error const&) {} |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class i8TestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "i8TestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
value_i8 int1(7); |
|
|
TEST(static_cast<xmlrpc_int64>(int1) == 7); |
|
|
value_i8 int2(-7); |
|
|
TEST(static_cast<xmlrpc_int64>(int2) == -7); |
|
|
value_i8 int5(1ull << 40); |
|
|
TEST(static_cast<xmlrpc_int64>(int5) == (1ull << 40)); |
|
|
value val1(int1); |
|
|
TEST(val1.type() == value::TYPE_I8); |
|
|
value_i8 int3(val1); |
|
|
TEST(static_cast<xmlrpc_int64>(int3) == 7); |
|
|
try { |
|
|
value_i8 int4(value_double(3.7)); |
|
|
TEST_FAILED("invalid cast double-i8 suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
value const int1x(toValue((xmlrpc_int64)7)); |
|
|
TEST(int1x.type() == value::TYPE_I8); |
|
|
TEST(static_cast<xmlrpc_int64>(value_i8(int1x)) == 7); |
|
|
|
|
|
xmlrpc_int64 test1x; |
|
|
fromValue(test1x, int1x); |
|
|
TEST(test1x == 7); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class structTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "structTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
cstruct structData; |
|
|
pair<string, value> member("the_integer", value_int(9)); |
|
|
structData.insert(member); |
|
|
|
|
|
value_struct struct1(structData); |
|
|
|
|
|
map<string, value> dataReadBack(struct1); |
|
|
|
|
|
TEST(static_cast<int>(value_int(dataReadBack["the_integer"])) == 9); |
|
|
|
|
|
value val1(struct1); |
|
|
TEST(val1.type() == value::TYPE_STRUCT); |
|
|
value_struct struct2(val1); |
|
|
try { |
|
|
value_struct struct4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-struct suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
map<string, int> structDatax; |
|
|
structDatax["one"] = 1; |
|
|
structDatax["two"] = 2; |
|
|
|
|
|
value const struct5(toValue(structDatax)); |
|
|
TEST(struct5.type() == value::TYPE_STRUCT); |
|
|
map<string, value> dataReadBackx; |
|
|
dataReadBackx = value_struct(struct5); |
|
|
|
|
|
TEST(static_cast<int>(value_int(dataReadBackx["two"])) == 2); |
|
|
|
|
|
map<string, int> test5x; |
|
|
fromValue(test5x, struct5); |
|
|
TEST(test5x["two"] == 2); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class arrayTestSuite : public testSuite { |
|
|
public: |
|
|
virtual string suiteName() { |
|
|
return "arrayTestSuite"; |
|
|
} |
|
|
virtual void runtests(unsigned int const) { |
|
|
carray arrayData; |
|
|
arrayData.push_back(value_int(7)); |
|
|
arrayData.push_back(value_double(2.78)); |
|
|
arrayData.push_back(value_string("hello world")); |
|
|
value_array array1(arrayData); |
|
|
|
|
|
TEST(array1.size() == 3); |
|
|
vector<value> dataReadBack1(array1.vectorValueValue()); |
|
|
TEST(dataReadBack1[0].type() == value::TYPE_INT); |
|
|
TEST(static_cast<int>(value_int(dataReadBack1[0])) == 7); |
|
|
TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); |
|
|
TEST(static_cast<double>(value_double(dataReadBack1[1])) == 2.78); |
|
|
TEST(dataReadBack1[2].type() == value::TYPE_STRING); |
|
|
TEST(static_cast<string>(value_string(dataReadBack1[2])) == |
|
|
"hello world"); |
|
|
|
|
|
value val1(array1); |
|
|
TEST(val1.type() == value::TYPE_ARRAY); |
|
|
value_array array2(val1); |
|
|
TEST(array2.size() == 3); |
|
|
try { |
|
|
value_array array4(value_int(4)); |
|
|
TEST_FAILED("invalid cast int-array suceeded"); |
|
|
} catch (error const&) {} |
|
|
|
|
|
int const arrayDatax[] = {7, 4}; |
|
|
|
|
|
value const array5( |
|
|
arrayValueArray(arrayDatax, ARRAY_SIZE(arrayDatax))); |
|
|
TEST(array5.type() == value::TYPE_ARRAY); |
|
|
TEST(value_array(array5).size() == 2); |
|
|
vector<value> dataReadBackx(value_array(array5).vectorValueValue()); |
|
|
|
|
|
TEST(dataReadBackx.size() == 2); |
|
|
TEST(static_cast<int>(value_int(dataReadBackx[0])) == 7); |
|
|
vector<int> test5x; |
|
|
fromValue(test5x, array5); |
|
|
TEST(test5x[1] == 4); |
|
|
|
|
|
vector<string> arrayDataVec; |
|
|
arrayDataVec.push_back("hello world"); |
|
|
value const array6(toValue(arrayDataVec)); |
|
|
TEST(array6.type() == value::TYPE_ARRAY); |
|
|
TEST(value_array(array6).size() == 1); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
string |
|
|
valueTestSuite::suiteName() { |
|
|
return "valueTestSuite"; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
valueTestSuite::runtests(unsigned int const indentation) { |
|
|
|
|
|
intTestSuite().run(indentation+1); |
|
|
doubleTestSuite().run(indentation+1); |
|
|
booleanTestSuite().run(indentation+1); |
|
|
datetimeTestSuite().run(indentation+1); |
|
|
stringTestSuite().run(indentation+1); |
|
|
bytestringTestSuite().run(indentation+1); |
|
|
nilTestSuite().run(indentation+1); |
|
|
i8TestSuite().run(indentation+1); |
|
|
structTestSuite().run(indentation+1); |
|
|
arrayTestSuite().run(indentation+1); |
|
|
} |
|
|
|