//CUPPA:include=+
//CUPPA:include=-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestAssert.h>

//CUPPA:namespace=+
//CUPPA:namespace=-

#include <akaxiso/akaxiso.h>
#include <akaxiso/content_model.h>

namespace {
  struct sample {
    aka2::wc_attributes attributes_;
  };

  struct sample_leaf : 
    public aka2::simplecontent<sample, sample_leaf>{
    void model() {
      any_attribute(&sample::attributes_);
    }
  };

}


class anyattrTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(anyattrTest);
//CUPPA:suite=+
  CPPUNIT_TEST(test_equals);
  CPPUNIT_TEST(test_not_equals0);
  CPPUNIT_TEST(test_not_equals1);
  CPPUNIT_TEST(test_not_equals2);
  CPPUNIT_TEST(test_copy);
  CPPUNIT_TEST(test_serialize);
  CPPUNIT_TEST(test_parse);
//CUPPA:suite=-
  CPPUNIT_TEST_SUITE_END();
private:

  // your stuff...

public:

  virtual void setUp() {
    aka2::initialize();
    aka2::doctype("attributes", sample_leaf());
  }
  virtual void tearDown() {
    aka2::uninitialize();
  }

//CUPPA:decl=+
  void test_equals() {
    sample s1, s2;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value1"));

    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));
    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value1"));

    bool res = aka2::equals(s1, s2, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", res);
  }
  void test_not_equals0() {
    sample s1, s2;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));

    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));
    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value1"));

    bool res = aka2::equals(s1, s2, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", !res);
  }

  void test_not_equals1() {
    sample s1, s2;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value1"));
    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));

    bool res = aka2::equals(s1, s2, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", !res);
  }
  void test_not_equals2() {
    sample s1, s2;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value1"));
    s2.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value0"));

    bool res = aka2::equals(s1, s2, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", !res);
  }

  void test_copy() {
    sample s1, s2;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value1"));
    aka2::copy_element(s2, s1, sample_leaf());
    bool res = aka2::equals(s1, s2, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Equality test failed.", res);
  }

  void test_serialize() {
    sample s1;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value1"));
    aka2::xml_serializer ser;
    std::ostringstream ostm;
    ser.serialize(s1, "attributes", ostm);
  }

  void test_parse() {
    sample s1;
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test0"), "value0"));
    s1.attributes_.push_back(aka2::wc_attribute(aka2::qname("test1"), "value1"));
    aka2::xml_serializer ser;
    std::ostringstream ostm;
    ser.serialize(s1, "attributes", ostm);

    aka2::xml_parser parser;
    aka2::document doc = parser.parse(ostm.rdbuf()->str());

    bool res = aka2::document_of(doc, "attributes");
    CPPUNIT_ASSERT_MESSAGE("Parsed document has wrong name.", res);

    sample *parsed = aka2::root_cast<sample>(doc);
    res = aka2::equals(s1, *parsed, sample_leaf());
    CPPUNIT_ASSERT_MESSAGE("Parsed document is not the same as the original.", res);
  }


//CUPPA:decl=-
};

//CUPPA:impl=+
//CUPPA:impl=-

CPPUNIT_TEST_SUITE_REGISTRATION(anyattrTest);
