159 lines
4.9 KiB
C++
159 lines
4.9 KiB
C++
|
#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);
|
||
|
}
|