/*! @file
@ id $ Id $
*/
// 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>
# include <memory>
class NodeTest : public CppUnit : : TestFixture {
public :
void constructorName ( ) {
xml : : Node t ( " test " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " test " ) , t . name ( ) ) ;
}
void clone ( ) {
xml : : Node t ( " test " ) ;
std : : unique_ptr < xml : : Node > p ( t . clone ( ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " test " ) , p - > name ( ) ) ;
}
void shift ( ) {
xml : : Node t ( " test " ) ;
t < < xml : : Node ( " yxz " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " yxz " ) , t [ " yxz " ] . name ( ) ) ;
}
void out ( ) {
xml : : Node t ( " test " ) ;
{ std : : stringstream ss ;
t . out ( ss ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " <test/> " ) , ss . str ( ) ) ;
}
{ std : : stringstream ss ;
t < < xml : : Node ( " ABC " ) ;
t . out ( ss ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " <test> \n \t <ABC/> \n </test> " ) ,
ss . str ( ) ) ;
}
}
void operatorParenses ( ) {
xml : : Node t ( " test " ) ;
t < < xml : : Node ( " yxz " ) ;
CPPUNIT_ASSERT_EQUAL ( true , t ( " yxz " ) ) ;
CPPUNIT_ASSERT_EQUAL ( false , t ( " zxy " ) ) ;
}
void operatorBrackets ( ) {
xml : : Node t ( " test " ) ;
t < < xml : : Node ( " yxz " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " yxz " ) , t [ " yxz " ] . name ( ) ) ;
CPPUNIT_ASSERT_THROW ( t [ " zxy " ] , xml : : access_error ) ;
}
void in ( ) {
//! @todo
}
void text ( ) {
xml : : Node t ( " test " ) ;
CPPUNIT_ASSERT_THROW ( t . text ( " Hallo Welt " ) , xml : : tag_expected ) ;
}
void textOut ( ) {
xml : : Node t ( " test " ) ;
t < < xml : : String ( " yxc " ) . text ( " Hello " ) < < xml : : String ( " dfg " ) . text ( " World " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " HelloWorld " ) , t . text ( ) ) ;
}
void dereference ( ) {
xml : : Node t ( " test " ) ;
t < < xml : : Node ( " yxc " ) < < xml : : Node ( " dfg " ) ;
CPPUNIT_ASSERT_EQUAL ( t . text ( ) , * t ) ;
}
void assign ( ) {
xml : : Node t ( " test " ) ;
CPPUNIT_ASSERT_THROW ( ( t = " Hallo Welt " ) , xml : : tag_expected ) ;
}
CPPUNIT_TEST_SUITE ( NodeTest ) ;
CPPUNIT_TEST ( constructorName ) ;
CPPUNIT_TEST ( clone ) ;
CPPUNIT_TEST ( operatorBrackets ) ;
CPPUNIT_TEST ( shift ) ;
CPPUNIT_TEST ( out ) ;
CPPUNIT_TEST ( operatorParenses ) ;
CPPUNIT_TEST ( in ) ;
CPPUNIT_TEST ( text ) ;
CPPUNIT_TEST ( textOut ) ;
CPPUNIT_TEST ( dereference ) ;
CPPUNIT_TEST ( assign ) ;
CPPUNIT_TEST_SUITE_END ( ) ;
} ;
CPPUNIT_TEST_SUITE_REGISTRATION ( NodeTest ) ;
class StringTest : public CppUnit : : TestFixture {
public :
void constructorName ( ) {
xml : : String t ( " test " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " test " ) , t . name ( ) ) ;
}
void clone ( ) {
xml : : String t ( " test " ) ;
std : : unique_ptr < xml : : Node > p ( t . clone ( ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " test " ) , p - > name ( ) ) ;
}
void shift ( ) {
xml : : String t ( " test " ) ;
CPPUNIT_ASSERT_THROW ( t < < xml : : String ( " yxz " ) , xml : : cannot_have_children ) ;
}
void out ( ) {
xml : : String t ( " test " ) ;
{ std : : stringstream ss ;
t . out ( ss ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " <test/> " ) , ss . str ( ) ) ;
}
{ std : : stringstream ss ;
( t = " ABC " ) . out ( ss ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " <test>ABC</test> " ) ,
ss . str ( ) ) ;
}
}
void operatorParenses ( ) {
xml : : String t ( " test " ) ;
CPPUNIT_ASSERT_EQUAL ( false , t ( " zxy " ) ) ;
}
void operatorBrackets ( ) {
xml : : String t ( " test " ) ;
CPPUNIT_ASSERT_THROW ( t [ std : : string ( " zxy " ) ] , xml : : access_error ) ;
}
void text ( ) {
xml : : String t ( " test " ) ;
t . text ( " Hallo Welt " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " Hallo Welt " ) , t . text ( ) ) ;
}
void textOut ( ) {
xml : : String t ( " test " ) ;
t = " yxc " ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " yxc " ) , t . text ( ) ) ;
}
void dereference ( ) {
xml : : String t ( " test " ) ;
t = " dfg " ;
CPPUNIT_ASSERT_EQUAL ( t . text ( ) , * t ) ;
}
void assign ( ) {
xml : : String t1 ( " test " ) , t2 ( t1 ) ;
t1 = " Hallo Welt " ;
t2 . text ( " Hallo Welt " ) ;
CPPUNIT_ASSERT_EQUAL ( t1 . text ( ) , t2 . text ( ) ) ;
}
CPPUNIT_TEST_SUITE ( StringTest ) ;
CPPUNIT_TEST ( constructorName ) ;
CPPUNIT_TEST ( clone ) ;
CPPUNIT_TEST ( operatorBrackets ) ;
CPPUNIT_TEST ( shift ) ;
CPPUNIT_TEST ( out ) ;
CPPUNIT_TEST ( operatorParenses ) ;
CPPUNIT_TEST ( text ) ;
CPPUNIT_TEST ( textOut ) ;
CPPUNIT_TEST ( dereference ) ;
CPPUNIT_TEST ( assign ) ;
CPPUNIT_TEST_SUITE_END ( ) ;
} ;
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 : : unique_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 : : wrong_start_tag ) ;
{
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 ( " <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 : : tag_expected ) ;
} {
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 " )
. attr ( " one " , xml : : mandatory )
. attr ( " two " , xml : : optional )
< < ( xml : : Node ( " child " )
< < xml : : String ( " childofchild " )
< < xml : : UnsignedInteger ( " number " ) )
< < xml : : Node ( " otherchild " ) ) ;
{
std : : stringstream file ( " <base></base> " ) ;
CPPUNIT_ASSERT_THROW ( factory . read ( file ) ,
xml : : mandatory_attribute_missing ) ;
} {
std : : stringstream file ( " <base one two three></base> " ) ;
CPPUNIT_ASSERT_THROW ( factory . read ( file ) , xml : : illegal_attribute ) ;
} {
std : : stringstream file ( " <base one/> " ) ;
CPPUNIT_ASSERT_NO_THROW ( factory . read ( file ) ) ;
} {
std : : stringstream file ( " <base one= \" abc def ghi \" /> " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " abc " ) ,
( * factory . read ( file ) ) . attribute ( " one " ) . front ( ) ) ;
} {
std : : stringstream file ( " <base one= \" abc def ghi \" /> " ) ;
CPPUNIT_ASSERT_EQUAL ( ( size_t ) 3 ,
( * factory . read ( file ) ) . attribute ( " one " ) . toList ( )
. size ( ) ) ;
} {
std : : stringstream file ( " <base one= \" abc \" /> " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " abc " ) ,
( * factory . read ( file ) ) . attribute ( " one " ) . front ( ) ) ;
} {
std : : stringstream file ( " <base one/> " ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " " ) ,
( * factory . read ( file ) ) . attribute ( " one " ) . front ( ) ) ;
}
}
void ranges ( ) {
xml : : Factory factory ( xml : : Node ( " base " )
< < xml : : Node ( " mandatory " , 1 , 1 )
< < xml : : Node ( " optional " , 0 , 1 ) ) ;
{
std : : stringstream file ( " <base><mandatory/><optional/></base> " ) ;
CPPUNIT_ASSERT_NO_THROW ( factory . read ( file ) ) ;
} {
std : : stringstream file ( " <base><optional/></base> " ) ;
CPPUNIT_ASSERT_THROW ( factory . read ( file ) ,
xml : : wrong_node_number ) ;
} {
std : : stringstream file ( " <base><mandatory/><optional/> "
" <optional/></base> " ) ;
CPPUNIT_ASSERT_THROW ( factory . read ( file ) ,
xml : : wrong_node_number ) ;
} {
std : : stringstream file ( " <base><mandatory/><mandatory/></base> " ) ;
CPPUNIT_ASSERT_THROW ( factory . read ( file ) ,
xml : : wrong_node_number ) ;
}
}
CPPUNIT_TEST_SUITE ( ComplexTest ) ;
CPPUNIT_TEST ( nodes ) ;
CPPUNIT_TEST ( attributes ) ;
CPPUNIT_TEST ( ranges ) ;
CPPUNIT_TEST_SUITE_END ( ) ;
} ;
CPPUNIT_TEST_SUITE_REGISTRATION ( ComplexTest ) ;
class FunTest : public CppUnit : : TestFixture {
public :
void playing ( ) {
std : : string contents ( " <html> \n \t <head> \n \t \t <title/> \n \t </head> \n "
" \t <body> \n \t \t <h1 class= \" main \" >Title</h1> "
" \n \t \t <p>First Paragraf.</p> \n \t \t <p/> \n "
" \t \t <h2/> \n \t \t <p/> \n \t \t <p/> \n \t </body> \n </html> " ) ;
xml : : Attributes attr ;
attr [ " class " ] = " main " ;
xml : : Node test ( xml : : Node ( " html " ) // example
< < ( xml : : Node ( " head " )
< < xml : : String ( " title " ) )
< < ( xml : : Node ( " body " )
< < ( xml : : String ( " h1 " )
< < ( xml : : Attributes ( )
< < ( xml : : Attr ( " class " ) = " main " ) ) )
< < xml : : String ( " p " )
< < xml : : String ( " p " )
< < xml : : String ( " h2 " )
< < xml : : String ( " p " )
< < xml : : String ( " p " ) ) ) ;
test [ " body " ] [ " h1 " ] = " Title " ;
test [ " body " ] [ " p " ] = " First Paragraf. " ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " main " ) ,
test [ " body " ] [ " h1 " ] . attr ( " class " ) ) ;
std : : stringstream ss ;
test . out ( ss ) ;
CPPUNIT_ASSERT_EQUAL ( contents , ss . str ( ) ) ;
xml : : Factory factory ( xml : : Node ( " html " ) // template
< < ( xml : : Node ( " head " )
< < xml : : String ( " title " ) )
< < ( xml : : Node ( " body " )
< < xml : : String ( " h1 " ) . attr ( " class " , xml : : optional )
< < xml : : String ( " h2 " )
< < xml : : String ( " p " ) ) ) ;
std : : unique_ptr < xml : : Node > read ( factory . read ( ss ) ) ; // read back the example
std : : stringstream ss2 ;
read - > out ( ss2 ) ;
CPPUNIT_ASSERT_EQUAL ( contents , ss2 . str ( ) ) ;
}
void project ( ) {
xml : : Factory applications ( xml : : Node ( " applications " )
< < ( xml : : Node ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional )
< < xml : : String ( " title " )
< < xml : : String ( " icon " )
< < xml : : String ( " info " )
< < ( xml : : String ( " prog " )
. attr ( " os " , xml : : optional ) )
< < ( xml : : Node ( " args " )
. attr ( " os " , xml : : optional )
< < xml : : String ( " arg " ) )
< < ( xml : : Node ( " env " )
. attr ( " os " , xml : : optional )
< < ( xml : : Node ( " var " )
. attr ( " name " , xml : : mandatory )
. attr ( " value " , xml : : optional ) ) )
< < ( xml : : Node ( " runtime " )
. attr ( " os " , xml : : optional )
< < ( xml : : Node ( " copy " )
. attr ( " from " , xml : : mandatory )
. attr ( " to " , xml : : mandatory )
. attr ( " os " , xml : : optional ) ) )
< < ( xml : : Node ( " buildtime " )
< < ( xml : : Node ( " copy " )
. attr ( " from " , xml : : mandatory )
. attr ( " to " , xml : : mandatory ) ) ) ) ) ;
xml : : Factory edition ( xml : : Node ( " edition " )
< < xml : : String ( " userfriendly-name " )
< < xml : : String ( " update-url " )
< < xml : : String ( " startpage " )
< < xml : : String ( " startsplash " )
< < xml : : String ( " endsplash " )
< < ( xml : : String ( " termination " )
. attr ( " terminate-on-media-removal " , xml : : optional )
. attr ( " terminate-children " , xml : : optional )
. attr ( " cleanup-files " , xml : : optional ) )
< < ( xml : : Node ( " startactions " )
. attr ( " os " , xml : : optional )
< < ( xml : : Node ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional )
< < xml : : String ( " splash " )
< < xml : : String ( " type " ) ) )
< < ( xml : : Node ( " stopactions " )
. attr ( " os " , xml : : optional )
< < ( xml : : Node ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional )
< < xml : : String ( " splash " ) ) )
< < ( xml : : Node ( " tree " )
< < ( xml : : String ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional ) )
< < ( xml : : Node ( " folder " )
. attr ( " open " , xml : : optional )
. attr ( " os " , xml : : optional )
< < xml : : String ( " title " )
< < xml : : String ( " icon " )
< < xml : : String ( " info " )
< < ( xml : : String ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional ) ) ) )
< < ( xml : : Node ( " toolbar " )
. attr ( " os " , xml : : optional )
< < ( xml : : String ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional ) ) )
< < ( xml : : Node ( " tray " )
. attr ( " os " , xml : : optional )
< < xml : : String ( " icon " )
< < ( xml : : String ( " application " )
. attr ( " id " , xml : : mandatory )
. attr ( " os " , xml : : optional ) ) ) ) ;
/*std::cout<<std::endl
< < * applications < < std : : endl
< < * edition < < std : : endl ; */
}
CPPUNIT_TEST_SUITE ( FunTest ) ;
CPPUNIT_TEST ( playing ) ;
CPPUNIT_TEST ( project ) ;
CPPUNIT_TEST_SUITE_END ( ) ;
} ;
CPPUNIT_TEST_SUITE_REGISTRATION ( FunTest ) ;
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 ;
}