closes #1
This commit is contained in:
		| @@ -35,10 +35,6 @@ class B: public xml::Serialize { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| std::ostream& fn(std::ostream& os) { | ||||
|   os<<std::endl<<"HALLO"<<std::endl; | ||||
| } | ||||
|  | ||||
| int main(int, char**) { | ||||
|   { // Serialization as a member | ||||
|     std::stringstream ss("<b>\n" | ||||
| @@ -56,7 +52,6 @@ int main(int, char**) { | ||||
|     std::cout<<"Text B: "<<b.txt<<std::endl; | ||||
|     std::cout<<"Text A: "<<b.a.txt<<std::endl; | ||||
|     b.saveXml(std::cout)<<std::endl; | ||||
|     std::cout<<fn; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ AM_LDFLAGS = -L${top_builddir}/src -lxml-cxx | ||||
|  | ||||
| noinst_PROGRAMS = address node_macros serialization \ | ||||
|                   contain_serialization inherit_serialization \ | ||||
| 		  list_serialization | ||||
| 		  list_serialization optional_serialization | ||||
|  | ||||
| address_SOURCES = address.cxx | ||||
| node_macros_SOURCES = node_macros.cxx | ||||
| @@ -16,5 +16,6 @@ serialization_SOURCES = serialization.cxx | ||||
| contain_serialization_SOURCES = contain_serialization.cxx | ||||
| inherit_serialization_SOURCES = inherit_serialization.cxx | ||||
| list_serialization_SOURCES = list_serialization.cxx | ||||
| optional_serialization_SOURCES = optional_serialization.cxx | ||||
|  | ||||
| MAINTAINERCLEANFILES = makefile.in | ||||
|   | ||||
							
								
								
									
										46
									
								
								doc/examples/optional_serialization.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								doc/examples/optional_serialization.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /*! @file | ||||
|  | ||||
|     @id $Id$ | ||||
| */ | ||||
| //       1         2         3         4         5         6         7         8 | ||||
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| #include <xml-cxx/xml.hxx> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
|  | ||||
| class A: public xml::Serialize { | ||||
|   public: | ||||
|     xml::Optional<int> a; | ||||
|     xml::Optional<std::string> txt; | ||||
|   protected: | ||||
|     void initXmlMembers() { | ||||
|       className("A"); | ||||
|       persist(a, "a"); | ||||
|       persist(txt, "txt"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class B: public xml::Serialize { | ||||
|   public: | ||||
|     xml::Optional<A> a; | ||||
|     xml::Optional<int> i; | ||||
|     xml::Optional<std::string> txt; | ||||
|   protected: | ||||
|     void initXmlMembers() { | ||||
|       className("B"); | ||||
|       persist(a, "a"); | ||||
|       persist(i, "i"); | ||||
|       persist(txt, "txt"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| int main(int, char**) { | ||||
|   { // Serialization as a member | ||||
|     std::stringstream ss("<B/>"); | ||||
|     B b; | ||||
|     b.loadXml(ss); | ||||
|     b.saveXml(std::cout)<<std::endl; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| @@ -165,9 +165,9 @@ class MethodTrace { | ||||
|        - most standard containers, but in their xml-form, | ||||
|          e.g. xml::List instead of @c std::list | ||||
|          (xml::List inherits @c std::list) | ||||
|        - Optional values through xml::Optional | ||||
|     - @c std::bitset, @c std::priority_queue, @c std::queue and | ||||
|       @c std::stack are not implemented | ||||
|     - Optional values are not yet implemented | ||||
|     - Polymorfic serialisation is not yet implemented | ||||
|  | ||||
|     @page rationale Rationale - Limitations of other libraries | ||||
| @@ -787,6 +787,9 @@ namespace xml { | ||||
|       virtual Node& text(const std::string& txt) throw(tag_expected, | ||||
|                                                        type_mismatch); | ||||
|       virtual Node& append(const Node& o) throw(cannot_have_children); | ||||
|       virtual Node& remove(Node& n) throw(access_error); | ||||
|       virtual Node& remove(const std::string& n) throw(access_error); | ||||
|       virtual Node& remove(size_type n) throw(out_of_range); | ||||
|       virtual Node& set(const Attributes& o) throw(); | ||||
|       Node& clear() throw (); | ||||
|       std::string name() const throw(); | ||||
| @@ -954,6 +957,7 @@ namespace xml { | ||||
|     private: | ||||
|       friend class stream_error; | ||||
|       friend class Serialize; | ||||
|       template<class T> friend class Optional; | ||||
|       template<class T> friend class Container; | ||||
|       template<class T> friend class AssociativeContainer; | ||||
|       template<class T> friend class AssociativeMap; | ||||
| @@ -1098,9 +1102,9 @@ namespace xml { | ||||
|       Serialize(const Serialize& other) throw(); | ||||
|       virtual ~Serialize(); | ||||
|       Serialize& operator=(const Serialize& other) throw(); | ||||
|       Serialize& className(const std::string& name) throw(); | ||||
|       virtual Serialize& persist(Serialize& member, | ||||
|                                  const std::string& name) throw(); | ||||
|       virtual Serialize& className(const std::string& name) throw(); | ||||
|       Serialize& persist(Serialize& member, | ||||
|                          const std::string& name) throw(); | ||||
|       Serialize& persist(bool& member, | ||||
|                          const std::string& name) throw(); | ||||
|       Serialize& persist(char& member, | ||||
| @@ -1136,6 +1140,7 @@ namespace xml { | ||||
|       static void registerFromNode(FromNodeFunc fromNodeFunc); | ||||
|       static void registerToNode(ToNodeFunc toNodeFunc); | ||||
|       static void registerClear(ClearFunc clearFunc); | ||||
|       virtual void clear() throw(); | ||||
|     protected: | ||||
|       virtual void initXmlMembers(); | ||||
|       void checkInit(const Serialize* const ser=0) const { | ||||
| @@ -1145,11 +1150,15 @@ namespace xml { | ||||
|           if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); | ||||
|         } | ||||
|       } | ||||
|       virtual void clear() throw(); | ||||
|       /*! @todo Why does @c protected: not work here?!? Children can't | ||||
|           access the members if they are protected! */ | ||||
|     public: | ||||
|       //! @cond INTERNAL | ||||
|       template<typename TYPE> friend bool assignFromNode(Any member, | ||||
|                                                          const xml::Node& node); | ||||
|       template<typename TYPE> friend bool assigntoNode(Any member, | ||||
|                                                        const xml::Node& node); | ||||
|       virtual bool optional() const throw(); | ||||
|       void clear(Any member) throw(); | ||||
|       void reset() throw(); | ||||
|       void copy(const Serialize& o) throw(); | ||||
| @@ -1162,8 +1171,8 @@ namespace xml { | ||||
|         _xmlFactory = schema; | ||||
|         return *this; | ||||
|       } | ||||
|       void fromNode(Any member, const xml::Node& node); | ||||
|       void toNode(const Any member, xml::Node& node) const; | ||||
|       virtual void fromNode(Any member, const xml::Node& node); | ||||
|       virtual void toNode(const Any member, xml::Node& node) const; | ||||
|       std::map<std::string, Any> _xmlNames; | ||||
|       xml::Factory _xmlFactory; | ||||
|       static std::set<FromNodeFunc> _fromNode; | ||||
| @@ -1174,54 +1183,71 @@ namespace xml { | ||||
|  | ||||
|   template <class TYPE> class Optional: public Serialize { | ||||
|     public: | ||||
|       Optional() throw() {} | ||||
|       Optional(const Optional& o) throw(): _member(new TYPE(*o._member)) {} | ||||
|       Optional(const TYPE& mem) throw(): _member(new TYPE(mem)) {} | ||||
|       Optional() throw(): _valid(false) {} | ||||
|       Optional(const Optional& o) throw(): | ||||
|           _member(o._member), _valid(o.valid) { | ||||
|       } | ||||
|       Optional(const TYPE& mem) throw(): | ||||
|           _member(mem), _valid(true) { | ||||
|       } | ||||
|       virtual ~Optional() throw() {} | ||||
|       Optional& operator=(const Optional& o) throw() { | ||||
|         _member = new TYPE(*o._member); | ||||
|         _member = o._member; | ||||
|         _valid = o._valid; | ||||
|         return *this; | ||||
|       } | ||||
|       Optional& operator=(const TYPE& mem) throw() { | ||||
|         _member = new TYPE(mem); | ||||
|         _member = mem; | ||||
|         _valid = true; | ||||
|         return *this; | ||||
|       } | ||||
|       operator bool() const throw() { | ||||
|         return _member.get(); | ||||
|         return _valid; | ||||
|       } | ||||
|       const TYPE& operator*() const throw() { | ||||
|         return *_member; | ||||
|         return _member; | ||||
|       } | ||||
|       TYPE& operator*() throw() { | ||||
|         return *_member; | ||||
|         return _member; | ||||
|       } | ||||
|       const TYPE*const operator->() const throw() { | ||||
|         return _member.get(); | ||||
|         return &_member; | ||||
|       } | ||||
|       TYPE*const operator->() throw() { | ||||
|         return _member.get(); | ||||
|         return &_member; | ||||
|       } | ||||
|       Optional& reset() throw() { | ||||
|         _member.reset(); | ||||
|       virtual void clear() throw() { | ||||
|         _valid = false; | ||||
|       } | ||||
|       virtual Optional& className(const std::string& name) throw() { | ||||
|         if (!_xmlFactory) { | ||||
|           Serialize::className(name); | ||||
|           persist(_member, name); | ||||
|            // make the child the root, and it's optional | ||||
|           _xmlFactory = (*_xmlFactory)[0]; | ||||
|           _xmlFactory->limits(0, 1); | ||||
|         } | ||||
|         return *this; | ||||
|       } | ||||
|     protected: | ||||
|       virtual void clear() throw() { | ||||
|         _member.reset(); | ||||
|       virtual bool optional() const throw() { | ||||
|         return true; | ||||
|       } | ||||
|       virtual std::ostream& saveXml(std::ostream& os, | ||||
|                                     const std::string& name = std::string()) | ||||
|           const throw() { | ||||
|         if (!_member.get()) return os; | ||||
|         checkInit(); | ||||
|         xml::Node node(*_xmlFactory); | ||||
|         if (name.size()) node.name(name); | ||||
|         toNode(*_member, node); | ||||
|         os<<node; | ||||
|         return os; | ||||
|       virtual void fromNode(Any member, const xml::Node& node) { | ||||
|         _valid = true; | ||||
|         Serialize::fromNode(Any(&_member), node); | ||||
|       } | ||||
|       virtual void toNode(const Any member, xml::Node& node) const { | ||||
|         if (!_valid) { | ||||
|           node.parent().remove(node); | ||||
|           return; | ||||
|         } | ||||
|         const Any mem(&const_cast<Optional*>(this)->_member); | ||||
|         Serialize::toNode(mem, node); | ||||
|       } | ||||
|     private: | ||||
|       std::auto_ptr<TYPE> _member; | ||||
|       TYPE _member; | ||||
|       bool _valid; | ||||
|   }; | ||||
|  | ||||
|   //! @addtogroup serialization | ||||
| @@ -1400,17 +1426,13 @@ namespace xml { | ||||
|         if (name.size()) factory->name(name); | ||||
|         std::auto_ptr<xml::Node> node(factory.read(is)); | ||||
|         CONTAINER_TYPE::clear(); | ||||
|         LOG("READING: "<<*node); | ||||
|         for (xml::Node::size_type i(0); i<node->children(); ++i) { | ||||
|           typename CONTAINER_TYPE::key_type key; | ||||
|           typename CONTAINER_TYPE::mapped_type data; | ||||
|           LOG("READING Key: "<<(*node)[i]<<"Value:"<<(*node)[1+i]); | ||||
|           Serialize::fromNode(&key, (*node)[i]); // reads into tmp | ||||
|           Serialize::fromNode(&data, (*node)[++i]); // key&value | ||||
|           insert(typename CONTAINER_TYPE::value_type(key, data)); | ||||
|           LOG("READ"); | ||||
|         } | ||||
|         LOG("DONE"); | ||||
|         return is; | ||||
|       } | ||||
|       virtual std::ostream& saveXml(std::ostream& os, | ||||
|   | ||||
							
								
								
									
										58
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <cstdlib> | ||||
| #include <algorithm> | ||||
|  | ||||
| unsigned int MethodTrace::_level(0); | ||||
|  | ||||
| @@ -310,6 +311,25 @@ namespace xml { | ||||
|     _contents.push_back(o.clone(this).release()); | ||||
|     return *this; | ||||
|   } | ||||
|   //! Removes a given child node. | ||||
|   Node& Node::remove(Node& n) throw(access_error) { | ||||
|     Contents::iterator it(std::find(_contents.begin(), _contents.end(), &n)); | ||||
|     if (it==_contents.end()) throw access_error(*this, n.name()); | ||||
|     _contents.erase(it); | ||||
|     return *this; | ||||
|   } | ||||
|   //! Removes the first child node of a given name. | ||||
|   Node& Node::remove(const std::string& n) throw(access_error) { | ||||
|     Node* t(find(n)); | ||||
|     if (!t) throw access_error(*this, n); | ||||
|     return remove(*t); | ||||
|   } | ||||
|   //! Removes the child node of a given position. | ||||
|   Node& Node::remove(size_type n) throw(out_of_range) { | ||||
|     if (n>=children()) throw out_of_range(*this, n); | ||||
|     _contents.erase(_contents.begin()+n); | ||||
|     return *this; | ||||
|   } | ||||
|   //! Set a list of attributes. | ||||
|   /*! Existing attributes with the same name are overwritten. */ | ||||
|   Node& Node::set(const Attributes& o) throw() { | ||||
| @@ -1020,13 +1040,21 @@ namespace xml { | ||||
|   } | ||||
|   Serialize& Serialize::persist(Serialize& ser, | ||||
|                                 const std::string& name) throw() { | ||||
|     ser.checkInit(); | ||||
|     _xmlNames[name] = &ser; | ||||
|     xml::Node schema(*_xmlFactory); | ||||
|     xml::Node node(xml::Node(name).limits(1,1)); | ||||
|     for (xml::Node::size_type i(0); i<ser._xmlFactory->children(); ++i) | ||||
|       node<<(*ser._xmlFactory)[i]; | ||||
|     _xmlFactory = schema<<node; | ||||
|     if (ser.optional()) { | ||||
|       _xmlNames[name] = &ser; | ||||
|       ser.className(name); | ||||
|       *_xmlFactory<<*ser._xmlFactory; | ||||
|       std::stringstream ss; | ||||
|     } else { | ||||
|       ser.checkInit(); | ||||
|       _xmlNames[name] = &ser; | ||||
|       xml::Node schema(*_xmlFactory); | ||||
|       xml::Node node(xml::Node(name).limits(1,1)); | ||||
|       for (xml::Node::size_type i(0); i<ser._xmlFactory->children(); ++i) | ||||
|         node<<(*ser._xmlFactory)[i]; | ||||
|       _xmlFactory = schema<<node; | ||||
|       return *this; | ||||
|      } | ||||
|     return *this; | ||||
|   } | ||||
|   Serialize& Serialize::persist(bool& member, | ||||
| @@ -1123,13 +1151,13 @@ namespace xml { | ||||
|   void Serialize::registerClear(Serialize::ClearFunc clearFunc) { | ||||
|     _clear.insert(clearFunc); | ||||
|   } | ||||
|   void Serialize::initXmlMembers() {} | ||||
|   void Serialize::clear() throw() { | ||||
|     for (std::map<std::string, Any>::const_iterator | ||||
|            it(_xmlNames.begin()); | ||||
|          it!=_xmlNames.end(); ++it) | ||||
|       clear(it->second); | ||||
|   } | ||||
|   void Serialize::initXmlMembers() {} | ||||
|   void Serialize::reset() throw() { | ||||
|     _xmlFactory.reset(); | ||||
|     _xmlNames.clear(); | ||||
| @@ -1156,6 +1184,10 @@ namespace xml { | ||||
|       if ((**it)(member)) return; // found match | ||||
|     throw type_not_registered(member.type().name()); | ||||
|   } | ||||
|   bool Serialize::optional() const throw() { | ||||
|     return false; | ||||
|   } | ||||
|    | ||||
|   std::set<Serialize::FromNodeFunc> Serialize::_fromNode; | ||||
|   std::set<Serialize::ToNodeFunc> Serialize::_toNode; | ||||
|   std::set<Serialize::ClearFunc> Serialize::_clear; | ||||
| @@ -1201,6 +1233,10 @@ namespace xml { | ||||
|   template<> bool assignFromNode<Serialize>(Any member, | ||||
|                                             const xml::Node& node) { | ||||
|     if (!any_cast<Serialize>(&member)) return false; | ||||
|     if (any_cast<Serialize>(member)->optional()) { | ||||
|       (*any_cast<Serialize>(member)).fromNode(member, node); | ||||
|       return true; | ||||
|     } | ||||
|     //! @todo improve this (inefficient) | ||||
|     std::stringstream ss; // simple but inefficient: rewrite and reread | ||||
|     ss<<node; | ||||
| @@ -1214,6 +1250,10 @@ namespace xml { | ||||
|   template<> bool assignToNode<Serialize>(const Any member, | ||||
|                                           xml::Node& node) { | ||||
|     if (!any_cast<Serialize>(&member)) return false; | ||||
|     if (any_cast<Serialize>(member)->optional()) { | ||||
|       any_cast<Serialize>(member)->toNode(member, node); | ||||
|       return true; | ||||
|     } | ||||
|     std::stringstream ss; | ||||
|     any_cast<Serialize>(member)->saveXml(ss, node.name()); | ||||
|     xml::Factory factory(node); | ||||
| @@ -1238,7 +1278,7 @@ namespace xml { | ||||
|   } | ||||
|   template<> bool clearMember<Serialize>(Any member) { | ||||
|     if (!any_cast<Serialize>(&member)) return false; | ||||
|     any_cast<std::string>(member)->clear(); | ||||
|     any_cast<Serialize>(member)->clear(); | ||||
|     return true; | ||||
|   } | ||||
|   // Init To and From Node --------------------------------------------------- | ||||
|   | ||||
| @@ -7,12 +7,15 @@ AM_CXXFLAGS += -I ${top_srcdir}/src | ||||
| AM_LDFLAGS = -L${top_builddir}/src | ||||
| LDADD = -lcppunit -lxml-cxx | ||||
|  | ||||
| check_PROGRAMS = xml_test serialization_test container_serialization_test | ||||
| check_PROGRAMS = xml_test serialization_test		 \ | ||||
|                  container_serialization_test optional_serialization_test | ||||
|  | ||||
| TESTS=${check_PROGRAMS} | ||||
|  | ||||
| xml_test_SOURCES = xml_test.cxx | ||||
| serialization_test_SOURCES = serialization_test.cxx | ||||
| container_serialization_test_SOURCES = container_serialization_test.cxx | ||||
| optional_serialization_test_SOURCES = optional_serialization_test.cxx | ||||
|  | ||||
| CLEANFILES =  | ||||
| MAINTAINERCLEANFILES = makefile.in | ||||
|   | ||||
							
								
								
									
										118
									
								
								test/optional_serialization_test.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								test/optional_serialization_test.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| /*! @file | ||||
|  | ||||
|     @id $Id: serialization_test.cxx 31 2009-04-28 07:36:07Z  $ | ||||
| */ | ||||
| //       1         2         3         4         5         6         7         8 | ||||
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| #include <xml-cxx/xml.hxx> | ||||
| #include <cppunit/TestFixture.h> | ||||
| #include <cppunit/ui/text/TestRunner.h> | ||||
| #include <cppunit/extensions/HelperMacros.h> | ||||
| #include <cppunit/extensions/TestFactoryRegistry.h> | ||||
| #include <cppunit/XmlOutputter.h> | ||||
| #include <fstream> | ||||
|  | ||||
| class A: public xml::Serialize { | ||||
|   public: | ||||
|     xml::Optional<int> _int; | ||||
|   protected: | ||||
|     void initXmlMembers() { | ||||
|       className("A"); | ||||
|       persist(_int, "int"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class B: public xml::Serialize { | ||||
|   public: | ||||
|     xml::Optional<long> _long; | ||||
|     xml::Optional<short> _short; | ||||
|   protected: | ||||
|     void initXmlMembers() { | ||||
|       className("B"); | ||||
|       persist(_long, "long"); | ||||
|       persist(_short, "short"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class B1: public B { | ||||
|   public: | ||||
|     xml::Optional<A> _a1; | ||||
|     xml::Optional<A> _a2; | ||||
|     xml::Optional<A> _a3; | ||||
|   protected: | ||||
|     void initXmlMembers() { | ||||
|       B::initXmlMembers(); | ||||
|       className("B1"); | ||||
|       persist(_a1, "a1"); | ||||
|       persist(_a2, "a2"); | ||||
|       persist(_a3, "a3"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class OptionalSerializationTest: public CppUnit::TestFixture { | ||||
|   public: | ||||
|     void checkOptional() { | ||||
|       std::string with("<A>\n" | ||||
|                        "\t<int>13</int>\n" | ||||
|                        "</A>"); | ||||
|       std::string without("<A/>"); | ||||
|       A a; | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("<A>\n" | ||||
|                                        "\t<int/>\n" | ||||
|                                        "</A>"), a.schema()); | ||||
|       std::stringstream ss1a(with); | ||||
|       CPPUNIT_ASSERT_NO_THROW(a.loadXml(ss1a)); | ||||
|       CPPUNIT_ASSERT_EQUAL(true, (bool)a._int); | ||||
|       CPPUNIT_ASSERT_EQUAL(13, *a._int); | ||||
|       std::stringstream ss1b; | ||||
|       CPPUNIT_ASSERT_NO_THROW(a.saveXml(ss1b)); | ||||
|       CPPUNIT_ASSERT_EQUAL(with, ss1b.str()); | ||||
|       std::stringstream ss2a(without); | ||||
|       CPPUNIT_ASSERT_NO_THROW(a.loadXml(ss2a)); | ||||
|       CPPUNIT_ASSERT_EQUAL(false, (bool)a._int); | ||||
|       std::stringstream ss2b; | ||||
|       CPPUNIT_ASSERT_NO_THROW(a.saveXml(ss2b)); | ||||
|       CPPUNIT_ASSERT_EQUAL(without, ss2b.str()); | ||||
|     } | ||||
|     void checkMoreOptional() { | ||||
|       std::string first("<B1>\n" | ||||
|                         "\t<short>13</short>\n" | ||||
|                         "\t<a2/>\n" | ||||
|                         "\t<a3>\n" | ||||
|                         "\t\t<int>42</int>\n" | ||||
|                         "\t</a3>\n" | ||||
|                         "</B1>"); | ||||
|       B1 b; | ||||
|       std::stringstream ifirst(first); | ||||
|       CPPUNIT_ASSERT_NO_THROW(b.loadXml(ifirst)); | ||||
|       CPPUNIT_ASSERT_EQUAL(false, (bool)b._long); | ||||
|       CPPUNIT_ASSERT_EQUAL(true, (bool)b._short); | ||||
|       CPPUNIT_ASSERT_EQUAL((short)13, *b._short); | ||||
|       CPPUNIT_ASSERT_EQUAL(false, (bool)b._a1); | ||||
|       CPPUNIT_ASSERT_EQUAL(true, (bool)b._a2); | ||||
|       CPPUNIT_ASSERT_EQUAL(false, (bool)b._a2->_int); | ||||
|       CPPUNIT_ASSERT_EQUAL(true, (bool)b._a3); | ||||
|       CPPUNIT_ASSERT_EQUAL(true, (bool)b._a3->_int); | ||||
|       CPPUNIT_ASSERT_EQUAL(42, *b._a3->_int); | ||||
|       std::stringstream ofirst; | ||||
|       CPPUNIT_ASSERT_NO_THROW(b.saveXml(ofirst)); | ||||
|       CPPUNIT_ASSERT_EQUAL(first, ofirst.str()); | ||||
|     } | ||||
|     CPPUNIT_TEST_SUITE(OptionalSerializationTest); | ||||
|     CPPUNIT_TEST(checkOptional); | ||||
|     CPPUNIT_TEST(checkMoreOptional); | ||||
|     CPPUNIT_TEST_SUITE_END(); | ||||
| }; | ||||
| CPPUNIT_TEST_SUITE_REGISTRATION(OptionalSerializationTest); | ||||
|  | ||||
| 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: "<<e.what()<<std::endl; | ||||
|   return 1; | ||||
|  } | ||||
		Reference in New Issue
	
	Block a user