#include <cppunit/config/SourcePrefix.h>
#include <iostream>
#include "TestInterpreter.h"
#include "Number.h"
#include "ExpressionFactory.h"
#include "NumberFormatException.h"
CPPUNIT_TEST_SUITE_REGISTRATION( TestInterpreter );

TestInterpreter::TestInterpreter(void)
{
}


TestInterpreter::~TestInterpreter(void)
{
}

void TestInterpreter::setUp(void)
{
    m_variables.insert(std::pair<std::string,Expression*>("w", new Number(5)));
    m_variables.insert(std::pair<std::string,Expression*>("w_x", new Number(5)));
    m_variables.insert(std::pair<std::string,Expression*>("x", new Number(10)));
    m_variables.insert(std::pair<std::string,Expression*>("z", new Number(42)));
}

void TestInterpreter::tearDown(void)
{
    for (std::map<std::string,Expression*>::iterator iter = m_variables.begin();
         iter != m_variables.end(); iter++)
         delete iter->second;
    m_variables.clear();
}

void TestInterpreter::test1(void)
{
    std::string expression = "w x z - +"; // -27,    w + (x - z)
    Expression *sentence = ExpressionFactory::parse(expression);
    int result = sentence->interpret(m_variables);
    delete sentence;
    std::cout << "[" << expression << "] => " << result << std::endl;
    CPPUNIT_ASSERT(result == -27);
}

void TestInterpreter::test2(void)
{
    std::string expression = "w 50 z - +"; // 13,     w - 50 + z
    Expression *sentence = ExpressionFactory::parse(expression);
    int result = sentence->interpret(m_variables);
    delete sentence;
    std::cout << "[" << expression << "] => " << result << std::endl;
    CPPUNIT_ASSERT(result == 13);
}

void TestInterpreter::test3(void)
{
    std::string expression = "w 2 * 50 z 2 / - +";   // 39,     w * 2 + ( 50 - z / 2)
    Expression *sentence = ExpressionFactory::parse(expression);
    int result = sentence->interpret(m_variables);
    delete sentence;
    std::cout << "[" << expression << "] => " << result << std::endl;
    CPPUNIT_ASSERT(result == 39);
}

void TestInterpreter::test4(void)
{
    std::string expression = "1 23 + 12345 w_x - +"; // 12364,  1 + 23 + (12345 - w2x)
    Expression *sentence = ExpressionFactory::parse(expression);
    int result = sentence->interpret(m_variables);
    delete sentence;
    std::cout << "[" << expression << "] => " << result << std::endl;
    CPPUNIT_ASSERT(result == 12364);
}

void TestInterpreter::testException(void)
{
    std::string expression = "w2y 123 -"; // Variable format error
    Expression *sentence;
    CPPUNIT_ASSERT_THROW(sentence = ExpressionFactory::parse(expression), 
                         NumberFormatException);
    std::cout << "[" << expression << "]    exception thrown" << std::endl;
}
