/*******************************************************************************
***  This file is part of Pecunia.                                           ***
***                                                                          ***
***  Copyright (C) 2017, 2018, 2019, 2020, 2021, 2023                        ***
***  John Schneiderman <Licencing _AT_ Schneiderman _DOT_ me>                ***
***                                                                          ***
***  This program is free software: you can redistribute it and/or modify it ***
***  under the terms of the GNU Lesser 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 Lesser General Public License for more details.             ***
***                                                                          ***
***  You should have received a copy of the GNU Lesser General Public License***
***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
*******************************************************************************/
#include <QTest>

#include <cstdint>

#include <pecunia/Rounders.h>
using pecunia::rounders::currency::up;


namespace pecunia
{
namespace rounders
{
namespace currency
{
namespace tests
{

struct RoundersUT : QObject
{
	Q_OBJECT

private slots:
	//{ Up

	void up_Zero_ShouldBeZero()
	{
		const UnitStorage value{up(0, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void up_OneSixPositive_ShouldBeRoundToTwo()
	{
		const UnitStorage value{up(160, 2, 0)};
		const UnitStorage expected{200};
		QCOMPARE(value, expected);
	}
	void up_OneSixSixPositive_ShouldBeRoundToOneSeven()
	{
		const UnitStorage value{up(166, 2, 1)};
		const UnitStorage expected{170};
		QCOMPARE(value, expected);
	}
	void up_OneFivePositive_ShouldBeRoundToTwo()
	{
		const UnitStorage value{up(150, 2, 0)};
		const UnitStorage expected{200};
		QCOMPARE(value, expected);
	}
	void up_OneFourPositive_ShouldBeRoundToOne()
	{
		const UnitStorage value{up(140, 2, 0)};
		const UnitStorage expected{100};
		QCOMPARE(value, expected);
	}
	void up_ZeroSixPositive_ShouldBeRoundToOne()
	{
		const UnitStorage value{up(60, 2, 0)};
		const UnitStorage expected{100};
		QCOMPARE(value, expected);
	}
	void up_ZeroFivePositive_ShouldBeRoundToOne()
	{
		const UnitStorage value{up(50, 2, 0)};
		const UnitStorage expected{100};
		QCOMPARE(value, expected);
	}
	void up_ZeroFourPositive_ShouldBeRoundToZero()
	{
		const UnitStorage value{up(40, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void up_ZeroFourNegative_ShouldBeZero()
	{
		const UnitStorage value{up(-40, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void up_ZeroFiveNegative_ShouldBeZero()
	{
		const UnitStorage value{up(-50, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void up_ZeroSixNegative_ShouldBeNegativeOne()
	{
		const UnitStorage value{up(-60, 2, 0)};
		const UnitStorage expected{-100};
		QCOMPARE(value, expected);
	}
	void up_OneFourNegative_ShouldBeNegativeOne()
	{
		const UnitStorage value{up(-140, 2, 0)};
		const UnitStorage expected{-100};
		QCOMPARE(value, expected);
	}
	void up_OneFiveNegative_ShouldBeNegativeOne()
	{
		const UnitStorage value{up(-150, 2, 0)};
		const UnitStorage expected{-100};
		QCOMPARE(value, expected);
	}
	void up_OneSixNegative_ShouldBeNegativeTwo()
	{
		const UnitStorage value{up(-160, 2, 0)};
		const UnitStorage expected{-200};
		QCOMPARE(value, expected);
	}
	void up_twentythreeFivePositive_ShouldBeTwentyfour()
	{
		const UnitStorage value{up(2350, 2, 0)};
		const UnitStorage expected{2400};
		QCOMPARE(value, expected);
	}
	void up_twentythreeFiveNegative_ShouldBeTwentythreeNegative()
	{
		const UnitStorage value{up(-2350, 2, 0)};
		const UnitStorage expected{-2300};
		QCOMPARE(value, expected);
	}

	//}

	//{ Even

	void even_OneSixPositive_ShouldBeRoundToTwo()
	{
		const UnitStorage value{even(160, 2, 0)};
		const UnitStorage expected{200};
		QCOMPARE(value, expected);
	}
	void even_OneFivePositive_ShouldBeRoundToTwo()
	{
		const UnitStorage value{even(150, 2, 0)};
		const UnitStorage expected{200};
		QCOMPARE(value, expected);
	}
	void even_OneFourPositive_ShouldBeRoundToOne()
	{
		const UnitStorage value{even(140, 2, 0)};
		const UnitStorage expected{100};
		QCOMPARE(value, expected);
	}
	void even_ZeroSixPositive_ShouldBeRoundToOne()
	{
		const UnitStorage value{even(60, 2, 0)};
		const UnitStorage expected{100};
		QCOMPARE(value, expected);
	}
	void even_ZeroFivePositive_ShouldBeRoundToZero()
	{
		const UnitStorage value{even(50, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void even_ZeroFourPositive_ShouldBeRoundToZero()
	{
		const UnitStorage value{even(40, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void even_ZeroFourNegative_ShouldBeZero()
	{
		const UnitStorage value{even(-40, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void even_ZeroFiveNegative_ShouldBeZero()
	{
		const UnitStorage value{even(-50, 2, 0)};
		const UnitStorage expected{0};
		QCOMPARE(value, expected);
	}
	void even_ZeroSixNegative_ShouldBeNegativeOne()
	{
		const UnitStorage value{even(-60, 2, 0)};
		const UnitStorage expected{-100};
		QCOMPARE(value, expected);
	}
	void even_OneFourNegative_ShouldBeNegativeOne()
	{
		const UnitStorage value{even(-140, 2, 0)};
		const UnitStorage expected{-100};
		QCOMPARE(value, expected);
	}
	void even_OneFiveNegative_ShouldBeNegativeTwo()
	{
		const UnitStorage value{even(-150, 2, 0)};
		const UnitStorage expected{-200};
		QCOMPARE(value, expected);
	}
	void even_OneSixNegative_ShouldBeNegativeTwo()
	{
		const UnitStorage value{even(-160, 2, 0)};
		const UnitStorage expected{-200};
		QCOMPARE(value, expected);
	}
	void even_OneZeroZeroSixNegativeTwoDigits_ShouldBeNegativeOneZeroOne()
	{
		const UnitStorage value{even(-1006, 3, 2)};
		const UnitStorage expected{-1010};
		QCOMPARE(value, expected);
	}
	void even_twentyfourFivePositive_ShouldBeTwentyfour()
	{
		const UnitStorage value{even(2450, 2, 0)};
		const UnitStorage expected{2400};
		QCOMPARE(value, expected);
	}
	void even_twentythreeFivePositive_ShouldBeTwentyfour()
	{
		const UnitStorage value{even(2350, 2, 0)};
		const UnitStorage expected{2400};
		QCOMPARE(value, expected);
	}
	void even_twentythreeFiveNegative_ShouldBeTwentyfourNegative()
	{
		const UnitStorage value{even(-2350, 2, 0)};
		const UnitStorage expected{-2400};
		QCOMPARE(value, expected);
	}
	void even_twentyfourFiveNegative_ShouldBeTwentyfourNegative()
	{
		const UnitStorage value{even(-2450, 2, 0)};
		const UnitStorage expected{-2400};
		QCOMPARE(value, expected);
	}

	//}
};

}}}}

QTEST_MAIN(pecunia::rounders::currency::tests::RoundersUT)
#include "rounders-currency-unit-tests.moc"
