#include <gtest/gtest.h>
#include "mathlib.h"

using namespace mathlib;


//=================================================================================================================================
//ADD


TEST(addTest, PositiveNumbers)
{
    EXPECT_DOUBLE_EQ(add(1.0,2.0),3.0);
}

TEST(addTest, NegativeNumbers)
{
    EXPECT_DOUBLE_EQ(add(-1.0,-3.0),-4.0);
}

TEST(addTest, MixedNumbersPositive)
{
    EXPECT_DOUBLE_EQ(add(-1.0,3.0),2.0);
}

TEST(addTest, MixedNumbersNegative)
{
    EXPECT_DOUBLE_EQ(add(-4.0,3.0),-1.0);
}

TEST(addTest, NumberZero)
{
    EXPECT_DOUBLE_EQ(add(0.0,1.0),1.0);
}


//=================================================================================================================================
//SUBTRACT

TEST(subtractTest, PositiveNumbers)
{
    EXPECT_DOUBLE_EQ(subtract(5.0,3.0),2.0);
}

TEST(subtractTest, NegativeNumbers)
{
    EXPECT_DOUBLE_EQ(subtract(-5.0,-1.0),-4.0);
}

TEST(subtractTest, MixedNumbersPositive)
{
    EXPECT_DOUBLE_EQ(subtract(1.0,-2.0),3.0);
}

TEST(subtractTest, MixedNumbersNegative)
{
    EXPECT_DOUBLE_EQ(subtract(-5.0,3.0),-8.0);
}

TEST(subtractTest, NumberZero)
{
    EXPECT_DOUBLE_EQ(subtract(0.0,3.0),-3.0);
}


//=================================================================================================================================
//MULTIPLY

TEST(multiplyTest, PositiveNumbers)
{
    EXPECT_DOUBLE_EQ(multiply(5.0,10.0),50.0);
}

TEST(multiplyTest, NegativeNumbers)
{
    EXPECT_DOUBLE_EQ(multiply(-3.0,-2.0),6.0);
}

TEST(multiplyTest, MixedNumbers)
{
    EXPECT_DOUBLE_EQ(multiply(-3.0,2.0),-6.0);
}

TEST(multiplyTest, NumberZero)
{
    EXPECT_DOUBLE_EQ(multiply(0.0,5.0),0.0);
}

TEST(multiplyTest, NeutralElement)
{
    EXPECT_DOUBLE_EQ(multiply(5.0,1.0),5.0);
}

TEST(multiplyTest, SmallDecimalNumber)
{
    EXPECT_DOUBLE_EQ(multiply(5.0,0.5),2.5);
}


//=================================================================================================================================
//DIVIDE

TEST(divideTest, PositiveNumbers)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(divide(10.0,5.0,err),2.0);
    EXPECT_EQ(err,OK);

}

TEST(divideTest, NegativeNumbers)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(divide(-9.0,-3.0,err),3.0);
    EXPECT_EQ(err,OK);
}

TEST(divideTest, MixedNumbers)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(divide(-27.0,9.0,err),-3.0);
    EXPECT_EQ(err,OK);
}

TEST(divideTest, NeutralElement)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(divide(10.0,1.0,err),10.0);
    EXPECT_EQ(err,OK);
}

TEST(divideTest, NumberZero)
{
    MathError err = OK;
    divide(5.0,0.0,err);
    
    EXPECT_EQ(err,DIVISION_BY_ZERO);
}

TEST(divideTest, ZeroDividend)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(divide(0.0,5.0,err),0.0);
    
    EXPECT_EQ(err,OK);
}


//=================================================================================================================================
//FACTORIAL

TEST(factorialTest, PositiveNumber)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(factorial(3,err),6);
    EXPECT_EQ(err,OK);
}

TEST(factorialTest, NegativeNumber)
{
    MathError err = OK;
    factorial(-4,err);

    EXPECT_EQ(err,NEGATIVE_FACTORIAL);
}

TEST(factorialTest, NumberZero)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(factorial(0,err),1);
    EXPECT_EQ(err,OK);
}

TEST(factorialTest, NumberOne)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(factorial(1,err),1);
    
    EXPECT_EQ(err,OK);
}

//=================================================================================================================================
//POWER


TEST(powerTest, PositiveNumber)
{
    EXPECT_DOUBLE_EQ(power(2.0,3),8.0);
}

TEST(powerTest, NeutralElement)
{
    EXPECT_DOUBLE_EQ(power(6.0,1),6.0);
}

TEST(powerTest, NumberZero)
{
    EXPECT_DOUBLE_EQ(power(15.0,0),1.0);
}

TEST(powerTest, BaseNumberOne)
{
    EXPECT_DOUBLE_EQ(power(1.0,50),1.0);
}


//=================================================================================================================================
//ROOT

TEST(rootTest, PositiveNumber)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(root(9.0,2,err),3.0);
    EXPECT_EQ(err,OK);
}

TEST(rootTest, NegativeRootNumber)
{
    MathError err = OK;
    root(25.0,-2,err);

    EXPECT_EQ(err,INVALID_ROOT);
}

TEST(rootTest, NegativeBaseOddRoot)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(root(-8.0,3,err),-2.0);

    EXPECT_EQ(err,OK);
}

TEST(rootTest, NegativeBaseEvenRoot)
{
    MathError err = OK;
    root(-5.0,2,err);

    EXPECT_EQ(err,INVALID_ARGUMENT);
}

TEST(rootTest, NumberZero)
{
    MathError err = OK;
    EXPECT_DOUBLE_EQ(root(0.0,3,err),0.0);
    
    EXPECT_EQ(err,OK);
}

TEST(rootTest, ZeroDegree)
{
    MathError err = OK;
    root(10.0,0,err);

    EXPECT_EQ(err, INVALID_ROOT);
}


//=================================================================================================================================
//MODULO

TEST(moduloTest, PositiveNumber)
{
    MathError err = OK;
    EXPECT_EQ(modulo(11.0,2.0,err),1.0);

    EXPECT_EQ(err,OK);
}

TEST(moduloTest, NegativeNumber)
{
    MathError err = OK;
    EXPECT_EQ(modulo(-7.0,3.0,err),-1.0);

    EXPECT_EQ(err,OK);
}

TEST(moduloTest, NumberZero)
{
    MathError err = OK;
    modulo(13.0,0.0,err);

    EXPECT_EQ(err,DIVISION_BY_ZERO);
}

TEST(moduloTest, NegativeModulo)
{
    MathError err = OK;
    EXPECT_EQ(modulo(9.0,-4.0,err),1.0);

    EXPECT_EQ(err,OK);
}