much more tests; all exceptions in readin tested
This commit is contained in:
		| @@ -189,13 +189,6 @@ namespace xml { | ||||
|           stream_error("missing end tag, end of file reached", t, is, tag, c) { | ||||
|       } | ||||
|   }; | ||||
|   class empty_stream: public stream_error { | ||||
|     public: | ||||
|       empty_stream(const Node& t, std::istream& is, const Tag& tag, char c=0) | ||||
|           throw(): | ||||
|           stream_error("no xml tag found, stream is empty", t, is, tag, c) { | ||||
|       } | ||||
|   }; | ||||
|   class wrong_start_tag: public stream_error { | ||||
|     public: | ||||
|       wrong_start_tag(const Node& t, std::istream& is, const Tag& tag, char c=0) | ||||
| @@ -303,7 +296,8 @@ namespace xml { | ||||
|   //---------------------------------------------------------------------------- | ||||
|   //! An xml Node. | ||||
|   /*! XML Nodes may contain either text or other nodes, but not both | ||||
|       at the same time. */ | ||||
|       at the same time. This node can hold other nodes. For a Node for | ||||
|       text contents, see xml::String. */ | ||||
|   class Node { | ||||
|     private: | ||||
|       typedef std::vector<Node*> Contents; | ||||
| @@ -398,7 +392,7 @@ namespace xml { | ||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|                 second_slash_in_tag, character_after_slash, | ||||
|                 missing_end_tag, attribute_value_not_quoted, access_error, | ||||
|                 empty_stream, duplicate_attribute, attributes_in_end_tag); | ||||
|                 duplicate_attribute, attributes_in_end_tag); | ||||
|     private: | ||||
|       friend class stream_error; | ||||
|       Factory(); // not implemented | ||||
|   | ||||
							
								
								
									
										19
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -426,15 +426,13 @@ namespace xml { | ||||
|       throw(tag_expected, type_mismatch) { | ||||
|     std::string::size_type | ||||
|       start(txt.find_first_not_of(" \t\n\r")), | ||||
|       last(txt.find_last_of(" \t\n\r")); | ||||
|       last(txt.find_last_not_of(" \t\n\r")); | ||||
|     if (start==std::string::npos) { // empty - set to 0 | ||||
|       _text = "0"; | ||||
|       return *this; | ||||
|     } | ||||
|     if (txt.find_first_not_of | ||||
|         ("0123456789", start, | ||||
|          last!=std::string::npos?last-start+1:txt.size()-start) | ||||
|         !=std::string::npos) | ||||
|     std::string::size_type pos(txt.find_first_not_of("0123456789", start)); | ||||
|     if (pos<last || pos==last && last==start) | ||||
|       throw type_mismatch(*this, txt, | ||||
|                           "unsigned integer may only contain numbers"); | ||||
|     unsigned long i(0); | ||||
| @@ -463,24 +461,25 @@ namespace xml { | ||||
|       throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|             second_slash_in_tag, | ||||
|             character_after_slash, missing_end_tag, attribute_value_not_quoted, | ||||
|             access_error, empty_stream, duplicate_attribute, | ||||
|             access_error, duplicate_attribute, | ||||
|             attributes_in_end_tag) try { | ||||
|     _line=1; | ||||
|     std::auto_ptr<Node> node(_template->clone()); | ||||
|     node->clear(); | ||||
|     Tag res; | ||||
|     while (true) try { | ||||
|     while (true) { | ||||
|       res = tag(is, *node); | ||||
|       *node<<res.attributes; | ||||
|       switch (res.type) { | ||||
|         case END: throw wrong_end_tag(*node, is, res); | ||||
|         case EMPTY: return node; // empty | ||||
|         case START: return read(is, *_template); | ||||
|         case START: | ||||
|           if (!res.name.size()) throw tag_expected(*node, res.text); | ||||
|           if (node->name()!=res.name) throw wrong_start_tag(*node, is, res); | ||||
|           return read(is, *_template); | ||||
|           //! @todo store instead of ignore | ||||
|         case SPECIAL: break; | ||||
|       } | ||||
|     } catch (missing_end_tag&) { | ||||
|       throw empty_stream(*node, is, res); | ||||
|     } | ||||
|   } catch (exception& e) { | ||||
|     e.line(_line); | ||||
|   | ||||
| @@ -161,6 +161,106 @@ class StringTest: public CppUnit::TestFixture { | ||||
| }; | ||||
| CPPUNIT_TEST_SUITE_REGISTRATION(StringTest); | ||||
|  | ||||
| class ComplexTest: public CppUnit::TestFixture {  | ||||
|   public: | ||||
|     void nodes() { | ||||
|       xml::Factory factory(xml::Node("base") | ||||
|                            <<(xml::Node("child").attr("a", xml::optional) | ||||
|                               <<xml::String("childofchild") | ||||
|                               <<xml::UnsignedInteger("number")) | ||||
|                            <<xml::Node("otherchild")); | ||||
|       std::stringstream file1; | ||||
|       file1<<"<!DOCTYPE xyz>"<<std::endl | ||||
|            <<"<?xml 1.0 encoding=\"utf8\"?>"<<std::endl | ||||
|            <<"<base>"<<std::endl | ||||
|            <<"<child a=\"b\"><childofchild/><childofchild/><childofchild>" | ||||
|            <<"xxx</childofchild><number>13</number><number/><number>" | ||||
|            <<" 42  </number><number>   </number></child>" | ||||
|            <<"<child a=\"b\"/>" | ||||
|            <<"< otherchild ><  / otherchild  >< otherchild / >"<<std::endl | ||||
|            <<"</base>"; | ||||
|       std::auto_ptr<xml::Node> node(factory.read(file1)); // should work | ||||
|       CPPUNIT_ASSERT_EQUAL((size_t)2, node->list("child").size()); | ||||
|       CPPUNIT_ASSERT_EQUAL((size_t)3, (*node)[0].list("childofchild").size()); | ||||
|       CPPUNIT_ASSERT_EQUAL((size_t)4, (*node)[0].list("number").size()); | ||||
|       CPPUNIT_ASSERT_EQUAL((size_t)0, (*node)[1].list("childofchild").size()); | ||||
|       CPPUNIT_ASSERT_EQUAL((size_t)2, node->list("otherchild").size()); | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("xxx"), *(*node)["child"][2]); | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("13"), *(*node)["child"][3]); | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("0"), *(*node)["child"][4]); | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("42"), *(*node)["child"][5]); | ||||
|       CPPUNIT_ASSERT_EQUAL(std::string("0"), *(*node)["child"][6]); | ||||
|       std::stringstream file2; | ||||
|       file2<<"<!DOCTYPE xyz>"<<std::endl | ||||
|            <<"<?xml 1.0 encoding=\"utf8\"?>"<<std::endl | ||||
|            <<"<base>"<<std::endl | ||||
|            <<"<child><childofchild/><exception><childofchild/><childofchild>" | ||||
|            <<"xxx</childofchild></child>" | ||||
|            <<"<child/>" | ||||
|            <<"< otherchild ><  / otherchild  >< otherchild / >"<<std::endl | ||||
|            <<"</base>"; | ||||
|       CPPUNIT_ASSERT_THROW(factory.read(file2), xml::access_error); | ||||
|       { | ||||
|         std::stringstream file("<base></xyz>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::wrong_end_tag); | ||||
|       } { | ||||
|         std::stringstream file("<xyz></xyz>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::wrong_start_tag); | ||||
|       } { | ||||
|         std::stringstream file("base"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::tag_expected); | ||||
|       } { | ||||
|         std::stringstream file("<base>hallo</base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::tag_expected); | ||||
|       } { | ||||
|         std::stringstream file | ||||
|           ("<base><child><number>x</number></child></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::type_mismatch); | ||||
|       } { | ||||
|         std::stringstream file | ||||
|           ("<base><child><number>xyz</number></child></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::type_mismatch); | ||||
|       } { | ||||
|         std::stringstream file("<base><child></child/></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::second_slash_in_tag); | ||||
|       } { | ||||
|         std::stringstream file("<base><child><child/a></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::character_after_slash); | ||||
|       } { | ||||
|         std::stringstream file("<base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::missing_end_tag); | ||||
|       } { | ||||
|         std::stringstream file("<base><child>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::missing_end_tag); | ||||
|       } { | ||||
|         std::stringstream file; | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::missing_end_tag); | ||||
|       } { | ||||
|         std::stringstream file("<base><child a=b></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), | ||||
|                              xml::attribute_value_not_quoted); | ||||
|       } { | ||||
|         std::stringstream file("<base><child a=\"b\" a=\"b\"></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::duplicate_attribute); | ||||
|       } { | ||||
|         std::stringstream file("<base><child></child a=\"b\"></base>"); | ||||
|         CPPUNIT_ASSERT_THROW(factory.read(file), xml::attributes_in_end_tag); | ||||
|       } | ||||
|     } | ||||
|     void attributes() { | ||||
|       xml::Factory factory(xml::Node("base") | ||||
|                            <<(xml::Node("child") | ||||
|                               <<xml::String("childofchild") | ||||
|                               <<xml::UnsignedInteger("number")) | ||||
|                            <<xml::Node("otherchild")); | ||||
|     } | ||||
|     CPPUNIT_TEST_SUITE(ComplexTest); | ||||
|     CPPUNIT_TEST(nodes); | ||||
|     CPPUNIT_TEST(attributes); | ||||
|     CPPUNIT_TEST_SUITE_END(); | ||||
| }; | ||||
| CPPUNIT_TEST_SUITE_REGISTRATION(ComplexTest); | ||||
|  | ||||
| class FunTest: public CppUnit::TestFixture {  | ||||
|   public: | ||||
|     void playing() { | ||||
| @@ -276,9 +376,9 @@ class FunTest: public CppUnit::TestFixture { | ||||
|                               <<(xml::String("application") | ||||
|                                  .attr("id", xml::mandatory) | ||||
|                                  .attr("os", xml::optional)))); | ||||
|       std::cout<<std::endl | ||||
|                <<*applications<<std::endl | ||||
|                <<*edition<<std::endl; | ||||
|       /*std::cout<<std::endl | ||||
|           <<*applications<<std::endl | ||||
|           <<*edition<<std::endl;*/ | ||||
|     } | ||||
|     CPPUNIT_TEST_SUITE(FunTest); | ||||
|     CPPUNIT_TEST(playing); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user