diff options
15 files changed, 484 insertions, 324 deletions
diff --git a/junit/src/main/java/junit/extensions/ActiveTestSuite.java b/junit/src/main/java/junit/extensions/ActiveTestSuite.java index 8b62853..bf50744 100644 --- a/junit/src/main/java/junit/extensions/ActiveTestSuite.java +++ b/junit/src/main/java/junit/extensions/ActiveTestSuite.java @@ -1,6 +1,9 @@ package junit.extensions; -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestResult; +import junit.framework.TestSuite; /** * A TestSuite for active Tests. It runs each @@ -14,7 +17,7 @@ public class ActiveTestSuite extends TestSuite { public ActiveTestSuite() { } - public ActiveTestSuite(Class theClass) { + public ActiveTestSuite(Class<? extends TestCase> theClass) { super(theClass); } @@ -22,25 +25,28 @@ public class ActiveTestSuite extends TestSuite { super (name); } - public ActiveTestSuite(Class theClass, String name) { + public ActiveTestSuite(Class<? extends TestCase> theClass, String name) { super(theClass, name); } + @Override public void run(TestResult result) { fActiveTestDeathCount= 0; super.run(result); waitUntilFinished(); } + @Override public void runTest(final Test test, final TestResult result) { Thread t= new Thread() { + @Override public void run() { try { // inlined due to limitation in VA/Java //ActiveTestSuite.super.runTest(test, result); test.run(result); } finally { - ActiveTestSuite.this.runFinished(test); + ActiveTestSuite.this.runFinished(); } } }; @@ -57,8 +63,8 @@ public class ActiveTestSuite extends TestSuite { } } - synchronized public void runFinished(Test test) { + synchronized public void runFinished() { fActiveTestDeathCount++; notifyAll(); } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/extensions/RepeatedTest.java b/junit/src/main/java/junit/extensions/RepeatedTest.java index 34f2541..74a7832 100644 --- a/junit/src/main/java/junit/extensions/RepeatedTest.java +++ b/junit/src/main/java/junit/extensions/RepeatedTest.java @@ -1,23 +1,28 @@ package junit.extensions; -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestResult; /** * A Decorator that runs a test repeatedly. - * + * */ -public class RepeatedTest extends TestDecorator { +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"); + throw new IllegalArgumentException("Repetition count must be >= 0"); fTimesRepeat= repeat; } + + @Override public int countTestCases() { - return super.countTestCases()*fTimesRepeat; + return super.countTestCases() * fTimesRepeat; } + + @Override public void run(TestResult result) { for (int i= 0; i < fTimesRepeat; i++) { if (result.shouldStop()) @@ -25,7 +30,9 @@ public class RepeatedTest extends TestDecorator { super.run(result); } } + + @Override public String toString() { - return super.toString()+"(repeated)"; + return super.toString() + "(repeated)"; } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/extensions/TestDecorator.java b/junit/src/main/java/junit/extensions/TestDecorator.java index cfbd021..52b9626 100644 --- a/junit/src/main/java/junit/extensions/TestDecorator.java +++ b/junit/src/main/java/junit/extensions/TestDecorator.java @@ -1,13 +1,14 @@ package junit.extensions; -import junit.framework.*; +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestResult; /** - * A Decorator for Tests. Use TestDecorator as the base class - * for defining new test decorators. Test decorator subclasses - * can be introduced to add behavior before or after a test - * is run. - * + * 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; @@ -15,19 +16,23 @@ public class TestDecorator extends Assert implements Test { public TestDecorator(Test test) { fTest= test; } + /** - * The basic run behavior. + * 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); } + @Override public String toString() { return fTest.toString(); } @@ -35,4 +40,4 @@ public class TestDecorator extends Assert implements Test { public Test getTest() { return fTest; } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/extensions/TestSetup.java b/junit/src/main/java/junit/extensions/TestSetup.java index 3651501..641c497 100644 --- a/junit/src/main/java/junit/extensions/TestSetup.java +++ b/junit/src/main/java/junit/extensions/TestSetup.java @@ -1,17 +1,21 @@ package junit.extensions; -import junit.framework.*; +import junit.framework.Protectable; +import junit.framework.Test; +import junit.framework.TestResult; /** - * 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. + * 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); } + + @Override public void run(final TestResult result) { Protectable p= new Protectable() { public void protect() throws Exception { @@ -22,16 +26,17 @@ public class TestSetup extends TestDecorator { }; result.runProtected(this, p); } + /** - * Sets up the fixture. Override to set up additional fixture - * state. + * 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. + * Tears down the fixture. Override to tear down the additional fixture + * state. */ protected void tearDown() throws Exception { } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/Assert.java b/junit/src/main/java/junit/framework/Assert.java index 289449a..b9f7f42 100644 --- a/junit/src/main/java/junit/framework/Assert.java +++ b/junit/src/main/java/junit/framework/Assert.java @@ -44,6 +44,9 @@ public class Assert { * Fails a test with the given message. */ static public void fail(String message) { + if (message == null) { + throw new AssertionFailedError(); + } throw new AssertionFailedError(message); } /** @@ -78,7 +81,8 @@ public class Assert { return; if (expected != null && expected.equals(actual)) return; - throw new ComparisonFailure(message, expected, actual); + String cleanMessage= message == null ? "" : message; + throw new ComparisonFailure(cleanMessage, expected, actual); } /** * Asserts that two Strings are equal. @@ -92,12 +96,9 @@ public class Assert { * 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 + if (Double.compare(expected, actual) == 0) + return; + if (!(Math.abs(expected-actual) <= delta)) failNotEquals(message, new Double(expected), new Double(actual)); } /** @@ -108,18 +109,15 @@ public class Assert { 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. + * Asserts that two floats are equal concerning a positive 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)); + if (Float.compare(expected, actual) == 0) + return; + 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 @@ -146,11 +144,11 @@ public class Assert { * 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)); - } + assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual)); + } /** * Asserts that two booleans are equal. - */ + */ static public void assertEquals(boolean expected, boolean actual) { assertEquals(null, expected, actual); } @@ -158,11 +156,11 @@ public class Assert { * 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) { + static public void assertEquals(String message, byte expected, byte actual) { assertEquals(message, new Byte(expected), new Byte(actual)); } /** - * Asserts that two bytes are equal. + * Asserts that two bytes are equal. */ static public void assertEquals(byte expected, byte actual) { assertEquals(null, expected, actual); @@ -171,13 +169,13 @@ public class Assert { * 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)); - } + 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) { + static public void assertEquals(char expected, char actual) { assertEquals(null, expected, actual); } /** @@ -185,9 +183,9 @@ public class Assert { * 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)); + assertEquals(message, new Short(expected), new Short(actual)); } - /** + /** * Asserts that two shorts are equal. */ static public void assertEquals(short expected, short actual) { @@ -197,14 +195,14 @@ public class Assert { * 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) { + static public void assertEquals(String message, int expected, int actual) { assertEquals(message, new Integer(expected), new Integer(actual)); - } - /** - * Asserts that two ints are equal. + } + /** + * Asserts that two ints are equal. */ - static public void assertEquals(int expected, int actual) { - assertEquals(null, expected, actual); + static public void assertEquals(int expected, int actual) { + assertEquals(null, expected, actual); } /** * Asserts that an object isn't null. @@ -220,10 +218,16 @@ public class Assert { assertTrue(message, object != null); } /** - * Asserts that an object is null. + * Asserts that an object is null. If it isn't an {@link AssertionError} is + * thrown. + * Message contains: Expected: <null> but was: object + * + * @param object + * Object to check or <code>null</code> */ static public void assertNull(Object object) { - assertNull(null, object); + String message = "Expected: <null> but was: " + String.valueOf(object); + assertNull(message, object); } /** * Asserts that an object is null. If it is not @@ -248,43 +252,44 @@ public class Assert { static public void assertSame(Object expected, Object actual) { assertSame(null, expected, actual); } - /** - * Asserts that two objects do not refer to the same object. If they are - * an AssertionFailedError is thrown with the given message. - */ + /** + * Asserts that two objects do not refer to the same object. If they do + * refer to the same object 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 do not refer to the same object. If they are - * the same an AssertionFailedError is thrown. + * Asserts that two objects do not refer to the same object. If they do + * refer to the same object an AssertionFailedError is thrown. */ static public void assertNotSame(Object expected, Object actual) { assertNotSame(null, expected, actual); } - static private void failSame(String message) { + static public void failSame(String message) { String formatted= ""; - if (message != null) - formatted= message+" "; - fail(formatted+"expected not same"); + if (message != null) + formatted= message+" "; + fail(formatted+"expected not same"); } - static private void failNotSame(String message, Object expected, Object actual) { + static public 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) { + static public void failNotEquals(String message, Object expected, Object actual) { fail(format(message, expected, actual)); } - static String format(String message, Object expected, Object actual) { + public static String format(String message, Object expected, Object actual) { String formatted= ""; - if (message != null) + if (message != null && message.length() > 0) 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 index e9cb3a3..9cae916 100644 --- a/junit/src/main/java/junit/framework/AssertionFailedError.java +++ b/junit/src/main/java/junit/framework/AssertionFailedError.java @@ -3,11 +3,18 @@ package junit.framework; /** * Thrown when an assertion failed. */ -public class AssertionFailedError extends Error { +public class AssertionFailedError extends AssertionError { - public AssertionFailedError () { + private static final long serialVersionUID= 1L; + + public AssertionFailedError() { + } + + public AssertionFailedError(String message) { + super(defaultString(message)); } - public AssertionFailedError (String message) { - super (message); + + private static String defaultString(String message) { + return message == null ? "" : message; } } diff --git a/junit/src/main/java/junit/framework/ComparisonCompactor.java b/junit/src/main/java/junit/framework/ComparisonCompactor.java new file mode 100644 index 0000000..3ca497a --- /dev/null +++ b/junit/src/main/java/junit/framework/ComparisonCompactor.java @@ -0,0 +1,76 @@ +package junit.framework; + +// android-changed add @hide +/** + * @hide not needed for public API + */ +public class ComparisonCompactor { + + private static final String ELLIPSIS= "..."; + private static final String DELTA_END= "]"; + private static final String DELTA_START= "["; + + private int fContextLength; + private String fExpected; + private String fActual; + private int fPrefix; + private int fSuffix; + + public ComparisonCompactor(int contextLength, String expected, String actual) { + fContextLength= contextLength; + fExpected= expected; + fActual= actual; + } + + public String compact(String message) { + if (fExpected == null || fActual == null || areStringsEqual()) + return Assert.format(message, fExpected, fActual); + + findCommonPrefix(); + findCommonSuffix(); + String expected= compactString(fExpected); + String actual= compactString(fActual); + return Assert.format(message, expected, actual); + } + + private String compactString(String source) { + String result= DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END; + if (fPrefix > 0) + result= computeCommonPrefix() + result; + if (fSuffix > 0) + result= result + computeCommonSuffix(); + return result; + } + + private void findCommonPrefix() { + fPrefix= 0; + int end= Math.min(fExpected.length(), fActual.length()); + for (; fPrefix < end; fPrefix++) { + if (fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) + break; + } + } + + private void findCommonSuffix() { + int expectedSuffix= fExpected.length() - 1; + int actualSuffix= fActual.length() - 1; + for (; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) { + if (fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) + break; + } + fSuffix= fExpected.length() - expectedSuffix; + } + + private String computeCommonPrefix() { + return (fPrefix > fContextLength ? ELLIPSIS : "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix); + } + + private String computeCommonSuffix() { + int end= Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length()); + return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength ? ELLIPSIS : ""); + } + + private boolean areStringsEqual() { + return fExpected.equals(fActual); + } +} diff --git a/junit/src/main/java/junit/framework/ComparisonFailure.java b/junit/src/main/java/junit/framework/ComparisonFailure.java index ccd476b..2fd7069 100644 --- a/junit/src/main/java/junit/framework/ComparisonFailure.java +++ b/junit/src/main/java/junit/framework/ComparisonFailure.java @@ -6,6 +6,9 @@ package junit.framework; * Inspired by a patch from Alex Chaffee mailto:alex@purpletech.com */ public class ComparisonFailure extends AssertionFailedError { + private static final int MAX_CONTEXT_LENGTH= 20; + private static final long serialVersionUID= 1L; + private String fExpected; private String fActual; @@ -25,44 +28,25 @@ public class ComparisonFailure extends AssertionFailedError { * Returns "..." in place of common prefix and "..." in * place of common suffix between expected and actual. * - * @see java.lang.Throwable#getMessage() + * @see Throwable#getMessage() */ + @Override 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; - } + return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage()); + } - if (j < fExpected.length()-1) - expected= expected+"..."; - if (k < fActual.length()-1) - actual= actual+"..."; - } - return Assert.format(super.getMessage(), expected, actual); + /** + * Gets the actual string value + * @return the actual string value + */ + public String getActual() { + return fActual; + } + /** + * Gets the expected string value + * @return the expected string value + */ + public String getExpected() { + return fExpected; } } diff --git a/junit/src/main/java/junit/framework/Protectable.java b/junit/src/main/java/junit/framework/Protectable.java index 9a63c96..9f30b10 100644 --- a/junit/src/main/java/junit/framework/Protectable.java +++ b/junit/src/main/java/junit/framework/Protectable.java @@ -11,4 +11,4 @@ public interface Protectable { * Run the the following method protected. */ public abstract void protect() throws Throwable; -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/Test.java b/junit/src/main/java/junit/framework/Test.java index 94f25cf..6e04b31 100644 --- a/junit/src/main/java/junit/framework/Test.java +++ b/junit/src/main/java/junit/framework/Test.java @@ -14,4 +14,4 @@ public interface Test { * Runs a test and collects its result in a TestResult instance. */ public abstract void run(TestResult result); -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/TestCase.java b/junit/src/main/java/junit/framework/TestCase.java index f29e8d2..05a02ac 100644 --- a/junit/src/main/java/junit/framework/TestCase.java +++ b/junit/src/main/java/junit/framework/TestCase.java @@ -1,72 +1,78 @@ package junit.framework; -import java.lang.reflect.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; /** - * 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> + * A test case defines the fixture to run multiple tests. To define a test case<br/> + * <ol> + * <li>implement a subclass of <code>TestCase</code></li> + * <li>define instance variables that store the state of the fixture</li> + * <li>initialize the fixture state by overriding {@link #setUp()}</li> + * <li>clean-up after a test by overriding {@link #tearDown()}.</li> + * </ol> * 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 double fValue1; + * protected double fValue2; * * protected void setUp() { - * fValue1= 2.0; - * fValue2= 3.0; - * } + * 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. + * by calling {@link junit.framework.Assert#assertTrue(String, boolean)} with a boolean. * <pre> * public void testAdd() { - * double result= fValue1 + fValue2; - * assertTrue(result == 5.0); + * 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(); - * } + * public void runTest() { + * testAdd(); + * } * }; * test.run(); * </pre> - * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds + * + * The dynamic way uses reflection to implement {@link #runTest()}. 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"); + * TestCase test= 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; - * } + * 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 @@ -119,30 +125,38 @@ public abstract class TestCase extends Assert implements Test { } /** * Runs the bare test sequence. - * @exception Throwable if any exception is thrown + * @throws Throwable if any exception is thrown */ public void runBare() throws Throwable { + Throwable exception= null; setUp(); try { runTest(); + } catch (Throwable running) { + exception= running; } finally { - tearDown(); + try { + tearDown(); + } catch (Throwable tearingDown) { + if (exception == null) exception= tearingDown; + } } + if (exception != null) throw exception; } /** * Override to run the test and assert its state. - * @exception Throwable if any exception is thrown + * @throws Throwable if any exception is thrown */ protected void runTest() throws Throwable { - assertNotNull(fName); + assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null); 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); + runMethod= getClass().getMethod(fName, (Class[])null); } catch (NoSuchMethodException e) { fail("Method \""+fName+"\" not found"); } @@ -151,7 +165,7 @@ public abstract class TestCase extends Assert implements Test { } try { - runMethod.invoke(this, (Object[]) null); + runMethod.invoke(this); } catch (InvocationTargetException e) { e.fillInStackTrace(); @@ -177,19 +191,20 @@ public abstract class TestCase extends Assert implements Test { /** * Returns a string representation of the test case */ + @Override public String toString() { return getName() + "(" + getClass().getName() + ")"; } /** * Gets the name of a TestCase - * @return returns a String + * @return the name of the TestCase */ public String getName() { return fName; } /** * Sets the name of a TestCase - * @param name The name to set + * @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 index 45614a3..b19b196 100644 --- a/junit/src/main/java/junit/framework/TestFailure.java +++ b/junit/src/main/java/junit/framework/TestFailure.java @@ -36,6 +36,7 @@ public class TestFailure extends Object { /** * Returns a short description of the failure. */ + @Override public String toString() { StringBuffer buffer= new StringBuffer(); buffer.append(fFailedTest+": "+fThrownException.getMessage()); @@ -54,4 +55,4 @@ public class TestFailure extends Object { public boolean isFailure() { return thrownException() instanceof AssertionFailedError; } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/TestListener.java b/junit/src/main/java/junit/framework/TestListener.java index 41c6ccf..9d8101f 100644 --- a/junit/src/main/java/junit/framework/TestListener.java +++ b/junit/src/main/java/junit/framework/TestListener.java @@ -5,19 +5,19 @@ package junit.framework; */ public interface TestListener { /** - * An error occurred. - */ + * An error occurred. + */ public void addError(Test test, Throwable t); /** - * A failure occurred. - */ - public void addFailure(Test test, AssertionFailedError t); + * A failure occurred. + */ + public void addFailure(Test test, AssertionFailedError t); /** * A test ended. */ - public void endTest(Test test); + public void endTest(Test test); /** * A test started. */ public void startTest(Test test); -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/TestResult.java b/junit/src/main/java/junit/framework/TestResult.java index bcca1de..4f7e6b3 100644 --- a/junit/src/main/java/junit/framework/TestResult.java +++ b/junit/src/main/java/junit/framework/TestResult.java @@ -1,28 +1,36 @@ package junit.framework; -import java.util.Vector; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.List; +import java.util.Vector; /** * 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>. + * unanticipated problems like an {@link ArrayIndexOutOfBoundsException}. * * @see Test */ public class TestResult extends Object { - protected Vector fFailures; - protected Vector fErrors; - protected Vector fListeners; + // BEGIN android-changed changed types from List<> to Vector<> for API compatibility + protected Vector<TestFailure> fFailures; + protected Vector<TestFailure> fErrors; + protected Vector<TestListener> fListeners; + // END android-changed protected int fRunTests; + private boolean fStop; public TestResult() { - fFailures= new Vector(); - fErrors= new Vector(); - fListeners= new Vector(); + // BEGIN android-changed to Vector + fFailures= new Vector<TestFailure>(); + fErrors= new Vector<TestFailure>(); + fListeners= new Vector<TestListener>(); + // END android-changed fRunTests= 0; fStop= false; } @@ -31,46 +39,45 @@ public class TestResult extends Object { * 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); - } + fErrors.add(new TestFailure(test, t)); + for (TestListener each : cloneListeners()) + each.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); - } + fFailures.add(new TestFailure(test, t)); + for (TestListener each : cloneListeners()) + each.addFailure(test, t); } /** * Registers a TestListener */ public synchronized void addListener(TestListener listener) { - fListeners.addElement(listener); + fListeners.add(listener); } /** * Unregisters a TestListener */ public synchronized void removeListener(TestListener listener) { - fListeners.removeElement(listener); + fListeners.remove(listener); } /** * Returns a copy of the listeners. */ - private synchronized Vector cloneListeners() { - return (Vector)fListeners.clone(); + private synchronized List<TestListener> cloneListeners() { + List<TestListener> result= new ArrayList<TestListener>(); + result.addAll(fListeners); + return result; } /** * 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); - } + for (TestListener each : cloneListeners()) + each.endTest(test); } /** * Gets the number of detected errors. @@ -81,9 +88,11 @@ public class TestResult extends Object { /** * Returns an Enumeration for the errors */ - public synchronized Enumeration errors() { - return fErrors.elements(); + public synchronized Enumeration<TestFailure> errors() { + return Collections.enumeration(fErrors); } + + /** * Gets the number of detected failures. */ @@ -93,9 +102,10 @@ public class TestResult extends Object { /** * Returns an Enumeration for the failures */ - public synchronized Enumeration failures() { - return fFailures.elements(); + public synchronized Enumeration<TestFailure> failures() { + return Collections.enumeration(fFailures); } + /** * Runs a TestCase. */ @@ -147,9 +157,8 @@ public class TestResult extends Object { synchronized(this) { fRunTests+= count; } - for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) { - ((TestListener)e.nextElement()).startTest(test); - } + for (TestListener each : cloneListeners()) + each.startTest(test); } /** * Marks that the test run should stop. @@ -163,4 +172,4 @@ public class TestResult extends Object { public synchronized boolean wasSuccessful() { return failureCount() == 0 && errorCount() == 0; } -} +}
\ No newline at end of file diff --git a/junit/src/main/java/junit/framework/TestSuite.java b/junit/src/main/java/junit/framework/TestSuite.java index d2df2b7..af11d02 100644 --- a/junit/src/main/java/junit/framework/TestSuite.java +++ b/junit/src/main/java/junit/framework/TestSuite.java @@ -1,14 +1,18 @@ 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; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Vector; /** - * A <code>TestSuite</code> is a <code>Composite</code> of Tests. + * <p>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> @@ -16,44 +20,116 @@ import java.lang.reflect.Constructor; * suite.addTest(new MathTest("testAdd")); * suite.addTest(new MathTest("testDivideByZero")); * </pre> - * Alternatively, a TestSuite can extract the tests to be run automatically. + * </p> + * + * <p>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. + * </p> + * + * <p>This constructor creates a suite with all the methods + * starting with "test" that take no arguments.</p> + * + * <p>A final option is to do the same for a large array of test classes. + * <pre> + * Class[] testClasses = { MathTest.class, AnotherTest.class } + * TestSuite suite= new TestSuite(testClasses); + * </pre> + * </p> * * @see Test */ public class TestSuite implements Test { - private Vector fTests= new Vector(10); - private String fName; + /** + * ...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; + } /** - * Constructs an empty TestSuite. + * Gets a constructor which takes a single String as + * its argument or a no arg constructor. */ - public TestSuite() { + public static Constructor<?> getTestConstructor(Class<?> theClass) throws NoSuchMethodException { + try { + return theClass.getConstructor(String.class); + } catch (NoSuchMethodException e) { + // fall through + } + return theClass.getConstructor(new Class[0]); } /** - * Constructs a TestSuite from the given class with the given name. - * @see TestSuite#TestSuite(Class) + * Returns a test which will fail and log a warning message. */ - public TestSuite(Class theClass, String name) { - this(theClass); - setName(name); + public static Test warning(final String message) { + return new TestCase("warning") { + @Override + protected void runTest() { + fail(message); + } + }; + } + + /** + * 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(); + } + + private String fName; + + private Vector<Test> fTests= new Vector<Test>(10); // Cannot convert this to List because it is used directly by some test runners + + /** + * Constructs an empty TestSuite. + */ + public TestSuite() { } /** * 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, + * Parts of this method were written at 2337 meters in the Hueffihuette, * Kanton Uri */ - public TestSuite(final Class theClass) { + public TestSuite(final Class<?> theClass) { + addTestsFromTestCase(theClass); + } + + private void addTestsFromTestCase(final Class<?> theClass) { fName= theClass.getName(); try { getTestConstructor(theClass); // Avoid generating multiple error messages @@ -67,92 +143,70 @@ public class TestSuite implements Test { return; } - Class superClass= theClass; - Vector names= new Vector(); + Class<?> superClass= theClass; + List<String> names= new ArrayList<String>(); while (Test.class.isAssignableFrom(superClass)) { - Method[] methods= superClass.getDeclaredMethods(); - for (int i= 0; i < methods.length; i++) { - addTestMethod(methods[i], names, theClass); - } + for (Method each : superClass.getDeclaredMethods()) + addTestMethod(each, names, theClass); superClass= superClass.getSuperclass(); } if (fTests.size() == 0) addTest(warning("No tests found in "+theClass.getName())); } - /** - * Constructs an empty TestSuite. + /** + * Constructs a TestSuite from the given class with the given name. + * @see TestSuite#TestSuite(Class) */ - public TestSuite(String name) { + public TestSuite(Class<? extends TestCase> theClass, String name) { + this(theClass); setName(name); } /** - * Adds a test to the suite. + * Constructs an empty TestSuite. */ - public void addTest(Test test) { - fTests.addElement(test); + public TestSuite(String name) { + setName(name); } /** - * Adds the tests from the given class to the suite + * Constructs a TestSuite from the given array of classes. + * @param classes {@link TestCase}s */ - public void addTestSuite(Class testClass) { - addTest(new TestSuite(testClass)); + public TestSuite (Class<?>... classes) { + for (Class<?> each : classes) + addTest(testCaseForClass(each)); } - 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)); + private Test testCaseForClass(Class<?> each) { + if (TestCase.class.isAssignableFrom(each)) + return new TestSuite(each.asSubclass(TestCase.class)); + else + return warning(each.getCanonicalName() + " does not extend TestCase"); } /** - * ...as the moon sets over the early morning Merlin, Oregon - * mountains, our intrepid adventurers type... + * Constructs a TestSuite from the given array of classes with the given name. + * @see TestSuite#TestSuite(Class[]) */ - 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; + public TestSuite(Class<? extends TestCase>[] classes, String name) { + this(classes); + setName(name); } /** - * Converts the stack trace into a string + * Adds a test to the suite. */ - private static String exceptionToString(Throwable t) { - StringWriter stringWriter= new StringWriter(); - PrintWriter writer= new PrintWriter(stringWriter); - t.printStackTrace(writer); - return stringWriter.toString(); + public void addTest(Test test) { + fTests.add(test); + } + /** + * Adds the tests from the given class to the suite + */ + public void addTestSuite(Class<? extends TestCase> testClass) { + addTest(new TestSuite(testClass)); } /** @@ -160,47 +214,28 @@ public class TestSuite implements Test { */ public int countTestCases() { int count= 0; - for (Enumeration e= tests(); e.hasMoreElements(); ) { - Test test= (Test)e.nextElement(); - count= count + test.countTestCases(); - } + for (Test each : fTests) + count+= each.countTestCases(); return count; } /** - * Gets a constructor which takes a single String as - * its argument or a no arg constructor. + * Returns the name of the suite. Not all + * test suites have a name and this method + * can return null. */ - 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]); + public String getName() { + return fName; } - 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); + for (Test each : fTests) { + if (result.shouldStop() ) + break; + runTest(each, result); } } @@ -209,10 +244,18 @@ public class TestSuite implements Test { } /** + * Sets the name of the suite. + * @param name the name to set + */ + public void setName(String name) { + fName= name; + } + + /** * Returns the test at the given index */ public Test testAt(int index) { - return (Test)fTests.elementAt(index); + return fTests.get(index); } /** @@ -225,43 +268,40 @@ public class TestSuite implements Test { /** * Returns the tests as an enumeration */ - public Enumeration tests() { + public Enumeration<Test> tests() { return fTests.elements(); } /** */ + @Override 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; + private void addTestMethod(Method m, List<String> 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() + "(" + theClass.getCanonicalName() + ")")); + return; + } + names.add(name); + addTest(createTest(theClass, 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; + private boolean isPublicTestMethod(Method m) { + return isTestMethod(m) && Modifier.isPublic(m.getModifiers()); } - /** - * 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); - } - }; + private boolean isTestMethod(Method m) { + return + m.getParameterTypes().length == 0 && + m.getName().startsWith("test") && + m.getReturnType().equals(Void.TYPE); } } |