text: #include <cppunit/XmlOutputter.h>
  #include <cppunit/TestFailure.h>
  #include <cppunit/XmlOutputter.h>
  #include <cppunit/XmlOutputterHook.h>
  #include "OutputSuite.h"
  #include "XmlOutputterTest.h"
  #include "XmlUniformiser.h"
  
  
  CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XmlOutputterTest, 
                                         outputSuiteName() );
  
  
  XmlOutputterTest::XmlOutputterTest()
  {
  }
  
  
  XmlOutputterTest::~XmlOutputterTest()
  {
  }
  
  
  void 
  XmlOutputterTest::setUp()
  {
    m_dummyTests.clear();
    m_result = new CPPUNIT_NS::TestResultCollector();
  }
  
  
  void 
  XmlOutputterTest::tearDown()
  {
    delete m_result;
    for ( unsigned int index =0; index < m_dummyTests.size(); ++index )
      delete m_dummyTests[index];
    m_dummyTests.clear();
  }
  
  
  void 
  XmlOutputterTest::testWriteXmlResultWithNoTest()
  {
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.write();
  
    std::string actualXml = stream.str();
    std::string expectedXml = 
      "<TestRun>"
        "<FailedTests></FailedTests>"
        "<SuccessfulTests></SuccessfulTests>"
        "<Statistics>"
          "<Tests>0</Tests>"
          "<FailuresTotal>0</FailuresTotal>"
          "<Errors>0</Errors>"
          "<Failures>0</Failures>"
        "</Statistics>"
      "</TestRun>";
    CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml );
  }
  
  
  void 
  XmlOutputterTest::testWriteXmlResultWithOneFailure()
  {
    addTestFailure( "test1", "message failure1", CPPUNIT_NS::SourceLine( "test.cpp", 3 ) );
  
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.write();
  
    std::string actualXml = stream.str();
    std::string expectedXml = 
      "<TestRun>"
        "<FailedTests>"
          "<FailedTest id=\"1\">"
            "<Name>test1</Name>"
            "<FailureType>Assertion</FailureType>"
            "<Location>"
              "<File>test.cpp</File>"
              "<Line>3</Line>"
            "</Location>"
            "<Message>message failure1</Message>"
          "</FailedTest>"
        "</FailedTests>"
        "<SuccessfulTests></SuccessfulTests>"
        "<Statistics>"
          "<Tests>1</Tests>"
          "<FailuresTotal>1</FailuresTotal>"
          "<Errors>0</Errors>"
          "<Failures>1</Failures>"
        "</Statistics>"
      "</TestRun>";
    CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml );
  }
  
  
  void 
  XmlOutputterTest::testWriteXmlResultWithOneError()
  {
    addTestError( "test1", "message error1" );
  
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.write();
  
    std::string actualXml = stream.str();
    std::string expectedXml = 
      "<TestRun>"
        "<FailedTests>"
          "<FailedTest id=\"1\">"
            "<Name>test1</Name>"
            "<FailureType>Error</FailureType>"
            "<Message>message error1</Message>"
          "</FailedTest>"
        "</FailedTests>"
        "<SuccessfulTests></SuccessfulTests>"
        "<Statistics>"
          "<Tests>1</Tests>"
          "<FailuresTotal>1</FailuresTotal>"
          "<Errors>1</Errors>"
          "<Failures>0</Failures>"
        "</Statistics>"
      "</TestRun>";
    CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml );
  }
  
  
  void 
  XmlOutputterTest::testWriteXmlResultWithOneSuccess()
  {
    addTest( "test1" );
  
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.write();
  
    std::string actualXml = stream.str();
    std::string expectedXml = 
      "<TestRun>"
        "<FailedTests></FailedTests>"
        "<SuccessfulTests>"
          "<Test id=\"1\">"
            "<Name>test1</Name>"
          "</Test>"
        "</SuccessfulTests>"
        "<Statistics>"
          "<Tests>1</Tests>"
          "<FailuresTotal>0</FailuresTotal>"
          "<Errors>0</Errors>"
          "<Failures>0</Failures>"
        "</Statistics>"
      "</TestRun>";
    CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml );
  }
  
  
  void 
  XmlOutputterTest::testWriteXmlResultWithThreeFailureTwoErrorsAndTwoSuccess()
  {
    addTestFailure( "test1", "failure1" );
    addTestError( "test2", "error1" );
    addTestFailure( "test3", "failure2" );
    addTestFailure( "test4", "failure3" );
    addTest( "test5" );
    addTestError( "test6", "error2" );
    addTest( "test7" );
  
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.write();
  
    std::string actualXml = stream.str();
    std::string expectedXml = 
      "<TestRun>"
         "<FailedTests>"
          "<FailedTest id=\"1\">"
            "<Name>test1</Name>"
            "<FailureType>Assertion</FailureType>"
            "<Message>failure1</Message>"
          "</FailedTest>"
          "<FailedTest id=\"2\">"
            "<Name>test2</Name>"
            "<FailureType>Error</FailureType>"
            "<Message>error1</Message>"
          "</FailedTest>"
          "<FailedTest id=\"3\">"
            "<Name>test3</Name>"
            "<FailureType>Assertion</FailureType>"
            "<Message>failure2</Message>"
          "</FailedTest>"
          "<FailedTest id=\"4\">"
            "<Name>test4</Name>"
            "<FailureType>Assertion</FailureType>"
            "<Message>failure3</Message>"
          "</FailedTest>"
          "<FailedTest id=\"6\">"
            "<Name>test6</Name>"
            "<FailureType>Error</FailureType>"
            "<Message>error2</Message>"
          "</FailedTest>"
        "</FailedTests>"
       "<SuccessfulTests>"
          "<Test id=\"5\">"
            "<Name>test5</Name>"
          "</Test>"
          "<Test id=\"7\">"
            "<Name>test7</Name>"
          "</Test>"
        "</SuccessfulTests>"
        "<Statistics>"
          "<Tests>7</Tests>"
          "<FailuresTotal>5</FailuresTotal>"
          "<Errors>2</Errors>"
          "<Failures>3</Failures>"
        "</Statistics>"
      "</TestRun>";
    CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml );
  }
  
  
  class XmlOutputterTest::MockHook : public CPPUNIT_NS::XmlOutputterHook
  {
  public:
    MockHook( int &beginCalls,
              int &endCalls,
              int &statisticsCalls,
              int &successfulTestCalls,
              int &failedTestCalls )
        : m_successfulTestCalls( successfulTestCalls )
        , m_failedTestCalls( failedTestCalls )
        , m_beginCalls( beginCalls )
        , m_endCalls( endCalls )
        , m_statisticsCalls( statisticsCalls )
    {
    }
  
    void beginDocument( CPPUNIT_NS::XmlDocument *document )
    {
      ++m_beginCalls;
    }
  
    void endDocument( CPPUNIT_NS::XmlDocument *document )
    {
      ++m_endCalls;
    }
  
    void failTestAdded( CPPUNIT_NS::XmlDocument *document,
                        CPPUNIT_NS::XmlElement *testElement,
                        CPPUNIT_NS::Test *test,
                        CPPUNIT_NS::TestFailure *failure )
    {
      ++m_failedTestCalls;
    }
  
    void successfulTestAdded( CPPUNIT_NS::XmlDocument *document,
                              CPPUNIT_NS::XmlElement *testElement,
                              CPPUNIT_NS::Test *test )
    {
      ++m_successfulTestCalls;
    }
  
    void statisticsAdded( CPPUNIT_NS::XmlDocument *document,
                          CPPUNIT_NS::XmlElement *statisticsElement )
    {
      ++m_statisticsCalls;
    }
  
  private:
    int &m_beginCalls;
    int &m_endCalls;
    int &m_statisticsCalls;
    int &m_successfulTestCalls;
    int &m_failedTestCalls;
  };
  
  
  void 
  XmlOutputterTest::testHook()
  {
    int begin =0, end =0, statistics =0, successful =0, failed =0;
    MockHook hook( begin, end, statistics, successful, failed );
  
    addTest( "test1" );
    addTest( "test2" );
    addTest( "test3" );
    addTestFailure( "testfail1", "assertion failed" );
    addTestError( "testerror1", "exception" );
  
    CPPUNIT_NS::OStringStream stream;
    CPPUNIT_NS::XmlOutputter outputter( m_result, stream );
    outputter.addHook( &hook );
    outputter.write();
  
    CPPUNIT_ASSERT_EQUAL( 1, begin );
    CPPUNIT_ASSERT_EQUAL( 1, end );
    CPPUNIT_ASSERT_EQUAL( 1, statistics );
    CPPUNIT_ASSERT_EQUAL( 3, successful );
    CPPUNIT_ASSERT_EQUAL( 2, failed );
  }
  
  
  void 
  XmlOutputterTest::addTest( std::string testName )
  {
    CPPUNIT_NS::Test *test = makeDummyTest( testName );
    m_result->startTest( test );
    m_result->endTest( test );
  }
  
  
  void 
  XmlOutputterTest::addTestFailure( std::string testName,
                                    std::string message,
                                    CPPUNIT_NS::SourceLine sourceLine )
  {
    addGenericTestFailure( testName, CPPUNIT_NS::Message(message), sourceLine, false );
  }
  
  
  void 
  XmlOutputterTest::addTestError( std::string testName,
                                  std::string message,
                                  CPPUNIT_NS::SourceLine sourceLine )
  {
    addGenericTestFailure( testName, CPPUNIT_NS::Message(message), sourceLine, true );
  }
  
  
  void 
  XmlOutputterTest::addGenericTestFailure(  std::string testName,
                                            CPPUNIT_NS::Message message,
                                            CPPUNIT_NS::SourceLine sourceLine,
                                            bool isError )
  {
    CPPUNIT_NS::Test *test = makeDummyTest( testName );
    m_result->startTest( test );
    CPPUNIT_NS::TestFailure failure( test, 
                                  new CPPUNIT_NS::Exception( message, sourceLine ),
                                  isError );
    m_result->addFailure( failure );
    m_result->endTest( test );
  }
  
  
  CPPUNIT_NS::Test *
  XmlOutputterTest::makeDummyTest( std::string testName )
  {
    CPPUNIT_NS::Test *test = new CPPUNIT_NS::TestCase( testName );
    m_dummyTests.push_back( test );
    return test;
  }
  
  