package l23_5;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class TestMoney {
	
	private static Money xmp_0_0;
	private static Money xmp_10_25;
	
	private Money xmp_5_75;

	@BeforeAll
	static void setUpBeforeClass() throws Exception {
		System.out.println("setUpBeforeClass run once before all tests.");
		xmp_0_0 = new Money();
		xmp_10_25=new Money(10,25);
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
		System.out.println("tearDownAfterClass run once after all tests.");
		xmp_0_0=null;
		xmp_10_25=null;
	}

	@BeforeEach
	void setUp() throws Exception {
		System.out.println("setUp run before each test.");
		xmp_5_75=new Money(5,75);
	}

	@AfterEach
	void tearDown() throws Exception {
		System.out.println("tearDown run after each test.");
		xmp_5_75=null;
	}

	@Test
	void testMoney() { 
		System.out.println("-- testMoney - test of the Money null constructor");
		assertAll("Should have 0 dollars and 0 cents.",
				()->assertEquals(0,xmp_0_0.getDollars(),"Null constructor should produce 0 dollars"),
				()->assertEquals(0,xmp_0_0.getCents(),"Null constructor should produce 0 cents")
				);
		
	}

	@Test
	void testMoneyIntInt() { 
		System.out.println("-- testMoneyIntInt - test of the Money two integer constructor");
		assertAll("Should have 10 dollars and 25 cents.",
				()->assertEquals(10,xmp_10_25.getDollars(),"Two integer constructor should produce 10 dollars"),
				()->assertEquals(25,xmp_10_25.getCents(),"Two integer constructor should produce 25 cents")
				);
	}

	@Test
	void testMoneyDouble() { 
		System.out.println("-- testMoneyDouble - test of the Money(double) constructor");
		Money xmp_3_21 = new Money(3.21);
		assertAll("Should have 3 dollars and 21 cents.",
			()->assertEquals(3,xmp_3_21.getDollars()),
			()->assertEquals(21,xmp_3_21.getCents())
			);		
		Money xmp_3_94 = new Money(3.93947);
		assertAll("Test Rounding up... should be 3 dollars and 94 cents",
			()->assertEquals(3,xmp_3_94.getDollars()),
			()->assertEquals(94,xmp_3_94.getCents())
			);		
		Money xmp_14_00 = new Money(13.999999999);
		assertAll("Test Rounding up to dollars... should be 14 dollars and 0 cents",
			()->assertEquals(14,xmp_14_00.getDollars()),
			()->assertEquals(0,xmp_14_00.getCents())
			);		
		Money xmp_m4_00 = new Money(-3.999999);
		assertAll("Test Rounding down to dollars... should be -4 dollars and 00 cents.",
			()->assertEquals(-4,xmp_m4_00.getDollars()),
			()->assertEquals(0,xmp_m4_00.getCents())
			);		
	}

	@Test
	void testMoneyMoney() { 
		System.out.println("-- testMoneyMoney - test of the Money(Money) constructor");
		Money xmp_10_25_Copy = new Money(xmp_10_25);
		assertAll("Should have 3 dollars and 21 cents.",
			()->assertEquals(10,xmp_10_25_Copy.getDollars()),
			()->assertEquals(25,xmp_10_25_Copy.getCents())
			);
	}

	@Test
	void testGetDollars() { 
		System.out.println("-- testGetDollars - test of the Money.getDollars method");
		assertEquals(0,xmp_0_0.getDollars());
		assertEquals(10,xmp_10_25.getDollars());
		assertEquals(5,xmp_5_75.getDollars());
	}

	@Test
	void testGetCents() { 		
		System.out.println("-- testGetCents - test of the Money.getCents method");
	assertEquals(0,xmp_0_0.getCents());
	assertEquals(25,xmp_10_25.getCents());
	assertEquals(75,xmp_5_75.getCents());
	}

	@Test
	void testAdd() { 
		System.out.println("-- testAdd - test of the Money.add method");
		Money sum = xmp_10_25.add(xmp_0_0);
		assertAll("Should have 10 dollars and 25 cents.",
				()->assertEquals(10,sum.getDollars()),
				()->assertEquals(25,sum.getCents())
				);
		Money sum2 = xmp_10_25.add(xmp_5_75);
		assertAll("Test round up... Should have 16 dollars and 00 cents.",
				()->assertEquals(16,sum2.getDollars()),
				()->assertEquals(0,sum2.getCents())
				);
	}

	@Test
	void testMult() { 
		System.out.println("-- testMult - test of the Money.mult method");
		Money mult = xmp_10_25.mult(0.00000001);
		assertAll("Should have 0 dollars and 0 cents.",
				()->assertEquals(0,mult.getDollars()),
				()->assertEquals(0,mult.getCents())
				);
		Money mult2 = xmp_10_25.mult(2.0);
		assertAll("Should have 20 dollars and 50 cents.",
				()->assertEquals(20,mult2.getDollars()),
				()->assertEquals(50,mult2.getCents())
				);
	}

	@Test
	void testCompareTo() { 
		System.out.println("-- testCompareTo - test of the Money.compareTo method");
		assertTrue(xmp_10_25.compareTo(xmp_5_75) > 0);
		assertTrue(xmp_5_75.compareTo(xmp_10_25) < 0);
		assertTrue(xmp_10_25.compareTo(xmp_10_25) == 0);
	}

	@Test
	void testToDouble() { 
		System.out.println("-- testToDouble - test of the Money.toDouble method");
		assertEquals(10.25,xmp_10_25.toDouble(),1e-5);
		assertEquals(5.75,xmp_5_75.toDouble(),1e-5);
	}

	@Test
	void testToString() { 
		System.out.println("-- testToString - test of the Money.toString method");
		assertEquals("$10.25",xmp_10_25.toString());
		assertEquals("$5.75",xmp_5_75.toString());
	}

}
