TestFailure collects a failed test together with
+ * the caught exception.
+ * @see TestResult
+ */
+public class TestFailure {
+ protected Test failedTest;
+ protected Throwable thrownException;
+
+ /**
+ * Constructs a TestFailure with the given test and exception.
+ */
+ public TestFailure(Test failedTest, Throwable thrownException) {
+ this.failedTest= failedTest;
+ this.thrownException= thrownException;
+ }
+ /**
+ * Gets the failed test.
+ */
+ public Test failedTest() {
+ return failedTest;
+ }
+ /**
+ * Gets the thrown exception.
+ */
+ public Throwable thrownException() {
+ return thrownException;
+ }
+ /**
+ * Returns a short description of the failure.
+ */
+ public String toString() {
+ StringBuffer buffer= new StringBuffer();
+ buffer.append(failedTest+": "+thrownException.getMessage());
+ return buffer.toString();
+ }
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestListener.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestListener.java
new file mode 100644
index 0000000000..412febcc55
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestListener.java
@@ -0,0 +1,15 @@
+package org.litejunit.v2;
+
+/**
+ * A Listener for test progress
+ */
+public interface TestListener {
+
+ public void addError(Test test, Throwable t);
+
+ public void addFailure(Test test, AssertionFailedError t);
+
+ public void endTest(Test test);
+
+ public void startTest(Test test);
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestResult.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestResult.java
new file mode 100644
index 0000000000..6fb789a495
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v2/TestResult.java
@@ -0,0 +1,121 @@
+package org.litejunit.v2;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class TestResult extends Object {
+ protected List
+ * public static void main (String[] args) {
+ * test.textui.TestRunner.run(suite());
+ * }
+ *
+ */
+ static public void run(Test suite) {
+ TestRunner aTestRunner= new TestRunner();
+ aTestRunner.doRun(suite);
+ }
+
+ protected PrintStream writer() {
+ return writer;
+ }
+
+
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/After.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/After.java
new file mode 100644
index 0000000000..f27496b8e1
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/After.java
@@ -0,0 +1,12 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface After {
+}
+
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/AfterClass.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/AfterClass.java
new file mode 100644
index 0000000000..82618d7afc
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/AfterClass.java
@@ -0,0 +1,13 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AfterClass {
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Assert.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Assert.java
new file mode 100644
index 0000000000..6d1b7689f9
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Assert.java
@@ -0,0 +1,269 @@
+package org.litejunit.v3;
+
+/**
+ * A set of assertion methods useful for writing tests. Only failed assertions are recorded.
+ * These methods can be used directly: Assert.assertEquals(...), however, they
+ * read better if they are referenced through static import:
+ * import static org.junit.Assert.*;
+ * ...
+ * assertEquals(...);
+ *
+ */
+
+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
+ * AssertionError 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
+ * AssertionError.
+ */
+ static public void assertTrue(boolean condition) {
+ assertTrue(null, condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws an
+ * AssertionError 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
+ * AssertionError.
+ */
+ static public void assertFalse(boolean condition) {
+ assertFalse(null, condition);
+ }
+
+ /**
+ * Fails a test with the given message.
+ */
+ static public void fail(String message) {
+ throw new AssertionError(message);
+ }
+
+ /**
+ * Fails a test with no message.
+ */
+ static public void fail() {
+ fail(null);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not, an
+ * AssertionError 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;
+ if (expected instanceof String && actual instanceof String)
+ throw new ComparisonFailure(message, (String)expected, (String)actual);
+ else
+ failNotEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not, an
+ * AssertionError is thrown.
+ */
+ static public void assertEquals(Object expected, Object actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * AssertionError is thrown with the given message.
+ */
+ public static void assertEquals(String message, Object[] expecteds, Object[] actuals) {
+ if (expecteds == actuals)
+ return;
+ String header = message == null ? "" : message + ": ";
+ if (expecteds == null)
+ fail(header + "expected array was null");
+ if (actuals == null)
+ fail(header + "actual array was null");
+ if (actuals.length != expecteds.length)
+ fail(header + "array lengths differed, expected.length=" + expecteds.length + " actual.length=" + actuals.length);
+
+ for (int i= 0; i < expecteds.length; i++) {
+ Object o1= expecteds[i];
+ Object o2= actuals[i];
+ if (o1.getClass().isArray() && o2.getClass().isArray()) {
+ Object[] expected= (Object[]) o1;
+ Object[] actual= (Object[]) o2;
+ assertEquals(header + "arrays first differed at element " + i + ";", expected, actual);
+ } else
+ assertEquals(header + "arrays first differed at element [" + i + "];", o1, o2);
+ }
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * AssertionError is thrown.
+ */
+ public static void assertEquals(Object[] expecteds, Object[] actuals) {
+ assertEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two doubles are equal to within a positive delta. If they
+ * are not, an AssertionError is thrown with the given message. If the
+ * expected value is infinity then the delta value is ignored. NaNs are
+ * considered equal:
+ * assertEquals(Double.NaN, Double.NaN, *) passes
+ */
+ static public void assertEquals(String message, double expected, double actual, double delta) {
+ if (Double.compare(expected, actual) == 0)
+ return;
+ if (!(Math.abs(expected - actual) <= delta))
+ failNotEquals(message, new Double(expected), new Double(actual));
+ }
+
+ /**
+ * Asserts that two doubles are equal to within a positive delta. If they
+ * are not, an AssertionError is thrown. If the
+ * expected value is infinity then the delta value is ignored.NaNs are
+ * considered equal:
+ * assertEquals(Double.NaN, Double.NaN, *) passes
+ */
+ static public void assertEquals(double expected, double actual, double delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that two floats are equal to within a positive delta. If they
+ * are not, an AssertionError is thrown with the given message. If the
+ * expected value is infinity then the delta value is ignored.NaNs are
+ * considered equal:
+ * assertEquals(Float.NaN, Float.NaN, *) passes
+ */
+ static public void assertEquals(String message, float expected, float actual, float delta) {
+ 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 to within a positive delta. If they
+ * are not, an AssertionError is thrown. If the
+ * expected value is infinity then the delta value is ignored.NaNs are
+ * considered equal:
+ * assertEquals(Float.NaN, Float.NaN, *) passes
+ */
+ static public void assertEquals(float expected, float actual, float delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that an object isn't null. If it is an AssertionError is
+ * thrown with the given message.
+ */
+ static public void assertNotNull(String message, Object object) {
+ assertTrue(message, object != null);
+ }
+
+ /**
+ * Asserts that an object isn't null. If it is an AssertionError is
+ * thrown.
+ */
+ static public void assertNotNull(Object object) {
+ assertNotNull(null, object);
+ }
+
+ /**
+ * Asserts that an object is null. If it is not, an AssertionError is
+ * thrown with the given message.
+ */
+ static public void assertNull(String message, Object object) {
+ assertTrue(message, object == null);
+ }
+
+ /**
+ * Asserts that an object is null. If it isn't an AssertionError is
+ * thrown.
+ */
+ static public void assertNull(Object object) {
+ assertNull(null, object);
+ }
+
+ /**
+ * Asserts that two objects refer to the same object. If they are not, an
+ * AssertionError 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 AssertionError is thrown.
+ */
+ 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 do
+ * refer to the same object, an AssertionError 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 do
+ * refer to the same object, an AssertionError 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/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Before.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Before.java
new file mode 100644
index 0000000000..72e0e3beb2
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Before.java
@@ -0,0 +1,13 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Before {
+}
+
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/BeforeClass.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/BeforeClass.java
new file mode 100644
index 0000000000..6334ab45b2
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/BeforeClass.java
@@ -0,0 +1,11 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface BeforeClass {
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/ComparisonFailure.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/ComparisonFailure.java
new file mode 100644
index 0000000000..77f9ea6f5f
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/ComparisonFailure.java
@@ -0,0 +1,124 @@
+package org.litejunit.v3;
+
+/**
+ * Thrown when an assertEquals(String, String) fails. Create and throw
+ * a ComparisonFailure manually if you want to show users the difference between two complex
+ * strings.
+ *
+ * Inspired by a patch from Alex Chaffee (alex@purpletech.com)
+ */
+public class ComparisonFailure extends AssertionError {
+ private static final int MAX_CONTEXT_LENGTH= 20;
+ private static final long serialVersionUID= 1L;
+
+ 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()
+ */
+ @Override
+ public String getMessage() {
+ return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage());
+ }
+
+ /**
+ * Returns the actual value
+ * @return the actual string value
+ */
+ public String getActual() {
+ return fActual;
+ }
+ /**
+ * Returns the expected value
+ * @return the expected string value
+ */
+ public String getExpected() {
+ return fExpected;
+ }
+
+ private static 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Ignore.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Ignore.java
new file mode 100644
index 0000000000..1652ac2431
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Ignore.java
@@ -0,0 +1,31 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Sometimes you want to temporarily disable a test. Methods annotated with @Test
+ * that are also annotated with @Ignore will not be executed as tests. Native JUnit 4 test runners
+ * should report the number of ignored tests along with the number of tests that ran and the
+ * number of tests that failed.
+ *
+ * For example:
+ *
+ * @Ignore @Test public void something() { ...
+ *
+ * @Ignore takes an optional default parameter if you want to record why a test is being ignored:
+ *
+ * @Ignore("not ready yet") @Test public void something() { ...
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Ignore {
+ /**
+ * The optional reason why the test is ignored.
+ */
+ String value() default "";
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Test.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Test.java
new file mode 100644
index 0000000000..f390d10671
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/Test.java
@@ -0,0 +1,62 @@
+package org.litejunit.v3;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The
+ * Test annotation tells JUnit that the public void method
+ * to which it is attached can be run as a test case. To run the method,
+ * JUnit first constructs a fresh instance of the class then invokes the
+ * annotated method. Any exceptions thrown by the test will be reported
+ * by JUnit as a failure. If no exceptions are thrown, the test is assumed
+ * to have succeeded.
+ *
+ * A simple test looks like this:
+ *
+ * public class Example {
+ *
+ * @Test public void method() {
+ * System.out.println("Hello");
+ * }
+ * }
+ *
+ * The Test annotation supports two optional parameters.
+ * The first, expected, declares that a test method should throw
+ * an exception. If it doesn't throw an exception or if it throws a different exception
+ * than the one declared, the test fails. For example, the following test succeeds:
+ *
+ * @Test(expected=IndexOutOfBoundsException.class) public void outOfBounds() {
+ *
+ * new ArrayList<Object>().get(1);
+ * }
+ *
+ * The second optional parameter,
+ *
+ * In the past, we used the raw
+ * The flow when JUnit runs tests is that a timeout, causes a test to fail if it takes longer than a specified
+ * amount of clock time (measured in milliseconds). The following test fails:
+ *
+ * @Test(timeout=100) public void infinity() {
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Test {
+ static class None extends Throwable {
+ private static final long serialVersionUID= 1L;
+ private None() {
+ }
+ }
+
+ /**
+ * Optionally specify
+ * for(;;);
+ * }
+ * expected, a Throwable, to cause a test method to succeed iff
+ * an exception of the specified class is thrown by the method.
+ */
+ Class extends Throwable> expected() default None.class;
+
+ /**
+ * Optionally specify timeout in milliseconds to cause a test method to fail if it
+ * takes longer than that number of milliseconds.*/
+ long timeout() default 0L;
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/Failure.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/Failure.java
new file mode 100644
index 0000000000..2eb516b75f
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/Failure.java
@@ -0,0 +1,78 @@
+package org.litejunit.v3.notification;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.litejunit.v3.runner.Description;
+
+
+/**
+ * A Failure holds a description of the failed test and the
+ * exception that was thrown while running it. In most cases the Description
+ * will be of a single test. However, if problems are encountered while constructing the
+ * test (for example, if a @BeforeClass method is not static), it may describe
+ * something other than a single test.
+ */
+public class Failure {
+ private final Description fDescription;
+ private Throwable fThrownException;
+
+ /**
+ * Constructs a Failure with the given description and exception.
+ * @param description a Description of the test that failed
+ * @param thrownException the exception that was thrown while running the test
+ */
+ public Failure(Description description, Throwable thrownException) {
+ fThrownException = thrownException;
+ fDescription= description;
+ }
+
+ /**
+ * @return a user-understandable label for the test
+ */
+ public String getTestHeader() {
+ return fDescription.getDisplayName();
+ }
+
+ /**
+ * @return the raw description of the context of the failure.
+ */
+ public Description getDescription() {
+ return fDescription;
+ }
+
+ /**
+ * @return the exception thrown
+ */
+
+ public Throwable getException() {
+ return fThrownException;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer= new StringBuffer();
+ buffer.append(getTestHeader() + ": "+fThrownException.getMessage());
+ return buffer.toString();
+ }
+
+ /**
+ * Convenience method
+ * @return the printed form of the exception
+ */
+ public String getTrace() {
+ StringWriter stringWriter= new StringWriter();
+ PrintWriter writer= new PrintWriter(stringWriter);
+ getException().printStackTrace(writer);
+ StringBuffer buffer= stringWriter.getBuffer();
+ return buffer.toString();
+ }
+
+ /**
+ * Convenience method
+ * @return the message of the thrown exception
+ */
+ public String getMessage() {
+ return getException().getMessage();
+ }
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunListener.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunListener.java
new file mode 100644
index 0000000000..aa30aa9abf
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunListener.java
@@ -0,0 +1,53 @@
+package org.litejunit.v3.notification;
+
+import org.litejunit.v3.runner.Description;
+import org.litejunit.v3.runner.Result;
+
+
+public class RunListener {
+
+ /**
+ * Called before any tests have been run.
+ * @param description describes the tests to be run
+ */
+ public void testRunStarted(Description description) throws Exception {
+ }
+
+ /**
+ * Called when all tests have finished
+ * @param result the summary of the test run, including all the tests that failed
+ */
+ public void testRunFinished(Result result) throws Exception {
+ }
+
+ /**
+ * Called when an atomic test is about to be started.
+ * @param description the description of the test that is about to be run (generally a class and method name)
+ */
+ public void testStarted(Description description) throws Exception {
+ }
+
+ /**
+ * Called when an atomic test has finished, whether the test succeeds or fails.
+ * @param description the description of the test that just ran
+ */
+ public void testFinished(Description description) throws Exception {
+ }
+
+ /**
+ * Called when an atomic test fails.
+ * @param failure describes the test that failed and the exception that was thrown
+ */
+ public void testFailure(Failure failure) throws Exception {
+ }
+
+ /**
+ * Called when a test will not be run, generally because a test method is annotated with @Ignored.
+ * @param description describes the test that will not be run
+ */
+ public void testIgnored(Description description) throws Exception {
+ }
+
+}
+
+
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunNotifier.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunNotifier.java
new file mode 100644
index 0000000000..d7d16e0677
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/RunNotifier.java
@@ -0,0 +1,139 @@
+package org.litejunit.v3.notification;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.litejunit.v3.runner.Description;
+import org.litejunit.v3.runner.Result;
+
+
+
+/**
+ * If you write custom runners, you may need to notify JUnit of your progress running tests.
+ * Do this by invoking the RunNotifier passed to your implementation of
+ * Runner.run(RunNotifier notifier). Future evolution of this class is likely to
+ * move fireTestRunStarted() and fireTestRunFinished()
+ * to a separate class since they should only be called once per run.
+ */
+public class RunNotifier {
+ private ListfireTestFinished()
+ * if you invoke fireTestStarted() as listeners are likely to expect them to come in pairs.
+ * @param description the description of the test that finished
+ */
+ public void fireTestFinished(final Description description) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testFinished(description);
+ };
+ }.run();
+ }
+
+ /**
+ * Ask that the tests run stop before starting the next test. Phrased politely because
+ * the test currently running will not be interrupted. It seems a little odd to put this
+ * functionality here, but the RunNotifier is the only object guaranteed
+ * to be shared amongst the many runners involved.
+ */
+ public void pleaseStop() {
+ fPleaseStop= true;
+ }
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/StoppedByUserException.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/StoppedByUserException.java
new file mode 100644
index 0000000000..829462445c
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/notification/StoppedByUserException.java
@@ -0,0 +1,11 @@
+package org.litejunit.v3.notification;
+
+/**
+ * Thrown when a user has requested that the test run stop. Writers of
+ * test running GUIs should be prepared to catch a StoppedByUserException.
+ *
+ * @see org.junit.runner.notification.RunNotifier
+ */
+public class StoppedByUserException extends RuntimeException {
+ private static final long serialVersionUID= 1L;
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/requests/ClassRequest.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/requests/ClassRequest.java
new file mode 100644
index 0000000000..315bbb6482
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/requests/ClassRequest.java
@@ -0,0 +1,48 @@
+/**
+ *
+ */
+package org.litejunit.v3.requests;
+
+import java.lang.reflect.Constructor;
+
+import org.litejunit.v3.runner.Request;
+import org.litejunit.v3.runner.Runner;
+import org.litejunit.v3.runners.TestClassRunner;
+
+
+public class ClassRequest extends Request {
+ private final Class> fTestClass;
+
+ public ClassRequest(Class> each) {
+ fTestClass= each;
+ }
+
+ @Override
+ public Runner getRunner() {
+ Class runnerClass= getRunnerClass(fTestClass);
+ try {
+ Constructor constructor= runnerClass.getConstructor(Class.class); // TODO good error message if no such constructor
+ Runner runner= (Runner) constructor
+ .newInstance(new Object[] { fTestClass });
+ return runner;
+ } catch (Exception e) {
+ return null;
+ //return Request.errorReport(fTestClass, e).getRunner();
+ }
+ }
+
+ Class getRunnerClass(Class> testClass) {
+ /*RunWith annotation= testClass.getAnnotation(RunWith.class);
+ if (annotation != null) {
+ return annotation.value();
+ } else if (isPre4Test(testClass)) {
+ return OldTestClassRunner.class;
+ } else {*/
+ return TestClassRunner.class;
+ /*}*/
+ }
+
+ /*boolean isPre4Test(Class> testClass) {
+ return junit.framework.TestCase.class.isAssignableFrom(testClass);
+ }*/
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Description.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Description.java
new file mode 100644
index 0000000000..db3610fd3f
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Description.java
@@ -0,0 +1,127 @@
+package org.litejunit.v3.runner;
+
+import java.util.ArrayList;
+
+/**
+ * A Description describes a test which is to be run or has been run. Descriptions can
+ * be atomic (a single test) or compound (containing children tests). Descriptions are used
+ * to provide feedback about the tests that are about to run (for example, the tree view
+ * visible in many IDEs) or tests that have been run (for example, the failures view). Descriptions are implemented as a single class rather than a Composite because
+ * they are entirely informational. They contain no logic aside from counting their tests. junit.framework.TestCases and junit.framework.TestSuites
+ * to display the tree of tests. This was no longer viable in JUnit 4 because atomic tests no longer have a superclass below Object.
+ * We needed a way to pass a class and name together. Description emerged from this.
+ *
+ * @see org.junit.runner.Request
+ * @see org.junit.runner.Runner
+ */
+public class Description {
+
+ /**
+ * Create a Description named name.
+ * Generally, you will add children to this Description.
+ * @param name The name of the Description
+ * @return A Description named name
+ */
+ public static Description createSuiteDescription(String name) {
+ return new Description(name);
+ }
+
+ /**
+ * Create a Description of a single test named name in the class clazz.
+ * Generally, this will be a leaf Description.
+ * @param clazz The class of the test
+ * @param name The name of the test (a method name for test annotated with @Test)
+ * @return A Description named name
+ */
+ public static Description createTestDescription(Class clazz, String name) {
+ return new Description(String.format("%s(%s)", name, clazz.getName()));
+ }
+
+ /**
+ * Create a generic Description that says there are tests in testClass.
+ * This is used as a last resort when you cannot precisely describe the individual tests in the class.
+ * @param testClass A Class containing tests
+ * @return A Description of testClass
+ */
+ public static Description createSuiteDescription(Class> testClass) {
+ return new Description(testClass.getName());
+ }
+
+ public static Description TEST_MECHANISM = new Description("Test mechanism");
+ private final ArrayListdescription as a child of the receiver.
+ * @param description The soon-to-be child.
+ */
+ public void addChild(Description description) {
+ getChildren().add(description);
+ }
+
+ /**
+ * @return the receiver's children, if any
+ */
+ public ArrayListJUnitCore is a facade for running tests. It supports running JUnit 4 tests,
+ * JUnit 3.8.2 tests, and mixtures. To run tests from the command line, run java org.junit.runner.JUnitCore TestClass1 TestClass2 ....
+ * For one-shot test runs, use the static method runClasses(Class... classes)
+ * . If you want to add special listeners,
+ * create an instance of JUnitCore first and use it to run the tests.
+ *
+ * @see org.junit.runner.Result
+ * @see org.junit.runner.notification.RunListener
+ * @see org.junit.runner.Request
+ */
+public class JUnitCore {
+
+ private RunNotifier notifier;
+
+ /**
+ * Create a new JUnitCore to run tests.
+ */
+ public JUnitCore() {
+ notifier= new RunNotifier();
+ }
+
+ /**
+ * Run the tests contained in the classes named in the args.
+ * If all tests run successfully, exit with a status of 0. Otherwise exit with a status of 1.
+ * Write feedback while tests are running and write
+ * stack traces for all failed tests after the tests all complete.
+ * @param args names of classes in which to find tests to run
+ */
+ /*public static void main(String... args) {
+ Class> clz = null;
+ try {
+ clz = Class.forName(args[0]);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ Request request = Request.aClass(clz);
+
+ new JUnitCore().run(request);
+
+ Result result= new JUnitCore().runMain(args);
+ killAllThreads(result);
+ }*/
+ public static void runClass(Class> clz){
+ try {
+ TestClassRunner runner = new TestClassRunner(clz);
+ JUnitCore core = new JUnitCore();
+ core.addListener(new TextListener());
+ Result result = core.run(runner);
+
+ } catch (InitializationError e) {
+
+ e.printStackTrace();
+ }
+
+ }
+ /*private static void killAllThreads(Result result) {
+ System.exit(result.wasSuccessful() ? 0 : 1);
+ }*/
+
+ /**
+ * Run the tests contained in classes. Write feedback while the tests
+ * are running and write stack traces for all failed tests after all tests complete. This is
+ * similar to main(), but intended to be used programmatically.
+ * @param classes Classes in which to find tests
+ * @return a Result describing the details of the test run and the failed tests.
+ */
+ /*public static Result runClasses(Class... classes) {
+ return new JUnitCore().run(classes);
+ }*/
+
+ /**
+ * Do not use. Testing purposes only.
+ */
+ /*public Result runMain(String... args) {
+
+ Listclasses.
+ * @param classes the classes containing tests
+ * @return a Result describing the details of the test run and the failed tests.
+ */
+ /*public Result run(Class... classes) {
+ return run(Request.classes("All", classes));
+ }*/
+
+ /**
+ * Run all the tests contained in request.
+ * @param request the request describing tests
+ * @return a Result describing the details of the test run and the failed tests.
+ */
+ /*public Result run(Request request) {
+ return run(request.getRunner());
+ }*/
+
+ /**
+ * Run all the tests contained in JUnit 3.8.x test. Here for backward compatibility.
+ * @param test the old-style test
+ * @return a Result describing the details of the test run and the failed tests.
+ */
+ /*public Result run(junit.framework.Test test) {
+ return run(new OldTestClassRunner(test));
+ }
+ */
+ /**
+ * Do not use. Testing purposes only.
+ */
+ public Result run(Runner runner) {
+ Result result= new Result();
+ RunListener listener= result.createListener();
+ addListener(listener);
+
+ try {
+ notifier.fireTestRunStarted(runner.getDescription());
+ runner.run(notifier);
+ notifier.fireTestRunFinished(result);
+ } finally {
+ removeListener(listener);
+ }
+ return result;
+ }
+
+ /**
+ * Add a listener to be notified as the tests run.
+ * @param listener the listener
+ * @see org.junit.runner.notification.RunListener
+ */
+ public void addListener(RunListener listener) {
+ notifier.addListener(listener);
+ }
+
+ /**
+ * Remove a listener.
+ * @param listener the listener to remove
+ */
+ public void removeListener(RunListener listener) {
+ notifier.removeListener(listener);
+ }
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Request.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Request.java
new file mode 100644
index 0000000000..02db808bb7
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Request.java
@@ -0,0 +1,86 @@
+package org.litejunit.v3.runner;
+
+import org.litejunit.v3.requests.ClassRequest;
+
+
+
+/**
+ * A Request is an abstract description of tests to be run. Older versions of
+ * JUnit did not need such a concept--tests to be run were described either by classes containing
+ * tests or a tree of Tests. However, we want to support filtering and sorting,
+ * so we need a more abstract specification than the tests themselves and a richer
+ * specification than just the classes.
+ * Request specifies some tests to be run ->
+ * a Runner is created for each class implied by the Request -> the Runner
+ * returns a detailed Description which is a tree structure of the tests to be run.
+ */
+public abstract class Request {
+ /**
+ * Create a Request that, when processed, will run a single test.
+ * This is done by filtering out all other tests. This method is used to support rerunning
+ * single tests.
+ * @param clazz the class of the test
+ * @param methodName the name of the test
+ * @return a Request that will cause a single test be run
+ */
+ /*public static Request method(Class> clazz, String methodName) {
+ Description method= Description.createTestDescription(clazz, methodName);
+ return Request.aClass(clazz).filterWith(method);
+ }*/
+
+ /**
+ * Create a Request that, when processed, will run all the tests
+ * in a class. The odd name is necessary because class is a reserved word.
+ * @param clazz the class containing the tests
+ * @return a Request that will cause all tests in the class to be run
+ */
+ public static Request aClass(Class> clazz) {
+ return new ClassRequest(clazz);
+ }
+
+ /**
+ * Create a Request that, when processed, will run all the tests
+ * in a set of classes.
+ * @param collectionName a name to identify this suite of tests
+ * @param classes the classes containing the tests
+ * @return a Request that will cause all tests in the classes to be run
+ */
+ /*public static Request classes(String collectionName, Class... classes) {
+ return new ClassesRequest(collectionName, classes);
+ }*/
+
+ /*public static Request errorReport(Class> klass, Throwable cause) {
+ return new ErrorReportingRequest(klass, cause);
+ }*/
+
+ public abstract Runner getRunner();
+
+ /*public Request filterWith(Filter filter) {
+ return new FilterRequest(this, filter);
+ }
+
+ public Request filterWith(final Description desiredDescription) {
+ return filterWith(new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ // TODO: test for equality even if we have children?
+ if (description.isTest())
+ return desiredDescription.equals(description);
+ for (Description each : description.getChildren())
+ if (shouldRun(each))
+ return true;
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return String.format("Method %s", desiredDescription.getDisplayName());
+ }
+ });
+ }
+
+ public Request sortWith(ComparatorResult collects and summarizes information from running multiple
+ * tests. Since tests are expected to run correctly, successful tests are only noted in
+ * the count of tests that ran.
+ */
+public class Result {
+ private int fCount= 0;
+ private int fIgnoreCount= 0;
+ private ListFailures describing tests that failed and the problems they encountered
+ */
+ public List@RunWith, JUnit will invoke
+ * the class it references to run the tests in that class instead of the runner
+ * built into JUnit. We added this feature late in development. While it
+ * seems powerful we expect the runner API to change as we learn how people
+ * really use it. Some of the classes that are currently internal will likely be refined
+ * and become public.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RunWith {
+ /**
+ * @return a Runner class (must have a constructor that takes a single Class to run)
+ */
+ Class extends Runner> value();
+}
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Runner.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Runner.java
new file mode 100644
index 0000000000..57ef0faf97
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runner/Runner.java
@@ -0,0 +1,24 @@
+package org.litejunit.v3.runner;
+
+import org.litejunit.v3.notification.RunNotifier;
+
+
+public abstract class Runner {
+ /**
+ * @return a Description showing the tests to be run by the receiver
+ */
+ public abstract Description getDescription();
+
+ /**
+ * Run the tests for this runner.
+ * @param notifier will be notified of events while tests are being run--tests being started, finishing, and failing
+ */
+ public abstract void run(RunNotifier notifier);
+
+ /**
+ * @return the number of tests to be run by the receiver
+ */
+ public int testCount() {
+ return getDescription().testCount();
+ }
+}
\ No newline at end of file
diff --git a/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runners/BeforeAndAfterRunner.java b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runners/BeforeAndAfterRunner.java
new file mode 100644
index 0000000000..1bcbf40d79
--- /dev/null
+++ b/liuxin/ood/ood-assignment/src/main/java/org/litejunit/v3/runners/BeforeAndAfterRunner.java
@@ -0,0 +1,76 @@
+package org.litejunit.v3.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public abstract class BeforeAndAfterRunner {
+ private static class FailedBefore extends Exception {
+ private static final long serialVersionUID= 1L;
+ }
+
+ private final Class extends Annotation> beforeAnnotation;
+
+ private final Class extends Annotation> afterAnnotation;
+
+ private TestIntrospector testIntrospector;
+
+ private Object test;
+
+ public BeforeAndAfterRunner(Class> testClass,
+ Class extends Annotation> beforeAnnotation,
+ Class extends Annotation> afterAnnotation,
+ Object test) {
+ this.beforeAnnotation= beforeAnnotation;
+ this.afterAnnotation= afterAnnotation;
+ this.testIntrospector= new TestIntrospector(testClass);
+ this.test= test;
+ }
+
+ public void runProtected() {
+ try {
+ runBefores();
+ runUnprotected();
+ } catch (FailedBefore e) {
+ } finally {
+ runAfters();
+ }
+ }
+
+ protected abstract void runUnprotected();
+
+ protected abstract void addFailure(Throwable targetException);
+
+ // Stop after first failed @Before
+ private void runBefores() throws FailedBefore {
+ try {
+ List