/*
 * c++check - c/c++ syntax checking
 * Copyright (C) 2007 Daniel Marjamäki
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/
 */





#include "testsuite.h"

#include <iostream>
#include <list>



/**
 * TestRegistry
 **/

class TestRegistry
{
private:
    std::list<TestFixture *> _tests;

public:
    static TestRegistry &theInstance()
    {
        static TestRegistry testreg;
        return testreg;
    }

    void addTest( TestFixture *t )
    {
        _tests.push_back( t );
    }

    void removeTest( TestFixture *t )
    {
        _tests.remove( t );
    }

    const std::list<TestFixture *> &tests() const
    {
        return _tests;
    }
};




/**
 * TestFixture
 **/

std::ostringstream TestFixture::errmsg;
unsigned int       TestFixture::countTests;

TestFixture::TestFixture(const std::string &_name) : classname(_name)
{
    TestRegistry::theInstance().addTest(this);
}

/*
TestFixture::~TestFixture()
{
    TestRegistry::theInstance().removeTest(this);
}
*/

bool TestFixture::runTest(const char testname[])
{
    countTests++;
    std::cout << classname << "::" << testname << "\n";
    return true;
}

void TestFixture::assertFail(const char *filename, int linenr)
{
    errmsg << "Assertion failed in " << filename << " at line " << linenr << std::endl;
}

void TestFixture::printTests()
{
    const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();

    for ( std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it )
    {
        std::cout << (*it)->classname << std::endl;
    }
}

void TestFixture::runTests(const char cmd[])
{
    std::string classname(cmd ? cmd : "");
    std::string testname("");
    if ( classname.find("::") != std::string::npos )
    {
        testname = classname.substr( classname.find("::") + 2 );
        classname.erase( classname.find("::") );
    }

    countTests = 0;
    errmsg.str("");

    const std::list<TestFixture *> &tests = TestRegistry::theInstance().tests();

    for ( std::list<TestFixture *>::const_iterator it = tests.begin(); it != tests.end(); ++it )
    {
        if ( classname.empty() || (*it)->classname == classname )
            (*it)->run();
    }

    std::cout << "\n\nTesting Complete\nNumber of tests: " << countTests << "\n";

    std::cerr << errmsg.str();
}