
#include "actconfig.h"
#include "actcomdef.h"
#include "actstdlib.h"
#include "acttest.h"
#include "acttestlist.h"
#include "acttestlistener.h"
#include "acttestresult.h"
#include "acttestrunner.h"
#include "acttestrunner_private.h"


static const ITestListenerVtbl g_ITestListenerVtbl = {
    (TestListnerStartTestCallBack)	__ITestRunner_startTest,
        (TestListnerEndTestCallBack)	__ITestRunner_endTest,
        (TestListnerAddFailureCallBack)	__ITestRunner_addFailure,
};

static ITestRunnerVtbl g_ITestRunnerVtbl = {
    __ITestRunner_start,
        __ITestRunner_addTest,
        __ITestRunner_runTest,
        __ITestRunner_end,
};

static const ITestListener testrunner_ = {
    (ITestListenerVtbl*)&g_ITestListenerVtbl,
};

static ITestResult result_;
static ITest* root_;

static void __ITestRunner_startTest(ITestListener* self,ITest* test)
{
    act_print(".");
}

static void __ITestRunner_endTest(ITestListener* self,ITest* test)
{
    
}

static void __ITestRunner_addFailure(ITestListener* self,ITest* test,char* msg,int line,char* file)
{
    act_print("\n");
    act_print(ITest_name(root_));
    act_print(".");
    act_print(ITest_name(test));
    {
        char buf[16];
        act_print(" (");
        act_print(file);
        act_print(" ");
        act_itoa(line, buf, 10);
        act_print(buf);
        act_print(") ");
    }
    act_print(msg);
    act_print("\n");
}

//
//
//

ITestRunner* ITestRunner_New()
{
    ITestRunner * pMe;
    
    pMe = ITestRunner_Alloc();
    pMe = ITestRunner_Ctor(pMe);
    return pMe;
}


void ITestRunner_Delete(ITestRunner* pMe)
{
    ITestRunner_Xtor(pMe);
    ITestRunner_Free(pMe);
}


ITestRunner* ITestRunner_Alloc()
{
    ITestRunner* pMe;
    
    pMe = (ITestRunner*) act_malloc(sizeof(ITestRunner));
    return pMe;
}

void ITestRunner_Free(ITestRunner* pMe)
{
    if(pMe)
    {
        act_free(pMe);
    }
}


ITestRunner* ITestRunner_Ctor(ITestRunner* pme)
{
    pme->pvt = &g_ITestRunnerVtbl;
    pme->m_lstTest__ = ITestList_New();
    return pme;
}


void ITestRunner_Xtor(ITestRunner* pMe)
{
    ITestList_Delete(pMe->m_lstTest__, TRUE);
}

static void __ITestRunner_start(ITestRunner* pme)
{
    ITestResult_Ctor(&result_,NULL);
    ITestResult_init(&result_, (ITestListener*) &testrunner_);
}

static void __ITestRunner_addTest(ITestRunner* pme, ITest* test)
{
#if 0
    root_ = test;
    ITest_run(test, &result_);
#endif
    ITestList_AddTail(pme->m_lstTest__, test);
}

static void __ITestRunner_runTest(ITestRunner* pMe)
{
    ITestNode* pNode;
    ITest* test;
    int nCount;
    int index;

    pNode = (ITestNode*) ITestList_GetHeadPosition(pMe->m_lstTest__);
    nCount = ITestList_GetCount(pMe->m_lstTest__);
    for(index = 0; index < nCount; index++)
    {
        test = (ITest*) ITestList_GetNext(pMe->m_lstTest__, &pNode);
        root_ = test;
        ITest_run(test, &result_);
    }
}


static void __ITestRunner_end(ITestRunner* pme)
{
    char buf[16];
    if (result_.failureCount) {
        act_print("\nrun ");
        act_itoa(result_.runCount, buf, 10);
        act_print(buf);
        act_print(" failures ");
        act_itoa(result_.failureCount, buf, 10);
        act_print(buf);
        act_print("\n");
    } else {
        act_print("\nOK (");
        act_itoa(result_.runCount, buf, 10);
        act_print(buf);
        act_print(" tests)\n");
    }
}
