#define BOOST_TEST_MODULE root_element_test /* * This test module contains several generators for * the SVG root element. */ // boost.test #include <boost/test/included/unit_test.hpp> // boost.spirit #include <boost/spirit/include/karma.hpp> #include <boost/spirit/repository/include/karma_confix.hpp> // boost #include <boost/fusion/tuple.hpp> // stl #include <string> #include <sstream> namespace karma = boost::spirit::karma; namespace repository = boost::spirit::repository; namespace fusion = boost::fusion; using namespace karma; struct F { F() : width(100), height(100), version(1.1), xmlns("http://www.w3.org/2000/svg"), expected_output("<svg width=\"100px\" height=\"100px\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">") {} ~F() {} const int width; const int height; const float version; const std::string xmlns; const std::string expected_output; std::ostringstream actual_output; }; /* * This test case uses one compound generator to generate the SVG element. * * It makes only one call to the format function and uses an ostringstream * as its output destination. * * The attribute values are provided as arguments to the format function. * The disadvantage of this is that the number of arguments is limited * by the preprocessor constant SPIRIT_ARGUMENTS_LIMIT, whose default * value is 10. The advantage is that they can be of any type (as long * as they are compatible with the corresponding generator type). */ BOOST_FIXTURE_TEST_CASE(bgcolor_stream_test_case, F) { actual_output << format( "<svg width=\"" << int_ << string << "\" " << "height=\"" << int_ << string << "\" " << "version=\"" << float_ << "\" " << "xmlns=\"" << string << "\"" << ">", width, "px", height, "px", version, xmlns); BOOST_CHECK_EQUAL(actual_output.str(), expected_output); } /* * This test case uses confix to wrap each xml attribute's value * inside double quotes. * * Notice that the generators' attribute list contains also tuples. * Tuples are needed to specify each confix's attributes that contain * more than one generator, like confix()[int_ << string] (this * generator needs a tuple: tuple<int, string>). * * The difference between this generator and the one in test case * 'bgcolor_stream_test_case' is the use of less << operators and * a more clean handling of double quotes. */ BOOST_FIXTURE_TEST_CASE(bgcolor_stream_confix_test_case, F) { using repository::confix; using fusion::tuple; actual_output << format( "<svg width=" << confix('"', '"')[int_ << string] << " height=" << confix('"', '"')[int_ << string] << " version=" << confix('"', '"')[float_] << " xmlns=" << confix('"', '"')[string] << ">", tuple<int, std::string>(width, "px"), tuple<int, std::string>(height, "px"), version, xmlns); BOOST_CHECK_EQUAL(actual_output.str(), expected_output); } /* * This test case generates the angle brackets of the svg/xml tag * using confix. notice that a confix generator can be part of another * confix generator's expression. * * Notice also that the attribute list is the same as in * 'bgcolor_stream_confix_test_case'. From this one can see that each * generator is meant to have a list of attributes if it has more than one. * * If the generator is nested inside another generator, the former's attribute * list will be another list (a tuple, for example) inside the latter's. */ BOOST_FIXTURE_TEST_CASE(bgcolor_stream_confix_complete_test_case, F) { using repository::confix; using fusion::tuple; actual_output << format( confix('<', ">")[ "svg width=" << confix('"', '"')[int_ << string] << " height=" << confix('"', '"')[int_ << string] << " version=" << confix('"', '"')[float_] << " xmlns=" << confix('"', '"')[string]], tuple<int, std::string>(width, "px"), tuple<int, std::string>(height, "px"), version, xmlns); BOOST_CHECK_EQUAL(actual_output.str(), expected_output); } /* * This test case uses an iterator to receive the generated * output. The iterator comes from the std::ostringstream that's * been used in the previous test cases, so the output is * actually generated into the stream. * * Using iterators instead of streams has the advantage that * more advanced concepts are implemented in karma for them, * like rules and grammars. */ BOOST_FIXTURE_TEST_CASE(bgcolor_stream_iterator_test_case, F) { using repository::confix; using fusion::tuple; std::ostream_iterator<char> actual_output_iterator(actual_output); generate( actual_output_iterator, confix("<", ">")[ "svg width=" << confix('"', '"')[int_ << string] << " height=" << confix('"', '"')[int_ << string] << " version=" << confix('"', '"')[float_] << " xmlns=" << confix('"', '"')[string]], tuple<int, std::string>(width, "px"), tuple<int, std::string>(height, "px"), version, xmlns); BOOST_CHECK_EQUAL(actual_output.str(), expected_output); }