/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #include #include #include #include #include #include #include class A: public xml::Serialize { public: int _anInteger; bool _aBool; double _aDouble; std::string _aString; std::string _anotherString; unsigned long _aLong; protected: void initXmlMembers() { className("A"); persist(_anInteger, "anInteger"); persist(_aBool, "aBool"); persist(_aDouble, "aDouble"); persist(_aString, "aString"); persist(_anotherString, "anotherString"); persist(_aLong, "aLong"); } }; class B: public xml::Serialize { public: long aLong; char aChar; protected: void initXmlMembers() { className("B"); persist(aLong, "aLong"); persist(aChar, "aChar"); } }; class B2: public B { public: float aFloat; short aShort; protected: void initXmlMembers() { B::initXmlMembers(); className("B2"); persist(aFloat, "float"); persist(aShort, "short"); } }; // Complex Example: Class A2 is a class that inherits another class // (A) and contains a class (B2) that inherits another class (B) class A2: public A { public: std::string aText; B2 childOfB; protected: void initXmlMembers() { A::initXmlMembers(); className("A2"); persist(aText, "aText"); persist(childOfB, "childOfB"); } }; class C: public xml::Serialize { public: A2 a2; B2 b2; protected: void initXmlMembers() { className("C") .persist(a2, "a2") .persist(b2, "b2"); } }; class SerializationTest: public CppUnit::TestFixture { public: std::string _file; A _a; void setUp() { _a._anInteger = 15; _a._aBool = true; _a._aDouble = 123.456; _a._aString = "Hello World"; _a._anotherString = "This is another Text"; _a._aLong = 4123674622ul; try { std::stringstream ss; _a.saveXml(ss); _file = ss.str(); } catch (...) {} } void memberDeclaration() { // This is more a compile time test than a runtime test. A a; a._anInteger = 15; CPPUNIT_ASSERT_EQUAL(15, a._anInteger); a._aString = "Hello World"; CPPUNIT_ASSERT_EQUAL(std::string("Hello World"), a._aString); std::stringstream ss; } void store() { { std::stringstream ss; CPPUNIT_ASSERT_NO_THROW(_a.saveXml(ss)); CPPUNIT_ASSERT_EQUAL(std::string("\n" "\t15\n" "\ttrue\n" "\t123.456\n" "\tHello World\n" "\tThis is" " another Text\n" "\t4123674622\n" ""), ss.str()); } { // again - initialisation of A should be done only once std::stringstream ss; CPPUNIT_ASSERT_NO_THROW(_a.saveXml(ss)); CPPUNIT_ASSERT_EQUAL(_file, ss.str()); } } void restore() { A a; std::stringstream ss(_file); CPPUNIT_ASSERT(_file.size()>0); CPPUNIT_ASSERT_EQUAL(_file, ss.str()); CPPUNIT_ASSERT_NO_THROW(a.loadXml(ss)); CPPUNIT_ASSERT_EQUAL(15, a._anInteger); CPPUNIT_ASSERT_EQUAL(true, a._aBool); CPPUNIT_ASSERT_EQUAL(123.456, a._aDouble); CPPUNIT_ASSERT_EQUAL(std::string("Hello World"), a._aString); CPPUNIT_ASSERT_EQUAL(std::string("This is another Text"), a._anotherString); CPPUNIT_ASSERT_EQUAL(4123674622ul, a._aLong); } void complexLoad() { std::stringstream ss("\n" " -1234\n" " true\n" " 3.141\n" " This is A inside of A2\n" " Another A-String\n" " 1234567890\n" " Text from A2\n" " \n" " 987654321\n" " Q\n" " 2.5\n" " -127\n" " \n" ""); A2 a2; CPPUNIT_ASSERT_EQUAL(std::string("\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\n" ""), a2.schema()); CPPUNIT_ASSERT_NO_THROW(a2.loadXml(ss)); CPPUNIT_ASSERT_EQUAL(-1234, a2._anInteger); CPPUNIT_ASSERT_EQUAL(true, a2._aBool); CPPUNIT_ASSERT_EQUAL(3.141, a2._aDouble); CPPUNIT_ASSERT_EQUAL(std::string("This is A inside of A2"), a2._aString); CPPUNIT_ASSERT_EQUAL(std::string("Another A-String"), a2._anotherString); CPPUNIT_ASSERT_EQUAL(1234567890ul, a2._aLong); CPPUNIT_ASSERT_EQUAL(std::string("Text from A2"), a2.aText); CPPUNIT_ASSERT_EQUAL(987654321l, a2.childOfB.aLong); CPPUNIT_ASSERT_EQUAL('Q', a2.childOfB.aChar); CPPUNIT_ASSERT_EQUAL(2.5f, a2.childOfB.aFloat); CPPUNIT_ASSERT_EQUAL((short)-127, a2.childOfB.aShort); } void complexSave() { A2 a2; a2._anInteger = -1234; a2._aBool = true; a2._aDouble = 3.141; a2._aString = std::string("This is A inside of A2"); a2._anotherString = std::string("Another A-String"); a2._aLong = 1234567890ul; a2.aText = std::string("Text from A2"); a2.childOfB.aLong = 987654321l; a2.childOfB.aChar = 'Q'; a2.childOfB.aFloat = 2.5f; a2.childOfB.aShort = (short)-127; std::stringstream ss; a2.saveXml(ss); CPPUNIT_ASSERT_EQUAL (std::string("\n" "\t-1234\n" "\ttrue\n" "\t3.141\n" "\tThis is A inside of A2\n" "\tAnother A-String\n" "\t1234567890\n" "\tText from A2\n" "\t\n" "\t\t987654321\n" "\t\tQ\n" "\t\t2.5\n" "\t\t-127\n" "\t\n" ""), ss.str()); } void moreComplexLoad() { std::stringstream ss ("\n" " \n" " -1234\n" " true\n" " 3.141\n" " This is A inside of A2\n" " Another A-String\n" " 1234567890\n" " Text from A2\n" " \n" " 987654321\n" " Q\n" " 2.5\n" " -127\n" " \n" " \n" " \n" " 212121\n" " W\n" " 2.25\n" " 124\n" " \n" ""); C c; CPPUNIT_ASSERT_EQUAL(std::string("\n" "\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\t\n" "\t\t\n" "\t\n" "\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\t\n" "\t\n" ""), c.schema()); CPPUNIT_ASSERT_NO_THROW(c.loadXml(ss)); CPPUNIT_ASSERT_EQUAL(-1234, c.a2._anInteger); CPPUNIT_ASSERT_EQUAL(true, c.a2._aBool); CPPUNIT_ASSERT_EQUAL(3.141, c.a2._aDouble); CPPUNIT_ASSERT_EQUAL(std::string("This is A inside of A2"), c.a2._aString); CPPUNIT_ASSERT_EQUAL(std::string("Another A-String"), c.a2._anotherString); CPPUNIT_ASSERT_EQUAL(1234567890ul, c.a2._aLong); CPPUNIT_ASSERT_EQUAL(std::string("Text from A2"), c.a2.aText); CPPUNIT_ASSERT_EQUAL(987654321l, c.a2.childOfB.aLong); CPPUNIT_ASSERT_EQUAL('Q', c.a2.childOfB.aChar); CPPUNIT_ASSERT_EQUAL(2.5f, c.a2.childOfB.aFloat); CPPUNIT_ASSERT_EQUAL((short)-127, c.a2.childOfB.aShort); CPPUNIT_ASSERT_EQUAL(212121l, c.b2.aLong); CPPUNIT_ASSERT_EQUAL('W', c.b2.aChar); CPPUNIT_ASSERT_EQUAL(2.25f, c.b2.aFloat); CPPUNIT_ASSERT_EQUAL((short)124, c.b2.aShort); } void moreComplexSave() { C c; c.a2._anInteger = -1234; c.a2._aBool = true; c.a2._aDouble = 3.141; c.a2._aString = std::string("This is A inside of A2"); c.a2._anotherString = std::string("Another A-String"); c.a2._aLong = 1234567890ul; c.a2.aText = std::string("Text from A2"); c.a2.childOfB.aLong = 987654321l; c.a2.childOfB.aChar = 'Q'; c.a2.childOfB.aFloat = 2.5f; c.a2.childOfB.aShort = (short)-127; c.b2.aLong = 212121l; c.b2.aChar = 'W'; c.b2.aFloat = 2.25f; c.b2.aShort = (short)124; std::stringstream ss; c.saveXml(ss); CPPUNIT_ASSERT_EQUAL (std::string("\n" "\t\n" "\t\t-1234\n" "\t\ttrue\n" "\t\t3.141\n" "\t\tThis is A inside of A2\n" "\t\tAnother A-String\n" "\t\t1234567890\n" "\t\tText from A2\n" "\t\t\n" "\t\t\t987654321\n" "\t\t\tQ\n" "\t\t\t2.5\n" "\t\t\t-127\n" "\t\t\n" "\t\n" "\t\n" "\t\t212121\n" "\t\tW\n" "\t\t2.25\n" "\t\t124\n" "\t\n" ""), ss.str()); } CPPUNIT_TEST_SUITE(SerializationTest); CPPUNIT_TEST(memberDeclaration); CPPUNIT_TEST(store); CPPUNIT_TEST(restore); CPPUNIT_TEST(complexLoad); CPPUNIT_TEST(complexSave); CPPUNIT_TEST(moreComplexLoad); CPPUNIT_TEST(moreComplexSave); CPPUNIT_TEST_SUITE_END(); }; CPPUNIT_TEST_SUITE_REGISTRATION(SerializationTest); int main(int argc, char** argv) try { std::ofstream ofs((*argv+std::string(".xml")).c_str()); CppUnit::TextUi::TestRunner runner; runner.setOutputter(new CppUnit::XmlOutputter(&runner.result(), ofs)); runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); return runner.run() ? 0 : 1; } catch (std::exception& e) { std::cerr<<"***Exception: "<