#ifdef TEST

#include "unity.h"

#include "addition.h"

num carry[1];

void setUp(void)
{
}

void tearDown(void)
{
}

void test_addition_full_adder_nullplusnullgleichnull(void)
{
    num result[1];
    num expected = 0;

    full_adder(result, carry, 0, 0, 0);

    TEST_ASSERT_EQUAL_UINT(expected, result[0]);
}

void test_addition_full_adder_nullplusnullgleichnullmituebertrag(void)
{
    num result[1];
    num expected = 1;

    full_adder(result, carry, 0, 0, 1);

    TEST_ASSERT_EQUAL_UINT(expected, result[0]);
}

void test_addition_full_adder_zahlpluszahlgleichsummeohneuebertrag(void)
{
    num result[5];
    num expected[5] = { 0, 1, 1, 1, 1};

    full_adder((result+0), carry, 1, 0, 1);
    full_adder((result+1), carry, 0, 1, 0);
    full_adder((result+2), carry, 1, 0, 0);
    full_adder((result+3), carry, 0, 0, 1);
    full_adder((result+4), carry, 1, 1, 1);

    TEST_ASSERT_EQUAL_UINT(expected[0], result[0]);
    TEST_ASSERT_EQUAL_UINT(expected[1], result[1]);
    TEST_ASSERT_EQUAL_UINT(expected[2], result[2]);
    TEST_ASSERT_EQUAL_UINT(expected[3], result[3]);
    TEST_ASSERT_EQUAL_UINT(expected[4], result[4]);
}

void test_addition_full_adder_completesumwithcarry(void)
{
    num result[5], carryresult[5];
    num expected[5] = { 0, 0, 1, 1, 0}, expectedcarry[5] = { 1, 1, 1, 0, 0};

    full_adder(result+0, carryresult+0, 0, 1, 1);
    full_adder(result+1, carryresult+1, 1, 1, 0);
    full_adder(result+2, carryresult+2, 1, 1, 1);
    full_adder(result+3, carryresult+3, 0, 1, 0);
    full_adder(result+4, carryresult+4, 0, 0, 0);

    TEST_ASSERT_EQUAL_UINT(expected[0], result[0]);
    TEST_ASSERT_EQUAL_UINT(expected[1], result[1]);
    TEST_ASSERT_EQUAL_UINT(expected[2], result[2]);
    TEST_ASSERT_EQUAL_UINT(expected[3], result[3]);
    TEST_ASSERT_EQUAL_UINT(expected[4], result[4]);
    TEST_ASSERT_EQUAL_UINT(expectedcarry[0], carryresult[0]);
    TEST_ASSERT_EQUAL_UINT(expectedcarry[1], carryresult[1]);
    TEST_ASSERT_EQUAL_UINT(expectedcarry[2], carryresult[2]);
    TEST_ASSERT_EQUAL_UINT(expectedcarry[3], carryresult[3]);
    TEST_ASSERT_EQUAL_UINT(expectedcarry[4], carryresult[4]);
}

void test_addition_addition_basecasezeropluszeroequalzero(void)
{
    unsigned int result;
    unsigned int expected = 0;

    result = addition(0, 0);

    TEST_ASSERT_EQUAL_UINT(expected, result);
}

void test_addition_addition_basecaseonescolumns(void)
{
    unsigned int result[2];
    unsigned int expected[2] = { 1, 1 };

    result[0] = addition(1, 0);
    result[1] = addition(0, 1);

    TEST_ASSERT_EQUAL_UINT(expected[0], result[0]);
    TEST_ASSERT_EQUAL_UINT(expected[1], result[1]);
}

void test_addition_addition_basecasetotenscolumns(void)
{
    unsigned int result[5];
    unsigned int expected[5] = { 3, 3, 2, 3, 3 };

    result[0] = addition(0, 3);
    result[1] = addition(1, 2);
    result[2] = addition(1, 1);
    result[3] = addition(2, 1);
    result[4] = addition(3, 0);

    TEST_ASSERT_EQUAL_UINT(expected[0], result[0]);
    TEST_ASSERT_EQUAL_UINT(expected[1], result[1]);
    TEST_ASSERT_EQUAL_UINT(expected[2], result[2]);
    TEST_ASSERT_EQUAL_UINT(expected[3], result[3]);
    TEST_ASSERT_EQUAL_UINT(expected[4], result[4]);
}

void test_addition_addition_allunsignedinteger(void)
{
    unsigned int result[5];
    unsigned int expected[5] = { 88879736, __UINT32_MAX__, 66558, __UINT32_MAX__, 477905879 };

    result[0] = addition(13456275, 75423461);    
    result[1] = addition(4294967294, 1);    
    result[2] = addition(1023, 65535);
    result[3] = addition(0, 4294967295);
    result[4] = addition(54321567,423584312);

    TEST_ASSERT_EQUAL_UINT(expected[0], result[0]);
    TEST_ASSERT_EQUAL_UINT(expected[1], result[1]);
    TEST_ASSERT_EQUAL_UINT(expected[2], result[2]);
    TEST_ASSERT_EQUAL_UINT(expected[3], result[3]);
    TEST_ASSERT_EQUAL_UINT(expected[4], result[4]);
}

#endif // TEST