//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// This file is part of J2MEUnit, a Java 2 Micro Edition unit testing framework.
//
// J2MEUnit is free software distributed under the Common Public License (CPL).
// It may be redistributed and/or modified under the terms of the CPL. You 
// should have received a copy of the license along with J2MEUnit. It is also 
// available from the website of the Open Source Initiative at 
// http://www.opensource.org.
//
// J2MEUnit 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.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
package j2meunit.tests;

import j2meunit.framework.AssertionFailedError;
import j2meunit.framework.Test;
import j2meunit.framework.TestCase;
import j2meunit.framework.TestResult;
import j2meunit.framework.TestSuite;

import j2meunit.util.StringUtil;


/********************************************************************
 * A test case testing the testing framework.
 */
public class TestTest extends TestCase
{
	//~ Constructors -----------------------------------------------------------

	/***************************************
	 * Creates a new TestTest object.
	 */
	public TestTest()
	{
	}

	/***************************************
	 * Creates a new TestTest object.
	 *
	 * @param name DOCUMENT ME!
	 */
	public TestTest(String name)
	{
		super(name);
	}

	//~ Methods ----------------------------------------------------------------

	/***************************************
	 * suite method comment.
	 *
	 * @return DOCUMENT ME!
	 */
	public j2meunit.framework.Test suite()
	{
		return new TestSuite(new TestTest().getClass(),
							 new String[]
							 {
								 "testAssertEquals", "testAssertEqualsNull",
								 "testAssertionCounting", "testAssertNull",
								 "testAssertNullNotEqualsNull", "testAssertSame",
								 "testCaseToString", "testError", "testFail",
								 "testFailAssertNotNull", "testFailure",
								 "testFailureException", "testRunnerPrinting",
								 "testSetupFails", "testSucceedAssertNotNull",
								 "testSuccess", "testTearDownFails",
								 "testWasNotSuccessful", "testWasSuccessful"
							 });
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertEquals()
	{
		Object o = new Object();
		assertEquals(o, o);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertEqualsNull()
	{
		assertEquals(null, null);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertNull()
	{
		TestCase succeeds = new TestCase("isnull")
		{
			protected void runTest()
			{
				assertNull(null);
			}

			public Test suite()
			{
				return null;
			}
		};

		verifySuccess(succeeds);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertNullNotEqualsNull()
	{
		TestCase fails = new TestCase("fails")
		{
			protected void runTest()
			{
				assertEquals(null, new Object());
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyFailure(fails);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertSame()
	{
		Object o = new Object();
		assertSame(o, o);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertSameFails()
	{
		TestCase assertSame = new TestCase("assertSame")
		{
			protected void runTest()
			{
				assertSame(new Integer(1), new Integer(1));
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyFailure(assertSame);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testAssertionCounting()
	{
		TestCase assertionCounting = new TestCase("assertionCounting")
		{
			protected void runTest()
			{
				assertTrue(true);
				assertTrue("", true);

				assertEquals(1L, 1L);
				assertEquals("", 1L, 1L);

				assertEquals("", "");
				assertEquals("", "", "");

				assertNotNull(new Object());
				assertNotNull("", new Object());

				assertNull(null);
				assertNull("", null);

				Object object = new Object();
				assertSame(object, object);
				assertSame("", object, object);
			}
		};

		TestResult result = assertionCounting.run();
		assertEquals("Run count wrong", 1, result.runCount());
		assertEquals("Failure count wrong", 0, result.failureCount());
		assertEquals("Result count wrong", 0, result.errorCount());
		assertEquals("Assertion count wrong", 12, result.assertionCount());
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testCaseToString()
	{
		// This test wins the award for twisted snake tail eating while
		// writing self tests. And you thought those weird anonymous
		// inner classes were bad...
		assertEquals("testCaseToString(j2meunit.tests.TestTest)", toString());
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testError()
	{
		TestCase error = new TestCase("error")
		{
			protected void runTest()
			{
				throw new Error();
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyError(error);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testFail()
	{
		TestCase failure = new TestCase("fail")
		{
			protected void runTest()
			{
				fail();
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyFailure(failure);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testFailAssertNotNull()
	{
		TestCase failure = new TestCase("fails")
		{
			protected void runTest()
			{
				assertNotNull(null);
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyFailure(failure);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testFailure()
	{
		TestCase failure = new TestCase("failure")
		{
			protected void runTest()
			{
				assertTrue(false);
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyFailure(failure);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testFailureException()
	{
		try
		{
			fail();
		}
		catch (AssertionFailedError e)
		{
			return;
		}

		fail();
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testRunnerPrinting()
	{
		assertEquals("1050ms", StringUtil.elapsedTimeAsString(1050));
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testSetupFails()
	{
		TestCase fails = new TestCase("success")
		{
			protected void setUp()
			{
				throw new Error();
			}

			protected void runTest()
			{
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyError(fails);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testSucceedAssertNotNull()
	{
		assertNotNull(new Object());
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testSuccess()
	{
		TestCase success = new TestCase("success")
		{
			protected void runTest()
			{
				assertTrue(true);
			}

			public Test suite()
			{
				return null;
			}
		};

		verifySuccess(success);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testTearDownFails()
	{
		TestCase fails = new TestCase("success")
		{
			protected void tearDown()
			{
				throw new Error();
			}

			protected void runTest()
			{
			}

			public Test suite()
			{
				return null;
			}
		};

		verifyError(fails);
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testWasNotSuccessful()
	{
		TestCase failure = new TestCase("fail")
		{
			protected void runTest()
			{
				fail();
			}

			public Test suite()
			{
				return null;
			}
		};

		TestResult result = failure.run();
		assertTrue(result.runCount() == 1);
		assertTrue(result.failureCount() == 1);
		assertTrue(result.errorCount() == 0);
		assertTrue(!result.wasSuccessful());
	}

	/***************************************
	 * DOCUMENT ME!
	 */
	public void testWasSuccessful()
	{
		TestCase success = new TestCase("success")
		{
			protected void runTest()
			{
				assertTrue(true);
			}

			public Test suite()
			{
				return null;
			}
		};

		TestResult result = success.run();
		assertTrue(result.runCount() == 1);
		assertTrue(result.failureCount() == 0);
		assertTrue(result.errorCount() == 0);
		assertTrue(result.wasSuccessful());
	}

	/***************************************
	 * Override to run the test and assert its state.
	 *
	 * @exception Throwable if any exception is thrown
	 */
	protected void runTest() throws java.lang.Throwable
	{
		if (getName().equals("testAssertEquals"))
			testAssertEquals();
		else if (getName().equals("testAssertEqualsNull"))
			testAssertEqualsNull();
		else if (getName().equals("testAssertionCounting"))
			testAssertionCounting();
		else if (getName().equals("testAssertNull"))
			testAssertNull();
		else if (getName().equals("testAssertNullNotEqualsNull"))
			testAssertNullNotEqualsNull();
		else if (getName().equals("testAssertSame"))
			testAssertSame();
		else if (getName().equals("testCaseToString"))
			testCaseToString();
		else if (getName().equals("testError"))
			testError();
		else if (getName().equals("testFail"))
			testFail();
		else if (getName().equals("testFailAssertNotNull"))
			testFailAssertNotNull();
		else if (getName().equals("testFailure"))
			testFailure();
		else if (getName().equals("testFailureException"))
			testFailureException();
		else if (getName().equals("testRunnerPrinting"))
			testRunnerPrinting();
		else if (getName().equals("testSetupFails"))
			testSetupFails();
		else if (getName().equals("testSucceedAssertNotNull"))
			testSucceedAssertNotNull();
		else if (getName().equals("testSuccess"))
			testSuccess();
		else if (getName().equals("testTearDownFails"))
			testTearDownFails();
		else if (getName().equals("testWasNotSuccessful"))
			testWasNotSuccessful();
		else if (getName().equals("testWasSuccessful"))
			testWasSuccessful();
		else
			throw new RuntimeException("You don't have a method called " +
									   getName());
	}

	/***************************************
	 * DOCUMENT ME!
	 *
	 * @param test DOCUMENT ME!
	 */
	private void verifyError(TestCase test)
	{
		TestResult result = test.run();
		assertTrue(result.runCount() == 1);
		assertTrue(result.failureCount() == 0);
		assertTrue(result.errorCount() == 1);
	}

	/***************************************
	 * DOCUMENT ME!
	 *
	 * @param test DOCUMENT ME!
	 */
	private void verifyFailure(TestCase test)
	{
		TestResult result = test.run();
		assertTrue(result.runCount() == 1);
		assertTrue(result.failureCount() == 1);
		assertTrue(result.errorCount() == 0);
	}

	/***************************************
	 * DOCUMENT ME!
	 *
	 * @param test DOCUMENT ME!
	 */
	private void verifySuccess(TestCase test)
	{
		TestResult result = test.run();
		assertTrue(result.runCount() == 1);
		assertTrue(result.failureCount() == 0);
		assertTrue(result.errorCount() == 0);
	}
}
