// file : tests/parser/driver.cxx // copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #ifdef NDEBUG # error tests require enabled assert(); un-define the NDEBUG macro #endif #include #include #include #include #include using namespace std; using namespace xml; int main () { // Test error handling. // try { istringstream is ("X"); parser p (is, "test"); assert (p.next () == parser::start_element); assert (p.next () == parser::start_element); assert (p.next () == parser::characters && p.value () == "X"); p.next (); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } try { istringstream is (""); is.exceptions (ios_base::badbit | ios_base::failbit); parser p (is, "test"); is.setstate (ios_base::badbit); p.next (); assert (false); } catch (const ios_base::failure&) { } // Test the next_expect() functionality. // { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root"); p.next_expect (parser::end_element); } try { istringstream is (""); parser p (is, "test"); p.next_expect (parser::end_element); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } try { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root1"); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } // Test namespace declarations. // { // Followup end element event that should be precedeeded by end // namespace declaration. // istringstream is (""); parser p (is, "test", parser::receive_default | parser::receive_namespace_decls); p.next_expect (parser::start_element, "root"); p.next_expect (parser::start_namespace_decl); p.next_expect (parser::end_namespace_decl); p.next_expect (parser::end_element); } // Test value extraction. // { istringstream is ("123"); parser p (is, "test"); p.next_expect (parser::start_element, "root"); p.next_expect (parser::characters); assert (p.value () == 123); p.next_expect (parser::end_element); } // Test attribute maps. // { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root"); assert (p.attribute ("a") == "a"); assert (p.attribute ("b", "B") == "b"); assert (p.attribute ("c", "C") == "C"); assert (p.attribute ("d") == 123); assert (p.attribute ("t") == true); assert (p.attribute ("f", false) == false); p.next_expect (parser::end_element); } { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root"); assert (p.attribute ("a") == "a"); assert (p.peek () == parser::start_element && p.name () == "nested"); assert (p.attribute ("a") == "a"); p.next_expect (parser::start_element, "nested"); assert (p.attribute ("a") == "A"); p.next_expect (parser::start_element, "inner"); assert (p.attribute ("a", "") == ""); p.next_expect (parser::end_element); assert (p.attribute ("a") == "A"); assert (p.peek () == parser::end_element); assert (p.attribute ("a") == "A"); // Still valid. p.next_expect (parser::end_element); assert (p.attribute ("a") == "a"); p.next_expect (parser::end_element); assert (p.attribute ("a", "") == ""); } try { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root"); assert (p.attribute ("a") == "a"); p.next_expect (parser::end_element); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } try { istringstream is (""); parser p (is, "test"); p.next_expect (parser::start_element, "root"); p.attribute ("a"); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } // Test peeking and getting the current event. // { istringstream is ("x"); parser p (is, "peek", parser::receive_default | parser::receive_attributes_event); assert (p.event () == parser::eof); assert (p.peek () == parser::start_element); assert (p.next () == parser::start_element); assert (p.event () == parser::start_element); assert (p.peek () == parser::start_attribute); assert (p.event () == parser::start_attribute); assert (p.next () == parser::start_attribute); assert (p.peek () == parser::characters && p.value () == "x"); assert (p.next () == parser::characters && p.value () == "x"); assert (p.event () == parser::characters && p.value () == "x"); assert (p.peek () == parser::end_attribute); assert (p.event () == parser::end_attribute); assert (p.next () == parser::end_attribute); assert (p.peek () == parser::characters && p.value () == "x"); assert (p.next () == parser::characters && p.value () == "x"); assert (p.event () == parser::characters && p.value () == "x"); assert (p.peek () == parser::start_element); assert (p.next () == parser::start_element); assert (p.event () == parser::start_element); assert (p.peek () == parser::end_element); assert (p.next () == parser::end_element); assert (p.event () == parser::end_element); assert (p.peek () == parser::end_element); assert (p.next () == parser::end_element); assert (p.event () == parser::end_element); assert (p.peek () == parser::eof); assert (p.next () == parser::eof); assert (p.event () == parser::eof); } // Test content processing. // // empty // { istringstream is (" \n\t "); parser p (is, "empty", parser::receive_default | parser::receive_attributes_event); assert (p.next () == parser::start_element); p.content (parser::empty); assert (p.next () == parser::start_attribute); assert (p.next () == parser::characters && p.value () == " x "); assert (p.next () == parser::end_attribute); assert (p.next () == parser::end_element); assert (p.next () == parser::eof); } try { istringstream is (" \n & X \t "); parser p (is, "empty"); assert (p.next () == parser::start_element); p.content (parser::empty); p.next (); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } // simple // { istringstream is (" X "); parser p (is, "simple"); assert (p.next () == parser::start_element); p.content (parser::simple); assert (p.next () == parser::characters && p.value () == " X "); assert (p.next () == parser::end_element); assert (p.next () == parser::eof); } try { istringstream is (" ? "); parser p (is, "simple"); assert (p.next () == parser::start_element); p.content (parser::simple); assert (p.next () == parser::characters && p.value () == " ? "); p.next (); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } { // Test content accumulation in simple content. // istringstream is ("123"); parser p (is, "simple", parser::receive_default | parser::receive_namespace_decls); assert (p.next () == parser::start_element); p.next_expect (parser::start_namespace_decl); p.content (parser::simple); assert (p.next () == parser::characters && p.value () == "123"); p.next_expect (parser::end_namespace_decl); assert (p.next () == parser::end_element); assert (p.next () == parser::eof); } try { // Test error handling in accumulation in simple content. // istringstream is ("123"); parser p (is, "simple", parser::receive_default | parser::receive_namespace_decls); assert (p.next () == parser::start_element); p.next_expect (parser::start_namespace_decl); p.content (parser::simple); p.next (); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } // complex // { istringstream is ("\n" " \n" " \n" " X \n" " \n" "\n"); parser p (is, "complex", parser::receive_default | parser::receive_attributes_event); assert (p.next () == parser::start_element); // root p.content (parser::complex); assert (p.next () == parser::start_attribute); assert (p.next () == parser::characters && p.value () == " x "); assert (p.next () == parser::end_attribute); assert (p.next () == parser::start_element); // nested p.content (parser::complex); assert (p.next () == parser::start_element); // inner p.content (parser::empty); assert (p.next () == parser::end_element); // inner assert (p.next () == parser::start_element); // inner p.content (parser::simple); assert (p.next () == parser::characters && p.value () == " X "); assert (p.next () == parser::end_element); // inner assert (p.next () == parser::end_element); // nested assert (p.next () == parser::end_element); // root assert (p.next () == parser::eof); } try { istringstream is (" \n X X "); parser p (is, "complex"); assert (p.next () == parser::start_element); p.content (parser::complex); assert (p.next () == parser::start_element); assert (p.next () == parser::end_element); p.next (); assert (false); } catch (const xml::exception&) { // cerr << e.what () << endl; } }