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

#include "../src/MiX/Document.h"
#include "../src/MiX/Element.h"
#include "../src/MiX/Attribute.h"
#include "../src/MiX/Text.h"

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

class ElementTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(ElementTest);
//CUPPA:suite=+
  CPPUNIT_TEST(testCreate);
  CPPUNIT_TEST(testString);
  CPPUNIT_TEST(testClone);
  CPPUNIT_TEST(testOtherOps);
  CPPUNIT_TEST(testDestroy);
//CUPPA:suite=-
  CPPUNIT_TEST_SUITE_END();
private:

  // your stuff...
  static MiX::Document<char>* doc_;
public:

  virtual void setUp() { /* initialize */ }
  virtual void tearDown() { /* terminate */ }

  //CUPPA:decl=+
  void testCreate() {
    //こーいうドキュメントを作る
    // <?xml version="1.0" encoding="UTF-8"?>
    // <TestSuite name="DocumentTest">
    // <TestCase name="testCreate"/>
    // <TestCase name="testString"/>
    // <Description>This is test for MiX::Document</Description>
    // </TestSuite>
    doc_ = &(MiX::Document<char>::create("TestSuite"));
    CPPUNIT_ASSERT_EQUAL(doc_->getType(),MiX::Node_Document);
    MiX::Attribute<char>::create("version","1.0",*doc_);
    MiX::Attribute<char>::create("encoding","UTF-8",*doc_);
    MiX::Element<char>& el = doc_->getRoot();
    MiX::Attribute<char>::create("name","DocumentTest",el);
    MiX::Attribute<char>::create("name","testCreate",
				 MiX::Element<char>::create("TestCase",el));
    MiX::Attribute<char>::create("name","testString",
				 MiX::Element<char>::create("TestCase",el));
    MiX::Text<char>::create("This is test for MiX::Document",
			    MiX::Element<char>::create("Description",el));
  }
  void testString() {
    std::string data[] = {
      "<TestCase name=\"testCreate\"/>",
      "<TestCase name=\"testString\"/>",
      "<Description>This is test for MiX::Document</Description>",
    };
    CPPUNIT_ASSERT(doc_->getRoot()("TestCase").toString()==data[0]);
    CPPUNIT_ASSERT(doc_->getRoot()("TestCase",1).toString()==data[1]);
    CPPUNIT_ASSERT(doc_->getRoot()("Description").toString()==data[2]);
  }
  void testClone() {
    const char data[] = {
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<TestSuite name=\"DocumentTest\">"
      "<TestCase name=\"testCreate\"/>"
      "<TestCase name=\"testString\"/>"
      "<Description>This is test for MiX::Document</Description>"
      "<TestCase name=\"testCreate\"/>"
      "<TestCase name=\"testString\"/>"
      "</TestSuite>"
    };
    doc_->getRoot()("TestCase").clone(doc_->getRoot());
    doc_->getRoot()("TestCase",1).clone(doc_->getRoot());
    CPPUNIT_ASSERT(doc_->toString()==data);
  }
  void testOtherOps() {
    const char data[] = {
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<TestSuite name=\"DocumentTest\">"
      "<CrackedTest name=\"testCreate\"/>"
      "<CrackedTest name=\"testString\"/>"
      "<CrackedElement>Cracked :)</CrackedElement>"
      "<CrackedTest name=\"testCreate\"/>"
      "<CrackedTest name=\"testString\"/>"
      "</TestSuite>"
    };
    for(int n=0;n<2;++n){
      CPPUNIT_ASSERT(doc_->getRoot()("TestCase",n*2)["name"].getValue()=="testCreate");
      CPPUNIT_ASSERT(doc_->getRoot()("TestCase",n*2+1)["name"].getValue()=="testString");
    };
    CPPUNIT_ASSERT(doc_->getRoot()("Description").getText()=="This is test for MiX::Document");
    doc_->getRoot()("Description").setText("Cracked :)");
    doc_->getRoot()("Description").setName("CrackedElement");
    MiX::NodeList<char> lst = doc_->getRoot().getElementsByTagName("TestCase");
    CPPUNIT_ASSERT_EQUAL(4,(int)lst.size());
    MiX::NodeList<char>::iterator it = lst.begin();
    MiX::NodeList<char>::iterator last = lst.end();
    for( ; it != last ; ++it ){
      CPPUNIT_ASSERT_EQUAL(MiX::Node_Element,(*it)->getType());
      MiX::Element<char>& el = dynamic_cast<MiX::Element<char>&>(**it);
      CPPUNIT_ASSERT(el.getName()=="TestCase");
      el.setName("CrackedTest");
    }
    CPPUNIT_ASSERT(doc_->toString()==data);
  }
  void testDestroy() {
    doc_->destroy();
  }
//CUPPA:decl=-
};

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

MiX::Document<char>* ElementTest::doc_ = 0;

CPPUNIT_TEST_SUITE_REGISTRATION(ElementTest);
