summaryrefslogtreecommitdiffstats
path: root/junit
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commitfdb2704414a9ed92394ada0d1395e4db86889465 (patch)
tree9b591a4a50054274a197f02b3ccb51313681879f /junit
downloadlibcore-fdb2704414a9ed92394ada0d1395e4db86889465.zip
libcore-fdb2704414a9ed92394ada0d1395e4db86889465.tar.gz
libcore-fdb2704414a9ed92394ada0d1395e4db86889465.tar.bz2
Initial Contribution
Diffstat (limited to 'junit')
-rw-r--r--junit/MODULE_LICENSE_CPL1
-rw-r--r--junit/src/main/java/junit/extensions/ActiveTestSuite.java64
-rw-r--r--junit/src/main/java/junit/extensions/ExceptionTestCase.java46
-rw-r--r--junit/src/main/java/junit/extensions/RepeatedTest.java31
-rw-r--r--junit/src/main/java/junit/extensions/TestDecorator.java38
-rw-r--r--junit/src/main/java/junit/extensions/TestSetup.java37
-rw-r--r--junit/src/main/java/junit/extensions/package.html6
-rw-r--r--junit/src/main/java/junit/framework/Assert.java291
-rw-r--r--junit/src/main/java/junit/framework/AssertionFailedError.java13
-rw-r--r--junit/src/main/java/junit/framework/ComparisonFailure.java68
-rw-r--r--junit/src/main/java/junit/framework/Protectable.java14
-rw-r--r--junit/src/main/java/junit/framework/Test.java17
-rw-r--r--junit/src/main/java/junit/framework/TestCase.java197
-rw-r--r--junit/src/main/java/junit/framework/TestFailure.java57
-rw-r--r--junit/src/main/java/junit/framework/TestListener.java23
-rw-r--r--junit/src/main/java/junit/framework/TestResult.java166
-rw-r--r--junit/src/main/java/junit/framework/TestSuite.java267
-rw-r--r--junit/src/main/java/junit/framework/package.html5
18 files changed, 1341 insertions, 0 deletions
diff --git a/junit/MODULE_LICENSE_CPL b/junit/MODULE_LICENSE_CPL
new file mode 100644
index 0000000..541dbb5
--- /dev/null
+++ b/junit/MODULE_LICENSE_CPL
@@ -0,0 +1 @@
+http://www.opensource.org/licenses/cpl1.0.php
diff --git a/junit/src/main/java/junit/extensions/ActiveTestSuite.java b/junit/src/main/java/junit/extensions/ActiveTestSuite.java
new file mode 100644
index 0000000..073e6f3
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/ActiveTestSuite.java
@@ -0,0 +1,64 @@
+package junit.extensions;
+
+import junit.framework.*;
+
+/**
+ * A TestSuite for active Tests. It runs each
+ * test in a separate thread and waits until all
+ * threads have terminated.
+ * -- Aarhus Radisson Scandinavian Center 11th floor
+ */
+public class ActiveTestSuite extends TestSuite {
+ private volatile int fActiveTestDeathCount;
+
+ public ActiveTestSuite() {
+ }
+
+ public ActiveTestSuite(Class theClass) {
+ super(theClass);
+ }
+
+ public ActiveTestSuite(String name) {
+ super (name);
+ }
+
+ public ActiveTestSuite(Class theClass, String name) {
+ super(theClass, name);
+ }
+
+ public void run(TestResult result) {
+ fActiveTestDeathCount= 0;
+ super.run(result);
+ waitUntilFinished();
+ }
+
+ public void runTest(final Test test, final TestResult result) {
+ Thread t= new Thread() {
+ public void run() {
+ try {
+ // inlined due to limitation in VA/Java
+ //ActiveTestSuite.super.runTest(test, result);
+ test.run(result);
+ } finally {
+ ActiveTestSuite.this.runFinished(test);
+ }
+ }
+ };
+ t.start();
+ }
+
+ synchronized void waitUntilFinished() {
+ while (fActiveTestDeathCount < testCount()) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ return; // ignore
+ }
+ }
+ }
+
+ synchronized public void runFinished(Test test) {
+ fActiveTestDeathCount++;
+ notifyAll();
+ }
+}
diff --git a/junit/src/main/java/junit/extensions/ExceptionTestCase.java b/junit/src/main/java/junit/extensions/ExceptionTestCase.java
new file mode 100644
index 0000000..de64b5b
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/ExceptionTestCase.java
@@ -0,0 +1,46 @@
+package junit.extensions;
+
+import junit.framework.*;
+
+/**
+ * A TestCase that expects an Exception of class fExpected to be thrown.
+ * The other way to check that an expected exception is thrown is:
+ * <pre>
+ * try {
+ * shouldThrow();
+ * }
+ * catch (SpecialException e) {
+ * return;
+ * }
+ * fail("Expected SpecialException");
+ * </pre>
+ *
+ * To use ExceptionTestCase, create a TestCase like:
+ * <pre>
+ * new ExceptionTestCase("testShouldThrow", SpecialException.class);
+ * </pre>
+ */
+public class ExceptionTestCase extends TestCase {
+ Class fExpected;
+
+ public ExceptionTestCase(String name, Class exception) {
+ super(name);
+ fExpected= exception;
+ }
+ /**
+ * Execute the test method expecting that an Exception of
+ * class fExpected or one of its subclasses will be thrown
+ */
+ protected void runTest() throws Throwable {
+ try {
+ super.runTest();
+ }
+ catch (Exception e) {
+ if (fExpected.isAssignableFrom(e.getClass()))
+ return;
+ else
+ throw e;
+ }
+ fail("Expected exception " + fExpected);
+ }
+}
diff --git a/junit/src/main/java/junit/extensions/RepeatedTest.java b/junit/src/main/java/junit/extensions/RepeatedTest.java
new file mode 100644
index 0000000..34f2541
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/RepeatedTest.java
@@ -0,0 +1,31 @@
+package junit.extensions;
+
+import junit.framework.*;
+
+/**
+ * A Decorator that runs a test repeatedly.
+ *
+ */
+public class RepeatedTest extends TestDecorator {
+ private int fTimesRepeat;
+
+ public RepeatedTest(Test test, int repeat) {
+ super(test);
+ if (repeat < 0)
+ throw new IllegalArgumentException("Repetition count must be > 0");
+ fTimesRepeat= repeat;
+ }
+ public int countTestCases() {
+ return super.countTestCases()*fTimesRepeat;
+ }
+ public void run(TestResult result) {
+ for (int i= 0; i < fTimesRepeat; i++) {
+ if (result.shouldStop())
+ break;
+ super.run(result);
+ }
+ }
+ public String toString() {
+ return super.toString()+"(repeated)";
+ }
+}
diff --git a/junit/src/main/java/junit/extensions/TestDecorator.java b/junit/src/main/java/junit/extensions/TestDecorator.java
new file mode 100644
index 0000000..6b5144a
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/TestDecorator.java
@@ -0,0 +1,38 @@
+package junit.extensions;
+
+import junit.framework.*;
+
+/**
+ * A Decorator for Tests. Use TestDecorator as the base class
+ * for defining new test decorators. Test decorator subclasses
+ * can be introduced to add behaviour before or after a test
+ * is run.
+ *
+ */
+public class TestDecorator extends Assert implements Test {
+ protected Test fTest;
+
+ public TestDecorator(Test test) {
+ fTest= test;
+ }
+ /**
+ * The basic run behaviour.
+ */
+ public void basicRun(TestResult result) {
+ fTest.run(result);
+ }
+ public int countTestCases() {
+ return fTest.countTestCases();
+ }
+ public void run(TestResult result) {
+ basicRun(result);
+ }
+
+ public String toString() {
+ return fTest.toString();
+ }
+
+ public Test getTest() {
+ return fTest;
+ }
+}
diff --git a/junit/src/main/java/junit/extensions/TestSetup.java b/junit/src/main/java/junit/extensions/TestSetup.java
new file mode 100644
index 0000000..3651501
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/TestSetup.java
@@ -0,0 +1,37 @@
+package junit.extensions;
+
+import junit.framework.*;
+
+/**
+ * A Decorator to set up and tear down additional fixture state.
+ * Subclass TestSetup and insert it into your tests when you want
+ * to set up additional state once before the tests are run.
+ */
+public class TestSetup extends TestDecorator {
+
+ public TestSetup(Test test) {
+ super(test);
+ }
+ public void run(final TestResult result) {
+ Protectable p= new Protectable() {
+ public void protect() throws Exception {
+ setUp();
+ basicRun(result);
+ tearDown();
+ }
+ };
+ result.runProtected(this, p);
+ }
+ /**
+ * Sets up the fixture. Override to set up additional fixture
+ * state.
+ */
+ protected void setUp() throws Exception {
+ }
+ /**
+ * Tears down the fixture. Override to tear down the additional
+ * fixture state.
+ */
+ protected void tearDown() throws Exception {
+ }
+}
diff --git a/junit/src/main/java/junit/extensions/package.html b/junit/src/main/java/junit/extensions/package.html
new file mode 100644
index 0000000..6b4be72
--- /dev/null
+++ b/junit/src/main/java/junit/extensions/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<BODY>
+Utility classes supporting the junit test framework.
+{@hide} - Not needed for 1.0 SDK
+</BODY>
+</HTML>
diff --git a/junit/src/main/java/junit/framework/Assert.java b/junit/src/main/java/junit/framework/Assert.java
new file mode 100644
index 0000000..c1bc7b2
--- /dev/null
+++ b/junit/src/main/java/junit/framework/Assert.java
@@ -0,0 +1,291 @@
+package junit.framework;
+
+/**
+ * A set of assert methods. Messages are only displayed when an assert fails.
+ */
+
+public class Assert {
+ /**
+ * Protect constructor since it is a static only class
+ */
+ protected Assert() {
+ }
+
+ /**
+ * Asserts that a condition is true. If it isn't it throws
+ * an AssertionFailedError with the given message.
+ */
+ static public void assertTrue(String message, boolean condition) {
+ if (!condition)
+ fail(message);
+ }
+ /**
+ * Asserts that a condition is true. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ static public void assertTrue(boolean condition) {
+ assertTrue(null, condition);
+ }
+ /**
+ * Asserts that a condition is false. If it isn't it throws
+ * an AssertionFailedError with the given message.
+ */
+ static public void assertFalse(String message, boolean condition) {
+ assertTrue(message, !condition);
+ }
+ /**
+ * Asserts that a condition is false. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ static public void assertFalse(boolean condition) {
+ assertFalse(null, condition);
+ }
+ /**
+ * Fails a test with the given message.
+ */
+ static public void fail(String message) {
+ throw new AssertionFailedError(message);
+ }
+ /**
+ * Fails a test with no message.
+ */
+ static public void fail() {
+ fail(null);
+ }
+ /**
+ * Asserts that two objects are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, Object expected, Object actual) {
+ if (expected == null && actual == null)
+ return;
+ if (expected != null && expected.equals(actual))
+ return;
+ failNotEquals(message, expected, actual);
+ }
+ /**
+ * Asserts that two objects are equal. If they are not
+ * an AssertionFailedError is thrown.
+ */
+ static public void assertEquals(Object expected, Object actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two Strings are equal.
+ */
+ static public void assertEquals(String message, String expected, String actual) {
+ if (expected == null && actual == null)
+ return;
+ if (expected != null && expected.equals(actual))
+ return;
+ throw new ComparisonFailure(message, expected, actual);
+ }
+ /**
+ * Asserts that two Strings are equal.
+ */
+ static public void assertEquals(String expected, String actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two doubles are equal concerning a delta. If they are not
+ * an AssertionFailedError is thrown with the given message. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ static public void assertEquals(String message, double expected, double actual, double delta) {
+ // handle infinity specially since subtracting to infinite values gives NaN and the
+ // the following test fails
+ if (Double.isInfinite(expected)) {
+ if (!(expected == actual))
+ failNotEquals(message, new Double(expected), new Double(actual));
+ } else if (!(Math.abs(expected-actual) <= delta)) // Because comparison with NaN always returns false
+ failNotEquals(message, new Double(expected), new Double(actual));
+ }
+ /**
+ * Asserts that two doubles are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ static public void assertEquals(double expected, double actual, double delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+ /**
+ * Asserts that two floats are equal concerning a delta. If they are not
+ * an AssertionFailedError is thrown with the given message. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ static public void assertEquals(String message, float expected, float actual, float delta) {
+ // handle infinity specially since subtracting to infinite values gives NaN and the
+ // the following test fails
+ if (Float.isInfinite(expected)) {
+ if (!(expected == actual))
+ failNotEquals(message, new Float(expected), new Float(actual));
+ } else if (!(Math.abs(expected-actual) <= delta))
+ failNotEquals(message, new Float(expected), new Float(actual));
+ }
+ /**
+ * Asserts that two floats are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ static public void assertEquals(float expected, float actual, float delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+ /**
+ * Asserts that two longs are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, long expected, long actual) {
+ assertEquals(message, new Long(expected), new Long(actual));
+ }
+ /**
+ * Asserts that two longs are equal.
+ */
+ static public void assertEquals(long expected, long actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two booleans are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, boolean expected, boolean actual) {
+ assertEquals(message, new Boolean(expected), new Boolean(actual));
+ }
+ /**
+ * Asserts that two booleans are equal.
+ */
+ static public void assertEquals(boolean expected, boolean actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two bytes are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, byte expected, byte actual) {
+ assertEquals(message, new Byte(expected), new Byte(actual));
+ }
+ /**
+ * Asserts that two bytes are equal.
+ */
+ static public void assertEquals(byte expected, byte actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two chars are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, char expected, char actual) {
+ assertEquals(message, new Character(expected), new Character(actual));
+ }
+ /**
+ * Asserts that two chars are equal.
+ */
+ static public void assertEquals(char expected, char actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two shorts are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, short expected, short actual) {
+ assertEquals(message, new Short(expected), new Short(actual));
+ }
+ /**
+ * Asserts that two shorts are equal.
+ */
+ static public void assertEquals(short expected, short actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that two ints are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertEquals(String message, int expected, int actual) {
+ assertEquals(message, new Integer(expected), new Integer(actual));
+ }
+ /**
+ * Asserts that two ints are equal.
+ */
+ static public void assertEquals(int expected, int actual) {
+ assertEquals(null, expected, actual);
+ }
+ /**
+ * Asserts that an object isn't null.
+ */
+ static public void assertNotNull(Object object) {
+ assertNotNull(null, object);
+ }
+ /**
+ * Asserts that an object isn't null. If it is
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertNotNull(String message, Object object) {
+ assertTrue(message, object != null);
+ }
+ /**
+ * Asserts that an object is null.
+ */
+ static public void assertNull(Object object) {
+ assertNull(null, object);
+ }
+ /**
+ * Asserts that an object is null. If it is not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertNull(String message, Object object) {
+ assertTrue(message, object == null);
+ }
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertSame(String message, Object expected, Object actual) {
+ if (expected == actual)
+ return;
+ failNotSame(message, expected, actual);
+ }
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * the same an AssertionFailedError is thrown.
+ */
+ static public void assertSame(Object expected, Object actual) {
+ assertSame(null, expected, actual);
+ }
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ static public void assertNotSame(String message, Object expected, Object actual) {
+ if (expected == actual)
+ failSame(message);
+ }
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * the same an AssertionFailedError is thrown.
+ */
+ static public void assertNotSame(Object expected, Object actual) {
+ assertNotSame(null, expected, actual);
+ }
+
+ static private void failSame(String message) {
+ String formatted= "";
+ if (message != null)
+ formatted= message+" ";
+ fail(formatted+"expected not same");
+ }
+
+ static private void failNotSame(String message, Object expected, Object actual) {
+ String formatted= "";
+ if (message != null)
+ formatted= message+" ";
+ fail(formatted+"expected same:<"+expected+"> was not:<"+actual+">");
+ }
+
+ static private void failNotEquals(String message, Object expected, Object actual) {
+ fail(format(message, expected, actual));
+ }
+
+ static String format(String message, Object expected, Object actual) {
+ String formatted= "";
+ if (message != null)
+ formatted= message+" ";
+ return formatted+"expected:<"+expected+"> but was:<"+actual+">";
+ }
+}
diff --git a/junit/src/main/java/junit/framework/AssertionFailedError.java b/junit/src/main/java/junit/framework/AssertionFailedError.java
new file mode 100644
index 0000000..e9cb3a3
--- /dev/null
+++ b/junit/src/main/java/junit/framework/AssertionFailedError.java
@@ -0,0 +1,13 @@
+package junit.framework;
+
+/**
+ * Thrown when an assertion failed.
+ */
+public class AssertionFailedError extends Error {
+
+ public AssertionFailedError () {
+ }
+ public AssertionFailedError (String message) {
+ super (message);
+ }
+}
diff --git a/junit/src/main/java/junit/framework/ComparisonFailure.java b/junit/src/main/java/junit/framework/ComparisonFailure.java
new file mode 100644
index 0000000..a0ad176
--- /dev/null
+++ b/junit/src/main/java/junit/framework/ComparisonFailure.java
@@ -0,0 +1,68 @@
+package junit.framework;
+
+/**
+ * Thrown when an assert equals for Strings failed.
+ *
+ * Inspired by a patch from Alex Chaffee mailto:alex@purpletech.com
+ */
+public class ComparisonFailure extends AssertionFailedError {
+ private String fExpected;
+ private String fActual;
+
+ /**
+ * Constructs a comparison failure.
+ * @param message the identifying message or null
+ * @param expected the expected string value
+ * @param actual the actual string value
+ */
+ public ComparisonFailure (String message, String expected, String actual) {
+ super (message);
+ fExpected= expected;
+ fActual= actual;
+ }
+
+ /**
+ * Returns "..." in place of common prefix and "..." in
+ * place of common suffix between expected and actual.
+ *
+ * @see java.lang.Throwable#getMessage()
+ */
+ public String getMessage() {
+ if (fExpected == null || fActual == null)
+ return Assert.format(super.getMessage(), fExpected, fActual);
+
+ int end= Math.min(fExpected.length(), fActual.length());
+
+ int i= 0;
+ for(; i < end; i++) {
+ if (fExpected.charAt(i) != fActual.charAt(i))
+ break;
+ }
+ int j= fExpected.length()-1;
+ int k= fActual.length()-1;
+ for (; k >= i && j >= i; k--,j--) {
+ if (fExpected.charAt(j) != fActual.charAt(k))
+ break;
+ }
+ String actual, expected;
+
+ // equal strings
+ if (j < i && k < i) {
+ expected= fExpected;
+ actual= fActual;
+ } else {
+ expected= fExpected.substring(i, j+1);
+ actual= fActual.substring(i, k+1);
+ if (i <= end && i > 0) {
+ expected= "..."+expected;
+ actual= "..."+actual;
+ }
+
+ if (j < fExpected.length()-1)
+ expected= expected+"...";
+ if (k < fActual.length()-1)
+ actual= actual+"...";
+ }
+ return Assert.format(super.getMessage(), expected, actual);
+ }
+}
diff --git a/junit/src/main/java/junit/framework/Protectable.java b/junit/src/main/java/junit/framework/Protectable.java
new file mode 100644
index 0000000..9a63c96
--- /dev/null
+++ b/junit/src/main/java/junit/framework/Protectable.java
@@ -0,0 +1,14 @@
+package junit.framework;
+
+/**
+ * A <em>Protectable</em> can be run and can throw a Throwable.
+ *
+ * @see TestResult
+ */
+public interface Protectable {
+
+ /**
+ * Run the the following method protected.
+ */
+ public abstract void protect() throws Throwable;
+}
diff --git a/junit/src/main/java/junit/framework/Test.java b/junit/src/main/java/junit/framework/Test.java
new file mode 100644
index 0000000..94f25cf
--- /dev/null
+++ b/junit/src/main/java/junit/framework/Test.java
@@ -0,0 +1,17 @@
+package junit.framework;
+
+/**
+ * A <em>Test</em> can be run and collect its results.
+ *
+ * @see TestResult
+ */
+public interface Test {
+ /**
+ * Counts the number of test cases that will be run by this test.
+ */
+ public abstract int countTestCases();
+ /**
+ * Runs a test and collects its result in a TestResult instance.
+ */
+ public abstract void run(TestResult result);
+}
diff --git a/junit/src/main/java/junit/framework/TestCase.java b/junit/src/main/java/junit/framework/TestCase.java
new file mode 100644
index 0000000..f29e8d2
--- /dev/null
+++ b/junit/src/main/java/junit/framework/TestCase.java
@@ -0,0 +1,197 @@
+package junit.framework;
+
+import java.lang.reflect.*;
+
+/**
+ * A test case defines the fixture to run multiple tests. To define a test case<br>
+ * 1) implement a subclass of TestCase<br>
+ * 2) define instance variables that store the state of the fixture<br>
+ * 3) initialize the fixture state by overriding <code>setUp</code><br>
+ * 4) clean-up after a test by overriding <code>tearDown</code>.<br>
+ * Each test runs in its own fixture so there
+ * can be no side effects among test runs.
+ * Here is an example:
+ * <pre>
+ * public class MathTest extends TestCase {
+ * protected double fValue1;
+ * protected double fValue2;
+ *
+ * protected void setUp() {
+ * fValue1= 2.0;
+ * fValue2= 3.0;
+ * }
+ * }
+ * </pre>
+ *
+ * For each test implement a method which interacts
+ * with the fixture. Verify the expected results with assertions specified
+ * by calling <code>assertTrue</code> with a boolean.
+ * <pre>
+ * public void testAdd() {
+ * double result= fValue1 + fValue2;
+ * assertTrue(result == 5.0);
+ * }
+ * </pre>
+ * Once the methods are defined you can run them. The framework supports
+ * both a static type safe and more dynamic way to run a test.
+ * In the static way you override the runTest method and define the method to
+ * be invoked. A convenient way to do so is with an anonymous inner class.
+ * <pre>
+ * TestCase test= new MathTest("add") {
+ * public void runTest() {
+ * testAdd();
+ * }
+ * };
+ * test.run();
+ * </pre>
+ * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds
+ * and invokes a method.
+ * In this case the name of the test case has to correspond to the test method
+ * to be run.
+ * <pre>
+ * TestCase= new MathTest("testAdd");
+ * test.run();
+ * </pre>
+ * The tests to be run can be collected into a TestSuite. JUnit provides
+ * different <i>test runners</i> which can run a test suite and collect the results.
+ * A test runner either expects a static method <code>suite</code> as the entry
+ * point to get a test to run or it will extract the suite automatically.
+ * <pre>
+ * public static Test suite() {
+ * suite.addTest(new MathTest("testAdd"));
+ * suite.addTest(new MathTest("testDivideByZero"));
+ * return suite;
+ * }
+ * </pre>
+ * @see TestResult
+ * @see TestSuite
+ */
+
+public abstract class TestCase extends Assert implements Test {
+ /**
+ * the name of the test case
+ */
+ private String fName;
+
+ /**
+ * No-arg constructor to enable serialization. This method
+ * is not intended to be used by mere mortals without calling setName().
+ */
+ public TestCase() {
+ fName= null;
+ }
+ /**
+ * Constructs a test case with the given name.
+ */
+ public TestCase(String name) {
+ fName= name;
+ }
+ /**
+ * Counts the number of test cases executed by run(TestResult result).
+ */
+ public int countTestCases() {
+ return 1;
+ }
+ /**
+ * Creates a default TestResult object
+ *
+ * @see TestResult
+ */
+ protected TestResult createResult() {
+ return new TestResult();
+ }
+ /**
+ * A convenience method to run this test, collecting the results with a
+ * default TestResult object.
+ *
+ * @see TestResult
+ */
+ public TestResult run() {
+ TestResult result= createResult();
+ run(result);
+ return result;
+ }
+ /**
+ * Runs the test case and collects the results in TestResult.
+ */
+ public void run(TestResult result) {
+ result.run(this);
+ }
+ /**
+ * Runs the bare test sequence.
+ * @exception Throwable if any exception is thrown
+ */
+ public void runBare() throws Throwable {
+ setUp();
+ try {
+ runTest();
+ }
+ finally {
+ tearDown();
+ }
+ }
+ /**
+ * Override to run the test and assert its state.
+ * @exception Throwable if any exception is thrown
+ */
+ protected void runTest() throws Throwable {
+ assertNotNull(fName);
+ Method runMethod= null;
+ try {
+ // use getMethod to get all public inherited
+ // methods. getDeclaredMethods returns all
+ // methods of this class but excludes the
+ // inherited ones.
+ runMethod= getClass().getMethod(fName, (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ fail("Method \""+fName+"\" not found");
+ }
+ if (!Modifier.isPublic(runMethod.getModifiers())) {
+ fail("Method \""+fName+"\" should be public");
+ }
+
+ try {
+ runMethod.invoke(this, (Object[]) null);
+ }
+ catch (InvocationTargetException e) {
+ e.fillInStackTrace();
+ throw e.getTargetException();
+ }
+ catch (IllegalAccessException e) {
+ e.fillInStackTrace();
+ throw e;
+ }
+ }
+ /**
+ * Sets up the fixture, for example, open a network connection.
+ * This method is called before a test is executed.
+ */
+ protected void setUp() throws Exception {
+ }
+ /**
+ * Tears down the fixture, for example, close a network connection.
+ * This method is called after a test is executed.
+ */
+ protected void tearDown() throws Exception {
+ }
+ /**
+ * Returns a string representation of the test case
+ */
+ public String toString() {
+ return getName() + "(" + getClass().getName() + ")";
+ }
+ /**
+ * Gets the name of a TestCase
+ * @return returns a String
+ */
+ public String getName() {
+ return fName;
+ }
+ /**
+ * Sets the name of a TestCase
+ * @param name The name to set
+ */
+ public void setName(String name) {
+ fName= name;
+ }
+}
diff --git a/junit/src/main/java/junit/framework/TestFailure.java b/junit/src/main/java/junit/framework/TestFailure.java
new file mode 100644
index 0000000..ace2dbe
--- /dev/null
+++ b/junit/src/main/java/junit/framework/TestFailure.java
@@ -0,0 +1,57 @@
+package junit.framework;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+
+/**
+ * A <code>TestFailure</code> collects a failed test together with
+ * the caught exception.
+ * @see TestResult
+ */
+public class TestFailure extends Object {
+ protected Test fFailedTest;
+ protected Throwable fThrownException;
+
+
+ /**
+ * Constructs a TestFailure with the given test and exception.
+ */
+ public TestFailure(Test failedTest, Throwable thrownException) {
+ fFailedTest= failedTest;
+ fThrownException= thrownException;
+ }
+ /**
+ * Gets the failed test.
+ */
+ public Test failedTest() {
+ return fFailedTest;
+ }
+ /**
+ * Gets the thrown exception.
+ */
+ public Throwable thrownException() {
+ return fThrownException;
+ }
+ /**
+ * Returns a short description of the failure.
+ */
+ public String toString() {
+ StringBuffer buffer= new StringBuffer();
+ buffer.append(fFailedTest+": "+fThrownException.getMessage());
+ return buffer.toString();
+ }
+ public String trace() {
+ StringWriter stringWriter= new StringWriter();
+ PrintWriter writer= new PrintWriter(stringWriter);
+ thrownException().printStackTrace(writer);
+ StringBuffer buffer= stringWriter.getBuffer();
+ return buffer.toString();
+ }
+ public String exceptionMessage() {
+ return thrownException().getMessage();
+ }
+ public boolean isFailure() {
+ return thrownException() instanceof AssertionFailedError;
+ }
+}
diff --git a/junit/src/main/java/junit/framework/TestListener.java b/junit/src/main/java/junit/framework/TestListener.java
new file mode 100644
index 0000000..3ef3e33
--- /dev/null
+++ b/junit/src/main/java/junit/framework/TestListener.java
@@ -0,0 +1,23 @@
+package junit.framework;
+
+/**
+ * A Listener for test progress
+ */
+public interface TestListener {
+ /**
+ * An error occurred.
+ */
+ public void addError(Test test, Throwable t);
+ /**
+ * A failure occurred.
+ */
+ public void addFailure(Test test, AssertionFailedError t);
+ /**
+ * A test ended.
+ */
+ public void endTest(Test test);
+ /**
+ * A test started.
+ */
+ public void startTest(Test test);
+}
diff --git a/junit/src/main/java/junit/framework/TestResult.java b/junit/src/main/java/junit/framework/TestResult.java
new file mode 100644
index 0000000..153a77b
--- /dev/null
+++ b/junit/src/main/java/junit/framework/TestResult.java
@@ -0,0 +1,166 @@
+package junit.framework;
+
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * A <code>TestResult</code> collects the results of executing
+ * a test case. It is an instance of the Collecting Parameter pattern.
+ * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
+ * A failure is anticipated and checked for with assertions. Errors are
+ * unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
+ *
+ * @see Test
+ */
+public class TestResult extends Object {
+ protected Vector fFailures;
+ protected Vector fErrors;
+ protected Vector fListeners;
+ protected int fRunTests;
+ private boolean fStop;
+
+ public TestResult() {
+ fFailures= new Vector();
+ fErrors= new Vector();
+ fListeners= new Vector();
+ fRunTests= 0;
+ fStop= false;
+ }
+ /**
+ * Adds an error to the list of errors. The passed in exception
+ * caused the error.
+ */
+ public synchronized void addError(Test test, Throwable t) {
+ fErrors.addElement(new TestFailure(test, t));
+ for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
+ ((TestListener)e.nextElement()).addError(test, t);
+ }
+ }
+ /**
+ * Adds a failure to the list of failures. The passed in exception
+ * caused the failure.
+ */
+ public synchronized void addFailure(Test test, AssertionFailedError t) {
+ fFailures.addElement(new TestFailure(test, t));
+ for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
+ ((TestListener)e.nextElement()).addFailure(test, t);
+ }
+ }
+ /**
+ * Registers a TestListener
+ */
+ public synchronized void addListener(TestListener listener) {
+ fListeners.addElement(listener);
+ }
+ /**
+ * Unregisters a TestListener
+ */
+ public synchronized void removeListener(TestListener listener) {
+ fListeners.removeElement(listener);
+ }
+ /**
+ * Returns a copy of the listeners.
+ */
+ private synchronized Vector cloneListeners() {
+ return (Vector)fListeners.clone();
+ }
+ /**
+ * Informs the result that a test was completed.
+ */
+ public void endTest(Test test) {
+ for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
+ ((TestListener)e.nextElement()).endTest(test);
+ }
+ }
+ /**
+ * Gets the number of detected errors.
+ */
+ public synchronized int errorCount() {
+ return fErrors.size();
+ }
+ /**
+ * Returns an Enumeration for the errors
+ */
+ public synchronized Enumeration errors() {
+ return fErrors.elements();
+ }
+ /**
+ * Gets the number of detected failures.
+ */
+ public synchronized int failureCount() {
+ return fFailures.size();
+ }
+ /**
+ * Returns an Enumeration for the failures
+ */
+ public synchronized Enumeration failures() {
+ return fFailures.elements();
+ }
+ /**
+ * Runs a TestCase.
+ */
+ protected void run(final TestCase test) {
+ startTest(test);
+ Protectable p= new Protectable() {
+ public void protect() throws Throwable {
+ test.runBare();
+ }
+ };
+ runProtected(test, p);
+
+ endTest(test);
+ }
+ /**
+ * Gets the number of run tests.
+ */
+ public synchronized int runCount() {
+ return fRunTests;
+ }
+ /**
+ * Runs a TestCase.
+ */
+ public void runProtected(final Test test, Protectable p) {
+ try {
+ p.protect();
+ }
+ catch (AssertionFailedError e) {
+ addFailure(test, e);
+ }
+ catch (ThreadDeath e) { // don't catch ThreadDeath by accident
+ throw e;
+ }
+ catch (Throwable e) {
+ addError(test, e);
+ }
+ }
+ /**
+ * Checks whether the test run should stop
+ */
+ public synchronized boolean shouldStop() {
+ return fStop;
+ }
+ /**
+ * Informs the result that a test will be started.
+ */
+ public void startTest(Test test) {
+ final int count= test.countTestCases();
+ synchronized(this) {
+ fRunTests+= count;
+ }
+ for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
+ ((TestListener)e.nextElement()).startTest(test);
+ }
+ }
+ /**
+ * Marks that the test run should stop.
+ */
+ public synchronized void stop() {
+ fStop= true;
+ }
+ /**
+ * Returns whether the entire test was successful or not.
+ */
+ public synchronized boolean wasSuccessful() {
+ return failureCount() == 0 && errorCount() == 0;
+ }
+}
diff --git a/junit/src/main/java/junit/framework/TestSuite.java b/junit/src/main/java/junit/framework/TestSuite.java
new file mode 100644
index 0000000..bf23198
--- /dev/null
+++ b/junit/src/main/java/junit/framework/TestSuite.java
@@ -0,0 +1,267 @@
+package junit.framework;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * A <code>TestSuite</code> is a <code>Composite</code> of Tests.
+ * It runs a collection of test cases. Here is an example using
+ * the dynamic test definition.
+ * <pre>
+ * TestSuite suite= new TestSuite();
+ * suite.addTest(new MathTest("testAdd"));
+ * suite.addTest(new MathTest("testDivideByZero"));
+ * </pre>
+ * Alternatively, a TestSuite can extract the tests to be run automatically.
+ * To do so you pass the class of your TestCase class to the
+ * TestSuite constructor.
+ * <pre>
+ * TestSuite suite= new TestSuite(MathTest.class);
+ * </pre>
+ * This constructor creates a suite with all the methods
+ * starting with "test" that take no arguments.
+ *
+ * @see Test
+ */
+public class TestSuite implements Test {
+
+ private Vector fTests= new Vector(10);
+ private String fName;
+
+ /**
+ * Constructs an empty TestSuite.
+ */
+ public TestSuite() {
+ }
+
+ /**
+ * Constructs a TestSuite from the given class with the given name.
+ * @see TestSuite#TestSuite(Class)
+ */
+ public TestSuite(Class theClass, String name) {
+ this(theClass);
+ setName(name);
+ }
+
+ /**
+ * Constructs a TestSuite from the given class. Adds all the methods
+ * starting with "test" as test cases to the suite.
+ * Parts of this method was written at 2337 meters in the Huffihutte,
+ * Kanton Uri
+ */
+ public TestSuite(final Class theClass) {
+ fName= theClass.getName();
+ try {
+ getTestConstructor(theClass); // Avoid generating multiple error messages
+ } catch (NoSuchMethodException e) {
+ addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
+ return;
+ }
+
+ if (!Modifier.isPublic(theClass.getModifiers())) {
+ addTest(warning("Class "+theClass.getName()+" is not public"));
+ return;
+ }
+
+ Class superClass= theClass;
+ Vector names= new Vector();
+ while (Test.class.isAssignableFrom(superClass)) {
+ Method[] methods= superClass.getDeclaredMethods();
+ for (int i= 0; i < methods.length; i++) {
+ addTestMethod(methods[i], names, theClass);
+ }
+ superClass= superClass.getSuperclass();
+ }
+ if (fTests.size() == 0)
+ addTest(warning("No tests found in "+theClass.getName()));
+ }
+
+ /**
+ * Constructs an empty TestSuite.
+ */
+ public TestSuite(String name) {
+ setName(name);
+ }
+
+ /**
+ * Adds a test to the suite.
+ */
+ public void addTest(Test test) {
+ fTests.addElement(test);
+ }
+
+ /**
+ * Adds the tests from the given class to the suite
+ */
+ public void addTestSuite(Class testClass) {
+ addTest(new TestSuite(testClass));
+ }
+
+ private void addTestMethod(Method m, Vector names, Class theClass) {
+ String name= m.getName();
+ if (names.contains(name))
+ return;
+ if (! isPublicTestMethod(m)) {
+ if (isTestMethod(m))
+ addTest(warning("Test method isn't public: "+m.getName()));
+ return;
+ }
+ names.addElement(name);
+ addTest(createTest(theClass, name));
+ }
+
+ /**
+ * ...as the moon sets over the early morning Merlin, Oregon
+ * mountains, our intrepid adventurers type...
+ */
+ static public Test createTest(Class theClass, String name) {
+ Constructor constructor;
+ try {
+ constructor= getTestConstructor(theClass);
+ } catch (NoSuchMethodException e) {
+ return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
+ }
+ Object test;
+ try {
+ if (constructor.getParameterTypes().length == 0) {
+ test= constructor.newInstance(new Object[0]);
+ if (test instanceof TestCase)
+ ((TestCase) test).setName(name);
+ } else {
+ test= constructor.newInstance(new Object[]{name});
+ }
+ } catch (InstantiationException e) {
+ return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
+ } catch (InvocationTargetException e) {
+ return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
+ } catch (IllegalAccessException e) {
+ return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
+ }
+ return (Test) test;
+ }
+
+ /**
+ * Converts the stack trace into a string
+ */
+ private static String exceptionToString(Throwable t) {
+ StringWriter stringWriter= new StringWriter();
+ PrintWriter writer= new PrintWriter(stringWriter);
+ t.printStackTrace(writer);
+ return stringWriter.toString();
+
+ }
+
+ /**
+ * Counts the number of test cases that will be run by this test.
+ */
+ public int countTestCases() {
+ int count= 0;
+ for (Enumeration e= tests(); e.hasMoreElements(); ) {
+ Test test= (Test)e.nextElement();
+ count= count + test.countTestCases();
+ }
+ return count;
+ }
+
+ /**
+ * Gets a constructor which takes a single String as
+ * its argument or a no arg constructor.
+ */
+ public static Constructor getTestConstructor(Class theClass) throws NoSuchMethodException {
+ Class[] args= { String.class };
+ try {
+ return theClass.getConstructor(args);
+ } catch (NoSuchMethodException e) {
+ // fall through
+ }
+ return theClass.getConstructor(new Class[0]);
+ }
+
+ private boolean isPublicTestMethod(Method m) {
+ return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+ }
+
+ private boolean isTestMethod(Method m) {
+ String name= m.getName();
+ Class[] parameters= m.getParameterTypes();
+ Class returnType= m.getReturnType();
+ return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
+ }
+
+ /**
+ * Runs the tests and collects their result in a TestResult.
+ */
+ public void run(TestResult result) {
+ for (Enumeration e= tests(); e.hasMoreElements(); ) {
+ if (result.shouldStop() )
+ break;
+ Test test= (Test)e.nextElement();
+ runTest(test, result);
+ }
+ }
+
+ public void runTest(Test test, TestResult result) {
+ test.run(result);
+ }
+
+ /**
+ * Returns the test at the given index
+ */
+ public Test testAt(int index) {
+ return (Test)fTests.elementAt(index);
+ }
+
+ /**
+ * Returns the number of tests in this suite
+ */
+ public int testCount() {
+ return fTests.size();
+ }
+
+ /**
+ * Returns the tests as an enumeration
+ */
+ public Enumeration tests() {
+ return fTests.elements();
+ }
+
+ /**
+ */
+ public String toString() {
+ if (getName() != null)
+ return getName();
+ return super.toString();
+ }
+
+ /**
+ * Sets the name of the suite.
+ * @param name The name to set
+ */
+ public void setName(String name) {
+ fName= name;
+ }
+
+ /**
+ * Returns the name of the suite. Not all
+ * test suites have a name and this method
+ * can return null.
+ */
+ public String getName() {
+ return fName;
+ }
+
+ /**
+ * Returns a test which will fail and log a warning message.
+ */
+ private static Test warning(final String message) {
+ return new TestCase("warning") {
+ protected void runTest() {
+ fail(message);
+ }
+ };
+ }
+}
diff --git a/junit/src/main/java/junit/framework/package.html b/junit/src/main/java/junit/framework/package.html
new file mode 100644
index 0000000..770d470
--- /dev/null
+++ b/junit/src/main/java/junit/framework/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+The junit test framework.
+</BODY>
+</HTML>