#include <scpp_os.hpp>
#include <scpp_unittest.hpp>

using namespace scpp;


/***
 * AssertError 単体テスト.
 */
class AssertErrorTest : public TestCase
{
	public:
		AssertErrorTest() {}
		~AssertErrorTest() {}

		/**
		 * 引数なし AssertError 単体試験.
		 */
		void testAssertError()
		{
			AssertError err;
			Assertion::assertEquals("Unknown", err.getFileName());
			Assertion::assertEquals(0        , err.getLineNumber());
			Assertion::assertEquals("Unknown", err.getFunctionName());
		}

		/**
		 * 引数メッセージあり AssertError 単体試験.
		 */
		void testAssertErrorMsg()
		{
			AssertError err("errmsg");
			Assertion::assertEquals("errmsg", err.what());
		}

		/**
		 * 引数 メッセージ, ファイル名, 行番号, 関数名あり AssertError 単体試験.
		 */
		void testAssertErrorFull()
		{
			AssertError err("messageA", "fileB", 12345, "funcX");
			Assertion::assertEquals("messageA", err.what());
			Assertion::assertEquals("fileB"   , err.getFileName());
			Assertion::assertEquals(12345     , err.getLineNumber());
			Assertion::assertEquals("funcX"   , err.getFunctionName());
		}

		void testAssertEqualsBool()
		{
			Assertion::assertEquals(true, true);
			try {
				Assertion::assertEquals(true, false);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
			try {
				Assertion::assertEquals(false, true);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsChar()
		{
			Assertion::assertEquals('x', 'x');
			try {
				Assertion::assertEquals('x', 'y');
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsDouble()
		{
			double x, y;
			x = 1.23456;
			y = 1.23456;
			Assertion::assertEquals(x, y);
			try {
				y = 1.23457;
				Assertion::assertEquals(x, y);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsFloat()
		{
			float x, y;
			x = 1.23456;
			y = 1.23456;
			Assertion::assertEquals(x, y);
			try {
				y = 1.23457;
				Assertion::assertEquals(x, y);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsInt()
		{
			int x = 0x12345;
			Assertion::assertEquals(0x12345, x);
			try {
				Assertion::assertEquals(0x12346, x);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsLong()
		{
			long x = 0x12345678L;
			Assertion::assertEquals(0x12345678L, x);
			try {
				Assertion::assertEquals(0x1234679L, x);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertEqualsString()
		{
			std::string x("str1");
			std::string y("str1");
			std::string z("str2");
			Assertion::assertEquals(x, y);
			Assertion::assertEquals("str1", x);
			Assertion::assertEquals(x, "str1");
			Assertion::assertEquals("str1", "str1");
			try {
				Assertion::assertEquals(x, z);
				Assertion::fail();
			} catch (AssertError) {}
			try {
				Assertion::assertEquals("str1", z);
				Assertion::fail();
			} catch (AssertError) {}
			try {
				Assertion::assertEquals(z, "str1");
				Assertion::fail();
			} catch (AssertError) {}
			try {
				Assertion::assertEquals("str1", "str2");
				Assertion::fail();
			} catch (AssertError) {}
		}


		void testAssertTrue()
		{
			Assertion::assertTrue(true);
			try {
				Assertion::assertTrue(false);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertFalse()
		{
			Assertion::assertFalse(false);
			try {
				Assertion::assertFalse(true);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertNull()
		{
			std::string* str = 0;
			Assertion::assertNull(str);
			Assertion::assertNull(0);
			try {
				std::string str2;
				Assertion::assertNull(&str2);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertNotNull()
		{
			std::string str;
			Assertion::assertNotNull(&str);
			try {
				Assertion::assertNotNull(0);
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}

		void testAssertFail()
		{
			try {
				Assertion::fail();
				Assertion::fail();
			} catch (AssertError) {
				// OK
			}
		}



		void suite()
		{
			RUN_TEST(testAssertError);
			RUN_TEST(testAssertErrorMsg);
			RUN_TEST(testAssertErrorFull);
			RUN_TEST(testAssertEqualsBool);
			RUN_TEST(testAssertEqualsChar);
			RUN_TEST(testAssertEqualsDouble);
			RUN_TEST(testAssertEqualsFloat);
			RUN_TEST(testAssertEqualsInt);
			RUN_TEST(testAssertEqualsLong);
			RUN_TEST(testAssertEqualsString);
			RUN_TEST(testAssertTrue);
			RUN_TEST(testAssertFalse);
			RUN_TEST(testAssertNull);
			RUN_TEST(testAssertNotNull);
			RUN_TEST(testAssertFail);
		}


};

