Internal change
PiperOrigin-RevId: 405717262
Change-Id: Ia055c28b59dae6447d37f408fcab1813f3836cb7
diff --git a/google3/third_party/java_src/junit/LICENSE b/google3/third_party/java_src/junit/LICENSE
new file mode 100644
index 0000000..fb68629
--- /dev/null
+++ b/google3/third_party/java_src/junit/LICENSE
@@ -0,0 +1,214 @@
+JUnit
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial code and
+ documentation distributed under this Agreement, and
+ b) in the case of each subsequent Contributor:
+
+ i) changes to the Program, and
+
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and
+such derivative works, in source code and object code form.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under
+Licensed Patents to make, use, sell, offer to sell, import and otherwise
+transfer the Contribution of such Contributor, if any, in source code and
+object code form. This patent license shall apply to the combination of the
+Contribution and the Program if, at the time the Contribution is added by the
+Contributor, such addition of the Contribution causes such combination to be
+covered by the Licensed Patents. The patent license shall not apply to any
+other combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are provided by
+any Contributor that the Program does not infringe the patent or other
+intellectual property rights of any other entity. Each Contributor disclaims
+any liability to Recipient for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a condition to
+exercising the rights and licenses granted hereunder, each Recipient hereby
+assumes sole responsibility to secure any other intellectual property rights
+needed, if any. For example, if a third party patent license is required to
+allow Recipient to distribute the Program, it is Recipient's responsibility to
+acquire that license before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright license
+set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+ i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose;
+
+ ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits;
+
+ iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+ iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable manner on
+or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+ b) a copy of this Agreement must be included with each copy of the
+Program.
+
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using
+and distributing the Program and assumes all risks associated with its exercise
+of rights under this Agreement, including but not limited to the risks and
+costs of program errors, compliance with applicable laws, damage to or loss of
+data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's rights
+granted under Section 2(b) shall terminate as of the date such litigation is
+filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue
+and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial
+in any resulting litigation.
+
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java b/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java
new file mode 100644
index 0000000..6f0f99d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/ActiveTestSuite.java
@@ -0,0 +1,70 @@
+package junit.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/**
+ * 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<? extends TestCase> theClass) {
+ super(theClass);
+ }
+
+ public ActiveTestSuite(String name) {
+ super(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();
+ }
+ }
+ };
+ t.start();
+ }
+
+ synchronized void waitUntilFinished() {
+ while (fActiveTestDeathCount < testCount()) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ return; // ignore
+ }
+ }
+ }
+
+ public synchronized void runFinished() {
+ fActiveTestDeathCount++;
+ notifyAll();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java b/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java
new file mode 100644
index 0000000..22c690a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/RepeatedTest.java
@@ -0,0 +1,39 @@
+package junit.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+/**
+ * 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;
+ }
+
+ @Override
+ public int countTestCases() {
+ return super.countTestCases() * fTimesRepeat;
+ }
+
+ @Override
+ public void run(TestResult result) {
+ for (int i = 0; i < fTimesRepeat; i++) {
+ if (result.shouldStop()) {
+ break;
+ }
+ super.run(result);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "(repeated)";
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java b/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java
new file mode 100644
index 0000000..a3c5e08
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/TestDecorator.java
@@ -0,0 +1,43 @@
+package junit.extensions;
+
+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 behaviour
+ * before or after a test is run.
+ */
+@SuppressWarnings("deprecation")
+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);
+ }
+
+ @Override
+ public String toString() {
+ return fTest.toString();
+ }
+
+ public Test getTest() {
+ return fTest;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java b/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java
new file mode 100644
index 0000000..fcdca8c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/TestSetup.java
@@ -0,0 +1,42 @@
+package junit.extensions;
+
+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.
+ */
+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 {
+ 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 {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java b/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java
new file mode 100644
index 0000000..a1c5bb4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/extensions/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides extended functionality for JUnit v3.x.
+ */
+package junit.extensions;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java b/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java
new file mode 100644
index 0000000..43482a1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/Assert.java
@@ -0,0 +1,339 @@
+package junit.framework;
+
+/**
+ * A set of assert methods. Messages are only displayed when an assert fails.
+ *
+ * @deprecated Please use {@link org.junit.Assert} instead.
+ */
+@Deprecated
+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.
+ */
+ public static void assertTrue(String message, boolean condition) {
+ if (!condition) {
+ fail(message);
+ }
+ }
+
+ /**
+ * Asserts that a condition is true. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ public static 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.
+ */
+ public static void assertFalse(String message, boolean condition) {
+ assertTrue(message, !condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ public static void assertFalse(boolean condition) {
+ assertFalse(null, condition);
+ }
+
+ /**
+ * Fails a test with the given message.
+ */
+ public static void fail(String message) {
+ if (message == null) {
+ throw new AssertionFailedError();
+ }
+ throw new AssertionFailedError(message);
+ }
+
+ /**
+ * Fails a test with no message.
+ */
+ public static void fail() {
+ fail(null);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static 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.
+ */
+ public static void assertEquals(Object expected, Object actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * Asserts that two Strings are equal.
+ */
+ public static void assertEquals(String message, String expected, String actual) {
+ if (expected == null && actual == null) {
+ return;
+ }
+ if (expected != null && expected.equals(actual)) {
+ return;
+ }
+ String cleanMessage = message == null ? "" : message;
+ throw new ComparisonFailure(cleanMessage, expected, actual);
+ }
+
+ /**
+ * Asserts that two Strings are equal.
+ */
+ public static 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.
+ */
+ public static 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, Double.valueOf(expected), Double.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two doubles are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ public static void assertEquals(double expected, double actual, double delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * 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.
+ */
+ public static 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, Float.valueOf(expected), Float.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two floats are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, long expected, long actual) {
+ assertEquals(message, Long.valueOf(expected), Long.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two longs are equal.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, boolean expected, boolean actual) {
+ assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two booleans are equal.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, byte expected, byte actual) {
+ assertEquals(message, Byte.valueOf(expected), Byte.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two bytes are equal.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, char expected, char actual) {
+ assertEquals(message, Character.valueOf(expected), Character.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two chars are equal.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, short expected, short actual) {
+ assertEquals(message, Short.valueOf(expected), Short.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two shorts are equal.
+ */
+ public static 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.
+ */
+ public static void assertEquals(String message, int expected, int actual) {
+ assertEquals(message, Integer.valueOf(expected), Integer.valueOf(actual));
+ }
+
+ /**
+ * Asserts that two ints are equal.
+ */
+ public static void assertEquals(int expected, int actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * Asserts that an object isn't null.
+ */
+ public static 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.
+ */
+ public static void assertNotNull(String message, Object object) {
+ assertTrue(message, object != 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>
+ */
+ public static void assertNull(Object object) {
+ if (object != null) {
+ assertNull("Expected: <null> but was: " + object.toString(), object);
+ }
+ }
+
+ /**
+ * Asserts that an object is null. If it is not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static 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.
+ */
+ public static 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.
+ */
+ public static 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 AssertionFailedError is thrown with the
+ * given message.
+ */
+ public static 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 AssertionFailedError is thrown.
+ */
+ public static void assertNotSame(Object expected, Object actual) {
+ assertNotSame(null, expected, actual);
+ }
+
+ public static void failSame(String message) {
+ String formatted = (message != null) ? message + " " : "";
+ fail(formatted + "expected not same");
+ }
+
+ public static void failNotSame(String message, Object expected, Object actual) {
+ String formatted = (message != null) ? message + " " : "";
+ fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">");
+ }
+
+ public static void failNotEquals(String message, Object expected, Object actual) {
+ fail(format(message, expected, actual));
+ }
+
+ public static String format(String message, Object expected, Object actual) {
+ String formatted = "";
+ if (message != null && message.length() > 0) {
+ formatted = message + " ";
+ }
+ return formatted + "expected:<" + expected + "> but was:<" + actual + ">";
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java b/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java
new file mode 100644
index 0000000..e11fbec
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/AssertionFailedError.java
@@ -0,0 +1,29 @@
+package junit.framework;
+
+/**
+ * Thrown when an assertion failed.
+ */
+public class AssertionFailedError extends AssertionError {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new AssertionFailedError without a detail message.
+ */
+ public AssertionFailedError() {
+ }
+
+ /**
+ * Constructs a new AssertionFailedError with the specified detail message.
+ * A null message is replaced by an empty String.
+ * @param message the detail message. The detail message is saved for later
+ * retrieval by the {@code Throwable.getMessage()} method.
+ */
+ public AssertionFailedError(String message) {
+ super(defaultString(message));
+ }
+
+ private static String defaultString(String message) {
+ return message == null ? "" : message;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java
new file mode 100644
index 0000000..81ddd5b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonCompactor.java
@@ -0,0 +1,78 @@
+package junit.framework;
+
+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;
+ }
+
+ @SuppressWarnings("deprecation")
+ 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/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java
new file mode 100644
index 0000000..66433ef
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/ComparisonFailure.java
@@ -0,0 +1,56 @@
+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 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 Throwable#getMessage()
+ */
+ @Override
+ public String getMessage() {
+ return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage());
+ }
+
+ /**
+ * 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;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java
new file mode 100644
index 0000000..9d32031
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapter.java
@@ -0,0 +1,107 @@
+package junit.framework;
+
+import java.util.List;
+
+import org.junit.Ignore;
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sorter;
+
+/**
+ * The JUnit4TestAdapter enables running JUnit-4-style tests using a JUnit-3-style test runner.
+ *
+ * <p> To use it, add the following to a test class:
+ * <pre>
+ public static Test suite() {
+ return new JUnit4TestAdapter(<em>YourJUnit4TestClass</em>.class);
+ }
+</pre>
+ */
+public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describable {
+ private final Class<?> fNewTestClass;
+
+ private final Runner fRunner;
+
+ private final JUnit4TestAdapterCache fCache;
+
+ public JUnit4TestAdapter(Class<?> newTestClass) {
+ this(newTestClass, JUnit4TestAdapterCache.getDefault());
+ }
+
+ public JUnit4TestAdapter(final Class<?> newTestClass, JUnit4TestAdapterCache cache) {
+ fCache = cache;
+ fNewTestClass = newTestClass;
+ fRunner = Request.classWithoutSuiteMethod(newTestClass).getRunner();
+ }
+
+ public int countTestCases() {
+ return fRunner.testCount();
+ }
+
+ public void run(TestResult result) {
+ fRunner.run(fCache.getNotifier(result, this));
+ }
+
+ // reflective interface for Eclipse
+ public List<Test> getTests() {
+ return fCache.asTestList(getDescription());
+ }
+
+ // reflective interface for Eclipse
+ public Class<?> getTestClass() {
+ return fNewTestClass;
+ }
+
+ public Description getDescription() {
+ Description description = fRunner.getDescription();
+ return removeIgnored(description);
+ }
+
+ private Description removeIgnored(Description description) {
+ if (isIgnored(description)) {
+ return Description.EMPTY;
+ }
+ Description result = description.childlessCopy();
+ for (Description each : description.getChildren()) {
+ Description child = removeIgnored(each);
+ if (!child.isEmpty()) {
+ result.addChild(child);
+ }
+ }
+ return result;
+ }
+
+ private boolean isIgnored(Description description) {
+ return description.getAnnotation(Ignore.class) != null;
+ }
+
+ @Override
+ public String toString() {
+ return fNewTestClass.getName();
+ }
+
+ public void filter(Filter filter) throws NoTestsRemainException {
+ filter.apply(fRunner);
+ }
+
+ public void sort(Sorter sorter) {
+ sorter.apply(fRunner);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 4.13
+ */
+ public void order(Orderer orderer) throws InvalidOrderingException {
+ orderer.apply(fRunner);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java
new file mode 100644
index 0000000..603f261
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestAdapterCache.java
@@ -0,0 +1,77 @@
+package junit.framework;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+public class JUnit4TestAdapterCache extends HashMap<Description, Test> {
+ private static final long serialVersionUID = 1L;
+ private static final JUnit4TestAdapterCache fInstance = new JUnit4TestAdapterCache();
+
+ public static JUnit4TestAdapterCache getDefault() {
+ return fInstance;
+ }
+
+ public Test asTest(Description description) {
+ if (description.isSuite()) {
+ return createTest(description);
+ } else {
+ if (!containsKey(description)) {
+ put(description, createTest(description));
+ }
+ return get(description);
+ }
+ }
+
+ Test createTest(Description description) {
+ if (description.isTest()) {
+ return new JUnit4TestCaseFacade(description);
+ } else {
+ TestSuite suite = new TestSuite(description.getDisplayName());
+ for (Description child : description.getChildren()) {
+ suite.addTest(asTest(child));
+ }
+ return suite;
+ }
+ }
+
+ public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
+ RunNotifier notifier = new RunNotifier();
+ notifier.addListener(new RunListener() {
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ result.addError(asTest(failure.getDescription()), failure.getException());
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ result.endTest(asTest(description));
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ result.startTest(asTest(description));
+ }
+ });
+ return notifier;
+ }
+
+ public List<Test> asTestList(Description description) {
+ if (description.isTest()) {
+ return Arrays.asList(asTest(description));
+ } else {
+ List<Test> returnThis = new ArrayList<Test>();
+ for (Description child : description.getChildren()) {
+ returnThis.add(asTest(child));
+ }
+ return returnThis;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java
new file mode 100644
index 0000000..5fd8ac7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/JUnit4TestCaseFacade.java
@@ -0,0 +1,30 @@
+package junit.framework;
+
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+
+public class JUnit4TestCaseFacade implements Test, Describable {
+ private final Description fDescription;
+
+ JUnit4TestCaseFacade(Description description) {
+ fDescription = description;
+ }
+
+ @Override
+ public String toString() {
+ return getDescription().toString();
+ }
+
+ public int countTestCases() {
+ return 1;
+ }
+
+ public void run(TestResult result) {
+ throw new RuntimeException(
+ "This test stub created only for informational purposes.");
+ }
+
+ public Description getDescription() {
+ return fDescription;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Protectable.java b/google3/third_party/java_src/junit/main/java/junit/framework/Protectable.java
new file mode 100644
index 0000000..c5ceb16
--- /dev/null
+++ b/google3/third_party/java_src/junit/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 following method protected.
+ */
+ public abstract void protect() throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/Test.java b/google3/third_party/java_src/junit/main/java/junit/framework/Test.java
new file mode 100644
index 0000000..db95c6c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/Test.java
@@ -0,0 +1,18 @@
+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);
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java
new file mode 100644
index 0000000..8e4385f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestCase.java
@@ -0,0 +1,524 @@
+package junit.framework;
+
+import com.google.j2objc.annotations.AutoreleasePool;
+
+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/>
+ * <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 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 {@link junit.framework.Assert#assertTrue(String, boolean)} 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 {@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 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;
+ * }
+ * </pre>
+ *
+ * @see TestResult
+ * @see TestSuite
+ */
+@SuppressWarnings("deprecation")
+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.
+ *
+ * @throws Throwable if any exception is thrown
+ */
+ public void runBare() throws Throwable {
+ Throwable exception = null;
+ setUp();
+ try {
+ runTest();
+ } catch (Throwable running) {
+ exception = running;
+ } finally {
+ try {
+ tearDown();
+ } catch (Throwable tearingDown) {
+ if (exception == null) exception = tearingDown;
+ }
+ }
+ if (exception != null) throw exception;
+ }
+
+ /**
+ * Override to run the test and assert its state.
+ *
+ * @throws Throwable if any exception is thrown
+ */
+ protected void runTest() throws Throwable {
+ 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);
+ } catch (NoSuchMethodException e) {
+ fail("Method \"" + fName + "\" not found");
+ }
+ if (!Modifier.isPublic(runMethod.getModifiers())) {
+ fail("Method \"" + fName + "\" should be public");
+ }
+
+ try {
+ runTest0(runMethod);
+ } catch (InvocationTargetException e) {
+ e.fillInStackTrace();
+ throw e.getTargetException();
+ } catch (IllegalAccessException e) {
+ e.fillInStackTrace();
+ throw e;
+ }
+ }
+
+ /**
+ * Invocation of the test method is pulled into this helper function so that
+ * AutoreleasePool can be applied to the invocation.
+ * This is a local modification to support translation of this code to
+ * Objective-C using J2ObjC. It causes the translator to add an autorelease
+ * pool around this method which is Objective-C's way of collecting and
+ * cleaning up garbage memory.
+ */
+ @AutoreleasePool
+ private void runTest0(Method m) throws InvocationTargetException, IllegalAccessException {
+ m.invoke(this);
+ }
+
+ /**
+ * Asserts that a condition is true. If it isn't it throws
+ * an AssertionFailedError with the given message.
+ */
+ public static void assertTrue(String message, boolean condition) {
+ Assert.assertTrue(message, condition);
+ }
+
+ /**
+ * Asserts that a condition is true. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ public static void assertTrue(boolean condition) {
+ Assert.assertTrue(condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws
+ * an AssertionFailedError with the given message.
+ */
+ public static void assertFalse(String message, boolean condition) {
+ Assert.assertFalse(message, condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws
+ * an AssertionFailedError.
+ */
+ public static void assertFalse(boolean condition) {
+ Assert.assertFalse(condition);
+ }
+
+ /**
+ * Fails a test with the given message.
+ */
+ public static void fail(String message) {
+ Assert.fail(message);
+ }
+
+ /**
+ * Fails a test with no message.
+ */
+ public static void fail() {
+ Assert.fail();
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, Object expected, Object actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not
+ * an AssertionFailedError is thrown.
+ */
+ public static void assertEquals(Object expected, Object actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two Strings are equal.
+ */
+ public static void assertEquals(String message, String expected, String actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two Strings are equal.
+ */
+ public static void assertEquals(String expected, String actual) {
+ Assert.assertEquals(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.
+ */
+ public static void assertEquals(String message, double expected, double actual, double delta) {
+ Assert.assertEquals(message, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that two doubles are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ public static void assertEquals(double expected, double actual, double delta) {
+ Assert.assertEquals(expected, actual, delta);
+ }
+
+ /**
+ * 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.
+ */
+ public static void assertEquals(String message, float expected, float actual, float delta) {
+ Assert.assertEquals(message, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that two floats are equal concerning a delta. If the expected
+ * value is infinity then the delta value is ignored.
+ */
+ public static void assertEquals(float expected, float actual, float delta) {
+ Assert.assertEquals(expected, actual, delta);
+ }
+
+ /**
+ * Asserts that two longs are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, long expected, long actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two longs are equal.
+ */
+ public static void assertEquals(long expected, long actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two booleans are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, boolean expected, boolean actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two booleans are equal.
+ */
+ public static void assertEquals(boolean expected, boolean actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two bytes are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, byte expected, byte actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two bytes are equal.
+ */
+ public static void assertEquals(byte expected, byte actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two chars are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, char expected, char actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two chars are equal.
+ */
+ public static void assertEquals(char expected, char actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two shorts are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, short expected, short actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two shorts are equal.
+ */
+ public static void assertEquals(short expected, short actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that two ints are equal. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertEquals(String message, int expected, int actual) {
+ Assert.assertEquals(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two ints are equal.
+ */
+ public static void assertEquals(int expected, int actual) {
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Asserts that an object isn't null.
+ */
+ public static void assertNotNull(Object object) {
+ Assert.assertNotNull(object);
+ }
+
+ /**
+ * Asserts that an object isn't null. If it is
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertNotNull(String message, Object object) {
+ Assert.assertNotNull(message, object);
+ }
+
+ /**
+ * 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>
+ */
+ public static void assertNull(Object object) {
+ Assert.assertNull(object);
+ }
+
+ /**
+ * Asserts that an object is null. If it is not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertNull(String message, Object object) {
+ Assert.assertNull(message, object);
+ }
+
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * an AssertionFailedError is thrown with the given message.
+ */
+ public static void assertSame(String message, Object expected, Object actual) {
+ Assert.assertSame(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two objects refer to the same object. If they are not
+ * the same an AssertionFailedError is thrown.
+ */
+ public static void assertSame(Object expected, Object actual) {
+ Assert.assertSame(expected, actual);
+ }
+
+ /**
+ * 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.
+ */
+ public static void assertNotSame(String message, Object expected, Object actual) {
+ Assert.assertNotSame(message, expected, actual);
+ }
+
+ /**
+ * Asserts that two objects do not refer to the same object. If they do
+ * refer to the same object an AssertionFailedError is thrown.
+ */
+ public static void assertNotSame(Object expected, Object actual) {
+ Assert.assertNotSame(expected, actual);
+ }
+
+ public static void failSame(String message) {
+ Assert.failSame(message);
+ }
+
+ public static void failNotSame(String message, Object expected, Object actual) {
+ Assert.failNotSame(message, expected, actual);
+ }
+
+ public static void failNotEquals(String message, Object expected, Object actual) {
+ Assert.failNotEquals(message, expected, actual);
+ }
+
+ public static String format(String message, Object expected, Object actual) {
+ return Assert.format(message, expected, actual);
+ }
+
+ /**
+ * 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.
+ */
+ @Override
+ public String toString() {
+ return getName() + "(" + getClass().getName() + ")";
+ }
+
+ /**
+ * Gets the name of a TestCase.
+ *
+ * @return the name of the TestCase
+ */
+ 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/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java
new file mode 100644
index 0000000..d1ddfbc
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestFailure.java
@@ -0,0 +1,69 @@
+package junit.framework;
+
+import org.junit.internal.Throwables;
+
+
+/**
+ * A {@code TestFailure} collects a failed test together with
+ * the caught exception.
+ *
+ * @see TestResult
+ */
+public class TestFailure {
+ 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.
+ */
+ @Override
+ public String toString() {
+ return fFailedTest + ": " + fThrownException.getMessage();
+ }
+
+ /**
+ * Returns a String containing the stack trace of the error
+ * thrown by TestFailure.
+ */
+ public String trace() {
+ return Throwables.getStacktrace(thrownException());
+ }
+
+ /**
+ * Returns a String containing the message from the thrown exception.
+ */
+ public String exceptionMessage() {
+ return thrownException().getMessage();
+ }
+
+ /**
+ * Returns {@code true} if the error is considered a failure
+ * (i.e. if it is an instance of {@code AssertionFailedError}),
+ * {@code false} otherwise.
+ */
+ public boolean isFailure() {
+ return thrownException() instanceof AssertionFailedError;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java
new file mode 100644
index 0000000..32d1a7f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestListener.java
@@ -0,0 +1,26 @@
+package junit.framework;
+
+/**
+ * A Listener for test progress
+ */
+public interface TestListener {
+ /**
+ * An error occurred.
+ */
+ public void addError(Test test, Throwable e);
+
+ /**
+ * A failure occurred.
+ */
+ public void addFailure(Test test, AssertionFailedError e);
+
+ /**
+ * A test ended.
+ */
+ public void endTest(Test test);
+
+ /**
+ * A test started.
+ */
+ public void startTest(Test test);
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java
new file mode 100644
index 0000000..e01a2b0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestResult.java
@@ -0,0 +1,185 @@
+package junit.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * 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 {@link ArrayIndexOutOfBoundsException}.
+ *
+ * @see Test
+ */
+public class TestResult {
+ protected List<TestFailure> fFailures;
+ protected List<TestFailure> fErrors;
+ protected List<TestListener> fListeners;
+ protected int fRunTests;
+ private boolean fStop;
+
+ public TestResult() {
+ fFailures = new ArrayList<TestFailure>();
+ fErrors = new ArrayList<TestFailure>();
+ fListeners = new ArrayList<TestListener>();
+ 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 e) {
+ fErrors.add(new TestFailure(test, e));
+ for (TestListener each : cloneListeners()) {
+ each.addError(test, e);
+ }
+ }
+
+ /**
+ * Adds a failure to the list of failures. The passed in exception
+ * caused the failure.
+ */
+ public synchronized void addFailure(Test test, AssertionFailedError e) {
+ fFailures.add(new TestFailure(test, e));
+ for (TestListener each : cloneListeners()) {
+ each.addFailure(test, e);
+ }
+ }
+
+ /**
+ * Registers a TestListener.
+ */
+ public synchronized void addListener(TestListener listener) {
+ fListeners.add(listener);
+ }
+
+ /**
+ * Unregisters a TestListener.
+ */
+ public synchronized void removeListener(TestListener listener) {
+ fListeners.remove(listener);
+ }
+
+ /**
+ * Returns a copy of the listeners.
+ */
+ 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 (TestListener each : cloneListeners()) {
+ each.endTest(test);
+ }
+ }
+
+ /**
+ * Gets the number of detected errors.
+ */
+ public synchronized int errorCount() {
+ return fErrors.size();
+ }
+
+ /**
+ * Returns an Enumeration for the errors.
+ */
+ public synchronized Enumeration<TestFailure> errors() {
+ return Collections.enumeration(fErrors);
+ }
+
+
+ /**
+ * Gets the number of detected failures.
+ */
+ public synchronized int failureCount() {
+ return fFailures.size();
+ }
+
+ /**
+ * Returns an Enumeration for the failures.
+ */
+ public synchronized Enumeration<TestFailure> failures() {
+ return Collections.enumeration(fFailures);
+ }
+
+ /**
+ * 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 (TestListener each : cloneListeners()) {
+ each.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/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java b/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java
new file mode 100644
index 0000000..50cd5f8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/TestSuite.java
@@ -0,0 +1,308 @@
+package junit.framework;
+
+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;
+
+import org.junit.internal.MethodSorter;
+import org.junit.internal.Throwables;
+
+/**
+ * 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>
+ * <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>
+ * <p>
+ * This constructor creates a suite with all the methods
+ * starting with "test" that take no arguments.
+ * <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>
+ *
+ * @see Test
+ */
+public class TestSuite implements Test {
+
+ /**
+ * ...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 + " (" + Throwables.getStacktrace(e) + ")"));
+ } catch (InvocationTargetException e) {
+ return (warning("Exception in constructor: " + name + " (" + Throwables.getStacktrace(e.getTargetException()) + ")"));
+ } catch (IllegalAccessException e) {
+ return (warning("Cannot access test case: " + name + " (" + Throwables.getStacktrace(e) + ")"));
+ }
+ return (Test) test;
+ }
+
+ /**
+ * Gets a constructor which takes a single String as
+ * its argument or a no arg constructor.
+ */
+ public static Constructor<?> getTestConstructor(Class<?> theClass) throws NoSuchMethodException {
+ try {
+ return theClass.getConstructor(String.class);
+ } catch (NoSuchMethodException e) {
+ // fall through
+ }
+ return theClass.getConstructor();
+ }
+
+ /**
+ * Returns a test which will fail and log a warning message.
+ */
+ public static Test warning(final String message) {
+ return new TestCase("warning") {
+ @Override
+ protected void runTest() {
+ fail(message);
+ }
+ };
+ }
+
+ 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 were written at 2337 meters in the Hueffihuette,
+ * Kanton Uri
+ */
+ public TestSuite(final Class<?> theClass) {
+ addTestsFromTestCase(theClass);
+ }
+
+ private void addTestsFromTestCase(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;
+ List<String> names = new ArrayList<String>();
+ while (Test.class.isAssignableFrom(superClass)) {
+ for (Method each : MethodSorter.getDeclaredMethods(superClass)) {
+ addTestMethod(each, names, theClass);
+ }
+ superClass = superClass.getSuperclass();
+ }
+ if (fTests.size() == 0) {
+ addTest(warning("No tests found in " + theClass.getName()));
+ }
+ }
+
+ /**
+ * Constructs a TestSuite from the given class with the given name.
+ *
+ * @see TestSuite#TestSuite(Class)
+ */
+ public TestSuite(Class<? extends TestCase> theClass, String name) {
+ this(theClass);
+ setName(name);
+ }
+
+ /**
+ * Constructs an empty TestSuite.
+ */
+ public TestSuite(String name) {
+ setName(name);
+ }
+
+ /**
+ * Constructs a TestSuite from the given array of classes.
+ *
+ * @param classes {@link TestCase}s
+ */
+ public TestSuite(Class<?>... classes) {
+ for (Class<?> each : classes) {
+ addTest(testCaseForClass(each));
+ }
+ }
+
+ 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");
+ }
+ }
+
+ /**
+ * Constructs a TestSuite from the given array of classes with the given name.
+ *
+ * @see TestSuite#TestSuite(Class[])
+ */
+ public TestSuite(Class<? extends TestCase>[] classes, String name) {
+ this(classes);
+ setName(name);
+ }
+
+ /**
+ * Adds a test to the suite.
+ */
+ 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));
+ }
+
+ /**
+ * Counts the number of test cases that will be run by this test.
+ */
+ public int countTestCases() {
+ int count = 0;
+ for (Test each : fTests) {
+ count += each.countTestCases();
+ }
+ return count;
+ }
+
+ /**
+ * Returns the name of the suite. Not all
+ * test suites have a name and this method
+ * can return null.
+ */
+ public String getName() {
+ return fName;
+ }
+
+ /**
+ * Runs the tests and collects their result in a TestResult.
+ */
+ public void run(TestResult result) {
+ for (Test each : fTests) {
+ if (result.shouldStop()) {
+ break;
+ }
+ runTest(each, result);
+ }
+ }
+
+ public void runTest(Test test, TestResult result) {
+ test.run(result);
+ }
+
+ /**
+ * 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 fTests.get(index);
+ }
+
+ /**
+ * Returns the number of tests in this suite.
+ */
+ public int testCount() {
+ return fTests.size();
+ }
+
+ /**
+ * Returns the tests as an enumeration.
+ */
+ public Enumeration<Test> tests() {
+ return fTests.elements();
+ }
+
+ /**
+ */
+ @Override
+ public String toString() {
+ if (getName() != null) {
+ return getName();
+ }
+ return super.toString();
+ }
+
+ 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));
+ }
+
+ private boolean isPublicTestMethod(Method m) {
+ return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+ }
+
+ private boolean isTestMethod(Method m) {
+ return m.getParameterTypes().length == 0 &&
+ m.getName().startsWith("test") &&
+ m.getReturnType().equals(Void.TYPE);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java b/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java
new file mode 100644
index 0000000..153a1c8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/framework/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x core classes.
+ */
+package junit.framework;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java b/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java
new file mode 100644
index 0000000..d63fae7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/BaseTestRunner.java
@@ -0,0 +1,326 @@
+package junit.runner;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.text.NumberFormat;
+import java.util.Properties;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestSuite;
+
+import org.junit.internal.Throwables;
+
+/**
+ * Base class for all test runners.
+ * This class was born live on stage in Sardinia during XP2000.
+ */
+public abstract class BaseTestRunner implements TestListener {
+ public static final String SUITE_METHODNAME = "suite";
+
+ private static Properties fPreferences;
+ static int fgMaxMessageLength = 500;
+ static boolean fgFilterStack = true;
+ boolean fLoading = true;
+
+ /*
+ * Implementation of TestListener
+ */
+ public synchronized void startTest(Test test) {
+ testStarted(test.toString());
+ }
+
+ protected static void setPreferences(Properties preferences) {
+ fPreferences = preferences;
+ }
+
+ protected static Properties getPreferences() {
+ if (fPreferences == null) {
+ fPreferences = new Properties();
+ fPreferences.put("loading", "true");
+ fPreferences.put("filterstack", "true");
+ readPreferences();
+ }
+ return fPreferences;
+ }
+
+ public static void savePreferences() throws IOException {
+ FileOutputStream fos = new FileOutputStream(getPreferencesFile());
+ try {
+ getPreferences().store(fos, "");
+ } finally {
+ fos.close();
+ }
+ }
+
+ public static void setPreference(String key, String value) {
+ getPreferences().put(key, value);
+ }
+
+ public synchronized void endTest(Test test) {
+ testEnded(test.toString());
+ }
+
+ public synchronized void addError(final Test test, final Throwable e) {
+ testFailed(TestRunListener.STATUS_ERROR, test, e);
+ }
+
+ public synchronized void addFailure(final Test test, final AssertionFailedError e) {
+ testFailed(TestRunListener.STATUS_FAILURE, test, e);
+ }
+
+ // TestRunListener implementation
+
+ public abstract void testStarted(String testName);
+
+ public abstract void testEnded(String testName);
+
+ public abstract void testFailed(int status, Test test, Throwable e);
+
+ /**
+ * Returns the Test corresponding to the given suite. This is
+ * a template method, subclasses override runFailed(), clearStatus().
+ */
+ public Test getTest(String suiteClassName) {
+ if (suiteClassName.length() <= 0) {
+ clearStatus();
+ return null;
+ }
+ Class<?> testClass = null;
+ try {
+ testClass = loadSuiteClass(suiteClassName);
+ } catch (ClassNotFoundException e) {
+ String clazz = e.getMessage();
+ if (clazz == null) {
+ clazz = suiteClassName;
+ }
+ runFailed("Class not found \"" + clazz + "\"");
+ return null;
+ } catch (Exception e) {
+ runFailed("Error: " + e.toString());
+ return null;
+ }
+ Method suiteMethod = null;
+ try {
+ suiteMethod = testClass.getMethod(SUITE_METHODNAME);
+ } catch (Exception e) {
+ // try to extract a test suite automatically
+ clearStatus();
+ return new TestSuite(testClass);
+ }
+ if (!Modifier.isStatic(suiteMethod.getModifiers())) {
+ runFailed("Suite() method must be static");
+ return null;
+ }
+ Test test = null;
+ try {
+ test = (Test) suiteMethod.invoke(null); // static method
+ if (test == null) {
+ return test;
+ }
+ } catch (InvocationTargetException e) {
+ runFailed("Failed to invoke suite():" + e.getTargetException().toString());
+ return null;
+ } catch (IllegalAccessException e) {
+ runFailed("Failed to invoke suite():" + e.toString());
+ return null;
+ }
+
+ clearStatus();
+ return test;
+ }
+
+ /**
+ * Returns the formatted string of the elapsed time.
+ */
+ public String elapsedTimeAsString(long runTime) {
+ return NumberFormat.getInstance().format((double) runTime / 1000);
+ }
+
+ /**
+ * Processes the command line arguments and
+ * returns the name of the suite class to run or null
+ */
+ protected String processArguments(String[] args) {
+ String suiteName = null;
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-noloading")) {
+ setLoading(false);
+ } else if (args[i].equals("-nofilterstack")) {
+ fgFilterStack = false;
+ } else if (args[i].equals("-c")) {
+ if (args.length > i + 1) {
+ suiteName = extractClassName(args[i + 1]);
+ } else {
+ System.out.println("Missing Test class name");
+ }
+ i++;
+ } else {
+ suiteName = args[i];
+ }
+ }
+ return suiteName;
+ }
+
+ /**
+ * Sets the loading behaviour of the test runner
+ */
+ public void setLoading(boolean enable) {
+ fLoading = enable;
+ }
+
+ /**
+ * Extract the class name from a String in VA/Java style
+ */
+ public String extractClassName(String className) {
+ if (className.startsWith("Default package for")) {
+ return className.substring(className.lastIndexOf(".") + 1);
+ }
+ return className;
+ }
+
+ /**
+ * Truncates a String to the maximum length.
+ */
+ public static String truncate(String s) {
+ if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength) {
+ s = s.substring(0, fgMaxMessageLength) + "...";
+ }
+ return s;
+ }
+
+ /**
+ * Override to define how to handle a failed loading of
+ * a test suite.
+ */
+ protected abstract void runFailed(String message);
+
+ /**
+ * Returns the loaded Class for a suite name.
+ */
+ protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
+ return Class.forName(suiteClassName);
+ }
+
+ /**
+ * Clears the status message.
+ */
+ protected void clearStatus() { // Belongs in the GUI TestRunner class
+ }
+
+ protected boolean useReloadingTestSuiteLoader() {
+ return getPreference("loading").equals("true") && fLoading;
+ }
+
+ private static File getPreferencesFile() {
+ String home = System.getProperty("user.home");
+ return new File(home, "junit.properties");
+ }
+
+ private static void readPreferences() {
+ InputStream is = null;
+ try {
+ is = new FileInputStream(getPreferencesFile());
+ setPreferences(new Properties(getPreferences()));
+ getPreferences().load(is);
+ } catch (IOException ignored) {
+ } catch (SecurityException ignored) {
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e1) {
+ }
+ }
+ }
+
+ public static String getPreference(String key) {
+ return getPreferences().getProperty(key);
+ }
+
+ public static int getPreference(String key, int dflt) {
+ String value = getPreference(key);
+ int intValue = dflt;
+ if (value == null) {
+ return intValue;
+ }
+ try {
+ intValue = Integer.parseInt(value);
+ } catch (NumberFormatException ne) {
+ }
+ return intValue;
+ }
+
+ /**
+ * Returns a filtered stack trace
+ */
+ public static String getFilteredTrace(Throwable e) {
+ return BaseTestRunner.getFilteredTrace(Throwables.getStacktrace(e));
+ }
+
+ /**
+ * Filters stack frames from internal JUnit classes
+ */
+ public static String getFilteredTrace(String stack) {
+ if (showStackRaw()) {
+ return stack;
+ }
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ StringReader sr = new StringReader(stack);
+ BufferedReader br = new BufferedReader(sr);
+
+ String line;
+ try {
+ while ((line = br.readLine()) != null) {
+ if (!filterLine(line)) {
+ pw.println(line);
+ }
+ }
+ } catch (Exception IOException) {
+ return stack; // return the stack unfiltered
+ }
+ return sw.toString();
+ }
+
+ protected static boolean showStackRaw() {
+ return !getPreference("filterstack").equals("true") || fgFilterStack == false;
+ }
+
+ static boolean filterLine(String line) {
+ String[] patterns = new String[]{
+ "junit.framework.TestCase",
+ "junit.framework.TestResult",
+ "junit.framework.TestSuite",
+ "junit.framework.Assert.", // don't filter AssertionFailure
+ "junit.swingui.TestRunner",
+ "junit.awtui.TestRunner",
+ "junit.textui.TestRunner",
+ "java.lang.reflect.Method.invoke("
+ };
+ for (int i = 0; i < patterns.length; i++) {
+ if (line.indexOf(patterns[i]) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static {
+ fgMaxMessageLength = getPreference("maxmessage", fgMaxMessageLength);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java b/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java
new file mode 100644
index 0000000..ce5b3d5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/TestRunListener.java
@@ -0,0 +1,25 @@
+package junit.runner;
+
+/**
+ * A listener interface for observing the
+ * execution of a test run. Unlike TestListener,
+ * this interface using only primitive objects,
+ * making it suitable for remote test execution.
+ */
+public interface TestRunListener {
+ /* test status constants*/
+ int STATUS_ERROR = 1;
+ int STATUS_FAILURE = 2;
+
+ void testRunStarted(String testSuiteName, int testCount);
+
+ void testRunEnded(long elapsedTime);
+
+ void testRunStopped(long elapsedTime);
+
+ void testStarted(String testName);
+
+ void testEnded(String testName);
+
+ void testFailed(int status, String testName, String trace);
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/Version.java b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java
new file mode 100644
index 0000000..bb12a70
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java
@@ -0,0 +1,18 @@
+package junit.runner;
+
+/**
+ * This class defines the current version of JUnit
+ */
+public class Version {
+ private Version() {
+ // don't instantiate
+ }
+
+ public static String id() {
+ return "4.13.2-SNAPSHOT";
+ }
+
+ public static void main(String[] args) {
+ System.out.println(id());
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template
new file mode 100644
index 0000000..3182cfd
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/Version.java.template
@@ -0,0 +1,18 @@
+package junit.runner;
+
+/**
+ * This class defines the current version of JUnit
+ */
+public class Version {
+ private Version() {
+ // don't instantiate
+ }
+
+ public static String id() {
+ return "@version@";
+ }
+
+ public static void main(String[] args) {
+ System.out.println(id());
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java b/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java
new file mode 100644
index 0000000..b746185
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/runner/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x test runners.
+ */
+package junit.runner;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java b/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java
new file mode 100644
index 0000000..95f10f4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/ResultPrinter.java
@@ -0,0 +1,137 @@
+package junit.textui;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.Enumeration;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+
+public class ResultPrinter implements TestListener {
+ PrintStream fWriter;
+ int fColumn = 0;
+
+ public ResultPrinter(PrintStream writer) {
+ fWriter = writer;
+ }
+
+ /* API for use by textui.TestRunner */
+
+ synchronized void print(TestResult result, long runTime) {
+ printHeader(runTime);
+ printErrors(result);
+ printFailures(result);
+ printFooter(result);
+ }
+
+ void printWaitPrompt() {
+ getWriter().println();
+ getWriter().println("<RETURN> to continue");
+ }
+
+ /* Internal methods */
+
+ protected void printHeader(long runTime) {
+ getWriter().println();
+ getWriter().println("Time: " + elapsedTimeAsString(runTime));
+ }
+
+ protected void printErrors(TestResult result) {
+ printDefects(result.errors(), result.errorCount(), "error");
+ }
+
+ protected void printFailures(TestResult result) {
+ printDefects(result.failures(), result.failureCount(), "failure");
+ }
+
+ protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
+ if (count == 0) return;
+ if (count == 1) {
+ getWriter().println("There was " + count + " " + type + ":");
+ } else {
+ getWriter().println("There were " + count + " " + type + "s:");
+ }
+ for (int i = 1; booBoos.hasMoreElements(); i++) {
+ printDefect(booBoos.nextElement(), i);
+ }
+ }
+
+ public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
+ printDefectHeader(booBoo, count);
+ printDefectTrace(booBoo);
+ }
+
+ protected void printDefectHeader(TestFailure booBoo, int count) {
+ // I feel like making this a println, then adding a line giving the throwable a chance to print something
+ // before we get to the stack trace.
+ getWriter().print(count + ") " + booBoo.failedTest());
+ }
+
+ protected void printDefectTrace(TestFailure booBoo) {
+ getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
+ }
+
+ protected void printFooter(TestResult result) {
+ if (result.wasSuccessful()) {
+ getWriter().println();
+ getWriter().print("OK");
+ getWriter().println(" (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")");
+
+ } else {
+ getWriter().println();
+ getWriter().println("FAILURES!!!");
+ getWriter().println("Tests run: " + result.runCount() +
+ ", Failures: " + result.failureCount() +
+ ", Errors: " + result.errorCount());
+ }
+ getWriter().println();
+ }
+
+ /**
+ * Returns the formatted string of the elapsed time.
+ * Duplicated from BaseTestRunner. Fix it.
+ */
+ protected String elapsedTimeAsString(long runTime) {
+ return NumberFormat.getInstance().format((double) runTime / 1000);
+ }
+
+ public PrintStream getWriter() {
+ return fWriter;
+ }
+
+ /**
+ * @see junit.framework.TestListener#addError(Test, Throwable)
+ */
+ public void addError(Test test, Throwable e) {
+ getWriter().print("E");
+ }
+
+ /**
+ * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+ */
+ public void addFailure(Test test, AssertionFailedError t) {
+ getWriter().print("F");
+ }
+
+ /**
+ * @see junit.framework.TestListener#endTest(Test)
+ */
+ public void endTest(Test test) {
+ }
+
+ /**
+ * @see junit.framework.TestListener#startTest(Test)
+ */
+ public void startTest(Test test) {
+ getWriter().print(".");
+ if (fColumn++ >= 40) {
+ getWriter().println();
+ fColumn = 0;
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java b/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java
new file mode 100644
index 0000000..913020a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/TestRunner.java
@@ -0,0 +1,206 @@
+package junit.textui;
+
+
+import java.io.PrintStream;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+import junit.runner.Version;
+
+/**
+ * A command line based tool to run tests.
+ * <pre>
+ * java junit.textui.TestRunner [-wait] TestCaseClass
+ * </pre>
+ * <p>
+ * TestRunner expects the name of a TestCase class as argument.
+ * If this class defines a static <code>suite</code> method it
+ * will be invoked and the returned test is run. Otherwise all
+ * the methods starting with "test" having no arguments are run.
+ * <p>
+ * When the wait command line argument is given TestRunner
+ * waits until the users types RETURN.
+ * <p>
+ * TestRunner prints a trace as the tests are executed followed by a
+ * summary at the end.
+ */
+public class TestRunner extends BaseTestRunner {
+ private ResultPrinter fPrinter;
+
+ public static final int SUCCESS_EXIT = 0;
+ public static final int FAILURE_EXIT = 1;
+ public static final int EXCEPTION_EXIT = 2;
+
+ /**
+ * Constructs a TestRunner.
+ */
+ public TestRunner() {
+ this(System.out);
+ }
+
+ /**
+ * Constructs a TestRunner using the given stream for all the output
+ */
+ public TestRunner(PrintStream writer) {
+ this(new ResultPrinter(writer));
+ }
+
+ /**
+ * Constructs a TestRunner using the given ResultPrinter all the output
+ */
+ public TestRunner(ResultPrinter printer) {
+ fPrinter = printer;
+ }
+
+ /**
+ * Runs a suite extracted from a TestCase subclass.
+ */
+ static public void run(Class<? extends TestCase> testClass) {
+ run(new TestSuite(testClass));
+ }
+
+ /**
+ * Runs a single test and collects its results.
+ * This method can be used to start a test run
+ * from your program.
+ * <pre>
+ * public static void main (String[] args) {
+ * test.textui.TestRunner.run(suite());
+ * }
+ * </pre>
+ */
+ static public TestResult run(Test test) {
+ TestRunner runner = new TestRunner();
+ return runner.doRun(test);
+ }
+
+ /**
+ * Runs a single test and waits until the user
+ * types RETURN.
+ */
+ static public void runAndWait(Test suite) {
+ TestRunner aTestRunner = new TestRunner();
+ aTestRunner.doRun(suite, true);
+ }
+
+ @Override
+ public void testFailed(int status, Test test, Throwable e) {
+ }
+
+ @Override
+ public void testStarted(String testName) {
+ }
+
+ @Override
+ public void testEnded(String testName) {
+ }
+
+ /**
+ * Creates the TestResult to be used for the test run.
+ */
+ protected TestResult createTestResult() {
+ return new TestResult();
+ }
+
+ public TestResult doRun(Test test) {
+ return doRun(test, false);
+ }
+
+ public TestResult doRun(Test suite, boolean wait) {
+ TestResult result = createTestResult();
+ result.addListener(fPrinter);
+ long startTime = System.currentTimeMillis();
+ suite.run(result);
+ long endTime = System.currentTimeMillis();
+ long runTime = endTime - startTime;
+ fPrinter.print(result, runTime);
+
+ pause(wait);
+ return result;
+ }
+
+ protected void pause(boolean wait) {
+ if (!wait) return;
+ fPrinter.printWaitPrompt();
+ try {
+ System.in.read();
+ } catch (Exception e) {
+ }
+ }
+
+ public static void main(String[] args) {
+ TestRunner aTestRunner = new TestRunner();
+ try {
+ TestResult r = aTestRunner.start(args);
+ if (!r.wasSuccessful()) {
+ System.exit(FAILURE_EXIT);
+ }
+ System.exit(SUCCESS_EXIT);
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ System.exit(EXCEPTION_EXIT);
+ }
+ }
+
+ /**
+ * Starts a test run. Analyzes the command line arguments and runs the given
+ * test suite.
+ */
+ public TestResult start(String[] args) throws Exception {
+ String testCase = "";
+ String method = "";
+ boolean wait = false;
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-wait")) {
+ wait = true;
+ } else if (args[i].equals("-c")) {
+ testCase = extractClassName(args[++i]);
+ } else if (args[i].equals("-m")) {
+ String arg = args[++i];
+ int lastIndex = arg.lastIndexOf('.');
+ testCase = arg.substring(0, lastIndex);
+ method = arg.substring(lastIndex + 1);
+ } else if (args[i].equals("-v")) {
+ System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma");
+ } else {
+ testCase = args[i];
+ }
+ }
+
+ if (testCase.equals("")) {
+ throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
+ }
+
+ try {
+ if (!method.equals("")) {
+ return runSingleMethod(testCase, method, wait);
+ }
+ Test suite = getTest(testCase);
+ return doRun(suite, wait);
+ } catch (Exception e) {
+ throw new Exception("Could not create and run test suite: " + e);
+ }
+ }
+
+ protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception {
+ Class<? extends TestCase> testClass = loadSuiteClass(testCase).asSubclass(TestCase.class);
+ Test test = TestSuite.createTest(testClass, method);
+ return doRun(test, wait);
+ }
+
+ @Override
+ protected void runFailed(String message) {
+ System.err.println(message);
+ System.exit(FAILURE_EXIT);
+ }
+
+ public void setPrinter(ResultPrinter printer) {
+ fPrinter = printer;
+ }
+
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java b/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java
new file mode 100644
index 0000000..2aa5176
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/junit/textui/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides JUnit v3.x command line based tool to run tests.
+ */
+package junit.textui;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/After.java b/google3/third_party/java_src/junit/main/java/org/junit/After.java
new file mode 100644
index 0000000..eae7e3a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/After.java
@@ -0,0 +1,41 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * If you allocate external resources in a {@link org.junit.Before} method you need to release them
+ * after the test runs. Annotating a <code>public void</code> method
+ * with <code>@After</code> causes that method to be run after the {@link org.junit.Test} method. All <code>@After</code>
+ * methods are guaranteed to run even if a {@link org.junit.Before} or {@link org.junit.Test} method throws an
+ * exception. The <code>@After</code> methods declared in superclasses will be run after those of the current
+ * class, unless they are overridden in the current class.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ * File output;
+ * @Before public void createOutputFile() {
+ * output= new File(...);
+ * }
+ * @Test public void something() {
+ * ...
+ * }
+ * @After public void deleteOutputFile() {
+ * output.delete();
+ * }
+ * }
+ * </pre>
+ *
+ * @see org.junit.Before
+ * @see org.junit.Test
+ * @since 4.0
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface After {
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java b/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java
new file mode 100644
index 0000000..dba4109
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/AfterClass.java
@@ -0,0 +1,42 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * If you allocate expensive external resources in a {@link org.junit.BeforeClass} method you need to release them
+ * after all the tests in the class have run. Annotating a <code>public static void</code> method
+ * with <code>@AfterClass</code> causes that method to be run after all the tests in the class have been run. All <code>@AfterClass</code>
+ * methods are guaranteed to run even if a {@link org.junit.BeforeClass} method throws an
+ * exception. The <code>@AfterClass</code> methods declared in superclasses will be run after those of the current
+ * class, unless they are shadowed in the current class.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ * private static DatabaseConnection database;
+ * @BeforeClass public static void login() {
+ * database= ...;
+ * }
+ * @Test public void something() {
+ * ...
+ * }
+ * @Test public void somethingElse() {
+ * ...
+ * }
+ * @AfterClass public static void logout() {
+ * database.logout();
+ * }
+ * }
+ * </pre>
+ *
+ * @see org.junit.BeforeClass
+ * @see org.junit.Test
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AfterClass {
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Assert.java b/google3/third_party/java_src/junit/main/java/org/junit/Assert.java
new file mode 100644
index 0000000..65bbc9d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Assert.java
@@ -0,0 +1,1034 @@
+package org.junit;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.MatcherAssert;
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.ArrayComparisonFailure;
+import org.junit.internal.ExactComparisonCriteria;
+import org.junit.internal.InexactComparisonCriteria;
+
+/**
+ * A set of assertion methods useful for writing tests. Only failed assertions
+ * are recorded. These methods can be used directly:
+ * <code>Assert.assertEquals(...)</code>, however, they read better if they
+ * are referenced through static import:
+ *
+ * <pre>
+ * import static org.junit.Assert.*;
+ * ...
+ * assertEquals(...);
+ * </pre>
+ *
+ * @see AssertionError
+ * @since 4.0
+ */
+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
+ * {@link AssertionError} with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param condition condition to be checked
+ */
+ public static void assertTrue(String message, boolean condition) {
+ if (!condition) {
+ fail(message);
+ }
+ }
+
+ /**
+ * Asserts that a condition is true. If it isn't it throws an
+ * {@link AssertionError} without a message.
+ *
+ * @param condition condition to be checked
+ */
+ public static void assertTrue(boolean condition) {
+ assertTrue(null, condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws an
+ * {@link AssertionError} with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param condition condition to be checked
+ */
+ public static void assertFalse(String message, boolean condition) {
+ assertTrue(message, !condition);
+ }
+
+ /**
+ * Asserts that a condition is false. If it isn't it throws an
+ * {@link AssertionError} without a message.
+ *
+ * @param condition condition to be checked
+ */
+ public static void assertFalse(boolean condition) {
+ assertFalse(null, condition);
+ }
+
+ /**
+ * Fails a test with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @see AssertionError
+ */
+ public static void fail(String message) {
+ if (message == null) {
+ throw new AssertionError();
+ }
+ throw new AssertionError(message);
+ }
+
+ /**
+ * Fails a test with no message.
+ */
+ public static void fail() {
+ fail(null);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>expected</code> and <code>actual</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expected expected value
+ * @param actual actual value
+ */
+ public static void assertEquals(String message, Object expected,
+ Object actual) {
+ if (equalsRegardingNull(expected, actual)) {
+ return;
+ }
+ if (expected instanceof String && actual instanceof String) {
+ String cleanMessage = message == null ? "" : message;
+ throw new ComparisonFailure(cleanMessage, (String) expected,
+ (String) actual);
+ } else {
+ failNotEquals(message, expected, actual);
+ }
+ }
+
+ private static boolean equalsRegardingNull(Object expected, Object actual) {
+ if (expected == null) {
+ return actual == null;
+ }
+
+ return isEquals(expected, actual);
+ }
+
+ private static boolean isEquals(Object expected, Object actual) {
+ return expected.equals(actual);
+ }
+
+ /**
+ * Asserts that two objects are equal. If they are not, an
+ * {@link AssertionError} without a message is thrown. If
+ * <code>expected</code> and <code>actual</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param expected expected value
+ * @param actual the value to check against <code>expected</code>
+ */
+ public static void assertEquals(Object expected, Object actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * Asserts that two objects are <b>not</b> equals. If they are, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param unexpected unexpected value to check
+ * @param actual the value to check against <code>unexpected</code>
+ */
+ public static void assertNotEquals(String message, Object unexpected,
+ Object actual) {
+ if (equalsRegardingNull(unexpected, actual)) {
+ failEquals(message, actual);
+ }
+ }
+
+ /**
+ * Asserts that two objects are <b>not</b> equals. If they are, an
+ * {@link AssertionError} without a message is thrown. If
+ * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param unexpected unexpected value to check
+ * @param actual the value to check against <code>unexpected</code>
+ */
+ public static void assertNotEquals(Object unexpected, Object actual) {
+ assertNotEquals(null, unexpected, actual);
+ }
+
+ private static void failEquals(String message, Object actual) {
+ String formatted = "Values should be different. ";
+ if (message != null) {
+ formatted = message + ". ";
+ }
+
+ formatted += "Actual: " + actual;
+ fail(formatted);
+ }
+
+ /**
+ * Asserts that two longs are <b>not</b> equals. If they are, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param unexpected unexpected value to check
+ * @param actual the value to check against <code>unexpected</code>
+ */
+ public static void assertNotEquals(String message, long unexpected, long actual) {
+ if (unexpected == actual) {
+ failEquals(message, Long.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two longs are <b>not</b> equals. If they are, an
+ * {@link AssertionError} without a message is thrown.
+ *
+ * @param unexpected unexpected value to check
+ * @param actual the value to check against <code>unexpected</code>
+ */
+ public static void assertNotEquals(long unexpected, long actual) {
+ assertNotEquals(null, unexpected, actual);
+ }
+
+ /**
+ * Asserts that two doubles are <b>not</b> equal to within a positive delta.
+ * If they are, an {@link AssertionError} is thrown with the given
+ * message. If the unexpected value is infinity then the delta value is
+ * ignored. NaNs are considered equal:
+ * <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param unexpected unexpected value
+ * @param actual the value to check against <code>unexpected</code>
+ * @param delta the maximum delta between <code>unexpected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertNotEquals(String message, double unexpected,
+ double actual, double delta) {
+ if (!doubleIsDifferent(unexpected, actual, delta)) {
+ failEquals(message, Double.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two doubles are <b>not</b> equal to within a positive delta.
+ * If they are, an {@link AssertionError} is thrown. If the unexpected
+ * value is infinity then the delta value is ignored.NaNs are considered
+ * equal: <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
+ *
+ * @param unexpected unexpected value
+ * @param actual the value to check against <code>unexpected</code>
+ * @param delta the maximum delta between <code>unexpected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertNotEquals(double unexpected, double actual, double delta) {
+ assertNotEquals(null, unexpected, actual, delta);
+ }
+
+ /**
+ * Asserts that two floats are <b>not</b> equal to within a positive delta.
+ * If they are, an {@link AssertionError} is thrown. If the unexpected
+ * value is infinity then the delta value is ignored.NaNs are considered
+ * equal: <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
+ *
+ * @param unexpected unexpected value
+ * @param actual the value to check against <code>unexpected</code>
+ * @param delta the maximum delta between <code>unexpected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertNotEquals(float unexpected, float actual, float delta) {
+ assertNotEquals(null, unexpected, actual, delta);
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values.
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ */
+ public static void assertArrayEquals(String message, Object[] expecteds,
+ Object[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown. If <code>expected</code> and
+ * <code>actual</code> are <code>null</code>, they are considered
+ * equal.
+ *
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ */
+ public static void assertArrayEquals(Object[] expecteds, Object[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two boolean arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds boolean array with expected values.
+ * @param actuals boolean array with expected values.
+ */
+ public static void assertArrayEquals(String message, boolean[] expecteds,
+ boolean[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two boolean arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown. If <code>expected</code> and
+ * <code>actual</code> are <code>null</code>, they are considered
+ * equal.
+ *
+ * @param expecteds boolean array with expected values.
+ * @param actuals boolean array with expected values.
+ */
+ public static void assertArrayEquals(boolean[] expecteds, boolean[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two byte arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds byte array with expected values.
+ * @param actuals byte array with actual values
+ */
+ public static void assertArrayEquals(String message, byte[] expecteds,
+ byte[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two byte arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds byte array with expected values.
+ * @param actuals byte array with actual values
+ */
+ public static void assertArrayEquals(byte[] expecteds, byte[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two char arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds char array with expected values.
+ * @param actuals char array with actual values
+ */
+ public static void assertArrayEquals(String message, char[] expecteds,
+ char[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two char arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds char array with expected values.
+ * @param actuals char array with actual values
+ */
+ public static void assertArrayEquals(char[] expecteds, char[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two short arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds short array with expected values.
+ * @param actuals short array with actual values
+ */
+ public static void assertArrayEquals(String message, short[] expecteds,
+ short[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two short arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds short array with expected values.
+ * @param actuals short array with actual values
+ */
+ public static void assertArrayEquals(short[] expecteds, short[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two int arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds int array with expected values.
+ * @param actuals int array with actual values
+ */
+ public static void assertArrayEquals(String message, int[] expecteds,
+ int[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two int arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds int array with expected values.
+ * @param actuals int array with actual values
+ */
+ public static void assertArrayEquals(int[] expecteds, int[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two long arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds long array with expected values.
+ * @param actuals long array with actual values
+ */
+ public static void assertArrayEquals(String message, long[] expecteds,
+ long[] actuals) throws ArrayComparisonFailure {
+ internalArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two long arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds long array with expected values.
+ * @param actuals long array with actual values
+ */
+ public static void assertArrayEquals(long[] expecteds, long[] actuals) {
+ assertArrayEquals(null, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two double arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds double array with expected values.
+ * @param actuals double array with actual values
+ * @param delta the maximum delta between <code>expecteds[i]</code> and
+ * <code>actuals[i]</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertArrayEquals(String message, double[] expecteds,
+ double[] actuals, double delta) throws ArrayComparisonFailure {
+ new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two double arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds double array with expected values.
+ * @param actuals double array with actual values
+ * @param delta the maximum delta between <code>expecteds[i]</code> and
+ * <code>actuals[i]</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertArrayEquals(double[] expecteds, double[] actuals, double delta) {
+ assertArrayEquals(null, expecteds, actuals, delta);
+ }
+
+ /**
+ * Asserts that two float arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds float array with expected values.
+ * @param actuals float array with actual values
+ * @param delta the maximum delta between <code>expecteds[i]</code> and
+ * <code>actuals[i]</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertArrayEquals(String message, float[] expecteds,
+ float[] actuals, float delta) throws ArrayComparisonFailure {
+ new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two float arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expecteds float array with expected values.
+ * @param actuals float array with actual values
+ * @param delta the maximum delta between <code>expecteds[i]</code> and
+ * <code>actuals[i]</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertArrayEquals(float[] expecteds, float[] actuals, float delta) {
+ assertArrayEquals(null, expecteds, actuals, delta);
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values.
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ */
+ private static void internalArrayEquals(String message, Object expecteds,
+ Object actuals) throws ArrayComparisonFailure {
+ new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two doubles are equal to within a positive delta.
+ * If they are not, an {@link AssertionError} is thrown with the given
+ * message. If the expected value is infinity then the delta value is
+ * ignored. NaNs are considered equal:
+ * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expected expected value
+ * @param actual the value to check against <code>expected</code>
+ * @param delta the maximum delta between <code>expected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertEquals(String message, double expected,
+ double actual, double delta) {
+ if (doubleIsDifferent(expected, actual, delta)) {
+ failNotEquals(message, Double.valueOf(expected), Double.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two floats are equal to within a positive delta.
+ * If they are not, an {@link AssertionError} is thrown with the given
+ * message. If the expected value is infinity then the delta value is
+ * ignored. NaNs are considered equal:
+ * <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expected expected value
+ * @param actual the value to check against <code>expected</code>
+ * @param delta the maximum delta between <code>expected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertEquals(String message, float expected,
+ float actual, float delta) {
+ if (floatIsDifferent(expected, actual, delta)) {
+ failNotEquals(message, Float.valueOf(expected), Float.valueOf(actual));
+ }
+ }
+
+ /**
+ * Asserts that two floats are <b>not</b> equal to within a positive delta.
+ * If they are, an {@link AssertionError} is thrown with the given
+ * message. If the unexpected value is infinity then the delta value is
+ * ignored. NaNs are considered equal:
+ * <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param unexpected unexpected value
+ * @param actual the value to check against <code>unexpected</code>
+ * @param delta the maximum delta between <code>unexpected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertNotEquals(String message, float unexpected,
+ float actual, float delta) {
+ if (!floatIsDifferent(unexpected, actual, delta)) {
+ failEquals(message, Float.valueOf(actual));
+ }
+ }
+
+ private static boolean doubleIsDifferent(double d1, double d2, double delta) {
+ if (Double.compare(d1, d2) == 0) {
+ return false;
+ }
+ if ((Math.abs(d1 - d2) <= delta)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean floatIsDifferent(float f1, float f2, float delta) {
+ if (Float.compare(f1, f2) == 0) {
+ return false;
+ }
+ if ((Math.abs(f1 - f2) <= delta)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Asserts that two longs are equal. If they are not, an
+ * {@link AssertionError} is thrown.
+ *
+ * @param expected expected long value.
+ * @param actual actual long value
+ */
+ public static void assertEquals(long expected, long actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * Asserts that two longs are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expected long expected value.
+ * @param actual long actual value
+ */
+ public static void assertEquals(String message, long expected, long actual) {
+ if (expected != actual) {
+ failNotEquals(message, Long.valueOf(expected), Long.valueOf(actual));
+ }
+ }
+
+ /**
+ * @deprecated Use
+ * <code>assertEquals(double expected, double actual, double delta)</code>
+ * instead
+ */
+ @Deprecated
+ public static void assertEquals(double expected, double actual) {
+ assertEquals(null, expected, actual);
+ }
+
+ /**
+ * @deprecated Use
+ * <code>assertEquals(String message, double expected, double actual, double delta)</code>
+ * instead
+ */
+ @Deprecated
+ public static void assertEquals(String message, double expected,
+ double actual) {
+ fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");
+ }
+
+ /**
+ * Asserts that two doubles are equal to within a positive delta.
+ * If they are not, an {@link AssertionError} is thrown. If the expected
+ * value is infinity then the delta value is ignored.NaNs are considered
+ * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
+ *
+ * @param expected expected value
+ * @param actual the value to check against <code>expected</code>
+ * @param delta the maximum delta between <code>expected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static 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 {@link AssertionError} is thrown. If the expected
+ * value is infinity then the delta value is ignored. NaNs are considered
+ * equal: <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
+ *
+ * @param expected expected value
+ * @param actual the value to check against <code>expected</code>
+ * @param delta the maximum delta between <code>expected</code> and
+ * <code>actual</code> for which both numbers are still
+ * considered equal.
+ */
+ public static void assertEquals(float expected, float actual, float delta) {
+ assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that an object isn't null. If it is an {@link AssertionError} is
+ * thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param object Object to check or <code>null</code>
+ */
+ public static void assertNotNull(String message, Object object) {
+ assertTrue(message, object != null);
+ }
+
+ /**
+ * Asserts that an object isn't null. If it is an {@link AssertionError} is
+ * thrown.
+ *
+ * @param object Object to check or <code>null</code>
+ */
+ public static void assertNotNull(Object object) {
+ assertNotNull(null, object);
+ }
+
+ /**
+ * Asserts that an object is null. If it is not, an {@link AssertionError}
+ * is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param object Object to check or <code>null</code>
+ */
+ public static void assertNull(String message, Object object) {
+ if (object == null) {
+ return;
+ }
+ failNotNull(message, object);
+ }
+
+ /**
+ * Asserts that an object is null. If it isn't an {@link AssertionError} is
+ * thrown.
+ *
+ * @param object Object to check or <code>null</code>
+ */
+ public static void assertNull(Object object) {
+ assertNull(null, object);
+ }
+
+ private static void failNotNull(String message, Object actual) {
+ String formatted = "";
+ if (message != null) {
+ formatted = message + " ";
+ }
+ fail(formatted + "expected null, but was:<" + actual + ">");
+ }
+
+ /**
+ * Asserts that two objects refer to the same object. If they are not, an
+ * {@link AssertionError} is thrown with the given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expected the expected object
+ * @param actual the object to compare to <code>expected</code>
+ */
+ public static 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 {@link AssertionError} without a message is thrown.
+ *
+ * @param expected the expected object
+ * @param actual the object to compare to <code>expected</code>
+ */
+ public static 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 {@link AssertionError} is thrown with the
+ * given message.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param unexpected the object you don't expect
+ * @param actual the object to compare to <code>unexpected</code>
+ */
+ public static void assertNotSame(String message, Object unexpected,
+ Object actual) {
+ if (unexpected == actual) {
+ failSame(message);
+ }
+ }
+
+ /**
+ * Asserts that two objects do not refer to the same object. If they do
+ * refer to the same object, an {@link AssertionError} without a message is
+ * thrown.
+ *
+ * @param unexpected the object you don't expect
+ * @param actual the object to compare to <code>unexpected</code>
+ */
+ public static void assertNotSame(Object unexpected, Object actual) {
+ assertNotSame(null, unexpected, actual);
+ }
+
+ private static void failSame(String message) {
+ String formatted = "";
+ if (message != null) {
+ formatted = message + " ";
+ }
+ fail(formatted + "expected not same");
+ }
+
+ private static void failNotSame(String message, Object expected,
+ Object actual) {
+ String formatted = "";
+ if (message != null) {
+ formatted = message + " ";
+ }
+ fail(formatted + "expected same:<" + expected + "> was not:<" + actual
+ + ">");
+ }
+
+ private static 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 && !"".equals(message)) {
+ formatted = message + " ";
+ }
+ String expectedString = String.valueOf(expected);
+ String actualString = String.valueOf(actual);
+ if (equalsRegardingNull(expectedString, actualString)) {
+ return formatted + "expected: "
+ + formatClassAndValue(expected, expectedString)
+ + " but was: " + formatClassAndValue(actual, actualString);
+ } else {
+ return formatted + "expected:<" + expectedString + "> but was:<"
+ + actualString + ">";
+ }
+ }
+
+ private static String formatClass(Class<?> value) {
+ String className = value.getCanonicalName();
+ return className == null ? value.getName() : className;
+ }
+
+ private static String formatClassAndValue(Object value, String valueString) {
+ String className = value == null ? "null" : value.getClass().getName();
+ return className + "<" + valueString + ">";
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown with the given message. If
+ * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
+ * they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values.
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ * @deprecated use assertArrayEquals
+ */
+ @Deprecated
+ public static void assertEquals(String message, Object[] expecteds,
+ Object[] actuals) {
+ assertArrayEquals(message, expecteds, actuals);
+ }
+
+ /**
+ * Asserts that two object arrays are equal. If they are not, an
+ * {@link AssertionError} is thrown. If <code>expected</code> and
+ * <code>actual</code> are <code>null</code>, they are considered
+ * equal.
+ *
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ * @deprecated use assertArrayEquals
+ */
+ @Deprecated
+ public static void assertEquals(Object[] expecteds, Object[] actuals) {
+ assertArrayEquals(expecteds, actuals);
+ }
+
+ /**
+ * Asserts that <code>actual</code> satisfies the condition specified by
+ * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
+ * information about the matcher and failing value. Example:
+ *
+ * <pre>
+ * assertThat(0, is(1)); // fails:
+ * // failure message:
+ * // expected: is <1>
+ * // got value: <0>
+ * assertThat(0, is(not(1))) // passes
+ * </pre>
+ *
+ * <code>org.hamcrest.Matcher</code> does not currently document the meaning
+ * of its type parameter <code>T</code>. This method assumes that a matcher
+ * typed as <code>Matcher<T></code> can be meaningfully applied only
+ * to values that could be assigned to a variable of type <code>T</code>.
+ *
+ * @param <T> the static type accepted by the matcher (this can flag obvious
+ * compile-time problems such as {@code assertThat(1, is("a"))}
+ * @param actual the computed value being compared
+ * @param matcher an expression, built of {@link Matcher}s, specifying allowed
+ * values
+ * @see org.hamcrest.CoreMatchers
+ * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()}
+ */
+ @Deprecated
+ public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
+ assertThat("", actual, matcher);
+ }
+
+ /**
+ * Asserts that <code>actual</code> satisfies the condition specified by
+ * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
+ * the reason and information about the matcher and failing value. Example:
+ *
+ * <pre>
+ * assertThat("Help! Integers don't work", 0, is(1)); // fails:
+ * // failure message:
+ * // Help! Integers don't work
+ * // expected: is <1>
+ * // got value: <0>
+ * assertThat("Zero is one", 0, is(not(1))) // passes
+ * </pre>
+ *
+ * <code>org.hamcrest.Matcher</code> does not currently document the meaning
+ * of its type parameter <code>T</code>. This method assumes that a matcher
+ * typed as <code>Matcher<T></code> can be meaningfully applied only
+ * to values that could be assigned to a variable of type <code>T</code>.
+ *
+ * @param reason additional information about the error
+ * @param <T> the static type accepted by the matcher (this can flag obvious
+ * compile-time problems such as {@code assertThat(1, is("a"))}
+ * @param actual the computed value being compared
+ * @param matcher an expression, built of {@link Matcher}s, specifying allowed
+ * values
+ * @see org.hamcrest.CoreMatchers
+ * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()}
+ */
+ @Deprecated
+ public static <T> void assertThat(String reason, T actual,
+ Matcher<? super T> matcher) {
+ MatcherAssert.assertThat(reason, actual, matcher);
+ }
+
+ /**
+ * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
+ * executed. If it does, the exception object is returned. If it does not throw an exception, an
+ * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code
+ * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can
+ * be obtained by calling {@link AssertionError#getCause}.
+ *
+ * @param expectedThrowable the expected type of the exception
+ * @param runnable a function that is expected to throw an exception when executed
+ * @return the exception thrown by {@code runnable}
+ * @since 4.13
+ */
+ public static <T extends Throwable> T assertThrows(Class<T> expectedThrowable,
+ ThrowingRunnable runnable) {
+ return assertThrows(null, expectedThrowable, runnable);
+ }
+
+ /**
+ * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
+ * executed. If it does, the exception object is returned. If it does not throw an exception, an
+ * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code
+ * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can
+ * be obtained by calling {@link AssertionError#getCause}.
+ *
+ * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+ * okay)
+ * @param expectedThrowable the expected type of the exception
+ * @param runnable a function that is expected to throw an exception when executed
+ * @return the exception thrown by {@code runnable}
+ * @since 4.13
+ */
+ public static <T extends Throwable> T assertThrows(String message, Class<T> expectedThrowable,
+ ThrowingRunnable runnable) {
+ try {
+ runnable.run();
+ } catch (Throwable actualThrown) {
+ if (expectedThrowable.isInstance(actualThrown)) {
+ @SuppressWarnings("unchecked") T retVal = (T) actualThrown;
+ return retVal;
+ } else {
+ String expected = formatClass(expectedThrowable);
+ Class<? extends Throwable> actualThrowable = actualThrown.getClass();
+ String actual = formatClass(actualThrowable);
+ if (expected.equals(actual)) {
+ // There must be multiple class loaders. Add the identity hash code so the message
+ // doesn't say "expected: java.lang.String<my.package.MyException> ..."
+ expected += "@" + Integer.toHexString(System.identityHashCode(expectedThrowable));
+ actual += "@" + Integer.toHexString(System.identityHashCode(actualThrowable));
+ }
+ String mismatchMessage = buildPrefix(message)
+ + format("unexpected exception type thrown;", expected, actual);
+
+ // The AssertionError(String, Throwable) ctor is only available on JDK7.
+ AssertionError assertionError = new AssertionError(mismatchMessage);
+ assertionError.initCause(actualThrown);
+ throw assertionError;
+ }
+ }
+ String notThrownMessage = buildPrefix(message) + String
+ .format("expected %s to be thrown, but nothing was thrown",
+ formatClass(expectedThrowable));
+ throw new AssertionError(notThrownMessage);
+ }
+
+ private static String buildPrefix(String message) {
+ return message != null && message.length() != 0 ? message + ": " : "";
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Assume.java b/google3/third_party/java_src/junit/main/java/org/junit/Assume.java
new file mode 100644
index 0000000..29b705b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Assume.java
@@ -0,0 +1,169 @@
+package org.junit;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import org.hamcrest.Matcher;
+
+/**
+ * A set of methods useful for stating assumptions about the conditions in which a test is meaningful.
+ * A failed assumption does not mean the code is broken, but that the test provides no useful information. Assume
+ * basically means "don't run this test if these conditions don't apply". The default JUnit runner skips tests with
+ * failing assumptions. Custom runners may behave differently.
+ * <p>
+ * A good example of using assumptions is in <a href="https://github.com/junit-team/junit4/wiki/Theories">Theories</a> where they are needed to exclude certain datapoints that aren't suitable or allowed for a certain test case.
+ * </p>
+ * Failed assumptions are usually not logged, because there may be many tests that don't apply to certain
+ * configurations.
+ *
+ * <p>
+ * These methods can be used directly: <code>Assume.assumeTrue(...)</code>, however, they
+ * read better if they are referenced through static import:<br/>
+ * <pre>
+ * import static org.junit.Assume.*;
+ * ...
+ * assumeTrue(...);
+ * </pre>
+ * </p>
+ *
+ * @see <a href="https://github.com/junit-team/junit4/wiki/Theories">Theories</a>
+ *
+ * @since 4.4
+ */
+public class Assume {
+
+ /**
+ * Do not instantiate.
+ * @deprecated since 4.13.
+ */
+ @Deprecated
+ public Assume() {
+ }
+
+ /**
+ * If called with an expression evaluating to {@code false}, the test will halt and be ignored.
+ */
+ public static void assumeTrue(boolean b) {
+ assumeThat(b, is(true));
+ }
+
+ /**
+ * The inverse of {@link #assumeTrue(boolean)}.
+ */
+ public static void assumeFalse(boolean b) {
+ assumeThat(b, is(false));
+ }
+
+ /**
+ * If called with an expression evaluating to {@code false}, the test will halt and be ignored.
+ *
+ * @param b If <code>false</code>, the method will attempt to stop the test and ignore it by
+ * throwing {@link AssumptionViolatedException}.
+ * @param message A message to pass to {@link AssumptionViolatedException}.
+ */
+ public static void assumeTrue(String message, boolean b) {
+ if (!b) throw new AssumptionViolatedException(message);
+ }
+
+ /**
+ * The inverse of {@link #assumeTrue(String, boolean)}.
+ */
+ public static void assumeFalse(String message, boolean b) {
+ assumeTrue(message, !b);
+ }
+
+ /**
+ * If called with a {@code null} array or one or more {@code null} elements in {@code objects},
+ * the test will halt and be ignored.
+ */
+ public static void assumeNotNull(Object... objects) {
+ assumeThat(objects, notNullValue());
+ assumeThat(asList(objects), everyItem(notNullValue()));
+ }
+
+ /**
+ * Call to assume that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
+ * If not, the test halts and is ignored.
+ * Example:
+ * <pre>:
+ * assumeThat(1, is(1)); // passes
+ * foo(); // will execute
+ * assumeThat(0, is(1)); // assumption failure! test halts
+ * int x = 1 / 0; // will never execute
+ * </pre>
+ *
+ * @param <T> the static type accepted by the matcher (this can flag obvious compile-time problems such as {@code assumeThat(1, is("a"))}
+ * @param actual the computed value being compared
+ * @param matcher an expression, built of {@link Matcher}s, specifying allowed values
+ * @see org.hamcrest.CoreMatchers
+ * @see org.junit.matchers.JUnitMatchers
+ */
+ public static <T> void assumeThat(T actual, Matcher<T> matcher) {
+ if (!matcher.matches(actual)) {
+ throw new AssumptionViolatedException(actual, matcher);
+ }
+ }
+
+ /**
+ * Call to assume that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
+ * If not, the test halts and is ignored.
+ * Example:
+ * <pre>:
+ * assumeThat("alwaysPasses", 1, is(1)); // passes
+ * foo(); // will execute
+ * assumeThat("alwaysFails", 0, is(1)); // assumption failure! test halts
+ * int x = 1 / 0; // will never execute
+ * </pre>
+ *
+ * @param <T> the static type accepted by the matcher (this can flag obvious compile-time problems such as {@code assumeThat(1, is("a"))}
+ * @param actual the computed value being compared
+ * @param matcher an expression, built of {@link Matcher}s, specifying allowed values
+ * @see org.hamcrest.CoreMatchers
+ * @see org.junit.matchers.JUnitMatchers
+ */
+ public static <T> void assumeThat(String message, T actual, Matcher<T> matcher) {
+ if (!matcher.matches(actual)) {
+ throw new AssumptionViolatedException(message, actual, matcher);
+ }
+ }
+
+ /**
+ * Use to assume that an operation completes normally. If {@code e} is non-null, the test will halt and be ignored.
+ *
+ * For example:
+ * <pre>
+ * \@Test public void parseDataFile() {
+ * DataFile file;
+ * try {
+ * file = DataFile.open("sampledata.txt");
+ * } catch (IOException e) {
+ * // stop test and ignore if data can't be opened
+ * assumeNoException(e);
+ * }
+ * // ...
+ * }
+ * </pre>
+ *
+ * @param e if non-null, the offending exception
+ */
+ public static void assumeNoException(Throwable e) {
+ assumeThat(e, nullValue());
+ }
+
+ /**
+ * Attempts to halt the test and ignore it if Throwable <code>e</code> is
+ * not <code>null</code>. Similar to {@link #assumeNoException(Throwable)},
+ * but provides an additional message that can explain the details
+ * concerning the assumption.
+ *
+ * @param e if non-null, the offending exception
+ * @param message Additional message to pass to {@link AssumptionViolatedException}.
+ * @see #assumeNoException(Throwable)
+ */
+ public static void assumeNoException(String message, Throwable e) {
+ assumeThat(message, e, nullValue());
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java b/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java
new file mode 100644
index 0000000..1d62190
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/AssumptionViolatedException.java
@@ -0,0 +1,46 @@
+package org.junit;
+
+import org.hamcrest.Matcher;
+
+/**
+ * An exception class used to implement <i>assumptions</i> (state in which a given test
+ * is meaningful and should or should not be executed). A test for which an assumption
+ * fails should not generate a test case failure.
+ *
+ * @see org.junit.Assume
+ * @since 4.12
+ */
+@SuppressWarnings("deprecation")
+public class AssumptionViolatedException extends org.junit.internal.AssumptionViolatedException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * An assumption exception with the given <i>actual</i> value and a <i>matcher</i> describing
+ * the expectation that failed.
+ */
+ public <T> AssumptionViolatedException(T actual, Matcher<T> matcher) {
+ super(actual, matcher);
+ }
+
+ /**
+ * An assumption exception with a message with the given <i>actual</i> value and a
+ * <i>matcher</i> describing the expectation that failed.
+ */
+ public <T> AssumptionViolatedException(String message, T expected, Matcher<T> matcher) {
+ super(message, expected, matcher);
+ }
+
+ /**
+ * An assumption exception with the given message only.
+ */
+ public AssumptionViolatedException(String message) {
+ super(message);
+ }
+
+ /**
+ * An assumption exception with the given message and a cause.
+ */
+ public AssumptionViolatedException(String message, Throwable t) {
+ super(message, t);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Before.java b/google3/third_party/java_src/junit/main/java/org/junit/Before.java
new file mode 100644
index 0000000..def8adb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Before.java
@@ -0,0 +1,39 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * When writing tests, it is common to find that several tests need similar
+ * objects created before they can run. Annotating a <code>public void</code> method
+ * with <code>@Before</code> causes that method to be run before the {@link org.junit.Test} method.
+ * The <code>@Before</code> methods of superclasses will be run before those of the current class,
+ * unless they are overridden in the current class. No other ordering is defined.
+ * <p>
+ * Here is a simple example:
+ * <pre>
+ * public class Example {
+ * List empty;
+ * @Before public void initialize() {
+ * empty= new ArrayList();
+ * }
+ * @Test public void size() {
+ * ...
+ * }
+ * @Test public void remove() {
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * @see org.junit.BeforeClass
+ * @see org.junit.After
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Before {
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java b/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java
new file mode 100644
index 0000000..8183fa0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/BeforeClass.java
@@ -0,0 +1,37 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Sometimes several tests need to share computationally expensive setup
+ * (like logging into a database). While this can compromise the independence of
+ * tests, sometimes it is a necessary optimization. Annotating a <code>public static void</code> no-arg method
+ * with <code>@BeforeClass</code> causes it to be run once before any of
+ * the test methods in the class. The <code>@BeforeClass</code> methods of superclasses
+ * will be run before those of the current class, unless they are shadowed in the current class.
+ * <p>
+ * For example:
+ * <pre>
+ * public class Example {
+ * @BeforeClass public static void onlyOnce() {
+ * ...
+ * }
+ * @Test public void one() {
+ * ...
+ * }
+ * @Test public void two() {
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * @see org.junit.AfterClass
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface BeforeClass {
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java b/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java
new file mode 100644
index 0000000..94ee29f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/ClassRule.java
@@ -0,0 +1,118 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates static fields that reference rules or methods that return them. A field must be public,
+ * static, and a subtype of {@link org.junit.rules.TestRule}. A method must be public static, and return
+ * a subtype of {@link org.junit.rules.TestRule}.
+ * <p>
+ * The {@link org.junit.runners.model.Statement} passed
+ * to the {@link org.junit.rules.TestRule} will run any {@link BeforeClass} methods,
+ * then the entire body of the test class (all contained methods, if it is
+ * a standard JUnit test class, or all contained classes, if it is a
+ * {@link org.junit.runners.Suite}), and finally any {@link AfterClass} methods.
+ * <p>
+ * The statement passed to the {@link org.junit.rules.TestRule} will never throw an exception,
+ * and throwing an exception from the {@link org.junit.rules.TestRule} will result in undefined
+ * behavior. This means that some {@link org.junit.rules.TestRule}s, such as
+ * {@link org.junit.rules.ErrorCollector},
+ * {@link org.junit.rules.ExpectedException},
+ * and {@link org.junit.rules.Timeout},
+ * have undefined behavior when used as {@link ClassRule}s.
+ * <p>
+ * If there are multiple
+ * annotated {@link ClassRule}s on a class, they will be applied in an order
+ * that depends on your JVM's implementation of the reflection API, which is
+ * undefined, in general. However, Rules defined by fields will always be applied
+ * after Rules defined by methods, i.e. the Statements returned by the former will
+ * be executed around those returned by the latter.
+ *
+ * <h3>Usage</h3>
+ * <p>
+ * For example, here is a test suite that connects to a server once before
+ * all the test classes run, and disconnects after they are finished:
+ * <pre>
+ * @RunWith(Suite.class)
+ * @SuiteClasses({A.class, B.class, C.class})
+ * public class UsesExternalResource {
+ * public static Server myServer= new Server();
+ *
+ * @ClassRule
+ * public static ExternalResource resource= new ExternalResource() {
+ * @Override
+ * protected void before() throws Throwable {
+ * myServer.connect();
+ * }
+ *
+ * @Override
+ * protected void after() {
+ * myServer.disconnect();
+ * }
+ * };
+ * }
+ * </pre>
+ * <p>
+ * and the same using a method
+ * <pre>
+ * @RunWith(Suite.class)
+ * @SuiteClasses({A.class, B.class, C.class})
+ * public class UsesExternalResource {
+ * public static Server myServer= new Server();
+ *
+ * @ClassRule
+ * public static ExternalResource getResource() {
+ * return new ExternalResource() {
+ * @Override
+ * protected void before() throws Throwable {
+ * myServer.connect();
+ * }
+ *
+ * @Override
+ * protected void after() {
+ * myServer.disconnect();
+ * }
+ * };
+ * }
+ * }
+ * </pre>
+ * <p>
+ * For more information and more examples, see {@link org.junit.rules.TestRule}.
+ *
+ * <h3>Ordering</h3>
+ * <p>
+ * You can use {@link #order()} if you want to have control over the order in
+ * which the Rules are applied.
+ *
+ * <pre>
+ * public class ThreeClassRules {
+ * @ClassRule(order = 0)
+ * public static LoggingRule outer = new LoggingRule("outer rule");
+ *
+ * @ClassRule(order = 1)
+ * public static LoggingRule middle = new LoggingRule("middle rule");
+ *
+ * @ClassRule(order = 2)
+ * public static LoggingRule inner = new LoggingRule("inner rule");
+ *
+ * // ...
+ * }
+ * </pre>
+ *
+ * @since 4.9
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface ClassRule {
+
+ /**
+ * Specifies the order in which rules are applied. The rules with a higher value are inner.
+ *
+ * @since 4.13
+ */
+ int order() default Rule.DEFAULT_ORDER;
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java b/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java
new file mode 100644
index 0000000..d1daa86
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/ComparisonFailure.java
@@ -0,0 +1,171 @@
+package org.junit;
+
+/**
+ * Thrown when an {@link org.junit.Assert#assertEquals(Object, Object) assertEquals(String, String)} fails.
+ * Create and throw a <code>ComparisonFailure</code> manually if you want to show users the
+ * difference between two complex strings.
+ * <p/>
+ * Inspired by a patch from Alex Chaffee (alex@purpletech.com)
+ *
+ * @since 4.0
+ */
+public class ComparisonFailure extends AssertionError {
+ /**
+ * The maximum length for expected and actual strings. If it is exceeded, the strings should be shortened.
+ *
+ * @see ComparisonCompactor
+ */
+ private static final int MAX_CONTEXT_LENGTH = 20;
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ 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);
+ this.fExpected = expected;
+ this.fActual = actual;
+ }
+
+ /**
+ * Returns "..." in place of common prefix and "..." in place of common suffix between expected and actual.
+ *
+ * @see Throwable#getMessage()
+ */
+ @Override
+ public String getMessage() {
+ return new ComparisonCompactor(MAX_CONTEXT_LENGTH, fExpected, fActual).compact(super.getMessage());
+ }
+
+ /**
+ * Returns the actual string value
+ *
+ * @return the actual string value
+ */
+ public String getActual() {
+ return fActual;
+ }
+
+ /**
+ * Returns the expected string value
+ *
+ * @return the expected string value
+ */
+ public String getExpected() {
+ return fExpected;
+ }
+
+ private static class ComparisonCompactor {
+ private static final String ELLIPSIS = "...";
+ private static final String DIFF_END = "]";
+ private static final String DIFF_START = "[";
+
+ /**
+ * The maximum length for <code>expected</code> and <code>actual</code> strings to show. When
+ * <code>contextLength</code> is exceeded, the Strings are shortened.
+ */
+ private final int contextLength;
+ private final String expected;
+ private final String actual;
+
+ /**
+ * @param contextLength the maximum length of context surrounding the difference between the compared strings.
+ * When context length is exceeded, the prefixes and suffixes are compacted.
+ * @param expected the expected string value
+ * @param actual the actual string value
+ */
+ public ComparisonCompactor(int contextLength, String expected, String actual) {
+ this.contextLength = contextLength;
+ this.expected = expected;
+ this.actual = actual;
+ }
+
+ public String compact(String message) {
+ if (expected == null || actual == null || expected.equals(actual)) {
+ return Assert.format(message, expected, actual);
+ } else {
+ DiffExtractor extractor = new DiffExtractor();
+ String compactedPrefix = extractor.compactPrefix();
+ String compactedSuffix = extractor.compactSuffix();
+ return Assert.format(message,
+ compactedPrefix + extractor.expectedDiff() + compactedSuffix,
+ compactedPrefix + extractor.actualDiff() + compactedSuffix);
+ }
+ }
+
+ private String sharedPrefix() {
+ int end = Math.min(expected.length(), actual.length());
+ for (int i = 0; i < end; i++) {
+ if (expected.charAt(i) != actual.charAt(i)) {
+ return expected.substring(0, i);
+ }
+ }
+ return expected.substring(0, end);
+ }
+
+ private String sharedSuffix(String prefix) {
+ int suffixLength = 0;
+ int maxSuffixLength = Math.min(expected.length() - prefix.length(),
+ actual.length() - prefix.length()) - 1;
+ for (; suffixLength <= maxSuffixLength; suffixLength++) {
+ if (expected.charAt(expected.length() - 1 - suffixLength)
+ != actual.charAt(actual.length() - 1 - suffixLength)) {
+ break;
+ }
+ }
+ return expected.substring(expected.length() - suffixLength);
+ }
+
+ private class DiffExtractor {
+ private final String sharedPrefix;
+ private final String sharedSuffix;
+
+ /**
+ * Can not be instantiated outside {@link org.junit.ComparisonFailure.ComparisonCompactor}.
+ */
+ private DiffExtractor() {
+ sharedPrefix = sharedPrefix();
+ sharedSuffix = sharedSuffix(sharedPrefix);
+ }
+
+ public String expectedDiff() {
+ return extractDiff(expected);
+ }
+
+ public String actualDiff() {
+ return extractDiff(actual);
+ }
+
+ public String compactPrefix() {
+ if (sharedPrefix.length() <= contextLength) {
+ return sharedPrefix;
+ }
+ return ELLIPSIS + sharedPrefix.substring(sharedPrefix.length() - contextLength);
+ }
+
+ public String compactSuffix() {
+ if (sharedSuffix.length() <= contextLength) {
+ return sharedSuffix;
+ }
+ return sharedSuffix.substring(0, contextLength) + ELLIPSIS;
+ }
+
+ private String extractDiff(String source) {
+ return DIFF_START + source.substring(sharedPrefix.length(), source.length() - sharedSuffix.length())
+ + DIFF_END;
+ }
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java b/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java
new file mode 100644
index 0000000..aaa0313
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/FixMethodOrder.java
@@ -0,0 +1,41 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.runners.MethodSorters;
+
+/**
+ * This class allows the user to choose the order of execution of the methods within a test class.
+ *
+ * <p>The default order of execution of JUnit tests within a class is deterministic but not predictable.
+ * The order of execution is not guaranteed for Java 7 (and some previous versions), and can even change
+ * from run to run, so the order of execution was changed to be deterministic (in JUnit 4.11)
+ *
+ * <p>It is recommended that test methods be written so that they are independent of the order that they are executed.
+ * However, there may be a number of dependent tests either through error or by design.
+ * This class allows the user to specify the order of execution of test methods.
+ *
+ * <p>For possibilities, see {@link MethodSorters}
+ *
+ * Here is an example:
+ *
+ * <pre>
+ * @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ * public class MyTest {
+ * }
+ * </pre>
+ *
+ * @see org.junit.runners.MethodSorters
+ * @since 4.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface FixMethodOrder {
+ /**
+ * Optionally specify <code>value</code> to have the methods executed in a particular order
+ */
+ MethodSorters value() default MethodSorters.DEFAULT;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java b/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java
new file mode 100644
index 0000000..db23581
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Ignore.java
@@ -0,0 +1,40 @@
+package org.junit;
+
+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 or a group of tests. Methods annotated with
+ * {@link org.junit.Test} that are also annotated with <code>@Ignore</code> will not be executed as tests.
+ * Also, you can annotate a class containing test methods with <code>@Ignore</code> and none of the containing
+ * tests will be executed. 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.
+ *
+ * <p>For example:
+ * <pre>
+ * @Ignore @Test public void something() { ...
+ * </pre>
+ * @Ignore takes an optional default parameter if you want to record why a test is being ignored:
+ * <pre>
+ * @Ignore("not ready yet") @Test public void something() { ...
+ * </pre>
+ * @Ignore can also be applied to the test class:
+ * <pre>
+ * @Ignore public class IgnoreMe {
+ * @Test public void test1() { ... }
+ * @Test public void test2() { ... }
+ * }
+ * </pre>
+ *
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Ignore {
+ /**
+ * The optional reason why the test is ignored.
+ */
+ String value() default "";
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Rule.java b/google3/third_party/java_src/junit/main/java/org/junit/Rule.java
new file mode 100644
index 0000000..9370e94
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Rule.java
@@ -0,0 +1,101 @@
+package org.junit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates fields that reference rules or methods that return a rule. A field must be public, not
+ * static, and a subtype of {@link org.junit.rules.TestRule} (preferred) or
+ * {@link org.junit.rules.MethodRule}. A method must be public, not static,
+ * and must return a subtype of {@link org.junit.rules.TestRule} (preferred) or
+ * {@link org.junit.rules.MethodRule}.
+ * <p>
+ * The {@link org.junit.runners.model.Statement} passed
+ * to the {@link org.junit.rules.TestRule} will run any {@link Before} methods,
+ * then the {@link Test} method, and finally any {@link After} methods,
+ * throwing an exception if any of these fail. If there are multiple
+ * annotated {@link Rule}s on a class, they will be applied in order of methods first, then fields.
+ * However, if there are multiple fields (or methods) they will be applied in an order
+ * that depends on your JVM's implementation of the reflection API, which is
+ * undefined, in general. Rules defined by fields will always be applied
+ * after Rules defined by methods, i.e. the Statements returned by the former will
+ * be executed around those returned by the latter.
+ *
+ * <h3>Usage</h3>
+ * <p>
+ * For example, here is a test class that creates a temporary folder before
+ * each test method, and deletes it after each:
+ * <pre>
+ * public static class HasTempFolder {
+ * @Rule
+ * public TemporaryFolder folder= new TemporaryFolder();
+ *
+ * @Test
+ * public void testUsingTempFolder() throws IOException {
+ * File createdFile= folder.newFile("myfile.txt");
+ * File createdFolder= folder.newFolder("subfolder");
+ * // ...
+ * }
+ * }
+ * </pre>
+ * <p>
+ * And the same using a method.
+ * <pre>
+ * public static class HasTempFolder {
+ * private TemporaryFolder folder= new TemporaryFolder();
+ *
+ * @Rule
+ * public TemporaryFolder getFolder() {
+ * return folder;
+ * }
+ *
+ * @Test
+ * public void testUsingTempFolder() throws IOException {
+ * File createdFile= folder.newFile("myfile.txt");
+ * File createdFolder= folder.newFolder("subfolder");
+ * // ...
+ * }
+ * }
+ * </pre>
+ * <p>
+ * For more information and more examples, see
+ * {@link org.junit.rules.TestRule}.
+ *
+ * <h3>Ordering</h3>
+ * <p>
+ * You can use {@link #order()} if you want to have control over the order in
+ * which the Rules are applied.
+ *
+ * <pre>
+ * public class ThreeRules {
+ * @Rule(order = 0)
+ * public LoggingRule outer = new LoggingRule("outer rule");
+ *
+ * @Rule(order = 1)
+ * public LoggingRule middle = new LoggingRule("middle rule");
+ *
+ * @Rule(order = 2)
+ * public LoggingRule inner = new LoggingRule("inner rule");
+ *
+ * // ...
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface Rule {
+
+ int DEFAULT_ORDER = -1;
+
+ /**
+ * Specifies the order in which rules are applied. The rules with a higher value are inner.
+ *
+ * @since 4.13
+ */
+ int order() default DEFAULT_ORDER;
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/Test.java b/google3/third_party/java_src/junit/main/java/org/junit/Test.java
new file mode 100644
index 0000000..1db6fc7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/Test.java
@@ -0,0 +1,117 @@
+package org.junit;
+
+import org.junit.function.ThrowingRunnable;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The <code>Test</code> annotation tells JUnit that the <code>public void</code> 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.
+ * <p>
+ * A simple test looks like this:
+ * <pre>
+ * public class Example {
+ * <b>@Test</b>
+ * public void method() {
+ * org.junit.Assert.assertTrue( new ArrayList().isEmpty() );
+ * }
+ * }
+ * </pre>
+ * <p>
+ * The <code>Test</code> annotation supports two optional parameters for
+ * exception testing and for limiting test execution time.
+ *
+ * <h3>Exception Testing</h3>
+ * <p>
+ * The parameter <code>expected</code> 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:
+ * <pre>
+ * @Test(<b>expected=IndexOutOfBoundsException.class</b>)
+ * public void outOfBounds() {
+ * new ArrayList<Object>().get(1);
+ * }
+ * </pre>
+ *
+ * Using the parameter <code>expected</code> for exception testing comes with
+ * some limitations: only the exception's type can be checked and it is not
+ * possible to precisely specify the code that throws the exception. Therefore
+ * JUnit 4 has improved its support for exception testing with
+ * {@link Assert#assertThrows(Class, ThrowingRunnable)} and the
+ * {@link org.junit.rules.ExpectedException ExpectedException} rule.
+ * With <code>assertThrows</code> the code that throws the exception can be
+ * precisely specified. If the exception's message or one of its properties
+ * should be verified, the <code>ExpectedException</code> rule can be used. Further
+ * information about exception testing can be found at the
+ * <a href="https://github.com/junit-team/junit4/wiki/Exception-testing">JUnit Wiki</a>.
+ *
+ * <h3>Timeout</h3>
+ * <p>
+ * The parameter <code>timeout</code> causes a test to fail if it takes
+ * longer than a specified amount of clock time (measured in milliseconds). The following test fails:
+ * <pre>
+ * @Test(<b>timeout=100</b>)
+ * public void infinity() {
+ * while(true);
+ * }
+ * </pre>
+ * <b>Warning</b>: while <code>timeout</code> is useful to catch and terminate
+ * infinite loops, it should <em>not</em> be considered deterministic. The
+ * following test may or may not fail depending on how the operating system
+ * schedules threads:
+ * <pre>
+ * @Test(<b>timeout=100</b>)
+ * public void sleep100() {
+ * Thread.sleep(100);
+ * }
+ * </pre>
+ * <b>THREAD SAFETY WARNING:</b> Test methods with a timeout parameter are run in a thread other than the
+ * thread which runs the fixture's @Before and @After methods. This may yield different behavior for
+ * code that is not thread safe when compared to the same test method without a timeout parameter.
+ * <b>Consider using the {@link org.junit.rules.Timeout} rule instead</b>, which ensures a test method is run on the
+ * same thread as the fixture's @Before and @After methods.
+ *
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Test {
+
+ /**
+ * Default empty exception.
+ */
+ static class None extends Throwable {
+ private static final long serialVersionUID = 1L;
+
+ private None() {
+ }
+ }
+
+ /**
+ * Optionally specify <code>expected</code>, a Throwable, to cause a test method to succeed if
+ * and only if an exception of the specified class is thrown by the method. If the Throwable's
+ * message or one of its properties should be verified, the
+ * {@link org.junit.rules.ExpectedException ExpectedException} rule can be used instead.
+ */
+ Class<? extends Throwable> expected() default None.class;
+
+ /**
+ * Optionally specify <code>timeout</code> in milliseconds to cause a test method to fail if it
+ * takes longer than that number of milliseconds.
+ * <p>
+ * <b>THREAD SAFETY WARNING:</b> Test methods with a timeout parameter are run in a thread other than the
+ * thread which runs the fixture's @Before and @After methods. This may yield different behavior for
+ * code that is not thread safe when compared to the same test method without a timeout parameter.
+ * <b>Consider using the {@link org.junit.rules.Timeout} rule instead</b>, which ensures a test method is run on the
+ * same thread as the fixture's @Before and @After methods.
+ * </p>
+ */
+ long timeout() default 0L;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java b/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java
new file mode 100644
index 0000000..4804493
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/TestCouldNotBeSkippedException.java
@@ -0,0 +1,19 @@
+package org.junit;
+
+/**
+ * Indicates that a test that indicated that it should be skipped could not be skipped.
+ * This can be thrown if a test uses the methods in {@link Assume} to indicate that
+ * it should be skipped, but before processing of the test was completed, other failures
+ * occured.
+ *
+ * @see org.junit.Assume
+ * @since 4.13
+ */
+public class TestCouldNotBeSkippedException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /** Creates an instance using the given assumption failure. */
+ public TestCouldNotBeSkippedException(org.junit.internal.AssumptionViolatedException cause) {
+ super("Test could not be skipped due to other failures", cause);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java
new file mode 100644
index 0000000..97da0f7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/ParallelComputer.java
@@ -0,0 +1,67 @@
+package org.junit.experimental;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.runner.Computer;
+import org.junit.runner.Runner;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+import org.junit.runners.model.RunnerScheduler;
+
+public class ParallelComputer extends Computer {
+ private final boolean classes;
+
+ private final boolean methods;
+
+ public ParallelComputer(boolean classes, boolean methods) {
+ this.classes = classes;
+ this.methods = methods;
+ }
+
+ public static Computer classes() {
+ return new ParallelComputer(true, false);
+ }
+
+ public static Computer methods() {
+ return new ParallelComputer(false, true);
+ }
+
+ private static Runner parallelize(Runner runner) {
+ if (runner instanceof ParentRunner) {
+ ((ParentRunner<?>) runner).setScheduler(new RunnerScheduler() {
+ private final ExecutorService fService = Executors.newCachedThreadPool();
+
+ public void schedule(Runnable childStatement) {
+ fService.submit(childStatement);
+ }
+
+ public void finished() {
+ try {
+ fService.shutdown();
+ fService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+ });
+ }
+ return runner;
+ }
+
+ @Override
+ public Runner getSuite(RunnerBuilder builder, java.lang.Class<?>[] classes)
+ throws InitializationError {
+ Runner suite = super.getSuite(builder, classes);
+ return this.classes ? parallelize(suite) : suite;
+ }
+
+ @Override
+ protected Runner getRunner(RunnerBuilder builder, Class<?> testClass)
+ throws Throwable {
+ Runner runner = super.getRunner(builder, testClass);
+ return methods ? parallelize(runner) : runner;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java
new file mode 100644
index 0000000..0c73ed8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Categories.java
@@ -0,0 +1,375 @@
+package org.junit.experimental.categories;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * From a given set of test classes, runs only the classes and methods that are
+ * annotated with either the category given with the @IncludeCategory
+ * annotation, or a subtype of that category.
+ * <p>
+ * Note that, for now, annotating suites with {@code @Category} has no effect.
+ * Categories must be annotated on the direct method or class.
+ * <p>
+ * Example:
+ * <pre>
+ * public interface FastTests {
+ * }
+ *
+ * public interface SlowTests {
+ * }
+ *
+ * public interface SmokeTests
+ * }
+ *
+ * public static class A {
+ * @Test
+ * public void a() {
+ * fail();
+ * }
+ *
+ * @Category(SlowTests.class)
+ * @Test
+ * public void b() {
+ * }
+ *
+ * @Category({FastTests.class, SmokeTests.class})
+ * @Test
+ * public void c() {
+ * }
+ * }
+ *
+ * @Category({SlowTests.class, FastTests.class})
+ * public static class B {
+ * @Test
+ * public void d() {
+ * }
+ * }
+ *
+ * @RunWith(Categories.class)
+ * @IncludeCategory(SlowTests.class)
+ * @SuiteClasses({A.class, B.class})
+ * // Note that Categories is a kind of Suite
+ * public static class SlowTestSuite {
+ * // Will run A.b and B.d, but not A.a and A.c
+ * }
+ * </pre>
+ * <p>
+ * Example to run multiple categories:
+ * <pre>
+ * @RunWith(Categories.class)
+ * @IncludeCategory({FastTests.class, SmokeTests.class})
+ * @SuiteClasses({A.class, B.class})
+ * public static class FastOrSmokeTestSuite {
+ * // Will run A.c and B.d, but not A.b because it is not any of FastTests or SmokeTests
+ * }
+ * </pre>
+ *
+ * @version 4.12
+ * @see <a href="https://github.com/junit-team/junit4/wiki/Categories">Categories at JUnit wiki</a>
+ */
+public class Categories extends Suite {
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface IncludeCategory {
+ /**
+ * Determines the tests to run that are annotated with categories specified in
+ * the value of this annotation or their subtypes unless excluded with {@link ExcludeCategory}.
+ */
+ Class<?>[] value() default {};
+
+ /**
+ * If <tt>true</tt>, runs tests annotated with <em>any</em> of the categories in
+ * {@link IncludeCategory#value()}. Otherwise, runs tests only if annotated with <em>all</em> of the categories.
+ */
+ boolean matchAny() default true;
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ExcludeCategory {
+ /**
+ * Determines the tests which do not run if they are annotated with categories specified in the
+ * value of this annotation or their subtypes regardless of being included in {@link IncludeCategory#value()}.
+ */
+ Class<?>[] value() default {};
+
+ /**
+ * If <tt>true</tt>, the tests annotated with <em>any</em> of the categories in {@link ExcludeCategory#value()}
+ * do not run. Otherwise, the tests do not run if and only if annotated with <em>all</em> categories.
+ */
+ boolean matchAny() default true;
+ }
+
+ public static class CategoryFilter extends Filter {
+ private final Set<Class<?>> included;
+ private final Set<Class<?>> excluded;
+ private final boolean includedAny;
+ private final boolean excludedAny;
+
+ public static CategoryFilter include(boolean matchAny, Class<?>... categories) {
+ return new CategoryFilter(matchAny, categories, true, null);
+ }
+
+ public static CategoryFilter include(Class<?> category) {
+ return include(true, category);
+ }
+
+ public static CategoryFilter include(Class<?>... categories) {
+ return include(true, categories);
+ }
+
+ public static CategoryFilter exclude(boolean matchAny, Class<?>... categories) {
+ return new CategoryFilter(true, null, matchAny, categories);
+ }
+
+ public static CategoryFilter exclude(Class<?> category) {
+ return exclude(true, category);
+ }
+
+ public static CategoryFilter exclude(Class<?>... categories) {
+ return exclude(true, categories);
+ }
+
+ public static CategoryFilter categoryFilter(boolean matchAnyInclusions, Set<Class<?>> inclusions,
+ boolean matchAnyExclusions, Set<Class<?>> exclusions) {
+ return new CategoryFilter(matchAnyInclusions, inclusions, matchAnyExclusions, exclusions);
+ }
+
+ @Deprecated
+ public CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory) {
+ includedAny = true;
+ excludedAny = true;
+ included = nullableClassToSet(includedCategory);
+ excluded = nullableClassToSet(excludedCategory);
+ }
+
+ protected CategoryFilter(boolean matchAnyIncludes, Set<Class<?>> includes,
+ boolean matchAnyExcludes, Set<Class<?>> excludes) {
+ includedAny = matchAnyIncludes;
+ excludedAny = matchAnyExcludes;
+ included = copyAndRefine(includes);
+ excluded = copyAndRefine(excludes);
+ }
+
+ private CategoryFilter(boolean matchAnyIncludes, Class<?>[] inclusions,
+ boolean matchAnyExcludes, Class<?>[] exclusions) {
+ includedAny = matchAnyIncludes;
+ excludedAny = matchAnyExcludes;
+ included = createSet(inclusions);
+ excluded = createSet(exclusions);
+ }
+
+ /**
+ * @see #toString()
+ */
+ @Override
+ public String describe() {
+ return toString();
+ }
+
+ /**
+ * Returns string in the form <tt>"[included categories] - [excluded categories]"</tt>, where both
+ * sets have comma separated names of categories.
+ *
+ * @return string representation for the relative complement of excluded categories set
+ * in the set of included categories. Examples:
+ * <ul>
+ * <li> <tt>"categories [all]"</tt> for all included categories and no excluded ones;
+ * <li> <tt>"categories [all] - [A, B]"</tt> for all included categories and given excluded ones;
+ * <li> <tt>"categories [A, B] - [C, D]"</tt> for given included categories and given excluded ones.
+ * </ul>
+ * @see Class#toString() name of category
+ */
+ @Override public String toString() {
+ StringBuilder description= new StringBuilder("categories ")
+ .append(included.isEmpty() ? "[all]" : included);
+ if (!excluded.isEmpty()) {
+ description.append(" - ").append(excluded);
+ }
+ return description.toString();
+ }
+
+ @Override
+ public boolean shouldRun(Description description) {
+ if (hasCorrectCategoryAnnotation(description)) {
+ return true;
+ }
+
+ for (Description each : description.getChildren()) {
+ if (shouldRun(each)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasCorrectCategoryAnnotation(Description description) {
+ final Set<Class<?>> childCategories= categories(description);
+
+ // If a child has no categories, immediately return.
+ if (childCategories.isEmpty()) {
+ return included.isEmpty();
+ }
+
+ if (!excluded.isEmpty()) {
+ if (excludedAny) {
+ if (matchesAnyParentCategories(childCategories, excluded)) {
+ return false;
+ }
+ } else {
+ if (matchesAllParentCategories(childCategories, excluded)) {
+ return false;
+ }
+ }
+ }
+
+ if (included.isEmpty()) {
+ // Couldn't be excluded, and with no suite's included categories treated as should run.
+ return true;
+ } else {
+ if (includedAny) {
+ return matchesAnyParentCategories(childCategories, included);
+ } else {
+ return matchesAllParentCategories(childCategories, included);
+ }
+ }
+ }
+
+ /**
+ * @return <tt>true</tt> if at least one (any) parent category match a child, otherwise <tt>false</tt>.
+ * If empty <tt>parentCategories</tt>, returns <tt>false</tt>.
+ */
+ private boolean matchesAnyParentCategories(Set<Class<?>> childCategories, Set<Class<?>> parentCategories) {
+ for (Class<?> parentCategory : parentCategories) {
+ if (hasAssignableTo(childCategories, parentCategory)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return <tt>false</tt> if at least one parent category does not match children, otherwise <tt>true</tt>.
+ * If empty <tt>parentCategories</tt>, returns <tt>true</tt>.
+ */
+ private boolean matchesAllParentCategories(Set<Class<?>> childCategories, Set<Class<?>> parentCategories) {
+ for (Class<?> parentCategory : parentCategories) {
+ if (!hasAssignableTo(childCategories, parentCategory)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static Set<Class<?>> categories(Description description) {
+ Set<Class<?>> categories= new HashSet<Class<?>>();
+ Collections.addAll(categories, directCategories(description));
+ Collections.addAll(categories, directCategories(parentDescription(description)));
+ return categories;
+ }
+
+ private static Description parentDescription(Description description) {
+ Class<?> testClass= description.getTestClass();
+ return testClass == null ? null : Description.createSuiteDescription(testClass);
+ }
+
+ private static Class<?>[] directCategories(Description description) {
+ if (description == null) {
+ return new Class<?>[0];
+ }
+
+ Category annotation= description.getAnnotation(Category.class);
+ return annotation == null ? new Class<?>[0] : annotation.value();
+ }
+
+ private static Set<Class<?>> copyAndRefine(Set<Class<?>> classes) {
+ Set<Class<?>> c= new LinkedHashSet<Class<?>>();
+ if (classes != null) {
+ c.addAll(classes);
+ }
+ c.remove(null);
+ return c;
+ }
+ }
+
+ public Categories(Class<?> klass, RunnerBuilder builder) throws InitializationError {
+ super(klass, builder);
+ try {
+ Set<Class<?>> included= getIncludedCategory(klass);
+ Set<Class<?>> excluded= getExcludedCategory(klass);
+ boolean isAnyIncluded= isAnyIncluded(klass);
+ boolean isAnyExcluded= isAnyExcluded(klass);
+
+ filter(CategoryFilter.categoryFilter(isAnyIncluded, included, isAnyExcluded, excluded));
+ } catch (NoTestsRemainException e) {
+ throw new InitializationError(e);
+ }
+ }
+
+ private static Set<Class<?>> getIncludedCategory(Class<?> klass) {
+ IncludeCategory annotation= klass.getAnnotation(IncludeCategory.class);
+ return createSet(annotation == null ? null : annotation.value());
+ }
+
+ private static boolean isAnyIncluded(Class<?> klass) {
+ IncludeCategory annotation= klass.getAnnotation(IncludeCategory.class);
+ return annotation == null || annotation.matchAny();
+ }
+
+ private static Set<Class<?>> getExcludedCategory(Class<?> klass) {
+ ExcludeCategory annotation= klass.getAnnotation(ExcludeCategory.class);
+ return createSet(annotation == null ? null : annotation.value());
+ }
+
+ private static boolean isAnyExcluded(Class<?> klass) {
+ ExcludeCategory annotation= klass.getAnnotation(ExcludeCategory.class);
+ return annotation == null || annotation.matchAny();
+ }
+
+ private static boolean hasAssignableTo(Set<Class<?>> assigns, Class<?> to) {
+ for (final Class<?> from : assigns) {
+ if (to.isAssignableFrom(from)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Set<Class<?>> createSet(Class<?>[] classes) {
+ // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.12
+ // for include(boolean, Class<?>...) and exclude(boolean, Class<?>...)
+ if (classes == null || classes.length == 0) {
+ return Collections.emptySet();
+ }
+ for (Class<?> category : classes) {
+ if (category == null) {
+ throw new NullPointerException("has null category");
+ }
+ }
+
+ return classes.length == 1
+ ? Collections.<Class<?>>singleton(classes[0])
+ : new LinkedHashSet<Class<?>>(Arrays.asList(classes));
+ }
+
+ private static Set<Class<?>> nullableClassToSet(Class<?> nullableClass) {
+ // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.11
+ // for CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory)
+ return nullableClass == null
+ ? Collections.<Class<?>>emptySet()
+ : Collections.<Class<?>>singleton(nullableClass);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java
new file mode 100644
index 0000000..8eae836
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/Category.java
@@ -0,0 +1,48 @@
+package org.junit.experimental.categories;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import org.junit.validator.ValidateWith;
+
+/**
+ * Marks a test class or test method as belonging to one or more categories of tests.
+ * The value is an array of arbitrary classes.
+ *
+ * This annotation is only interpreted by the Categories runner (at present).
+ *
+ * For example:
+ * <pre>
+ * public interface FastTests {}
+ * public interface SlowTests {}
+ *
+ * public static class A {
+ * @Test
+ * public void a() {
+ * fail();
+ * }
+ *
+ * @Category(SlowTests.class)
+ * @Test
+ * public void b() {
+ * }
+ * }
+ *
+ * @Category({SlowTests.class, FastTests.class})
+ * public static class B {
+ * @Test
+ * public void c() {
+ *
+ * }
+ * }
+ * </pre>
+ *
+ * For more usage, see code example on {@link Categories}.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@ValidateWith(CategoryValidator.class)
+public @interface Category {
+ Class<?>[] value();
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java
new file mode 100644
index 0000000..405feeb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryFilterFactory.java
@@ -0,0 +1,51 @@
+package org.junit.experimental.categories;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.internal.Classes;
+import org.junit.runner.FilterFactory;
+import org.junit.runner.FilterFactoryParams;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Implementation of FilterFactory for Category filtering.
+ */
+abstract class CategoryFilterFactory implements FilterFactory {
+ /**
+ * Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given a
+ * {@link FilterFactoryParams} argument.
+ *
+ * @param params Parameters needed to create the {@link Filter}
+ */
+ public Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException {
+ try {
+ return createFilter(parseCategories(params.getArgs()));
+ } catch (ClassNotFoundException e) {
+ throw new FilterNotCreatedException(e);
+ }
+ }
+
+ /**
+ * Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given an array of classes.
+ *
+ * @param categories Category classes.
+ */
+ protected abstract Filter createFilter(List<Class<?>> categories);
+
+ private List<Class<?>> parseCategories(String categories) throws ClassNotFoundException {
+ List<Class<?>> categoryClasses = new ArrayList<Class<?>>();
+
+ for (String category : categories.split(",")) {
+ /*
+ * Load the category class using the context class loader.
+ * If there is no context class loader, use the class loader for this class.
+ */
+ Class<?> categoryClass = Classes.getClass(category, getClass());
+
+ categoryClasses.add(categoryClass);
+ }
+
+ return categoryClasses;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java
new file mode 100644
index 0000000..491d8ac
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/CategoryValidator.java
@@ -0,0 +1,62 @@
+package org.junit.experimental.categories;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableSet;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.validator.AnnotationValidator;
+
+/**
+ * Validates that there are no errors in the use of the {@code Category}
+ * annotation. If there is, a {@code Throwable} object will be added to the list
+ * of errors.
+ *
+ * @since 4.12
+ */
+public final class CategoryValidator extends AnnotationValidator {
+
+ @SuppressWarnings("unchecked")
+ private static final Set<Class<? extends Annotation>> INCOMPATIBLE_ANNOTATIONS = unmodifiableSet(new HashSet<Class<? extends Annotation>>(
+ asList(BeforeClass.class, AfterClass.class, Before.class, After.class)));
+
+ /**
+ * Adds to {@code errors} a throwable for each problem detected. Looks for
+ * {@code BeforeClass}, {@code AfterClass}, {@code Before} and {@code After}
+ * annotations.
+ *
+ * @param method the method that is being validated
+ * @return A list of exceptions detected
+ *
+ * @since 4.12
+ */
+ @Override
+ public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
+ List<Exception> errors = new ArrayList<Exception>();
+ Annotation[] annotations = method.getAnnotations();
+ for (Annotation annotation : annotations) {
+ for (Class<?> clazz : INCOMPATIBLE_ANNOTATIONS) {
+ if (annotation.annotationType().isAssignableFrom(clazz)) {
+ addErrorMessage(errors, clazz);
+ }
+ }
+ }
+ return unmodifiableList(errors);
+ }
+
+ private void addErrorMessage(List<Exception> errors, Class<?> clazz) {
+ String message = String.format("@%s can not be combined with @Category",
+ clazz.getSimpleName());
+ errors.add(new Exception(message));
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java
new file mode 100644
index 0000000..5117eef
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/ExcludeCategories.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.categories;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * {@link org.junit.runner.FilterFactory} to exclude categories.
+ *
+ * The {@link Filter} that is created will filter out tests that are categorized with any of the
+ * given categories.
+ *
+ * Usage from command line:
+ * <code>
+ * --filter=org.junit.experimental.categories.ExcludeCategories=pkg.of.Cat1,pkg.of.Cat2
+ * </code>
+ *
+ * Usage from API:
+ * <code>
+ * new ExcludeCategories().createFilter(Cat1.class, Cat2.class);
+ * </code>
+ */
+public final class ExcludeCategories extends CategoryFilterFactory {
+ /**
+ * Creates a {@link Filter} which is only passed by tests that are
+ * not categorized with any of the specified categories.
+ *
+ * @param categories Category classes.
+ */
+ @Override
+ protected Filter createFilter(List<Class<?>> categories) {
+ return new ExcludesAny(categories);
+ }
+
+ private static class ExcludesAny extends CategoryFilter {
+ public ExcludesAny(List<Class<?>> categories) {
+ this(new HashSet<Class<?>>(categories));
+ }
+
+ public ExcludesAny(Set<Class<?>> categories) {
+ super(true, null, true, categories);
+ }
+
+ @Override
+ public String describe() {
+ return "excludes " + super.describe();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java
new file mode 100644
index 0000000..b7f7507
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/categories/IncludeCategories.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.categories;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * {@link org.junit.runner.FilterFactory} to include categories.
+ *
+ * The {@link Filter} that is created will filter out tests that are categorized with any of the
+ * given categories.
+ *
+ * Usage from command line:
+ * <code>
+ * --filter=org.junit.experimental.categories.IncludeCategories=pkg.of.Cat1,pkg.of.Cat2
+ * </code>
+ *
+ * Usage from API:
+ * <code>
+ * new IncludeCategories().createFilter(Cat1.class, Cat2.class);
+ * </code>
+ */
+public final class IncludeCategories extends CategoryFilterFactory {
+ /**
+ * Creates a {@link Filter} which is only passed by tests that are
+ * categorized with any of the specified categories.
+ *
+ * @param categories Category classes.
+ */
+ @Override
+ protected Filter createFilter(List<Class<?>> categories) {
+ return new IncludesAny(categories);
+ }
+
+ private static class IncludesAny extends CategoryFilter {
+ public IncludesAny(List<Class<?>> categories) {
+ this(new HashSet<Class<?>>(categories));
+ }
+
+ public IncludesAny(Set<Class<?>> categories) {
+ super(true, categories, true, null);
+ }
+
+ @Override
+ public String describe() {
+ return "includes " + super.describe();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java
new file mode 100644
index 0000000..116d755
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/CouldNotReadCoreException.java
@@ -0,0 +1,15 @@
+package org.junit.experimental.max;
+
+/**
+ * Thrown when Max cannot read the MaxCore serialization
+ */
+public class CouldNotReadCoreException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs
+ */
+ public CouldNotReadCoreException(Throwable e) {
+ super(e);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java
new file mode 100644
index 0000000..625cade
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxCore.java
@@ -0,0 +1,181 @@
+package org.junit.experimental.max;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestSuite;
+import org.junit.internal.requests.SortingRequest;
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A replacement for JUnitCore, which keeps track of runtime and failure history, and reorders tests
+ * to maximize the chances that a failing test occurs early in the test run.
+ *
+ * The rules for sorting are:
+ * <ol>
+ * <li> Never-run tests first, in arbitrary order
+ * <li> Group remaining tests by the date at which they most recently failed.
+ * <li> Sort groups such that the most recent failure date is first, and never-failing tests are at the end.
+ * <li> Within a group, run the fastest tests first.
+ * </ol>
+ */
+public class MaxCore {
+ private static final String MALFORMED_JUNIT_3_TEST_CLASS_PREFIX = "malformed JUnit 3 test class: ";
+
+ /**
+ * Create a new MaxCore from a serialized file stored at storedResults
+ *
+ * @deprecated use storedLocally()
+ */
+ @Deprecated
+ public static MaxCore forFolder(String folderName) {
+ return storedLocally(new File(folderName));
+ }
+
+ /**
+ * Create a new MaxCore from a serialized file stored at storedResults
+ */
+ public static MaxCore storedLocally(File storedResults) {
+ return new MaxCore(storedResults);
+ }
+
+ private final MaxHistory history;
+
+ private MaxCore(File storedResults) {
+ history = MaxHistory.forFolder(storedResults);
+ }
+
+ /**
+ * Run all the tests in <code>class</code>.
+ *
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(Class<?> testClass) {
+ return run(Request.aClass(testClass));
+ }
+
+ /**
+ * Run all the tests contained in <code>request</code>.
+ *
+ * @param request the request describing tests
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(Request request) {
+ return run(request, new JUnitCore());
+ }
+
+ /**
+ * Run all the tests contained in <code>request</code>.
+ *
+ * This variant should be used if {@code core} has attached listeners that this
+ * run should notify.
+ *
+ * @param request the request describing tests
+ * @param core a JUnitCore to delegate to.
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(Request request, JUnitCore core) {
+ core.addListener(history.listener());
+ return core.run(sortRequest(request).getRunner());
+ }
+
+ /**
+ * @return a new Request, which contains all of the same tests, but in a new order.
+ */
+ public Request sortRequest(Request request) {
+ if (request instanceof SortingRequest) {
+ // We'll pay big karma points for this
+ return request;
+ }
+ List<Description> leaves = findLeaves(request);
+ Collections.sort(leaves, history.testComparator());
+ return constructLeafRequest(leaves);
+ }
+
+ private Request constructLeafRequest(List<Description> leaves) {
+ final List<Runner> runners = new ArrayList<Runner>();
+ for (Description each : leaves) {
+ runners.add(buildRunner(each));
+ }
+ return new Request() {
+ @Override
+ public Runner getRunner() {
+ try {
+ return new Suite((Class<?>) null, runners) {
+ };
+ } catch (InitializationError e) {
+ return new ErrorReportingRunner(null, e);
+ }
+ }
+ };
+ }
+
+ private Runner buildRunner(Description each) {
+ if (each.toString().equals("TestSuite with 0 tests")) {
+ return Suite.emptySuite();
+ }
+ if (each.toString().startsWith(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX)) {
+ // This is cheating, because it runs the whole class
+ // to get the warning for this method, but we can't do better,
+ // because JUnit 3.8's
+ // thrown away which method the warning is for.
+ return new JUnit38ClassRunner(new TestSuite(getMalformedTestClass(each)));
+ }
+ Class<?> type = each.getTestClass();
+ if (type == null) {
+ throw new RuntimeException("Can't build a runner from description [" + each + "]");
+ }
+ String methodName = each.getMethodName();
+ if (methodName == null) {
+ return Request.aClass(type).getRunner();
+ }
+ return Request.method(type, methodName).getRunner();
+ }
+
+ private Class<?> getMalformedTestClass(Description each) {
+ try {
+ return Class.forName(each.toString().replace(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX, ""));
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * @param request a request to run
+ * @return a list of method-level tests to run, sorted in the order
+ * specified in the class comment.
+ */
+ public List<Description> sortedLeavesForTest(Request request) {
+ return findLeaves(sortRequest(request));
+ }
+
+ private List<Description> findLeaves(Request request) {
+ List<Description> results = new ArrayList<Description>();
+ findLeaves(null, request.getRunner().getDescription(), results);
+ return results;
+ }
+
+ private void findLeaves(Description parent, Description description, List<Description> results) {
+ if (description.getChildren().isEmpty()) {
+ if (description.toString().equals("warning(junit.framework.TestSuite$1)")) {
+ results.add(Description.createSuiteDescription(MALFORMED_JUNIT_3_TEST_CLASS_PREFIX + parent));
+ } else {
+ results.add(description);
+ }
+ } else {
+ for (Description each : description.getChildren()) {
+ findLeaves(description, each, results);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java
new file mode 100644
index 0000000..ab7443f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/max/MaxHistory.java
@@ -0,0 +1,178 @@
+package org.junit.experimental.max;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * Stores a subset of the history of each test:
+ * <ul>
+ * <li>Last failure timestamp
+ * <li>Duration of last execution
+ * </ul>
+ */
+public class MaxHistory implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Loads a {@link MaxHistory} from {@code file}, or generates a new one that
+ * will be saved to {@code file}.
+ */
+ public static MaxHistory forFolder(File file) {
+ if (file.exists()) {
+ try {
+ return readHistory(file);
+ } catch (CouldNotReadCoreException e) {
+ e.printStackTrace();
+ file.delete();
+ }
+ }
+ return new MaxHistory(file);
+ }
+
+ private static MaxHistory readHistory(File storedResults)
+ throws CouldNotReadCoreException {
+ try {
+ FileInputStream file = new FileInputStream(storedResults);
+ try {
+ ObjectInputStream stream = new ObjectInputStream(file);
+ try {
+ return (MaxHistory) stream.readObject();
+ } finally {
+ stream.close();
+ }
+ } finally {
+ file.close();
+ }
+ } catch (Exception e) {
+ throw new CouldNotReadCoreException(e);
+ }
+ }
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final Map<String, Long> fDurations = new HashMap<String, Long>();
+ private final Map<String, Long> fFailureTimestamps = new HashMap<String, Long>();
+ private final File fHistoryStore;
+
+ private MaxHistory(File storedResults) {
+ fHistoryStore = storedResults;
+ }
+
+ private void save() throws IOException {
+ ObjectOutputStream stream = null;
+ try {
+ stream = new ObjectOutputStream(new FileOutputStream(fHistoryStore));
+ stream.writeObject(this);
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ Long getFailureTimestamp(Description key) {
+ return fFailureTimestamps.get(key.toString());
+ }
+
+ void putTestFailureTimestamp(Description key, long end) {
+ fFailureTimestamps.put(key.toString(), end);
+ }
+
+ boolean isNewTest(Description key) {
+ return !fDurations.containsKey(key.toString());
+ }
+
+ Long getTestDuration(Description key) {
+ return fDurations.get(key.toString());
+ }
+
+ void putTestDuration(Description description, long duration) {
+ fDurations.put(description.toString(), duration);
+ }
+
+ private final class RememberingListener extends RunListener {
+ private long overallStart = System.currentTimeMillis();
+
+ private Map<Description, Long> starts = new HashMap<Description, Long>();
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ starts.put(description, System.nanoTime()); // Get most accurate
+ // possible time
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ long end = System.nanoTime();
+ long start = starts.get(description);
+ putTestDuration(description, end - start);
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ putTestFailureTimestamp(failure.getDescription(), overallStart);
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ save();
+ }
+ }
+
+ private class TestComparator implements Comparator<Description> {
+ public int compare(Description o1, Description o2) {
+ // Always prefer new tests
+ if (isNewTest(o1)) {
+ return -1;
+ }
+ if (isNewTest(o2)) {
+ return 1;
+ }
+ // Then most recently failed first
+ int result = getFailure(o2).compareTo(getFailure(o1));
+ return result != 0 ? result
+ // Then shorter tests first
+ : getTestDuration(o1).compareTo(getTestDuration(o2));
+ }
+
+ private Long getFailure(Description key) {
+ Long result = getFailureTimestamp(key);
+ if (result == null) {
+ return 0L; // 0 = "never failed (that I know about)"
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @return a listener that will update this history based on the test
+ * results reported.
+ */
+ public RunListener listener() {
+ return new RememberingListener();
+ }
+
+ /**
+ * @return a comparator that ranks tests based on the JUnit Max sorting
+ * rules, as described in the {@link MaxCore} class comment.
+ */
+ public Comparator<Description> testComparator() {
+ return new TestComparator();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java
new file mode 100644
index 0000000..e02eeae
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/FailureList.java
@@ -0,0 +1,28 @@
+package org.junit.experimental.results;
+
+import java.util.List;
+
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+class FailureList {
+ private final List<Failure> failures;
+
+ public FailureList(List<Failure> failures) {
+ this.failures = failures;
+ }
+
+ public Result result() {
+ Result result = new Result();
+ RunListener listener = result.createListener();
+ for (Failure failure : failures) {
+ try {
+ listener.testFailure(failure);
+ } catch (Exception e) {
+ throw new RuntimeException("I can't believe this happened");
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java
new file mode 100644
index 0000000..0f67766
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/PrintableResult.java
@@ -0,0 +1,72 @@
+package org.junit.experimental.results;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+/**
+ * A test result that prints nicely in error messages.
+ * This is only intended to be used in JUnit self-tests.
+ * For example:
+ *
+ * <pre>
+ * assertThat(testResult(HasExpectedException.class), isSuccessful());
+ * </pre>
+ */
+public class PrintableResult {
+ private Result result;
+
+ /**
+ * The result of running JUnit on {@code type}
+ */
+ public static PrintableResult testResult(Class<?> type) {
+ return testResult(Request.aClass(type));
+ }
+
+ /**
+ * The result of running JUnit on Request {@code request}
+ */
+ public static PrintableResult testResult(Request request) {
+ return new PrintableResult(new JUnitCore().run(request));
+ }
+
+ /**
+ * A result that includes the given {@code failures}
+ */
+ public PrintableResult(List<Failure> failures) {
+ this(new FailureList(failures).result());
+ }
+
+ private PrintableResult(Result result) {
+ this.result = result;
+ }
+
+ /**
+ * Returns the number of failures in this result.
+ */
+ public int failureCount() {
+ return result.getFailures().size();
+ }
+
+ /**
+ * Returns the failures in this result.
+ *
+ * @since 4.13
+ */
+ public List<Failure> failures() {
+ return result.getFailures();
+ }
+
+ @Override
+ public String toString() {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ new TextListener(new PrintStream(stream)).testRunFinished(result);
+ return stream.toString();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java
new file mode 100644
index 0000000..92f2e6b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/results/ResultMatchers.java
@@ -0,0 +1,99 @@
+package org.junit.experimental.results;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matchers on a PrintableResult, to enable JUnit self-tests.
+ * For example:
+ *
+ * <pre>
+ * assertThat(testResult(HasExpectedException.class), isSuccessful());
+ * </pre>
+ */
+public class ResultMatchers {
+
+ /**
+ * Do not instantiate.
+ * @deprecated will be private soon.
+ */
+ @Deprecated
+ public ResultMatchers() {
+ }
+
+ /**
+ * Matches if the tests are all successful
+ */
+ public static Matcher<PrintableResult> isSuccessful() {
+ return failureCountIs(0);
+ }
+
+ /**
+ * Matches if there are {@code count} failures
+ */
+ public static Matcher<PrintableResult> failureCountIs(final int count) {
+ return new TypeSafeMatcher<PrintableResult>() {
+ public void describeTo(Description description) {
+ description.appendText("has " + count + " failures");
+ }
+
+ @Override
+ public boolean matchesSafely(PrintableResult item) {
+ return item.failureCount() == count;
+ }
+ };
+ }
+
+ /**
+ * Matches if the result has exactly one failure, and it contains {@code string}
+ */
+ public static Matcher<Object> hasSingleFailureContaining(final String string) {
+ return new BaseMatcher<Object>() {
+ public boolean matches(Object item) {
+ return item.toString().contains(string) && failureCountIs(1).matches(item);
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("has single failure containing " + string);
+ }
+ };
+ }
+
+ /**
+ * Matches if the result has exactly one failure matching the given matcher.
+ *
+ * @since 4.13
+ */
+ public static Matcher<PrintableResult> hasSingleFailureMatching(final Matcher<Throwable> matcher) {
+ return new TypeSafeMatcher<PrintableResult>() {
+ @Override
+ public boolean matchesSafely(PrintableResult item) {
+ return item.failureCount() == 1 && matcher.matches(item.failures().get(0).getException());
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("has failure with exception matching ");
+ matcher.describeTo(description);
+ }
+ };
+ }
+
+ /**
+ * Matches if the result has one or more failures, and at least one of them
+ * contains {@code string}
+ */
+ public static Matcher<PrintableResult> hasFailureContaining(final String string) {
+ return new TypeSafeMatcher<PrintableResult>() {
+ @Override
+ public boolean matchesSafely(PrintableResult item) {
+ return item.failureCount() > 0 && item.toString().contains(string);
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("has failure containing " + string);
+ }
+ };
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java
new file mode 100644
index 0000000..610b970
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/runners/Enclosed.java
@@ -0,0 +1,45 @@
+package org.junit.experimental.runners;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runners.Suite;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * If you put tests in inner classes, Ant, for example, won't find them. By running the outer class
+ * with Enclosed, the tests in the inner classes will be run. You might put tests in inner classes
+ * to group them for convenience or to share constants. Abstract inner classes are ignored.
+ * <p>
+ * So, for example:
+ * <pre>
+ * @RunWith(Enclosed.class)
+ * public class ListTests {
+ * ...useful shared stuff...
+ * public static class OneKindOfListTest {...}
+ * public static class AnotherKind {...}
+ * abstract public static class Ignored {...}
+ * }
+ * </pre>
+ */
+public class Enclosed extends Suite {
+ /**
+ * Only called reflectively. Do not use programmatically.
+ */
+ public Enclosed(Class<?> klass, RunnerBuilder builder) throws Throwable {
+ super(builder, klass, filterAbstractClasses(klass.getClasses()));
+ }
+
+ private static Class<?>[] filterAbstractClasses(final Class<?>[] classes) {
+ final List<Class<?>> filteredList= new ArrayList<Class<?>>(classes.length);
+
+ for (final Class<?> clazz : classes) {
+ if (!Modifier.isAbstract(clazz.getModifiers())) {
+ filteredList.add(clazz);
+ }
+ }
+
+ return filteredList.toArray(new Class<?>[filteredList.size()]);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java
new file mode 100644
index 0000000..0a017bb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoint.java
@@ -0,0 +1,56 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating an field or method with @DataPoint will cause the field value
+ * or the value returned by the method to be used as a potential parameter for
+ * theories in that class, when run with the
+ * {@link org.junit.experimental.theories.Theories Theories} runner.
+ * <p>
+ * A DataPoint is only considered as a potential value for parameters for
+ * which its type is assignable. When multiple {@code DataPoint}s exist
+ * with overlapping types more control can be obtained by naming each DataPoint
+ * using the value of this annotation, e.g. with
+ * <code>@DataPoint({"dataset1", "dataset2"})</code>, and then specifying
+ * which named set to consider as potential values for each parameter using the
+ * {@link org.junit.experimental.theories.FromDataPoints @FromDataPoints}
+ * annotation.
+ * <p>
+ * Parameters with no specified source (i.e. without @FromDataPoints or
+ * other {@link org.junit.experimental.theories.ParametersSuppliedBy
+ * @ParameterSuppliedBy} annotations) will use all {@code DataPoint}s that are
+ * assignable to the parameter type as potential values, including named sets of
+ * {@code DataPoint}s.
+ *
+ * <pre>
+ * @DataPoint
+ * public static String dataPoint = "value";
+ *
+ * @DataPoint("generated")
+ * public static String generatedDataPoint() {
+ * return "generated value";
+ * }
+ *
+ * @Theory
+ * public void theoryMethod(String param) {
+ * ...
+ * }
+ * </pre>
+ *
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({FIELD, METHOD})
+public @interface DataPoint {
+ String[] value() default {};
+ Class<? extends Throwable>[] ignoredExceptions() default {};
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java
new file mode 100644
index 0000000..b47461b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/DataPoints.java
@@ -0,0 +1,64 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating an array or iterable-typed field or method with @DataPoints
+ * will cause the values in the array or iterable given to be used as potential
+ * parameters for theories in that class when run with the
+ * {@link org.junit.experimental.theories.Theories Theories} runner.
+ * <p>
+ * DataPoints will only be considered as potential values for parameters for
+ * which their types are assignable. When multiple sets of DataPoints exist with
+ * overlapping types more control can be obtained by naming the DataPoints using
+ * the value of this annotation, e.g. with
+ * <code>@DataPoints({"dataset1", "dataset2"})</code>, and then specifying
+ * which named set to consider as potential values for each parameter using the
+ * {@link org.junit.experimental.theories.FromDataPoints @FromDataPoints}
+ * annotation.
+ * <p>
+ * Parameters with no specified source (i.e. without @FromDataPoints or
+ * other {@link org.junit.experimental.theories.ParametersSuppliedBy
+ * @ParameterSuppliedBy} annotations) will use all DataPoints that are
+ * assignable to the parameter type as potential values, including named sets of
+ * DataPoints.
+ * <p>
+ * DataPoints methods whose array types aren't assignable from the target
+ * parameter type (and so can't possibly return relevant values) will not be
+ * called when generating values for that parameter. Iterable-typed datapoints
+ * methods must always be called though, as this information is not available
+ * here after generic type erasure, so expensive methods returning iterable
+ * datapoints are a bad idea.
+ *
+ * <pre>
+ * @DataPoints
+ * public static String[] dataPoints = new String[] { ... };
+ *
+ * @DataPoints
+ * public static String[] generatedDataPoints() {
+ * return new String[] { ... };
+ * }
+ *
+ * @Theory
+ * public void theoryMethod(String param) {
+ * ...
+ * }
+ * </pre>
+ *
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ FIELD, METHOD })
+public @interface DataPoints {
+ String[] value() default {};
+
+ Class<? extends Throwable>[] ignoredExceptions() default {};
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java
new file mode 100644
index 0000000..2b149ca
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/FromDataPoints.java
@@ -0,0 +1,54 @@
+package org.junit.experimental.theories;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.experimental.theories.internal.SpecificDataPointsSupplier;
+
+/**
+ * Annotating a parameter of a {@link org.junit.experimental.theories.Theory
+ * @Theory} method with <code>@FromDataPoints</code> will limit the
+ * datapoints considered as potential values for that parameter to just the
+ * {@link org.junit.experimental.theories.DataPoints DataPoints} with the given
+ * name. DataPoint names can be given as the value parameter of the
+ * @DataPoints annotation.
+ * <p>
+ * DataPoints without names will not be considered as values for any parameters
+ * annotated with @FromDataPoints.
+ * <pre>
+ * @DataPoints
+ * public static String[] unnamed = new String[] { ... };
+ *
+ * @DataPoints("regexes")
+ * public static String[] regexStrings = new String[] { ... };
+ *
+ * @DataPoints({"forMatching", "alphanumeric"})
+ * public static String[] testStrings = new String[] { ... };
+ *
+ * @Theory
+ * public void stringTheory(String param) {
+ * // This will be called with every value in 'regexStrings',
+ * // 'testStrings' and 'unnamed'.
+ * }
+ *
+ * @Theory
+ * public void regexTheory(@FromDataPoints("regexes") String regex,
+ * @FromDataPoints("forMatching") String value) {
+ * // This will be called with only the values in 'regexStrings' as
+ * // regex, only the values in 'testStrings' as value, and none
+ * // of the values in 'unnamed'.
+ * }
+ * </pre>
+ *
+ * @see org.junit.experimental.theories.Theory
+ * @see org.junit.experimental.theories.DataPoint
+ * @see org.junit.experimental.theories.DataPoints
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+@ParametersSuppliedBy(SpecificDataPointsSupplier.class)
+public @interface FromDataPoints {
+ String value();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java
new file mode 100644
index 0000000..cf22583
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSignature.java
@@ -0,0 +1,134 @@
+package org.junit.experimental.theories;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ParameterSignature {
+
+ private static final Map<Class<?>, Class<?>> CONVERTABLE_TYPES_MAP = buildConvertableTypesMap();
+
+ private static Map<Class<?>, Class<?>> buildConvertableTypesMap() {
+ Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
+
+ putSymmetrically(map, boolean.class, Boolean.class);
+ putSymmetrically(map, byte.class, Byte.class);
+ putSymmetrically(map, short.class, Short.class);
+ putSymmetrically(map, char.class, Character.class);
+ putSymmetrically(map, int.class, Integer.class);
+ putSymmetrically(map, long.class, Long.class);
+ putSymmetrically(map, float.class, Float.class);
+ putSymmetrically(map, double.class, Double.class);
+
+ return Collections.unmodifiableMap(map);
+ }
+
+ private static <T> void putSymmetrically(Map<T, T> map, T a, T b) {
+ map.put(a, b);
+ map.put(b, a);
+ }
+
+ public static ArrayList<ParameterSignature> signatures(Method method) {
+ return signatures(method.getParameterTypes(), method
+ .getParameterAnnotations());
+ }
+
+ public static List<ParameterSignature> signatures(Constructor<?> constructor) {
+ return signatures(constructor.getParameterTypes(), constructor
+ .getParameterAnnotations());
+ }
+
+ private static ArrayList<ParameterSignature> signatures(
+ Class<?>[] parameterTypes, Annotation[][] parameterAnnotations) {
+ ArrayList<ParameterSignature> sigs = new ArrayList<ParameterSignature>();
+ for (int i = 0; i < parameterTypes.length; i++) {
+ sigs.add(new ParameterSignature(parameterTypes[i],
+ parameterAnnotations[i]));
+ }
+ return sigs;
+ }
+
+ private final Class<?> type;
+
+ private final Annotation[] annotations;
+
+ private ParameterSignature(Class<?> type, Annotation[] annotations) {
+ this.type = type;
+ this.annotations = annotations;
+ }
+
+ public boolean canAcceptValue(Object candidate) {
+ return (candidate == null) ? !type.isPrimitive() : canAcceptType(candidate.getClass());
+ }
+
+ public boolean canAcceptType(Class<?> candidate) {
+ return type.isAssignableFrom(candidate) ||
+ isAssignableViaTypeConversion(type, candidate);
+ }
+
+ public boolean canPotentiallyAcceptType(Class<?> candidate) {
+ return candidate.isAssignableFrom(type) ||
+ isAssignableViaTypeConversion(candidate, type) ||
+ canAcceptType(candidate);
+ }
+
+ private boolean isAssignableViaTypeConversion(Class<?> targetType, Class<?> candidate) {
+ if (CONVERTABLE_TYPES_MAP.containsKey(candidate)) {
+ Class<?> wrapperClass = CONVERTABLE_TYPES_MAP.get(candidate);
+ return targetType.isAssignableFrom(wrapperClass);
+ } else {
+ return false;
+ }
+ }
+
+ public Class<?> getType() {
+ return type;
+ }
+
+ public List<Annotation> getAnnotations() {
+ return Arrays.asList(annotations);
+ }
+
+ public boolean hasAnnotation(Class<? extends Annotation> type) {
+ return getAnnotation(type) != null;
+ }
+
+ public <T extends Annotation> T findDeepAnnotation(Class<T> annotationType) {
+ Annotation[] annotations2 = annotations;
+ return findDeepAnnotation(annotations2, annotationType, 3);
+ }
+
+ private <T extends Annotation> T findDeepAnnotation(
+ Annotation[] annotations, Class<T> annotationType, int depth) {
+ if (depth == 0) {
+ return null;
+ }
+ for (Annotation each : annotations) {
+ if (annotationType.isInstance(each)) {
+ return annotationType.cast(each);
+ }
+ Annotation candidate = findDeepAnnotation(each.annotationType()
+ .getAnnotations(), annotationType, depth - 1);
+ if (candidate != null) {
+ return annotationType.cast(candidate);
+ }
+ }
+
+ return null;
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ for (Annotation each : getAnnotations()) {
+ if (annotationType.isInstance(each)) {
+ return annotationType.cast(each);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java
new file mode 100644
index 0000000..bac8b34
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParameterSupplier.java
@@ -0,0 +1,43 @@
+package org.junit.experimental.theories;
+
+import java.util.List;
+
+/**
+ * Abstract parent class for suppliers of input data points for theories. Extend this class to customize how {@link
+ * org.junit.experimental.theories.Theories Theories} runner
+ * finds accepted data points. Then use your class together with <b>@ParametersSuppliedBy</b> on input
+ * parameters for theories.
+ *
+ * <p>
+ * For example, here is a supplier for values between two integers, and an annotation that references it:
+ *
+ * <pre>
+ * @Retention(RetentionPolicy.RUNTIME)
+ * <b>@ParametersSuppliedBy</b>(BetweenSupplier.class)
+ * public @interface Between {
+ * int first();
+ *
+ * int last();
+ * }
+ *
+ * public static class BetweenSupplier extends <b>ParameterSupplier</b> {
+ * @Override
+ * public List<<b>PotentialAssignment</b>> getValueSources(<b>ParameterSignature</b> sig) {
+ * List<<b>PotentialAssignment</b>> list = new ArrayList<PotentialAssignment>();
+ * Between annotation = (Between) sig.getSupplierAnnotation();
+ *
+ * for (int i = annotation.first(); i <= annotation.last(); i++)
+ * list.add(<b>PotentialAssignment</b>.forValue("ints", i));
+ * return list;
+ * }
+ * }
+ * </pre>
+ * </p>
+ *
+ * @see org.junit.experimental.theories.ParametersSuppliedBy
+ * @see org.junit.experimental.theories.Theories
+ * @see org.junit.experimental.theories.FromDataPoints
+ */
+public abstract class ParameterSupplier {
+ public abstract List<PotentialAssignment> getValueSources(ParameterSignature sig) throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java
new file mode 100644
index 0000000..846a39e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java
@@ -0,0 +1,48 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotating a {@link org.junit.experimental.theories.Theory Theory} method
+ * parameter with @ParametersSuppliedBy causes it to be supplied with
+ * values from the named
+ * {@link org.junit.experimental.theories.ParameterSupplier ParameterSupplier}
+ * when run as a theory by the {@link org.junit.experimental.theories.Theories
+ * Theories} runner.
+ *
+ * In addition, annotations themselves can be annotated with
+ * @ParametersSuppliedBy, and then used similarly. ParameterSuppliedBy
+ * annotations on parameters are detected by searching up this hierarchy such
+ * that these act as syntactic sugar, making:
+ *
+ * <pre>
+ * @ParametersSuppliedBy(Supplier.class)
+ * public @interface SpecialParameter { }
+ *
+ * @Theory
+ * public void theoryMethod(@SpecialParameter String param) {
+ * ...
+ * }
+ * </pre>
+ *
+ * equivalent to:
+ *
+ * <pre>
+ * @Theory
+ * public void theoryMethod(@ParametersSuppliedBy(Supplier.class) String param) {
+ * ...
+ * }
+ * </pre>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ANNOTATION_TYPE, PARAMETER })
+public @interface ParametersSuppliedBy {
+
+ Class<? extends ParameterSupplier> value();
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java
new file mode 100644
index 0000000..18ca07a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/PotentialAssignment.java
@@ -0,0 +1,52 @@
+package org.junit.experimental.theories;
+
+import static java.lang.String.format;
+
+public abstract class PotentialAssignment {
+ public static class CouldNotGenerateValueException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public CouldNotGenerateValueException() {
+ }
+
+ public CouldNotGenerateValueException(Throwable e) {
+ super(e);
+ }
+ }
+
+ public static PotentialAssignment forValue(final String name, final Object value) {
+ return new PotentialAssignment() {
+ @Override
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return format("[%s]", value);
+ }
+
+ @Override
+ public String getDescription() {
+ String valueString;
+
+ if (value == null) {
+ valueString = "null";
+ } else {
+ try {
+ valueString = format("\"%s\"", value);
+ } catch (Throwable e) {
+ valueString = format("[toString() threw %s: %s]",
+ e.getClass().getSimpleName(), e.getMessage());
+ }
+ }
+
+ return format("%s <from %s>", valueString, name);
+ }
+ };
+ }
+
+ public abstract Object getValue() throws CouldNotGenerateValueException;
+
+ public abstract String getDescription() throws CouldNotGenerateValueException;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java
new file mode 100644
index 0000000..ac88a36
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theories.java
@@ -0,0 +1,310 @@
+package org.junit.experimental.theories;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.experimental.theories.internal.Assignments;
+import org.junit.experimental.theories.internal.ParameterizedAssertionError;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+/**
+ * The Theories runner allows to test a certain functionality against a subset of an infinite set of data points.
+ * <p>
+ * A Theory is a piece of functionality (a method) that is executed against several data inputs called data points.
+ * To make a test method a theory you mark it with <b>@Theory</b>. To create a data point you create a public
+ * field in your test class and mark it with <b>@DataPoint</b>. The Theories runner then executes your test
+ * method as many times as the number of data points declared, providing a different data point as
+ * the input argument on each invocation.
+ * </p>
+ * <p>
+ * A Theory differs from standard test method in that it captures some aspect of the intended behavior in possibly
+ * infinite numbers of scenarios which corresponds to the number of data points declared. Using assumptions and
+ * assertions properly together with covering multiple scenarios with different data points can make your tests more
+ * flexible and bring them closer to scientific theories (hence the name).
+ * </p>
+ * <p>
+ * For example:
+ * <pre>
+ *
+ * @RunWith(<b>Theories.class</b>)
+ * public class UserTest {
+ * <b>@DataPoint</b>
+ * public static String GOOD_USERNAME = "optimus";
+ * <b>@DataPoint</b>
+ * public static String USERNAME_WITH_SLASH = "optimus/prime";
+ *
+ * <b>@Theory</b>
+ * public void filenameIncludesUsername(String username) {
+ * assumeThat(username, not(containsString("/")));
+ * assertThat(new User(username).configFileName(), containsString(username));
+ * }
+ * }
+ * </pre>
+ * This makes it clear that the username should be included in the config file name,
+ * only if it doesn't contain a slash. Another test or theory might define what happens when a username does contain
+ * a slash. <code>UserTest</code> will attempt to run <code>filenameIncludesUsername</code> on every compatible data
+ * point defined in the class. If any of the assumptions fail, the data point is silently ignored. If all of the
+ * assumptions pass, but an assertion fails, the test fails. If no parameters can be found that satisfy all assumptions, the test fails.
+ * <p>
+ * Defining general statements as theories allows data point reuse across a bunch of functionality tests and also
+ * allows automated tools to search for new, unexpected data points that expose bugs.
+ * </p>
+ * <p>
+ * The support for Theories has been absorbed from the Popper project, and more complete documentation can be found
+ * from that projects archived documentation.
+ * </p>
+ *
+ * @see <a href="http://web.archive.org/web/20071012143326/popper.tigris.org/tutorial.html">Archived Popper project documentation</a>
+ * @see <a href="http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf">Paper on Theories</a>
+ */
+public class Theories extends BlockJUnit4ClassRunner {
+ public Theories(Class<?> klass) throws InitializationError {
+ super(klass);
+ }
+
+ /** @since 4.13 */
+ protected Theories(TestClass testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ @Override
+ protected void collectInitializationErrors(List<Throwable> errors) {
+ super.collectInitializationErrors(errors);
+ validateDataPointFields(errors);
+ validateDataPointMethods(errors);
+ }
+
+ private void validateDataPointFields(List<Throwable> errors) {
+ Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
+
+ for (Field field : fields) {
+ if (field.getAnnotation(DataPoint.class) == null && field.getAnnotation(DataPoints.class) == null) {
+ continue;
+ }
+ if (!Modifier.isStatic(field.getModifiers())) {
+ errors.add(new Error("DataPoint field " + field.getName() + " must be static"));
+ }
+ if (!Modifier.isPublic(field.getModifiers())) {
+ errors.add(new Error("DataPoint field " + field.getName() + " must be public"));
+ }
+ }
+ }
+
+ private void validateDataPointMethods(List<Throwable> errors) {
+ Method[] methods = getTestClass().getJavaClass().getDeclaredMethods();
+
+ for (Method method : methods) {
+ if (method.getAnnotation(DataPoint.class) == null && method.getAnnotation(DataPoints.class) == null) {
+ continue;
+ }
+ if (!Modifier.isStatic(method.getModifiers())) {
+ errors.add(new Error("DataPoint method " + method.getName() + " must be static"));
+ }
+ if (!Modifier.isPublic(method.getModifiers())) {
+ errors.add(new Error("DataPoint method " + method.getName() + " must be public"));
+ }
+ }
+ }
+
+ @Override
+ protected void validateConstructor(List<Throwable> errors) {
+ validateOnlyOneConstructor(errors);
+ }
+
+ @Override
+ protected void validateTestMethods(List<Throwable> errors) {
+ for (FrameworkMethod each : computeTestMethods()) {
+ if (each.getAnnotation(Theory.class) != null) {
+ each.validatePublicVoid(false, errors);
+ each.validateNoTypeParametersOnArgs(errors);
+ } else {
+ each.validatePublicVoidNoArg(false, errors);
+ }
+
+ for (ParameterSignature signature : ParameterSignature.signatures(each.getMethod())) {
+ ParametersSuppliedBy annotation = signature.findDeepAnnotation(ParametersSuppliedBy.class);
+ if (annotation != null) {
+ validateParameterSupplier(annotation.value(), errors);
+ }
+ }
+ }
+ }
+
+ private void validateParameterSupplier(Class<? extends ParameterSupplier> supplierClass, List<Throwable> errors) {
+ Constructor<?>[] constructors = supplierClass.getConstructors();
+
+ if (constructors.length != 1) {
+ errors.add(new Error("ParameterSupplier " + supplierClass.getName() +
+ " must have only one constructor (either empty or taking only a TestClass)"));
+ } else {
+ Class<?>[] paramTypes = constructors[0].getParameterTypes();
+ if (!(paramTypes.length == 0) && !paramTypes[0].equals(TestClass.class)) {
+ errors.add(new Error("ParameterSupplier " + supplierClass.getName() +
+ " constructor must take either nothing or a single TestClass instance"));
+ }
+ }
+ }
+
+ @Override
+ protected List<FrameworkMethod> computeTestMethods() {
+ List<FrameworkMethod> testMethods = new ArrayList<FrameworkMethod>(super.computeTestMethods());
+ List<FrameworkMethod> theoryMethods = getTestClass().getAnnotatedMethods(Theory.class);
+ testMethods.removeAll(theoryMethods);
+ testMethods.addAll(theoryMethods);
+ return testMethods;
+ }
+
+ @Override
+ public Statement methodBlock(final FrameworkMethod method) {
+ return new TheoryAnchor(method, getTestClass());
+ }
+
+ public static class TheoryAnchor extends Statement {
+ private int successes = 0;
+
+ private final FrameworkMethod testMethod;
+ private final TestClass testClass;
+
+ private List<AssumptionViolatedException> fInvalidParameters = new ArrayList<AssumptionViolatedException>();
+
+ public TheoryAnchor(FrameworkMethod testMethod, TestClass testClass) {
+ this.testMethod = testMethod;
+ this.testClass = testClass;
+ }
+
+ private TestClass getTestClass() {
+ return testClass;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ runWithAssignment(Assignments.allUnassigned(
+ testMethod.getMethod(), getTestClass()));
+
+ //if this test method is not annotated with Theory, then no successes is a valid case
+ boolean hasTheoryAnnotation = testMethod.getAnnotation(Theory.class) != null;
+ if (successes == 0 && hasTheoryAnnotation) {
+ Assert
+ .fail("Never found parameters that satisfied method assumptions. Violated assumptions: "
+ + fInvalidParameters);
+ }
+ }
+
+ protected void runWithAssignment(Assignments parameterAssignment)
+ throws Throwable {
+ if (!parameterAssignment.isComplete()) {
+ runWithIncompleteAssignment(parameterAssignment);
+ } else {
+ runWithCompleteAssignment(parameterAssignment);
+ }
+ }
+
+ protected void runWithIncompleteAssignment(Assignments incomplete)
+ throws Throwable {
+ for (PotentialAssignment source : incomplete
+ .potentialsForNextUnassigned()) {
+ runWithAssignment(incomplete.assignNext(source));
+ }
+ }
+
+ protected void runWithCompleteAssignment(final Assignments complete)
+ throws Throwable {
+ new BlockJUnit4ClassRunner(getTestClass()) {
+ @Override
+ protected void collectInitializationErrors(
+ List<Throwable> errors) {
+ // do nothing
+ }
+
+ @Override
+ public Statement methodBlock(FrameworkMethod method) {
+ final Statement statement = super.methodBlock(method);
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ statement.evaluate();
+ handleDataPointSuccess();
+ } catch (AssumptionViolatedException e) {
+ handleAssumptionViolation(e);
+ } catch (Throwable e) {
+ reportParameterizedError(e, complete
+ .getArgumentStrings(nullsOk()));
+ }
+ }
+
+ };
+ }
+
+ @Override
+ protected Statement methodInvoker(FrameworkMethod method, Object test) {
+ return methodCompletesWithParameters(method, complete, test);
+ }
+
+ @Override
+ public Object createTest() throws Exception {
+ Object[] params = complete.getConstructorArguments();
+
+ if (!nullsOk()) {
+ Assume.assumeNotNull(params);
+ }
+
+ return getTestClass().getOnlyConstructor().newInstance(params);
+ }
+ }.methodBlock(testMethod).evaluate();
+ }
+
+ private Statement methodCompletesWithParameters(
+ final FrameworkMethod method, final Assignments complete, final Object freshInstance) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ final Object[] values = complete.getMethodArguments();
+
+ if (!nullsOk()) {
+ Assume.assumeNotNull(values);
+ }
+
+ method.invokeExplosively(freshInstance, values);
+ }
+ };
+ }
+
+ protected void handleAssumptionViolation(AssumptionViolatedException e) {
+ fInvalidParameters.add(e);
+ }
+
+ protected void reportParameterizedError(Throwable e, Object... params)
+ throws Throwable {
+ if (params.length == 0) {
+ throw e;
+ }
+ throw new ParameterizedAssertionError(e, testMethod.getName(),
+ params);
+ }
+
+ private boolean nullsOk() {
+ Theory annotation = testMethod.getMethod().getAnnotation(
+ Theory.class);
+ if (annotation == null) {
+ return false;
+ }
+ return annotation.nullsAccepted();
+ }
+
+ protected void handleDataPointSuccess() {
+ successes++;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java
new file mode 100644
index 0000000..0b9f2c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/Theory.java
@@ -0,0 +1,18 @@
+package org.junit.experimental.theories;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks test methods that should be read as theories by the {@link org.junit.experimental.theories.Theories Theories} runner.
+ *
+ * @see org.junit.experimental.theories.Theories
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(METHOD)
+public @interface Theory {
+ boolean nullsAccepted() default true;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
new file mode 100644
index 0000000..f15fb28
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
@@ -0,0 +1,204 @@
+package org.junit.experimental.theories.internal;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assume;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+/**
+ * Supplies Theory parameters based on all public members of the target class.
+ */
+public class AllMembersSupplier extends ParameterSupplier {
+ static class MethodParameterValue extends PotentialAssignment {
+ private final FrameworkMethod method;
+
+ private MethodParameterValue(FrameworkMethod dataPointMethod) {
+ method = dataPointMethod;
+ }
+
+ @Override
+ public Object getValue() throws CouldNotGenerateValueException {
+ try {
+ return method.invokeExplosively(null);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(
+ "unexpected: argument length is checked");
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(
+ "unexpected: getMethods returned an inaccessible method");
+ } catch (Throwable throwable) {
+ DataPoint annotation = method.getAnnotation(DataPoint.class);
+ Assume.assumeTrue(annotation == null || !isAssignableToAnyOf(annotation.ignoredExceptions(), throwable));
+
+ throw new CouldNotGenerateValueException(throwable);
+ }
+ }
+
+ @Override
+ public String getDescription() throws CouldNotGenerateValueException {
+ return method.getName();
+ }
+ }
+
+ private final TestClass clazz;
+
+ /**
+ * Constructs a new supplier for {@code type}
+ */
+ public AllMembersSupplier(TestClass type) {
+ clazz = type;
+ }
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) throws Throwable {
+ List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
+
+ addSinglePointFields(sig, list);
+ addMultiPointFields(sig, list);
+ addSinglePointMethods(sig, list);
+ addMultiPointMethods(sig, list);
+
+ return list;
+ }
+
+ private void addMultiPointMethods(ParameterSignature sig, List<PotentialAssignment> list) throws Throwable {
+ for (FrameworkMethod dataPointsMethod : getDataPointsMethods(sig)) {
+ Class<?> returnType = dataPointsMethod.getReturnType();
+
+ if ((returnType.isArray() && sig.canPotentiallyAcceptType(returnType.getComponentType())) ||
+ Iterable.class.isAssignableFrom(returnType)) {
+ try {
+ addDataPointsValues(returnType, sig, dataPointsMethod.getName(), list,
+ dataPointsMethod.invokeExplosively(null));
+ } catch (Throwable throwable) {
+ DataPoints annotation = dataPointsMethod.getAnnotation(DataPoints.class);
+ if (annotation != null && isAssignableToAnyOf(annotation.ignoredExceptions(), throwable)) {
+ return;
+ } else {
+ throw throwable;
+ }
+ }
+ }
+ }
+ }
+
+ private void addSinglePointMethods(ParameterSignature sig, List<PotentialAssignment> list) {
+ for (FrameworkMethod dataPointMethod : getSingleDataPointMethods(sig)) {
+ if (sig.canAcceptType(dataPointMethod.getType())) {
+ list.add(new MethodParameterValue(dataPointMethod));
+ }
+ }
+ }
+
+ private void addMultiPointFields(ParameterSignature sig, List<PotentialAssignment> list) {
+ for (final Field field : getDataPointsFields(sig)) {
+ Class<?> type = field.getType();
+ addDataPointsValues(type, sig, field.getName(), list, getStaticFieldValue(field));
+ }
+ }
+
+ private void addSinglePointFields(ParameterSignature sig, List<PotentialAssignment> list) {
+ for (final Field field : getSingleDataPointFields(sig)) {
+ Object value = getStaticFieldValue(field);
+
+ if (sig.canAcceptValue(value)) {
+ list.add(PotentialAssignment.forValue(field.getName(), value));
+ }
+ }
+ }
+
+ private void addDataPointsValues(Class<?> type, ParameterSignature sig, String name,
+ List<PotentialAssignment> list, Object value) {
+ if (type.isArray()) {
+ addArrayValues(sig, name, list, value);
+ }
+ else if (Iterable.class.isAssignableFrom(type)) {
+ addIterableValues(sig, name, list, (Iterable<?>) value);
+ }
+ }
+
+ private void addArrayValues(ParameterSignature sig, String name, List<PotentialAssignment> list, Object array) {
+ for (int i = 0; i < Array.getLength(array); i++) {
+ Object value = Array.get(array, i);
+ if (sig.canAcceptValue(value)) {
+ list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
+ }
+ }
+ }
+
+ private void addIterableValues(ParameterSignature sig, String name, List<PotentialAssignment> list, Iterable<?> iterable) {
+ Iterator<?> iterator = iterable.iterator();
+ int i = 0;
+ while (iterator.hasNext()) {
+ Object value = iterator.next();
+ if (sig.canAcceptValue(value)) {
+ list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
+ }
+ i += 1;
+ }
+ }
+
+ private Object getStaticFieldValue(final Field field) {
+ try {
+ return field.get(null);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(
+ "unexpected: field from getClass doesn't exist on object");
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(
+ "unexpected: getFields returned an inaccessible field");
+ }
+ }
+
+ private static boolean isAssignableToAnyOf(Class<?>[] typeArray, Object target) {
+ for (Class<?> type : typeArray) {
+ if (type.isAssignableFrom(target.getClass())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected Collection<FrameworkMethod> getDataPointsMethods(ParameterSignature sig) {
+ return clazz.getAnnotatedMethods(DataPoints.class);
+ }
+
+ protected Collection<Field> getSingleDataPointFields(ParameterSignature sig) {
+ List<FrameworkField> fields = clazz.getAnnotatedFields(DataPoint.class);
+ Collection<Field> validFields = new ArrayList<Field>();
+
+ for (FrameworkField frameworkField : fields) {
+ validFields.add(frameworkField.getField());
+ }
+
+ return validFields;
+ }
+
+ protected Collection<Field> getDataPointsFields(ParameterSignature sig) {
+ List<FrameworkField> fields = clazz.getAnnotatedFields(DataPoints.class);
+ Collection<Field> validFields = new ArrayList<Field>();
+
+ for (FrameworkField frameworkField : fields) {
+ validFields.add(frameworkField.getField());
+ }
+
+ return validFields;
+ }
+
+ protected Collection<FrameworkMethod> getSingleDataPointMethods(ParameterSignature sig) {
+ return clazz.getAnnotatedMethods(DataPoint.class);
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java
new file mode 100644
index 0000000..6626797
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/Assignments.java
@@ -0,0 +1,153 @@
+package org.junit.experimental.theories.internal;
+
+import static java.util.Collections.emptyList;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.ParametersSuppliedBy;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException;
+import org.junit.runners.model.TestClass;
+
+/**
+ * A potentially incomplete list of value assignments for a method's formal
+ * parameters
+ */
+public class Assignments {
+ private final List<PotentialAssignment> assigned;
+
+ private final List<ParameterSignature> unassigned;
+
+ private final TestClass clazz;
+
+ private Assignments(List<PotentialAssignment> assigned,
+ List<ParameterSignature> unassigned, TestClass clazz) {
+ this.unassigned = unassigned;
+ this.assigned = assigned;
+ this.clazz = clazz;
+ }
+
+ /**
+ * Returns a new assignment list for {@code testMethod}, with no params
+ * assigned.
+ */
+ public static Assignments allUnassigned(Method testMethod,
+ TestClass testClass) {
+ List<ParameterSignature> signatures;
+ signatures = ParameterSignature.signatures(testClass
+ .getOnlyConstructor());
+ signatures.addAll(ParameterSignature.signatures(testMethod));
+ return new Assignments(new ArrayList<PotentialAssignment>(),
+ signatures, testClass);
+ }
+
+ public boolean isComplete() {
+ return unassigned.isEmpty();
+ }
+
+ public ParameterSignature nextUnassigned() {
+ return unassigned.get(0);
+ }
+
+ public Assignments assignNext(PotentialAssignment source) {
+ List<PotentialAssignment> potentialAssignments = new ArrayList<PotentialAssignment>(assigned);
+ potentialAssignments.add(source);
+
+ return new Assignments(potentialAssignments, unassigned.subList(1,
+ unassigned.size()), clazz);
+ }
+
+ public Object[] getActualValues(int start, int stop)
+ throws CouldNotGenerateValueException {
+ Object[] values = new Object[stop - start];
+ for (int i = start; i < stop; i++) {
+ values[i - start] = assigned.get(i).getValue();
+ }
+ return values;
+ }
+
+ public List<PotentialAssignment> potentialsForNextUnassigned()
+ throws Throwable {
+ ParameterSignature unassigned = nextUnassigned();
+ List<PotentialAssignment> assignments = getSupplier(unassigned).getValueSources(unassigned);
+
+ if (assignments.isEmpty()) {
+ assignments = generateAssignmentsFromTypeAlone(unassigned);
+ }
+
+ return assignments;
+ }
+
+ private List<PotentialAssignment> generateAssignmentsFromTypeAlone(ParameterSignature unassigned) {
+ Class<?> paramType = unassigned.getType();
+
+ if (paramType.isEnum()) {
+ return new EnumSupplier(paramType).getValueSources(unassigned);
+ } else if (paramType.equals(Boolean.class) || paramType.equals(boolean.class)) {
+ return new BooleanSupplier().getValueSources(unassigned);
+ } else {
+ return emptyList();
+ }
+ }
+
+ private ParameterSupplier getSupplier(ParameterSignature unassigned)
+ throws Exception {
+ ParametersSuppliedBy annotation = unassigned
+ .findDeepAnnotation(ParametersSuppliedBy.class);
+
+ if (annotation != null) {
+ return buildParameterSupplierFromClass(annotation.value());
+ } else {
+ return new AllMembersSupplier(clazz);
+ }
+ }
+
+ private ParameterSupplier buildParameterSupplierFromClass(
+ Class<? extends ParameterSupplier> cls) throws Exception {
+ Constructor<?>[] supplierConstructors = cls.getConstructors();
+
+ for (Constructor<?> constructor : supplierConstructors) {
+ Class<?>[] parameterTypes = constructor.getParameterTypes();
+ if (parameterTypes.length == 1
+ && parameterTypes[0].equals(TestClass.class)) {
+ return (ParameterSupplier) constructor.newInstance(clazz);
+ }
+ }
+
+ return cls.newInstance();
+ }
+
+ public Object[] getConstructorArguments()
+ throws CouldNotGenerateValueException {
+ return getActualValues(0, getConstructorParameterCount());
+ }
+
+ public Object[] getMethodArguments() throws CouldNotGenerateValueException {
+ return getActualValues(getConstructorParameterCount(), assigned.size());
+ }
+
+ public Object[] getAllArguments() throws CouldNotGenerateValueException {
+ return getActualValues(0, assigned.size());
+ }
+
+ private int getConstructorParameterCount() {
+ List<ParameterSignature> signatures = ParameterSignature
+ .signatures(clazz.getOnlyConstructor());
+ int constructorParameterCount = signatures.size();
+ return constructorParameterCount;
+ }
+
+ public Object[] getArgumentStrings(boolean nullsOk)
+ throws CouldNotGenerateValueException {
+ Object[] values = new Object[assigned.size()];
+ for (int i = 0; i < values.length; i++) {
+ values[i] = assigned.get(i).getDescription();
+ }
+ return values;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java
new file mode 100644
index 0000000..5f7032f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/BooleanSupplier.java
@@ -0,0 +1,18 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+public class BooleanSupplier extends ParameterSupplier {
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ return Arrays.asList(PotentialAssignment.forValue("true", true),
+ PotentialAssignment.forValue("false", false));
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java
new file mode 100644
index 0000000..1f3ab90
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/EnumSupplier.java
@@ -0,0 +1,30 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+public class EnumSupplier extends ParameterSupplier {
+
+ private Class<?> enumType;
+
+ public EnumSupplier(Class<?> enumType) {
+ this.enumType = enumType;
+ }
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ Object[] enumValues = enumType.getEnumConstants();
+
+ List<PotentialAssignment> assignments = new ArrayList<PotentialAssignment>();
+ for (Object value : enumValues) {
+ assignments.add(PotentialAssignment.forValue(value.toString(), value));
+ }
+
+ return assignments;
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java
new file mode 100644
index 0000000..5b9e947
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java
@@ -0,0 +1,50 @@
+package org.junit.experimental.theories.internal;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class ParameterizedAssertionError extends AssertionError {
+ private static final long serialVersionUID = 1L;
+
+ public ParameterizedAssertionError(Throwable targetException,
+ String methodName, Object... params) {
+ super(String.format("%s(%s)", methodName, join(", ", params)));
+ this.initCause(targetException);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ParameterizedAssertionError && toString().equals(obj.toString());
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ public static String join(String delimiter, Object... params) {
+ return join(delimiter, Arrays.asList(params));
+ }
+
+ public static String join(String delimiter, Collection<Object> values) {
+ StringBuilder sb = new StringBuilder();
+ Iterator<Object> iter = values.iterator();
+ while (iter.hasNext()) {
+ Object next = iter.next();
+ sb.append(stringValueOf(next));
+ if (iter.hasNext()) {
+ sb.append(delimiter);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String stringValueOf(Object next) {
+ try {
+ return String.valueOf(next);
+ } catch (Throwable e) {
+ return "[toString failed]";
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java
new file mode 100644
index 0000000..7b571e3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/internal/SpecificDataPointsSupplier.java
@@ -0,0 +1,90 @@
+package org.junit.experimental.theories.internal;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+public class SpecificDataPointsSupplier extends AllMembersSupplier {
+
+ public SpecificDataPointsSupplier(TestClass testClass) {
+ super(testClass);
+ }
+
+ @Override
+ protected Collection<Field> getSingleDataPointFields(ParameterSignature sig) {
+ Collection<Field> fields = super.getSingleDataPointFields(sig);
+ String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+
+ List<Field> fieldsWithMatchingNames = new ArrayList<Field>();
+
+ for (Field field : fields) {
+ String[] fieldNames = field.getAnnotation(DataPoint.class).value();
+ if (Arrays.asList(fieldNames).contains(requestedName)) {
+ fieldsWithMatchingNames.add(field);
+ }
+ }
+
+ return fieldsWithMatchingNames;
+ }
+
+ @Override
+ protected Collection<Field> getDataPointsFields(ParameterSignature sig) {
+ Collection<Field> fields = super.getDataPointsFields(sig);
+ String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+
+ List<Field> fieldsWithMatchingNames = new ArrayList<Field>();
+
+ for (Field field : fields) {
+ String[] fieldNames = field.getAnnotation(DataPoints.class).value();
+ if (Arrays.asList(fieldNames).contains(requestedName)) {
+ fieldsWithMatchingNames.add(field);
+ }
+ }
+
+ return fieldsWithMatchingNames;
+ }
+
+ @Override
+ protected Collection<FrameworkMethod> getSingleDataPointMethods(ParameterSignature sig) {
+ Collection<FrameworkMethod> methods = super.getSingleDataPointMethods(sig);
+ String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+
+ List<FrameworkMethod> methodsWithMatchingNames = new ArrayList<FrameworkMethod>();
+
+ for (FrameworkMethod method : methods) {
+ String[] methodNames = method.getAnnotation(DataPoint.class).value();
+ if (Arrays.asList(methodNames).contains(requestedName)) {
+ methodsWithMatchingNames.add(method);
+ }
+ }
+
+ return methodsWithMatchingNames;
+ }
+
+ @Override
+ protected Collection<FrameworkMethod> getDataPointsMethods(ParameterSignature sig) {
+ Collection<FrameworkMethod> methods = super.getDataPointsMethods(sig);
+ String requestedName = sig.getAnnotation(FromDataPoints.class).value();
+
+ List<FrameworkMethod> methodsWithMatchingNames = new ArrayList<FrameworkMethod>();
+
+ for (FrameworkMethod method : methods) {
+ String[] methodNames = method.getAnnotation(DataPoints.class).value();
+ if (Arrays.asList(methodNames).contains(requestedName)) {
+ methodsWithMatchingNames.add(method);
+ }
+ }
+
+ return methodsWithMatchingNames;
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java
new file mode 100644
index 0000000..a19f20a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOn.java
@@ -0,0 +1,31 @@
+package org.junit.experimental.theories.suppliers;
+
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.experimental.theories.ParametersSuppliedBy;
+
+/**
+ * Annotating a {@link org.junit.experimental.theories.Theory Theory} method int
+ * parameter with @TestedOn causes it to be supplied with values from the
+ * ints array given when run as a theory by the
+ * {@link org.junit.experimental.theories.Theories Theories} runner. For
+ * example, the below method would be called three times by the Theories runner,
+ * once with each of the int parameters specified.
+ *
+ * <pre>
+ * @Theory
+ * public void shouldPassForSomeInts(@TestedOn(ints={1, 2, 3}) int param) {
+ * ...
+ * }
+ * </pre>
+ */
+@ParametersSuppliedBy(TestedOnSupplier.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target(PARAMETER)
+public @interface TestedOn {
+ int[] ints();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java
new file mode 100644
index 0000000..dc3d0c9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/experimental/theories/suppliers/TestedOnSupplier.java
@@ -0,0 +1,25 @@
+package org.junit.experimental.theories.suppliers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.PotentialAssignment;
+
+/**
+ * @see org.junit.experimental.theories.suppliers.TestedOn
+ * @see org.junit.experimental.theories.ParameterSupplier
+ */
+public class TestedOnSupplier extends ParameterSupplier {
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
+ TestedOn testedOn = sig.getAnnotation(TestedOn.class);
+ int[] ints = testedOn.ints();
+ for (final int i : ints) {
+ list.add(PotentialAssignment.forValue("ints", i));
+ }
+ return list;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java b/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java
new file mode 100644
index 0000000..d0eb782
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/function/ThrowingRunnable.java
@@ -0,0 +1,14 @@
+package org.junit.function;
+
+/**
+ * This interface facilitates the use of
+ * {@link org.junit.Assert#assertThrows(Class, ThrowingRunnable)} from Java 8. It allows method
+ * references to void methods (that declare checked exceptions) to be passed directly into
+ * {@code assertThrows}
+ * without wrapping. It is not meant to be implemented directly.
+ *
+ * @since 4.13
+ */
+public interface ThrowingRunnable {
+ void run() throws Throwable;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java
new file mode 100644
index 0000000..d300e7e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ArrayComparisonFailure.java
@@ -0,0 +1,74 @@
+package org.junit.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+
+/**
+ * Thrown when two array elements differ
+ *
+ * @see Assert#assertArrayEquals(String, Object[], Object[])
+ */
+public class ArrayComparisonFailure extends AssertionError {
+
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final List<Integer> fIndices = new ArrayList<Integer>();
+ private final String fMessage;
+ private final AssertionError fCause;
+
+ /**
+ * Construct a new <code>ArrayComparisonFailure</code> with an error text and the array's
+ * dimension that was not equal
+ *
+ * @param cause the exception that caused the array's content to fail the assertion test
+ * @param index the array position of the objects that are not equal.
+ * @see Assert#assertArrayEquals(String, Object[], Object[])
+ */
+ public ArrayComparisonFailure(String message, AssertionError cause, int index) {
+ this.fMessage = message;
+ this.fCause = cause;
+ initCause(fCause);
+ addDimension(index);
+ }
+
+ public void addDimension(int index) {
+ fIndices.add(0, index);
+ }
+
+ @Override
+ public synchronized Throwable getCause() {
+ return super.getCause() == null ? fCause : super.getCause();
+ }
+
+ @Override
+ public String getMessage() {
+ StringBuilder sb = new StringBuilder();
+ if (fMessage != null) {
+ sb.append(fMessage);
+ }
+ sb.append("arrays first differed at element ");
+ for (int each : fIndices) {
+ sb.append("[");
+ sb.append(each);
+ sb.append("]");
+ }
+ sb.append("; ");
+ sb.append(getCause().getMessage());
+ return sb.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return getMessage();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java
new file mode 100644
index 0000000..0e79b56
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/AssumptionViolatedException.java
@@ -0,0 +1,139 @@
+package org.junit.internal;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.SelfDescribing;
+import org.hamcrest.StringDescription;
+
+/**
+ * An exception class used to implement <i>assumptions</i> (state in which a given test
+ * is meaningful and should or should not be executed). A test for which an assumption
+ * fails should not generate a test case failure.
+ *
+ * @see org.junit.Assume
+ */
+public class AssumptionViolatedException extends RuntimeException implements SelfDescribing {
+ private static final long serialVersionUID = 2L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final String fAssumption;
+ private final boolean fValueMatcher;
+ private final Object fValue;
+ private final Matcher<?> fMatcher;
+
+ /**
+ * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+ */
+ @Deprecated
+ public AssumptionViolatedException(String assumption, boolean hasValue, Object value, Matcher<?> matcher) {
+ this.fAssumption = assumption;
+ this.fValue = value;
+ this.fMatcher = matcher;
+ this.fValueMatcher = hasValue;
+
+ if (value instanceof Throwable) {
+ initCause((Throwable) value);
+ }
+ }
+
+ /**
+ * An assumption exception with the given <i>value</i> (String or
+ * Throwable) and an additional failing {@link Matcher}.
+ *
+ * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+ */
+ @Deprecated
+ public AssumptionViolatedException(Object value, Matcher<?> matcher) {
+ this(null, true, value, matcher);
+ }
+
+ /**
+ * An assumption exception with the given <i>value</i> (String or
+ * Throwable) and an additional failing {@link Matcher}.
+ *
+ * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+ */
+ @Deprecated
+ public AssumptionViolatedException(String assumption, Object value, Matcher<?> matcher) {
+ this(assumption, true, value, matcher);
+ }
+
+ /**
+ * An assumption exception with the given message only.
+ *
+ * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+ */
+ @Deprecated
+ public AssumptionViolatedException(String assumption) {
+ this(assumption, false, null, null);
+ }
+
+ /**
+ * An assumption exception with the given message and a cause.
+ *
+ * @deprecated Please use {@link org.junit.AssumptionViolatedException} instead.
+ */
+ @Deprecated
+ public AssumptionViolatedException(String assumption, Throwable e) {
+ this(assumption, false, null, null);
+ initCause(e);
+ }
+
+ @Override
+ public String getMessage() {
+ return StringDescription.asString(this);
+ }
+
+ public void describeTo(Description description) {
+ if (fAssumption != null) {
+ description.appendText(fAssumption);
+ }
+
+ if (fValueMatcher) {
+ // a value was passed in when this instance was constructed; print it
+ if (fAssumption != null) {
+ description.appendText(": ");
+ }
+
+ description.appendText("got: ");
+ description.appendValue(fValue);
+
+ if (fMatcher != null) {
+ description.appendText(", expected: ");
+ description.appendDescriptionOf(fMatcher);
+ }
+ }
+ }
+
+ /**
+ * Override default Java object serialization to correctly deal with potentially unserializable matchers or values.
+ * By not implementing readObject, we assure ourselves of backwards compatibility and compatibility with the
+ * standard way of Java serialization.
+ *
+ * @param objectOutputStream The outputStream to write our representation to
+ * @throws IOException When serialization fails
+ */
+ private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
+ ObjectOutputStream.PutField putField = objectOutputStream.putFields();
+ putField.put("fAssumption", fAssumption);
+ putField.put("fValueMatcher", fValueMatcher);
+
+ // We have to wrap the matcher into a serializable form.
+ putField.put("fMatcher", SerializableMatcherDescription.asSerializableMatcher(fMatcher));
+
+ // We have to wrap the value inside a non-String class (instead of serializing the String value directly) as
+ // A Description will handle a String and non-String object differently (1st is surrounded by '"' while the
+ // latter will be surrounded by '<' '>'. Wrapping it makes sure that the description of a serialized and
+ // non-serialized instance produce the exact same description
+ putField.put("fValue", SerializableValueDescription.asSerializableValue(fValue));
+
+ objectOutputStream.writeFields();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java
new file mode 100644
index 0000000..9724947
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Checks.java
@@ -0,0 +1,37 @@
+package org.junit.internal;
+
+/** @since 4.13 */
+public final class Checks {
+
+ private Checks() {}
+
+ /**
+ * Checks that the given value is not {@code null}.
+ *
+ * @param value object reference to check
+ * @return the passed-in value, if not {@code null}
+ * @throws NullPointerException if {@code value} is {@code null}
+ */
+ public static <T> T notNull(T value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ return value;
+ }
+
+ /**
+ * Checks that the given value is not {@code null}, using the given message
+ * as the exception message if an exception is thrown.
+ *
+ * @param value object reference to check
+ * @param message message to use if {@code value} is {@code null}
+ * @return the passed-in value, if not {@code null}
+ * @throws NullPointerException if {@code value} is {@code null}
+ */
+ public static <T> T notNull(T value, String message) {
+ if (value == null) {
+ throw new NullPointerException(message);
+ }
+ return value;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java
new file mode 100644
index 0000000..0693836
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Classes.java
@@ -0,0 +1,44 @@
+package org.junit.internal;
+
+import static java.lang.Thread.currentThread;
+
+/**
+ * Miscellaneous functions dealing with classes.
+ */
+public class Classes {
+
+ /**
+ * Do not instantiate.
+ * @deprecated will be private soon.
+ */
+ @Deprecated
+ public Classes() {
+ }
+
+ /**
+ * Returns Class.forName for {@code className} using the current thread's class loader.
+ * If the current thread does not have a class loader, falls back to the class loader for
+ * {@link Classes}.
+ *
+ * @param className Name of the class.
+ * @throws ClassNotFoundException
+ */
+ public static Class<?> getClass(String className) throws ClassNotFoundException {
+ return getClass(className, Classes.class);
+ }
+
+ /**
+ * Returns Class.forName for {@code className} using the current thread's class loader.
+ * If the current thread does not have a class loader, falls back to the class loader for the
+ * passed-in class.
+ *
+ * @param className Name of the class.
+ * @param callingClass Class that is requesting a the class
+ * @throws ClassNotFoundException
+ * @since 4.13
+ */
+ public static Class<?> getClass(String className, Class<?> callingClass) throws ClassNotFoundException {
+ ClassLoader classLoader = currentThread().getContextClassLoader();
+ return Class.forName(className, true, classLoader == null ? callingClass.getClassLoader() : classLoader);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java
new file mode 100644
index 0000000..ed1c674
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ComparisonCriteria.java
@@ -0,0 +1,132 @@
+package org.junit.internal;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+import org.junit.Assert;
+
+/**
+ * Defines criteria for finding two items "equal enough". Concrete subclasses
+ * may demand exact equality, or, for example, equality within a given delta.
+ */
+public abstract class ComparisonCriteria {
+ /**
+ * Asserts that two arrays are equal, according to the criteria defined by
+ * the concrete subclass. If they are not, an {@link AssertionError} is
+ * thrown with the given message. If <code>expecteds</code> and
+ * <code>actuals</code> are <code>null</code>, they are considered equal.
+ *
+ * @param message the identifying message for the {@link AssertionError} (
+ * <code>null</code> okay)
+ * @param expecteds Object array or array of arrays (multi-dimensional array) with
+ * expected values.
+ * @param actuals Object array or array of arrays (multi-dimensional array) with
+ * actual values
+ */
+ public void arrayEquals(String message, Object expecteds, Object actuals)
+ throws ArrayComparisonFailure {
+ arrayEquals(message, expecteds, actuals, true);
+ }
+
+ private void arrayEquals(String message, Object expecteds, Object actuals, boolean outer)
+ throws ArrayComparisonFailure {
+ if (expecteds == actuals
+ || Arrays.deepEquals(new Object[] {expecteds}, new Object[] {actuals})) {
+ // The reflection-based loop below is potentially very slow, especially for primitive
+ // arrays. The deepEquals check allows us to circumvent it in the usual case where
+ // the arrays are exactly equal.
+ return;
+ }
+ String header = message == null ? "" : message + ": ";
+
+ // Only include the user-provided message in the outer exception.
+ String exceptionMessage = outer ? header : "";
+
+ if (expecteds == null) {
+ Assert.fail(exceptionMessage + "expected array was null");
+ }
+ if (actuals == null) {
+ Assert.fail(exceptionMessage + "actual array was null");
+ }
+
+ int actualsLength = Array.getLength(actuals);
+ int expectedsLength = Array.getLength(expecteds);
+ if (actualsLength != expectedsLength) {
+ header += "array lengths differed, expected.length="
+ + expectedsLength + " actual.length=" + actualsLength + "; ";
+ }
+ int prefixLength = Math.min(actualsLength, expectedsLength);
+
+ for (int i = 0; i < prefixLength; i++) {
+ Object expected = Array.get(expecteds, i);
+ Object actual = Array.get(actuals, i);
+
+ if (isArray(expected) && isArray(actual)) {
+ try {
+ arrayEquals(message, expected, actual, false);
+ } catch (ArrayComparisonFailure e) {
+ e.addDimension(i);
+ throw e;
+ } catch (AssertionError e) {
+ // Array lengths differed.
+ throw new ArrayComparisonFailure(header, e, i);
+ }
+ } else {
+ try {
+ assertElementsEqual(expected, actual);
+ } catch (AssertionError e) {
+ throw new ArrayComparisonFailure(header, e, i);
+ }
+ }
+ }
+
+ if (actualsLength != expectedsLength) {
+ Object expected = getToStringableArrayElement(expecteds, expectedsLength, prefixLength);
+ Object actual = getToStringableArrayElement(actuals, actualsLength, prefixLength);
+ try {
+ Assert.assertEquals(expected, actual);
+ } catch (AssertionError e) {
+ throw new ArrayComparisonFailure(header, e, prefixLength);
+ }
+ }
+ }
+
+ private static final Object END_OF_ARRAY_SENTINEL = objectWithToString("end of array");
+
+ private Object getToStringableArrayElement(Object array, int length, int index) {
+ if (index < length) {
+ Object element = Array.get(array, index);
+ if (isArray(element)) {
+ return objectWithToString(componentTypeName(element.getClass()) + "[" + Array.getLength(element) + "]");
+ } else {
+ return element;
+ }
+ } else {
+ return END_OF_ARRAY_SENTINEL;
+ }
+ }
+
+ private static Object objectWithToString(final String string) {
+ return new Object() {
+ @Override
+ public String toString() {
+ return string;
+ }
+ };
+ }
+
+ private String componentTypeName(Class<?> arrayClass) {
+ Class<?> componentType = arrayClass.getComponentType();
+ if (componentType.isArray()) {
+ return componentTypeName(componentType) + "[]";
+ } else {
+ return componentType.getName();
+ }
+ }
+
+ private boolean isArray(Object expected) {
+ return expected != null && expected.getClass().isArray();
+ }
+
+ protected abstract void assertElementsEqual(Object expected, Object actual);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java
new file mode 100644
index 0000000..a267f7f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/ExactComparisonCriteria.java
@@ -0,0 +1,10 @@
+package org.junit.internal;
+
+import org.junit.Assert;
+
+public class ExactComparisonCriteria extends ComparisonCriteria {
+ @Override
+ protected void assertElementsEqual(Object expected, Object actual) {
+ Assert.assertEquals(expected, actual);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java
new file mode 100644
index 0000000..16e804b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/InexactComparisonCriteria.java
@@ -0,0 +1,24 @@
+package org.junit.internal;
+
+import org.junit.Assert;
+
+public class InexactComparisonCriteria extends ComparisonCriteria {
+ public Object fDelta;
+
+ public InexactComparisonCriteria(double delta) {
+ fDelta = delta;
+ }
+
+ public InexactComparisonCriteria(float delta) {
+ fDelta = delta;
+ }
+
+ @Override
+ protected void assertElementsEqual(Object expected, Object actual) {
+ if (expected instanceof Double) {
+ Assert.assertEquals((Double) expected, (Double) actual, (Double) fDelta);
+ } else {
+ Assert.assertEquals((Float) expected, (Float) actual, (Float) fDelta);
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java
new file mode 100644
index 0000000..cf0f2c0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/JUnitSystem.java
@@ -0,0 +1,14 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+
+public interface JUnitSystem {
+
+ /**
+ * Will be removed in the next major release
+ */
+ @Deprecated
+ void exit(int code);
+
+ PrintStream out();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java
new file mode 100644
index 0000000..d8e661a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/MethodSorter.java
@@ -0,0 +1,72 @@
+package org.junit.internal;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.junit.FixMethodOrder;
+
+public class MethodSorter {
+ /**
+ * DEFAULT sort order
+ */
+ public static final Comparator<Method> DEFAULT = new Comparator<Method>() {
+ public int compare(Method m1, Method m2) {
+ int i1 = m1.getName().hashCode();
+ int i2 = m2.getName().hashCode();
+ if (i1 != i2) {
+ return i1 < i2 ? -1 : 1;
+ }
+ return NAME_ASCENDING.compare(m1, m2);
+ }
+ };
+
+ /**
+ * Method name ascending lexicographic sort order, with {@link Method#toString()} as a tiebreaker
+ */
+ public static final Comparator<Method> NAME_ASCENDING = new Comparator<Method>() {
+ public int compare(Method m1, Method m2) {
+ final int comparison = m1.getName().compareTo(m2.getName());
+ if (comparison != 0) {
+ return comparison;
+ }
+ return m1.toString().compareTo(m2.toString());
+ }
+ };
+
+ /**
+ * Gets declared methods of a class in a predictable order, unless @FixMethodOrder(MethodSorters.JVM) is specified.
+ *
+ * Using the JVM order is unwise since the Java platform does not
+ * specify any particular order, and in fact JDK 7 returns a more or less
+ * random order; well-written test code would not assume any order, but some
+ * does, and a predictable failure is better than a random failure on
+ * certain platforms. By default, uses an unspecified but deterministic order.
+ *
+ * @param clazz a class
+ * @return same as {@link Class#getDeclaredMethods} but sorted
+ * @see <a href="http://bugs.sun.com/view_bug.do?bug_id=7023180">JDK
+ * (non-)bug #7023180</a>
+ */
+ public static Method[] getDeclaredMethods(Class<?> clazz) {
+ Comparator<Method> comparator = getSorter(clazz.getAnnotation(FixMethodOrder.class));
+
+ Method[] methods = clazz.getDeclaredMethods();
+ if (comparator != null) {
+ Arrays.sort(methods, comparator);
+ }
+
+ return methods;
+ }
+
+ private MethodSorter() {
+ }
+
+ private static Comparator<Method> getSorter(FixMethodOrder fixMethodOrder) {
+ if (fixMethodOrder == null) {
+ return DEFAULT;
+ }
+
+ return fixMethodOrder.value().getComparator();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java
new file mode 100644
index 0000000..e64e1fe
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/RealSystem.java
@@ -0,0 +1,19 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+
+public class RealSystem implements JUnitSystem {
+
+ /**
+ * Will be removed in the next major release
+ */
+ @Deprecated
+ public void exit(int code) {
+ System.exit(code);
+ }
+
+ public PrintStream out() {
+ return System.out;
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java
new file mode 100644
index 0000000..e036557
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableMatcherDescription.java
@@ -0,0 +1,47 @@
+package org.junit.internal;
+
+import java.io.Serializable;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+
+/**
+ * This class exists solely to provide a serializable description of a matcher to be serialized as a field in
+ * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but most
+ * implementations of {@link Matcher} are not. This class works around that limitation as
+ * {@link AssumptionViolatedException} only every uses the description of the {@link Matcher}, while still retaining
+ * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of
+ * previously serialized instances.
+ */
+class SerializableMatcherDescription<T> extends BaseMatcher<T> implements Serializable {
+
+ private final String matcherDescription;
+
+ private SerializableMatcherDescription(Matcher<T> matcher) {
+ matcherDescription = StringDescription.asString(matcher);
+ }
+
+ public boolean matches(Object o) {
+ throw new UnsupportedOperationException("This Matcher implementation only captures the description");
+ }
+
+ public void describeTo(Description description) {
+ description.appendText(matcherDescription);
+ }
+
+ /**
+ * Factory method that checks to see if the matcher is already serializable.
+ * @param matcher the matcher to make serializable
+ * @return The provided matcher if it is null or already serializable,
+ * the SerializableMatcherDescription representation of it if it is not.
+ */
+ static <T> Matcher<T> asSerializableMatcher(Matcher<T> matcher) {
+ if (matcher == null || matcher instanceof Serializable) {
+ return matcher;
+ } else {
+ return new SerializableMatcherDescription<T>(matcher);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java
new file mode 100644
index 0000000..4d055d7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/SerializableValueDescription.java
@@ -0,0 +1,38 @@
+package org.junit.internal;
+
+import java.io.Serializable;
+
+/**
+ * This class exists solely to provide a serializable description of a value to be serialized as a field in
+ * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but a
+ * value of type Object provides no guarantee to be serializable. This class works around that limitation as
+ * {@link AssumptionViolatedException} only every uses the string representation of the value, while still retaining
+ * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of
+ * previously serialized instances.
+ */
+class SerializableValueDescription implements Serializable {
+ private final String value;
+
+ private SerializableValueDescription(Object value) {
+ this.value = String.valueOf(value);
+ }
+
+ /**
+ * Factory method that checks to see if the value is already serializable.
+ * @param value the value to make serializable
+ * @return The provided value if it is null or already serializable,
+ * the SerializableValueDescription representation of it if it is not.
+ */
+ static Object asSerializableValue(Object value) {
+ if (value == null || value instanceof Serializable) {
+ return value;
+ } else {
+ return new SerializableValueDescription(value);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java
new file mode 100644
index 0000000..d548aeb
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/TextListener.java
@@ -0,0 +1,101 @@
+package org.junit.internal;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class TextListener extends RunListener {
+
+ private final PrintStream writer;
+
+ public TextListener(JUnitSystem system) {
+ this(system.out());
+ }
+
+ public TextListener(PrintStream writer) {
+ this.writer = writer;
+ }
+
+ @Override
+ public void testRunFinished(Result result) {
+ printHeader(result.getRunTime());
+ printFailures(result);
+ printFooter(result);
+ }
+
+ @Override
+ public void testStarted(Description description) {
+ writer.append('.');
+ }
+
+ @Override
+ public void testFailure(Failure failure) {
+ writer.append('E');
+ }
+
+ @Override
+ public void testIgnored(Description description) {
+ writer.append('I');
+ }
+
+ /*
+ * Internal methods
+ */
+
+ private PrintStream getWriter() {
+ return writer;
+ }
+
+ protected void printHeader(long runTime) {
+ getWriter().println();
+ getWriter().println("Time: " + elapsedTimeAsString(runTime));
+ }
+
+ protected void printFailures(Result result) {
+ List<Failure> failures = result.getFailures();
+ if (failures.isEmpty()) {
+ return;
+ }
+ if (failures.size() == 1) {
+ getWriter().println("There was " + failures.size() + " failure:");
+ } else {
+ getWriter().println("There were " + failures.size() + " failures:");
+ }
+ int i = 1;
+ for (Failure each : failures) {
+ printFailure(each, "" + i++);
+ }
+ }
+
+ protected void printFailure(Failure each, String prefix) {
+ getWriter().println(prefix + ") " + each.getTestHeader());
+ getWriter().print(each.getTrimmedTrace());
+ }
+
+ protected void printFooter(Result result) {
+ if (result.wasSuccessful()) {
+ getWriter().println();
+ getWriter().print("OK");
+ getWriter().println(" (" + result.getRunCount() + " test" + (result.getRunCount() == 1 ? "" : "s") + ")");
+
+ } else {
+ getWriter().println();
+ getWriter().println("FAILURES!!!");
+ getWriter().println("Tests run: " + result.getRunCount() + ", Failures: " + result.getFailureCount());
+ }
+ getWriter().println();
+ }
+
+ /**
+ * Returns the formatted string of the elapsed time. Duplicated from
+ * BaseTestRunner. Fix it.
+ */
+ protected String elapsedTimeAsString(long runTime) {
+ return NumberFormat.getInstance().format((double) runTime / 1000);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java
new file mode 100644
index 0000000..3f0f7a3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/Throwables.java
@@ -0,0 +1,273 @@
+package org.junit.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Miscellaneous functions dealing with {@code Throwable}.
+ *
+ * @author kcooney@google.com (Kevin Cooney)
+ * @since 4.12
+ */
+public final class Throwables {
+
+ private Throwables() {
+ }
+
+ /**
+ * Rethrows the given {@code Throwable}, allowing the caller to
+ * declare that it throws {@code Exception}. This is useful when
+ * your callers have nothing reasonable they can do when a
+ * {@code Throwable} is thrown. This is declared to return {@code Exception}
+ * so it can be used in a {@code throw} clause:
+ * <pre>
+ * try {
+ * doSomething();
+ * } catch (Throwable e} {
+ * throw Throwables.rethrowAsException(e);
+ * }
+ * doSomethingLater();
+ * </pre>
+ *
+ * @param e exception to rethrow
+ * @return does not return anything
+ * @since 4.12
+ */
+ public static Exception rethrowAsException(Throwable e) throws Exception {
+ Throwables.<Exception>rethrow(e);
+ return null; // we never get here
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends Throwable> void rethrow(Throwable e) throws T {
+ throw (T) e;
+ }
+
+ /**
+ * Returns the stacktrace of the given Throwable as a String.
+ *
+ * @since 4.13
+ */
+ public static String getStacktrace(Throwable exception) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ exception.printStackTrace(writer);
+ return stringWriter.toString();
+ }
+
+ /**
+ * Gets a trimmed version of the stack trace of the given exception. Stack trace
+ * elements that are below the test method are filtered out.
+ *
+ * @return a trimmed stack trace, or the original trace if trimming wasn't possible
+ */
+ public static String getTrimmedStackTrace(Throwable exception) {
+ List<String> trimmedStackTraceLines = getTrimmedStackTraceLines(exception);
+ if (trimmedStackTraceLines.isEmpty()) {
+ return getFullStackTrace(exception);
+ }
+
+ StringBuilder result = new StringBuilder(exception.toString());
+ appendStackTraceLines(trimmedStackTraceLines, result);
+ appendStackTraceLines(getCauseStackTraceLines(exception), result);
+ return result.toString();
+ }
+
+ private static List<String> getTrimmedStackTraceLines(Throwable exception) {
+ List<StackTraceElement> stackTraceElements = Arrays.asList(exception.getStackTrace());
+ int linesToInclude = stackTraceElements.size();
+
+ State state = State.PROCESSING_OTHER_CODE;
+ for (StackTraceElement stackTraceElement : asReversedList(stackTraceElements)) {
+ state = state.processStackTraceElement(stackTraceElement);
+ if (state == State.DONE) {
+ List<String> trimmedLines = new ArrayList<String>(linesToInclude + 2);
+ trimmedLines.add("");
+ for (StackTraceElement each : stackTraceElements.subList(0, linesToInclude)) {
+ trimmedLines.add("\tat " + each);
+ }
+ if (exception.getCause() != null) {
+ trimmedLines.add("\t... " + (stackTraceElements.size() - trimmedLines.size()) + " trimmed");
+ }
+ return trimmedLines;
+ }
+ linesToInclude--;
+ }
+ return Collections.emptyList();
+ }
+
+ private static final Method getSuppressed = initGetSuppressed();
+
+ private static Method initGetSuppressed() {
+ try {
+ return Throwable.class.getMethod("getSuppressed");
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ private static boolean hasSuppressed(Throwable exception) {
+ if (getSuppressed == null) {
+ return false;
+ }
+ try {
+ Throwable[] suppressed = (Throwable[]) getSuppressed.invoke(exception);
+ return suppressed.length != 0;
+ } catch (Throwable e) {
+ return false;
+ }
+ }
+
+ private static List<String> getCauseStackTraceLines(Throwable exception) {
+ if (exception.getCause() != null || hasSuppressed(exception)) {
+ String fullTrace = getFullStackTrace(exception);
+ BufferedReader reader = new BufferedReader(
+ new StringReader(fullTrace.substring(exception.toString().length())));
+ List<String> causedByLines = new ArrayList<String>();
+
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith("Caused by: ") || line.trim().startsWith("Suppressed: ")) {
+ causedByLines.add(line);
+ while ((line = reader.readLine()) != null) {
+ causedByLines.add(line);
+ }
+ return causedByLines;
+ }
+ }
+ } catch (IOException e) {
+ // We should never get here, because we are reading from a StringReader
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+ private static String getFullStackTrace(Throwable exception) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ exception.printStackTrace(writer);
+ return stringWriter.toString();
+ }
+
+ private static void appendStackTraceLines(
+ List<String> stackTraceLines, StringBuilder destBuilder) {
+ for (String stackTraceLine : stackTraceLines) {
+ destBuilder.append(String.format("%s%n", stackTraceLine));
+ }
+ }
+
+ private static <T> List<T> asReversedList(final List<T> list) {
+ return new AbstractList<T>() {
+
+ @Override
+ public T get(int index) {
+ return list.get(list.size() - index - 1);
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+ };
+ }
+
+ private enum State {
+ PROCESSING_OTHER_CODE {
+ @Override public State processLine(String methodName) {
+ if (isTestFrameworkMethod(methodName)) {
+ return PROCESSING_TEST_FRAMEWORK_CODE;
+ }
+ return this;
+ }
+ },
+ PROCESSING_TEST_FRAMEWORK_CODE {
+ @Override public State processLine(String methodName) {
+ if (isReflectionMethod(methodName)) {
+ return PROCESSING_REFLECTION_CODE;
+ } else if (isTestFrameworkMethod(methodName)) {
+ return this;
+ }
+ return PROCESSING_OTHER_CODE;
+ }
+ },
+ PROCESSING_REFLECTION_CODE {
+ @Override public State processLine(String methodName) {
+ if (isReflectionMethod(methodName)) {
+ return this;
+ } else if (isTestFrameworkMethod(methodName)) {
+ // This is here to handle TestCase.runBare() calling TestCase.runTest().
+ return PROCESSING_TEST_FRAMEWORK_CODE;
+ }
+ return DONE;
+ }
+ },
+ DONE {
+ @Override public State processLine(String methodName) {
+ return this;
+ }
+ };
+
+ /** Processes a stack trace element method name, possibly moving to a new state. */
+ protected abstract State processLine(String methodName);
+
+ /** Processes a stack trace element, possibly moving to a new state. */
+ public final State processStackTraceElement(StackTraceElement element) {
+ return processLine(element.getClassName() + "." + element.getMethodName() + "()");
+ }
+ }
+
+ private static final String[] TEST_FRAMEWORK_METHOD_NAME_PREFIXES = {
+ "org.junit.runner.",
+ "org.junit.runners.",
+ "org.junit.experimental.runners.",
+ "org.junit.internal.",
+ "junit.extensions",
+ "junit.framework",
+ "junit.runner",
+ "junit.textui",
+ };
+
+ private static final String[] TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES = {
+ "org.junit.internal.StackTracesTest",
+ };
+
+ private static boolean isTestFrameworkMethod(String methodName) {
+ return isMatchingMethod(methodName, TEST_FRAMEWORK_METHOD_NAME_PREFIXES) &&
+ !isMatchingMethod(methodName, TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES);
+ }
+
+ private static final String[] REFLECTION_METHOD_NAME_PREFIXES = {
+ "sun.reflect.",
+ "java.lang.reflect.",
+ "jdk.internal.reflect.",
+ "org.junit.rules.RunRules.<init>(",
+ "org.junit.rules.RunRules.applyAll(", // calls TestRules
+ "org.junit.runners.RuleContainer.apply(", // calls MethodRules & TestRules
+ "junit.framework.TestCase.runBare(", // runBare() directly calls setUp() and tearDown()
+ };
+
+ private static boolean isReflectionMethod(String methodName) {
+ return isMatchingMethod(methodName, REFLECTION_METHOD_NAME_PREFIXES);
+ }
+
+ private static boolean isMatchingMethod(String methodName, String[] methodNamePrefixes) {
+ for (String methodNamePrefix : methodNamePrefixes) {
+ if (methodName.startsWith(methodNamePrefix)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java
new file mode 100644
index 0000000..8704a54
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java
@@ -0,0 +1,67 @@
+package org.junit.internal.builders;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class AllDefaultPossibilitiesBuilder extends RunnerBuilder {
+ private final boolean canUseSuiteMethod;
+
+ /**
+ * @since 4.13
+ */
+ public AllDefaultPossibilitiesBuilder() {
+ canUseSuiteMethod = true;
+ }
+
+ /**
+ * @deprecated used {@link #AllDefaultPossibilitiesBuilder()}.
+ */
+ @Deprecated
+ public AllDefaultPossibilitiesBuilder(boolean canUseSuiteMethod) {
+ this.canUseSuiteMethod = canUseSuiteMethod;
+ }
+
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ List<RunnerBuilder> builders = Arrays.asList(
+ ignoredBuilder(),
+ annotatedBuilder(),
+ suiteMethodBuilder(),
+ junit3Builder(),
+ junit4Builder());
+
+ for (RunnerBuilder each : builders) {
+ Runner runner = each.safeRunnerForClass(testClass);
+ if (runner != null) {
+ return runner;
+ }
+ }
+ return null;
+ }
+
+ protected JUnit4Builder junit4Builder() {
+ return new JUnit4Builder();
+ }
+
+ protected JUnit3Builder junit3Builder() {
+ return new JUnit3Builder();
+ }
+
+ protected AnnotatedBuilder annotatedBuilder() {
+ return new AnnotatedBuilder(this);
+ }
+
+ protected IgnoredBuilder ignoredBuilder() {
+ return new IgnoredBuilder();
+ }
+
+ protected RunnerBuilder suiteMethodBuilder() {
+ if (canUseSuiteMethod) {
+ return new SuiteMethodBuilder();
+ }
+ return new NullBuilder();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java
new file mode 100644
index 0000000..04d7a68
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/AnnotatedBuilder.java
@@ -0,0 +1,116 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+import java.lang.reflect.Modifier;
+
+
+/**
+ * The {@code AnnotatedBuilder} is a strategy for constructing runners for test class that have been annotated with the
+ * {@code @RunWith} annotation. All tests within this class will be executed using the runner that was specified within
+ * the annotation.
+ * <p>
+ * If a runner supports inner member classes, the member classes will inherit the runner from the enclosing class, e.g.:
+ * <pre>
+ * @RunWith(MyRunner.class)
+ * public class MyTest {
+ * // some tests might go here
+ *
+ * public class MyMemberClass {
+ * @Test
+ * public void thisTestRunsWith_MyRunner() {
+ * // some test logic
+ * }
+ *
+ * // some more tests might go here
+ * }
+ *
+ * @RunWith(AnotherRunner.class)
+ * public class AnotherMemberClass {
+ * // some tests might go here
+ *
+ * public class DeepInnerClass {
+ * @Test
+ * public void thisTestRunsWith_AnotherRunner() {
+ * // some test logic
+ * }
+ * }
+ *
+ * public class DeepInheritedClass extends SuperTest {
+ * @Test
+ * public void thisTestRunsWith_SuperRunner() {
+ * // some test logic
+ * }
+ * }
+ * }
+ * }
+ *
+ * @RunWith(SuperRunner.class)
+ * public class SuperTest {
+ * // some tests might go here
+ * }
+ * </pre>
+ * The key points to note here are:
+ * <ul>
+ * <li>If there is no RunWith annotation, no runner will be created.</li>
+ * <li>The resolve step is inside-out, e.g. the closest RunWith annotation wins</li>
+ * <li>RunWith annotations are inherited and work as if the class was annotated itself.</li>
+ * <li>The default JUnit runner does not support inner member classes,
+ * so this is only valid for custom runners that support inner member classes.</li>
+ * <li>Custom runners with support for inner classes may or may not support RunWith annotations for member
+ * classes. Please refer to the custom runner documentation.</li>
+ * </ul>
+ *
+ * @see org.junit.runners.model.RunnerBuilder
+ * @see org.junit.runner.RunWith
+ * @since 4.0
+ */
+public class AnnotatedBuilder extends RunnerBuilder {
+ private static final String CONSTRUCTOR_ERROR_FORMAT = "Custom runner class %s should have a public constructor with signature %s(Class testClass)";
+
+ private final RunnerBuilder suiteBuilder;
+
+ public AnnotatedBuilder(RunnerBuilder suiteBuilder) {
+ this.suiteBuilder = suiteBuilder;
+ }
+
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Exception {
+ for (Class<?> currentTestClass = testClass; currentTestClass != null;
+ currentTestClass = getEnclosingClassForNonStaticMemberClass(currentTestClass)) {
+ RunWith annotation = currentTestClass.getAnnotation(RunWith.class);
+ if (annotation != null) {
+ return buildRunner(annotation.value(), testClass);
+ }
+ }
+
+ return null;
+ }
+
+ private Class<?> getEnclosingClassForNonStaticMemberClass(Class<?> currentTestClass) {
+ if (currentTestClass.isMemberClass() && !Modifier.isStatic(currentTestClass.getModifiers())) {
+ return currentTestClass.getEnclosingClass();
+ } else {
+ return null;
+ }
+ }
+
+ public Runner buildRunner(Class<? extends Runner> runnerClass,
+ Class<?> testClass) throws Exception {
+ try {
+ return runnerClass.getConstructor(Class.class).newInstance(testClass);
+ } catch (NoSuchMethodException e) {
+ try {
+ return runnerClass.getConstructor(Class.class,
+ RunnerBuilder.class).newInstance(testClass, suiteBuilder);
+ } catch (NoSuchMethodException e2) {
+ String simpleName = runnerClass.getSimpleName();
+ throw new InitializationError(String.format(
+ CONSTRUCTOR_ERROR_FORMAT, simpleName, simpleName));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java
new file mode 100644
index 0000000..71940c8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredBuilder.java
@@ -0,0 +1,15 @@
+package org.junit.internal.builders;
+
+import org.junit.Ignore;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class IgnoredBuilder extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) {
+ if (testClass.getAnnotation(Ignore.class) != null) {
+ return new IgnoredClassRunner(testClass);
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java
new file mode 100644
index 0000000..7c8926b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/IgnoredClassRunner.java
@@ -0,0 +1,23 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+public class IgnoredClassRunner extends Runner {
+ private final Class<?> clazz;
+
+ public IgnoredClassRunner(Class<?> testClass) {
+ clazz = testClass;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ notifier.fireTestIgnored(getDescription());
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.createSuiteDescription(clazz);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java
new file mode 100644
index 0000000..8b6b371
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit3Builder.java
@@ -0,0 +1,19 @@
+package org.junit.internal.builders;
+
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class JUnit3Builder extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ if (isPre4Test(testClass)) {
+ return new JUnit38ClassRunner(testClass);
+ }
+ return null;
+ }
+
+ boolean isPre4Test(Class<?> testClass) {
+ return junit.framework.TestCase.class.isAssignableFrom(testClass);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java
new file mode 100644
index 0000000..7959e75
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/JUnit4Builder.java
@@ -0,0 +1,12 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Runner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.RunnerBuilder;
+
+public class JUnit4Builder extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ return new JUnit4(testClass);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java
new file mode 100644
index 0000000..c8d306e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/NullBuilder.java
@@ -0,0 +1,11 @@
+package org.junit.internal.builders;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class NullBuilder extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> each) throws Throwable {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java
new file mode 100644
index 0000000..953e6cf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/builders/SuiteMethodBuilder.java
@@ -0,0 +1,24 @@
+package org.junit.internal.builders;
+
+import org.junit.internal.runners.SuiteMethod;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class SuiteMethodBuilder extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> each) throws Throwable {
+ if (hasSuiteMethod(each)) {
+ return new SuiteMethod(each);
+ }
+ return null;
+ }
+
+ public boolean hasSuiteMethod(Class<?> testClass) {
+ try {
+ testClass.getMethod("suite");
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java
new file mode 100644
index 0000000..477b150
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeRuntimeMXBean.java
@@ -0,0 +1,21 @@
+package org.junit.internal.management;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * No-op implementation of RuntimeMXBean when the platform doesn't provide it.
+ */
+class FakeRuntimeMXBean implements RuntimeMXBean {
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Always returns an empty list.
+ */
+ public List<String> getInputArguments() {
+ return Collections.emptyList();
+ }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java
new file mode 100644
index 0000000..893f2e3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/FakeThreadMXBean.java
@@ -0,0 +1,27 @@
+package org.junit.internal.management;
+
+/**
+ * No-op implementation of ThreadMXBean when the platform doesn't provide it.
+ */
+final class FakeThreadMXBean implements ThreadMXBean {
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Always throws an {@link UnsupportedOperationException}
+ */
+ public long getThreadCpuTime(long id) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Always returns false.
+ */
+ public boolean isThreadCpuTimeSupported() {
+ return false;
+ }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java
new file mode 100644
index 0000000..5be1447
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ManagementFactory.java
@@ -0,0 +1,77 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Reflective wrapper around {@link java.lang.management.ManagementFactory}
+ */
+public class ManagementFactory {
+ private static final class FactoryHolder {
+ private static final Class<?> MANAGEMENT_FACTORY_CLASS;
+
+ static {
+ Class<?> managementFactoryClass = null;
+ try {
+ managementFactoryClass = Classes.getClass("java.lang.management.ManagementFactory");
+ } catch (ClassNotFoundException e) {
+ // do nothing, managementFactoryClass will be none on failure
+ }
+ MANAGEMENT_FACTORY_CLASS = managementFactoryClass;
+ }
+
+ static Object getBeanObject(String methodName) {
+ if (MANAGEMENT_FACTORY_CLASS != null) {
+ try {
+ return MANAGEMENT_FACTORY_CLASS.getMethod(methodName).invoke(null);
+ } catch (IllegalAccessException e) {
+ // fallthrough
+ } catch (IllegalArgumentException e) {
+ // fallthrough
+ } catch (InvocationTargetException e) {
+ // fallthrough
+ } catch (NoSuchMethodException e) {
+ // fallthrough
+ } catch (SecurityException e) {
+ // fallthrough
+ }
+ }
+ return null;
+ }
+ }
+
+ private static final class RuntimeHolder {
+ private static final RuntimeMXBean RUNTIME_MX_BEAN =
+ getBean(FactoryHolder.getBeanObject("getRuntimeMXBean"));
+
+ private static final RuntimeMXBean getBean(Object runtimeMxBean) {
+ return runtimeMxBean != null
+ ? new ReflectiveRuntimeMXBean(runtimeMxBean) : new FakeRuntimeMXBean();
+ }
+ }
+
+ private static final class ThreadHolder {
+ private static final ThreadMXBean THREAD_MX_BEAN =
+ getBean(FactoryHolder.getBeanObject("getThreadMXBean"));
+
+ private static final ThreadMXBean getBean(Object threadMxBean) {
+ return threadMxBean != null
+ ? new ReflectiveThreadMXBean(threadMxBean) : new FakeThreadMXBean();
+ }
+ }
+
+ /**
+ * @see java.lang.management.ManagementFactory#getRuntimeMXBean()
+ */
+ public static RuntimeMXBean getRuntimeMXBean() {
+ return RuntimeHolder.RUNTIME_MX_BEAN;
+ }
+
+ /**
+ * @see java.lang.management.ManagementFactory#getThreadMXBean()
+ */
+ public static ThreadMXBean getThreadMXBean() {
+ return ThreadHolder.THREAD_MX_BEAN;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java
new file mode 100644
index 0000000..289587a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java
@@ -0,0 +1,61 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implementation of {@link RuntimeMXBean} using the JVM reflectively.
+ */
+final class ReflectiveRuntimeMXBean implements RuntimeMXBean {
+ private final Object runtimeMxBean;
+
+ private static final class Holder {
+ private static final Method getInputArgumentsMethod;
+ static {
+ Method inputArguments = null;
+ try {
+ Class<?> threadMXBeanClass = Classes.getClass("java.lang.management.RuntimeMXBean");
+ inputArguments = threadMXBeanClass.getMethod("getInputArguments");
+ } catch (ClassNotFoundException e) {
+ // do nothing, input arguments will be null on failure
+ } catch (NoSuchMethodException e) {
+ // do nothing, input arguments will be null on failure
+ } catch (SecurityException e) {
+ // do nothing, input arguments will be null on failure
+ }
+ getInputArgumentsMethod = inputArguments;
+ }
+ }
+
+ ReflectiveRuntimeMXBean(Object runtimeMxBean) {
+ super();
+ this.runtimeMxBean = runtimeMxBean;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public List<String> getInputArguments() {
+ if (Holder.getInputArgumentsMethod != null) {
+ try {
+ return (List<String>) Holder.getInputArgumentsMethod.invoke(runtimeMxBean);
+ } catch (ClassCastException e) { // no multi-catch with source level 6
+ // fallthrough
+ } catch (IllegalAccessException e) {
+ // fallthrough
+ } catch (IllegalArgumentException e) {
+ // fallthrough
+ } catch (InvocationTargetException e) {
+ // fallthrough
+ }
+ }
+ return Collections.emptyList();
+ }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java
new file mode 100644
index 0000000..bc741be
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java
@@ -0,0 +1,92 @@
+package org.junit.internal.management;
+
+import org.junit.internal.Classes;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Implementation of {@link ThreadMXBean} using the JVM reflectively.
+ */
+final class ReflectiveThreadMXBean implements ThreadMXBean {
+ private final Object threadMxBean;
+
+
+ private static final class Holder {
+ static final Method getThreadCpuTimeMethod;
+ static final Method isThreadCpuTimeSupportedMethod;
+
+ private static final String FAILURE_MESSAGE = "Unable to access ThreadMXBean";
+
+ static {
+ Method threadCpuTime = null;
+ Method threadCpuTimeSupported = null;
+ try {
+ Class<?> threadMXBeanClass = Classes.getClass("java.lang.management.ThreadMXBean");
+ threadCpuTime = threadMXBeanClass.getMethod("getThreadCpuTime", long.class);
+ threadCpuTimeSupported = threadMXBeanClass.getMethod("isThreadCpuTimeSupported");
+ } catch (ClassNotFoundException e) {
+ // do nothing, the methods will be null on failure
+ } catch (NoSuchMethodException e) {
+ // do nothing, the methods will be null on failure
+ } catch (SecurityException e) {
+ // do nothing, the methods will be null on failure
+ }
+ getThreadCpuTimeMethod = threadCpuTime;
+ isThreadCpuTimeSupportedMethod = threadCpuTimeSupported;
+ }
+ }
+
+ ReflectiveThreadMXBean(Object threadMxBean) {
+ super();
+ this.threadMxBean = threadMxBean;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getThreadCpuTime(long id) {
+ if (Holder.getThreadCpuTimeMethod != null) {
+ Exception error = null;
+ try {
+ return (Long) Holder.getThreadCpuTimeMethod.invoke(threadMxBean, id);
+ } catch (ClassCastException e) {
+ error = e;
+ // fallthrough
+ } catch (IllegalAccessException e) {
+ error = e;
+ // fallthrough
+ } catch (IllegalArgumentException e) {
+ error = e;
+ // fallthrough
+ } catch (InvocationTargetException e) {
+ error = e;
+ // fallthrough
+ }
+ throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE, error);
+ }
+ throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isThreadCpuTimeSupported() {
+ if (Holder.isThreadCpuTimeSupportedMethod != null) {
+ try {
+ return (Boolean) Holder.isThreadCpuTimeSupportedMethod.invoke(threadMxBean);
+ } catch (ClassCastException e) {
+ // fallthrough
+ } catch (IllegalAccessException e) {
+ // fallthrough
+ } catch (IllegalArgumentException e) {
+ // fallthrough
+ } catch (InvocationTargetException e) {
+ // fallthrough
+ }
+ }
+ return false;
+ }
+
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java
new file mode 100644
index 0000000..84f8861
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/RuntimeMXBean.java
@@ -0,0 +1,14 @@
+package org.junit.internal.management;
+
+import java.util.List;
+
+/**
+ * Wrapper for {@link java.lang.management.RuntimeMXBean}.
+ */
+public interface RuntimeMXBean {
+
+ /**
+ * @see java.lang.management.RuntimeMXBean#getInputArguments()
+ */
+ List<String> getInputArguments();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java
new file mode 100644
index 0000000..f9225c9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/management/ThreadMXBean.java
@@ -0,0 +1,17 @@
+package org.junit.internal.management;
+
+/**
+ * Wrapper for {@link java.lang.management.ThreadMXBean}.
+ */
+public interface ThreadMXBean {
+ /**
+ * @see java.lang.management.ThreadMXBean#getThreadCpuTime(long)
+ */
+ long getThreadCpuTime(long id);
+
+ /**
+ * @see java.lang.management.ThreadMXBean#isThreadCpuTimeSupported()
+ */
+ boolean isThreadCpuTimeSupported();
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
new file mode 100644
index 0000000..93a6827
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
@@ -0,0 +1,53 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+import org.junit.internal.Throwables;
+
+/**
+ * A matcher that delegates to throwableMatcher and in addition appends the
+ * stacktrace of the actual Throwable in case of a mismatch.
+ */
+public class StacktracePrintingMatcher<T extends Throwable> extends
+ org.hamcrest.TypeSafeMatcher<T> {
+
+ private final Matcher<T> throwableMatcher;
+
+ public StacktracePrintingMatcher(Matcher<T> throwableMatcher) {
+ this.throwableMatcher = throwableMatcher;
+ }
+
+ public void describeTo(Description description) {
+ throwableMatcher.describeTo(description);
+ }
+
+ @Override
+ protected boolean matchesSafely(T item) {
+ return throwableMatcher.matches(item);
+ }
+
+ @Override
+ protected void describeMismatchSafely(T item, Description description) {
+ throwableMatcher.describeMismatch(item, description);
+ description.appendText("\nStacktrace was: ");
+ description.appendText(readStacktrace(item));
+ }
+
+ private String readStacktrace(Throwable throwable) {
+ return Throwables.getStacktrace(throwable);
+ }
+
+ @Factory
+ public static <T extends Throwable> Matcher<T> isThrowable(
+ Matcher<T> throwableMatcher) {
+ return new StacktracePrintingMatcher<T>(throwableMatcher);
+ }
+
+ @Factory
+ public static <T extends Exception> Matcher<T> isException(
+ Matcher<T> exceptionMatcher) {
+ return new StacktracePrintingMatcher<T>(exceptionMatcher);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
new file mode 100644
index 0000000..6e2ff5e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
@@ -0,0 +1,50 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * A matcher that applies a delegate matcher to the cause of the current Throwable, returning the result of that
+ * match.
+ *
+ * @param <T> the type of the throwable being matched
+ */
+public class ThrowableCauseMatcher<T extends Throwable> extends
+ TypeSafeMatcher<T> {
+
+ private final Matcher<?> causeMatcher;
+
+ public ThrowableCauseMatcher(Matcher<?> causeMatcher) {
+ this.causeMatcher = causeMatcher;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("exception with cause ");
+ description.appendDescriptionOf(causeMatcher);
+ }
+
+ @Override
+ protected boolean matchesSafely(T item) {
+ return causeMatcher.matches(item.getCause());
+ }
+
+ @Override
+ protected void describeMismatchSafely(T item, Description description) {
+ description.appendText("cause ");
+ causeMatcher.describeMismatch(item.getCause(), description);
+ }
+
+ /**
+ * Returns a matcher that verifies that the outer exception has a cause for which the supplied matcher
+ * evaluates to true.
+ *
+ * @param matcher to apply to the cause of the outer exception
+ * @param <T> type of the outer exception
+ */
+ @Factory
+ public static <T extends Throwable> Matcher<T> hasCause(final Matcher<?> matcher) {
+ return new ThrowableCauseMatcher<T>(matcher);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java
new file mode 100644
index 0000000..74386a8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/ThrowableMessageMatcher.java
@@ -0,0 +1,37 @@
+package org.junit.internal.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+public class ThrowableMessageMatcher<T extends Throwable> extends
+ TypeSafeMatcher<T> {
+
+ private final Matcher<String> matcher;
+
+ public ThrowableMessageMatcher(Matcher<String> matcher) {
+ this.matcher = matcher;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("exception with message ");
+ description.appendDescriptionOf(matcher);
+ }
+
+ @Override
+ protected boolean matchesSafely(T item) {
+ return matcher.matches(item.getMessage());
+ }
+
+ @Override
+ protected void describeMismatchSafely(T item, Description description) {
+ description.appendText("message ");
+ matcher.describeMismatch(item.getMessage(), description);
+ }
+
+ @Factory
+ public static <T extends Throwable> Matcher<T> hasMessage(final Matcher<String> matcher) {
+ return new ThrowableMessageMatcher<T>(matcher);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
new file mode 100644
index 0000000..fb25982
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
@@ -0,0 +1,63 @@
+package org.junit.internal.matchers;
+
+import java.lang.reflect.Method;
+
+import org.hamcrest.BaseMatcher;
+import org.junit.internal.MethodSorter;
+
+/**
+ * Convenient base class for Matchers that require a non-null value of a specific type.
+ * This simply implements the null check, checks the type and then casts.
+ *
+ * @author Joe Walnes
+ * @deprecated Please use {@link org.hamcrest.TypeSafeMatcher}.
+ */
+@Deprecated
+public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
+
+ private Class<?> expectedType;
+
+ /**
+ * Subclasses should implement this. The item will already have been checked for
+ * the specific type and will never be null.
+ */
+ public abstract boolean matchesSafely(T item);
+
+ protected TypeSafeMatcher() {
+ expectedType = findExpectedType(getClass());
+ }
+
+ private static Class<?> findExpectedType(Class<?> fromClass) {
+ for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
+ for (Method method : MethodSorter.getDeclaredMethods(c)) {
+ if (isMatchesSafelyMethod(method)) {
+ return method.getParameterTypes()[0];
+ }
+ }
+ }
+
+ throw new Error("Cannot determine correct type for matchesSafely() method.");
+ }
+
+ private static boolean isMatchesSafelyMethod(Method method) {
+ return "matchesSafely".equals(method.getName())
+ && method.getParameterTypes().length == 1
+ && !method.isSynthetic();
+ }
+
+ protected TypeSafeMatcher(Class<T> expectedType) {
+ this.expectedType = expectedType;
+ }
+
+ /**
+ * Method made final to prevent accidental override.
+ * If you need to override this, there's no point on extending TypeSafeMatcher.
+ * Instead, extend the {@link BaseMatcher}.
+ */
+ @SuppressWarnings({"unchecked"})
+ public final boolean matches(Object item) {
+ return item != null
+ && expectedType.isInstance(item)
+ && matchesSafely((T) item);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java
new file mode 100644
index 0000000..d60e360
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/ClassRequest.java
@@ -0,0 +1,54 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.builders.SuiteMethodBuilder;
+import org.junit.runner.Runner;
+import org.junit.runners.model.RunnerBuilder;
+
+public class ClassRequest extends MemoizingRequest {
+ /*
+ * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses
+ * reflection to access this field. See
+ * https://github.com/junit-team/junit4/issues/960
+ */
+ private final Class<?> fTestClass;
+ private final boolean canUseSuiteMethod;
+
+ public ClassRequest(Class<?> testClass, boolean canUseSuiteMethod) {
+ this.fTestClass = testClass;
+ this.canUseSuiteMethod = canUseSuiteMethod;
+ }
+
+ public ClassRequest(Class<?> testClass) {
+ this(testClass, true);
+ }
+
+ @Override
+ protected Runner createRunner() {
+ return new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass);
+ }
+
+ private class CustomAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder {
+
+ @Override
+ protected RunnerBuilder suiteMethodBuilder() {
+ return new CustomSuiteMethodBuilder();
+ }
+ }
+
+ /*
+ * Customization of {@link SuiteMethodBuilder} that prevents use of the
+ * suite method when creating a runner for fTestClass when canUseSuiteMethod
+ * is false.
+ */
+ private class CustomSuiteMethodBuilder extends SuiteMethodBuilder {
+
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ if (testClass == fTestClass && !canUseSuiteMethod) {
+ return null;
+ }
+ return super.runnerForClass(testClass);
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java
new file mode 100644
index 0000000..5f00399
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/FilterRequest.java
@@ -0,0 +1,45 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+
+/**
+ * A filtered {@link Request}.
+ */
+public final class FilterRequest extends Request {
+ private final Request request;
+ /*
+ * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses
+ * reflection to access this field. See
+ * https://github.com/junit-team/junit4/issues/960
+ */
+ private final Filter fFilter;
+
+ /**
+ * Creates a filtered Request
+ *
+ * @param request a {@link Request} describing your Tests
+ * @param filter {@link Filter} to apply to the Tests described in
+ * <code>request</code>
+ */
+ public FilterRequest(Request request, Filter filter) {
+ this.request = request;
+ this.fFilter = filter;
+ }
+
+ @Override
+ public Runner getRunner() {
+ try {
+ Runner runner = request.getRunner();
+ fFilter.apply(runner);
+ return runner;
+ } catch (NoTestsRemainException e) {
+ return new ErrorReportingRunner(Filter.class, new Exception(String
+ .format("No tests found matching %s from %s", fFilter
+ .describe(), request.toString())));
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java
new file mode 100644
index 0000000..191c230
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/MemoizingRequest.java
@@ -0,0 +1,30 @@
+package org.junit.internal.requests;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+
+abstract class MemoizingRequest extends Request {
+ private final Lock runnerLock = new ReentrantLock();
+ private volatile Runner runner;
+
+ @Override
+ public final Runner getRunner() {
+ if (runner == null) {
+ runnerLock.lock();
+ try {
+ if (runner == null) {
+ runner = createRunner();
+ }
+ } finally {
+ runnerLock.unlock();
+ }
+ }
+ return runner;
+ }
+
+ /** Creates the {@link Runner} to return from {@link #getRunner()}. Called at most once. */
+ protected abstract Runner createRunner();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java
new file mode 100644
index 0000000..441e595
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/OrderingRequest.java
@@ -0,0 +1,29 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.Ordering;
+
+/** @since 4.13 */
+public class OrderingRequest extends MemoizingRequest {
+ private final Request request;
+ private final Ordering ordering;
+
+ public OrderingRequest(Request request, Ordering ordering) {
+ this.request = request;
+ this.ordering = ordering;
+ }
+
+ @Override
+ protected Runner createRunner() {
+ Runner runner = request.getRunner();
+ try {
+ ordering.apply(runner);
+ } catch (InvalidOrderingException e) {
+ return new ErrorReportingRunner(ordering.getClass(), e);
+ }
+ return runner;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java
new file mode 100644
index 0000000..77061da
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/SortingRequest.java
@@ -0,0 +1,25 @@
+package org.junit.internal.requests;
+
+import java.util.Comparator;
+
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Sorter;
+
+public class SortingRequest extends Request {
+ private final Request request;
+ private final Comparator<Description> comparator;
+
+ public SortingRequest(Request request, Comparator<Description> comparator) {
+ this.request = request;
+ this.comparator = comparator;
+ }
+
+ @Override
+ public Runner getRunner() {
+ Runner runner = request.getRunner();
+ new Sorter(comparator).apply(runner);
+ return runner;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java
new file mode 100644
index 0000000..66d2928
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/requests/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides implementations of {@link org.junit.runner.Request}.
+ *
+ * @since 4.0
+ */
+package org.junit.internal.requests;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java
new file mode 100644
index 0000000..df1b453
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ClassRoadie.java
@@ -0,0 +1,81 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class ClassRoadie {
+ private RunNotifier notifier;
+ private TestClass testClass;
+ private Description description;
+ private final Runnable runnable;
+
+ public ClassRoadie(RunNotifier notifier, TestClass testClass,
+ Description description, Runnable runnable) {
+ this.notifier = notifier;
+ this.testClass = testClass;
+ this.description = description;
+ this.runnable = runnable;
+ }
+
+ protected void runUnprotected() {
+ runnable.run();
+ }
+
+ protected void addFailure(Throwable targetException) {
+ notifier.fireTestFailure(new Failure(description, targetException));
+ }
+
+ public void runProtected() {
+ try {
+ runBefores();
+ runUnprotected();
+ } catch (FailedBefore e) {
+ } finally {
+ runAfters();
+ }
+ }
+
+ private void runBefores() throws FailedBefore {
+ try {
+ try {
+ List<Method> befores = testClass.getBefores();
+ for (Method before : befores) {
+ before.invoke(null);
+ }
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ } catch (AssumptionViolatedException e) {
+ throw new FailedBefore();
+ } catch (Throwable e) {
+ addFailure(e);
+ throw new FailedBefore();
+ }
+ }
+
+ private void runAfters() {
+ List<Method> afters = testClass.getAfters();
+ for (Method after : afters) {
+ try {
+ after.invoke(null);
+ } catch (InvocationTargetException e) {
+ addFailure(e.getTargetException());
+ } catch (Throwable e) {
+ addFailure(e); // Untested, but seems impossible
+ }
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java
new file mode 100644
index 0000000..f52abab
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/ErrorReportingRunner.java
@@ -0,0 +1,92 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InvalidTestClassError;
+import org.junit.runners.model.InitializationError;
+
+import static java.util.Collections.singletonList;
+
+public class ErrorReportingRunner extends Runner {
+ private final List<Throwable> causes;
+
+ private final String classNames;
+
+ public ErrorReportingRunner(Class<?> testClass, Throwable cause) {
+ this(cause, testClass);
+ }
+
+ public ErrorReportingRunner(Throwable cause, Class<?>... testClasses) {
+ if (testClasses == null || testClasses.length == 0) {
+ throw new NullPointerException("Test classes cannot be null or empty");
+ }
+ for (Class<?> testClass : testClasses) {
+ if (testClass == null) {
+ throw new NullPointerException("Test class cannot be null");
+ }
+ }
+ classNames = getClassNames(testClasses);
+ causes = getCauses(cause);
+ }
+
+ @Override
+ public Description getDescription() {
+ Description description = Description.createSuiteDescription(classNames);
+ for (Throwable each : causes) {
+ description.addChild(describeCause());
+ }
+ return description;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ for (Throwable each : causes) {
+ runCause(each, notifier);
+ }
+ }
+
+ private String getClassNames(Class<?>... testClasses) {
+ final StringBuilder builder = new StringBuilder();
+ for (Class<?> testClass : testClasses) {
+ if (builder.length() != 0) {
+ builder.append(", ");
+ }
+ builder.append(testClass.getName());
+ }
+ return builder.toString();
+ }
+
+ @SuppressWarnings("deprecation")
+ private List<Throwable> getCauses(Throwable cause) {
+ if (cause instanceof InvocationTargetException) {
+ return getCauses(cause.getCause());
+ }
+ if (cause instanceof InvalidTestClassError) {
+ return singletonList(cause);
+ }
+ if (cause instanceof InitializationError) {
+ return ((InitializationError) cause).getCauses();
+ }
+ if (cause instanceof org.junit.internal.runners.InitializationError) {
+ return ((org.junit.internal.runners.InitializationError) cause)
+ .getCauses();
+ }
+ return singletonList(cause);
+ }
+
+ private Description describeCause() {
+ return Description.createTestDescription(classNames, "initializationError");
+ }
+
+ private void runCause(Throwable child, RunNotifier notifier) {
+ Description description = describeCause();
+ notifier.fireTestStarted(description);
+ notifier.fireTestFailure(new Failure(description, child));
+ notifier.fireTestFinished(description);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java
new file mode 100644
index 0000000..1036cb6
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/FailedBefore.java
@@ -0,0 +1,13 @@
+package org.junit.internal.runners;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+class FailedBefore extends Exception {
+ private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java
new file mode 100644
index 0000000..484f58d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/InitializationError.java
@@ -0,0 +1,37 @@
+package org.junit.internal.runners;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Use the published version:
+ * {@link org.junit.runners.model.InitializationError}
+ * This may disappear as soon as 1 April 2009
+ */
+@Deprecated
+public class InitializationError extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final List<Throwable> fErrors;
+
+ public InitializationError(List<Throwable> errors) {
+ this.fErrors = errors;
+ }
+
+ public InitializationError(Throwable... errors) {
+ this(Arrays.asList(errors));
+ }
+
+ public InitializationError(String string) {
+ this(new Exception(string));
+ }
+
+ public List<Throwable> getCauses() {
+ return fErrors;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
new file mode 100644
index 0000000..0d51541
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
@@ -0,0 +1,196 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import junit.extensions.TestDecorator;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import org.junit.runner.Describable;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+
+public class JUnit38ClassRunner extends Runner implements Filterable, Orderable {
+ private static final class OldTestClassAdaptingListener implements
+ TestListener {
+ private final RunNotifier notifier;
+
+ private OldTestClassAdaptingListener(RunNotifier notifier) {
+ this.notifier = notifier;
+ }
+
+ public void endTest(Test test) {
+ notifier.fireTestFinished(asDescription(test));
+ }
+
+ public void startTest(Test test) {
+ notifier.fireTestStarted(asDescription(test));
+ }
+
+ // Implement junit.framework.TestListener
+ public void addError(Test test, Throwable e) {
+ Failure failure = new Failure(asDescription(test), e);
+ notifier.fireTestFailure(failure);
+ }
+
+ private Description asDescription(Test test) {
+ if (test instanceof Describable) {
+ Describable facade = (Describable) test;
+ return facade.getDescription();
+ }
+ return Description.createTestDescription(getEffectiveClass(test), getName(test));
+ }
+
+ private Class<? extends Test> getEffectiveClass(Test test) {
+ return test.getClass();
+ }
+
+ private String getName(Test test) {
+ if (test instanceof TestCase) {
+ return ((TestCase) test).getName();
+ } else {
+ return test.toString();
+ }
+ }
+
+ public void addFailure(Test test, AssertionFailedError t) {
+ addError(test, t);
+ }
+ }
+
+ private volatile Test test;
+
+ public JUnit38ClassRunner(Class<?> klass) {
+ this(new TestSuite(klass.asSubclass(TestCase.class)));
+ }
+
+ public JUnit38ClassRunner(Test test) {
+ super();
+ setTest(test);
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ TestResult result = new TestResult();
+ result.addListener(createAdaptingListener(notifier));
+ getTest().run(result);
+ }
+
+ public TestListener createAdaptingListener(final RunNotifier notifier) {
+ return new OldTestClassAdaptingListener(notifier);
+ }
+
+ @Override
+ public Description getDescription() {
+ return makeDescription(getTest());
+ }
+
+ private static Description makeDescription(Test test) {
+ if (test instanceof TestCase) {
+ TestCase tc = (TestCase) test;
+ return Description.createTestDescription(tc.getClass(), tc.getName(),
+ getAnnotations(tc));
+ } else if (test instanceof TestSuite) {
+ TestSuite ts = (TestSuite) test;
+ String name = ts.getName() == null ? createSuiteDescription(ts) : ts.getName();
+ Description description = Description.createSuiteDescription(name);
+ int n = ts.testCount();
+ for (int i = 0; i < n; i++) {
+ Description made = makeDescription(ts.testAt(i));
+ description.addChild(made);
+ }
+ return description;
+ } else if (test instanceof Describable) {
+ Describable adapter = (Describable) test;
+ return adapter.getDescription();
+ } else if (test instanceof TestDecorator) {
+ TestDecorator decorator = (TestDecorator) test;
+ return makeDescription(decorator.getTest());
+ } else {
+ // This is the best we can do in this case
+ return Description.createSuiteDescription(test.getClass());
+ }
+ }
+
+ /**
+ * Get the annotations associated with given TestCase.
+ * @param test the TestCase.
+ */
+ private static Annotation[] getAnnotations(TestCase test) {
+ try {
+ Method m = test.getClass().getMethod(test.getName());
+ return m.getDeclaredAnnotations();
+ } catch (SecurityException e) {
+ } catch (NoSuchMethodException e) {
+ }
+ return new Annotation[0];
+ }
+
+ private static String createSuiteDescription(TestSuite ts) {
+ int count = ts.countTestCases();
+ String example = count == 0 ? "" : String.format(" [example: %s]", ts.testAt(0));
+ return String.format("TestSuite with %s tests%s", count, example);
+ }
+
+ public void filter(Filter filter) throws NoTestsRemainException {
+ if (getTest() instanceof Filterable) {
+ Filterable adapter = (Filterable) getTest();
+ adapter.filter(filter);
+ } else if (getTest() instanceof TestSuite) {
+ TestSuite suite = (TestSuite) getTest();
+ TestSuite filtered = new TestSuite(suite.getName());
+ int n = suite.testCount();
+ for (int i = 0; i < n; i++) {
+ Test test = suite.testAt(i);
+ if (filter.shouldRun(makeDescription(test))) {
+ filtered.addTest(test);
+ }
+ }
+ setTest(filtered);
+ if (filtered.testCount() == 0) {
+ throw new NoTestsRemainException();
+ }
+ }
+ }
+
+ public void sort(Sorter sorter) {
+ if (getTest() instanceof Sortable) {
+ Sortable adapter = (Sortable) getTest();
+ adapter.sort(sorter);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 4.13
+ */
+ public void order(Orderer orderer) throws InvalidOrderingException {
+ if (getTest() instanceof Orderable) {
+ Orderable adapter = (Orderable) getTest();
+ adapter.order(orderer);
+ }
+ }
+
+ private void setTest(Test test) {
+ this.test = test;
+ }
+
+ private Test getTest() {
+ return test;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java
new file mode 100644
index 0000000..69a23c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/JUnit4ClassRunner.java
@@ -0,0 +1,147 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class JUnit4ClassRunner extends Runner implements Filterable, Sortable {
+ private final List<Method> testMethods;
+ private TestClass testClass;
+
+ public JUnit4ClassRunner(Class<?> klass) throws InitializationError {
+ testClass = new TestClass(klass);
+ testMethods = getTestMethods();
+ validate();
+ }
+
+ protected List<Method> getTestMethods() {
+ return testClass.getTestMethods();
+ }
+
+ protected void validate() throws InitializationError {
+ MethodValidator methodValidator = new MethodValidator(testClass);
+ methodValidator.validateMethodsForDefaultRunner();
+ methodValidator.assertValid();
+ }
+
+ @Override
+ public void run(final RunNotifier notifier) {
+ new ClassRoadie(notifier, testClass, getDescription(), new Runnable() {
+ public void run() {
+ runMethods(notifier);
+ }
+ }).runProtected();
+ }
+
+ protected void runMethods(final RunNotifier notifier) {
+ for (Method method : testMethods) {
+ invokeTestMethod(method, notifier);
+ }
+ }
+
+ @Override
+ public Description getDescription() {
+ Description spec = Description.createSuiteDescription(getName(), classAnnotations());
+ List<Method> testMethods = this.testMethods;
+ for (Method method : testMethods) {
+ spec.addChild(methodDescription(method));
+ }
+ return spec;
+ }
+
+ protected Annotation[] classAnnotations() {
+ return testClass.getJavaClass().getAnnotations();
+ }
+
+ protected String getName() {
+ return getTestClass().getName();
+ }
+
+ protected Object createTest() throws Exception {
+ return getTestClass().getConstructor().newInstance();
+ }
+
+ protected void invokeTestMethod(Method method, RunNotifier notifier) {
+ Description description = methodDescription(method);
+ Object test;
+ try {
+ test = createTest();
+ } catch (InvocationTargetException e) {
+ testAborted(notifier, description, e.getCause());
+ return;
+ } catch (Exception e) {
+ testAborted(notifier, description, e);
+ return;
+ }
+ TestMethod testMethod = wrapMethod(method);
+ new MethodRoadie(test, testMethod, notifier, description).run();
+ }
+
+ private void testAborted(RunNotifier notifier, Description description,
+ Throwable e) {
+ notifier.fireTestStarted(description);
+ notifier.fireTestFailure(new Failure(description, e));
+ notifier.fireTestFinished(description);
+ }
+
+ protected TestMethod wrapMethod(Method method) {
+ return new TestMethod(method, testClass);
+ }
+
+ protected String testName(Method method) {
+ return method.getName();
+ }
+
+ protected Description methodDescription(Method method) {
+ return Description.createTestDescription(getTestClass().getJavaClass(), testName(method), testAnnotations(method));
+ }
+
+ protected Annotation[] testAnnotations(Method method) {
+ return method.getAnnotations();
+ }
+
+ public void filter(Filter filter) throws NoTestsRemainException {
+ for (Iterator<Method> iter = testMethods.iterator(); iter.hasNext(); ) {
+ Method method = iter.next();
+ if (!filter.shouldRun(methodDescription(method))) {
+ iter.remove();
+ }
+ }
+ if (testMethods.isEmpty()) {
+ throw new NoTestsRemainException();
+ }
+ }
+
+ public void sort(final Sorter sorter) {
+ Collections.sort(testMethods, new Comparator<Method>() {
+ public int compare(Method o1, Method o2) {
+ return sorter.compare(methodDescription(o1), methodDescription(o2));
+ }
+ });
+ }
+
+ protected TestClass getTestClass() {
+ return testClass;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java
new file mode 100644
index 0000000..01a476b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodRoadie.java
@@ -0,0 +1,163 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.TestTimedOutException;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class MethodRoadie {
+ private final Object test;
+ private final RunNotifier notifier;
+ private final Description description;
+ private TestMethod testMethod;
+
+ public MethodRoadie(Object test, TestMethod method, RunNotifier notifier, Description description) {
+ this.test = test;
+ this.notifier = notifier;
+ this.description = description;
+ testMethod = method;
+ }
+
+ public void run() {
+ if (testMethod.isIgnored()) {
+ notifier.fireTestIgnored(description);
+ return;
+ }
+ notifier.fireTestStarted(description);
+ try {
+ long timeout = testMethod.getTimeout();
+ if (timeout > 0) {
+ runWithTimeout(timeout);
+ } else {
+ runTest();
+ }
+ } finally {
+ notifier.fireTestFinished(description);
+ }
+ }
+
+ private void runWithTimeout(final long timeout) {
+ runBeforesThenTestThenAfters(new Runnable() {
+
+ public void run() {
+ ExecutorService service = Executors.newSingleThreadExecutor();
+ Callable<Object> callable = new Callable<Object>() {
+ public Object call() throws Exception {
+ runTestMethod();
+ return null;
+ }
+ };
+ Future<Object> result = service.submit(callable);
+ service.shutdown();
+ try {
+ boolean terminated = service.awaitTermination(timeout,
+ TimeUnit.MILLISECONDS);
+ if (!terminated) {
+ service.shutdownNow();
+ }
+ result.get(0, TimeUnit.MILLISECONDS); // throws the exception if one occurred during the invocation
+ } catch (TimeoutException e) {
+ addFailure(new TestTimedOutException(timeout, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ }
+ });
+ }
+
+ public void runTest() {
+ runBeforesThenTestThenAfters(new Runnable() {
+ public void run() {
+ runTestMethod();
+ }
+ });
+ }
+
+ public void runBeforesThenTestThenAfters(Runnable test) {
+ try {
+ runBefores();
+ test.run();
+ } catch (FailedBefore e) {
+ } catch (Exception e) {
+ throw new RuntimeException("test should never throw an exception to this level");
+ } finally {
+ runAfters();
+ }
+ }
+
+ protected void runTestMethod() {
+ try {
+ testMethod.invoke(test);
+ if (testMethod.expectsException()) {
+ addFailure(new AssertionError("Expected exception: " + testMethod.getExpectedException().getName()));
+ }
+ } catch (InvocationTargetException e) {
+ Throwable actual = e.getTargetException();
+ if (actual instanceof AssumptionViolatedException) {
+ return;
+ } else if (!testMethod.expectsException()) {
+ addFailure(actual);
+ } else if (testMethod.isUnexpected(actual)) {
+ String message = "Unexpected exception, expected<" + testMethod.getExpectedException().getName() + "> but was<"
+ + actual.getClass().getName() + ">";
+ addFailure(new Exception(message, actual));
+ }
+ } catch (Throwable e) {
+ addFailure(e);
+ }
+ }
+
+ private void runBefores() throws FailedBefore {
+ try {
+ try {
+ List<Method> befores = testMethod.getBefores();
+ for (Method before : befores) {
+ before.invoke(test);
+ }
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ } catch (AssumptionViolatedException e) {
+ throw new FailedBefore();
+ } catch (Throwable e) {
+ addFailure(e);
+ throw new FailedBefore();
+ }
+ }
+
+ private void runAfters() {
+ List<Method> afters = testMethod.getAfters();
+ for (Method after : afters) {
+ try {
+ after.invoke(test);
+ } catch (InvocationTargetException e) {
+ addFailure(e.getTargetException());
+ } catch (Throwable e) {
+ addFailure(e); // Untested, but seems impossible
+ }
+ }
+ }
+
+ protected void addFailure(Throwable e) {
+ notifier.fireTestFailure(new Failure(description, e));
+ }
+}
+
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java
new file mode 100644
index 0000000..e656ee5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/MethodValidator.java
@@ -0,0 +1,97 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class MethodValidator {
+
+ private final List<Throwable> errors = new ArrayList<Throwable>();
+
+ private TestClass testClass;
+
+ public MethodValidator(TestClass testClass) {
+ this.testClass = testClass;
+ }
+
+ public void validateInstanceMethods() {
+ validateTestMethods(After.class, false);
+ validateTestMethods(Before.class, false);
+ validateTestMethods(Test.class, false);
+
+ List<Method> methods = testClass.getAnnotatedMethods(Test.class);
+ if (methods.size() == 0) {
+ errors.add(new Exception("No runnable methods"));
+ }
+ }
+
+ public void validateStaticMethods() {
+ validateTestMethods(BeforeClass.class, true);
+ validateTestMethods(AfterClass.class, true);
+ }
+
+ public List<Throwable> validateMethodsForDefaultRunner() {
+ validateNoArgConstructor();
+ validateStaticMethods();
+ validateInstanceMethods();
+ return errors;
+ }
+
+ public void assertValid() throws InitializationError {
+ if (!errors.isEmpty()) {
+ throw new InitializationError(errors);
+ }
+ }
+
+ public void validateNoArgConstructor() {
+ try {
+ testClass.getConstructor();
+ } catch (Exception e) {
+ errors.add(new Exception("Test class should have public zero-argument constructor", e));
+ }
+ }
+
+ private void validateTestMethods(Class<? extends Annotation> annotation,
+ boolean isStatic) {
+ List<Method> methods = testClass.getAnnotatedMethods(annotation);
+
+ for (Method each : methods) {
+ if (Modifier.isStatic(each.getModifiers()) != isStatic) {
+ String state = isStatic ? "should" : "should not";
+ errors.add(new Exception("Method " + each.getName() + "() "
+ + state + " be static"));
+ }
+ if (!Modifier.isPublic(each.getDeclaringClass().getModifiers())) {
+ errors.add(new Exception("Class " + each.getDeclaringClass().getName()
+ + " should be public"));
+ }
+ if (!Modifier.isPublic(each.getModifiers())) {
+ errors.add(new Exception("Method " + each.getName()
+ + " should be public"));
+ }
+ if (each.getReturnType() != Void.TYPE) {
+ errors.add(new Exception("Method " + each.getName()
+ + "should have a return type of void"));
+ }
+ if (each.getParameterTypes().length != 0) {
+ errors.add(new Exception("Method " + each.getName()
+ + " should have no parameters"));
+ }
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java
new file mode 100644
index 0000000..e336983
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/SuiteMethod.java
@@ -0,0 +1,41 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import junit.framework.Test;
+
+/**
+ * Runner for use with JUnit 3.8.x-style AllTests classes
+ * (those that only implement a static <code>suite()</code>
+ * method). For example:
+ * <pre>
+ * @RunWith(AllTests.class)
+ * public class ProductTests {
+ * public static junit.framework.Test suite() {
+ * ...
+ * }
+ * }
+ * </pre>
+ */
+public class SuiteMethod extends JUnit38ClassRunner {
+ public SuiteMethod(Class<?> klass) throws Throwable {
+ super(testFromSuiteMethod(klass));
+ }
+
+ public static Test testFromSuiteMethod(Class<?> klass) throws Throwable {
+ Method suiteMethod = null;
+ Test suite = null;
+ try {
+ suiteMethod = klass.getMethod("suite");
+ if (!Modifier.isStatic(suiteMethod.getModifiers())) {
+ throw new Exception(klass.getName() + ".suite() must be static");
+ }
+ suite = (Test) suiteMethod.invoke(null); // static method
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ }
+ return suite;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java
new file mode 100644
index 0000000..6d24f4f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestClass.java
@@ -0,0 +1,109 @@
+package org.junit.internal.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.internal.MethodSorter;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class TestClass {
+ private final Class<?> klass;
+
+ public TestClass(Class<?> klass) {
+ this.klass = klass;
+ }
+
+ public List<Method> getTestMethods() {
+ return getAnnotatedMethods(Test.class);
+ }
+
+ List<Method> getBefores() {
+ return getAnnotatedMethods(BeforeClass.class);
+ }
+
+ List<Method> getAfters() {
+ return getAnnotatedMethods(AfterClass.class);
+ }
+
+ public List<Method> getAnnotatedMethods(Class<? extends Annotation> annotationClass) {
+ List<Method> results = new ArrayList<Method>();
+ for (Class<?> eachClass : getSuperClasses(klass)) {
+ Method[] methods = MethodSorter.getDeclaredMethods(eachClass);
+ for (Method eachMethod : methods) {
+ Annotation annotation = eachMethod.getAnnotation(annotationClass);
+ if (annotation != null && !isShadowed(eachMethod, results)) {
+ results.add(eachMethod);
+ }
+ }
+ }
+ if (runsTopToBottom(annotationClass)) {
+ Collections.reverse(results);
+ }
+ return results;
+ }
+
+ private boolean runsTopToBottom(Class<? extends Annotation> annotation) {
+ return annotation.equals(Before.class) || annotation.equals(BeforeClass.class);
+ }
+
+ private boolean isShadowed(Method method, List<Method> results) {
+ for (Method each : results) {
+ if (isShadowed(method, each)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isShadowed(Method current, Method previous) {
+ if (!previous.getName().equals(current.getName())) {
+ return false;
+ }
+ if (previous.getParameterTypes().length != current.getParameterTypes().length) {
+ return false;
+ }
+ for (int i = 0; i < previous.getParameterTypes().length; i++) {
+ if (!previous.getParameterTypes()[i].equals(current.getParameterTypes()[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private List<Class<?>> getSuperClasses(Class<?> testClass) {
+ List<Class<?>> results = new ArrayList<Class<?>>();
+ Class<?> current = testClass;
+ while (current != null) {
+ results.add(current);
+ current = current.getSuperclass();
+ }
+ return results;
+ }
+
+ public Constructor<?> getConstructor() throws SecurityException, NoSuchMethodException {
+ return klass.getConstructor();
+ }
+
+ public Class<?> getJavaClass() {
+ return klass;
+ }
+
+ public String getName() {
+ return klass.getName();
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java
new file mode 100644
index 0000000..821e193
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/TestMethod.java
@@ -0,0 +1,71 @@
+package org.junit.internal.runners;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.Test.None;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next major release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class TestMethod {
+ private final Method method;
+ private TestClass testClass;
+
+ public TestMethod(Method method, TestClass testClass) {
+ this.method = method;
+ this.testClass = testClass;
+ }
+
+ public boolean isIgnored() {
+ return method.getAnnotation(Ignore.class) != null;
+ }
+
+ public long getTimeout() {
+ Test annotation = method.getAnnotation(Test.class);
+ if (annotation == null) {
+ return 0;
+ }
+ long timeout = annotation.timeout();
+ return timeout;
+ }
+
+ protected Class<? extends Throwable> getExpectedException() {
+ Test annotation = method.getAnnotation(Test.class);
+ if (annotation == null || annotation.expected() == None.class) {
+ return null;
+ } else {
+ return annotation.expected();
+ }
+ }
+
+ boolean isUnexpected(Throwable exception) {
+ return !getExpectedException().isAssignableFrom(exception.getClass());
+ }
+
+ boolean expectsException() {
+ return getExpectedException() != null;
+ }
+
+ List<Method> getBefores() {
+ return testClass.getAnnotatedMethods(Before.class);
+ }
+
+ List<Method> getAfters() {
+ return testClass.getAnnotatedMethods(After.class);
+ }
+
+ public void invoke(Object test) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ method.invoke(test);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java
new file mode 100644
index 0000000..c5a0764
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/EachTestNotifier.java
@@ -0,0 +1,71 @@
+package org.junit.internal.runners.model;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.MultipleFailureException;
+
+public class EachTestNotifier {
+ private final RunNotifier notifier;
+
+ private final Description description;
+
+ public EachTestNotifier(RunNotifier notifier, Description description) {
+ this.notifier = notifier;
+ this.description = description;
+ }
+
+ public void addFailure(Throwable targetException) {
+ if (targetException instanceof MultipleFailureException) {
+ addMultipleFailureException((MultipleFailureException) targetException);
+ } else {
+ notifier.fireTestFailure(new Failure(description, targetException));
+ }
+ }
+
+ private void addMultipleFailureException(MultipleFailureException mfe) {
+ for (Throwable each : mfe.getFailures()) {
+ addFailure(each);
+ }
+ }
+
+ public void addFailedAssumption(AssumptionViolatedException e) {
+ notifier.fireTestAssumptionFailed(new Failure(description, e));
+ }
+
+ public void fireTestFinished() {
+ notifier.fireTestFinished(description);
+ }
+
+ public void fireTestStarted() {
+ notifier.fireTestStarted(description);
+ }
+
+ public void fireTestIgnored() {
+ notifier.fireTestIgnored(description);
+ }
+
+ /**
+ * Calls {@link RunNotifier#fireTestSuiteStarted(Description)}, passing the
+ * {@link Description} that was passed to the {@code EachTestNotifier} constructor.
+ * This should be called when a test suite is about to be started.
+ * @see RunNotifier#fireTestSuiteStarted(Description)
+ * @since 4.13
+ */
+ public void fireTestSuiteStarted() {
+ notifier.fireTestSuiteStarted(description);
+ }
+
+ /**
+ * Calls {@link RunNotifier#fireTestSuiteFinished(Description)}, passing the
+ * {@link Description} that was passed to the {@code EachTestNotifier} constructor.
+ * This should be called when a test suite has finished, whether the test suite succeeds
+ * or fails.
+ * @see RunNotifier#fireTestSuiteFinished(Description)
+ * @since 4.13
+ */
+ public void fireTestSuiteFinished() {
+ notifier.fireTestSuiteFinished(description);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java
new file mode 100644
index 0000000..054f042
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/MultipleFailureException.java
@@ -0,0 +1,12 @@
+package org.junit.internal.runners.model;
+
+import java.util.List;
+
+@Deprecated
+public class MultipleFailureException extends org.junit.runners.model.MultipleFailureException {
+ private static final long serialVersionUID = 1L;
+
+ public MultipleFailureException(List<Throwable> errors) {
+ super(errors);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java
new file mode 100644
index 0000000..79d5c05
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/model/ReflectiveCallable.java
@@ -0,0 +1,19 @@
+package org.junit.internal.runners.model;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * When invoked, throws the exception from the reflected method, rather than
+ * wrapping it in an InvocationTargetException.
+ */
+public abstract class ReflectiveCallable {
+ public Object run() throws Throwable {
+ try {
+ return runReflectiveCall();
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+
+ protected abstract Object runReflectiveCall() throws Throwable;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java
new file mode 100644
index 0000000..5ab7e7b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides implementations of {@link org.junit.runner.Runner}
+ *
+ * @since 4.0
+ */
+package org.junit.internal.runners;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java
new file mode 100644
index 0000000..36de4f1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java
@@ -0,0 +1,279 @@
+package org.junit.internal.runners.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runners.model.FrameworkMember;
+import org.junit.runners.model.TestClass;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A RuleMemberValidator validates the rule fields/methods of a
+ * {@link org.junit.runners.model.TestClass}. All reasons for rejecting the
+ * {@code TestClass} are written to a list of errors.
+ *
+ * <p>There are four slightly different validators. The {@link #CLASS_RULE_VALIDATOR}
+ * validates fields with a {@link ClassRule} annotation and the
+ * {@link #RULE_VALIDATOR} validates fields with a {@link Rule} annotation.</p>
+ *
+ * <p>The {@link #CLASS_RULE_METHOD_VALIDATOR}
+ * validates methods with a {@link ClassRule} annotation and the
+ * {@link #RULE_METHOD_VALIDATOR} validates methods with a {@link Rule} annotation.</p>
+ */
+public class RuleMemberValidator {
+ /**
+ * Validates fields with a {@link ClassRule} annotation.
+ */
+ public static final RuleMemberValidator CLASS_RULE_VALIDATOR =
+ classRuleValidatorBuilder()
+ .withValidator(new DeclaringClassMustBePublic())
+ .withValidator(new MemberMustBeStatic())
+ .withValidator(new MemberMustBePublic())
+ .withValidator(new FieldMustBeATestRule())
+ .build();
+ /**
+ * Validates fields with a {@link Rule} annotation.
+ */
+ public static final RuleMemberValidator RULE_VALIDATOR =
+ testRuleValidatorBuilder()
+ .withValidator(new MemberMustBeNonStaticOrAlsoClassRule())
+ .withValidator(new MemberMustBePublic())
+ .withValidator(new FieldMustBeARule())
+ .build();
+ /**
+ * Validates methods with a {@link ClassRule} annotation.
+ */
+ public static final RuleMemberValidator CLASS_RULE_METHOD_VALIDATOR =
+ classRuleValidatorBuilder()
+ .forMethods()
+ .withValidator(new DeclaringClassMustBePublic())
+ .withValidator(new MemberMustBeStatic())
+ .withValidator(new MemberMustBePublic())
+ .withValidator(new MethodMustBeATestRule())
+ .build();
+
+ /**
+ * Validates methods with a {@link Rule} annotation.
+ */
+ public static final RuleMemberValidator RULE_METHOD_VALIDATOR =
+ testRuleValidatorBuilder()
+ .forMethods()
+ .withValidator(new MemberMustBeNonStaticOrAlsoClassRule())
+ .withValidator(new MemberMustBePublic())
+ .withValidator(new MethodMustBeARule())
+ .build();
+
+ private final Class<? extends Annotation> annotation;
+ private final boolean methods;
+ private final List<RuleValidator> validatorStrategies;
+
+ RuleMemberValidator(Builder builder) {
+ this.annotation = builder.annotation;
+ this.methods = builder.methods;
+ this.validatorStrategies = builder.validators;
+ }
+
+ /**
+ * Validate the {@link org.junit.runners.model.TestClass} and adds reasons
+ * for rejecting the class to a list of errors.
+ *
+ * @param target the {@code TestClass} to validate.
+ * @param errors the list of errors.
+ */
+ public void validate(TestClass target, List<Throwable> errors) {
+ List<? extends FrameworkMember<?>> members = methods ? target.getAnnotatedMethods(annotation)
+ : target.getAnnotatedFields(annotation);
+
+ for (FrameworkMember<?> each : members) {
+ validateMember(each, errors);
+ }
+ }
+
+ private void validateMember(FrameworkMember<?> member, List<Throwable> errors) {
+ for (RuleValidator strategy : validatorStrategies) {
+ strategy.validate(member, annotation, errors);
+ }
+ }
+
+ private static Builder classRuleValidatorBuilder() {
+ return new Builder(ClassRule.class);
+ }
+
+ private static Builder testRuleValidatorBuilder() {
+ return new Builder(Rule.class);
+ }
+
+ private static class Builder {
+ private final Class<? extends Annotation> annotation;
+ private boolean methods;
+ private final List<RuleValidator> validators;
+
+ private Builder(Class<? extends Annotation> annotation) {
+ this.annotation = annotation;
+ this.methods = false;
+ this.validators = new ArrayList<RuleValidator>();
+ }
+
+ Builder forMethods() {
+ methods = true;
+ return this;
+ }
+
+ Builder withValidator(RuleValidator validator) {
+ validators.add(validator);
+ return this;
+ }
+
+ RuleMemberValidator build() {
+ return new RuleMemberValidator(this);
+ }
+ }
+
+ private static boolean isRuleType(FrameworkMember<?> member) {
+ return isMethodRule(member) || isTestRule(member);
+ }
+
+ private static boolean isTestRule(FrameworkMember<?> member) {
+ return TestRule.class.isAssignableFrom(member.getType());
+ }
+
+ private static boolean isMethodRule(FrameworkMember<?> member) {
+ return MethodRule.class.isAssignableFrom(member.getType());
+ }
+
+ /**
+ * Encapsulates a single piece of validation logic, used to determine if {@link org.junit.Rule} and
+ * {@link org.junit.ClassRule} annotations have been used correctly
+ */
+ interface RuleValidator {
+ /**
+ * Examine the given member and add any violations of the strategy's validation logic to the given list of errors
+ * @param member The member (field or member) to examine
+ * @param annotation The type of rule annotation on the member
+ * @param errors The list of errors to add validation violations to
+ */
+ void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors);
+ }
+
+ /**
+ * Requires the validated member to be non-static
+ */
+ private static final class MemberMustBeNonStaticOrAlsoClassRule implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ boolean isMethodRuleMember = isMethodRule(member);
+ boolean isClassRuleAnnotated = (member.getAnnotation(ClassRule.class) != null);
+
+ // We disallow:
+ // - static MethodRule members
+ // - static @Rule annotated members
+ // - UNLESS they're also @ClassRule annotated
+ // Note that MethodRule cannot be annotated with @ClassRule
+ if (member.isStatic() && (isMethodRuleMember || !isClassRuleAnnotated)) {
+ String message;
+ if (isMethodRule(member)) {
+ message = "must not be static.";
+ } else {
+ message = "must not be static or it must be annotated with @ClassRule.";
+ }
+ errors.add(new ValidationError(member, annotation, message));
+ }
+ }
+ }
+
+ /**
+ * Requires the member to be static
+ */
+ private static final class MemberMustBeStatic implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!member.isStatic()) {
+ errors.add(new ValidationError(member, annotation,
+ "must be static."));
+ }
+ }
+ }
+
+ /**
+ * Requires the member's declaring class to be public
+ */
+ private static final class DeclaringClassMustBePublic implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!isDeclaringClassPublic(member)) {
+ errors.add(new ValidationError(member, annotation,
+ "must be declared in a public class."));
+ }
+ }
+
+ private boolean isDeclaringClassPublic(FrameworkMember<?> member) {
+ return Modifier.isPublic(member.getDeclaringClass().getModifiers());
+ }
+ }
+
+ /**
+ * Requires the member to be public
+ */
+ private static final class MemberMustBePublic implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!member.isPublic()) {
+ errors.add(new ValidationError(member, annotation,
+ "must be public."));
+ }
+ }
+ }
+
+ /**
+ * Requires the member is a field implementing {@link org.junit.rules.MethodRule} or {@link org.junit.rules.TestRule}
+ */
+ private static final class FieldMustBeARule implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!isRuleType(member)) {
+ errors.add(new ValidationError(member, annotation,
+ "must implement MethodRule or TestRule."));
+ }
+ }
+ }
+
+ /**
+ * Require the member to return an implementation of {@link org.junit.rules.MethodRule} or
+ * {@link org.junit.rules.TestRule}
+ */
+ private static final class MethodMustBeARule implements RuleValidator {
+ public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!isRuleType(member)) {
+ errors.add(new ValidationError(member, annotation,
+ "must return an implementation of MethodRule or TestRule."));
+ }
+ }
+ }
+
+ /**
+ * Require the member to return an implementation of {@link org.junit.rules.TestRule}
+ */
+ private static final class MethodMustBeATestRule implements RuleValidator {
+ public void validate(FrameworkMember<?> member,
+ Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!isTestRule(member)) {
+ errors.add(new ValidationError(member, annotation,
+ "must return an implementation of TestRule."));
+ }
+ }
+ }
+
+ /**
+ * Requires the member is a field implementing {@link org.junit.rules.TestRule}
+ */
+ private static final class FieldMustBeATestRule implements RuleValidator {
+
+ public void validate(FrameworkMember<?> member,
+ Class<? extends Annotation> annotation, List<Throwable> errors) {
+ if (!isTestRule(member)) {
+ errors.add(new ValidationError(member, annotation,
+ "must implement TestRule."));
+ }
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java
new file mode 100644
index 0000000..31bd660
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/rules/ValidationError.java
@@ -0,0 +1,14 @@
+package org.junit.internal.runners.rules;
+
+import org.junit.runners.model.FrameworkMember;
+
+import java.lang.annotation.Annotation;
+
+class ValidationError extends Exception {
+
+ private static final long serialVersionUID = 3176511008672645574L;
+
+ public ValidationError(FrameworkMember<?> member, Class<? extends Annotation> annotation, String suffix) {
+ super(String.format("The @%s '%s' %s", annotation.getSimpleName(), member.getName(), suffix));
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java
new file mode 100644
index 0000000..9a2a952
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/ExpectException.java
@@ -0,0 +1,38 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.Statement;
+
+public class ExpectException extends Statement {
+ private final Statement next;
+ private final Class<? extends Throwable> expected;
+
+ public ExpectException(Statement next, Class<? extends Throwable> expected) {
+ this.next = next;
+ this.expected = expected;
+ }
+
+ @Override
+ public void evaluate() throws Exception {
+ boolean complete = false;
+ try {
+ next.evaluate();
+ complete = true;
+ } catch (AssumptionViolatedException e) {
+ if (!expected.isAssignableFrom(e.getClass())) {
+ throw e;
+ }
+ } catch (Throwable e) {
+ if (!expected.isAssignableFrom(e.getClass())) {
+ String message = "Unexpected exception, expected<"
+ + expected.getName() + "> but was<"
+ + e.getClass().getName() + ">";
+ throw new Exception(message, e);
+ }
+ }
+ if (complete) {
+ throw new AssertionError("Expected exception: "
+ + expected.getName());
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java
new file mode 100644
index 0000000..e55875c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/Fail.java
@@ -0,0 +1,16 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.runners.model.Statement;
+
+public class Fail extends Statement {
+ private final Throwable error;
+
+ public Fail(Throwable e) {
+ error = e;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ throw error;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
new file mode 100644
index 0000000..9362cc1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
@@ -0,0 +1,312 @@
+package org.junit.internal.runners.statements;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.internal.management.ManagementFactory;
+import org.junit.internal.management.ThreadMXBean;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestTimedOutException;
+
+public class FailOnTimeout extends Statement {
+ private final Statement originalStatement;
+ private final TimeUnit timeUnit;
+ private final long timeout;
+ private final boolean lookForStuckThread;
+
+ /**
+ * Returns a new builder for building an instance.
+ *
+ * @since 4.12
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Creates an instance wrapping the given statement with the given timeout in milliseconds.
+ *
+ * @param statement the statement to wrap
+ * @param timeoutMillis the timeout in milliseconds
+ * @deprecated use {@link #builder()} instead.
+ */
+ @Deprecated
+ public FailOnTimeout(Statement statement, long timeoutMillis) {
+ this(builder().withTimeout(timeoutMillis, TimeUnit.MILLISECONDS), statement);
+ }
+
+ private FailOnTimeout(Builder builder, Statement statement) {
+ originalStatement = statement;
+ timeout = builder.timeout;
+ timeUnit = builder.unit;
+ lookForStuckThread = builder.lookForStuckThread;
+ }
+
+ /**
+ * Builder for {@link FailOnTimeout}.
+ *
+ * @since 4.12
+ */
+ public static class Builder {
+ private boolean lookForStuckThread = false;
+ private long timeout = 0;
+ private TimeUnit unit = TimeUnit.SECONDS;
+
+ private Builder() {
+ }
+
+ /**
+ * Specifies the time to wait before timing out the test.
+ *
+ * <p>If this is not called, or is called with a {@code timeout} of
+ * {@code 0}, the returned {@code Statement} will wait forever for the
+ * test to complete, however the test will still launch from a separate
+ * thread. This can be useful for disabling timeouts in environments
+ * where they are dynamically set based on some property.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the {@code timeout} argument
+ * @return {@code this} for method chaining.
+ */
+ public Builder withTimeout(long timeout, TimeUnit unit) {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout must be non-negative");
+ }
+ if (unit == null) {
+ throw new NullPointerException("TimeUnit cannot be null");
+ }
+ this.timeout = timeout;
+ this.unit = unit;
+ return this;
+ }
+
+ /**
+ * Specifies whether to look for a stuck thread. If a timeout occurs and this
+ * feature is enabled, the test will look for a thread that appears to be stuck
+ * and dump its backtrace. This feature is experimental. Behavior may change
+ * after the 4.12 release in response to feedback.
+ *
+ * @param enable {@code true} to enable the feature
+ * @return {@code this} for method chaining.
+ */
+ public Builder withLookingForStuckThread(boolean enable) {
+ this.lookForStuckThread = enable;
+ return this;
+ }
+
+ /**
+ * Builds a {@link FailOnTimeout} instance using the values in this builder,
+ * wrapping the given statement.
+ *
+ * @param statement
+ */
+ public FailOnTimeout build(Statement statement) {
+ if (statement == null) {
+ throw new NullPointerException("statement cannot be null");
+ }
+ return new FailOnTimeout(this, statement);
+ }
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ CallableStatement callable = new CallableStatement();
+ FutureTask<Throwable> task = new FutureTask<Throwable>(callable);
+ ThreadGroup threadGroup = threadGroupForNewThread();
+ Thread thread = new Thread(threadGroup, task, "Time-limited test");
+ thread.setDaemon(true);
+ thread.start();
+ callable.awaitStarted();
+ Throwable throwable = getResult(task, thread);
+ if (throwable != null) {
+ throw throwable;
+ }
+ }
+
+ private ThreadGroup threadGroupForNewThread() {
+ if (!lookForStuckThread) {
+ // Use the default ThreadGroup (usually the one from the current
+ // thread).
+ return null;
+ }
+
+ // Create the thread in a new ThreadGroup, so if the time-limited thread
+ // becomes stuck, getStuckThread() can find the thread likely to be the
+ // culprit.
+ ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup");
+ if (!threadGroup.isDaemon()) {
+ // Mark the new ThreadGroup as a daemon thread group, so it will be
+ // destroyed after the time-limited thread completes. By ensuring the
+ // ThreadGroup is destroyed, any data associated with the ThreadGroup
+ // (ex: via java.beans.ThreadGroupContext) is destroyed.
+ try {
+ threadGroup.setDaemon(true);
+ } catch (SecurityException e) {
+ // Swallow the exception to keep the same behavior as in JUnit 4.12.
+ }
+ }
+ return threadGroup;
+ }
+
+ /**
+ * Wait for the test task, returning the exception thrown by the test if the
+ * test failed, an exception indicating a timeout if the test timed out, or
+ * {@code null} if the test passed.
+ */
+ private Throwable getResult(FutureTask<Throwable> task, Thread thread) {
+ try {
+ if (timeout > 0) {
+ return task.get(timeout, timeUnit);
+ } else {
+ return task.get();
+ }
+ } catch (InterruptedException e) {
+ return e; // caller will re-throw; no need to call Thread.interrupt()
+ } catch (ExecutionException e) {
+ // test failed; have caller re-throw the exception thrown by the test
+ return e.getCause();
+ } catch (TimeoutException e) {
+ return createTimeoutException(thread);
+ }
+ }
+
+ private Exception createTimeoutException(Thread thread) {
+ StackTraceElement[] stackTrace = thread.getStackTrace();
+ final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null;
+ Exception currThreadException = new TestTimedOutException(timeout, timeUnit);
+ if (stackTrace != null) {
+ currThreadException.setStackTrace(stackTrace);
+ thread.interrupt();
+ }
+ if (stuckThread != null) {
+ Exception stuckThreadException =
+ new Exception("Appears to be stuck in thread " +
+ stuckThread.getName());
+ stuckThreadException.setStackTrace(getStackTrace(stuckThread));
+ return new MultipleFailureException(
+ Arrays.<Throwable>asList(currThreadException, stuckThreadException));
+ } else {
+ return currThreadException;
+ }
+ }
+
+ /**
+ * Retrieves the stack trace for a given thread.
+ * @param thread The thread whose stack is to be retrieved.
+ * @return The stack trace; returns a zero-length array if the thread has
+ * terminated or the stack cannot be retrieved for some other reason.
+ */
+ private StackTraceElement[] getStackTrace(Thread thread) {
+ try {
+ return thread.getStackTrace();
+ } catch (SecurityException e) {
+ return new StackTraceElement[0];
+ }
+ }
+
+ /**
+ * Determines whether the test appears to be stuck in some thread other than
+ * the "main thread" (the one created to run the test). This feature is experimental.
+ * Behavior may change after the 4.12 release in response to feedback.
+ * @param mainThread The main thread created by {@code evaluate()}
+ * @return The thread which appears to be causing the problem, if different from
+ * {@code mainThread}, or {@code null} if the main thread appears to be the
+ * problem or if the thread cannot be determined. The return value is never equal
+ * to {@code mainThread}.
+ */
+ private Thread getStuckThread(Thread mainThread) {
+ List<Thread> threadsInGroup = getThreadsInGroup(mainThread.getThreadGroup());
+ if (threadsInGroup.isEmpty()) {
+ return null;
+ }
+
+ // Now that we have all the threads in the test's thread group: Assume that
+ // any thread we're "stuck" in is RUNNABLE. Look for all RUNNABLE threads.
+ // If just one, we return that (unless it equals threadMain). If there's more
+ // than one, pick the one that's using the most CPU time, if this feature is
+ // supported.
+ Thread stuckThread = null;
+ long maxCpuTime = 0;
+ for (Thread thread : threadsInGroup) {
+ if (thread.getState() == Thread.State.RUNNABLE) {
+ long threadCpuTime = cpuTime(thread);
+ if (stuckThread == null || threadCpuTime > maxCpuTime) {
+ stuckThread = thread;
+ maxCpuTime = threadCpuTime;
+ }
+ }
+ }
+ return (stuckThread == mainThread) ? null : stuckThread;
+ }
+
+ /**
+ * Returns all active threads belonging to a thread group.
+ * @param group The thread group.
+ * @return The active threads in the thread group. The result should be a
+ * complete list of the active threads at some point in time. Returns an empty list
+ * if this cannot be determined, e.g. because new threads are being created at an
+ * extremely fast rate.
+ */
+ private List<Thread> getThreadsInGroup(ThreadGroup group) {
+ final int activeThreadCount = group.activeCount(); // this is just an estimate
+ int threadArraySize = Math.max(activeThreadCount * 2, 100);
+ for (int loopCount = 0; loopCount < 5; loopCount++) {
+ Thread[] threads = new Thread[threadArraySize];
+ int enumCount = group.enumerate(threads);
+ if (enumCount < threadArraySize) {
+ return Arrays.asList(threads).subList(0, enumCount);
+ }
+ // if there are too many threads to fit into the array, enumerate's result
+ // is >= the array's length; therefore we can't trust that it returned all
+ // the threads. Try again.
+ threadArraySize += 100;
+ }
+ // threads are proliferating too fast for us. Bail before we get into
+ // trouble.
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns the CPU time used by a thread, if possible.
+ * @param thr The thread to query.
+ * @return The CPU time used by {@code thr}, or 0 if it cannot be determined.
+ */
+ private long cpuTime(Thread thr) {
+ ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
+ if (mxBean.isThreadCpuTimeSupported()) {
+ try {
+ return mxBean.getThreadCpuTime(thr.getId());
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+ return 0;
+ }
+
+ private class CallableStatement implements Callable<Throwable> {
+ private final CountDownLatch startLatch = new CountDownLatch(1);
+
+ public Throwable call() throws Exception {
+ try {
+ startLatch.countDown();
+ originalStatement.evaluate();
+ } catch (Exception e) {
+ throw e;
+ } catch (Throwable e) {
+ return e;
+ }
+ return null;
+ }
+
+ public void awaitStarted() throws InterruptedException {
+ startLatch.await();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java
new file mode 100644
index 0000000..68c0545
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/InvokeMethod.java
@@ -0,0 +1,19 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class InvokeMethod extends Statement {
+ private final FrameworkMethod testMethod;
+ private final Object target;
+
+ public InvokeMethod(FrameworkMethod testMethod, Object target) {
+ this.testMethod = testMethod;
+ this.target = target;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ testMethod.invokeExplosively(target);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java
new file mode 100644
index 0000000..5e56c33
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunAfters.java
@@ -0,0 +1,48 @@
+package org.junit.internal.runners.statements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+public class RunAfters extends Statement {
+ private final Statement next;
+
+ private final Object target;
+
+ private final List<FrameworkMethod> afters;
+
+ public RunAfters(Statement next, List<FrameworkMethod> afters, Object target) {
+ this.next = next;
+ this.afters = afters;
+ this.target = target;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ List<Throwable> errors = new ArrayList<Throwable>();
+ try {
+ next.evaluate();
+ } catch (Throwable e) {
+ errors.add(e);
+ } finally {
+ for (FrameworkMethod each : afters) {
+ try {
+ invokeMethod(each);
+ } catch (Throwable e) {
+ errors.add(e);
+ }
+ }
+ }
+ MultipleFailureException.assertEmpty(errors);
+ }
+
+ /**
+ * @since 4.13
+ */
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ method.invokeExplosively(target);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java
new file mode 100644
index 0000000..bd835c7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/internal/runners/statements/RunBefores.java
@@ -0,0 +1,35 @@
+package org.junit.internal.runners.statements;
+
+import java.util.List;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class RunBefores extends Statement {
+ private final Statement next;
+
+ private final Object target;
+
+ private final List<FrameworkMethod> befores;
+
+ public RunBefores(Statement next, List<FrameworkMethod> befores, Object target) {
+ this.next = next;
+ this.befores = befores;
+ this.target = target;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ for (FrameworkMethod before : befores) {
+ invokeMethod(before);
+ }
+ next.evaluate();
+ }
+
+ /**
+ * @since 4.13
+ */
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ method.invokeExplosively(target);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java b/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java
new file mode 100644
index 0000000..13407cc
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/matchers/JUnitMatchers.java
@@ -0,0 +1,113 @@
+package org.junit.matchers;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.CombinableMatcher.CombinableBothMatcher;
+import org.hamcrest.core.CombinableMatcher.CombinableEitherMatcher;
+import org.junit.internal.matchers.StacktracePrintingMatcher;
+
+/**
+ * Convenience import class: these are useful matchers for use with the assertThat method, but they are
+ * not currently included in the basic CoreMatchers class from hamcrest.
+ *
+ * @since 4.4
+ */
+public class JUnitMatchers {
+ /**
+ * @return A matcher matching any collection containing element
+ * @deprecated Please use {@link CoreMatchers#hasItem(Object)} instead.
+ */
+ @Deprecated
+ public static <T> Matcher<Iterable<? super T>> hasItem(T element) {
+ return CoreMatchers.hasItem(element);
+ }
+
+ /**
+ * @return A matcher matching any collection containing an element matching elementMatcher
+ * @deprecated Please use {@link CoreMatchers#hasItem(Matcher)} instead.
+ */
+ @Deprecated
+ public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> elementMatcher) {
+ return CoreMatchers.<T>hasItem(elementMatcher);
+ }
+
+ /**
+ * @return A matcher matching any collection containing every element in elements
+ * @deprecated Please use {@link CoreMatchers#hasItems(Object...)} instead.
+ */
+ @Deprecated
+ public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
+ return CoreMatchers.hasItems(elements);
+ }
+
+ /**
+ * @return A matcher matching any collection containing at least one element that matches
+ * each matcher in elementMatcher (this may be one element matching all matchers,
+ * or different elements matching each matcher)
+ * @deprecated Please use {@link CoreMatchers#hasItems(Matcher...)} instead.
+ */
+ @Deprecated
+ public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... elementMatchers) {
+ return CoreMatchers.hasItems(elementMatchers);
+ }
+
+ /**
+ * @return A matcher matching any collection in which every element matches elementMatcher
+ * @deprecated Please use {@link CoreMatchers#everyItem(Matcher)} instead.
+ */
+ @Deprecated
+ public static <T> Matcher<Iterable<T>> everyItem(final Matcher<T> elementMatcher) {
+ return CoreMatchers.everyItem(elementMatcher);
+ }
+
+ /**
+ * @return a matcher matching any string that contains substring
+ * @deprecated Please use {@link CoreMatchers#containsString(String)} instead.
+ */
+ @Deprecated
+ public static Matcher<java.lang.String> containsString(java.lang.String substring) {
+ return CoreMatchers.containsString(substring);
+ }
+
+ /**
+ * This is useful for fluently combining matchers that must both pass. For example:
+ * <pre>
+ * assertThat(string, both(containsString("a")).and(containsString("b")));
+ * </pre>
+ *
+ * @deprecated Please use {@link CoreMatchers#both(Matcher)} instead.
+ */
+ @Deprecated
+ public static <T> CombinableBothMatcher<T> both(Matcher<? super T> matcher) {
+ return CoreMatchers.both(matcher);
+ }
+
+ /**
+ * This is useful for fluently combining matchers where either may pass, for example:
+ * <pre>
+ * assertThat(string, either(containsString("a")).or(containsString("b")));
+ * </pre>
+ *
+ * @deprecated Please use {@link CoreMatchers#either(Matcher)} instead.
+ */
+ @Deprecated
+ public static <T> CombinableEitherMatcher<T> either(Matcher<? super T> matcher) {
+ return CoreMatchers.either(matcher);
+ }
+
+ /**
+ * @return A matcher that delegates to throwableMatcher and in addition
+ * appends the stacktrace of the actual Throwable in case of a mismatch.
+ */
+ public static <T extends Throwable> Matcher<T> isThrowable(Matcher<T> throwableMatcher) {
+ return StacktracePrintingMatcher.isThrowable(throwableMatcher);
+ }
+
+ /**
+ * @return A matcher that delegates to exceptionMatcher and in addition
+ * appends the stacktrace of the actual Exception in case of a mismatch.
+ */
+ public static <T extends Exception> Matcher<T> isException(Matcher<T> exceptionMatcher) {
+ return StacktracePrintingMatcher.isException(exceptionMatcher);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java
new file mode 100644
index 0000000..71aca34
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/matchers/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * Provides useful additional {@link org.hamcrest.Matcher}s for use with
+ * the {@link org.junit.Assert#assertThat(Object, org.hamcrest.Matcher)}
+ * statement
+ *
+ * @since 4.0
+ * @see org.junit.matchers.JUnitMatchers
+ */
+package org.junit.matchers;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/package-info.java
new file mode 100644
index 0000000..fb12f25
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Provides JUnit core classes and annotations.
+ *
+ * Corresponds to junit.framework in Junit 3.x.
+ *
+ * @since 4.0
+ */
+package org.junit;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java
new file mode 100644
index 0000000..3bca103
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/DisableOnDebug.java
@@ -0,0 +1,125 @@
+package org.junit.rules;
+
+import java.util.List;
+
+import org.junit.internal.management.ManagementFactory;
+import org.junit.internal.management.RuntimeMXBean;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code DisableOnDebug} Rule allows you to label certain rules to be
+ * disabled when debugging.
+ * <p>
+ * The most illustrative use case is for tests that make use of the
+ * {@link Timeout} rule, when ran in debug mode the test may terminate on
+ * timeout abruptly during debugging. Developers may disable the timeout, or
+ * increase the timeout by making a code change on tests that need debugging and
+ * remember revert the change afterwards or rules such as {@link Timeout} that
+ * may be disabled during debugging may be wrapped in a {@code DisableOnDebug}.
+ * <p>
+ * The important benefit of this feature is that you can disable such rules
+ * without any making any modifications to your test class to remove them during
+ * debugging.
+ * <p>
+ * This does nothing to tackle timeouts or time sensitive code under test when
+ * debugging and may make this less useful in such circumstances.
+ * <p>
+ * Example usage:
+ *
+ * <pre>
+ * public static class DisableTimeoutOnDebugSampleTest {
+ *
+ * @Rule
+ * public TestRule timeout = new DisableOnDebug(new Timeout(20));
+ *
+ * @Test
+ * public void myTest() {
+ * int i = 0;
+ * assertEquals(0, i); // suppose you had a break point here to inspect i
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.12
+ */
+public class DisableOnDebug implements TestRule {
+ private final TestRule rule;
+ private final boolean debugging;
+
+ /**
+ * Create a {@code DisableOnDebug} instance with the timeout specified in
+ * milliseconds.
+ *
+ * @param rule to disable during debugging
+ */
+ public DisableOnDebug(TestRule rule) {
+ this(rule, ManagementFactory.getRuntimeMXBean()
+ .getInputArguments());
+ }
+
+ /**
+ * Visible for testing purposes only.
+ *
+ * @param rule the rule to disable during debugging
+ * @param inputArguments
+ * arguments provided to the Java runtime
+ */
+ DisableOnDebug(TestRule rule, List<String> inputArguments) {
+ this.rule = rule;
+ debugging = isDebugging(inputArguments);
+ }
+
+ /**
+ * @see TestRule#apply(Statement, Description)
+ */
+ public Statement apply(Statement base, Description description) {
+ if (debugging) {
+ return base;
+ } else {
+ return rule.apply(base, description);
+ }
+ }
+
+ /**
+ * Parses arguments passed to the runtime environment for debug flags
+ * <p>
+ * Options specified in:
+ * <ul>
+ * <li>
+ * <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-6</a></li>
+ * <li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-7</a></li>
+ * <li><a href="http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html#Invocation"
+ * >javase-8</a></li>
+ *
+ *
+ * @param arguments
+ * the arguments passed to the runtime environment, usually this
+ * will be {@link RuntimeMXBean#getInputArguments()}
+ * @return true if the current JVM was started in debug mode, false
+ * otherwise.
+ */
+ private static boolean isDebugging(List<String> arguments) {
+ for (final String argument : arguments) {
+ if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if the JVM is in debug mode. This method may be used
+ * by test classes to take additional action to disable code paths that
+ * interfere with debugging if required.
+ *
+ * @return {@code true} if the current JVM is in debug mode, {@code false}
+ * otherwise
+ */
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java
new file mode 100644
index 0000000..9711e50
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ErrorCollector.java
@@ -0,0 +1,120 @@
+package org.junit.rules;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertThrows;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.AssumptionViolatedException;
+import org.hamcrest.Matcher;
+import org.junit.runners.model.MultipleFailureException;
+
+/**
+ * The ErrorCollector rule allows execution of a test to continue after the
+ * first problem is found (for example, to collect _all_ the incorrect rows in a
+ * table, and report them all at once):
+ *
+ * <pre>
+ * public static class UsesErrorCollectorTwice {
+ * @Rule
+ * public ErrorCollector collector= new ErrorCollector();
+ *
+ * @Test
+ * public void example() {
+ * collector.addError(new Throwable("first thing went wrong"));
+ * collector.addError(new Throwable("second thing went wrong"));
+ * collector.checkThat(getResult(), not(containsString("ERROR!")));
+ * // all lines will run, and then a combined failure logged at the end.
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class ErrorCollector extends Verifier {
+ private List<Throwable> errors = new ArrayList<Throwable>();
+
+ @Override
+ protected void verify() throws Throwable {
+ MultipleFailureException.assertEmpty(errors);
+ }
+
+ /**
+ * Adds a Throwable to the table. Execution continues, but the test will fail at the end.
+ */
+ public void addError(Throwable error) {
+ if (error == null) {
+ throw new NullPointerException("Error cannot be null");
+ }
+ if (error instanceof AssumptionViolatedException) {
+ AssertionError e = new AssertionError(error.getMessage());
+ e.initCause(error);
+ errors.add(e);
+ } else {
+ errors.add(error);
+ }
+ }
+
+ /**
+ * Adds a failure to the table if {@code matcher} does not match {@code value}.
+ * Execution continues, but the test will fail at the end if the match fails.
+ */
+ public <T> void checkThat(final T value, final Matcher<T> matcher) {
+ checkThat("", value, matcher);
+ }
+
+ /**
+ * Adds a failure with the given {@code reason}
+ * to the table if {@code matcher} does not match {@code value}.
+ * Execution continues, but the test will fail at the end if the match fails.
+ */
+ public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
+ checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ assertThat(reason, value, matcher);
+ return value;
+ }
+ });
+ }
+
+ /**
+ * Adds to the table the exception, if any, thrown from {@code callable}.
+ * Execution continues, but the test will fail at the end if
+ * {@code callable} threw an exception.
+ */
+ public <T> T checkSucceeds(Callable<T> callable) {
+ try {
+ return callable.call();
+ } catch (AssumptionViolatedException e) {
+ AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
+ error.initCause(e);
+ addError(error);
+ return null;
+ } catch (Throwable e) {
+ addError(e);
+ return null;
+ }
+ }
+
+ /**
+ * Adds a failure to the table if {@code runnable} does not throw an
+ * exception of type {@code expectedThrowable} when executed.
+ * Execution continues, but the test will fail at the end if the runnable
+ * does not throw an exception, or if it throws a different exception.
+ *
+ * @param expectedThrowable the expected type of the exception
+ * @param runnable a function that is expected to throw an exception when executed
+ * @since 4.13
+ */
+ public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
+ try {
+ assertThrows(expectedThrowable, runnable);
+ } catch (AssertionError e) {
+ addError(e);
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java
new file mode 100644
index 0000000..431ad49
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedException.java
@@ -0,0 +1,285 @@
+package org.junit.rules;
+
+import static java.lang.String.format;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause;
+import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+import org.junit.AssumptionViolatedException;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code ExpectedException} rule allows you to verify that your code
+ * throws a specific exception.
+ *
+ * <h3>Usage</h3>
+ *
+ * <pre> public class SimpleExpectedExceptionTest {
+ * @Rule
+ * public ExpectedException thrown = ExpectedException.none();
+ *
+ * @Test
+ * public void throwsNothing() {
+ * // no exception expected, none thrown: passes.
+ * }
+ *
+ * @Test
+ * public void throwsExceptionWithSpecificType() {
+ * thrown.expect(NullPointerException.class);
+ * throw new NullPointerException();
+ * }
+ * }</pre>
+ *
+ * <p>You have to add the {@code ExpectedException} rule to your test.
+ * This doesn't affect your existing tests (see {@code throwsNothing()}).
+ * After specifying the type of the expected exception your test is
+ * successful when such an exception is thrown and it fails if a
+ * different or no exception is thrown.
+ *
+ * <p>This rule does not perform any special magic to make execution continue
+ * as if the exception had not been thrown. So it is nearly always a mistake
+ * for a test method to have statements after the one that is expected to
+ * throw the exception.
+ *
+ * <p>Instead of specifying the exception's type you can characterize the
+ * expected exception based on other criteria, too:
+ *
+ * <ul>
+ * <li>The exception's message contains a specific text: {@link #expectMessage(String)}</li>
+ * <li>The exception's message complies with a Hamcrest matcher: {@link #expectMessage(Matcher)}</li>
+ * <li>The exception's cause complies with a Hamcrest matcher: {@link #expectCause(Matcher)}</li>
+ * <li>The exception itself complies with a Hamcrest matcher: {@link #expect(Matcher)}</li>
+ * </ul>
+ *
+ * <p>You can combine any of the presented expect-methods. The test is
+ * successful if all specifications are met.
+ * <pre> @Test
+ * public void throwsException() {
+ * thrown.expect(NullPointerException.class);
+ * thrown.expectMessage("happened");
+ * throw new NullPointerException("What happened?");
+ * }</pre>
+ *
+ * <p>It is recommended to set the {@link org.junit.Rule#order() order} of the
+ * {@code ExpectedException} to {@code Integer.MAX_VALUE} if it is used together
+ * with another rule that handles exceptions, e.g. {@link ErrorCollector}.
+ * Otherwise failing tests may be successful.
+ * <pre> @Rule(order = Integer.MAX_VALUE)
+ * public ExpectedException thrown = ExpectedException.none();</pre>
+ *
+ * <h3>AssumptionViolatedExceptions</h3>
+ * <p>JUnit uses {@link AssumptionViolatedException}s for indicating that a test
+ * provides no useful information. (See {@link org.junit.Assume} for more
+ * information.) You have to call {@code assume} methods before you set
+ * expectations of the {@code ExpectedException} rule. In this case the rule
+ * will not handle consume the exceptions and it can be handled by the
+ * framework. E.g. the following test is ignored by JUnit's default runner.
+ *
+ * <pre> @Test
+ * public void ignoredBecauseOfFailedAssumption() {
+ * assumeTrue(false); // throws AssumptionViolatedException
+ * thrown.expect(NullPointerException.class);
+ * }</pre>
+ *
+ * <h3>AssertionErrors</h3>
+ *
+ * <p>JUnit uses {@link AssertionError}s for indicating that a test is failing. You
+ * have to call {@code assert} methods before you set expectations of the
+ * {@code ExpectedException} rule, if they should be handled by the framework.
+ * E.g. the following test fails because of the {@code assertTrue} statement.
+ *
+ * <pre> @Test
+ * public void throwsUnhandled() {
+ * assertTrue(false); // throws AssertionError
+ * thrown.expect(NullPointerException.class);
+ * }</pre>
+ *
+ * <h3>Missing Exceptions</h3>
+ * <p>By default missing exceptions are reported with an error message
+ * like "Expected test to throw an instance of foo". You can configure a different
+ * message by means of {@link #reportMissingExceptionWithMessage(String)}. You
+ * can use a {@code %s} placeholder for the description of the expected
+ * exception. E.g. "Test doesn't throw %s." will fail with the error message
+ * "Test doesn't throw an instance of foo.".
+ *
+ * @since 4.7
+ */
+public class ExpectedException implements TestRule {
+ /**
+ * Returns a {@linkplain TestRule rule} that expects no exception to
+ * be thrown (identical to behavior without this rule).
+ *
+ * @deprecated Since 4.13
+ * {@link org.junit.Assert#assertThrows(Class, org.junit.function.ThrowingRunnable)
+ * Assert.assertThrows} can be used to verify that your code throws a specific
+ * exception.
+ */
+ @Deprecated
+ public static ExpectedException none() {
+ return new ExpectedException();
+ }
+
+ private final ExpectedExceptionMatcherBuilder matcherBuilder = new ExpectedExceptionMatcherBuilder();
+
+ private String missingExceptionMessage= "Expected test to throw %s";
+
+ private ExpectedException() {
+ }
+
+ /**
+ * This method does nothing. Don't use it.
+ * @deprecated AssertionErrors are handled by default since JUnit 4.12. Just
+ * like in JUnit <= 4.10.
+ */
+ @Deprecated
+ public ExpectedException handleAssertionErrors() {
+ return this;
+ }
+
+ /**
+ * This method does nothing. Don't use it.
+ * @deprecated AssumptionViolatedExceptions are handled by default since
+ * JUnit 4.12. Just like in JUnit <= 4.10.
+ */
+ @Deprecated
+ public ExpectedException handleAssumptionViolatedExceptions() {
+ return this;
+ }
+
+ /**
+ * Specifies the failure message for tests that are expected to throw
+ * an exception but do not throw any. You can use a {@code %s} placeholder for
+ * the description of the expected exception. E.g. "Test doesn't throw %s."
+ * will fail with the error message
+ * "Test doesn't throw an instance of foo.".
+ *
+ * @param message exception detail message
+ * @return the rule itself
+ */
+ public ExpectedException reportMissingExceptionWithMessage(String message) {
+ missingExceptionMessage = message;
+ return this;
+ }
+
+ public Statement apply(Statement base,
+ org.junit.runner.Description description) {
+ return new ExpectedExceptionStatement(base);
+ }
+
+ /**
+ * Verify that your code throws an exception that is matched by
+ * a Hamcrest matcher.
+ * <pre> @Test
+ * public void throwsExceptionThatCompliesWithMatcher() {
+ * NullPointerException e = new NullPointerException();
+ * thrown.expect(is(e));
+ * throw e;
+ * }</pre>
+ */
+ public void expect(Matcher<?> matcher) {
+ matcherBuilder.add(matcher);
+ }
+
+ /**
+ * Verify that your code throws an exception that is an
+ * instance of specific {@code type}.
+ * <pre> @Test
+ * public void throwsExceptionWithSpecificType() {
+ * thrown.expect(NullPointerException.class);
+ * throw new NullPointerException();
+ * }</pre>
+ */
+ public void expect(Class<? extends Throwable> type) {
+ expect(instanceOf(type));
+ }
+
+ /**
+ * Verify that your code throws an exception whose message contains
+ * a specific text.
+ * <pre> @Test
+ * public void throwsExceptionWhoseMessageContainsSpecificText() {
+ * thrown.expectMessage("happened");
+ * throw new NullPointerException("What happened?");
+ * }</pre>
+ */
+ public void expectMessage(String substring) {
+ expectMessage(containsString(substring));
+ }
+
+ /**
+ * Verify that your code throws an exception whose message is matched
+ * by a Hamcrest matcher.
+ * <pre> @Test
+ * public void throwsExceptionWhoseMessageCompliesWithMatcher() {
+ * thrown.expectMessage(startsWith("What"));
+ * throw new NullPointerException("What happened?");
+ * }</pre>
+ */
+ public void expectMessage(Matcher<String> matcher) {
+ expect(hasMessage(matcher));
+ }
+
+ /**
+ * Verify that your code throws an exception whose cause is matched by
+ * a Hamcrest matcher.
+ * <pre> @Test
+ * public void throwsExceptionWhoseCauseCompliesWithMatcher() {
+ * NullPointerException expectedCause = new NullPointerException();
+ * thrown.expectCause(is(expectedCause));
+ * throw new IllegalArgumentException("What happened?", cause);
+ * }</pre>
+ */
+ public void expectCause(Matcher<?> expectedCause) {
+ expect(hasCause(expectedCause));
+ }
+
+ /**
+ * Check if any Exception is expected.
+ * @since 4.13
+ */
+ public final boolean isAnyExceptionExpected() {
+ return matcherBuilder.expectsThrowable();
+ }
+
+ private class ExpectedExceptionStatement extends Statement {
+ private final Statement next;
+
+ public ExpectedExceptionStatement(Statement base) {
+ next = base;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ next.evaluate();
+ } catch (Throwable e) {
+ handleException(e);
+ return;
+ }
+ if (isAnyExceptionExpected()) {
+ failDueToMissingException();
+ }
+ }
+ }
+
+ private void handleException(Throwable e) throws Throwable {
+ if (isAnyExceptionExpected()) {
+ assertThat(e, matcherBuilder.build());
+ } else {
+ throw e;
+ }
+ }
+
+ private void failDueToMissingException() throws AssertionError {
+ fail(missingExceptionMessage());
+ }
+
+ private String missingExceptionMessage() {
+ String expectation= StringDescription.toString(matcherBuilder.build());
+ return format(missingExceptionMessage, expectation);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java
new file mode 100644
index 0000000..e7d94c4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExpectedExceptionMatcherBuilder.java
@@ -0,0 +1,46 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.junit.matchers.JUnitMatchers.isThrowable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Builds special matcher used by {@link ExpectedException}.
+ */
+class ExpectedExceptionMatcherBuilder {
+
+ private final List<Matcher<?>> matchers = new ArrayList<Matcher<?>>();
+
+ void add(Matcher<?> matcher) {
+ matchers.add(matcher);
+ }
+
+ boolean expectsThrowable() {
+ return !matchers.isEmpty();
+ }
+
+ Matcher<Throwable> build() {
+ return isThrowable(allOfTheMatchers());
+ }
+
+ private Matcher<Throwable> allOfTheMatchers() {
+ if (matchers.size() == 1) {
+ return cast(matchers.get(0));
+ }
+ return allOf(castedMatchers());
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private List<Matcher<? super Throwable>> castedMatchers() {
+ return new ArrayList<Matcher<? super Throwable>>((List) matchers);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Matcher<Throwable> cast(Matcher<?> singleMatcher) {
+ return (Matcher<Throwable>) singleMatcher;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java
new file mode 100644
index 0000000..71fc842
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java
@@ -0,0 +1,84 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+/**
+ * A base class for Rules (like TemporaryFolder) that set up an external
+ * resource before a test (a file, socket, server, database connection, etc.),
+ * and guarantee to tear it down afterward:
+ *
+ * <pre>
+ * public static class UsesExternalResource {
+ * Server myServer= new Server();
+ *
+ * @Rule
+ * public ExternalResource resource= new ExternalResource() {
+ * @Override
+ * protected void before() throws Throwable {
+ * myServer.connect();
+ * };
+ *
+ * @Override
+ * protected void after() {
+ * myServer.disconnect();
+ * };
+ * };
+ *
+ * @Test
+ * public void testFoo() {
+ * new Client().run(myServer);
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public abstract class ExternalResource implements TestRule {
+ public Statement apply(Statement base, Description description) {
+ return statement(base);
+ }
+
+ private Statement statement(final Statement base) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ before();
+
+ List<Throwable> errors = new ArrayList<Throwable>();
+ try {
+ base.evaluate();
+ } catch (Throwable t) {
+ errors.add(t);
+ } finally {
+ try {
+ after();
+ } catch (Throwable t) {
+ errors.add(t);
+ }
+ }
+ MultipleFailureException.assertEmpty(errors);
+ }
+ };
+ }
+
+ /**
+ * Override to set up your specific external resource.
+ *
+ * @throws Throwable if setup fails (which will disable {@code after}
+ */
+ protected void before() throws Throwable {
+ // do nothing
+ }
+
+ /**
+ * Override to tear down your specific external resource.
+ */
+ protected void after() {
+ // do nothing
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java
new file mode 100644
index 0000000..94608f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/MethodRule.java
@@ -0,0 +1,32 @@
+package org.junit.rules;
+
+import org.junit.Rule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * A MethodRule is an alteration in how a test method is run and reported.
+ * Multiple {@link MethodRule}s can be applied to a test method. The
+ * {@link Statement} that executes the method is passed to each annotated
+ * {@link Rule} in turn, and each may return a substitute or modified
+ * {@link Statement}, which is passed to the next {@link Rule}, if any. For
+ * an example of how this can be useful, see {@link TestWatchman}.
+ *
+ * <p>Note that {@link MethodRule} has been replaced by {@link TestRule},
+ * which has the added benefit of supporting class rules.
+ *
+ * @since 4.7
+ */
+public interface MethodRule {
+ /**
+ * Modifies the method-running {@link Statement} to implement an additional
+ * test-running rule.
+ *
+ * @param base The {@link Statement} to be modified
+ * @param method The method to be run
+ * @param target The object on which the method will be run.
+ * @return a new statement, which may be the same as {@code base},
+ * a wrapper around {@code base}, or a completely new Statement.
+ */
+ Statement apply(Statement base, FrameworkMethod method, Object target);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java
new file mode 100644
index 0000000..bf93aae
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/RuleChain.java
@@ -0,0 +1,113 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * The {@code RuleChain} can be used for creating composite rules. You create a
+ * {@code RuleChain} with {@link #outerRule(TestRule)} and subsequent calls of
+ * {@link #around(TestRule)}:
+ *
+ * <pre>
+ * public abstract class CompositeRules {
+ * public static TestRule extendedLogging() {
+ * return RuleChain.outerRule(new LoggingRule("outer rule"))
+ * .around(new LoggingRule("middle rule"))
+ * .around(new LoggingRule("inner rule"));
+ * }
+ * }
+ * </pre>
+ *
+ * <pre>
+ * public class UseRuleChain {
+ * @Rule
+ * public final TestRule extendedLogging = CompositeRules.extendedLogging();
+ *
+ * @Test
+ * public void example() {
+ * assertTrue(true);
+ * }
+ * }
+ * </pre>
+ *
+ * writes the log
+ *
+ * <pre>
+ * starting outer rule
+ * starting middle rule
+ * starting inner rule
+ * finished inner rule
+ * finished middle rule
+ * finished outer rule
+ * </pre>
+ *
+ * In older versions of JUnit (before 4.13) {@code RuleChain} was used for
+ * ordering rules. We recommend to not use it for this purpose anymore. You can
+ * use the attribute {@code order} of the annotation {@link Rule#order() Rule}
+ * or {@link org.junit.ClassRule#order() ClassRule} for ordering rules.
+ *
+ * @see org.junit.Rule#order()
+ * @see org.junit.ClassRule#order()
+ * @since 4.10
+ */
+public class RuleChain implements TestRule {
+ private static final RuleChain EMPTY_CHAIN = new RuleChain(
+ Collections.<TestRule>emptyList());
+
+ private List<TestRule> rulesStartingWithInnerMost;
+
+ /**
+ * Returns a {@code RuleChain} without a {@link TestRule}. This method may
+ * be the starting point of a {@code RuleChain}.
+ *
+ * @return a {@code RuleChain} without a {@link TestRule}.
+ */
+ public static RuleChain emptyRuleChain() {
+ return EMPTY_CHAIN;
+ }
+
+ /**
+ * Returns a {@code RuleChain} with a single {@link TestRule}. This method
+ * is the usual starting point of a {@code RuleChain}.
+ *
+ * @param outerRule the outer rule of the {@code RuleChain}.
+ * @return a {@code RuleChain} with a single {@link TestRule}.
+ */
+ public static RuleChain outerRule(TestRule outerRule) {
+ return emptyRuleChain().around(outerRule);
+ }
+
+ private RuleChain(List<TestRule> rules) {
+ this.rulesStartingWithInnerMost = rules;
+ }
+
+ /**
+ * Create a new {@code RuleChain}, which encloses the given {@link TestRule} with
+ * the rules of the current {@code RuleChain}.
+ *
+ * @param enclosedRule the rule to enclose; must not be {@code null}.
+ * @return a new {@code RuleChain}.
+ * @throws NullPointerException if the argument {@code enclosedRule} is {@code null}
+ */
+ public RuleChain around(TestRule enclosedRule) {
+ if (enclosedRule == null) {
+ throw new NullPointerException("The enclosed rule must not be null");
+ }
+ List<TestRule> rulesOfNewChain = new ArrayList<TestRule>();
+ rulesOfNewChain.add(enclosedRule);
+ rulesOfNewChain.addAll(rulesStartingWithInnerMost);
+ return new RuleChain(rulesOfNewChain);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Statement apply(Statement base, Description description) {
+ return new RunRules(base, rulesStartingWithInnerMost, description);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java
new file mode 100644
index 0000000..131fc1f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/RunRules.java
@@ -0,0 +1,30 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Runs a collection of rules on a statement.
+ *
+ * @since 4.9
+ */
+public class RunRules extends Statement {
+ private final Statement statement;
+
+ public RunRules(Statement base, Iterable<TestRule> rules, Description description) {
+ statement = applyAll(base, rules, description);
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ statement.evaluate();
+ }
+
+ private static Statement applyAll(Statement result, Iterable<TestRule> rules,
+ Description description) {
+ for (TestRule each : rules) {
+ result = each.apply(result, description);
+ }
+ return result;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java
new file mode 100644
index 0000000..6900a48
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/Stopwatch.java
@@ -0,0 +1,183 @@
+package org.junit.rules;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The Stopwatch Rule notifies one of its own protected methods of the time spent by a test.
+ *
+ * <p>Override them to get the time in nanoseconds. For example, this class will keep logging the
+ * time spent by each passed, failed, skipped, and finished test:
+ *
+ * <pre>
+ * public static class StopwatchTest {
+ * private static final Logger logger = Logger.getLogger("");
+ *
+ * private static void logInfo(Description description, String status, long nanos) {
+ * String testName = description.getMethodName();
+ * logger.info(String.format("Test %s %s, spent %d microseconds",
+ * testName, status, TimeUnit.NANOSECONDS.toMicros(nanos)));
+ * }
+ *
+ * @Rule
+ * public Stopwatch stopwatch = new Stopwatch() {
+ * @Override
+ * protected void succeeded(long nanos, Description description) {
+ * logInfo(description, "succeeded", nanos);
+ * }
+ *
+ * @Override
+ * protected void failed(long nanos, Throwable e, Description description) {
+ * logInfo(description, "failed", nanos);
+ * }
+ *
+ * @Override
+ * protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
+ * logInfo(description, "skipped", nanos);
+ * }
+ *
+ * @Override
+ * protected void finished(long nanos, Description description) {
+ * logInfo(description, "finished", nanos);
+ * }
+ * };
+ *
+ * @Test
+ * public void succeeds() {
+ * }
+ *
+ * @Test
+ * public void fails() {
+ * fail();
+ * }
+ *
+ * @Test
+ * public void skips() {
+ * assumeTrue(false);
+ * }
+ * }
+ * </pre>
+ *
+ * An example to assert runtime:
+ * <pre>
+ * @Test
+ * public void performanceTest() throws InterruptedException {
+ * long delta = 30;
+ * Thread.sleep(300L);
+ * assertEquals(300d, stopwatch.runtime(MILLISECONDS), delta);
+ * Thread.sleep(500L);
+ * assertEquals(800d, stopwatch.runtime(MILLISECONDS), delta);
+ * }
+ * </pre>
+ *
+ * @author tibor17
+ * @since 4.12
+ */
+public class Stopwatch implements TestRule {
+ private final Clock clock;
+ private volatile long startNanos;
+ private volatile long endNanos;
+
+ public Stopwatch() {
+ this(new Clock());
+ }
+
+ Stopwatch(Clock clock) {
+ this.clock = clock;
+ }
+
+ /**
+ * Gets the runtime for the test.
+ *
+ * @param unit time unit for returned runtime
+ * @return runtime measured during the test
+ */
+ public long runtime(TimeUnit unit) {
+ return unit.convert(getNanos(), TimeUnit.NANOSECONDS);
+ }
+
+ /**
+ * Invoked when a test succeeds
+ */
+ protected void succeeded(long nanos, Description description) {
+ }
+
+ /**
+ * Invoked when a test fails
+ */
+ protected void failed(long nanos, Throwable e, Description description) {
+ }
+
+ /**
+ * Invoked when a test is skipped due to a failed assumption.
+ */
+ protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
+ }
+
+ /**
+ * Invoked when a test method finishes (whether passing or failing)
+ */
+ protected void finished(long nanos, Description description) {
+ }
+
+ private long getNanos() {
+ if (startNanos == 0) {
+ throw new IllegalStateException("Test has not started");
+ }
+ long currentEndNanos = endNanos; // volatile read happens here
+ if (currentEndNanos == 0) {
+ currentEndNanos = clock.nanoTime();
+ }
+
+ return currentEndNanos - startNanos;
+ }
+
+ private void starting() {
+ startNanos = clock.nanoTime();
+ endNanos = 0;
+ }
+
+ private void stopping() {
+ endNanos = clock.nanoTime();
+ }
+
+ public final Statement apply(Statement base, Description description) {
+ return new InternalWatcher().apply(base, description);
+ }
+
+ private class InternalWatcher extends TestWatcher {
+
+ @Override protected void starting(Description description) {
+ Stopwatch.this.starting();
+ }
+
+ @Override protected void finished(Description description) {
+ Stopwatch.this.finished(getNanos(), description);
+ }
+
+ @Override protected void succeeded(Description description) {
+ Stopwatch.this.stopping();
+ Stopwatch.this.succeeded(getNanos(), description);
+ }
+
+ @Override protected void failed(Throwable e, Description description) {
+ Stopwatch.this.stopping();
+ Stopwatch.this.failed(getNanos(), e, description);
+ }
+
+ @Override protected void skipped(AssumptionViolatedException e, Description description) {
+ Stopwatch.this.stopping();
+ Stopwatch.this.skipped(getNanos(), e, description);
+ }
+ }
+
+ static class Clock {
+
+ public long nanoTime() {
+ return System.nanoTime();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java
new file mode 100644
index 0000000..a726c66
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TemporaryFolder.java
@@ -0,0 +1,351 @@
+package org.junit.rules;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.Rule;
+
+/**
+ * The TemporaryFolder Rule allows creation of files and folders that should
+ * be deleted when the test method finishes (whether it passes or
+ * fails).
+ * By default no exception will be thrown in case the deletion fails.
+ *
+ * <p>Example of usage:
+ * <pre>
+ * public static class HasTempFolder {
+ * @Rule
+ * public TemporaryFolder folder= new TemporaryFolder();
+ *
+ * @Test
+ * public void testUsingTempFolder() throws IOException {
+ * File createdFile= folder.newFile("myfile.txt");
+ * File createdFolder= folder.newFolder("subfolder");
+ * // ...
+ * }
+ * }
+ * </pre>
+ *
+ * <p>TemporaryFolder rule supports assured deletion mode, which
+ * will fail the test in case deletion fails with {@link AssertionError}.
+ *
+ * <p>Creating TemporaryFolder with assured deletion:
+ * <pre>
+ * @Rule
+ * public TemporaryFolder folder= TemporaryFolder.builder().assureDeletion().build();
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class TemporaryFolder extends ExternalResource {
+ private final File parentFolder;
+ private final boolean assureDeletion;
+ private File folder;
+
+ private static final int TEMP_DIR_ATTEMPTS = 10000;
+ private static final String TMP_PREFIX = "junit";
+
+ /**
+ * Create a temporary folder which uses system default temporary-file
+ * directory to create temporary resources.
+ */
+ public TemporaryFolder() {
+ this((File) null);
+ }
+
+ /**
+ * Create a temporary folder which uses the specified directory to create
+ * temporary resources.
+ *
+ * @param parentFolder folder where temporary resources will be created.
+ * If {@code null} then system default temporary-file directory is used.
+ */
+ public TemporaryFolder(File parentFolder) {
+ this.parentFolder = parentFolder;
+ this.assureDeletion = false;
+ }
+
+ /**
+ * Create a {@link TemporaryFolder} initialized with
+ * values from a builder.
+ */
+ protected TemporaryFolder(Builder builder) {
+ this.parentFolder = builder.parentFolder;
+ this.assureDeletion = builder.assureDeletion;
+ }
+
+ /**
+ * Returns a new builder for building an instance of {@link TemporaryFolder}.
+ *
+ * @since 4.13
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builds an instance of {@link TemporaryFolder}.
+ *
+ * @since 4.13
+ */
+ public static class Builder {
+ private File parentFolder;
+ private boolean assureDeletion;
+
+ protected Builder() {}
+
+ /**
+ * Specifies which folder to use for creating temporary resources.
+ * If {@code null} then system default temporary-file directory is
+ * used.
+ *
+ * @return this
+ */
+ public Builder parentFolder(File parentFolder) {
+ this.parentFolder = parentFolder;
+ return this;
+ }
+
+ /**
+ * Setting this flag assures that no resources are left undeleted. Failure
+ * to fulfill the assurance results in failure of tests with an
+ * {@link AssertionError}.
+ *
+ * @return this
+ */
+ public Builder assureDeletion() {
+ this.assureDeletion = true;
+ return this;
+ }
+
+ /**
+ * Builds a {@link TemporaryFolder} instance using the values in this builder.
+ */
+ public TemporaryFolder build() {
+ return new TemporaryFolder(this);
+ }
+ }
+
+ @Override
+ protected void before() throws Throwable {
+ create();
+ }
+
+ @Override
+ protected void after() {
+ delete();
+ }
+
+ // testing purposes only
+
+ /**
+ * for testing purposes only. Do not use.
+ */
+ public void create() throws IOException {
+ folder = createTemporaryFolderIn(parentFolder);
+ }
+
+ /**
+ * Returns a new fresh file with the given name under the temporary folder.
+ */
+ public File newFile(String fileName) throws IOException {
+ File file = new File(getRoot(), fileName);
+ if (!file.createNewFile()) {
+ throw new IOException(
+ "a file with the name \'" + fileName + "\' already exists in the test folder");
+ }
+ return file;
+ }
+
+ /**
+ * Returns a new fresh file with a random name under the temporary folder.
+ */
+ public File newFile() throws IOException {
+ return File.createTempFile(TMP_PREFIX, null, getRoot());
+ }
+
+ /**
+ * Returns a new fresh folder with the given path under the temporary
+ * folder.
+ */
+ public File newFolder(String path) throws IOException {
+ return newFolder(new String[]{path});
+ }
+
+ /**
+ * Returns a new fresh folder with the given paths under the temporary
+ * folder. For example, if you pass in the strings {@code "parent"} and {@code "child"}
+ * then a directory named {@code "parent"} will be created under the temporary folder
+ * and a directory named {@code "child"} will be created under the newly-created
+ * {@code "parent"} directory.
+ */
+ public File newFolder(String... paths) throws IOException {
+ if (paths.length == 0) {
+ throw new IllegalArgumentException("must pass at least one path");
+ }
+
+ /*
+ * Before checking if the paths are absolute paths, check if create() was ever called,
+ * and if it wasn't, throw IllegalStateException.
+ */
+ File root = getRoot();
+ for (String path : paths) {
+ if (new File(path).isAbsolute()) {
+ throw new IOException("folder path \'" + path + "\' is not a relative path");
+ }
+ }
+
+ File relativePath = null;
+ File file = root;
+ boolean lastMkdirsCallSuccessful = true;
+ for (String path : paths) {
+ relativePath = new File(relativePath, path);
+ file = new File(root, relativePath.getPath());
+
+ lastMkdirsCallSuccessful = file.mkdirs();
+ if (!lastMkdirsCallSuccessful && !file.isDirectory()) {
+ if (file.exists()) {
+ throw new IOException(
+ "a file with the path \'" + relativePath.getPath() + "\' exists");
+ } else {
+ throw new IOException(
+ "could not create a folder with the path \'" + relativePath.getPath() + "\'");
+ }
+ }
+ }
+ if (!lastMkdirsCallSuccessful) {
+ throw new IOException(
+ "a folder with the path \'" + relativePath.getPath() + "\' already exists");
+ }
+ return file;
+ }
+
+ /**
+ * Returns a new fresh folder with a random name under the temporary folder.
+ */
+ public File newFolder() throws IOException {
+ return createTemporaryFolderIn(getRoot());
+ }
+
+ private static File createTemporaryFolderIn(File parentFolder) throws IOException {
+ try {
+ return createTemporaryFolderWithNioApi(parentFolder);
+ } catch (ClassNotFoundException ignore) {
+ // Fallback for Java 5 and 6
+ return createTemporaryFolderWithFileApi(parentFolder);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof IOException) {
+ throw (IOException) cause;
+ }
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ }
+ IOException exception = new IOException("Failed to create temporary folder in " + parentFolder);
+ exception.initCause(cause);
+ throw exception;
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to create temporary folder in " + parentFolder, e);
+ }
+ }
+
+ private static File createTemporaryFolderWithNioApi(File parentFolder) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ Class<?> filesClass = Class.forName("java.nio.file.Files");
+ Object fileAttributeArray = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0);
+ Class<?> pathClass = Class.forName("java.nio.file.Path");
+ Object tempDir;
+ if (parentFolder != null) {
+ Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", pathClass, String.class, fileAttributeArray.getClass());
+ Object parentPath = File.class.getDeclaredMethod("toPath").invoke(parentFolder);
+ tempDir = createTempDirectoryMethod.invoke(null, parentPath, TMP_PREFIX, fileAttributeArray);
+ } else {
+ Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", String.class, fileAttributeArray.getClass());
+ tempDir = createTempDirectoryMethod.invoke(null, TMP_PREFIX, fileAttributeArray);
+ }
+ return (File) pathClass.getDeclaredMethod("toFile").invoke(tempDir);
+ }
+
+ private static File createTemporaryFolderWithFileApi(File parentFolder) throws IOException {
+ File createdFolder = null;
+ for (int i = 0; i < TEMP_DIR_ATTEMPTS; ++i) {
+ // Use createTempFile to get a suitable folder name.
+ String suffix = ".tmp";
+ File tmpFile = File.createTempFile(TMP_PREFIX, suffix, parentFolder);
+ String tmpName = tmpFile.toString();
+ // Discard .tmp suffix of tmpName.
+ String folderName = tmpName.substring(0, tmpName.length() - suffix.length());
+ createdFolder = new File(folderName);
+ if (createdFolder.mkdir()) {
+ tmpFile.delete();
+ return createdFolder;
+ }
+ tmpFile.delete();
+ }
+ throw new IOException("Unable to create temporary directory in: "
+ + parentFolder.toString() + ". Tried " + TEMP_DIR_ATTEMPTS + " times. "
+ + "Last attempted to create: " + createdFolder.toString());
+ }
+
+ /**
+ * @return the location of this temporary folder.
+ */
+ public File getRoot() {
+ if (folder == null) {
+ throw new IllegalStateException(
+ "the temporary folder has not yet been created");
+ }
+ return folder;
+ }
+
+ /**
+ * Delete all files and folders under the temporary folder. Usually not
+ * called directly, since it is automatically applied by the {@link Rule}.
+ *
+ * @throws AssertionError if unable to clean up resources
+ * and deletion of resources is assured.
+ */
+ public void delete() {
+ if (!tryDelete()) {
+ if (assureDeletion) {
+ fail("Unable to clean up temporary folder " + folder);
+ }
+ }
+ }
+
+ /**
+ * Tries to delete all files and folders under the temporary folder and
+ * returns whether deletion was successful or not.
+ *
+ * @return {@code true} if all resources are deleted successfully,
+ * {@code false} otherwise.
+ */
+ private boolean tryDelete() {
+ if (folder == null) {
+ return true;
+ }
+
+ return recursiveDelete(folder);
+ }
+
+ private boolean recursiveDelete(File file) {
+ // Try deleting file before assuming file is a directory
+ // to prevent following symbolic links.
+ if (file.delete()) {
+ return true;
+ }
+ File[] files = file.listFiles();
+ if (files != null) {
+ for (File each : files) {
+ if (!recursiveDelete(each)) {
+ return false;
+ }
+ }
+ }
+ return file.delete();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java
new file mode 100644
index 0000000..e2ebc2e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestName.java
@@ -0,0 +1,41 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+
+/**
+ * The TestName Rule makes the current test name available inside test methods:
+ *
+ * <pre>
+ * public class TestNameTest {
+ * @Rule
+ * public TestName name= new TestName();
+ *
+ * @Test
+ * public void testA() {
+ * assertEquals("testA", name.getMethodName());
+ * }
+ *
+ * @Test
+ * public void testB() {
+ * assertEquals("testB", name.getMethodName());
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public class TestName extends TestWatcher {
+ private volatile String name;
+
+ @Override
+ protected void starting(Description d) {
+ name = d.getMethodName();
+ }
+
+ /**
+ * @return the name of the currently-running test method
+ */
+ public String getMethodName() {
+ return name;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java
new file mode 100644
index 0000000..53e2f70
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestRule.java
@@ -0,0 +1,56 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * A TestRule is an alteration in how a test method, or set of test methods,
+ * is run and reported. A {@link TestRule} may add additional checks that cause
+ * a test that would otherwise fail to pass, or it may perform necessary setup or
+ * cleanup for tests, or it may observe test execution to report it elsewhere.
+ * {@link TestRule}s can do everything that could be done previously with
+ * methods annotated with {@link org.junit.Before},
+ * {@link org.junit.After}, {@link org.junit.BeforeClass}, or
+ * {@link org.junit.AfterClass}, but they are more powerful, and more easily
+ * shared
+ * between projects and classes.
+ *
+ * The default JUnit test runners for suites and
+ * individual test cases recognize {@link TestRule}s introduced in two different
+ * ways. {@link org.junit.Rule} annotates method-level
+ * {@link TestRule}s, and {@link org.junit.ClassRule}
+ * annotates class-level {@link TestRule}s. See Javadoc for those annotations
+ * for more information.
+ *
+ * Multiple {@link TestRule}s can be applied to a test or suite execution. The
+ * {@link Statement} that executes the method or suite is passed to each annotated
+ * {@link org.junit.Rule} in turn, and each may return a substitute or modified
+ * {@link Statement}, which is passed to the next {@link org.junit.Rule}, if any. For
+ * examples of how this can be useful, see these provided TestRules,
+ * or write your own:
+ *
+ * <ul>
+ * <li>{@link ErrorCollector}: collect multiple errors in one test method</li>
+ * <li>{@link ExpectedException}: make flexible assertions about thrown exceptions</li>
+ * <li>{@link ExternalResource}: start and stop a server, for example</li>
+ * <li>{@link TemporaryFolder}: create fresh files, and delete after test</li>
+ * <li>{@link TestName}: remember the test name for use during the method</li>
+ * <li>{@link TestWatcher}: add logic at events during method execution</li>
+ * <li>{@link Timeout}: cause test to fail after a set time</li>
+ * <li>{@link Verifier}: fail test if object state ends up incorrect</li>
+ * </ul>
+ *
+ * @since 4.9
+ */
+public interface TestRule {
+ /**
+ * Modifies the method-running {@link Statement} to implement this
+ * test-running rule.
+ *
+ * @param base The {@link Statement} to be modified
+ * @param description A {@link Description} of the test implemented in {@code base}
+ * @return a new statement, which may be the same as {@code base},
+ * a wrapper around {@code base}, or a completely new Statement.
+ */
+ Statement apply(Statement base, Description description);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java
new file mode 100644
index 0000000..a28514d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java
@@ -0,0 +1,170 @@
+package org.junit.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.Rule;
+import org.junit.runner.Description;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+/**
+ * TestWatcher is a base class for Rules that take note of the testing
+ * action, without modifying it. For example, this class will keep a log of each
+ * passing and failing test:
+ *
+ * <pre>
+ * public static class WatchmanTest {
+ * private static String watchedLog;
+ *
+ * @Rule(order = Integer.MIN_VALUE)
+ * public TestWatcher watchman= new TestWatcher() {
+ * @Override
+ * protected void failed(Throwable e, Description description) {
+ * watchedLog+= description + "\n";
+ * }
+ *
+ * @Override
+ * protected void succeeded(Description description) {
+ * watchedLog+= description + " " + "success!\n";
+ * }
+ * };
+ *
+ * @Test
+ * public void fails() {
+ * fail();
+ * }
+ *
+ * @Test
+ * public void succeeds() {
+ * }
+ * }
+ * </pre>
+ * <p>It is recommended to always set the {@link Rule#order() order} of the
+ * {@code TestWatcher} to {@code Integer.MIN_VALUE} so that it encloses all
+ * other rules. Otherwise it may see failed tests as successful and vice versa
+ * if some rule changes the result of a test (e.g. {@link ErrorCollector} or
+ * {@link ExpectedException}).
+ *
+ * @since 4.9
+ */
+public abstract class TestWatcher implements TestRule {
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ List<Throwable> errors = new ArrayList<Throwable>();
+
+ startingQuietly(description, errors);
+ try {
+ base.evaluate();
+ succeededQuietly(description, errors);
+ } catch (org.junit.internal.AssumptionViolatedException e) {
+ errors.add(e);
+ skippedQuietly(e, description, errors);
+ } catch (Throwable e) {
+ errors.add(e);
+ failedQuietly(e, description, errors);
+ } finally {
+ finishedQuietly(description, errors);
+ }
+
+ MultipleFailureException.assertEmpty(errors);
+ }
+ };
+ }
+
+ private void succeededQuietly(Description description,
+ List<Throwable> errors) {
+ try {
+ succeeded(description);
+ } catch (Throwable e) {
+ errors.add(e);
+ }
+ }
+
+ private void failedQuietly(Throwable e, Description description,
+ List<Throwable> errors) {
+ try {
+ failed(e, description);
+ } catch (Throwable e1) {
+ errors.add(e1);
+ }
+ }
+
+ private void skippedQuietly(
+ org.junit.internal.AssumptionViolatedException e, Description description,
+ List<Throwable> errors) {
+ try {
+ if (e instanceof AssumptionViolatedException) {
+ skipped((AssumptionViolatedException) e, description);
+ } else {
+ skipped(e, description);
+ }
+ } catch (Throwable e1) {
+ errors.add(e1);
+ }
+ }
+
+ private void startingQuietly(Description description,
+ List<Throwable> errors) {
+ try {
+ starting(description);
+ } catch (Throwable e) {
+ errors.add(e);
+ }
+ }
+
+ private void finishedQuietly(Description description,
+ List<Throwable> errors) {
+ try {
+ finished(description);
+ } catch (Throwable e) {
+ errors.add(e);
+ }
+ }
+
+ /**
+ * Invoked when a test succeeds
+ */
+ protected void succeeded(Description description) {
+ }
+
+ /**
+ * Invoked when a test fails
+ */
+ protected void failed(Throwable e, Description description) {
+ }
+
+ /**
+ * Invoked when a test is skipped due to a failed assumption.
+ */
+ protected void skipped(AssumptionViolatedException e, Description description) {
+ // For backwards compatibility with JUnit 4.11 and earlier, call the legacy version
+ org.junit.internal.AssumptionViolatedException asInternalException = e;
+ skipped(asInternalException, description);
+ }
+
+ /**
+ * Invoked when a test is skipped due to a failed assumption.
+ *
+ * @deprecated use {@link #skipped(AssumptionViolatedException, Description)}
+ */
+ @Deprecated
+ protected void skipped(
+ org.junit.internal.AssumptionViolatedException e, Description description) {
+ }
+
+ /**
+ * Invoked when a test is about to start
+ */
+ protected void starting(Description description) {
+ }
+
+ /**
+ * Invoked when a test method finishes (whether passing or failing)
+ */
+ protected void finished(Description description) {
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java
new file mode 100644
index 0000000..c8d6c71
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatchman.java
@@ -0,0 +1,91 @@
+package org.junit.rules;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * TestWatchman is a base class for Rules that take note of the testing
+ * action, without modifying it. For example, this class will keep a log of each
+ * passing and failing test:
+ *
+ * <pre>
+ * public static class WatchmanTest {
+ * private static String watchedLog;
+ *
+ * @Rule
+ * public MethodRule watchman= new TestWatchman() {
+ * @Override
+ * public void failed(Throwable e, FrameworkMethod method) {
+ * watchedLog+= method.getName() + " " + e.getClass().getSimpleName()
+ * + "\n";
+ * }
+ *
+ * @Override
+ * public void succeeded(FrameworkMethod method) {
+ * watchedLog+= method.getName() + " " + "success!\n";
+ * }
+ * };
+ *
+ * @Test
+ * public void fails() {
+ * fail();
+ * }
+ *
+ * @Test
+ * public void succeeds() {
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ * @deprecated Use {@link TestWatcher} (which implements {@link TestRule}) instead.
+ */
+@Deprecated
+public class TestWatchman implements MethodRule {
+ public Statement apply(final Statement base, final FrameworkMethod method,
+ Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ starting(method);
+ try {
+ base.evaluate();
+ succeeded(method);
+ } catch (AssumptionViolatedException e) {
+ throw e;
+ } catch (Throwable e) {
+ failed(e, method);
+ throw e;
+ } finally {
+ finished(method);
+ }
+ }
+ };
+ }
+
+ /**
+ * Invoked when a test method succeeds
+ */
+ public void succeeded(FrameworkMethod method) {
+ }
+
+ /**
+ * Invoked when a test method fails
+ */
+ public void failed(Throwable e, FrameworkMethod method) {
+ }
+
+ /**
+ * Invoked when a test method is about to start
+ */
+ public void starting(FrameworkMethod method) {
+ }
+
+
+ /**
+ * Invoked when a test method finishes (whether passing or failing)
+ */
+ public void finished(FrameworkMethod method) {
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java
new file mode 100644
index 0000000..334a923
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/Timeout.java
@@ -0,0 +1,233 @@
+package org.junit.rules;
+
+import org.junit.internal.runners.statements.FailOnTimeout;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The Timeout Rule applies the same timeout to all test methods in a class:
+ * <pre>
+ * public static class HasGlobalLongTimeout {
+ *
+ * @Rule
+ * public Timeout globalTimeout = Timeout.millis(20);
+ *
+ * @Test
+ * public void run1() throws InterruptedException {
+ * Thread.sleep(100);
+ * }
+ *
+ * @Test
+ * public void infiniteLoop() {
+ * while (true) {}
+ * }
+ * }
+ * </pre>
+ * <p>
+ * Each test is run in a new thread. If the specified timeout elapses before
+ * the test completes, its execution is interrupted via {@link Thread#interrupt()}.
+ * This happens in interruptable I/O and locks, and methods in {@link Object}
+ * and {@link Thread} throwing {@link InterruptedException}.
+ * <p>
+ * A specified timeout of 0 will be interpreted as not set, however tests will
+ * still launch from separate threads. This can be useful for disabling timeouts
+ * in environments where they are dynamically set based on some property.
+ *
+ * @since 4.7
+ */
+public class Timeout implements TestRule {
+ private final long timeout;
+ private final TimeUnit timeUnit;
+ private final boolean lookForStuckThread;
+
+ /**
+ * Returns a new builder for building an instance.
+ *
+ * @since 4.12
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Create a {@code Timeout} instance with the timeout specified
+ * in milliseconds.
+ * <p>
+ * This constructor is deprecated.
+ * <p>
+ * Instead use {@link #Timeout(long, java.util.concurrent.TimeUnit)},
+ * {@link Timeout#millis(long)}, or {@link Timeout#seconds(long)}.
+ *
+ * @param millis the maximum time in milliseconds to allow the
+ * test to run before it should timeout
+ */
+ @Deprecated
+ public Timeout(int millis) {
+ this(millis, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Create a {@code Timeout} instance with the timeout specified
+ * at the timeUnit of granularity of the provided {@code TimeUnit}.
+ *
+ * @param timeout the maximum time to allow the test to run
+ * before it should timeout
+ * @param timeUnit the time unit for the {@code timeout}
+ * @since 4.12
+ */
+ public Timeout(long timeout, TimeUnit timeUnit) {
+ this.timeout = timeout;
+ this.timeUnit = timeUnit;
+ lookForStuckThread = false;
+ }
+
+ /**
+ * Create a {@code Timeout} instance initialized with values from
+ * a builder.
+ *
+ * @since 4.12
+ */
+ protected Timeout(Builder builder) {
+ timeout = builder.getTimeout();
+ timeUnit = builder.getTimeUnit();
+ lookForStuckThread = builder.getLookingForStuckThread();
+ }
+
+ /**
+ * Creates a {@link Timeout} that will timeout a test after the
+ * given duration, in milliseconds.
+ *
+ * @since 4.12
+ */
+ public static Timeout millis(long millis) {
+ return new Timeout(millis, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Creates a {@link Timeout} that will timeout a test after the
+ * given duration, in seconds.
+ *
+ * @since 4.12
+ */
+ public static Timeout seconds(long seconds) {
+ return new Timeout(seconds, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Gets the timeout configured for this rule, in the given units.
+ *
+ * @since 4.12
+ */
+ protected final long getTimeout(TimeUnit unit) {
+ return unit.convert(timeout, timeUnit);
+ }
+
+ /**
+ * Gets whether this {@code Timeout} will look for a stuck thread
+ * when the test times out.
+ *
+ * @since 4.12
+ */
+ protected final boolean getLookingForStuckThread() {
+ return lookForStuckThread;
+ }
+
+ /**
+ * Creates a {@link Statement} that will run the given
+ * {@code statement}, and timeout the operation based
+ * on the values configured in this rule. Subclasses
+ * can override this method for different behavior.
+ *
+ * @since 4.12
+ */
+ protected Statement createFailOnTimeoutStatement(
+ Statement statement) throws Exception {
+ return FailOnTimeout.builder()
+ .withTimeout(timeout, timeUnit)
+ .withLookingForStuckThread(lookForStuckThread)
+ .build(statement);
+ }
+
+ public Statement apply(Statement base, Description description) {
+ try {
+ return createFailOnTimeoutStatement(base);
+ } catch (final Exception e) {
+ return new Statement() {
+ @Override public void evaluate() throws Throwable {
+ throw new RuntimeException("Invalid parameters for Timeout", e);
+ }
+ };
+ }
+ }
+
+ /**
+ * Builder for {@link Timeout}.
+ *
+ * @since 4.12
+ */
+ public static class Builder {
+ private boolean lookForStuckThread = false;
+ private long timeout = 0;
+ private TimeUnit timeUnit = TimeUnit.SECONDS;
+
+ protected Builder() {
+ }
+
+ /**
+ * Specifies the time to wait before timing out the test.
+ *
+ * <p>If this is not called, or is called with a
+ * {@code timeout} of {@code 0}, the returned {@code Timeout}
+ * rule instance will cause the tests to wait forever to
+ * complete, however the tests will still launch from a
+ * separate thread. This can be useful for disabling timeouts
+ * in environments where they are dynamically set based on
+ * some property.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the {@code timeout} argument
+ * @return {@code this} for method chaining.
+ */
+ public Builder withTimeout(long timeout, TimeUnit unit) {
+ this.timeout = timeout;
+ this.timeUnit = unit;
+ return this;
+ }
+
+ protected long getTimeout() {
+ return timeout;
+ }
+
+ protected TimeUnit getTimeUnit() {
+ return timeUnit;
+ }
+
+ /**
+ * Specifies whether to look for a stuck thread. If a timeout occurs and this
+ * feature is enabled, the rule will look for a thread that appears to be stuck
+ * and dump its backtrace. This feature is experimental. Behavior may change
+ * after the 4.12 release in response to feedback.
+ *
+ * @param enable {@code true} to enable the feature
+ * @return {@code this} for method chaining.
+ */
+ public Builder withLookingForStuckThread(boolean enable) {
+ this.lookForStuckThread = enable;
+ return this;
+ }
+
+ protected boolean getLookingForStuckThread() {
+ return lookForStuckThread;
+ }
+
+
+ /**
+ * Builds a {@link Timeout} instance using the values in this builder.,
+ */
+ public Timeout build() {
+ return new Timeout(this);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/rules/Verifier.java b/google3/third_party/java_src/junit/main/java/org/junit/rules/Verifier.java
new file mode 100644
index 0000000..7a03b0c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/rules/Verifier.java
@@ -0,0 +1,47 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Verifier is a base class for Rules like ErrorCollector, which can turn
+ * otherwise passing test methods into failing tests if a verification check is
+ * failed
+ *
+ * <pre>
+ * public static class ErrorLogVerifier {
+ * private ErrorLog errorLog = new ErrorLog();
+ *
+ * @Rule
+ * public Verifier verifier = new Verifier() {
+ * @Override public void verify() {
+ * assertTrue(errorLog.isEmpty());
+ * }
+ * }
+ *
+ * @Test public void testThatMightWriteErrorLog() {
+ * // ...
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.7
+ */
+public abstract class Verifier implements TestRule {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ verify();
+ }
+ };
+ }
+
+ /**
+ * Override this to add verification logic. Overrides should throw an
+ * exception to indicate that verification failed.
+ */
+ protected void verify() throws Throwable {
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/Computer.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Computer.java
new file mode 100644
index 0000000..18d0d31
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Computer.java
@@ -0,0 +1,52 @@
+package org.junit.runner;
+
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Represents a strategy for computing runners and suites.
+ * WARNING: this class is very likely to undergo serious changes in version 4.8 and
+ * beyond.
+ *
+ * @since 4.6
+ */
+public class Computer {
+ /**
+ * Returns a new default computer, which runs tests in serial order
+ */
+ public static Computer serial() {
+ return new Computer();
+ }
+
+ /**
+ * Create a suite for {@code classes}, building Runners with {@code builder}.
+ * Throws an InitializationError if Runner construction fails
+ */
+ public Runner getSuite(final RunnerBuilder builder,
+ Class<?>[] classes) throws InitializationError {
+ return new Suite(new RunnerBuilder() {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ return getRunner(builder, testClass);
+ }
+ }, classes) {
+ @Override
+ protected String getName() {
+ /*
+ * #1320 The generated suite is not based on a real class so
+ * only a 'null' description can be generated from it. This name
+ * will be overridden here.
+ */
+ return "classes";
+ }
+ };
+ }
+
+ /**
+ * Create a single-class runner for {@code testClass}, using {@code builder}
+ */
+ protected Runner getRunner(RunnerBuilder builder, Class<?> testClass) throws Throwable {
+ return builder.runnerForClass(testClass);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/Describable.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Describable.java
new file mode 100644
index 0000000..293fdb3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Describable.java
@@ -0,0 +1,14 @@
+package org.junit.runner;
+
+
+/**
+ * Represents an object that can describe itself
+ *
+ * @since 4.5
+ */
+public interface Describable {
+ /**
+ * @return a {@link Description} showing the tests to be run by the receiver
+ */
+ Description getDescription();
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/Description.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Description.java
new file mode 100644
index 0000000..0846a1e
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Description.java
@@ -0,0 +1,327 @@
+package org.junit.runner;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A <code>Description</code> describes a test which is to be run or has been run. <code>Descriptions</code>
+ * can be atomic (a single test) or compound (containing children tests). <code>Descriptions</code> 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).
+ * <p>
+ * <code>Descriptions</code> are implemented as a single class rather than a Composite because
+ * they are entirely informational. They contain no logic aside from counting their tests.
+ * <p>
+ * In the past, we used the raw {@link junit.framework.TestCase}s and {@link junit.framework.TestSuite}s
+ * to display the tree of tests. This was no longer viable in JUnit 4 because atomic tests no longer have
+ * a superclass below {@link 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
+ * @since 4.0
+ */
+public class Description implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private static final Pattern METHOD_AND_CLASS_NAME_PATTERN = Pattern
+ .compile("([\\s\\S]*)\\((.*)\\)");
+
+ /**
+ * Create a <code>Description</code> named <code>name</code>.
+ * Generally, you will add children to this <code>Description</code>.
+ *
+ * @param name the name of the <code>Description</code>
+ * @param annotations meta-data about the test, for downstream interpreters
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createSuiteDescription(String name, Annotation... annotations) {
+ return new Description(null, name, annotations);
+ }
+
+ /**
+ * Create a <code>Description</code> named <code>name</code>.
+ * Generally, you will add children to this <code>Description</code>.
+ *
+ * @param name the name of the <code>Description</code>
+ * @param uniqueId an arbitrary object used to define uniqueness (in {@link #equals(Object)}
+ * @param annotations meta-data about the test, for downstream interpreters
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createSuiteDescription(String name, Serializable uniqueId, Annotation... annotations) {
+ return new Description(null, name, uniqueId, annotations);
+ }
+
+ /**
+ * Create a <code>Description</code> of a single test named <code>name</code> in the 'class' named
+ * <code>className</code>. Generally, this will be a leaf <code>Description</code>. This method is a better choice
+ * than {@link #createTestDescription(Class, String, Annotation...)} for test runners whose test cases are not
+ * defined in an actual Java <code>Class</code>.
+ *
+ * @param className the class name of the test
+ * @param name the name of the test (a method name for test annotated with {@link org.junit.Test})
+ * @param annotations meta-data about the test, for downstream interpreters
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createTestDescription(String className, String name, Annotation... annotations) {
+ return new Description(null, formatDisplayName(name, className), annotations);
+ }
+
+ /**
+ * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>.
+ * Generally, this will be a leaf <code>Description</code>.
+ *
+ * @param clazz the class of the test
+ * @param name the name of the test (a method name for test annotated with {@link org.junit.Test})
+ * @param annotations meta-data about the test, for downstream interpreters
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations) {
+ return new Description(clazz, formatDisplayName(name, clazz.getName()), annotations);
+ }
+
+ /**
+ * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>.
+ * Generally, this will be a leaf <code>Description</code>.
+ * (This remains for binary compatibility with clients of JUnit 4.3)
+ *
+ * @param clazz the class of the test
+ * @param name the name of the test (a method name for test annotated with {@link org.junit.Test})
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createTestDescription(Class<?> clazz, String name) {
+ return new Description(clazz, formatDisplayName(name, clazz.getName()));
+ }
+
+ /**
+ * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>.
+ * Generally, this will be a leaf <code>Description</code>.
+ *
+ * @param name the name of the test (a method name for test annotated with {@link org.junit.Test})
+ * @return a <code>Description</code> named <code>name</code>
+ */
+ public static Description createTestDescription(String className, String name, Serializable uniqueId) {
+ return new Description(null, formatDisplayName(name, className), uniqueId);
+ }
+
+ private static String formatDisplayName(String name, String className) {
+ return String.format("%s(%s)", name, className);
+ }
+
+ /**
+ * Create a <code>Description</code> named after <code>testClass</code>
+ *
+ * @param testClass A {@link Class} containing tests
+ * @return a <code>Description</code> of <code>testClass</code>
+ */
+ public static Description createSuiteDescription(Class<?> testClass) {
+ return new Description(testClass, testClass.getName(), testClass.getAnnotations());
+ }
+
+ /**
+ * Create a <code>Description</code> named after <code>testClass</code>
+ *
+ * @param testClass A not null {@link Class} containing tests
+ * @param annotations meta-data about the test, for downstream interpreters
+ * @return a <code>Description</code> of <code>testClass</code>
+ */
+ public static Description createSuiteDescription(Class<?> testClass, Annotation... annotations) {
+ return new Description(testClass, testClass.getName(), annotations);
+ }
+
+ /**
+ * Describes a Runner which runs no tests
+ */
+ public static final Description EMPTY = new Description(null, "No Tests");
+
+ /**
+ * Describes a step in the test-running mechanism that goes so wrong no
+ * other description can be used (for example, an exception thrown from a Runner's
+ * constructor
+ */
+ public static final Description TEST_MECHANISM = new Description(null, "Test mechanism");
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final Collection<Description> fChildren = new ConcurrentLinkedQueue<Description>();
+ private final String fDisplayName;
+ private final Serializable fUniqueId;
+ private final Annotation[] fAnnotations;
+ private volatile /* write-once */ Class<?> fTestClass;
+
+ private Description(Class<?> clazz, String displayName, Annotation... annotations) {
+ this(clazz, displayName, displayName, annotations);
+ }
+
+ private Description(Class<?> testClass, String displayName, Serializable uniqueId, Annotation... annotations) {
+ if ((displayName == null) || (displayName.length() == 0)) {
+ throw new IllegalArgumentException(
+ "The display name must not be empty.");
+ }
+ if ((uniqueId == null)) {
+ throw new IllegalArgumentException(
+ "The unique id must not be null.");
+ }
+ this.fTestClass = testClass;
+ this.fDisplayName = displayName;
+ this.fUniqueId = uniqueId;
+ this.fAnnotations = annotations;
+ }
+
+ /**
+ * @return a user-understandable label
+ */
+ public String getDisplayName() {
+ return fDisplayName;
+ }
+
+ /**
+ * Add <code>Description</code> as a child of the receiver.
+ *
+ * @param description the soon-to-be child.
+ */
+ public void addChild(Description description) {
+ fChildren.add(description);
+ }
+
+ /**
+ * Gets the copy of the children of this {@code Description}.
+ * Returns an empty list if there are no children.
+ */
+ public ArrayList<Description> getChildren() {
+ return new ArrayList<Description>(fChildren);
+ }
+
+ /**
+ * @return <code>true</code> if the receiver is a suite
+ */
+ public boolean isSuite() {
+ return !isTest();
+ }
+
+ /**
+ * @return <code>true</code> if the receiver is an atomic test
+ */
+ public boolean isTest() {
+ return fChildren.isEmpty();
+ }
+
+ /**
+ * @return the total number of atomic tests in the receiver
+ */
+ public int testCount() {
+ if (isTest()) {
+ return 1;
+ }
+ int result = 0;
+ for (Description child : fChildren) {
+ result += child.testCount();
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return fUniqueId.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Description)) {
+ return false;
+ }
+ Description d = (Description) obj;
+ return fUniqueId.equals(d.fUniqueId);
+ }
+
+ @Override
+ public String toString() {
+ return getDisplayName();
+ }
+
+ /**
+ * @return true if this is a description of a Runner that runs no tests
+ */
+ public boolean isEmpty() {
+ return equals(EMPTY);
+ }
+
+ /**
+ * @return a copy of this description, with no children (on the assumption that some of the
+ * children will be added back)
+ */
+ public Description childlessCopy() {
+ return new Description(fTestClass, fDisplayName, fAnnotations);
+ }
+
+ /**
+ * @return the annotation of type annotationType that is attached to this description node,
+ * or null if none exists
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ for (Annotation each : fAnnotations) {
+ if (each.annotationType().equals(annotationType)) {
+ return annotationType.cast(each);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return all of the annotations attached to this description node
+ */
+ public Collection<Annotation> getAnnotations() {
+ return Arrays.asList(fAnnotations);
+ }
+
+ /**
+ * @return If this describes a method invocation,
+ * the class of the test instance.
+ */
+ public Class<?> getTestClass() {
+ if (fTestClass != null) {
+ return fTestClass;
+ }
+ String name = getClassName();
+ if (name == null) {
+ return null;
+ }
+ try {
+ fTestClass = Class.forName(name, false, getClass().getClassLoader());
+ return fTestClass;
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * @return If this describes a method invocation,
+ * the name of the class of the test instance
+ */
+ public String getClassName() {
+ return fTestClass != null ? fTestClass.getName() : methodAndClassNamePatternGroupOrDefault(2, toString());
+ }
+
+ /**
+ * @return If this describes a method invocation,
+ * the name of the method (or null if not)
+ */
+ public String getMethodName() {
+ return methodAndClassNamePatternGroupOrDefault(1, null);
+ }
+
+ private String methodAndClassNamePatternGroupOrDefault(int group,
+ String defaultString) {
+ Matcher matcher = METHOD_AND_CLASS_NAME_PATTERN.matcher(toString());
+ return matcher.matches() ? matcher.group(group) : defaultString;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactories.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactories.java
new file mode 100644
index 0000000..1160359
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactories.java
@@ -0,0 +1,82 @@
+package org.junit.runner;
+
+import org.junit.internal.Classes;
+import org.junit.runner.FilterFactory.FilterNotCreatedException;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Utility class whose methods create a {@link FilterFactory}.
+ */
+class FilterFactories {
+ /**
+ * Creates a {@link Filter}.
+ *
+ * A filter specification is of the form "package.of.FilterFactory=args-to-filter-factory" or
+ * "package.of.FilterFactory".
+ *
+ * @param request the request that will be filtered
+ * @param filterSpec the filter specification
+ * @throws org.junit.runner.FilterFactory.FilterNotCreatedException
+ */
+ public static Filter createFilterFromFilterSpec(Request request, String filterSpec)
+ throws FilterFactory.FilterNotCreatedException {
+ Description topLevelDescription = request.getRunner().getDescription();
+ String[] tuple;
+
+ if (filterSpec.contains("=")) {
+ tuple = filterSpec.split("=", 2);
+ } else {
+ tuple = new String[]{ filterSpec, "" };
+ }
+
+ return createFilter(tuple[0], new FilterFactoryParams(topLevelDescription, tuple[1]));
+ }
+
+ /**
+ * Creates a {@link Filter}.
+ *
+ * @param filterFactoryFqcn The fully qualified class name of the {@link FilterFactory}
+ * @param params The arguments to the {@link FilterFactory}
+ */
+ public static Filter createFilter(String filterFactoryFqcn, FilterFactoryParams params)
+ throws FilterFactory.FilterNotCreatedException {
+ FilterFactory filterFactory = createFilterFactory(filterFactoryFqcn);
+
+ return filterFactory.createFilter(params);
+ }
+
+ /**
+ * Creates a {@link Filter}.
+ *
+ * @param filterFactoryClass The class of the {@link FilterFactory}
+ * @param params The arguments to the {@link FilterFactory}
+ *
+ */
+ public static Filter createFilter(Class<? extends FilterFactory> filterFactoryClass, FilterFactoryParams params)
+ throws FilterFactory.FilterNotCreatedException {
+ FilterFactory filterFactory = createFilterFactory(filterFactoryClass);
+
+ return filterFactory.createFilter(params);
+ }
+
+ static FilterFactory createFilterFactory(String filterFactoryFqcn) throws FilterNotCreatedException {
+ Class<? extends FilterFactory> filterFactoryClass;
+
+ try {
+ filterFactoryClass = Classes.getClass(filterFactoryFqcn).asSubclass(FilterFactory.class);
+ } catch (Exception e) {
+ throw new FilterNotCreatedException(e);
+ }
+
+ return createFilterFactory(filterFactoryClass);
+ }
+
+ static FilterFactory createFilterFactory(Class<? extends FilterFactory> filterFactoryClass)
+ throws FilterNotCreatedException {
+ try {
+ return filterFactoryClass.getConstructor().newInstance();
+ } catch (Exception e) {
+ throw new FilterNotCreatedException(e);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactory.java
new file mode 100644
index 0000000..a966055
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactory.java
@@ -0,0 +1,25 @@
+package org.junit.runner;
+
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Extend this class to create a factory that creates {@link Filter}.
+ */
+public interface FilterFactory {
+ /**
+ * Creates a {@link Filter} given a {@link FilterFactoryParams} argument.
+ *
+ * @param params Parameters needed to create the {@link Filter}
+ */
+ Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException;
+
+ /**
+ * Exception thrown if the {@link Filter} cannot be created.
+ */
+ @SuppressWarnings("serial")
+ class FilterNotCreatedException extends Exception {
+ public FilterNotCreatedException(Exception exception) {
+ super(exception.getMessage(), exception);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactoryParams.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactoryParams.java
new file mode 100644
index 0000000..4ef7c23
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/FilterFactoryParams.java
@@ -0,0 +1,23 @@
+package org.junit.runner;
+
+public final class FilterFactoryParams {
+ private final Description topLevelDescription;
+ private final String args;
+
+ public FilterFactoryParams(Description topLevelDescription, String args) {
+ if (args == null || topLevelDescription == null) {
+ throw new NullPointerException();
+ }
+
+ this.topLevelDescription = topLevelDescription;
+ this.args = args;
+ }
+
+ public String getArgs() {
+ return args;
+ }
+
+ public Description getTopLevelDescription() {
+ return topLevelDescription;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCommandLineParseResult.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCommandLineParseResult.java
new file mode 100644
index 0000000..990c7c6
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCommandLineParseResult.java
@@ -0,0 +1,147 @@
+package org.junit.runner;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.internal.Classes;
+import org.junit.runner.FilterFactory.FilterNotCreatedException;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.model.InitializationError;
+
+class JUnitCommandLineParseResult {
+ private final List<String> filterSpecs = new ArrayList<String>();
+ private final List<Class<?>> classes = new ArrayList<Class<?>>();
+ private final List<Throwable> parserErrors = new ArrayList<Throwable>();
+
+ /**
+ * Do not use. Testing purposes only.
+ */
+ JUnitCommandLineParseResult() {}
+
+ /**
+ * Returns filter specs parsed from command line.
+ */
+ public List<String> getFilterSpecs() {
+ return Collections.unmodifiableList(filterSpecs);
+ }
+
+ /**
+ * Returns test classes parsed from command line.
+ */
+ public List<Class<?>> getClasses() {
+ return Collections.unmodifiableList(classes);
+ }
+
+ /**
+ * Parses the arguments.
+ *
+ * @param args Arguments
+ */
+ public static JUnitCommandLineParseResult parse(String[] args) {
+ JUnitCommandLineParseResult result = new JUnitCommandLineParseResult();
+
+ result.parseArgs(args);
+
+ return result;
+ }
+
+ private void parseArgs(String[] args) {
+ parseParameters(parseOptions(args));
+ }
+
+ String[] parseOptions(String... args) {
+ for (int i = 0; i != args.length; ++i) {
+ String arg = args[i];
+
+ if (arg.equals("--")) {
+ return copyArray(args, i + 1, args.length);
+ } else if (arg.startsWith("--")) {
+ if (arg.startsWith("--filter=") || arg.equals("--filter")) {
+ String filterSpec;
+ if (arg.equals("--filter")) {
+ ++i;
+
+ if (i < args.length) {
+ filterSpec = args[i];
+ } else {
+ parserErrors.add(new CommandLineParserError(arg + " value not specified"));
+ break;
+ }
+ } else {
+ filterSpec = arg.substring(arg.indexOf('=') + 1);
+ }
+
+ filterSpecs.add(filterSpec);
+ } else {
+ parserErrors.add(new CommandLineParserError("JUnit knows nothing about the " + arg + " option"));
+ }
+ } else {
+ return copyArray(args, i, args.length);
+ }
+ }
+
+ return new String[]{};
+ }
+
+ private String[] copyArray(String[] args, int from, int to) {
+ String[] result = new String[to - from];
+ for (int j = from; j != to; ++j) {
+ result[j - from] = args[j];
+ }
+ return result;
+ }
+
+ void parseParameters(String[] args) {
+ for (String arg : args) {
+ try {
+ classes.add(Classes.getClass(arg));
+ } catch (ClassNotFoundException e) {
+ parserErrors.add(new IllegalArgumentException("Could not find class [" + arg + "]", e));
+ }
+ }
+ }
+
+ private Request errorReport(Throwable cause) {
+ return Request.errorReport(JUnitCommandLineParseResult.class, cause);
+ }
+
+ /**
+ * Creates a {@link Request}.
+ *
+ * @param computer {@link Computer} to be used.
+ */
+ public Request createRequest(Computer computer) {
+ if (parserErrors.isEmpty()) {
+ Request request = Request.classes(
+ computer, classes.toArray(new Class<?>[classes.size()]));
+ return applyFilterSpecs(request);
+ } else {
+ return errorReport(new InitializationError(parserErrors));
+ }
+ }
+
+ private Request applyFilterSpecs(Request request) {
+ try {
+ for (String filterSpec : filterSpecs) {
+ Filter filter = FilterFactories.createFilterFromFilterSpec(
+ request, filterSpec);
+ request = request.filterWith(filter);
+ }
+ return request;
+ } catch (FilterNotCreatedException e) {
+ return errorReport(e);
+ }
+ }
+
+ /**
+ * Exception used if there's a problem parsing the command line.
+ */
+ public static class CommandLineParserError extends Exception {
+ private static final long serialVersionUID= 1L;
+
+ public CommandLineParserError(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCore.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCore.java
new file mode 100644
index 0000000..c1479e0
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCore.java
@@ -0,0 +1,167 @@
+package org.junit.runner;
+
+import junit.runner.Version;
+import org.junit.internal.JUnitSystem;
+import org.junit.internal.RealSystem;
+import org.junit.internal.TextListener;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+/**
+ * <code>JUnitCore</code> is a facade for running tests. It supports running JUnit 4 tests,
+ * JUnit 3.8.x tests, and mixtures. To run tests from the command line, run
+ * <code>java org.junit.runner.JUnitCore TestClass1 TestClass2 ...</code>.
+ * For one-shot test runs, use the static method {@link #runClasses(Class[])}.
+ * If you want to add special listeners,
+ * create an instance of {@link org.junit.runner.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
+ * @since 4.0
+ */
+public class JUnitCore {
+ private final RunNotifier notifier = new RunNotifier();
+
+ /**
+ * Run the tests contained in the classes named in the <code>args</code>.
+ * 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) {
+ Result result = new JUnitCore().runMain(new RealSystem(), args);
+ System.exit(result.wasSuccessful() ? 0 : 1);
+ }
+
+ /**
+ * Run the tests contained in <code>classes</code>. Write feedback while the tests
+ * are running and write stack traces for all failed tests after all tests complete. This is
+ * similar to {@link #main(String[])}, but intended to be used programmatically.
+ *
+ * @param classes Classes in which to find tests
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public static Result runClasses(Class<?>... classes) {
+ return runClasses(defaultComputer(), classes);
+ }
+
+ /**
+ * Run the tests contained in <code>classes</code>. Write feedback while the tests
+ * are running and write stack traces for all failed tests after all tests complete. This is
+ * similar to {@link #main(String[])}, but intended to be used programmatically.
+ *
+ * @param computer Helps construct Runners from classes
+ * @param classes Classes in which to find tests
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public static Result runClasses(Computer computer, Class<?>... classes) {
+ return new JUnitCore().run(computer, classes);
+ }
+
+ /**
+ * @param system
+ * @param args from main()
+ */
+ Result runMain(JUnitSystem system, String... args) {
+ system.out().println("JUnit version " + Version.id());
+
+ JUnitCommandLineParseResult jUnitCommandLineParseResult = JUnitCommandLineParseResult.parse(args);
+
+ RunListener listener = new TextListener(system);
+ addListener(listener);
+
+ return run(jUnitCommandLineParseResult.createRequest(defaultComputer()));
+ }
+
+ /**
+ * @return the version number of this release
+ */
+ public String getVersion() {
+ return Version.id();
+ }
+
+ /**
+ * Run all the tests in <code>classes</code>.
+ *
+ * @param classes the classes containing tests
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(Class<?>... classes) {
+ return run(defaultComputer(), classes);
+ }
+
+ /**
+ * Run all the tests in <code>classes</code>.
+ *
+ * @param computer Helps construct Runners from classes
+ * @param classes the classes containing tests
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(Computer computer, Class<?>... classes) {
+ return run(Request.classes(computer, classes));
+ }
+
+ /**
+ * Run all the tests contained in <code>request</code>.
+ *
+ * @param request the request describing tests
+ * @return a {@link 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 <code>test</code>. Here for backward compatibility.
+ *
+ * @param test the old-style test
+ * @return a {@link Result} describing the details of the test run and the failed tests.
+ */
+ public Result run(junit.framework.Test test) {
+ return run(new JUnit38ClassRunner(test));
+ }
+
+ /**
+ * Do not use. Testing purposes only.
+ */
+ public Result run(Runner runner) {
+ Result result = new Result();
+ RunListener listener = result.createListener();
+ notifier.addFirstListener(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 to add
+ * @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);
+ }
+
+ static Computer defaultComputer() {
+ return new Computer();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWith.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWith.java
new file mode 100644
index 0000000..e8470c9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWith.java
@@ -0,0 +1,28 @@
+package org.junit.runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.runner.manipulation.Ordering;
+import org.junit.validator.ValidateWith;
+
+/**
+ * When a test class is annotated with <code>@OrderWith</code> or extends a class annotated
+ * with <code>@OrderWith</code>, JUnit will order the tests in the test class (and child
+ * test classes, if any) using the ordering defined by the {@link Ordering} class.
+ *
+ * @since 4.13
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+@ValidateWith(OrderWithValidator.class)
+public @interface OrderWith {
+ /**
+ * Gets a class that extends {@link Ordering}. The class must have a public no-arg constructor.
+ */
+ Class<? extends Ordering.Factory> value();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWithValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWithValidator.java
new file mode 100644
index 0000000..f8eab25
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/OrderWithValidator.java
@@ -0,0 +1,38 @@
+package org.junit.runner;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import org.junit.FixMethodOrder;
+import org.junit.runners.model.TestClass;
+import org.junit.validator.AnnotationValidator;
+
+/**
+ * Validates that there are no errors in the use of the {@code OrderWith}
+ * annotation. If there is, a {@code Throwable} object will be added to the list
+ * of errors.
+ *
+ * @since 4.13
+ */
+public final class OrderWithValidator extends AnnotationValidator {
+
+ /**
+ * Adds to {@code errors} a throwable for each problem detected. Looks for
+ * {@code FixMethodOrder} annotations.
+ *
+ * @param testClass that is being validated
+ * @return A list of exceptions detected
+ *
+ * @since 4.13
+ */
+ @Override
+ public List<Exception> validateAnnotatedClass(TestClass testClass) {
+ if (testClass.getAnnotation(FixMethodOrder.class) != null) {
+ return singletonList(
+ new Exception("@FixMethodOrder cannot be combined with @OrderWith"));
+ }
+ return emptyList();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/Request.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Request.java
new file mode 100644
index 0000000..7b9a990
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Request.java
@@ -0,0 +1,202 @@
+package org.junit.runner;
+
+import java.util.Comparator;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.requests.ClassRequest;
+import org.junit.internal.requests.FilterRequest;
+import org.junit.internal.requests.OrderingRequest;
+import org.junit.internal.requests.SortingRequest;
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Ordering;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A <code>Request</code> 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 {@link org.junit.Test}s. 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.
+ *
+ * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run ->
+ * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> ->
+ * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
+ * which is a tree structure of the tests to be run.
+ *
+ * @since 4.0
+ */
+public abstract class Request {
+ /**
+ * Create a <code>Request</code> 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 <code>Request</code> 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 <code>Request</code> that, when processed, will run all the tests
+ * in a class. The odd name is necessary because <code>class</code> is a reserved word.
+ *
+ * @param clazz the class containing the tests
+ * @return a <code>Request</code> that will cause all tests in the class to be run
+ */
+ public static Request aClass(Class<?> clazz) {
+ return new ClassRequest(clazz);
+ }
+
+ /**
+ * Create a <code>Request</code> that, when processed, will run all the tests
+ * in a class. If the class has a suite() method, it will be ignored.
+ *
+ * @param clazz the class containing the tests
+ * @return a <code>Request</code> that will cause all tests in the class to be run
+ */
+ public static Request classWithoutSuiteMethod(Class<?> clazz) {
+ return new ClassRequest(clazz, false);
+ }
+
+ /**
+ * Create a <code>Request</code> that, when processed, will run all the tests
+ * in a set of classes.
+ *
+ * @param computer Helps construct Runners from classes
+ * @param classes the classes containing the tests
+ * @return a <code>Request</code> that will cause all tests in the classes to be run
+ */
+ public static Request classes(Computer computer, Class<?>... classes) {
+ try {
+ AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder();
+ Runner suite = computer.getSuite(builder, classes);
+ return runner(suite);
+ } catch (InitializationError e) {
+ return runner(new ErrorReportingRunner(e, classes));
+ }
+ }
+
+ /**
+ * Create a <code>Request</code> that, when processed, will run all the tests
+ * in a set of classes with the default <code>Computer</code>.
+ *
+ * @param classes the classes containing the tests
+ * @return a <code>Request</code> that will cause all tests in the classes to be run
+ */
+ public static Request classes(Class<?>... classes) {
+ return classes(JUnitCore.defaultComputer(), classes);
+ }
+
+
+ /**
+ * Creates a {@link Request} that, when processed, will report an error for the given
+ * test class with the given cause.
+ */
+ public static Request errorReport(Class<?> klass, Throwable cause) {
+ return runner(new ErrorReportingRunner(klass, cause));
+ }
+
+ /**
+ * @param runner the runner to return
+ * @return a <code>Request</code> that will run the given runner when invoked
+ */
+ public static Request runner(final Runner runner) {
+ return new Request() {
+ @Override
+ public Runner getRunner() {
+ return runner;
+ }
+ };
+ }
+
+ /**
+ * Returns a {@link Runner} for this Request
+ *
+ * @return corresponding {@link Runner} for this Request
+ */
+ public abstract Runner getRunner();
+
+ /**
+ * Returns a Request that only contains those tests that should run when
+ * <code>filter</code> is applied
+ *
+ * @param filter The {@link Filter} to apply to this Request
+ * @return the filtered Request
+ */
+ public Request filterWith(Filter filter) {
+ return new FilterRequest(this, filter);
+ }
+
+ /**
+ * Returns a Request that only runs tests whose {@link Description}
+ * matches the given description.
+ *
+ * <p>Returns an empty {@code Request} if {@code desiredDescription} is not a single test and filters all but the single
+ * test if {@code desiredDescription} is a single test.</p>
+ *
+ * @param desiredDescription {@code Description} of those tests that should be run
+ * @return the filtered Request
+ */
+ public Request filterWith(Description desiredDescription) {
+ return filterWith(Filter.matchMethodDescription(desiredDescription));
+ }
+
+ /**
+ * Returns a Request whose Tests can be run in a certain order, defined by
+ * <code>comparator</code>
+ * <p>
+ * For example, here is code to run a test suite in alphabetical order:
+ * <pre>
+ * private static Comparator<Description> forward() {
+ * return new Comparator<Description>() {
+ * public int compare(Description o1, Description o2) {
+ * return o1.getDisplayName().compareTo(o2.getDisplayName());
+ * }
+ * };
+ * }
+ *
+ * public static main() {
+ * new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
+ * }
+ * </pre>
+ *
+ * @param comparator definition of the order of the tests in this Request
+ * @return a Request with ordered Tests
+ */
+ public Request sortWith(Comparator<Description> comparator) {
+ return new SortingRequest(this, comparator);
+ }
+
+ /**
+ * Returns a Request whose Tests can be run in a certain order, defined by
+ * <code>ordering</code>
+ * <p>
+ * For example, here is code to run a test suite in reverse order:
+ * <pre>
+ * private static Ordering reverse() {
+ * return new Ordering() {
+ * public List<Description> orderItems(Collection<Description> descriptions) {
+ * List<Description> ordered = new ArrayList<>(descriptions);
+ * Collections.reverse(ordered);
+ * return ordered;
+ * }
+ * }
+ * }
+ *
+ * public static main() {
+ * new JUnitCore().run(Request.aClass(AllTests.class).orderWith(reverse()));
+ * }
+ * </pre>
+ *
+ * @return a Request with ordered Tests
+ * @since 4.13
+ */
+ public Request orderWith(Ordering ordering) {
+ return new OrderingRequest(this, ordering);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/Result.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Result.java
new file mode 100644
index 0000000..4b5f4a4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Result.java
@@ -0,0 +1,217 @@
+package org.junit.runner;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+/**
+ * A <code>Result</code> collects and summarizes information from running multiple tests.
+ * All tests are counted -- additional information is collected from tests that fail.
+ *
+ * @since 4.0
+ */
+public class Result implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private static final ObjectStreamField[] serialPersistentFields =
+ ObjectStreamClass.lookup(SerializedForm.class).getFields();
+ private final AtomicInteger count;
+ private final AtomicInteger ignoreCount;
+ private final AtomicInteger assumptionFailureCount;
+ private final CopyOnWriteArrayList<Failure> failures;
+ private final AtomicLong runTime;
+ private final AtomicLong startTime;
+
+ /** Only set during deserialization process. */
+ private SerializedForm serializedForm;
+
+ public Result() {
+ count = new AtomicInteger();
+ ignoreCount = new AtomicInteger();
+ assumptionFailureCount = new AtomicInteger();
+ failures = new CopyOnWriteArrayList<Failure>();
+ runTime = new AtomicLong();
+ startTime = new AtomicLong();
+ }
+
+ private Result(SerializedForm serializedForm) {
+ count = serializedForm.fCount;
+ ignoreCount = serializedForm.fIgnoreCount;
+ assumptionFailureCount = serializedForm.assumptionFailureCount;
+ failures = new CopyOnWriteArrayList<Failure>(serializedForm.fFailures);
+ runTime = new AtomicLong(serializedForm.fRunTime);
+ startTime = new AtomicLong(serializedForm.fStartTime);
+ }
+
+ /**
+ * Returns the number of tests run
+ */
+ public int getRunCount() {
+ return count.get();
+ }
+
+ /**
+ * Returns the number of tests that failed during the run
+ */
+ public int getFailureCount() {
+ return failures.size();
+ }
+
+ /**
+ * Returns the number of milliseconds it took to run the entire suite to run
+ */
+ public long getRunTime() {
+ return runTime.get();
+ }
+
+ /**
+ * Returns the {@link Failure}s describing tests that failed and the problems they encountered
+ */
+ public List<Failure> getFailures() {
+ return failures;
+ }
+
+ /**
+ * @return the number of tests ignored during the run
+ */
+ public int getIgnoreCount() {
+ return ignoreCount.get();
+ }
+
+ /**
+ * Returns the number of tests skipped because of an assumption failure
+ *
+ * @throws UnsupportedOperationException if the result was serialized in a version before JUnit 4.13
+ * @since 4.13
+ */
+ public int getAssumptionFailureCount() {
+ if (assumptionFailureCount == null) {
+ throw new UnsupportedOperationException(
+ "Result was serialized from a version of JUnit that doesn't support this method");
+ }
+ return assumptionFailureCount.get();
+ }
+
+ /**
+ * @return <code>true</code> if all tests succeeded
+ */
+ public boolean wasSuccessful() {
+ return getFailureCount() == 0;
+ }
+
+ private void writeObject(ObjectOutputStream s) throws IOException {
+ SerializedForm serializedForm = new SerializedForm(this);
+ serializedForm.serialize(s);
+ }
+
+ private void readObject(ObjectInputStream s)
+ throws ClassNotFoundException, IOException {
+ serializedForm = SerializedForm.deserialize(s);
+ }
+
+ private Object readResolve() {
+ return new Result(serializedForm);
+ }
+
+ @RunListener.ThreadSafe
+ private class Listener extends RunListener {
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ startTime.set(System.currentTimeMillis());
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ long endTime = System.currentTimeMillis();
+ runTime.addAndGet(endTime - startTime.get());
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ count.getAndIncrement();
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ failures.add(failure);
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ ignoreCount.getAndIncrement();
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ assumptionFailureCount.getAndIncrement();
+ }
+ }
+
+ /**
+ * Internal use only.
+ */
+ public RunListener createListener() {
+ return new Listener();
+ }
+
+ /**
+ * Represents the serialized output of {@code Result}. The fields on this
+ * class match the files that {@code Result} had in JUnit 4.11.
+ */
+ private static class SerializedForm implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private final AtomicInteger fCount;
+ private final AtomicInteger fIgnoreCount;
+ private final AtomicInteger assumptionFailureCount;
+ private final List<Failure> fFailures;
+ private final long fRunTime;
+ private final long fStartTime;
+
+ public SerializedForm(Result result) {
+ fCount = result.count;
+ fIgnoreCount = result.ignoreCount;
+ assumptionFailureCount = result.assumptionFailureCount;
+ fFailures = Collections.synchronizedList(new ArrayList<Failure>(result.failures));
+ fRunTime = result.runTime.longValue();
+ fStartTime = result.startTime.longValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ private SerializedForm(ObjectInputStream.GetField fields) throws IOException {
+ fCount = (AtomicInteger) fields.get("fCount", null);
+ fIgnoreCount = (AtomicInteger) fields.get("fIgnoreCount", null);
+ assumptionFailureCount = (AtomicInteger) fields.get("assumptionFailureCount", null);
+ fFailures = (List<Failure>) fields.get("fFailures", null);
+ fRunTime = fields.get("fRunTime", 0L);
+ fStartTime = fields.get("fStartTime", 0L);
+ }
+
+ public void serialize(ObjectOutputStream s) throws IOException {
+ ObjectOutputStream.PutField fields = s.putFields();
+ fields.put("fCount", fCount);
+ fields.put("fIgnoreCount", fIgnoreCount);
+ fields.put("fFailures", fFailures);
+ fields.put("fRunTime", fRunTime);
+ fields.put("fStartTime", fStartTime);
+ fields.put("assumptionFailureCount", assumptionFailureCount);
+ s.writeFields();
+ }
+
+ public static SerializedForm deserialize(ObjectInputStream s)
+ throws ClassNotFoundException, IOException {
+ ObjectInputStream.GetField fields = s.readFields();
+ return new SerializedForm(fields);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/RunWith.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/RunWith.java
new file mode 100644
index 0000000..3428ee2
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/RunWith.java
@@ -0,0 +1,36 @@
+package org.junit.runner;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * When a class is annotated with <code>@RunWith</code> or extends a class annotated
+ * with <code>@RunWith</code>, 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.
+ *
+ * For example, suites in JUnit 4 are built using RunWith, and a custom runner named Suite:
+ *
+ * <pre>
+ * @RunWith(Suite.class)
+ * @SuiteClasses({ATest.class, BTest.class, CTest.class})
+ * public class ABCSuite {
+ * }
+ * </pre>
+ *
+ * @since 4.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+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/google3/third_party/java_src/junit/main/java/org/junit/runner/Runner.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/Runner.java
new file mode 100644
index 0000000..d728dd8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/Runner.java
@@ -0,0 +1,43 @@
+package org.junit.runner;
+
+import org.junit.runner.notification.RunNotifier;
+
+/**
+ * A <code>Runner</code> runs tests and notifies a {@link org.junit.runner.notification.RunNotifier}
+ * of significant events as it does so. You will need to subclass <code>Runner</code>
+ * when using {@link org.junit.runner.RunWith} to invoke a custom runner. When creating
+ * a custom runner, in addition to implementing the abstract methods here you must
+ * also provide a constructor that takes as an argument the {@link Class} containing
+ * the tests.
+ *
+ * <p>The default runner implementation guarantees that the instances of the test case
+ * class will be constructed immediately before running the test and that the runner
+ * will retain no reference to the test case instances, generally making them
+ * available for garbage collection.
+ *
+ * @see org.junit.runner.Description
+ * @see org.junit.runner.RunWith
+ * @since 4.0
+ */
+public abstract class Runner implements Describable {
+ /*
+ * (non-Javadoc)
+ * @see org.junit.runner.Describable#getDescription()
+ */
+ 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();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Alphanumeric.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Alphanumeric.java
new file mode 100644
index 0000000..8388d21
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Alphanumeric.java
@@ -0,0 +1,27 @@
+package org.junit.runner.manipulation;
+
+import java.util.Comparator;
+
+import org.junit.runner.Description;
+
+/**
+ * A sorter that orders tests alphanumerically by test name.
+ *
+ * @since 4.13
+ */
+public final class Alphanumeric extends Sorter implements Ordering.Factory {
+
+ public Alphanumeric() {
+ super(COMPARATOR);
+ }
+
+ public Ordering create(Context context) {
+ return this;
+ }
+
+ private static final Comparator<Description> COMPARATOR = new Comparator<Description>() {
+ public int compare(Description o1, Description o2) {
+ return o1.getDisplayName().compareTo(o2.getDisplayName());
+ }
+ };
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filter.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filter.java
new file mode 100644
index 0000000..0287351
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filter.java
@@ -0,0 +1,122 @@
+package org.junit.runner.manipulation;
+
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+
+/**
+ * The canonical case of filtering is when you want to run a single test method in a class. Rather
+ * than introduce runner API just for that one case, JUnit provides a general filtering mechanism.
+ * If you want to filter the tests to be run, extend <code>Filter</code> and apply an instance of
+ * your filter to the {@link org.junit.runner.Request} before running it (see
+ * {@link org.junit.runner.JUnitCore#run(Request)}. Alternatively, apply a <code>Filter</code> to
+ * a {@link org.junit.runner.Runner} before running tests (for example, in conjunction with
+ * {@link org.junit.runner.RunWith}.
+ *
+ * @since 4.0
+ */
+public abstract class Filter {
+ /**
+ * A null <code>Filter</code> that passes all tests through.
+ */
+ public static final Filter ALL = new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return true;
+ }
+
+ @Override
+ public String describe() {
+ return "all tests";
+ }
+
+ @Override
+ public void apply(Object child) throws NoTestsRemainException {
+ // do nothing
+ }
+
+ @Override
+ public Filter intersect(Filter second) {
+ return second;
+ }
+ };
+
+ /**
+ * Returns a {@code Filter} that only runs the single method described by
+ * {@code desiredDescription}
+ */
+ public static Filter matchMethodDescription(final Description desiredDescription) {
+ return new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ if (description.isTest()) {
+ return desiredDescription.equals(description);
+ }
+
+ // explicitly check if any children want to run
+ for (Description each : description.getChildren()) {
+ if (shouldRun(each)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return String.format("Method %s", desiredDescription.getDisplayName());
+ }
+ };
+ }
+
+
+ /**
+ * @param description the description of the test to be run
+ * @return <code>true</code> if the test should be run
+ */
+ public abstract boolean shouldRun(Description description);
+
+ /**
+ * Returns a textual description of this Filter
+ *
+ * @return a textual description of this Filter
+ */
+ public abstract String describe();
+
+ /**
+ * Invoke with a {@link org.junit.runner.Runner} to cause all tests it intends to run
+ * to first be checked with the filter. Only those that pass the filter will be run.
+ *
+ * @param child the runner to be filtered by the receiver
+ * @throws NoTestsRemainException if the receiver removes all tests
+ */
+ public void apply(Object child) throws NoTestsRemainException {
+ if (!(child instanceof Filterable)) {
+ return;
+ }
+ Filterable filterable = (Filterable) child;
+ filterable.filter(this);
+ }
+
+ /**
+ * Returns a new Filter that accepts the intersection of the tests accepted
+ * by this Filter and {@code second}
+ */
+ public Filter intersect(final Filter second) {
+ if (second == this || second == ALL) {
+ return this;
+ }
+ final Filter first = this;
+ return new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return first.shouldRun(description)
+ && second.shouldRun(description);
+ }
+
+ @Override
+ public String describe() {
+ return first.describe() + " and " + second.describe();
+ }
+ };
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filterable.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filterable.java
new file mode 100644
index 0000000..d605027
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Filterable.java
@@ -0,0 +1,19 @@
+package org.junit.runner.manipulation;
+
+/**
+ * Runners that allow filtering should implement this interface. Implement {@link #filter(Filter)}
+ * to remove tests that don't pass the filter.
+ *
+ * @since 4.0
+ */
+public interface Filterable {
+
+ /**
+ * Remove tests that don't pass the parameter <code>filter</code>.
+ *
+ * @param filter the {@link Filter} to apply
+ * @throws NoTestsRemainException if all tests are filtered out
+ */
+ void filter(Filter filter) throws NoTestsRemainException;
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/InvalidOrderingException.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/InvalidOrderingException.java
new file mode 100644
index 0000000..d9d60f7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/InvalidOrderingException.java
@@ -0,0 +1,21 @@
+package org.junit.runner.manipulation;
+
+/**
+ * Thrown when an ordering does something invalid (like remove or add children)
+ *
+ * @since 4.13
+ */
+public class InvalidOrderingException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public InvalidOrderingException() {
+ }
+
+ public InvalidOrderingException(String message) {
+ super(message);
+ }
+
+ public InvalidOrderingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/NoTestsRemainException.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/NoTestsRemainException.java
new file mode 100644
index 0000000..21935bd
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/NoTestsRemainException.java
@@ -0,0 +1,10 @@
+package org.junit.runner.manipulation;
+
+/**
+ * Thrown when a filter removes all tests from a runner.
+ *
+ * @since 4.0
+ */
+public class NoTestsRemainException extends Exception {
+ private static final long serialVersionUID = 1L;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderable.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderable.java
new file mode 100644
index 0000000..9a12a3b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderable.java
@@ -0,0 +1,21 @@
+package org.junit.runner.manipulation;
+
+/**
+ * Interface for runners that allow ordering of tests.
+ *
+ * <p>Beware of using this interface to cope with order dependencies between tests.
+ * Tests that are isolated from each other are less expensive to maintain and
+ * can be run individually.
+ *
+ * @since 4.13
+ */
+public interface Orderable extends Sortable {
+
+ /**
+ * Orders the tests using <code>orderer</code>
+ *
+ * @throws InvalidOrderingException if orderer does something invalid (like remove or add
+ * children)
+ */
+ void order(Orderer orderer) throws InvalidOrderingException;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderer.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderer.java
new file mode 100644
index 0000000..eb13054
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Orderer.java
@@ -0,0 +1,62 @@
+package org.junit.runner.manipulation;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.runner.Description;
+
+/**
+ * Orders tests.
+ *
+ * @since 4.13
+ */
+public final class Orderer {
+ private final Ordering ordering;
+
+ Orderer(Ordering delegate) {
+ this.ordering = delegate;
+ }
+
+ /**
+ * Orders the descriptions.
+ *
+ * @return descriptions in order
+ */
+ public List<Description> order(Collection<Description> descriptions)
+ throws InvalidOrderingException {
+ List<Description> inOrder = ordering.orderItems(
+ Collections.unmodifiableCollection(descriptions));
+ if (!ordering.validateOrderingIsCorrect()) {
+ return inOrder;
+ }
+
+ Set<Description> uniqueDescriptions = new HashSet<Description>(descriptions);
+ if (!uniqueDescriptions.containsAll(inOrder)) {
+ throw new InvalidOrderingException("Ordering added items");
+ }
+ Set<Description> resultAsSet = new HashSet<Description>(inOrder);
+ if (resultAsSet.size() != inOrder.size()) {
+ throw new InvalidOrderingException("Ordering duplicated items");
+ } else if (!resultAsSet.containsAll(uniqueDescriptions)) {
+ throw new InvalidOrderingException("Ordering removed items");
+ }
+
+ return inOrder;
+ }
+
+ /**
+ * Order the tests in <code>target</code>.
+ *
+ * @throws InvalidOrderingException if ordering does something invalid (like remove or add
+ * children)
+ */
+ public void apply(Object target) throws InvalidOrderingException {
+ if (target instanceof Orderable) {
+ Orderable orderable = (Orderable) target;
+ orderable.order(this);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Ordering.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Ordering.java
new file mode 100644
index 0000000..0d0ce93
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Ordering.java
@@ -0,0 +1,172 @@
+package org.junit.runner.manipulation;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import org.junit.runner.Description;
+import org.junit.runner.OrderWith;
+
+/**
+ * Reorders tests. An {@code Ordering} can reverse the order of tests, sort the
+ * order or even shuffle the order.
+ *
+ * <p>In general you will not need to use a <code>Ordering</code> directly.
+ * Instead, use {@link org.junit.runner.Request#orderWith(Ordering)}.
+ *
+ * @since 4.13
+ */
+public abstract class Ordering {
+ private static final String CONSTRUCTOR_ERROR_FORMAT
+ = "Ordering class %s should have a public constructor with signature "
+ + "%s(Ordering.Context context)";
+
+ /**
+ * Creates an {@link Ordering} that shuffles the items using the given
+ * {@link Random} instance.
+ */
+ public static Ordering shuffledBy(final Random random) {
+ return new Ordering() {
+ @Override
+ boolean validateOrderingIsCorrect() {
+ return false;
+ }
+
+ @Override
+ protected List<Description> orderItems(Collection<Description> descriptions) {
+ List<Description> shuffled = new ArrayList<Description>(descriptions);
+ Collections.shuffle(shuffled, random);
+ return shuffled;
+ }
+ };
+ }
+
+ /**
+ * Creates an {@link Ordering} from the given factory class. The class must have a public no-arg
+ * constructor.
+ *
+ * @param factoryClass class to use to create the ordering
+ * @param annotatedTestClass test class that is annotated with {@link OrderWith}.
+ * @throws InvalidOrderingException if the instance could not be created
+ */
+ public static Ordering definedBy(
+ Class<? extends Ordering.Factory> factoryClass, Description annotatedTestClass)
+ throws InvalidOrderingException {
+ if (factoryClass == null) {
+ throw new NullPointerException("factoryClass cannot be null");
+ }
+ if (annotatedTestClass == null) {
+ throw new NullPointerException("annotatedTestClass cannot be null");
+ }
+
+ Ordering.Factory factory;
+ try {
+ Constructor<? extends Ordering.Factory> constructor = factoryClass.getConstructor();
+ factory = constructor.newInstance();
+ } catch (NoSuchMethodException e) {
+ throw new InvalidOrderingException(String.format(
+ CONSTRUCTOR_ERROR_FORMAT,
+ getClassName(factoryClass),
+ factoryClass.getSimpleName()));
+ } catch (Exception e) {
+ throw new InvalidOrderingException(
+ "Could not create ordering for " + annotatedTestClass, e);
+ }
+ return definedBy(factory, annotatedTestClass);
+ }
+
+ /**
+ * Creates an {@link Ordering} from the given factory.
+ *
+ * @param factory factory to use to create the ordering
+ * @param annotatedTestClass test class that is annotated with {@link OrderWith}.
+ * @throws InvalidOrderingException if the instance could not be created
+ */
+ public static Ordering definedBy(
+ Ordering.Factory factory, Description annotatedTestClass)
+ throws InvalidOrderingException {
+ if (factory == null) {
+ throw new NullPointerException("factory cannot be null");
+ }
+ if (annotatedTestClass == null) {
+ throw new NullPointerException("annotatedTestClass cannot be null");
+ }
+
+ return factory.create(new Ordering.Context(annotatedTestClass));
+ }
+
+ private static String getClassName(Class<?> clazz) {
+ String name = clazz.getCanonicalName();
+ if (name == null) {
+ return clazz.getName();
+ }
+ return name;
+ }
+
+ /**
+ * Order the tests in <code>target</code> using this ordering.
+ *
+ * @throws InvalidOrderingException if ordering does something invalid (like remove or add
+ * children)
+ */
+ public void apply(Object target) throws InvalidOrderingException {
+ /*
+ * Note that some subclasses of Ordering override apply(). The Sorter
+ * subclass of Ordering overrides apply() to apply the sort (this is
+ * done because sorting is more efficient than ordering).
+ */
+ if (target instanceof Orderable) {
+ Orderable orderable = (Orderable) target;
+ orderable.order(new Orderer(this));
+ }
+ }
+
+ /**
+ * Returns {@code true} if this ordering could produce invalid results (i.e.
+ * if it could add or remove values).
+ */
+ boolean validateOrderingIsCorrect() {
+ return true;
+ }
+
+ /**
+ * Implemented by sub-classes to order the descriptions.
+ *
+ * @return descriptions in order
+ */
+ protected abstract List<Description> orderItems(Collection<Description> descriptions);
+
+ /** Context about the ordering being applied. */
+ public static class Context {
+ private final Description description;
+
+ /**
+ * Gets the description for the top-level target being ordered.
+ */
+ public Description getTarget() {
+ return description;
+ }
+
+ private Context(Description description) {
+ this.description = description;
+ }
+ }
+
+ /**
+ * Factory for creating {@link Ordering} instances.
+ *
+ * <p>For a factory to be used with {@code @OrderWith} it needs to have a public no-arg
+ * constructor.
+ */
+ public interface Factory {
+ /**
+ * Creates an Ordering instance using the given context. Implementations
+ * of this method that do not need to use the context can return the
+ * same instance every time.
+ */
+ Ordering create(Context context);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sortable.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sortable.java
new file mode 100644
index 0000000..0c59f33
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sortable.java
@@ -0,0 +1,20 @@
+package org.junit.runner.manipulation;
+
+/**
+ * Interface for runners that allow sorting of tests. By sorting tests based on when they last failed, most recently
+ * failed first, you can reduce the average time to the first test failing. Test sorting should not be used to
+ * cope with order dependencies between tests. Tests that are isolated from each other are less
+ * expensive to maintain and can be run individually.
+ *
+ * @since 4.0
+ */
+public interface Sortable {
+
+ /**
+ * Sorts the tests using <code>sorter</code>
+ *
+ * @param sorter the {@link Sorter} to use for sorting the tests
+ */
+ void sort(Sorter sorter);
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sorter.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sorter.java
new file mode 100644
index 0000000..4b5274c
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/Sorter.java
@@ -0,0 +1,90 @@
+package org.junit.runner.manipulation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.junit.runner.Description;
+
+/**
+ * A <code>Sorter</code> orders tests. In general you will not need
+ * to use a <code>Sorter</code> directly. Instead, use
+ * {@link org.junit.runner.Request#sortWith(Comparator)}.
+ *
+ * @since 4.0
+ */
+public class Sorter extends Ordering implements Comparator<Description> {
+ /**
+ * NULL is a <code>Sorter</code> that leaves elements in an undefined order
+ */
+ public static final Sorter NULL = new Sorter(new Comparator<Description>() {
+ public int compare(Description o1, Description o2) {
+ return 0;
+ }
+ });
+
+ private final Comparator<Description> comparator;
+
+ /**
+ * Creates a <code>Sorter</code> that uses <code>comparator</code>
+ * to sort tests
+ *
+ * @param comparator the {@link Comparator} to use when sorting tests
+ * @since 4.0
+ */
+ public Sorter(Comparator<Description> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Sorts the tests in <code>target</code> using <code>comparator</code>.
+ *
+ * @since 4.0
+ */
+ @Override
+ public void apply(Object target) {
+ /*
+ * Note that all runners that are Orderable are also Sortable (because
+ * Orderable extends Sortable). Sorting is more efficient than ordering,
+ * so we override the parent behavior so we sort instead.
+ */
+ if (target instanceof Sortable) {
+ Sortable sortable = (Sortable) target;
+ sortable.sort(this);
+ }
+ }
+
+ public int compare(Description o1, Description o2) {
+ return comparator.compare(o1, o2);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 4.13
+ */
+ @Override
+ protected final List<Description> orderItems(Collection<Description> descriptions) {
+ /*
+ * In practice, we will never get here--Sorters do their work in the
+ * compare() method--but the Liskov substitution principle demands that
+ * we obey the general contract of Orderable. Luckily, it's trivial to
+ * implement.
+ */
+ List<Description> sorted = new ArrayList<Description>(descriptions);
+ Collections.sort(sorted, this); // Note: it would be incorrect to pass in "comparator"
+ return sorted;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 4.13
+ */
+ @Override
+ boolean validateOrderingIsCorrect() {
+ return false;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/package-info.java
new file mode 100644
index 0000000..ba5c3b2
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/manipulation/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Provides classes to {@link org.junit.runner.manipulation.Filter filter} or {@link org.junit.runner.manipulation.Sorter sort} tests.
+ *
+ * @since 4.0
+ * @see org.junit.runner.Runner
+ */
+package org.junit.runner.manipulation;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/Failure.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/Failure.java
new file mode 100644
index 0000000..4551302
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/Failure.java
@@ -0,0 +1,90 @@
+package org.junit.runner.notification;
+
+import java.io.Serializable;
+
+import org.junit.internal.Throwables;
+import org.junit.runner.Description;
+
+/**
+ * A <code>Failure</code> holds a description of the failed test and the
+ * exception that was thrown while running it. In most cases the {@link org.junit.runner.Description}
+ * will be of a single test. However, if problems are encountered while constructing the
+ * test (for example, if a {@link org.junit.BeforeClass} method is not static), it may describe
+ * something other than a single test.
+ *
+ * @since 4.0
+ */
+public class Failure implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final Description fDescription;
+ private final Throwable fThrownException;
+
+ /**
+ * Constructs a <code>Failure</code> with the given description and exception.
+ *
+ * @param description a {@link org.junit.runner.Description} of the test that failed
+ * @param thrownException the exception that was thrown while running the test
+ */
+ public Failure(Description description, Throwable thrownException) {
+ this.fThrownException = thrownException;
+ this.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() {
+ return getTestHeader() + ": " + fThrownException.getMessage();
+ }
+
+ /**
+ * Gets the printed form of the exception and its stack trace.
+ */
+ public String getTrace() {
+ return Throwables.getStacktrace(getException());
+ }
+
+ /**
+ * Gets a the printed form of the exception, with a trimmed version of the stack trace.
+ * This method will attempt to filter out frames of the stack trace that are below
+ * the test method call.
+ */
+ public String getTrimmedTrace() {
+ return Throwables.getTrimmedStackTrace(getException());
+ }
+
+ /**
+ * Convenience method
+ *
+ * @return the message of the thrown exception
+ */
+ public String getMessage() {
+ return getException().getMessage();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunListener.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunListener.java
new file mode 100644
index 0000000..d7cac00
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunListener.java
@@ -0,0 +1,168 @@
+package org.junit.runner.notification;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+
+/**
+ * Register an instance of this class with {@link RunNotifier} to be notified
+ * of events that occur during a test run. All of the methods in this class
+ * are abstract and have no implementation; override one or more methods to
+ * receive events.
+ * <p>
+ * For example, suppose you have a <code>Cowbell</code>
+ * class that you want to make a noise whenever a test fails. You could write:
+ * <pre>
+ * public class RingingListener extends RunListener {
+ * public void testFailure(Failure failure) {
+ * Cowbell.ring();
+ * }
+ * }
+ * </pre>
+ * <p>
+ * To invoke your listener, you need to run your tests through <code>JUnitCore</code>.
+ * <pre>
+ * public void main(String... args) {
+ * JUnitCore core= new JUnitCore();
+ * core.addListener(new RingingListener());
+ * core.run(MyTestClass.class);
+ * }
+ * </pre>
+ * <p>
+ * If a listener throws an exception for a test event, the other listeners will
+ * have their {@link RunListener#testFailure(Failure)} called with a {@code Description}
+ * of {@link Description#TEST_MECHANISM} to indicate the failure.
+ * <p>
+ * By default, JUnit will synchronize calls to your listener. If your listener
+ * is thread-safe and you want to allow JUnit to call your listener from
+ * multiple threads when tests are run in parallel, you can annotate your
+ * test class with {@link RunListener.ThreadSafe}.
+ * <p>
+ * Listener methods will be called from the same thread as is running
+ * the test, unless otherwise indicated by the method Javadoc
+ *
+ * @see org.junit.runner.JUnitCore
+ * @since 4.0
+ */
+public class RunListener {
+
+ /**
+ * Called before any tests have been run. This may be called on an
+ * arbitrary thread.
+ *
+ * @param description describes the tests to be run
+ */
+ public void testRunStarted(Description description) throws Exception {
+ }
+
+ /**
+ * Called when all tests have finished. This may be called on an
+ * arbitrary thread.
+ *
+ * @param result the summary of the test run, including all the tests that failed
+ */
+ public void testRunFinished(Result result) throws Exception {
+ }
+
+ /**
+ * Called when a test suite is about to be started. If this method is
+ * called for a given {@link Description}, then {@link #testSuiteFinished(Description)}
+ * will also be called for the same {@code Description}.
+ *
+ * <p>Note that not all runners will call this method, so runners should
+ * be prepared to handle {@link #testStarted(Description)} calls for tests
+ * where there was no corresponding {@code testSuiteStarted()} call for
+ * the parent {@code Description}.
+ *
+ * @param description the description of the test suite that is about to be run
+ * (generally a class name)
+ * @since 4.13
+ */
+ public void testSuiteStarted(Description description) throws Exception {
+ }
+
+ /**
+ * Called when a test suite has finished, whether the test suite succeeds or fails.
+ * This method will not be called for a given {@link Description} unless
+ * {@link #testSuiteStarted(Description)} was called for the same @code Description}.
+ *
+ * @param description the description of the test suite that just ran
+ * @since 4.13
+ */
+ public void testSuiteFinished(Description description) 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, or when a listener throws an exception.
+ *
+ * <p>In the case of a failure of an atomic test, this method will be called
+ * with the same {@code Description} passed to
+ * {@link #testStarted(Description)}, from the same thread that called
+ * {@link #testStarted(Description)}.
+ *
+ * <p>In the case of a listener throwing an exception, this will be called with
+ * a {@code Description} of {@link Description#TEST_MECHANISM}, and may be called
+ * on an arbitrary thread.
+ *
+ * @param failure describes the test that failed and the exception that was thrown
+ */
+ public void testFailure(Failure failure) throws Exception {
+ }
+
+ /**
+ * Called when an atomic test flags that it assumes a condition that is
+ * false
+ *
+ * @param failure describes the test that failed and the
+ * {@link org.junit.AssumptionViolatedException} that was thrown
+ */
+ public void testAssumptionFailure(Failure failure) {
+ }
+
+ /**
+ * Called when a test will not be run, generally because a test method is annotated
+ * with {@link org.junit.Ignore}.
+ *
+ * @param description describes the test that will not be run
+ */
+ public void testIgnored(Description description) throws Exception {
+ }
+
+
+ /**
+ * Indicates a {@code RunListener} that can have its methods called
+ * concurrently. This implies that the class is thread-safe (i.e. no set of
+ * listener calls can put the listener into an invalid state, even if those
+ * listener calls are being made by multiple threads without
+ * synchronization).
+ *
+ * @since 4.12
+ */
+ @Documented
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ThreadSafe {
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunNotifier.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunNotifier.java
new file mode 100644
index 0000000..752fa3b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/RunNotifier.java
@@ -0,0 +1,249 @@
+package org.junit.runner.notification;
+
+import static java.util.Arrays.asList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+
+/**
+ * If you write custom runners, you may need to notify JUnit of your progress running tests.
+ * Do this by invoking the <code>RunNotifier</code> passed to your implementation of
+ * {@link org.junit.runner.Runner#run(RunNotifier)}. Future evolution of this class is likely to
+ * move {@link #fireTestRunStarted(Description)} and {@link #fireTestRunFinished(Result)}
+ * to a separate class since they should only be called once per run.
+ *
+ * @since 4.0
+ */
+public class RunNotifier {
+ private final List<RunListener> listeners = new CopyOnWriteArrayList<RunListener>();
+ private volatile boolean pleaseStop = false;
+
+ /**
+ * Internal use only
+ */
+ public void addListener(RunListener listener) {
+ if (listener == null) {
+ throw new NullPointerException("Cannot add a null listener");
+ }
+ listeners.add(wrapIfNotThreadSafe(listener));
+ }
+
+ /**
+ * Internal use only
+ */
+ public void removeListener(RunListener listener) {
+ if (listener == null) {
+ throw new NullPointerException("Cannot remove a null listener");
+ }
+ listeners.remove(wrapIfNotThreadSafe(listener));
+ }
+
+ /**
+ * Wraps the given listener with {@link SynchronizedRunListener} if
+ * it is not annotated with {@link RunListener.ThreadSafe}.
+ */
+ RunListener wrapIfNotThreadSafe(RunListener listener) {
+ return listener.getClass().isAnnotationPresent(RunListener.ThreadSafe.class) ?
+ listener : new SynchronizedRunListener(listener, this);
+ }
+
+
+ private abstract class SafeNotifier {
+ private final List<RunListener> currentListeners;
+
+ SafeNotifier() {
+ this(listeners);
+ }
+
+ SafeNotifier(List<RunListener> currentListeners) {
+ this.currentListeners = currentListeners;
+ }
+
+ void run() {
+ int capacity = currentListeners.size();
+ List<RunListener> safeListeners = new ArrayList<RunListener>(capacity);
+ List<Failure> failures = new ArrayList<Failure>(capacity);
+ for (RunListener listener : currentListeners) {
+ try {
+ notifyListener(listener);
+ safeListeners.add(listener);
+ } catch (Exception e) {
+ failures.add(new Failure(Description.TEST_MECHANISM, e));
+ }
+ }
+ fireTestFailures(safeListeners, failures);
+ }
+
+ protected abstract void notifyListener(RunListener each) throws Exception;
+ }
+
+ /**
+ * Do not invoke.
+ */
+ public void fireTestRunStarted(final Description description) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testRunStarted(description);
+ }
+ }.run();
+ }
+
+ /**
+ * Do not invoke.
+ */
+ public void fireTestRunFinished(final Result result) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testRunFinished(result);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that a test suite is about to start. Runners are strongly
+ * encouraged--but not required--to call this method. If this method is called for
+ * a given {@link Description} then {@link #fireTestSuiteFinished(Description)} MUST
+ * be called for the same {@code Description}.
+ *
+ * @param description the description of the suite test (generally a class name)
+ * @since 4.13
+ */
+ public void fireTestSuiteStarted(final Description description) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testSuiteStarted(description);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that a test suite is about to finish. Always invoke
+ * this method if you invoke {@link #fireTestSuiteStarted(Description)}
+ * as listeners are likely to expect them to come in pairs.
+ *
+ * @param description the description of the suite test (generally a class name)
+ * @since 4.13
+ */
+ public void fireTestSuiteFinished(final Description description) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testSuiteFinished(description);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that an atomic test is about to start.
+ *
+ * @param description the description of the atomic test (generally a class and method name)
+ * @throws StoppedByUserException thrown if a user has requested that the test run stop
+ */
+ public void fireTestStarted(final Description description) throws StoppedByUserException {
+ if (pleaseStop) {
+ throw new StoppedByUserException();
+ }
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testStarted(description);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that an atomic test failed.
+ *
+ * @param failure the description of the test that failed and the exception thrown
+ */
+ public void fireTestFailure(Failure failure) {
+ fireTestFailures(listeners, asList(failure));
+ }
+
+ private void fireTestFailures(List<RunListener> listeners,
+ final List<Failure> failures) {
+ if (!failures.isEmpty()) {
+ new SafeNotifier(listeners) {
+ @Override
+ protected void notifyListener(RunListener listener) throws Exception {
+ for (Failure each : failures) {
+ listener.testFailure(each);
+ }
+ }
+ }.run();
+ }
+ }
+
+ /**
+ * Invoke to tell listeners that an atomic test flagged that it assumed
+ * something false.
+ *
+ * @param failure the description of the test that failed and the
+ * {@link org.junit.AssumptionViolatedException} thrown
+ */
+ public void fireTestAssumptionFailed(final Failure failure) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testAssumptionFailure(failure);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that an atomic test was ignored.
+ *
+ * @param description the description of the ignored test
+ */
+ public void fireTestIgnored(final Description description) {
+ new SafeNotifier() {
+ @Override
+ protected void notifyListener(RunListener each) throws Exception {
+ each.testIgnored(description);
+ }
+ }.run();
+ }
+
+ /**
+ * Invoke to tell listeners that an atomic test finished. Always invoke
+ * this method if you invoke {@link #fireTestStarted(Description)}
+ * 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 <code>RunNotifier</code> is the only object guaranteed
+ * to be shared amongst the many runners involved.
+ */
+ public void pleaseStop() {
+ pleaseStop = true;
+ }
+
+ /**
+ * Internal use only. The Result's listener must be first.
+ */
+ public void addFirstListener(RunListener listener) {
+ if (listener == null) {
+ throw new NullPointerException("Cannot add a null listener");
+ }
+ listeners.add(0, wrapIfNotThreadSafe(listener));
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/StoppedByUserException.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/StoppedByUserException.java
new file mode 100644
index 0000000..f5490f7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/StoppedByUserException.java
@@ -0,0 +1,12 @@
+package org.junit.runner.notification;
+
+/**
+ * Thrown when a user has requested that the test run stop. Writers of
+ * test running GUIs should be prepared to catch a <code>StoppedByUserException</code>.
+ *
+ * @see org.junit.runner.notification.RunNotifier
+ * @since 4.0
+ */
+public class StoppedByUserException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/SynchronizedRunListener.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/SynchronizedRunListener.java
new file mode 100644
index 0000000..400fed8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/SynchronizedRunListener.java
@@ -0,0 +1,134 @@
+package org.junit.runner.notification;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+
+/**
+ * Thread-safe decorator for {@link RunListener} implementations that synchronizes
+ * calls to the delegate.
+ *
+ * <p>This class synchronizes all listener calls on a RunNotifier instance. This is done because
+ * prior to JUnit 4.12, all listeners were called in a synchronized block in RunNotifier,
+ * so no two listeners were ever called concurrently. If we instead made the methods here
+ * synchronized, clients that added multiple listeners that called common code might see
+ * issues due to the reduced synchronization.
+ *
+ * @author Tibor Digana (tibor17)
+ * @author Kevin Cooney (kcooney)
+ * @since 4.12
+ *
+ * @see RunNotifier
+ */
+@RunListener.ThreadSafe
+final class SynchronizedRunListener extends RunListener {
+ private final RunListener listener;
+ private final Object monitor;
+
+ SynchronizedRunListener(RunListener listener, Object monitor) {
+ this.listener = listener;
+ this.monitor = monitor;
+ }
+
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testRunStarted(description);
+ }
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ synchronized (monitor) {
+ listener.testRunFinished(result);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Synchronized decorator for {@link RunListener#testSuiteStarted(Description)}.
+ * @param description the description of the test suite that is about to be run
+ * (generally a class name).
+ * @throws Exception if any occurs.
+ * @since 4.13
+ */
+ @Override
+ public void testSuiteStarted(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testSuiteStarted(description);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Synchronized decorator for {@link RunListener#testSuiteFinished(Description)}.
+ * @param description the description of the test suite that just ran.
+ * @throws Exception
+ * @since 4.13
+ */
+ @Override
+ public void testSuiteFinished(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testSuiteFinished(description);
+ }
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testStarted(description);
+ }
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testFinished(description);
+ }
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ synchronized (monitor) {
+ listener.testFailure(failure);
+ }
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ synchronized (monitor) {
+ listener.testAssumptionFailure(failure);
+ }
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ synchronized (monitor) {
+ listener.testIgnored(description);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return listener.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof SynchronizedRunListener)) {
+ return false;
+ }
+ SynchronizedRunListener that = (SynchronizedRunListener) other;
+
+ return listener.equals(that.listener);
+ }
+
+ @Override
+ public String toString() {
+ return listener.toString() + " (with synchronization wrapper)";
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/package-info.java
new file mode 100644
index 0000000..0331c8f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/notification/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides information about a test run.
+ *
+ * @since 4.0
+ */
+package org.junit.runner.notification;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runner/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/runner/package-info.java
new file mode 100644
index 0000000..e19fa0b
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runner/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides classes used to describe, collect, run and analyze multiple tests.
+ *
+ * @since 4.0
+ */
+package org.junit.runner;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/AllTests.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/AllTests.java
new file mode 100644
index 0000000..416c99d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/AllTests.java
@@ -0,0 +1,27 @@
+package org.junit.runners;
+
+import org.junit.internal.runners.SuiteMethod;
+
+/**
+ * Runner for use with JUnit 3.8.x-style AllTests classes
+ * (those that only implement a static <code>suite()</code>
+ * method). For example:
+ * <pre>
+ * @RunWith(AllTests.class)
+ * public class ProductTests {
+ * public static junit.framework.Test suite() {
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * @since 4.0
+ */
+public class AllTests extends SuiteMethod {
+ /**
+ * Only called reflectively. Do not use programmatically.
+ */
+ public AllTests(Class<?> klass) throws Throwable {
+ super(klass);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
new file mode 100644
index 0000000..455341a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
@@ -0,0 +1,473 @@
+package org.junit.runners;
+
+import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_METHOD_VALIDATOR;
+import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_VALIDATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.Test.None;
+import org.junit.internal.runners.model.ReflectiveCallable;
+import org.junit.internal.runners.statements.ExpectException;
+import org.junit.internal.runners.statements.Fail;
+import org.junit.internal.runners.statements.FailOnTimeout;
+import org.junit.internal.runners.statements.InvokeMethod;
+import org.junit.internal.runners.statements.RunAfters;
+import org.junit.internal.runners.statements.RunBefores;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.FrameworkMember;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.MemberValueConsumer;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+import org.junit.validator.PublicClassValidator;
+import org.junit.validator.TestClassValidator;
+
+/**
+ * Implements the JUnit 4 standard test case class model, as defined by the
+ * annotations in the org.junit package. Many users will never notice this
+ * class: it is now the default test class runner, but it should have exactly
+ * the same behavior as the old test class runner ({@code JUnit4ClassRunner}).
+ * <p>
+ * BlockJUnit4ClassRunner has advantages for writers of custom JUnit runners
+ * that are slight changes to the default behavior, however:
+ *
+ * <ul>
+ * <li>It has a much simpler implementation based on {@link Statement}s,
+ * allowing new operations to be inserted into the appropriate point in the
+ * execution flow.
+ *
+ * <li>It is published, and extension and reuse are encouraged, whereas {@code
+ * JUnit4ClassRunner} was in an internal package, and is now deprecated.
+ * </ul>
+ * <p>
+ * In turn, in 2009 we introduced {@link Rule}s. In many cases where extending
+ * BlockJUnit4ClassRunner was necessary to add new behavior, {@link Rule}s can
+ * be used, which makes the extension more reusable and composable.
+ *
+ * @since 4.5
+ */
+public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> {
+ private static TestClassValidator PUBLIC_CLASS_VALIDATOR = new PublicClassValidator();
+
+ private final ConcurrentMap<FrameworkMethod, Description> methodDescriptions = new ConcurrentHashMap<FrameworkMethod, Description>();
+
+ /**
+ * Creates a BlockJUnit4ClassRunner to run {@code testClass}
+ *
+ * @throws InitializationError if the test class is malformed.
+ */
+ public BlockJUnit4ClassRunner(Class<?> testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ /**
+ * Creates a BlockJUnit4ClassRunner to run {@code testClass}.
+ *
+ * @throws InitializationError if the test class is malformed.
+ * @since 4.13
+ */
+ protected BlockJUnit4ClassRunner(TestClass testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ //
+ // Implementation of ParentRunner
+ //
+
+ @Override
+ protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
+ Description description = describeChild(method);
+ if (isIgnored(method)) {
+ notifier.fireTestIgnored(description);
+ } else {
+ Statement statement = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ methodBlock(method).evaluate();
+ }
+ };
+ runLeaf(statement, description, notifier);
+ }
+ }
+
+ /**
+ * Evaluates whether {@link FrameworkMethod}s are ignored based on the
+ * {@link Ignore} annotation.
+ */
+ @Override
+ protected boolean isIgnored(FrameworkMethod child) {
+ return child.getAnnotation(Ignore.class) != null;
+ }
+
+ @Override
+ protected Description describeChild(FrameworkMethod method) {
+ Description description = methodDescriptions.get(method);
+
+ if (description == null) {
+ description = Description.createTestDescription(getTestClass().getJavaClass(),
+ testName(method), method.getAnnotations());
+ methodDescriptions.putIfAbsent(method, description);
+ }
+
+ return description;
+ }
+
+ @Override
+ protected List<FrameworkMethod> getChildren() {
+ return computeTestMethods();
+ }
+
+ //
+ // Override in subclasses
+ //
+
+ /**
+ * Returns the methods that run tests. Default implementation returns all
+ * methods annotated with {@code @Test} on this class and superclasses that
+ * are not overridden.
+ */
+ protected List<FrameworkMethod> computeTestMethods() {
+ return getTestClass().getAnnotatedMethods(Test.class);
+ }
+
+ @Override
+ protected void collectInitializationErrors(List<Throwable> errors) {
+ super.collectInitializationErrors(errors);
+
+ validatePublicConstructor(errors);
+ validateNoNonStaticInnerClass(errors);
+ validateConstructor(errors);
+ validateInstanceMethods(errors);
+ validateFields(errors);
+ validateMethods(errors);
+ }
+
+ private void validatePublicConstructor(List<Throwable> errors) {
+ if (getTestClass().getJavaClass() != null) {
+ errors.addAll(PUBLIC_CLASS_VALIDATOR.validateTestClass(getTestClass()));
+ }
+ }
+
+ protected void validateNoNonStaticInnerClass(List<Throwable> errors) {
+ if (getTestClass().isANonStaticInnerClass()) {
+ String gripe = "The inner class " + getTestClass().getName()
+ + " is not static.";
+ errors.add(new Exception(gripe));
+ }
+ }
+
+ /**
+ * Adds to {@code errors} if the test class has more than one constructor,
+ * or if the constructor takes parameters. Override if a subclass requires
+ * different validation rules.
+ */
+ protected void validateConstructor(List<Throwable> errors) {
+ validateOnlyOneConstructor(errors);
+ validateZeroArgConstructor(errors);
+ }
+
+ /**
+ * Adds to {@code errors} if the test class has more than one constructor
+ * (do not override)
+ */
+ protected void validateOnlyOneConstructor(List<Throwable> errors) {
+ if (!hasOneConstructor()) {
+ String gripe = "Test class should have exactly one public constructor";
+ errors.add(new Exception(gripe));
+ }
+ }
+
+ /**
+ * Adds to {@code errors} if the test class's single constructor takes
+ * parameters (do not override)
+ */
+ protected void validateZeroArgConstructor(List<Throwable> errors) {
+ if (!getTestClass().isANonStaticInnerClass()
+ && hasOneConstructor()
+ && (getTestClass().getOnlyConstructor().getParameterTypes().length != 0)) {
+ String gripe = "Test class should have exactly one public zero-argument constructor";
+ errors.add(new Exception(gripe));
+ }
+ }
+
+ private boolean hasOneConstructor() {
+ return getTestClass().getJavaClass().getConstructors().length == 1;
+ }
+
+ /**
+ * Adds to {@code errors} for each method annotated with {@code @Test},
+ * {@code @Before}, or {@code @After} that is not a public, void instance
+ * method with no arguments.
+ * @deprecated
+ */
+ @Deprecated
+ protected void validateInstanceMethods(List<Throwable> errors) {
+ validatePublicVoidNoArgMethods(After.class, false, errors);
+ validatePublicVoidNoArgMethods(Before.class, false, errors);
+ validateTestMethods(errors);
+
+ if (computeTestMethods().isEmpty()) {
+ errors.add(new Exception("No runnable methods"));
+ }
+ }
+
+ protected void validateFields(List<Throwable> errors) {
+ RULE_VALIDATOR.validate(getTestClass(), errors);
+ }
+
+ private void validateMethods(List<Throwable> errors) {
+ RULE_METHOD_VALIDATOR.validate(getTestClass(), errors);
+ }
+
+ /**
+ * Adds to {@code errors} for each method annotated with {@code @Test}that
+ * is not a public, void instance method with no arguments.
+ */
+ protected void validateTestMethods(List<Throwable> errors) {
+ validatePublicVoidNoArgMethods(Test.class, false, errors);
+ }
+
+ /**
+ * Returns a new fixture for running a test. Default implementation executes
+ * the test class's no-argument constructor (validation should have ensured
+ * one exists).
+ */
+ protected Object createTest() throws Exception {
+ return getTestClass().getOnlyConstructor().newInstance();
+ }
+
+ /**
+ * Returns a new fixture to run a particular test {@code method} against.
+ * Default implementation executes the no-argument {@link #createTest()} method.
+ *
+ * @since 4.13
+ */
+ protected Object createTest(FrameworkMethod method) throws Exception {
+ return createTest();
+ }
+
+ /**
+ * Returns the name that describes {@code method} for {@link Description}s.
+ * Default implementation is the method's name
+ */
+ protected String testName(FrameworkMethod method) {
+ return method.getName();
+ }
+
+ /**
+ * Returns a Statement that, when executed, either returns normally if
+ * {@code method} passes, or throws an exception if {@code method} fails.
+ *
+ * Here is an outline of the default implementation:
+ *
+ * <ul>
+ * <li>Invoke {@code method} on the result of {@link #createTest(org.junit.runners.model.FrameworkMethod)}, and
+ * throw any exceptions thrown by either operation.
+ * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@link Test#expected()}
+ * attribute, return normally only if the previous step threw an
+ * exception of the correct type, and throw an exception otherwise.
+ * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code
+ * timeout} attribute, throw an exception if the previous step takes more
+ * than the specified number of milliseconds.
+ * <li>ALWAYS run all non-overridden {@code @Before} methods on this class
+ * and superclasses before any of the previous steps; if any throws an
+ * Exception, stop execution and pass the exception on.
+ * <li>ALWAYS run all non-overridden {@code @After} methods on this class
+ * and superclasses after any of the previous steps; all After methods are
+ * always executed: exceptions thrown by previous steps are combined, if
+ * necessary, with exceptions from After methods into a
+ * {@link MultipleFailureException}.
+ * <li>ALWAYS allow {@code @Rule} fields to modify the execution of the
+ * above steps. A {@code Rule} may prevent all execution of the above steps,
+ * or add additional behavior before and after, or modify thrown exceptions.
+ * For more information, see {@link TestRule}
+ * </ul>
+ *
+ * This can be overridden in subclasses, either by overriding this method,
+ * or the implementations creating each sub-statement.
+ */
+ protected Statement methodBlock(final FrameworkMethod method) {
+ Object test;
+ try {
+ test = new ReflectiveCallable() {
+ @Override
+ protected Object runReflectiveCall() throws Throwable {
+ return createTest(method);
+ }
+ }.run();
+ } catch (Throwable e) {
+ return new Fail(e);
+ }
+
+ Statement statement = methodInvoker(method, test);
+ statement = possiblyExpectingExceptions(method, test, statement);
+ statement = withPotentialTimeout(method, test, statement);
+ statement = withBefores(method, test, statement);
+ statement = withAfters(method, test, statement);
+ statement = withRules(method, test, statement);
+ statement = withInterruptIsolation(statement);
+ return statement;
+ }
+
+ //
+ // Statement builders
+ //
+
+ /**
+ * Returns a {@link Statement} that invokes {@code method} on {@code test}
+ */
+ protected Statement methodInvoker(FrameworkMethod method, Object test) {
+ return new InvokeMethod(method, test);
+ }
+
+ /**
+ * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation
+ * has the {@link Test#expected()} attribute, return normally only if {@code next}
+ * throws an exception of the correct type, and throw an exception
+ * otherwise.
+ */
+ protected Statement possiblyExpectingExceptions(FrameworkMethod method,
+ Object test, Statement next) {
+ Test annotation = method.getAnnotation(Test.class);
+ Class<? extends Throwable> expectedExceptionClass = getExpectedException(annotation);
+ return expectedExceptionClass != null ? new ExpectException(next, expectedExceptionClass) : next;
+ }
+
+ /**
+ * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation
+ * has the {@code timeout} attribute, throw an exception if {@code next}
+ * takes more than the specified number of milliseconds.
+ * @deprecated
+ */
+ @Deprecated
+ protected Statement withPotentialTimeout(FrameworkMethod method,
+ Object test, Statement next) {
+ long timeout = getTimeout(method.getAnnotation(Test.class));
+ if (timeout <= 0) {
+ return next;
+ }
+ return FailOnTimeout.builder()
+ .withTimeout(timeout, TimeUnit.MILLISECONDS)
+ .build(next);
+ }
+
+ /**
+ * Returns a {@link Statement}: run all non-overridden {@code @Before}
+ * methods on this class and superclasses before running {@code next}; if
+ * any throws an Exception, stop execution and pass the exception on.
+ */
+ protected Statement withBefores(FrameworkMethod method, Object target,
+ Statement statement) {
+ List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods(
+ Before.class);
+ return befores.isEmpty() ? statement : new RunBefores(statement,
+ befores, target);
+ }
+
+ /**
+ * Returns a {@link Statement}: run all non-overridden {@code @After}
+ * methods on this class and superclasses before running {@code next}; all
+ * After methods are always executed: exceptions thrown by previous steps
+ * are combined, if necessary, with exceptions from After methods into a
+ * {@link MultipleFailureException}.
+ */
+ protected Statement withAfters(FrameworkMethod method, Object target,
+ Statement statement) {
+ List<FrameworkMethod> afters = getTestClass().getAnnotatedMethods(
+ After.class);
+ return afters.isEmpty() ? statement : new RunAfters(statement, afters,
+ target);
+ }
+
+ private Statement withRules(FrameworkMethod method, Object target, Statement statement) {
+ RuleContainer ruleContainer = new RuleContainer();
+ CURRENT_RULE_CONTAINER.set(ruleContainer);
+ try {
+ List<TestRule> testRules = getTestRules(target);
+ for (MethodRule each : rules(target)) {
+ if (!(each instanceof TestRule && testRules.contains(each))) {
+ ruleContainer.add(each);
+ }
+ }
+ for (TestRule rule : testRules) {
+ ruleContainer.add(rule);
+ }
+ } finally {
+ CURRENT_RULE_CONTAINER.remove();
+ }
+ return ruleContainer.apply(method, describeChild(method), target, statement);
+ }
+
+ /**
+ * @param target the test case instance
+ * @return a list of MethodRules that should be applied when executing this
+ * test
+ */
+ protected List<MethodRule> rules(Object target) {
+ RuleCollector<MethodRule> collector = new RuleCollector<MethodRule>();
+ getTestClass().collectAnnotatedMethodValues(target, Rule.class, MethodRule.class,
+ collector);
+ getTestClass().collectAnnotatedFieldValues(target, Rule.class, MethodRule.class,
+ collector);
+ return collector.result;
+ }
+
+ /**
+ * @param target the test case instance
+ * @return a list of TestRules that should be applied when executing this
+ * test
+ */
+ protected List<TestRule> getTestRules(Object target) {
+ RuleCollector<TestRule> collector = new RuleCollector<TestRule>();
+ getTestClass().collectAnnotatedMethodValues(target, Rule.class, TestRule.class, collector);
+ getTestClass().collectAnnotatedFieldValues(target, Rule.class, TestRule.class, collector);
+ return collector.result;
+ }
+
+ private Class<? extends Throwable> getExpectedException(Test annotation) {
+ if (annotation == null || annotation.expected() == None.class) {
+ return null;
+ } else {
+ return annotation.expected();
+ }
+ }
+
+ private long getTimeout(Test annotation) {
+ if (annotation == null) {
+ return 0;
+ }
+ return annotation.timeout();
+ }
+
+ private static final ThreadLocal<RuleContainer> CURRENT_RULE_CONTAINER =
+ new ThreadLocal<RuleContainer>();
+
+ private static class RuleCollector<T> implements MemberValueConsumer<T> {
+ final List<T> result = new ArrayList<T>();
+
+ public void accept(FrameworkMember<?> member, T value) {
+ Rule rule = member.getAnnotation(Rule.class);
+ if (rule != null) {
+ RuleContainer container = CURRENT_RULE_CONTAINER.get();
+ if (container != null) {
+ container.setOrder(value, rule.order());
+ }
+ }
+ result.add(value);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/JUnit4.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/JUnit4.java
new file mode 100644
index 0000000..28eafb3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/JUnit4.java
@@ -0,0 +1,25 @@
+package org.junit.runners;
+
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.TestClass;
+
+/**
+ * Aliases the current default JUnit 4 class runner, for future-proofing. If
+ * future versions of JUnit change the default Runner class, they will also
+ * change the definition of this class. Developers wanting to explicitly tag a
+ * class as a JUnit 4 class should use {@code @RunWith(JUnit4.class)}, not,
+ * for example in JUnit 4.5, {@code @RunWith(BlockJUnit4ClassRunner.class)}.
+ * This is the only way this class should be used--any extension that
+ * depends on the implementation details of this class is likely to break
+ * in future versions.
+ *
+ * @since 4.5
+ */
+public final class JUnit4 extends BlockJUnit4ClassRunner {
+ /**
+ * Constructs a new instance of the default runner
+ */
+ public JUnit4(Class<?> klass) throws InitializationError {
+ super(new TestClass(klass));
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/MethodSorters.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/MethodSorters.java
new file mode 100644
index 0000000..5821892
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/MethodSorters.java
@@ -0,0 +1,41 @@
+package org.junit.runners;
+
+import java.lang.reflect.Method;
+import java.util.Comparator;
+
+import org.junit.internal.MethodSorter;
+
+/**
+ * Sort the methods into a specified execution order.
+ * Defines common {@link MethodSorter} implementations.
+ *
+ * @since 4.11
+ */
+public enum MethodSorters {
+ /**
+ * Sorts the test methods by the method name, in lexicographic order,
+ * with {@link Method#toString()} used as a tiebreaker
+ */
+ NAME_ASCENDING(MethodSorter.NAME_ASCENDING),
+
+ /**
+ * Leaves the test methods in the order returned by the JVM.
+ * Note that the order from the JVM may vary from run to run
+ */
+ JVM(null),
+
+ /**
+ * Sorts the test methods in a deterministic, but not predictable, order
+ */
+ DEFAULT(MethodSorter.DEFAULT);
+
+ private final Comparator<Method> comparator;
+
+ private MethodSorters(Comparator<Method> comparator) {
+ this.comparator = comparator;
+ }
+
+ public Comparator<Method> getComparator() {
+ return comparator;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/Parameterized.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/Parameterized.java
new file mode 100644
index 0000000..d11b66a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/Parameterized.java
@@ -0,0 +1,504 @@
+package org.junit.runners;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InvalidTestClassError;
+import org.junit.runners.model.TestClass;
+import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParametersFactory;
+import org.junit.runners.parameterized.ParametersRunnerFactory;
+import org.junit.runners.parameterized.TestWithParameters;
+
+/**
+ * The custom runner <code>Parameterized</code> implements parameterized tests.
+ * When running a parameterized test class, instances are created for the
+ * cross-product of the test methods and the test data elements.
+ * <p>
+ * For example, to test the <code>+</code> operator, write:
+ * <pre>
+ * @RunWith(Parameterized.class)
+ * public class AdditionTest {
+ * @Parameters(name = "{index}: {0} + {1} = {2}")
+ * public static Iterable<Object[]> data() {
+ * return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
+ * { 3, 2, 5 }, { 4, 3, 7 } });
+ * }
+ *
+ * private int firstSummand;
+ *
+ * private int secondSummand;
+ *
+ * private int sum;
+ *
+ * public AdditionTest(int firstSummand, int secondSummand, int sum) {
+ * this.firstSummand = firstSummand;
+ * this.secondSummand = secondSummand;
+ * this.sum = sum;
+ * }
+ *
+ * @Test
+ * public void test() {
+ * assertEquals(sum, firstSummand + secondSummand);
+ * }
+ * }
+ * </pre>
+ * <p>
+ * Each instance of <code>AdditionTest</code> will be constructed using the
+ * three-argument constructor and the data values in the
+ * <code>@Parameters</code> method.
+ * <p>
+ * In order that you can easily identify the individual tests, you may provide a
+ * name for the <code>@Parameters</code> annotation. This name is allowed
+ * to contain placeholders, which are replaced at runtime. The placeholders are
+ * <dl>
+ * <dt>{index}</dt>
+ * <dd>the current parameter index</dd>
+ * <dt>{0}</dt>
+ * <dd>the first parameter value</dd>
+ * <dt>{1}</dt>
+ * <dd>the second parameter value</dd>
+ * <dt>...</dt>
+ * <dd>...</dd>
+ * </dl>
+ * <p>
+ * In the example given above, the <code>Parameterized</code> runner creates
+ * names like <code>[2: 3 + 2 = 5]</code>. If you don't use the name parameter,
+ * then the current parameter index is used as name.
+ * <p>
+ * You can also write:
+ * <pre>
+ * @RunWith(Parameterized.class)
+ * public class AdditionTest {
+ * @Parameters(name = "{index}: {0} + {1} = {2}")
+ * public static Iterable<Object[]> data() {
+ * return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
+ * { 3, 2, 5 }, { 4, 3, 7 } });
+ * }
+ *
+ * @Parameter(0)
+ * public int firstSummand;
+ *
+ * @Parameter(1)
+ * public int secondSummand;
+ *
+ * @Parameter(2)
+ * public int sum;
+ *
+ * @Test
+ * public void test() {
+ * assertEquals(sum, firstSummand + secondSummand);
+ * }
+ * }
+ * </pre>
+ * <p>
+ * Each instance of <code>AdditionTest</code> will be constructed with the default constructor
+ * and fields annotated by <code>@Parameter</code> will be initialized
+ * with the data values in the <code>@Parameters</code> method.
+ *
+ * <p>
+ * The parameters can be provided as an array, too:
+ *
+ * <pre>
+ * @Parameters
+ * public static Object[][] data() {
+ * return new Object[][] { { 0, 0, 0 }, { 1, 1, 2 }, { 3, 2, 5 }, { 4, 3, 7 } } };
+ * }
+ * </pre>
+ *
+ * <h3>Tests with single parameter</h3>
+ * <p>
+ * If your test needs a single parameter only, you don't have to wrap it with an
+ * array. Instead you can provide an <code>Iterable</code> or an array of
+ * objects.
+ * <pre>
+ * @Parameters
+ * public static Iterable<? extends Object> data() {
+ * return Arrays.asList("first test", "second test");
+ * }
+ * </pre>
+ * <p>
+ * or
+ * <pre>
+ * @Parameters
+ * public static Object[] data() {
+ * return new Object[] { "first test", "second test" };
+ * }
+ * </pre>
+ *
+ * <h3>Executing code before/after executing tests for specific parameters</h3>
+ * <p>
+ * If your test needs to perform some preparation or cleanup based on the
+ * parameters, this can be done by adding public static methods annotated with
+ * {@code @BeforeParam}/{@code @AfterParam}. Such methods should either have no
+ * parameters or the same parameters as the test.
+ * <pre>
+ * @BeforeParam
+ * public static void beforeTestsForParameter(String onlyParameter) {
+ * System.out.println("Testing " + onlyParameter);
+ * }
+ * </pre>
+ *
+ * <h3>Create different runners</h3>
+ * <p>
+ * By default the {@code Parameterized} runner creates a slightly modified
+ * {@link BlockJUnit4ClassRunner} for each set of parameters. You can build an
+ * own {@code Parameterized} runner that creates another runner for each set of
+ * parameters. Therefore you have to build a {@link ParametersRunnerFactory}
+ * that creates a runner for each {@link TestWithParameters}. (
+ * {@code TestWithParameters} are bundling the parameters and the test name.)
+ * The factory must have a public zero-arg constructor.
+ *
+ * <pre>
+ * public class YourRunnerFactory implements ParametersRunnerFactory {
+ * public Runner createRunnerForTestWithParameters(TestWithParameters test)
+ * throws InitializationError {
+ * return YourRunner(test);
+ * }
+ * }
+ * </pre>
+ * <p>
+ * Use the {@link UseParametersRunnerFactory} to tell the {@code Parameterized}
+ * runner that it should use your factory.
+ *
+ * <pre>
+ * @RunWith(Parameterized.class)
+ * @UseParametersRunnerFactory(YourRunnerFactory.class)
+ * public class YourTest {
+ * ...
+ * }
+ * </pre>
+ *
+ * <h3>Avoid creating parameters</h3>
+ * <p>With {@link org.junit.Assume assumptions} you can dynamically skip tests.
+ * Assumptions are also supported by the <code>@Parameters</code> method.
+ * Creating parameters is stopped when the assumption fails and none of the
+ * tests in the test class is executed. JUnit reports a
+ * {@link Result#getAssumptionFailureCount() single assumption failure} for the
+ * whole test class in this case.
+ * <pre>
+ * @Parameters
+ * public static Iterable<? extends Object> data() {
+ * String os = System.getProperty("os.name").toLowerCase()
+ * Assume.assumeTrue(os.contains("win"));
+ * return Arrays.asList("first test", "second test");
+ * }
+ * </pre>
+ * @since 4.0
+ */
+public class Parameterized extends Suite {
+ /**
+ * Annotation for a method which provides parameters to be injected into the
+ * test class constructor by <code>Parameterized</code>. The method has to
+ * be public and static.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface Parameters {
+ /**
+ * Optional pattern to derive the test's name from the parameters. Use
+ * numbers in braces to refer to the parameters or the additional data
+ * as follows:
+ * <pre>
+ * {index} - the current parameter index
+ * {0} - the first parameter value
+ * {1} - the second parameter value
+ * etc...
+ * </pre>
+ * <p>
+ * Default value is "{index}" for compatibility with previous JUnit
+ * versions.
+ *
+ * @return {@link MessageFormat} pattern string, except the index
+ * placeholder.
+ * @see MessageFormat
+ */
+ String name() default "{index}";
+ }
+
+ /**
+ * Annotation for fields of the test class which will be initialized by the
+ * method annotated by <code>Parameters</code>.
+ * By using directly this annotation, the test class constructor isn't needed.
+ * Index range must start at 0.
+ * Default value is 0.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface Parameter {
+ /**
+ * Method that returns the index of the parameter in the array
+ * returned by the method annotated by <code>Parameters</code>.
+ * Index range must start at 0.
+ * Default value is 0.
+ *
+ * @return the index of the parameter.
+ */
+ int value() default 0;
+ }
+
+ /**
+ * Add this annotation to your test class if you want to generate a special
+ * runner. You have to specify a {@link ParametersRunnerFactory} class that
+ * creates such runners. The factory must have a public zero-arg
+ * constructor.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Inherited
+ @Target(ElementType.TYPE)
+ public @interface UseParametersRunnerFactory {
+ /**
+ * @return a {@link ParametersRunnerFactory} class (must have a default
+ * constructor)
+ */
+ Class<? extends ParametersRunnerFactory> value() default BlockJUnit4ClassRunnerWithParametersFactory.class;
+ }
+
+ /**
+ * Annotation for {@code public static void} methods which should be executed before
+ * evaluating tests with particular parameters.
+ *
+ * @see org.junit.BeforeClass
+ * @see org.junit.Before
+ * @since 4.13
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface BeforeParam {
+ }
+
+ /**
+ * Annotation for {@code public static void} methods which should be executed after
+ * evaluating tests with particular parameters.
+ *
+ * @see org.junit.AfterClass
+ * @see org.junit.After
+ * @since 4.13
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface AfterParam {
+ }
+
+ /**
+ * Only called reflectively. Do not use programmatically.
+ */
+ public Parameterized(Class<?> klass) throws Throwable {
+ this(klass, new RunnersFactory(klass));
+ }
+
+ private Parameterized(Class<?> klass, RunnersFactory runnersFactory) throws Exception {
+ super(klass, runnersFactory.createRunners());
+ validateBeforeParamAndAfterParamMethods(runnersFactory.parameterCount);
+ }
+
+ private void validateBeforeParamAndAfterParamMethods(Integer parameterCount)
+ throws InvalidTestClassError {
+ List<Throwable> errors = new ArrayList<Throwable>();
+ validatePublicStaticVoidMethods(Parameterized.BeforeParam.class, parameterCount, errors);
+ validatePublicStaticVoidMethods(Parameterized.AfterParam.class, parameterCount, errors);
+ if (!errors.isEmpty()) {
+ throw new InvalidTestClassError(getTestClass().getJavaClass(), errors);
+ }
+ }
+
+ private void validatePublicStaticVoidMethods(
+ Class<? extends Annotation> annotation, Integer parameterCount,
+ List<Throwable> errors) {
+ List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(annotation);
+ for (FrameworkMethod fm : methods) {
+ fm.validatePublicVoid(true, errors);
+ if (parameterCount != null) {
+ int methodParameterCount = fm.getMethod().getParameterTypes().length;
+ if (methodParameterCount != 0 && methodParameterCount != parameterCount) {
+ errors.add(new Exception("Method " + fm.getName()
+ + "() should have 0 or " + parameterCount + " parameter(s)"));
+ }
+ }
+ }
+ }
+
+ private static class AssumptionViolationRunner extends Runner {
+ private final Description description;
+ private final AssumptionViolatedException exception;
+
+ AssumptionViolationRunner(TestClass testClass, String methodName,
+ AssumptionViolatedException exception) {
+ this.description = Description
+ .createTestDescription(testClass.getJavaClass(),
+ methodName + "() assumption violation");
+ this.exception = exception;
+ }
+
+ @Override
+ public Description getDescription() {
+ return description;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ notifier.fireTestAssumptionFailed(new Failure(description, exception));
+ }
+ }
+
+ private static class RunnersFactory {
+ private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory();
+
+ private final TestClass testClass;
+ private final FrameworkMethod parametersMethod;
+ private final List<Object> allParameters;
+ private final int parameterCount;
+ private final Runner runnerOverride;
+
+ private RunnersFactory(Class<?> klass) throws Throwable {
+ testClass = new TestClass(klass);
+ parametersMethod = getParametersMethod(testClass);
+ List<Object> allParametersResult;
+ AssumptionViolationRunner assumptionViolationRunner = null;
+ try {
+ allParametersResult = allParameters(testClass, parametersMethod);
+ } catch (AssumptionViolatedException e) {
+ allParametersResult = Collections.emptyList();
+ assumptionViolationRunner = new AssumptionViolationRunner(testClass,
+ parametersMethod.getName(), e);
+ }
+ allParameters = allParametersResult;
+ runnerOverride = assumptionViolationRunner;
+ parameterCount =
+ allParameters.isEmpty() ? 0 : normalizeParameters(allParameters.get(0)).length;
+ }
+
+ private List<Runner> createRunners() throws Exception {
+ if (runnerOverride != null) {
+ return Collections.singletonList(runnerOverride);
+ }
+ Parameters parameters = parametersMethod.getAnnotation(Parameters.class);
+ return Collections.unmodifiableList(createRunnersForParameters(
+ allParameters, parameters.name(),
+ getParametersRunnerFactory()));
+ }
+
+ private ParametersRunnerFactory getParametersRunnerFactory()
+ throws InstantiationException, IllegalAccessException {
+ UseParametersRunnerFactory annotation = testClass
+ .getAnnotation(UseParametersRunnerFactory.class);
+ if (annotation == null) {
+ return DEFAULT_FACTORY;
+ } else {
+ Class<? extends ParametersRunnerFactory> factoryClass = annotation
+ .value();
+ return factoryClass.newInstance();
+ }
+ }
+
+ private TestWithParameters createTestWithNotNormalizedParameters(
+ String pattern, int index, Object parametersOrSingleParameter) {
+ Object[] parameters = normalizeParameters(parametersOrSingleParameter);
+ return createTestWithParameters(testClass, pattern, index, parameters);
+ }
+
+ private static Object[] normalizeParameters(Object parametersOrSingleParameter) {
+ return (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter
+ : new Object[] { parametersOrSingleParameter };
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<Object> allParameters(
+ TestClass testClass, FrameworkMethod parametersMethod) throws Throwable {
+ Object parameters = parametersMethod.invokeExplosively(null);
+ if (parameters instanceof List) {
+ return (List<Object>) parameters;
+ } else if (parameters instanceof Collection) {
+ return new ArrayList<Object>((Collection<Object>) parameters);
+ } else if (parameters instanceof Iterable) {
+ List<Object> result = new ArrayList<Object>();
+ for (Object entry : ((Iterable<Object>) parameters)) {
+ result.add(entry);
+ }
+ return result;
+ } else if (parameters instanceof Object[]) {
+ return Arrays.asList((Object[]) parameters);
+ } else {
+ throw parametersMethodReturnedWrongType(testClass, parametersMethod);
+ }
+ }
+
+ private static FrameworkMethod getParametersMethod(TestClass testClass) throws Exception {
+ List<FrameworkMethod> methods = testClass
+ .getAnnotatedMethods(Parameters.class);
+ for (FrameworkMethod each : methods) {
+ if (each.isStatic() && each.isPublic()) {
+ return each;
+ }
+ }
+
+ throw new Exception("No public static parameters method on class "
+ + testClass.getName());
+ }
+
+ private List<Runner> createRunnersForParameters(
+ Iterable<Object> allParameters, String namePattern,
+ ParametersRunnerFactory runnerFactory) throws Exception {
+ try {
+ List<TestWithParameters> tests = createTestsForParameters(
+ allParameters, namePattern);
+ List<Runner> runners = new ArrayList<Runner>();
+ for (TestWithParameters test : tests) {
+ runners.add(runnerFactory
+ .createRunnerForTestWithParameters(test));
+ }
+ return runners;
+ } catch (ClassCastException e) {
+ throw parametersMethodReturnedWrongType(testClass, parametersMethod);
+ }
+ }
+
+ private List<TestWithParameters> createTestsForParameters(
+ Iterable<Object> allParameters, String namePattern)
+ throws Exception {
+ int i = 0;
+ List<TestWithParameters> children = new ArrayList<TestWithParameters>();
+ for (Object parametersOfSingleTest : allParameters) {
+ children.add(createTestWithNotNormalizedParameters(namePattern,
+ i++, parametersOfSingleTest));
+ }
+ return children;
+ }
+
+ private static Exception parametersMethodReturnedWrongType(
+ TestClass testClass, FrameworkMethod parametersMethod) throws Exception {
+ String className = testClass.getName();
+ String methodName = parametersMethod.getName();
+ String message = MessageFormat.format(
+ "{0}.{1}() must return an Iterable of arrays.", className,
+ methodName);
+ return new Exception(message);
+ }
+
+ private TestWithParameters createTestWithParameters(
+ TestClass testClass, String pattern, int index,
+ Object[] parameters) {
+ String finalPattern = pattern.replaceAll("\\{index\\}",
+ Integer.toString(index));
+ String name = MessageFormat.format(finalPattern, parameters);
+ return new TestWithParameters("[" + name + "]", testClass,
+ Arrays.asList(parameters));
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java
new file mode 100644
index 0000000..8b508fd
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java
@@ -0,0 +1,589 @@
+package org.junit.runners;
+
+import static org.junit.internal.Checks.notNull;
+import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_METHOD_VALIDATOR;
+import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_VALIDATOR;
+
+import com.google.j2objc.annotations.AutoreleasePool;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.internal.runners.model.EachTestNotifier;
+import org.junit.internal.runners.statements.RunAfters;
+import org.junit.internal.runners.statements.RunBefores;
+import org.junit.rules.RunRules;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runner.notification.StoppedByUserException;
+import org.junit.runners.model.FrameworkMember;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.InvalidTestClassError;
+import org.junit.runners.model.MemberValueConsumer;
+import org.junit.runners.model.RunnerScheduler;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+import org.junit.validator.AnnotationsValidator;
+import org.junit.validator.TestClassValidator;
+
+/**
+ * Provides most of the functionality specific to a Runner that implements a
+ * "parent node" in the test tree, with children defined by objects of some data
+ * type {@code T}. (For {@link BlockJUnit4ClassRunner}, {@code T} is
+ * {@link Method} . For {@link Suite}, {@code T} is {@link Class}.) Subclasses
+ * must implement finding the children of the node, describing each child, and
+ * running each child. ParentRunner will filter and sort children, handle
+ * {@code @BeforeClass} and {@code @AfterClass} methods,
+ * handle annotated {@link ClassRule}s, create a composite
+ * {@link Description}, and run children sequentially.
+ *
+ * @since 4.5
+ */
+public abstract class ParentRunner<T> extends Runner implements Filterable,
+ Orderable {
+ private static final List<TestClassValidator> VALIDATORS = Collections.<TestClassValidator>singletonList(
+ new AnnotationsValidator());
+
+ private final Lock childrenLock = new ReentrantLock();
+ private final TestClass testClass;
+
+ // Guarded by childrenLock
+ private volatile List<T> filteredChildren = null;
+
+ private volatile RunnerScheduler scheduler = new RunnerScheduler() {
+ public void schedule(Runnable childStatement) {
+ childStatement.run();
+ }
+
+ public void finished() {
+ // do nothing
+ }
+ };
+
+ /**
+ * Constructs a new {@code ParentRunner} that will run {@code @TestClass}
+ */
+ protected ParentRunner(Class<?> testClass) throws InitializationError {
+ this.testClass = createTestClass(testClass);
+ validate();
+ }
+
+ /**
+ * Constructs a new {@code ParentRunner} that will run the {@code TestClass}.
+ *
+ * @since 4.13
+ */
+ protected ParentRunner(TestClass testClass) throws InitializationError {
+ this.testClass = notNull(testClass);
+ validate();
+ }
+
+ /**
+ * @deprecated Please use {@link #ParentRunner(org.junit.runners.model.TestClass)}.
+ * @since 4.12
+ */
+ @Deprecated
+ protected TestClass createTestClass(Class<?> testClass) {
+ return new TestClass(testClass);
+ }
+
+ //
+ // Must be overridden
+ //
+
+ /**
+ * Returns a list of objects that define the children of this Runner.
+ */
+ protected abstract List<T> getChildren();
+
+ /**
+ * Returns a {@link Description} for {@code child}, which can be assumed to
+ * be an element of the list returned by {@link ParentRunner#getChildren()}
+ */
+ protected abstract Description describeChild(T child);
+
+ /**
+ * Runs the test corresponding to {@code child}, which can be assumed to be
+ * an element of the list returned by {@link ParentRunner#getChildren()}.
+ * Subclasses are responsible for making sure that relevant test events are
+ * reported through {@code notifier}
+ */
+ protected abstract void runChild(T child, RunNotifier notifier);
+
+ //
+ // May be overridden
+ //
+
+ /**
+ * Adds to {@code errors} a throwable for each problem noted with the test class (available from {@link #getTestClass()}).
+ * Default implementation adds an error for each method annotated with
+ * {@code @BeforeClass} or {@code @AfterClass} that is not
+ * {@code public static void} with no arguments.
+ */
+ protected void collectInitializationErrors(List<Throwable> errors) {
+ validatePublicVoidNoArgMethods(BeforeClass.class, true, errors);
+ validatePublicVoidNoArgMethods(AfterClass.class, true, errors);
+ validateClassRules(errors);
+ applyValidators(errors);
+ }
+
+ private void applyValidators(List<Throwable> errors) {
+ if (getTestClass().getJavaClass() != null) {
+ for (TestClassValidator each : VALIDATORS) {
+ errors.addAll(each.validateTestClass(getTestClass()));
+ }
+ }
+ }
+
+ /**
+ * Adds to {@code errors} if any method in this class is annotated with
+ * {@code annotation}, but:
+ * <ul>
+ * <li>is not public, or
+ * <li>takes parameters, or
+ * <li>returns something other than void, or
+ * <li>is static (given {@code isStatic is false}), or
+ * <li>is not static (given {@code isStatic is true}).
+ * </ul>
+ */
+ protected void validatePublicVoidNoArgMethods(Class<? extends Annotation> annotation,
+ boolean isStatic, List<Throwable> errors) {
+ List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(annotation);
+
+ for (FrameworkMethod eachTestMethod : methods) {
+ eachTestMethod.validatePublicVoidNoArg(isStatic, errors);
+ }
+ }
+
+ private void validateClassRules(List<Throwable> errors) {
+ CLASS_RULE_VALIDATOR.validate(getTestClass(), errors);
+ CLASS_RULE_METHOD_VALIDATOR.validate(getTestClass(), errors);
+ }
+
+ /**
+ * Constructs a {@code Statement} to run all of the tests in the test class.
+ * Override to add pre-/post-processing. Here is an outline of the
+ * implementation:
+ * <ol>
+ * <li>Determine the children to be run using {@link #getChildren()}
+ * (subject to any imposed filter and sort).</li>
+ * <li>If there are any children remaining after filtering and ignoring,
+ * construct a statement that will:
+ * <ol>
+ * <li>Apply all {@code ClassRule}s on the test-class and superclasses.</li>
+ * <li>Run all non-overridden {@code @BeforeClass} methods on the test-class
+ * and superclasses; if any throws an Exception, stop execution and pass the
+ * exception on.</li>
+ * <li>Run all remaining tests on the test-class.</li>
+ * <li>Run all non-overridden {@code @AfterClass} methods on the test-class
+ * and superclasses: exceptions thrown by previous steps are combined, if
+ * necessary, with exceptions from AfterClass methods into a
+ * {@link org.junit.runners.model.MultipleFailureException}.</li>
+ * </ol>
+ * </li>
+ * </ol>
+ *
+ * @return {@code Statement}
+ */
+ protected Statement classBlock(final RunNotifier notifier) {
+ Statement statement = childrenInvoker(notifier);
+ if (!areAllChildrenIgnored()) {
+ statement = withBeforeClasses(statement);
+ statement = withAfterClasses(statement);
+ statement = withClassRules(statement);
+ statement = withInterruptIsolation(statement);
+ }
+ return statement;
+ }
+
+ private boolean areAllChildrenIgnored() {
+ for (T child : getFilteredChildren()) {
+ if (!isIgnored(child)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a {@link Statement}: run all non-overridden {@code @BeforeClass} methods on this class
+ * and superclasses before executing {@code statement}; if any throws an
+ * Exception, stop execution and pass the exception on.
+ */
+ protected Statement withBeforeClasses(Statement statement) {
+ List<FrameworkMethod> befores = testClass
+ .getAnnotatedMethods(BeforeClass.class);
+ return befores.isEmpty() ? statement :
+ new RunBefores(statement, befores, null);
+ }
+
+ /**
+ * Returns a {@link Statement}: run all non-overridden {@code @AfterClass} methods on this class
+ * and superclasses after executing {@code statement}; all AfterClass methods are
+ * always executed: exceptions thrown by previous steps are combined, if
+ * necessary, with exceptions from AfterClass methods into a
+ * {@link org.junit.runners.model.MultipleFailureException}.
+ */
+ protected Statement withAfterClasses(Statement statement) {
+ List<FrameworkMethod> afters = testClass
+ .getAnnotatedMethods(AfterClass.class);
+ return afters.isEmpty() ? statement :
+ new RunAfters(statement, afters, null);
+ }
+
+ /**
+ * Returns a {@link Statement}: apply all
+ * static fields assignable to {@link TestRule}
+ * annotated with {@link ClassRule}.
+ *
+ * @param statement the base statement
+ * @return a RunRules statement if any class-level {@link Rule}s are
+ * found, or the base statement
+ */
+ private Statement withClassRules(Statement statement) {
+ List<TestRule> classRules = classRules();
+ return classRules.isEmpty() ? statement :
+ new RunRules(statement, classRules, getDescription());
+ }
+
+ /**
+ * @return the {@code ClassRule}s that can transform the block that runs
+ * each method in the tested class.
+ */
+ protected List<TestRule> classRules() {
+ ClassRuleCollector collector = new ClassRuleCollector();
+ testClass.collectAnnotatedMethodValues(null, ClassRule.class, TestRule.class, collector);
+ testClass.collectAnnotatedFieldValues(null, ClassRule.class, TestRule.class, collector);
+ return collector.getOrderedRules();
+ }
+
+ /**
+ * Returns a {@link Statement}: Call {@link #runChild(Object, RunNotifier)}
+ * on each object returned by {@link #getChildren()} (subject to any imposed
+ * filter and sort)
+ */
+ protected Statement childrenInvoker(final RunNotifier notifier) {
+ return new Statement() {
+ @Override
+ public void evaluate() {
+ runChildren(notifier);
+ }
+ };
+ }
+
+ /**
+ * @return a {@link Statement}: clears interrupt status of current thread after execution of statement
+ */
+ protected final Statement withInterruptIsolation(final Statement statement) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ statement.evaluate();
+ } finally {
+ Thread.interrupted(); // clearing thread interrupted status for isolation
+ }
+ }
+ };
+ }
+
+ /**
+ * Evaluates whether a child is ignored. The default implementation always
+ * returns <code>false</code>.
+ *
+ * <p>{@link BlockJUnit4ClassRunner}, for example, overrides this method to
+ * filter tests based on the {@link Ignore} annotation.
+ */
+ protected boolean isIgnored(T child) {
+ return false;
+ }
+
+ private void runChildren(final RunNotifier notifier) {
+ final RunnerScheduler currentScheduler = scheduler;
+ try {
+ for (final T each : getFilteredChildren()) {
+ currentScheduler.schedule(new Runnable() {
+ public void run() {
+ ParentRunner.this.runChild(each, notifier);
+ }
+ });
+ }
+ } finally {
+ currentScheduler.finished();
+ }
+ }
+
+ /**
+ * Returns a name used to describe this Runner
+ */
+ protected String getName() {
+ return testClass.getName();
+ }
+
+ //
+ // Available for subclasses
+ //
+
+ /**
+ * Returns a {@link TestClass} object wrapping the class to be executed.
+ */
+ public final TestClass getTestClass() {
+ return testClass;
+ }
+
+ /**
+ * Runs a {@link Statement} that represents a leaf (aka atomic) test.
+ */
+ protected final void runLeaf(Statement statement, Description description,
+ RunNotifier notifier) {
+ EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
+ eachNotifier.fireTestStarted();
+ try {
+ statement.evaluate();
+ } catch (AssumptionViolatedException e) {
+ eachNotifier.addFailedAssumption(e);
+ } catch (Throwable e) {
+ eachNotifier.addFailure(e);
+ } finally {
+ eachNotifier.fireTestFinished();
+ }
+ }
+
+ /**
+ * @return the annotations that should be attached to this runner's
+ * description.
+ */
+ protected Annotation[] getRunnerAnnotations() {
+ return testClass.getAnnotations();
+ }
+
+ //
+ // Implementation of Runner
+ //
+
+ @Override
+ public Description getDescription() {
+ Class<?> clazz = getTestClass().getJavaClass();
+ Description description;
+ // if subclass overrides `getName()` then we should use it
+ // to maintain backwards compatibility with JUnit 4.12
+ if (clazz == null || !clazz.getName().equals(getName())) {
+ description = Description.createSuiteDescription(getName(), getRunnerAnnotations());
+ } else {
+ description = Description.createSuiteDescription(clazz, getRunnerAnnotations());
+ }
+
+ for (T child : getFilteredChildren()) {
+ description.addChild(describeChild(child));
+ }
+ return description;
+ }
+
+ // @AutoreleasePool is a local modification to support translation of this
+ // code to Objective-C using J2ObjC. It causes the translator to add an
+ // autorelease pool around this method which is Objective-C's way of
+ // collecting and cleaning up garbage memory.
+ @AutoreleasePool
+ @Override
+ public void run(final RunNotifier notifier) {
+ EachTestNotifier testNotifier = new EachTestNotifier(notifier,
+ getDescription());
+ testNotifier.fireTestSuiteStarted();
+ try {
+ Statement statement = classBlock(notifier);
+ statement.evaluate();
+ } catch (AssumptionViolatedException e) {
+ testNotifier.addFailedAssumption(e);
+ } catch (StoppedByUserException e) {
+ throw e;
+ } catch (Throwable e) {
+ testNotifier.addFailure(e);
+ } finally {
+ testNotifier.fireTestSuiteFinished();
+ }
+ }
+
+ //
+ // Implementation of Filterable and Sortable
+ //
+
+ public void filter(Filter filter) throws NoTestsRemainException {
+ childrenLock.lock();
+ try {
+ List<T> children = new ArrayList<T>(getFilteredChildren());
+ for (Iterator<T> iter = children.iterator(); iter.hasNext(); ) {
+ T each = iter.next();
+ if (shouldRun(filter, each)) {
+ try {
+ filter.apply(each);
+ } catch (NoTestsRemainException e) {
+ iter.remove();
+ }
+ } else {
+ iter.remove();
+ }
+ }
+ filteredChildren = Collections.unmodifiableList(children);
+ if (filteredChildren.isEmpty()) {
+ throw new NoTestsRemainException();
+ }
+ } finally {
+ childrenLock.unlock();
+ }
+ }
+
+ public void sort(Sorter sorter) {
+ if (shouldNotReorder()) {
+ return;
+ }
+
+ childrenLock.lock();
+ try {
+ for (T each : getFilteredChildren()) {
+ sorter.apply(each);
+ }
+ List<T> sortedChildren = new ArrayList<T>(getFilteredChildren());
+ Collections.sort(sortedChildren, comparator(sorter));
+ filteredChildren = Collections.unmodifiableList(sortedChildren);
+ } finally {
+ childrenLock.unlock();
+ }
+ }
+
+ /**
+ * Implementation of {@link Orderable#order(Orderer)}.
+ *
+ * @since 4.13
+ */
+ public void order(Orderer orderer) throws InvalidOrderingException {
+ if (shouldNotReorder()) {
+ return;
+ }
+
+ childrenLock.lock();
+ try {
+ List<T> children = getFilteredChildren();
+ // In theory, we could have duplicate Descriptions. De-dup them before ordering,
+ // and add them back at the end.
+ Map<Description, List<T>> childMap = new LinkedHashMap<Description, List<T>>(
+ children.size());
+ for (T child : children) {
+ Description description = describeChild(child);
+ List<T> childrenWithDescription = childMap.get(description);
+ if (childrenWithDescription == null) {
+ childrenWithDescription = new ArrayList<T>(1);
+ childMap.put(description, childrenWithDescription);
+ }
+ childrenWithDescription.add(child);
+ orderer.apply(child);
+ }
+
+ List<Description> inOrder = orderer.order(childMap.keySet());
+
+ children = new ArrayList<T>(children.size());
+ for (Description description : inOrder) {
+ children.addAll(childMap.get(description));
+ }
+ filteredChildren = Collections.unmodifiableList(children);
+ } finally {
+ childrenLock.unlock();
+ }
+ }
+
+ //
+ // Private implementation
+ //
+
+ private boolean shouldNotReorder() {
+ // If the test specifies a specific order, do not reorder.
+ return getDescription().getAnnotation(FixMethodOrder.class) != null;
+ }
+
+ private void validate() throws InitializationError {
+ List<Throwable> errors = new ArrayList<Throwable>();
+ collectInitializationErrors(errors);
+ if (!errors.isEmpty()) {
+ throw new InvalidTestClassError(testClass.getJavaClass(), errors);
+ }
+ }
+
+ private List<T> getFilteredChildren() {
+ if (filteredChildren == null) {
+ childrenLock.lock();
+ try {
+ if (filteredChildren == null) {
+ filteredChildren = Collections.unmodifiableList(
+ new ArrayList<T>(getChildren()));
+ }
+ } finally {
+ childrenLock.unlock();
+ }
+ }
+ return filteredChildren;
+ }
+
+ private boolean shouldRun(Filter filter, T each) {
+ return filter.shouldRun(describeChild(each));
+ }
+
+ private Comparator<? super T> comparator(final Sorter sorter) {
+ return new Comparator<T>() {
+ public int compare(T o1, T o2) {
+ return sorter.compare(describeChild(o1), describeChild(o2));
+ }
+ };
+ }
+
+ /**
+ * Sets a scheduler that determines the order and parallelization
+ * of children. Highly experimental feature that may change.
+ */
+ public void setScheduler(RunnerScheduler scheduler) {
+ this.scheduler = scheduler;
+ }
+
+ private static class ClassRuleCollector implements MemberValueConsumer<TestRule> {
+ final List<RuleContainer.RuleEntry> entries = new ArrayList<RuleContainer.RuleEntry>();
+
+ public void accept(FrameworkMember<?> member, TestRule value) {
+ ClassRule rule = member.getAnnotation(ClassRule.class);
+ entries.add(new RuleContainer.RuleEntry(value, RuleContainer.RuleEntry.TYPE_TEST_RULE,
+ rule != null ? rule.order() : null));
+ }
+
+ public List<TestRule> getOrderedRules() {
+ Collections.sort(entries, RuleContainer.ENTRY_COMPARATOR);
+ List<TestRule> result = new ArrayList<TestRule>(entries.size());
+ for (RuleContainer.RuleEntry entry : entries) {
+ result.add((TestRule) entry.rule);
+ }
+ return result;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/RuleContainer.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/RuleContainer.java
new file mode 100644
index 0000000..30ddd8d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/RuleContainer.java
@@ -0,0 +1,113 @@
+package org.junit.runners;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.IdentityHashMap;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * Data structure for ordering of {@link TestRule}/{@link MethodRule} instances.
+ *
+ * @since 4.13
+ */
+class RuleContainer {
+ private final IdentityHashMap<Object, Integer> orderValues = new IdentityHashMap<Object, Integer>();
+ private final List<TestRule> testRules = new ArrayList<TestRule>();
+ private final List<MethodRule> methodRules = new ArrayList<MethodRule>();
+
+ /**
+ * Sets order value for the specified rule.
+ */
+ public void setOrder(Object rule, int order) {
+ orderValues.put(rule, order);
+ }
+
+ public void add(MethodRule methodRule) {
+ methodRules.add(methodRule);
+ }
+
+ public void add(TestRule testRule) {
+ testRules.add(testRule);
+ }
+
+ static final Comparator<RuleEntry> ENTRY_COMPARATOR = new Comparator<RuleEntry>() {
+ public int compare(RuleEntry o1, RuleEntry o2) {
+ int result = compareInt(o1.order, o2.order);
+ return result != 0 ? result : o1.type - o2.type;
+ }
+
+ private int compareInt(int a, int b) {
+ return (a < b) ? 1 : (a == b ? 0 : -1);
+ }
+ };
+
+ /**
+ * Returns entries in the order how they should be applied, i.e. inner-to-outer.
+ */
+ private List<RuleEntry> getSortedEntries() {
+ List<RuleEntry> ruleEntries = new ArrayList<RuleEntry>(
+ methodRules.size() + testRules.size());
+ for (MethodRule rule : methodRules) {
+ ruleEntries.add(new RuleEntry(rule, RuleEntry.TYPE_METHOD_RULE, orderValues.get(rule)));
+ }
+ for (TestRule rule : testRules) {
+ ruleEntries.add(new RuleEntry(rule, RuleEntry.TYPE_TEST_RULE, orderValues.get(rule)));
+ }
+ Collections.sort(ruleEntries, ENTRY_COMPARATOR);
+ return ruleEntries;
+ }
+
+ /**
+ * Applies all the rules ordered accordingly to the specified {@code statement}.
+ */
+ public Statement apply(FrameworkMethod method, Description description, Object target,
+ Statement statement) {
+ if (methodRules.isEmpty() && testRules.isEmpty()) {
+ return statement;
+ }
+ Statement result = statement;
+ for (RuleEntry ruleEntry : getSortedEntries()) {
+ if (ruleEntry.type == RuleEntry.TYPE_TEST_RULE) {
+ result = ((TestRule) ruleEntry.rule).apply(result, description);
+ } else {
+ result = ((MethodRule) ruleEntry.rule).apply(result, method, target);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns rule instances in the order how they should be applied, i.e. inner-to-outer.
+ * VisibleForTesting
+ */
+ List<Object> getSortedRules() {
+ List<Object> result = new ArrayList<Object>();
+ for (RuleEntry entry : getSortedEntries()) {
+ result.add(entry.rule);
+ }
+ return result;
+ }
+
+ static class RuleEntry {
+ static final int TYPE_TEST_RULE = 1;
+ static final int TYPE_METHOD_RULE = 0;
+
+ final Object rule;
+ final int type;
+ final int order;
+
+ RuleEntry(Object rule, int type, Integer order) {
+ this.rule = rule;
+ this.type = type;
+ this.order = order != null ? order.intValue() : Rule.DEFAULT_ORDER;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/Suite.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/Suite.java
new file mode 100644
index 0000000..c2c8e58
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/Suite.java
@@ -0,0 +1,130 @@
+package org.junit.runners;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * Using <code>Suite</code> as a runner allows you to manually
+ * build a suite containing tests from many classes. It is the JUnit 4 equivalent of the JUnit 3.8.x
+ * static {@link junit.framework.Test} <code>suite()</code> method. To use it, annotate a class
+ * with <code>@RunWith(Suite.class)</code> and <code>@SuiteClasses({TestClass1.class, ...})</code>.
+ * When you run this class, it will run all the tests in all the suite classes.
+ *
+ * @since 4.0
+ */
+public class Suite extends ParentRunner<Runner> {
+ /**
+ * Returns an empty suite.
+ */
+ public static Runner emptySuite() {
+ try {
+ return new Suite((Class<?>) null, new Class<?>[0]);
+ } catch (InitializationError e) {
+ throw new RuntimeException("This shouldn't be possible");
+ }
+ }
+
+ /**
+ * The <code>SuiteClasses</code> annotation specifies the classes to be run when a class
+ * annotated with <code>@RunWith(Suite.class)</code> is run.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ @Inherited
+ public @interface SuiteClasses {
+ /**
+ * @return the classes to be run
+ */
+ Class<?>[] value();
+ }
+
+ private static Class<?>[] getAnnotatedClasses(Class<?> klass) throws InitializationError {
+ SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class);
+ if (annotation == null) {
+ throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName()));
+ }
+ return annotation.value();
+ }
+
+ private final List<Runner> runners;
+
+ /**
+ * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code>
+ *
+ * @param klass the root class
+ * @param builder builds runners for classes in the suite
+ */
+ public Suite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
+ this(builder, klass, getAnnotatedClasses(klass));
+ }
+
+ /**
+ * Call this when there is no single root class (for example, multiple class names
+ * passed on the command line to {@link org.junit.runner.JUnitCore}
+ *
+ * @param builder builds runners for classes in the suite
+ * @param classes the classes in the suite
+ */
+ public Suite(RunnerBuilder builder, Class<?>[] classes) throws InitializationError {
+ this(null, builder.runners(null, classes));
+ }
+
+ /**
+ * Call this when the default builder is good enough. Left in for compatibility with JUnit 4.4.
+ *
+ * @param klass the root of the suite
+ * @param suiteClasses the classes in the suite
+ */
+ protected Suite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
+ this(new AllDefaultPossibilitiesBuilder(), klass, suiteClasses);
+ }
+
+ /**
+ * Called by this class and subclasses once the classes making up the suite have been determined
+ *
+ * @param builder builds runners for classes in the suite
+ * @param klass the root of the suite
+ * @param suiteClasses the classes in the suite
+ */
+ protected Suite(RunnerBuilder builder, Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
+ this(klass, builder.runners(klass, suiteClasses));
+ }
+
+ /**
+ * Called by this class and subclasses once the runners making up the suite have been determined
+ *
+ * @param klass root of the suite
+ * @param runners for each class in the suite, a {@link Runner}
+ */
+ protected Suite(Class<?> klass, List<Runner> runners) throws InitializationError {
+ super(klass);
+ this.runners = Collections.unmodifiableList(runners);
+ }
+
+ @Override
+ protected List<Runner> getChildren() {
+ return runners;
+ }
+
+ @Override
+ protected Description describeChild(Runner child) {
+ return child.getDescription();
+ }
+
+ @Override
+ protected void runChild(Runner runner, final RunNotifier notifier) {
+ runner.run(notifier);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Annotatable.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Annotatable.java
new file mode 100644
index 0000000..8eff6fd
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Annotatable.java
@@ -0,0 +1,20 @@
+package org.junit.runners.model;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * A model element that may have annotations.
+ *
+ * @since 4.12
+ */
+public interface Annotatable {
+ /**
+ * Returns the model elements' annotations.
+ */
+ Annotation[] getAnnotations();
+
+ /**
+ * Returns the annotation on the model element of the given type, or @code{null}
+ */
+ <T extends Annotation> T getAnnotation(Class<T> annotationType);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkField.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkField.java
new file mode 100644
index 0000000..ea2b16f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkField.java
@@ -0,0 +1,99 @@
+package org.junit.runners.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+/**
+ * Represents a field on a test class (currently used only for Rules in
+ * {@link BlockJUnit4ClassRunner}, but custom runners can make other uses)
+ *
+ * @since 4.7
+ */
+public class FrameworkField extends FrameworkMember<FrameworkField> {
+ private final Field field;
+
+ /**
+ * Returns a new {@code FrameworkField} for {@code field}.
+ *
+ * <p>Access relaxed to {@code public} since version 4.13.1.
+ */
+ public FrameworkField(Field field) {
+ if (field == null) {
+ throw new NullPointerException(
+ "FrameworkField cannot be created without an underlying field.");
+ }
+ this.field = field;
+
+ if (isPublic()) {
+ // This field could be a public field in a package-scope base class
+ try {
+ field.setAccessible(true);
+ } catch (SecurityException e) {
+ // We may get an IllegalAccessException when we try to access the field
+ }
+ }
+ }
+
+ @Override
+ public String getName() {
+ return getField().getName();
+ }
+
+ public Annotation[] getAnnotations() {
+ return field.getAnnotations();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ return field.getAnnotation(annotationType);
+ }
+
+ @Override
+ public boolean isShadowedBy(FrameworkField otherMember) {
+ return otherMember.getName().equals(getName());
+ }
+
+ @Override
+ boolean isBridgeMethod() {
+ return false;
+ }
+
+ @Override
+ protected int getModifiers() {
+ return field.getModifiers();
+ }
+
+ /**
+ * @return the underlying java Field
+ */
+ public Field getField() {
+ return field;
+ }
+
+ /**
+ * @return the underlying Java Field type
+ * @see java.lang.reflect.Field#getType()
+ */
+ @Override
+ public Class<?> getType() {
+ return field.getType();
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return field.getDeclaringClass();
+ }
+
+ /**
+ * Attempts to retrieve the value of this field on {@code target}
+ */
+ public Object get(Object target) throws IllegalArgumentException, IllegalAccessException {
+ return field.get(target);
+ }
+
+ @Override
+ public String toString() {
+ return field.toString();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMember.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMember.java
new file mode 100644
index 0000000..5634b3f
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMember.java
@@ -0,0 +1,59 @@
+package org.junit.runners.model;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Parent class for {@link FrameworkField} and {@link FrameworkMethod}
+ *
+ * @since 4.7
+ */
+public abstract class FrameworkMember<T extends FrameworkMember<T>> implements
+ Annotatable {
+ abstract boolean isShadowedBy(T otherMember);
+
+ T handlePossibleBridgeMethod(List<T> members) {
+ for (int i = members.size() - 1; i >=0; i--) {
+ T otherMember = members.get(i);
+ if (isShadowedBy(otherMember)) {
+ if (otherMember.isBridgeMethod()) {
+ /*
+ * We need to return the previously-encountered bridge method
+ * because JUnit won't be able to call the parent method,
+ * because the parent class isn't public.
+ */
+ members.remove(i);
+ return otherMember;
+ }
+ // We found a shadowed member that isn't a bridge method. Ignore it.
+ return null;
+ }
+ }
+ // No shadow or bridge method found. The caller should add *this* member.
+ return (T) this;
+ }
+
+ abstract boolean isBridgeMethod();
+
+ protected abstract int getModifiers();
+
+ /**
+ * Returns true if this member is static, false if not.
+ */
+ public boolean isStatic() {
+ return Modifier.isStatic(getModifiers());
+ }
+
+ /**
+ * Returns true if this member is public, false if not.
+ */
+ public boolean isPublic() {
+ return Modifier.isPublic(getModifiers());
+ }
+
+ public abstract String getName();
+
+ public abstract Class<?> getType();
+
+ public abstract Class<?> getDeclaringClass();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMethod.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMethod.java
new file mode 100644
index 0000000..4471407
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/FrameworkMethod.java
@@ -0,0 +1,216 @@
+package org.junit.runners.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.junit.internal.runners.model.ReflectiveCallable;
+
+/**
+ * Represents a method on a test class to be invoked at the appropriate point in
+ * test execution. These methods are usually marked with an annotation (such as
+ * {@code @Test}, {@code @Before}, {@code @After}, {@code @BeforeClass},
+ * {@code @AfterClass}, etc.)
+ *
+ * @since 4.5
+ */
+public class FrameworkMethod extends FrameworkMember<FrameworkMethod> {
+ private final Method method;
+
+ /**
+ * Returns a new {@code FrameworkMethod} for {@code method}
+ */
+ public FrameworkMethod(Method method) {
+ if (method == null) {
+ throw new NullPointerException(
+ "FrameworkMethod cannot be created without an underlying method.");
+ }
+ this.method = method;
+
+ if (isPublic()) {
+ // This method could be a public method in a package-scope base class
+ try {
+ method.setAccessible(true);
+ } catch (SecurityException e) {
+ // We may get an IllegalAccessException when we try to call the method
+ }
+ }
+ }
+
+ /**
+ * Returns the underlying Java method
+ */
+ public Method getMethod() {
+ return method;
+ }
+
+ /**
+ * Returns the result of invoking this method on {@code target} with
+ * parameters {@code params}. {@link InvocationTargetException}s thrown are
+ * unwrapped, and their causes rethrown.
+ */
+ public Object invokeExplosively(final Object target, final Object... params)
+ throws Throwable {
+ return new ReflectiveCallable() {
+ @Override
+ protected Object runReflectiveCall() throws Throwable {
+ return method.invoke(target, params);
+ }
+ }.run();
+ }
+
+ /**
+ * Returns the method's name
+ */
+ @Override
+ public String getName() {
+ return method.getName();
+ }
+
+ /**
+ * Adds to {@code errors} if this method:
+ * <ul>
+ * <li>is not public, or
+ * <li>takes parameters, or
+ * <li>returns something other than void, or
+ * <li>is static (given {@code isStatic is false}), or
+ * <li>is not static (given {@code isStatic is true}).
+ * </ul>
+ */
+ public void validatePublicVoidNoArg(boolean isStatic, List<Throwable> errors) {
+ validatePublicVoid(isStatic, errors);
+ if (method.getParameterTypes().length != 0) {
+ errors.add(new Exception("Method " + method.getName() + " should have no parameters"));
+ }
+ }
+
+
+ /**
+ * Adds to {@code errors} if this method:
+ * <ul>
+ * <li>is not public, or
+ * <li>returns something other than void, or
+ * <li>is static (given {@code isStatic is false}), or
+ * <li>is not static (given {@code isStatic is true}).
+ * </ul>
+ */
+ public void validatePublicVoid(boolean isStatic, List<Throwable> errors) {
+ if (isStatic() != isStatic) {
+ String state = isStatic ? "should" : "should not";
+ errors.add(new Exception("Method " + method.getName() + "() " + state + " be static"));
+ }
+ if (!isPublic()) {
+ errors.add(new Exception("Method " + method.getName() + "() should be public"));
+ }
+ if (method.getReturnType() != Void.TYPE) {
+ errors.add(new Exception("Method " + method.getName() + "() should be void"));
+ }
+ }
+
+ @Override
+ protected int getModifiers() {
+ return method.getModifiers();
+ }
+
+ /**
+ * Returns the return type of the method
+ */
+ public Class<?> getReturnType() {
+ return method.getReturnType();
+ }
+
+ /**
+ * Returns the return type of the method
+ */
+ @Override
+ public Class<?> getType() {
+ return getReturnType();
+ }
+
+ /**
+ * Returns the class where the method is actually declared
+ */
+ @Override
+ public Class<?> getDeclaringClass() {
+ return method.getDeclaringClass();
+ }
+
+ public void validateNoTypeParametersOnArgs(List<Throwable> errors) {
+ new NoGenericTypeParametersValidator(method).validate(errors);
+ }
+
+ @Override
+ public boolean isShadowedBy(FrameworkMethod other) {
+ if (!other.getName().equals(getName())) {
+ return false;
+ }
+ if (other.getParameterTypes().length != getParameterTypes().length) {
+ return false;
+ }
+ for (int i = 0; i < other.getParameterTypes().length; i++) {
+ if (!other.getParameterTypes()[i].equals(getParameterTypes()[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ boolean isBridgeMethod() {
+ return method.isBridge();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!FrameworkMethod.class.isInstance(obj)) {
+ return false;
+ }
+ return ((FrameworkMethod) obj).method.equals(method);
+ }
+
+ @Override
+ public int hashCode() {
+ return method.hashCode();
+ }
+
+ /**
+ * Returns true if this is a no-arg method that returns a value assignable
+ * to {@code type}
+ *
+ * @deprecated This is used only by the Theories runner, and does not
+ * use all the generic type info that it ought to. It will be replaced
+ * with a forthcoming ParameterSignature#canAcceptResultOf(FrameworkMethod)
+ * once Theories moves to junit-contrib.
+ */
+ @Deprecated
+ public boolean producesType(Type type) {
+ return getParameterTypes().length == 0 && type instanceof Class<?>
+ && ((Class<?>) type).isAssignableFrom(method.getReturnType());
+ }
+
+ private Class<?>[] getParameterTypes() {
+ return method.getParameterTypes();
+ }
+
+ /**
+ * Returns the annotations on this method
+ */
+ public Annotation[] getAnnotations() {
+ return method.getAnnotations();
+ }
+
+ /**
+ * Returns the annotation of type {@code annotationType} on this method, if
+ * one exists.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ return method.getAnnotation(annotationType);
+ }
+
+ @Override
+ public String toString() {
+ return method.toString();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InitializationError.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InitializationError.java
new file mode 100644
index 0000000..dd9c8b3
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InitializationError.java
@@ -0,0 +1,47 @@
+package org.junit.runners.model;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represents one or more problems encountered while initializing a Runner
+ *
+ * @since 4.5
+ */
+public class InitializationError extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final List<Throwable> fErrors;
+
+ /**
+ * Construct a new {@code InitializationError} with one or more
+ * errors {@code errors} as causes
+ */
+ public InitializationError(List<Throwable> errors) {
+ this.fErrors = errors;
+ }
+
+ public InitializationError(Throwable error) {
+ this(Arrays.asList(error));
+ }
+
+ /**
+ * Construct a new {@code InitializationError} with one cause
+ * with message {@code string}
+ */
+ public InitializationError(String string) {
+ this(new Exception(string));
+ }
+
+ /**
+ * Returns one or more Throwables that led to this initialization error.
+ */
+ public List<Throwable> getCauses() {
+ return fErrors;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InvalidTestClassError.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InvalidTestClassError.java
new file mode 100644
index 0000000..57be610
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/InvalidTestClassError.java
@@ -0,0 +1,39 @@
+package org.junit.runners.model;
+
+import java.util.List;
+
+/**
+ * Thrown by {@link org.junit.runner.Runner}s in case the class under test is not valid.
+ * <p>
+ * Its message conveniently lists all of the validation errors.
+ *
+ * @since 4.13
+ */
+public class InvalidTestClassError extends InitializationError {
+ private static final long serialVersionUID = 1L;
+
+ private final String message;
+
+ public InvalidTestClassError(Class<?> offendingTestClass, List<Throwable> validationErrors) {
+ super(validationErrors);
+ this.message = createMessage(offendingTestClass, validationErrors);
+ }
+
+ private static String createMessage(Class<?> testClass, List<Throwable> validationErrors) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(String.format("Invalid test class '%s':", testClass.getName()));
+ int i = 1;
+ for (Throwable error : validationErrors) {
+ sb.append("\n " + (i++) + ". " + error.getMessage());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * @return a message with a list of all of the validation errors
+ */
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MemberValueConsumer.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MemberValueConsumer.java
new file mode 100644
index 0000000..a6157bf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MemberValueConsumer.java
@@ -0,0 +1,18 @@
+package org.junit.runners.model;
+
+/**
+ * Represents a receiver for values of annotated fields/methods together with the declaring member.
+ *
+ * @see TestClass#collectAnnotatedFieldValues(Object, Class, Class, MemberValueConsumer)
+ * @see TestClass#collectAnnotatedMethodValues(Object, Class, Class, MemberValueConsumer)
+ * @since 4.13
+ */
+public interface MemberValueConsumer<T> {
+ /**
+ * Receives the next value and its declaring member.
+ *
+ * @param member declaring member ({@link FrameworkMethod} or {@link FrameworkField})
+ * @param value the value of the next member
+ */
+ void accept(FrameworkMember<?> member, T value);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MultipleFailureException.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MultipleFailureException.java
new file mode 100644
index 0000000..8e355a7
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/MultipleFailureException.java
@@ -0,0 +1,104 @@
+package org.junit.runners.model;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.TestCouldNotBeSkippedException;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.internal.Throwables;
+
+/**
+ * Collects multiple {@code Throwable}s into one exception.
+ *
+ * @since 4.9
+ */
+public class MultipleFailureException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * We have to use the f prefix until the next major release to ensure
+ * serialization compatibility.
+ * See https://github.com/junit-team/junit4/issues/976
+ */
+ private final List<Throwable> fErrors;
+
+ public MultipleFailureException(List<Throwable> errors) {
+ if (errors.isEmpty()) {
+ throw new IllegalArgumentException(
+ "List of Throwables must not be empty");
+ }
+ this.fErrors = new ArrayList<Throwable>(errors.size());
+ for (Throwable error : errors) {
+ if (error instanceof AssumptionViolatedException) {
+ error = new TestCouldNotBeSkippedException((AssumptionViolatedException) error);
+ }
+ fErrors.add(error);
+ }
+ }
+
+ public List<Throwable> getFailures() {
+ return Collections.unmodifiableList(fErrors);
+ }
+
+ @Override
+ public String getMessage() {
+ StringBuilder sb = new StringBuilder(
+ String.format("There were %d errors:", fErrors.size()));
+ for (Throwable e : fErrors) {
+ sb.append(String.format("%n %s(%s)", e.getClass().getName(), e.getMessage()));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public void printStackTrace() {
+ for (Throwable e: fErrors) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void printStackTrace(PrintStream s) {
+ for (Throwable e: fErrors) {
+ e.printStackTrace(s);
+ }
+ }
+
+ @Override
+ public void printStackTrace(PrintWriter s) {
+ for (Throwable e: fErrors) {
+ e.printStackTrace(s);
+ }
+ }
+
+ /**
+ * Asserts that a list of throwables is empty. If it isn't empty,
+ * will throw {@link MultipleFailureException} (if there are
+ * multiple throwables in the list) or the first element in the list
+ * (if there is only one element).
+ *
+ * @param errors list to check
+ * @throws Exception or Error if the list is not empty
+ */
+ @SuppressWarnings("deprecation")
+ public static void assertEmpty(List<Throwable> errors) throws Exception {
+ if (errors.isEmpty()) {
+ return;
+ }
+ if (errors.size() == 1) {
+ throw Throwables.rethrowAsException(errors.get(0));
+ }
+
+ /*
+ * Many places in the code are documented to throw
+ * org.junit.internal.runners.model.MultipleFailureException.
+ * That class now extends this one, so we throw the internal
+ * exception in case developers have tests that catch
+ * MultipleFailureException.
+ */
+ throw new org.junit.internal.runners.model.MultipleFailureException(errors);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/NoGenericTypeParametersValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/NoGenericTypeParametersValidator.java
new file mode 100644
index 0000000..386b7ff
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/NoGenericTypeParametersValidator.java
@@ -0,0 +1,58 @@
+package org.junit.runners.model;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.List;
+
+class NoGenericTypeParametersValidator {
+ private final Method method;
+
+ NoGenericTypeParametersValidator(Method method) {
+ this.method = method;
+ }
+
+ void validate(List<Throwable> errors) {
+ for (Type each : method.getGenericParameterTypes()) {
+ validateNoTypeParameterOnType(each, errors);
+ }
+ }
+
+ private void validateNoTypeParameterOnType(Type type, List<Throwable> errors) {
+ if (type instanceof TypeVariable<?>) {
+ errors.add(new Exception("Method " + method.getName()
+ + "() contains unresolved type variable " + type));
+ } else if (type instanceof ParameterizedType) {
+ validateNoTypeParameterOnParameterizedType((ParameterizedType) type, errors);
+ } else if (type instanceof WildcardType) {
+ validateNoTypeParameterOnWildcardType((WildcardType) type, errors);
+ } else if (type instanceof GenericArrayType) {
+ validateNoTypeParameterOnGenericArrayType((GenericArrayType) type, errors);
+ }
+ }
+
+ private void validateNoTypeParameterOnParameterizedType(ParameterizedType parameterized,
+ List<Throwable> errors) {
+ for (Type each : parameterized.getActualTypeArguments()) {
+ validateNoTypeParameterOnType(each, errors);
+ }
+ }
+
+ private void validateNoTypeParameterOnWildcardType(WildcardType wildcard,
+ List<Throwable> errors) {
+ for (Type each : wildcard.getUpperBounds()) {
+ validateNoTypeParameterOnType(each, errors);
+ }
+ for (Type each : wildcard.getLowerBounds()) {
+ validateNoTypeParameterOnType(each, errors);
+ }
+ }
+
+ private void validateNoTypeParameterOnGenericArrayType(
+ GenericArrayType arrayType, List<Throwable> errors) {
+ validateNoTypeParameterOnType(arrayType.getGenericComponentType(), errors);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerBuilder.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerBuilder.java
new file mode 100644
index 0000000..ba7c9e2
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerBuilder.java
@@ -0,0 +1,132 @@
+package org.junit.runners.model;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Description;
+import org.junit.runner.OrderWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.Ordering;
+
+/**
+ * A RunnerBuilder is a strategy for constructing runners for classes.
+ *
+ * Only writers of custom runners should use <code>RunnerBuilder</code>s. A custom runner class with a constructor taking
+ * a <code>RunnerBuilder</code> parameter will be passed the instance of <code>RunnerBuilder</code> used to build that runner itself.
+ * For example,
+ * imagine a custom runner that builds suites based on a list of classes in a text file:
+ *
+ * <pre>
+ * \@RunWith(TextFileSuite.class)
+ * \@SuiteSpecFile("mysuite.txt")
+ * class MySuite {}
+ * </pre>
+ *
+ * The implementation of TextFileSuite might include:
+ *
+ * <pre>
+ * public TextFileSuite(Class testClass, RunnerBuilder builder) {
+ * // ...
+ * for (String className : readClassNames())
+ * addRunner(builder.runnerForClass(Class.forName(className)));
+ * // ...
+ * }
+ * </pre>
+ *
+ * @see org.junit.runners.Suite
+ * @since 4.5
+ */
+public abstract class RunnerBuilder {
+ private final Set<Class<?>> parents = new HashSet<Class<?>>();
+
+ /**
+ * Override to calculate the correct runner for a test class at runtime.
+ *
+ * @param testClass class to be run
+ * @return a Runner
+ * @throws Throwable if a runner cannot be constructed
+ */
+ public abstract Runner runnerForClass(Class<?> testClass) throws Throwable;
+
+ /**
+ * Always returns a runner for the given test class.
+ *
+ * <p>In case of an exception a runner will be returned that prints an error instead of running
+ * tests.
+ *
+ * <p>Note that some of the internal JUnit implementations of RunnerBuilder will return
+ * {@code null} from this method, but no RunnerBuilder passed to a Runner constructor will
+ * return {@code null} from this method.
+ *
+ * @param testClass class to be run
+ * @return a Runner
+ */
+ public Runner safeRunnerForClass(Class<?> testClass) {
+ try {
+ Runner runner = runnerForClass(testClass);
+ if (runner != null) {
+ configureRunner(runner);
+ }
+ return runner;
+ } catch (Throwable e) {
+ return new ErrorReportingRunner(testClass, e);
+ }
+ }
+
+ private void configureRunner(Runner runner) throws InvalidOrderingException {
+ Description description = runner.getDescription();
+ OrderWith orderWith = description.getAnnotation(OrderWith.class);
+ if (orderWith != null) {
+ Ordering ordering = Ordering.definedBy(orderWith.value(), description);
+ ordering.apply(runner);
+ }
+ }
+
+ Class<?> addParent(Class<?> parent) throws InitializationError {
+ if (!parents.add(parent)) {
+ throw new InitializationError(String.format("class '%s' (possibly indirectly) contains itself as a SuiteClass", parent.getName()));
+ }
+ return parent;
+ }
+
+ void removeParent(Class<?> klass) {
+ parents.remove(klass);
+ }
+
+ /**
+ * Constructs and returns a list of Runners, one for each child class in
+ * {@code children}. Care is taken to avoid infinite recursion:
+ * this builder will throw an exception if it is requested for another
+ * runner for {@code parent} before this call completes.
+ */
+ public List<Runner> runners(Class<?> parent, Class<?>[] children)
+ throws InitializationError {
+ addParent(parent);
+
+ try {
+ return runners(children);
+ } finally {
+ removeParent(parent);
+ }
+ }
+
+ public List<Runner> runners(Class<?> parent, List<Class<?>> children)
+ throws InitializationError {
+ return runners(parent, children.toArray(new Class<?>[0]));
+ }
+
+ private List<Runner> runners(Class<?>[] children) {
+ List<Runner> runners = new ArrayList<Runner>();
+ for (Class<?> each : children) {
+ Runner childRunner = safeRunnerForClass(each);
+ if (childRunner != null) {
+ runners.add(childRunner);
+ }
+ }
+ return runners;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerScheduler.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerScheduler.java
new file mode 100644
index 0000000..db43308
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/RunnerScheduler.java
@@ -0,0 +1,23 @@
+package org.junit.runners.model;
+
+/**
+ * Represents a strategy for scheduling when individual test methods
+ * should be run (in serial or parallel)
+ *
+ * WARNING: still experimental, may go away.
+ *
+ * @since 4.7
+ */
+public interface RunnerScheduler {
+ /**
+ * Schedule a child statement to run
+ */
+ void schedule(Runnable childStatement);
+
+ /**
+ * Override to implement any behavior that must occur
+ * after all children have been scheduled (for example,
+ * waiting for them all to finish)
+ */
+ void finished();
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Statement.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Statement.java
new file mode 100644
index 0000000..fa53fa1
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/Statement.java
@@ -0,0 +1,15 @@
+package org.junit.runners.model;
+
+
+/**
+ * Represents one or more actions to be taken at runtime in the course
+ * of running a JUnit test suite.
+ *
+ * @since 4.5
+ */
+public abstract class Statement {
+ /**
+ * Run the action, throwing a {@code Throwable} if anything goes wrong.
+ */
+ public abstract void evaluate() throws Throwable;
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestClass.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestClass.java
new file mode 100644
index 0000000..3032d52
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestClass.java
@@ -0,0 +1,348 @@
+package org.junit.runners.model;
+
+import static java.lang.reflect.Modifier.isStatic;
+import static org.junit.internal.MethodSorter.NAME_ASCENDING;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.internal.MethodSorter;
+
+/**
+ * Wraps a class to be run, providing method validation and annotation searching
+ *
+ * @since 4.5
+ */
+public class TestClass implements Annotatable {
+ private static final FieldComparator FIELD_COMPARATOR = new FieldComparator();
+ private static final MethodComparator METHOD_COMPARATOR = new MethodComparator();
+
+ private final Class<?> clazz;
+ private final Map<Class<? extends Annotation>, List<FrameworkMethod>> methodsForAnnotations;
+ private final Map<Class<? extends Annotation>, List<FrameworkField>> fieldsForAnnotations;
+
+ /**
+ * Creates a {@code TestClass} wrapping {@code clazz}. Each time this
+ * constructor executes, the class is scanned for annotations, which can be
+ * an expensive process (we hope in future JDK's it will not be.) Therefore,
+ * try to share instances of {@code TestClass} where possible.
+ */
+ public TestClass(Class<?> clazz) {
+ this.clazz = clazz;
+ if (clazz != null && clazz.getConstructors().length > 1) {
+ throw new IllegalArgumentException(
+ "Test class can only have one constructor");
+ }
+
+ Map<Class<? extends Annotation>, List<FrameworkMethod>> methodsForAnnotations =
+ new LinkedHashMap<Class<? extends Annotation>, List<FrameworkMethod>>();
+ Map<Class<? extends Annotation>, List<FrameworkField>> fieldsForAnnotations =
+ new LinkedHashMap<Class<? extends Annotation>, List<FrameworkField>>();
+
+ scanAnnotatedMembers(methodsForAnnotations, fieldsForAnnotations);
+
+ this.methodsForAnnotations = makeDeeplyUnmodifiable(methodsForAnnotations);
+ this.fieldsForAnnotations = makeDeeplyUnmodifiable(fieldsForAnnotations);
+ }
+
+ protected void scanAnnotatedMembers(Map<Class<? extends Annotation>, List<FrameworkMethod>> methodsForAnnotations, Map<Class<? extends Annotation>, List<FrameworkField>> fieldsForAnnotations) {
+ for (Class<?> eachClass : getSuperClasses(clazz)) {
+ for (Method eachMethod : MethodSorter.getDeclaredMethods(eachClass)) {
+ addToAnnotationLists(new FrameworkMethod(eachMethod), methodsForAnnotations);
+ }
+ // ensuring fields are sorted to make sure that entries are inserted
+ // and read from fieldForAnnotations in a deterministic order
+ for (Field eachField : getSortedDeclaredFields(eachClass)) {
+ addToAnnotationLists(new FrameworkField(eachField), fieldsForAnnotations);
+ }
+ }
+ }
+
+ private static Field[] getSortedDeclaredFields(Class<?> clazz) {
+ Field[] declaredFields = clazz.getDeclaredFields();
+ // TODO(b/66985866) - uncomment when affected tests have Rule order fixed.
+ // Arrays.sort(declaredFields, FIELD_COMPARATOR);
+ return declaredFields;
+ }
+
+ protected static <T extends FrameworkMember<T>> void addToAnnotationLists(T member,
+ Map<Class<? extends Annotation>, List<T>> map) {
+ for (Annotation each : member.getAnnotations()) {
+ Class<? extends Annotation> type = each.annotationType();
+ List<T> members = getAnnotatedMembers(map, type, true);
+ T memberToAdd = member.handlePossibleBridgeMethod(members);
+ if (memberToAdd == null) {
+ return;
+ }
+ if (runsTopToBottom(type)) {
+ members.add(0, memberToAdd);
+ } else {
+ members.add(memberToAdd);
+ }
+ }
+ }
+
+ private static <T extends FrameworkMember<T>> Map<Class<? extends Annotation>, List<T>>
+ makeDeeplyUnmodifiable(Map<Class<? extends Annotation>, List<T>> source) {
+ Map<Class<? extends Annotation>, List<T>> copy =
+ new LinkedHashMap<Class<? extends Annotation>, List<T>>();
+ for (Map.Entry<Class<? extends Annotation>, List<T>> entry : source.entrySet()) {
+ copy.put(entry.getKey(), Collections.unmodifiableList(entry.getValue()));
+ }
+ return Collections.unmodifiableMap(copy);
+ }
+
+ /**
+ * Returns, efficiently, all the non-overridden methods in this class and
+ * its superclasses that are annotated}.
+ *
+ * @since 4.12
+ */
+ public List<FrameworkMethod> getAnnotatedMethods() {
+ List<FrameworkMethod> methods = collectValues(methodsForAnnotations);
+ Collections.sort(methods, METHOD_COMPARATOR);
+ return methods;
+ }
+
+ /**
+ * Returns, efficiently, all the non-overridden methods in this class and
+ * its superclasses that are annotated with {@code annotationClass}.
+ */
+ public List<FrameworkMethod> getAnnotatedMethods(
+ Class<? extends Annotation> annotationClass) {
+ return Collections.unmodifiableList(getAnnotatedMembers(methodsForAnnotations, annotationClass, false));
+ }
+
+ /**
+ * Returns, efficiently, all the non-overridden fields in this class and its
+ * superclasses that are annotated.
+ *
+ * @since 4.12
+ */
+ public List<FrameworkField> getAnnotatedFields() {
+ return collectValues(fieldsForAnnotations);
+ }
+
+ /**
+ * Returns, efficiently, all the non-overridden fields in this class and its
+ * superclasses that are annotated with {@code annotationClass}.
+ */
+ public List<FrameworkField> getAnnotatedFields(
+ Class<? extends Annotation> annotationClass) {
+ return Collections.unmodifiableList(getAnnotatedMembers(fieldsForAnnotations, annotationClass, false));
+ }
+
+ private <T> List<T> collectValues(Map<?, List<T>> map) {
+ Set<T> values = new LinkedHashSet<T>();
+ for (List<T> additionalValues : map.values()) {
+ values.addAll(additionalValues);
+ }
+ return new ArrayList<T>(values);
+ }
+
+ private static <T> List<T> getAnnotatedMembers(Map<Class<? extends Annotation>, List<T>> map,
+ Class<? extends Annotation> type, boolean fillIfAbsent) {
+ if (!map.containsKey(type) && fillIfAbsent) {
+ map.put(type, new ArrayList<T>());
+ }
+ List<T> members = map.get(type);
+ return members == null ? Collections.<T>emptyList() : members;
+ }
+
+ private static boolean runsTopToBottom(Class<? extends Annotation> annotation) {
+ return annotation.equals(Before.class)
+ || annotation.equals(BeforeClass.class);
+ }
+
+ private static List<Class<?>> getSuperClasses(Class<?> testClass) {
+ List<Class<?>> results = new ArrayList<Class<?>>();
+ Class<?> current = testClass;
+ while (current != null) {
+ results.add(current);
+ current = current.getSuperclass();
+ }
+ return results;
+ }
+
+ /**
+ * Returns the underlying Java class.
+ */
+ public Class<?> getJavaClass() {
+ return clazz;
+ }
+
+ /**
+ * Returns the class's name.
+ */
+ public String getName() {
+ if (clazz == null) {
+ return "null";
+ }
+ return clazz.getName();
+ }
+
+ /**
+ * Returns the only public constructor in the class, or throws an {@code
+ * AssertionError} if there are more or less than one.
+ */
+
+ public Constructor<?> getOnlyConstructor() {
+ Constructor<?>[] constructors = clazz.getConstructors();
+ Assert.assertEquals(1, constructors.length);
+ return constructors[0];
+ }
+
+ /**
+ * Returns the annotations on this class
+ */
+ public Annotation[] getAnnotations() {
+ if (clazz == null) {
+ return new Annotation[0];
+ }
+ return clazz.getAnnotations();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ if (clazz == null) {
+ return null;
+ }
+ return clazz.getAnnotation(annotationType);
+ }
+
+ public <T> List<T> getAnnotatedFieldValues(Object test,
+ Class<? extends Annotation> annotationClass, Class<T> valueClass) {
+ final List<T> results = new ArrayList<T>();
+ collectAnnotatedFieldValues(test, annotationClass, valueClass,
+ new MemberValueConsumer<T>() {
+ public void accept(FrameworkMember<?> member, T value) {
+ results.add(value);
+ }
+ });
+ return results;
+ }
+
+ /**
+ * Finds the fields annotated with the specified annotation and having the specified type,
+ * retrieves the values and passes those to the specified consumer.
+ *
+ * @since 4.13
+ */
+ public <T> void collectAnnotatedFieldValues(Object test,
+ Class<? extends Annotation> annotationClass, Class<T> valueClass,
+ MemberValueConsumer<T> consumer) {
+ for (FrameworkField each : getAnnotatedFields(annotationClass)) {
+ try {
+ Object fieldValue = each.get(test);
+ if (valueClass.isInstance(fieldValue)) {
+ consumer.accept(each, valueClass.cast(fieldValue));
+ }
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(
+ "How did getFields return a field we couldn't access?", e);
+ }
+ }
+ }
+
+ public <T> List<T> getAnnotatedMethodValues(Object test,
+ Class<? extends Annotation> annotationClass, Class<T> valueClass) {
+ final List<T> results = new ArrayList<T>();
+ collectAnnotatedMethodValues(test, annotationClass, valueClass,
+ new MemberValueConsumer<T>() {
+ public void accept(FrameworkMember<?> member, T value) {
+ results.add(value);
+ }
+ });
+ return results;
+ }
+
+ /**
+ * Finds the methods annotated with the specified annotation and returning the specified type,
+ * invokes it and pass the return value to the specified consumer.
+ *
+ * @since 4.13
+ */
+ public <T> void collectAnnotatedMethodValues(Object test,
+ Class<? extends Annotation> annotationClass, Class<T> valueClass,
+ MemberValueConsumer<T> consumer) {
+ for (FrameworkMethod each : getAnnotatedMethods(annotationClass)) {
+ try {
+ /*
+ * A method annotated with @Rule may return a @TestRule or a @MethodRule,
+ * we cannot call the method to check whether the return type matches our
+ * expectation i.e. subclass of valueClass. If we do that then the method
+ * will be invoked twice and we do not want to do that. So we first check
+ * whether return type matches our expectation and only then call the method
+ * to fetch the MethodRule
+ */
+ if (valueClass.isAssignableFrom(each.getReturnType())) {
+ Object fieldValue = each.invokeExplosively(test);
+ consumer.accept(each, valueClass.cast(fieldValue));
+ }
+ } catch (Throwable e) {
+ throw new RuntimeException(
+ "Exception in " + each.getName(), e);
+ }
+ }
+ }
+
+ public boolean isPublic() {
+ return Modifier.isPublic(clazz.getModifiers());
+ }
+
+ public boolean isANonStaticInnerClass() {
+ return clazz.isMemberClass() && !isStatic(clazz.getModifiers());
+ }
+
+ @Override
+ public int hashCode() {
+ return (clazz == null) ? 0 : clazz.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ TestClass other = (TestClass) obj;
+ return clazz == other.clazz;
+ }
+
+ /**
+ * Compares two fields by its name.
+ */
+ private static class FieldComparator implements Comparator<Field> {
+ public int compare(Field left, Field right) {
+ return left.getName().compareTo(right.getName());
+ }
+ }
+
+ /**
+ * Compares two methods by its name.
+ */
+ private static class MethodComparator implements
+ Comparator<FrameworkMethod> {
+ public int compare(FrameworkMethod left, FrameworkMethod right) {
+ return NAME_ASCENDING.compare(left.getMethod(), right.getMethod());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestTimedOutException.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestTimedOutException.java
new file mode 100644
index 0000000..60e1a8a
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/model/TestTimedOutException.java
@@ -0,0 +1,44 @@
+package org.junit.runners.model;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Exception thrown when a test fails on timeout.
+ *
+ * @since 4.12
+ *
+ */
+public class TestTimedOutException extends Exception {
+
+ private static final long serialVersionUID = 31935685163547539L;
+
+ private final TimeUnit timeUnit;
+ private final long timeout;
+
+ /**
+ * Creates exception with a standard message "test timed out after [timeout] [timeUnit]"
+ *
+ * @param timeout the amount of time passed before the test was interrupted
+ * @param timeUnit the time unit for the timeout value
+ */
+ public TestTimedOutException(long timeout, TimeUnit timeUnit) {
+ super(String.format("test timed out after %d %s",
+ timeout, timeUnit.name().toLowerCase()));
+ this.timeUnit = timeUnit;
+ this.timeout = timeout;
+ }
+
+ /**
+ * Gets the time passed before the test was interrupted
+ */
+ public long getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Gets the time unit for the timeout value
+ */
+ public TimeUnit getTimeUnit() {
+ return timeUnit;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/package-info.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/package-info.java
new file mode 100644
index 0000000..418acaf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Provides standard {@link org.junit.runner.Runner Runner} implementations.
+ *
+ * @since 4.0
+ * @see org.junit.runner.Runner
+ * @see org.junit.runners.BlockJUnit4ClassRunner
+ */
+package org.junit.runners;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
new file mode 100644
index 0000000..5c70a75
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
@@ -0,0 +1,219 @@
+package org.junit.runners.parameterized;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.List;
+
+import org.junit.internal.runners.statements.RunAfters;
+import org.junit.internal.runners.statements.RunBefores;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * A {@link BlockJUnit4ClassRunner} with parameters support. Parameters can be
+ * injected via constructor or into annotated fields.
+ */
+public class BlockJUnit4ClassRunnerWithParameters extends
+ BlockJUnit4ClassRunner {
+ private enum InjectionType {
+ CONSTRUCTOR, FIELD
+ }
+
+ private final Object[] parameters;
+
+ private final String name;
+
+ public BlockJUnit4ClassRunnerWithParameters(TestWithParameters test)
+ throws InitializationError {
+ super(test.getTestClass());
+ parameters = test.getParameters().toArray(
+ new Object[test.getParameters().size()]);
+ name = test.getName();
+ }
+
+ @Override
+ public Object createTest() throws Exception {
+ InjectionType injectionType = getInjectionType();
+ switch (injectionType) {
+ case CONSTRUCTOR:
+ return createTestUsingConstructorInjection();
+ case FIELD:
+ return createTestUsingFieldInjection();
+ default:
+ throw new IllegalStateException("The injection type "
+ + injectionType + " is not supported.");
+ }
+ }
+
+ private Object createTestUsingConstructorInjection() throws Exception {
+ return getTestClass().getOnlyConstructor().newInstance(parameters);
+ }
+
+ private Object createTestUsingFieldInjection() throws Exception {
+ List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
+ if (annotatedFieldsByParameter.size() != parameters.length) {
+ throw new Exception(
+ "Wrong number of parameters and @Parameter fields."
+ + " @Parameter fields counted: "
+ + annotatedFieldsByParameter.size()
+ + ", available parameters: " + parameters.length
+ + ".");
+ }
+ Object testClassInstance = getTestClass().getJavaClass().newInstance();
+ for (FrameworkField each : annotatedFieldsByParameter) {
+ Field field = each.getField();
+ Parameter annotation = field.getAnnotation(Parameter.class);
+ int index = annotation.value();
+ try {
+ field.set(testClassInstance, parameters[index]);
+ } catch (IllegalAccessException e) {
+ IllegalAccessException wrappedException = new IllegalAccessException(
+ "Cannot set parameter '" + field.getName()
+ + "'. Ensure that the field '" + field.getName()
+ + "' is public.");
+ wrappedException.initCause(e);
+ throw wrappedException;
+ } catch (IllegalArgumentException iare) {
+ throw new Exception(getTestClass().getName()
+ + ": Trying to set " + field.getName()
+ + " with the value " + parameters[index]
+ + " that is not the right type ("
+ + parameters[index].getClass().getSimpleName()
+ + " instead of " + field.getType().getSimpleName()
+ + ").", iare);
+ }
+ }
+ return testClassInstance;
+ }
+
+ @Override
+ protected String getName() {
+ return name;
+ }
+
+ @Override
+ protected String testName(FrameworkMethod method) {
+ return method.getName() + getName();
+ }
+
+ @Override
+ protected void validateConstructor(List<Throwable> errors) {
+ validateOnlyOneConstructor(errors);
+ if (getInjectionType() != InjectionType.CONSTRUCTOR) {
+ validateZeroArgConstructor(errors);
+ }
+ }
+
+ @Override
+ protected void validateFields(List<Throwable> errors) {
+ super.validateFields(errors);
+ if (getInjectionType() == InjectionType.FIELD) {
+ List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
+ int[] usedIndices = new int[annotatedFieldsByParameter.size()];
+ for (FrameworkField each : annotatedFieldsByParameter) {
+ int index = each.getField().getAnnotation(Parameter.class)
+ .value();
+ if (index < 0 || index > annotatedFieldsByParameter.size() - 1) {
+ errors.add(new Exception("Invalid @Parameter value: "
+ + index + ". @Parameter fields counted: "
+ + annotatedFieldsByParameter.size()
+ + ". Please use an index between 0 and "
+ + (annotatedFieldsByParameter.size() - 1) + "."));
+ } else {
+ usedIndices[index]++;
+ }
+ }
+ for (int index = 0; index < usedIndices.length; index++) {
+ int numberOfUse = usedIndices[index];
+ if (numberOfUse == 0) {
+ errors.add(new Exception("@Parameter(" + index
+ + ") is never used."));
+ } else if (numberOfUse > 1) {
+ errors.add(new Exception("@Parameter(" + index
+ + ") is used more than once (" + numberOfUse + ")."));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Statement classBlock(RunNotifier notifier) {
+ Statement statement = childrenInvoker(notifier);
+ statement = withBeforeParams(statement);
+ statement = withAfterParams(statement);
+ return statement;
+ }
+
+ private Statement withBeforeParams(Statement statement) {
+ List<FrameworkMethod> befores = getTestClass()
+ .getAnnotatedMethods(Parameterized.BeforeParam.class);
+ return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores);
+ }
+
+ private class RunBeforeParams extends RunBefores {
+ RunBeforeParams(Statement next, List<FrameworkMethod> befores) {
+ super(next, befores, null);
+ }
+
+ @Override
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ int paramCount = method.getMethod().getParameterTypes().length;
+ method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters);
+ }
+ }
+
+ private Statement withAfterParams(Statement statement) {
+ List<FrameworkMethod> afters = getTestClass()
+ .getAnnotatedMethods(Parameterized.AfterParam.class);
+ return afters.isEmpty() ? statement : new RunAfterParams(statement, afters);
+ }
+
+ private class RunAfterParams extends RunAfters {
+ RunAfterParams(Statement next, List<FrameworkMethod> afters) {
+ super(next, afters, null);
+ }
+
+ @Override
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ int paramCount = method.getMethod().getParameterTypes().length;
+ method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters);
+ }
+ }
+
+ @Override
+ protected Annotation[] getRunnerAnnotations() {
+ Annotation[] allAnnotations = super.getRunnerAnnotations();
+ Annotation[] annotationsWithoutRunWith = new Annotation[allAnnotations.length - 1];
+ int i = 0;
+ for (Annotation annotation: allAnnotations) {
+ if (!annotation.annotationType().equals(RunWith.class)) {
+ annotationsWithoutRunWith[i] = annotation;
+ ++i;
+ }
+ }
+ return annotationsWithoutRunWith;
+ }
+
+ private List<FrameworkField> getAnnotatedFieldsByParameter() {
+ return getTestClass().getAnnotatedFields(Parameter.class);
+ }
+
+ private InjectionType getInjectionType() {
+ if (fieldsAreAnnotated()) {
+ return InjectionType.FIELD;
+ } else {
+ return InjectionType.CONSTRUCTOR;
+ }
+ }
+
+ private boolean fieldsAreAnnotated() {
+ return !getAnnotatedFieldsByParameter().isEmpty();
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersFactory.java
new file mode 100644
index 0000000..ae49ef4
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersFactory.java
@@ -0,0 +1,18 @@
+package org.junit.runners.parameterized;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A {@link ParametersRunnerFactory} that creates
+ * {@link BlockJUnit4ClassRunnerWithParameters}.
+ *
+ * @since 4.12
+ */
+public class BlockJUnit4ClassRunnerWithParametersFactory implements
+ ParametersRunnerFactory {
+ public Runner createRunnerForTestWithParameters(TestWithParameters test)
+ throws InitializationError {
+ return new BlockJUnit4ClassRunnerWithParameters(test);
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java
new file mode 100644
index 0000000..8123e83
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java
@@ -0,0 +1,21 @@
+package org.junit.runners.parameterized;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * A {@code ParametersRunnerFactory} creates a runner for a single
+ * {@link TestWithParameters}.
+ *
+ * @since 4.12
+ */
+public interface ParametersRunnerFactory {
+ /**
+ * Returns a runner for the specified {@link TestWithParameters}.
+ *
+ * @throws InitializationError
+ * if the runner could not be created.
+ */
+ Runner createRunnerForTestWithParameters(TestWithParameters test)
+ throws InitializationError;
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/TestWithParameters.java b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/TestWithParameters.java
new file mode 100644
index 0000000..1c5abd9
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/runners/parameterized/TestWithParameters.java
@@ -0,0 +1,77 @@
+package org.junit.runners.parameterized;
+
+import static java.util.Collections.unmodifiableList;
+import static org.junit.internal.Checks.notNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.runners.model.TestClass;
+
+/**
+ * A {@code TestWithParameters} keeps the data together that are needed for
+ * creating a runner for a single data set of a parameterized test. It has a
+ * name, the test class and a list of parameters.
+ *
+ * @since 4.12
+ */
+public class TestWithParameters {
+ private final String name;
+
+ private final TestClass testClass;
+
+ private final List<Object> parameters;
+
+ public TestWithParameters(String name, TestClass testClass,
+ List<Object> parameters) {
+ notNull(name, "The name is missing.");
+ notNull(testClass, "The test class is missing.");
+ notNull(parameters, "The parameters are missing.");
+ this.name = name;
+ this.testClass = testClass;
+ this.parameters = unmodifiableList(new ArrayList<Object>(parameters));
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public TestClass getTestClass() {
+ return testClass;
+ }
+
+ public List<Object> getParameters() {
+ return parameters;
+ }
+
+ @Override
+ public int hashCode() {
+ int prime = 14747;
+ int result = prime + name.hashCode();
+ result = prime * result + testClass.hashCode();
+ return prime * result + parameters.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ TestWithParameters other = (TestWithParameters) obj;
+ return name.equals(other.name)
+ && parameters.equals(other.parameters)
+ && testClass.equals(other.testClass);
+ }
+
+ @Override
+ public String toString() {
+ return testClass.getName() + " '" + name + "' with parameters "
+ + parameters;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidator.java
new file mode 100644
index 0000000..8a53adf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidator.java
@@ -0,0 +1,60 @@
+package org.junit.validator;
+
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+import static java.util.Collections.emptyList;
+
+import java.util.List;
+
+/**
+ * Validates annotations on classes and methods. To be validated,
+ * an annotation should be annotated with {@link ValidateWith}
+ *
+ * Instances of this class are shared by multiple test runners, so they should
+ * be immutable and thread-safe.
+ *
+ * @since 4.12
+ */
+public abstract class AnnotationValidator {
+
+ private static final List<Exception> NO_VALIDATION_ERRORS = emptyList();
+
+ /**
+ * Validates annotation on the given class.
+ *
+ * @param testClass that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedClass(TestClass testClass) {
+ return NO_VALIDATION_ERRORS;
+ }
+
+ /**
+ * Validates annotation on the given field.
+ *
+ * @param field that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedField(FrameworkField field) {
+ return NO_VALIDATION_ERRORS;
+
+ }
+
+ /**
+ * Validates annotation on the given method.
+ *
+ * @param method that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
+ return NO_VALIDATION_ERRORS;
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidatorFactory.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidatorFactory.java
new file mode 100644
index 0000000..fb2460d
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationValidatorFactory.java
@@ -0,0 +1,39 @@
+package org.junit.validator;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Creates instances of Annotation Validators.
+ *
+ * @since 4.12
+ */
+public class AnnotationValidatorFactory {
+ private static final ConcurrentHashMap<ValidateWith, AnnotationValidator> VALIDATORS_FOR_ANNOTATION_TYPES =
+ new ConcurrentHashMap<ValidateWith, AnnotationValidator>();
+
+ /**
+ * Creates the AnnotationValidator specified by the value in
+ * {@link org.junit.validator.ValidateWith}. Instances are
+ * cached.
+ *
+ * @return An instance of the AnnotationValidator.
+ *
+ * @since 4.12
+ */
+ public AnnotationValidator createAnnotationValidator(ValidateWith validateWithAnnotation) {
+ AnnotationValidator validator = VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
+ if (validator != null) {
+ return validator;
+ }
+
+ Class<? extends AnnotationValidator> clazz = validateWithAnnotation.value();
+ try {
+ AnnotationValidator annotationValidator = clazz.newInstance();
+ VALIDATORS_FOR_ANNOTATION_TYPES.putIfAbsent(validateWithAnnotation, annotationValidator);
+ return VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
+ } catch (Exception e) {
+ throw new RuntimeException("Exception received when creating AnnotationValidator class " + clazz.getName(), e);
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationsValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationsValidator.java
new file mode 100644
index 0000000..d8b5840
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/AnnotationsValidator.java
@@ -0,0 +1,120 @@
+package org.junit.validator;
+
+import static java.util.Collections.singletonList;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.runners.model.Annotatable;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+/**
+ * An {@code AnnotationsValidator} validates all annotations of a test class,
+ * including its annotated fields and methods.
+ *
+ * @since 4.12
+ */
+public final class AnnotationsValidator implements TestClassValidator {
+ private static final List<AnnotatableValidator<?>> VALIDATORS = Arrays.<AnnotatableValidator<?>>asList(
+ new ClassValidator(), new MethodValidator(), new FieldValidator());
+
+ /**
+ * Validate all annotations of the specified test class that are be
+ * annotated with {@link ValidateWith}.
+ *
+ * @param testClass
+ * the {@link TestClass} that is validated.
+ * @return the errors found by the validator.
+ */
+ public List<Exception> validateTestClass(TestClass testClass) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (AnnotatableValidator<?> validator : VALIDATORS) {
+ List<Exception> additionalErrors= validator
+ .validateTestClass(testClass);
+ validationErrors.addAll(additionalErrors);
+ }
+ return validationErrors;
+ }
+
+ private abstract static class AnnotatableValidator<T extends Annotatable> {
+ private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory();
+
+ abstract Iterable<T> getAnnotatablesForTestClass(TestClass testClass);
+
+ abstract List<Exception> validateAnnotatable(
+ AnnotationValidator validator, T annotatable);
+
+ public List<Exception> validateTestClass(TestClass testClass) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (T annotatable : getAnnotatablesForTestClass(testClass)) {
+ List<Exception> additionalErrors= validateAnnotatable(annotatable);
+ validationErrors.addAll(additionalErrors);
+ }
+ return validationErrors;
+ }
+
+ private List<Exception> validateAnnotatable(T annotatable) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (Annotation annotation : annotatable.getAnnotations()) {
+ Class<? extends Annotation> annotationType = annotation
+ .annotationType();
+ ValidateWith validateWith = annotationType
+ .getAnnotation(ValidateWith.class);
+ if (validateWith != null) {
+ AnnotationValidator annotationValidator = ANNOTATION_VALIDATOR_FACTORY
+ .createAnnotationValidator(validateWith);
+ List<Exception> errors= validateAnnotatable(
+ annotationValidator, annotatable);
+ validationErrors.addAll(errors);
+ }
+ }
+ return validationErrors;
+ }
+ }
+
+ private static class ClassValidator extends AnnotatableValidator<TestClass> {
+ @Override
+ Iterable<TestClass> getAnnotatablesForTestClass(TestClass testClass) {
+ return singletonList(testClass);
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, TestClass testClass) {
+ return validator.validateAnnotatedClass(testClass);
+ }
+ }
+
+ private static class MethodValidator extends
+ AnnotatableValidator<FrameworkMethod> {
+ @Override
+ Iterable<FrameworkMethod> getAnnotatablesForTestClass(
+ TestClass testClass) {
+ return testClass.getAnnotatedMethods();
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, FrameworkMethod method) {
+ return validator.validateAnnotatedMethod(method);
+ }
+ }
+
+ private static class FieldValidator extends
+ AnnotatableValidator<FrameworkField> {
+ @Override
+ Iterable<FrameworkField> getAnnotatablesForTestClass(TestClass testClass) {
+ return testClass.getAnnotatedFields();
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, FrameworkField field) {
+ return validator.validateAnnotatedField(field);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/PublicClassValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/PublicClassValidator.java
new file mode 100644
index 0000000..fe3f185
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/PublicClassValidator.java
@@ -0,0 +1,33 @@
+package org.junit.validator;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import org.junit.runners.model.TestClass;
+
+/**
+ * Validates that a {@link TestClass} is public.
+ *
+ * @since 4.12
+ */
+public class PublicClassValidator implements TestClassValidator {
+ private static final List<Exception> NO_VALIDATION_ERRORS = emptyList();
+
+ /**
+ * Validate that the specified {@link TestClass} is public.
+ *
+ * @param testClass the {@link TestClass} that is validated.
+ * @return an empty list if the class is public or a list with a single
+ * exception otherwise.
+ */
+ public List<Exception> validateTestClass(TestClass testClass) {
+ if (testClass.isPublic()) {
+ return NO_VALIDATION_ERRORS;
+ } else {
+ return singletonList(new Exception("The class "
+ + testClass.getName() + " is not public."));
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/TestClassValidator.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/TestClassValidator.java
new file mode 100644
index 0000000..ba5e892
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/TestClassValidator.java
@@ -0,0 +1,21 @@
+package org.junit.validator;
+
+import java.util.List;
+
+import org.junit.runners.model.TestClass;
+
+/**
+ * Validates a single facet of a test class.
+ *
+ * @since 4.12
+ */
+public interface TestClassValidator {
+ /**
+ * Validate a single facet of a test class.
+ *
+ * @param testClass
+ * the {@link TestClass} that is validated.
+ * @return the validation errors found by the validator.
+ */
+ List<Exception> validateTestClass(TestClass testClass);
+}
diff --git a/google3/third_party/java_src/junit/main/java/org/junit/validator/ValidateWith.java b/google3/third_party/java_src/junit/main/java/org/junit/validator/ValidateWith.java
new file mode 100644
index 0000000..3725db8
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/java/org/junit/validator/ValidateWith.java
@@ -0,0 +1,22 @@
+package org.junit.validator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Allows for an {@link AnnotationValidator} to be attached to an annotation.
+ *
+ * <p>When attached to an annotation, the validator will be instantiated and invoked
+ * by the {@link org.junit.runners.ParentRunner}.</p>
+ *
+ * @since 4.12
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+@Inherited
+public @interface ValidateWith {
+ Class<? extends AnnotationValidator> value();
+}
diff --git a/google3/third_party/java_src/junit/main/javadoc/stylesheet.css b/google3/third_party/java_src/junit/main/javadoc/stylesheet.css
new file mode 100644
index 0000000..ab56778
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/javadoc/stylesheet.css
@@ -0,0 +1,25 @@
+/* Javadoc style sheet */
+/* makes unvisited links red (red bad) */
+A {color:red;}
+/* makes visited links the same green as the toolbar (green good) */
+A:visited {color:#03A35D;}
+/* Define colors, fonts and other style attributes here to override the defaults */
+/* Page background color */
+body { background-color: #FFFFFF }
+/* Table colors */
+.TableHeadingColor { background: #03A35D} /* Green */
+.TableSubHeadingColor { background: #03A35D } /* Green */
+.TableRowColor { background: #FFFFFF } /* White */
+/* Font used in left-hand frame lists */
+.FrameTitleFont { font-size: normal; font-family: normal }
+.FrameHeadingFont { font-size: normal; font-family: normal }
+.FrameItemFont { font-size: normal; font-family: normal }
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#03A35D;}/* Green */
+.NavBarCell1Rev { background-color:#006400;}/* Dark green */
+.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
diff --git a/google3/third_party/java_src/junit/main/resources/junit/runner/logo.gif b/google3/third_party/java_src/junit/main/resources/junit/runner/logo.gif
new file mode 100644
index 0000000..d0e1547
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/resources/junit/runner/logo.gif
Binary files differ
diff --git a/google3/third_party/java_src/junit/main/resources/junit/runner/smalllogo.gif b/google3/third_party/java_src/junit/main/resources/junit/runner/smalllogo.gif
new file mode 100644
index 0000000..7b25eaf
--- /dev/null
+++ b/google3/third_party/java_src/junit/main/resources/junit/runner/smalllogo.gif
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/AllTests.java b/google3/third_party/java_src/junit/test/java/junit/samples/AllTests.java
new file mode 100644
index 0000000..6307404
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/AllTests.java
@@ -0,0 +1,22 @@
+package junit.samples;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestSuite that runs all the sample tests
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("All JUnit Tests");
+ suite.addTest(ListTest.suite());
+ suite.addTest(new TestSuite(junit.samples.money.MoneyTest.class));
+ suite.addTest(junit.tests.AllTests.suite());
+ return suite;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/ListTest.java b/google3/third_party/java_src/junit/test/java/junit/samples/ListTest.java
new file mode 100644
index 0000000..324f12b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/ListTest.java
@@ -0,0 +1,67 @@
+package junit.samples;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * A sample test case, testing {@link java.util.ArrayList}.
+ */
+public class ListTest extends TestCase {
+ private List<Integer> emptyList;
+ private List<Integer> fullList;
+
+
+ @Override
+ protected void setUp() {
+ emptyList = new ArrayList<Integer>();
+ fullList = new ArrayList<Integer>();
+ fullList.add(1);
+ fullList.add(2);
+ fullList.add(3);
+ }
+
+ public static Test suite() {
+ return new TestSuite(ListTest.class);
+ }
+
+ public void testCapacity() {
+ int size = fullList.size();
+ for (int i = 0; i < 100; i++) {
+ fullList.add(i);
+ }
+ assertTrue(fullList.size() == 100 + size);
+ }
+
+ public void testContains() {
+ assertTrue(fullList.contains(1));
+ assertFalse(emptyList.contains(1));
+ }
+
+ public void testElementAt() {
+ int i = fullList.get(0);
+ assertEquals(1,i);
+
+ try {
+ fullList.get(fullList.size());
+ } catch (IndexOutOfBoundsException e) {
+ return;
+ }
+ fail("Should raise an ArrayIndexOutOfBoundsException");
+ }
+
+ public void testRemoveAll() {
+ fullList.removeAll(fullList);
+ emptyList.removeAll(emptyList);
+ assertTrue(fullList.isEmpty());
+ assertTrue(emptyList.isEmpty());
+ }
+
+ public void testRemoveElement() {
+ fullList.remove(Integer.valueOf(3));
+ assertFalse(fullList.contains(3));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/SimpleTest.java b/google3/third_party/java_src/junit/test/java/junit/samples/SimpleTest.java
new file mode 100644
index 0000000..5177f48
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/SimpleTest.java
@@ -0,0 +1,72 @@
+package junit.samples;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Some simple tests.
+ */
+public class SimpleTest extends TestCase {
+ protected int fValue1;
+ protected int fValue2;
+
+ @Override
+ protected void setUp() {
+ fValue1 = 2;
+ fValue2 = 3;
+ }
+
+ public static Test suite() {
+
+ /*
+ * the type safe way
+ *
+ TestSuite suite= new TestSuite();
+ suite.addTest(
+ new SimpleTest("add") {
+ protected void runTest() { testAdd(); }
+ }
+ );
+
+ suite.addTest(
+ new SimpleTest("testDivideByZero") {
+ protected void runTest() { testDivideByZero(); }
+ }
+ );
+ return suite;
+ */
+
+ /*
+ * the dynamic way
+ */
+ return new TestSuite(SimpleTest.class);
+ }
+
+ public void testAdd() {
+ double result = fValue1 + fValue2;
+ // forced failure result == 5
+ assertTrue(result == 6);
+ }
+
+ public int unused;
+
+ public void testDivideByZero() {
+ int zero = 0;
+ int result = 8 / zero;
+ unused = result; // avoid warning for not using result
+ }
+
+ public void testEquals() {
+ assertEquals(12, 12);
+ assertEquals(12L, 12L);
+ assertEquals(new Long(12), new Long(12));
+
+ assertEquals("Size", 12, 13);
+ assertEquals("Capacity", 12.0, 11.99, 0.0);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/money/IMoney.java b/google3/third_party/java_src/junit/test/java/junit/samples/money/IMoney.java
new file mode 100644
index 0000000..d48757a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/money/IMoney.java
@@ -0,0 +1,51 @@
+package junit.samples.money;
+
+/**
+ * The common interface for simple Monies and MoneyBags
+ */
+public interface IMoney {
+ /**
+ * Adds a money to this money.
+ */
+ IMoney add(IMoney m);
+
+ /**
+ * Adds a simple Money to this money. This is a helper method for
+ * implementing double dispatch
+ */
+ IMoney addMoney(Money m);
+
+ /**
+ * Adds a MoneyBag to this money. This is a helper method for
+ * implementing double dispatch
+ */
+ IMoney addMoneyBag(MoneyBag s);
+
+ /**
+ * Tests whether this money is zero
+ */
+ boolean isZero();
+
+ /**
+ * Multiplies a money by the given factor.
+ */
+ IMoney multiply(int factor);
+
+ /**
+ * Negates this money.
+ */
+ IMoney negate();
+
+ /**
+ * Subtracts a money from this money.
+ */
+ IMoney subtract(IMoney m);
+
+ /**
+ * Append this to a MoneyBag m.
+ * appendTo() needs to be public because it is used
+ * polymorphically, but it should not be used by clients
+ * because it modifies the argument m.
+ */
+ void appendTo(MoneyBag m);
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/money/Money.java b/google3/third_party/java_src/junit/test/java/junit/samples/money/Money.java
new file mode 100644
index 0000000..de6525b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/money/Money.java
@@ -0,0 +1,92 @@
+package junit.samples.money;
+
+/**
+ * A simple Money.
+ */
+public class Money implements IMoney {
+
+ private int fAmount;
+ private String fCurrency;
+
+ /**
+ * Constructs a money from the given amount and currency.
+ */
+ public Money(int amount, String currency) {
+ fAmount = amount;
+ fCurrency = currency;
+ }
+
+ /**
+ * Adds a money to this money. Forwards the request to the addMoney helper.
+ */
+ public IMoney add(IMoney m) {
+ return m.addMoney(this);
+ }
+
+ public IMoney addMoney(Money m) {
+ if (m.currency().equals(currency())) {
+ return new Money(amount() + m.amount(), currency());
+ }
+ return MoneyBag.create(this, m);
+ }
+
+ public IMoney addMoneyBag(MoneyBag s) {
+ return s.addMoney(this);
+ }
+
+ public int amount() {
+ return fAmount;
+ }
+
+ public String currency() {
+ return fCurrency;
+ }
+
+ @Override
+ public boolean equals(Object anObject) {
+ if (isZero()) {
+ if (anObject instanceof IMoney) {
+ return ((IMoney) anObject).isZero();
+ }
+ }
+ if (anObject instanceof Money) {
+ Money aMoney = (Money) anObject;
+ return aMoney.currency().equals(currency())
+ && amount() == aMoney.amount();
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (fAmount == 0) {
+ return 0;
+ }
+ return fCurrency.hashCode() + fAmount;
+ }
+
+ public boolean isZero() {
+ return amount() == 0;
+ }
+
+ public IMoney multiply(int factor) {
+ return new Money(amount() * factor, currency());
+ }
+
+ public IMoney negate() {
+ return new Money(-amount(), currency());
+ }
+
+ public IMoney subtract(IMoney m) {
+ return add(m.negate());
+ }
+
+ @Override
+ public String toString() {
+ return "[" + amount() + " " + currency() + "]";
+ }
+
+ public /*this makes no sense*/ void appendTo(MoneyBag m) {
+ m.appendMoney(this);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyBag.java b/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyBag.java
new file mode 100644
index 0000000..e02bb51
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyBag.java
@@ -0,0 +1,155 @@
+package junit.samples.money;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A MoneyBag defers exchange rate conversions. For example adding
+ * 12 Swiss Francs to 14 US Dollars is represented as a bag
+ * containing the two Monies 12 CHF and 14 USD. Adding another
+ * 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to
+ * the deferred exchange rate conversion we can later value a
+ * MoneyBag with different exchange rates.
+ *
+ * A MoneyBag is represented as a list of Monies and provides
+ * different constructors to create a MoneyBag.
+ */
+public class MoneyBag implements IMoney {
+ private List<Money> fMonies = new ArrayList<Money>(5);
+
+ public static IMoney create(IMoney m1, IMoney m2) {
+ MoneyBag result = new MoneyBag();
+ m1.appendTo(result);
+ m2.appendTo(result);
+ return result.simplify();
+ }
+
+ public IMoney add(IMoney m) {
+ return m.addMoneyBag(this);
+ }
+
+ public IMoney addMoney(Money m) {
+ return MoneyBag.create(m, this);
+ }
+
+ public IMoney addMoneyBag(MoneyBag s) {
+ return MoneyBag.create(s, this);
+ }
+
+ void appendBag(MoneyBag aBag) {
+ for (Money each : aBag.fMonies) {
+ appendMoney(each);
+ }
+ }
+
+ void appendMoney(Money aMoney) {
+ if (aMoney.isZero()) return;
+ IMoney old = findMoney(aMoney.currency());
+ if (old == null) {
+ fMonies.add(aMoney);
+ return;
+ }
+ fMonies.remove(old);
+ Money sum = (Money) old.add(aMoney);
+ if (sum.isZero()) {
+ return;
+ }
+ fMonies.add(sum);
+ }
+
+ @Override
+ public boolean equals(Object anObject) {
+ if (isZero()) {
+ if (anObject instanceof IMoney) {
+ return ((IMoney) anObject).isZero();
+ }
+ }
+
+ if (anObject instanceof MoneyBag) {
+ MoneyBag aMoneyBag = (MoneyBag) anObject;
+ if (aMoneyBag.fMonies.size() != fMonies.size()) {
+ return false;
+ }
+
+ for (Money each : fMonies) {
+ if (!aMoneyBag.contains(each)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private Money findMoney(String currency) {
+ for (Money each : fMonies) {
+ if (each.currency().equals(currency)) {
+ return each;
+ }
+ }
+ return null;
+ }
+
+ private boolean contains(Money m) {
+ Money found = findMoney(m.currency());
+ if (found == null) return false;
+ return found.amount() == m.amount();
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ for (Money each : fMonies) {
+ hash ^= each.hashCode();
+ }
+ return hash;
+ }
+
+ public boolean isZero() {
+ return fMonies.size() == 0;
+ }
+
+ public IMoney multiply(int factor) {
+ MoneyBag result = new MoneyBag();
+ if (factor != 0) {
+ for (Money each : fMonies) {
+ result.appendMoney((Money) each.multiply(factor));
+ }
+ }
+ return result;
+ }
+
+ public IMoney negate() {
+ MoneyBag result = new MoneyBag();
+ for (Money each : fMonies) {
+ result.appendMoney((Money) each.negate());
+ }
+ return result;
+ }
+
+ private IMoney simplify() {
+ if (fMonies.size() == 1) {
+ return fMonies.iterator().next();
+ }
+ return this;
+ }
+
+ public IMoney subtract(IMoney m) {
+ return add(m.negate());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ for (Money each : fMonies) {
+ sb.append(each);
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ public void appendTo(MoneyBag m) {
+ m.appendBag(this);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyTest.java b/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyTest.java
new file mode 100644
index 0000000..170363a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/money/MoneyTest.java
@@ -0,0 +1,166 @@
+package junit.samples.money;
+
+import junit.framework.TestCase;
+
+public class MoneyTest extends TestCase {
+ private Money f12CHF;
+ private Money f14CHF;
+ private Money f7USD;
+ private Money f21USD;
+
+ private IMoney fMB1;
+ private IMoney fMB2;
+
+ public static void main(String args[]) {
+ junit.textui.TestRunner.run(MoneyTest.class);
+ }
+
+ @Override
+ protected void setUp() {
+ f12CHF = new Money(12, "CHF");
+ f14CHF = new Money(14, "CHF");
+ f7USD = new Money(7, "USD");
+ f21USD = new Money(21, "USD");
+
+ fMB1 = MoneyBag.create(f12CHF, f7USD);
+ fMB2 = MoneyBag.create(f14CHF, f21USD);
+ }
+
+ public void testBagMultiply() {
+ // {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]}
+ IMoney expected = MoneyBag.create(new Money(24, "CHF"), new Money(14, "USD"));
+ assertEquals(expected, fMB1.multiply(2));
+ assertEquals(fMB1, fMB1.multiply(1));
+ assertTrue(fMB1.multiply(0).isZero());
+ }
+
+ public void testBagNegate() {
+ // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]}
+ IMoney expected = MoneyBag.create(new Money(-12, "CHF"), new Money(-7, "USD"));
+ assertEquals(expected, fMB1.negate());
+ }
+
+ public void testBagSimpleAdd() {
+ // {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD"));
+ assertEquals(expected, fMB1.add(f14CHF));
+ }
+
+ public void testBagSubtract() {
+ // {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]}
+ IMoney expected = MoneyBag.create(new Money(-2, "CHF"), new Money(-14, "USD"));
+ assertEquals(expected, fMB1.subtract(fMB2));
+ }
+
+ public void testBagSumAdd() {
+ // {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(28, "USD"));
+ assertEquals(expected, fMB1.add(fMB2));
+ }
+
+ public void testIsZero() {
+ assertTrue(fMB1.subtract(fMB1).isZero());
+ assertTrue(MoneyBag.create(new Money(0, "CHF"), new Money(0, "USD")).isZero());
+ }
+
+ public void testMixedSimpleAdd() {
+ // [12 CHF] + [7 USD] == {[12 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(f12CHF, f7USD);
+ assertEquals(expected, f12CHF.add(f7USD));
+ }
+
+ public void testBagNotEquals() {
+ IMoney bag = MoneyBag.create(f12CHF, f7USD);
+ assertFalse(bag.equals(new Money(12, "DEM").add(f7USD)));
+ }
+
+ public void testMoneyBagEquals() {
+ assertTrue(!fMB1.equals(null));
+
+ assertEquals(fMB1, fMB1);
+ IMoney equal = MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD"));
+ assertTrue(fMB1.equals(equal));
+ assertTrue(!fMB1.equals(f12CHF));
+ assertTrue(!f12CHF.equals(fMB1));
+ assertTrue(!fMB1.equals(fMB2));
+ }
+
+ public void testMoneyBagHash() {
+ IMoney equal = MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD"));
+ assertEquals(fMB1.hashCode(), equal.hashCode());
+ }
+
+ public void testMoneyEquals() {
+ assertTrue(!f12CHF.equals(null));
+ Money equalMoney = new Money(12, "CHF");
+ assertEquals(f12CHF, f12CHF);
+ assertEquals(f12CHF, equalMoney);
+ assertEquals(f12CHF.hashCode(), equalMoney.hashCode());
+ assertTrue(!f12CHF.equals(f14CHF));
+ }
+
+ public void testMoneyHash() {
+ assertTrue(!f12CHF.equals(null));
+ Money equal = new Money(12, "CHF");
+ assertEquals(f12CHF.hashCode(), equal.hashCode());
+ }
+
+ public void testSimplify() {
+ IMoney money = MoneyBag.create(new Money(26, "CHF"), new Money(28, "CHF"));
+ assertEquals(new Money(54, "CHF"), money);
+ }
+
+ public void testNormalize2() {
+ // {[12 CHF][7 USD]} - [12 CHF] == [7 USD]
+ Money expected = new Money(7, "USD");
+ assertEquals(expected, fMB1.subtract(f12CHF));
+ }
+
+ public void testNormalize3() {
+ // {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD]
+ IMoney ms1 = MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD"));
+ Money expected = new Money(4, "USD");
+ assertEquals(expected, fMB1.subtract(ms1));
+ }
+
+ public void testNormalize4() {
+ // [12 CHF] - {[12 CHF][3 USD]} == [-3 USD]
+ IMoney ms1 = MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD"));
+ Money expected = new Money(-3, "USD");
+ assertEquals(expected, f12CHF.subtract(ms1));
+ }
+
+ public void testPrint() {
+ assertEquals("[12 CHF]", f12CHF.toString());
+ }
+
+ public void testSimpleAdd() {
+ // [12 CHF] + [14 CHF] == [26 CHF]
+ Money expected = new Money(26, "CHF");
+ assertEquals(expected, f12CHF.add(f14CHF));
+ }
+
+ public void testSimpleBagAdd() {
+ // [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD"));
+ assertEquals(expected, f14CHF.add(fMB1));
+ }
+
+ public void testSimpleMultiply() {
+ // [14 CHF] *2 == [28 CHF]
+ Money expected = new Money(28, "CHF");
+ assertEquals(expected, f14CHF.multiply(2));
+ }
+
+ public void testSimpleNegate() {
+ // [14 CHF] negate == [-14 CHF]
+ Money expected = new Money(-14, "CHF");
+ assertEquals(expected, f14CHF.negate());
+ }
+
+ public void testSimpleSubtract() {
+ // [14 CHF] - [12 CHF] == [2 CHF]
+ Money expected = new Money(2, "CHF");
+ assertEquals(expected, f14CHF.subtract(f12CHF));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/money/package-info.java b/google3/third_party/java_src/junit/test/java/junit/samples/money/package-info.java
new file mode 100644
index 0000000..eb37dd8
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/money/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Example "Money" for JUnit v3.x.
+ */
+package junit.samples.money;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/samples/package-info.java b/google3/third_party/java_src/junit/test/java/junit/samples/package-info.java
new file mode 100644
index 0000000..7b9ea8f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/samples/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * JUnit v3.x examples.
+ */
+package junit.samples;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/AllTests.java b/google3/third_party/java_src/junit/test/java/junit/tests/AllTests.java
new file mode 100644
index 0000000..8be6e26
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/AllTests.java
@@ -0,0 +1,22 @@
+package junit.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestSuite that runs all the JUnit tests
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Framework Tests");
+ suite.addTest(junit.tests.framework.AllTests.suite());
+ suite.addTest(junit.tests.runner.AllTests.suite());
+ suite.addTest(junit.tests.extensions.AllTests.suite());
+ return suite;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/SampleJUnit3Tests.java b/google3/third_party/java_src/junit/test/java/junit/tests/SampleJUnit3Tests.java
new file mode 100644
index 0000000..46f996b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/SampleJUnit3Tests.java
@@ -0,0 +1,51 @@
+package junit.tests;
+
+import junit.framework.TestCase;
+
+/**
+ * Container for sample JUnit3-style tests used in integration tests.
+ */
+public class SampleJUnit3Tests {
+
+ public static class TestWithOneThrowingTestMethod extends TestCase {
+
+ public void testAlwaysThrows() {
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ }
+ }
+
+ public static class TestWithThrowingSetUpMethod extends TestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ }
+
+ public void testAlwaysPasses() {
+ }
+ }
+
+ private static class FakeClassUnderTest {
+
+ public void throwsExceptionWithCause() {
+ doThrowExceptionWithCause();
+ }
+
+ public void throwsExceptionWithoutCause() {
+ doThrowExceptionWithoutCause();
+ }
+
+ private void doThrowExceptionWithCause() {
+ try {
+ throwsExceptionWithoutCause();
+ } catch (Exception e) {
+ throw new RuntimeException("outer", e);
+ }
+ }
+
+ private void doThrowExceptionWithoutCause() {
+ throw new RuntimeException("cause");
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/WasRun.java b/google3/third_party/java_src/junit/test/java/junit/tests/WasRun.java
new file mode 100644
index 0000000..fb294ca
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/WasRun.java
@@ -0,0 +1,16 @@
+package junit.tests;
+
+import junit.framework.TestCase;
+
+/**
+ * A helper test case for testing whether the testing method
+ * is run.
+ */
+public class WasRun extends TestCase {
+ public boolean fWasRun = false;
+
+ @Override
+ protected void runTest() {
+ fWasRun = true;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ActiveTestTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ActiveTestTest.java
new file mode 100644
index 0000000..5015b76
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ActiveTestTest.java
@@ -0,0 +1,64 @@
+package junit.tests.extensions;
+
+import junit.extensions.ActiveTestSuite;
+import junit.extensions.RepeatedTest;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Testing the ActiveTest support
+ */
+public class ActiveTestTest extends TestCase {
+
+ public static class SuccessTest extends TestCase {
+ @Override
+ public void runTest() {
+ }
+ }
+
+ public void testActiveTest() {
+ Test test = createActiveTestSuite();
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(100, result.runCount());
+ assertEquals(0, result.failureCount());
+ assertEquals(0, result.errorCount());
+ }
+
+ public void testActiveRepeatedTest() {
+ Test test = new RepeatedTest(createActiveTestSuite(), 5);
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(500, result.runCount());
+ assertEquals(0, result.failureCount());
+ assertEquals(0, result.errorCount());
+ }
+
+ public void testActiveRepeatedTest0() {
+ Test test = new RepeatedTest(createActiveTestSuite(), 0);
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(0, result.runCount());
+ assertEquals(0, result.failureCount());
+ assertEquals(0, result.errorCount());
+ }
+
+ public void testActiveRepeatedTest1() {
+ Test test = new RepeatedTest(createActiveTestSuite(), 1);
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(100, result.runCount());
+ assertEquals(0, result.failureCount());
+ assertEquals(0, result.errorCount());
+ }
+
+ ActiveTestSuite createActiveTestSuite() {
+ ActiveTestSuite suite = new ActiveTestSuite();
+ for (int i = 0; i < 100; i++) {
+ suite.addTest(new SuccessTest());
+ }
+ return suite;
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/extensions/AllTests.java b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/AllTests.java
new file mode 100644
index 0000000..1cbcfa5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/AllTests.java
@@ -0,0 +1,22 @@
+package junit.tests.extensions;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestSuite that runs all the extension tests
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() { // Collect tests manually because we have to test class collection code
+ TestSuite suite = new TestSuite("Framework Tests");
+ suite.addTestSuite(ExtensionTest.class);
+ suite.addTestSuite(ActiveTestTest.class);
+ suite.addTestSuite(RepeatedTestTest.class);
+ return suite;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ExtensionTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ExtensionTest.java
new file mode 100644
index 0000000..155a478
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/ExtensionTest.java
@@ -0,0 +1,104 @@
+package junit.tests.extensions;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.tests.WasRun;
+
+/**
+ * A test case testing the extensions to the testing framework.
+ */
+public class ExtensionTest extends TestCase {
+ static class TornDown extends TestSetup {
+ boolean fTornDown = false;
+
+ TornDown(Test test) {
+ super(test);
+ }
+
+ @Override
+ protected void tearDown() {
+ fTornDown = true;
+ }
+ }
+
+ public void testRunningErrorInTestSetup() {
+ TestCase test = new TestCase("failure") {
+ @Override
+ public void runTest() {
+ fail();
+ }
+ };
+
+ TestSetup wrapper = new TestSetup(test);
+
+ TestResult result = new TestResult();
+ wrapper.run(result);
+ assertTrue(!result.wasSuccessful());
+ }
+
+ public void testRunningErrorsInTestSetup() {
+ TestCase failure = new TestCase("failure") {
+ @Override
+ public void runTest() {
+ fail();
+ }
+ };
+
+ TestCase error = new TestCase("error") {
+ @Override
+ public void runTest() {
+ throw new Error();
+ }
+ };
+
+ TestSuite suite = new TestSuite();
+ suite.addTest(failure);
+ suite.addTest(error);
+
+ TestSetup wrapper = new TestSetup(suite);
+
+ TestResult result = new TestResult();
+ wrapper.run(result);
+
+ assertEquals(1, result.failureCount());
+ assertEquals(1, result.errorCount());
+ }
+
+ public void testSetupErrorDontTearDown() {
+ WasRun test = new WasRun();
+
+ TornDown wrapper = new TornDown(test) {
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setUp() {
+ fail();
+ }
+ };
+
+ TestResult result = new TestResult();
+ wrapper.run(result);
+
+ assertTrue(!wrapper.fTornDown);
+ }
+
+ public void testSetupErrorInTestSetup() {
+ WasRun test = new WasRun();
+
+ TestSetup wrapper = new TestSetup(test) {
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setUp() {
+ fail();
+ }
+ };
+
+ TestResult result = new TestResult();
+ wrapper.run(result);
+
+ assertTrue(!test.fWasRun);
+ assertTrue(!result.wasSuccessful());
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/extensions/RepeatedTestTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/RepeatedTestTest.java
new file mode 100644
index 0000000..0ba7366
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/RepeatedTestTest.java
@@ -0,0 +1,62 @@
+package junit.tests.extensions;
+
+import junit.extensions.RepeatedTest;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/**
+ * Testing the RepeatedTest support.
+ */
+public class RepeatedTestTest extends TestCase {
+ private TestSuite fSuite;
+
+ public static class SuccessTest extends TestCase {
+
+ @Override
+ public void runTest() {
+ }
+ }
+
+ public RepeatedTestTest(String name) {
+ super(name);
+ fSuite = new TestSuite();
+ fSuite.addTest(new SuccessTest());
+ fSuite.addTest(new SuccessTest());
+ }
+
+ public void testRepeatedOnce() {
+ Test test = new RepeatedTest(fSuite, 1);
+ assertEquals(2, test.countTestCases());
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(2, result.runCount());
+ }
+
+ public void testRepeatedMoreThanOnce() {
+ Test test = new RepeatedTest(fSuite, 3);
+ assertEquals(6, test.countTestCases());
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(6, result.runCount());
+ }
+
+ public void testRepeatedZero() {
+ Test test = new RepeatedTest(fSuite, 0);
+ assertEquals(0, test.countTestCases());
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(0, result.runCount());
+ }
+
+ public void testRepeatedNegative() {
+ try {
+ new RepeatedTest(fSuite, -1);
+ } catch (IllegalArgumentException e) {
+ assertTrue(e.getMessage().contains(">="));
+ return;
+ }
+ fail("Should throw an IllegalArgumentException");
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/extensions/package-info.java b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/package-info.java
new file mode 100644
index 0000000..acc0194
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/extensions/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Tests for the JUnit v3.x extension functionality.
+ */
+package junit.tests.extensions;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/AllTests.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AllTests.java
new file mode 100644
index 0000000..860ddca
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AllTests.java
@@ -0,0 +1,31 @@
+package junit.tests.framework;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestSuite that runs all the sample tests
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Framework Tests");
+ suite.addTestSuite(TestCaseTest.class);
+ suite.addTest(SuiteTest.suite()); // Tests suite building, so can't use automatic test extraction
+ suite.addTestSuite(TestListenerTest.class);
+ suite.addTestSuite(AssertionFailedErrorTest.class);
+ suite.addTestSuite(AssertTest.class);
+ suite.addTestSuite(TestImplementorTest.class);
+ suite.addTestSuite(NoArgTestCaseTest.class);
+ suite.addTestSuite(ComparisonCompactorTest.class);
+ suite.addTestSuite(ComparisonFailureTest.class);
+ suite.addTestSuite(DoublePrecisionAssertTest.class);
+ suite.addTestSuite(FloatAssertTest.class);
+ return suite;
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertTest.java
new file mode 100644
index 0000000..19cca63
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertTest.java
@@ -0,0 +1,171 @@
+package junit.tests.framework;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.ComparisonFailure;
+import junit.framework.TestCase;
+
+public class AssertTest extends TestCase {
+
+ /* In the tests that follow, we can't use standard formatting
+ * for exception tests:
+ * try {
+ * somethingThatShouldThrow();
+ * fail();
+ * catch (AssertionFailedError e) {
+ * }
+ * because fail() would never be reported.
+ */
+ public void testFail() {
+ // Also, we are testing fail, so we can't rely on fail() working.
+ // We have to throw the exception manually.
+ try {
+ fail();
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ throw new AssertionFailedError();
+ }
+
+ public void testAssertionFailedErrorToStringWithNoMessage() {
+ // Also, we are testing fail, so we can't rely on fail() working.
+ // We have to throw the exception manually.
+ try {
+ fail();
+ } catch (AssertionFailedError e) {
+ assertEquals("junit.framework.AssertionFailedError", e.toString());
+ return;
+ }
+ throw new AssertionFailedError();
+ }
+
+ public void testAssertionFailedErrorToStringWithMessage() {
+ // Also, we are testing fail, so we can't rely on fail() working.
+ // We have to throw the exception manually.
+ try {
+ fail("woops!");
+ } catch (AssertionFailedError e) {
+ assertEquals("junit.framework.AssertionFailedError: woops!", e.toString());
+ return;
+ }
+ throw new AssertionFailedError();
+ }
+
+ public void testAssertEquals() {
+ Object o = new Object();
+ assertEquals(o, o);
+ try {
+ assertEquals(new Object(), new Object());
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertEqualsNull() {
+ assertEquals((Object) null, (Object) null);
+ }
+
+ public void testAssertStringEquals() {
+ assertEquals("a", "a");
+ }
+
+ public void testAssertNullNotEqualsString() {
+ try {
+ assertEquals(null, "foo");
+ fail();
+ } catch (ComparisonFailure e) {
+ }
+ }
+
+ public void testAssertStringNotEqualsNull() {
+ try {
+ assertEquals("foo", null);
+ fail();
+ } catch (ComparisonFailure e) {
+ e.getMessage(); // why no assertion?
+ }
+ }
+
+ public void testAssertNullNotEqualsNull() {
+ try {
+ assertEquals(null, new Object());
+ } catch (AssertionFailedError e) {
+ e.getMessage(); // why no assertion?
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNull() {
+ assertNull(null);
+ try {
+ assertNull(new Object());
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNotNull() {
+ assertNotNull(new Object());
+ try {
+ assertNotNull(null);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertTrue() {
+ assertTrue(true);
+ try {
+ assertTrue(false);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertFalse() {
+ assertFalse(false);
+ try {
+ assertFalse(true);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertSame() {
+ Object o = new Object();
+ assertSame(o, o);
+ try {
+ assertSame(new Integer(1), new Integer(1));
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNotSame() {
+ assertNotSame(new Integer(1), null);
+ assertNotSame(null, new Integer(1));
+ assertNotSame(new Integer(1), new Integer(1));
+ try {
+ Integer obj = new Integer(1);
+ assertNotSame(obj, obj);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNotSameFailsNull() {
+ try {
+ assertNotSame(null, null);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertionFailedErrorTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertionFailedErrorTest.java
new file mode 100644
index 0000000..16328b4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/AssertionFailedErrorTest.java
@@ -0,0 +1,23 @@
+package junit.tests.framework;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+public class AssertionFailedErrorTest extends TestCase {
+ private static final String ARBITRARY_MESSAGE = "arbitrary message";
+
+ public void testCreateErrorWithoutMessage() throws Exception {
+ AssertionFailedError error = new AssertionFailedError();
+ assertNull(error.getMessage());
+ }
+
+ public void testCreateErrorWithMessage() throws Exception {
+ AssertionFailedError error = new AssertionFailedError(ARBITRARY_MESSAGE);
+ assertEquals(ARBITRARY_MESSAGE, error.getMessage());
+ }
+
+ public void testCreateErrorWithoutMessageInsteadOfNull() throws Exception {
+ AssertionFailedError error = new AssertionFailedError(null);
+ assertEquals("", error.getMessage());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonCompactorTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonCompactorTest.java
new file mode 100644
index 0000000..16e0b4e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonCompactorTest.java
@@ -0,0 +1,102 @@
+package junit.tests.framework;
+
+import junit.framework.ComparisonCompactor;
+import junit.framework.TestCase;
+
+public class ComparisonCompactorTest extends TestCase {
+
+ public void testMessage() {
+ String failure = new ComparisonCompactor(0, "b", "c").compact("a");
+ assertTrue("a expected:<[b]> but was:<[c]>".equals(failure));
+ }
+
+ public void testStartSame() {
+ String failure = new ComparisonCompactor(1, "ba", "bc").compact(null);
+ assertEquals("expected:<b[a]> but was:<b[c]>", failure);
+ }
+
+ public void testEndSame() {
+ String failure = new ComparisonCompactor(1, "ab", "cb").compact(null);
+ assertEquals("expected:<[a]b> but was:<[c]b>", failure);
+ }
+
+ public void testSame() {
+ String failure = new ComparisonCompactor(1, "ab", "ab").compact(null);
+ assertEquals("expected:<ab> but was:<ab>", failure);
+ }
+
+ public void testNoContextStartAndEndSame() {
+ String failure = new ComparisonCompactor(0, "abc", "adc").compact(null);
+ assertEquals("expected:<...[b]...> but was:<...[d]...>", failure);
+ }
+
+ public void testStartAndEndContext() {
+ String failure = new ComparisonCompactor(1, "abc", "adc").compact(null);
+ assertEquals("expected:<a[b]c> but was:<a[d]c>", failure);
+ }
+
+ public void testStartAndEndContextWithEllipses() {
+ String failure = new ComparisonCompactor(1, "abcde", "abfde").compact(null);
+ assertEquals("expected:<...b[c]d...> but was:<...b[f]d...>", failure);
+ }
+
+ public void testComparisonErrorStartSameComplete() {
+ String failure = new ComparisonCompactor(2, "ab", "abc").compact(null);
+ assertEquals("expected:<ab[]> but was:<ab[c]>", failure);
+ }
+
+ public void testComparisonErrorEndSameComplete() {
+ String failure = new ComparisonCompactor(0, "bc", "abc").compact(null);
+ assertEquals("expected:<[]...> but was:<[a]...>", failure);
+ }
+
+ public void testComparisonErrorEndSameCompleteContext() {
+ String failure = new ComparisonCompactor(2, "bc", "abc").compact(null);
+ assertEquals("expected:<[]bc> but was:<[a]bc>", failure);
+ }
+
+ public void testComparisonErrorOverlappingMatches() {
+ String failure = new ComparisonCompactor(0, "abc", "abbc").compact(null);
+ assertEquals("expected:<...[]...> but was:<...[b]...>", failure);
+ }
+
+ public void testComparisonErrorOverlappingMatchesContext() {
+ String failure = new ComparisonCompactor(2, "abc", "abbc").compact(null);
+ assertEquals("expected:<ab[]c> but was:<ab[b]c>", failure);
+ }
+
+ public void testComparisonErrorOverlappingMatches2() {
+ String failure = new ComparisonCompactor(0, "abcdde", "abcde").compact(null);
+ assertEquals("expected:<...[d]...> but was:<...[]...>", failure);
+ }
+
+ public void testComparisonErrorOverlappingMatches2Context() {
+ String failure = new ComparisonCompactor(2, "abcdde", "abcde").compact(null);
+ assertEquals("expected:<...cd[d]e> but was:<...cd[]e>", failure);
+ }
+
+ public void testComparisonErrorWithActualNull() {
+ String failure = new ComparisonCompactor(0, "a", null).compact(null);
+ assertEquals("expected:<a> but was:<null>", failure);
+ }
+
+ public void testComparisonErrorWithActualNullContext() {
+ String failure = new ComparisonCompactor(2, "a", null).compact(null);
+ assertEquals("expected:<a> but was:<null>", failure);
+ }
+
+ public void testComparisonErrorWithExpectedNull() {
+ String failure = new ComparisonCompactor(0, null, "a").compact(null);
+ assertEquals("expected:<null> but was:<a>", failure);
+ }
+
+ public void testComparisonErrorWithExpectedNullContext() {
+ String failure = new ComparisonCompactor(2, null, "a").compact(null);
+ assertEquals("expected:<null> but was:<a>", failure);
+ }
+
+ public void testBug609972() {
+ String failure = new ComparisonCompactor(10, "S&P500", "0").compact(null);
+ assertEquals("expected:<[S&P50]0> but was:<[]0>", failure);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonFailureTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonFailureTest.java
new file mode 100644
index 0000000..284b7f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ComparisonFailureTest.java
@@ -0,0 +1,47 @@
+package junit.tests.framework;
+
+import junit.framework.ComparisonFailure;
+import junit.framework.TestCase;
+
+public class ComparisonFailureTest extends TestCase {
+
+ // Most of the tests are in ComparisonCompactorTest
+ public void testConnection() {
+ ComparisonFailure failure = new ComparisonFailure("warning", "Mary had a little lamb", "Mary had the little lamb");
+ assertEquals("warning expected:<Mary had [a] little lamb> but was:<Mary had [the] little lamb>", failure.getMessage());
+ }
+
+ // This is like an instanceof test.
+ public void testThrowing() {
+ try {
+ assertEquals("a", "b");
+ } catch (ComparisonFailure e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testExceptionToStringWithMessage() {
+ try {
+ assertEquals("woops!", "a", "b");
+ } catch (ComparisonFailure e) {
+ if (!e.toString().startsWith("junit.framework.ComparisonFailure: woops! expected:<")) {
+ fail("Unexpected message: " + e);
+ }
+ return;
+ }
+ fail();
+ }
+
+ public void testExceptionToStringWithoutMessage() {
+ try {
+ assertEquals("a", "b");
+ } catch (ComparisonFailure e) {
+ if (!e.toString().startsWith("junit.framework.ComparisonFailure: expected:<")) {
+ fail("Unexpected message: " + e);
+ }
+ return;
+ }
+ fail();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/DoublePrecisionAssertTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/DoublePrecisionAssertTest.java
new file mode 100644
index 0000000..f416109
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/DoublePrecisionAssertTest.java
@@ -0,0 +1,59 @@
+package junit.tests.framework;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+public class DoublePrecisionAssertTest extends TestCase {
+
+ /**
+ * Test for the special Double.NaN value.
+ */
+ public void testAssertEqualsNaNFails() {
+ try {
+ assertEquals(1.234, Double.NaN, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNaNEqualsFails() {
+ try {
+ assertEquals(Double.NaN, 1.234, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNaNEqualsNaN() {
+ assertEquals(Double.NaN, Double.NaN, 0.0);
+ }
+
+ public void testAssertPosInfinityNotEqualsNegInfinity() {
+ try {
+ assertEquals(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertPosInfinityNotEquals() {
+ try {
+ assertEquals(Double.POSITIVE_INFINITY, 1.23, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertPosInfinityEqualsInfinity() {
+ assertEquals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, 0.0);
+ }
+
+ public void testAssertNegInfinityEqualsInfinity() {
+ assertEquals(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/Failure.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/Failure.java
new file mode 100644
index 0000000..00267df
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/Failure.java
@@ -0,0 +1,13 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * A test case testing the testing framework.
+ */
+public class Failure extends TestCase {
+ @Override
+ public void runTest() {
+ fail();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/FloatAssertTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/FloatAssertTest.java
new file mode 100644
index 0000000..aeae944
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/FloatAssertTest.java
@@ -0,0 +1,63 @@
+package junit.tests.framework;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+public class FloatAssertTest extends TestCase {
+
+ /**
+ * Test for the special Double.NaN value.
+ */
+ public void testAssertEqualsNaNFails() {
+ try {
+ assertEquals(1.234f, Float.NaN, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNaNEqualsFails() {
+ try {
+ assertEquals(Float.NaN, 1.234f, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertNaNEqualsNaN() {
+ assertEquals(Float.NaN, Float.NaN, 0.0);
+ }
+
+ public void testAssertPosInfinityNotEqualsNegInfinity() {
+ try {
+ assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertPosInfinityNotEquals() {
+ try {
+ assertEquals(Float.POSITIVE_INFINITY, 1.23f, 0.0);
+ } catch (AssertionFailedError e) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertPosInfinityEqualsInfinity() {
+ assertEquals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, 0.0);
+ }
+
+ public void testAssertNegInfinityEqualsInfinity() {
+ assertEquals(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0);
+ }
+
+ public void testAllInfinities() {
+ assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/InheritedTestCase.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/InheritedTestCase.java
new file mode 100644
index 0000000..f264e4e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/InheritedTestCase.java
@@ -0,0 +1,9 @@
+package junit.tests.framework;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class InheritedTestCase extends OneTestCase {
+ public void test2() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoArgTestCaseTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoArgTestCaseTest.java
new file mode 100644
index 0000000..65d1bb5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoArgTestCaseTest.java
@@ -0,0 +1,8 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+public class NoArgTestCaseTest extends TestCase {
+ public void testNothing() { // If this compiles, the no arg ctor is there
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCaseClass.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCaseClass.java
new file mode 100644
index 0000000..f92adef
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCaseClass.java
@@ -0,0 +1,9 @@
+package junit.tests.framework;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class NoTestCaseClass extends Object {
+ public void testSuccess() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCases.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCases.java
new file mode 100644
index 0000000..61abfd3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NoTestCases.java
@@ -0,0 +1,11 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class NoTestCases extends TestCase {
+ public void noTestCase() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotPublicTestCase.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotPublicTestCase.java
new file mode 100644
index 0000000..d95aa91
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotPublicTestCase.java
@@ -0,0 +1,14 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class NotPublicTestCase extends TestCase {
+ protected void testNotPublic() {
+ }
+
+ public void testPublic() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotVoidTestCase.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotVoidTestCase.java
new file mode 100644
index 0000000..e087a22
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/NotVoidTestCase.java
@@ -0,0 +1,15 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class NotVoidTestCase extends TestCase {
+ public int testNotVoid() {
+ return 1;
+ }
+
+ public void testVoid() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/OneTestCase.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/OneTestCase.java
new file mode 100644
index 0000000..b54b7f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/OneTestCase.java
@@ -0,0 +1,17 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class OneTestCase extends TestCase {
+ public void noTestCase() {
+ }
+
+ public void testCase() {
+ }
+
+ public void testCase(int arg) {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/OverrideTestCase.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/OverrideTestCase.java
new file mode 100644
index 0000000..a9b665d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/OverrideTestCase.java
@@ -0,0 +1,10 @@
+package junit.tests.framework;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class OverrideTestCase extends OneTestCase {
+ @Override
+ public void testCase() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/Success.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/Success.java
new file mode 100644
index 0000000..510468f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/Success.java
@@ -0,0 +1,16 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * A test case testing the testing framework.
+ */
+public class Success extends TestCase {
+
+ @Override
+ public void runTest() {
+ }
+
+ public void testSuccess() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/SuiteTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/SuiteTest.java
new file mode 100644
index 0000000..9854548
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/SuiteTest.java
@@ -0,0 +1,118 @@
+package junit.tests.framework;
+
+import java.util.Collections;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/**
+ * A fixture for testing the "auto" test suite feature.
+ */
+public class SuiteTest extends TestCase {
+ protected TestResult fResult;
+
+ public SuiteTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() {
+ fResult = new TestResult();
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Suite Tests");
+ // build the suite manually, because some of the suites are testing
+ // the functionality that automatically builds suites
+ suite.addTest(new SuiteTest("testNoTestCases"));
+ suite.addTest(new SuiteTest("testOneTestCase"));
+ suite.addTest(new SuiteTest("testNotPublicTestCase"));
+ suite.addTest(new SuiteTest("testNotVoidTestCase"));
+ suite.addTest(new SuiteTest("testNotExistingTestCase"));
+ suite.addTest(new SuiteTest("testInheritedTests"));
+ suite.addTest(new SuiteTest("testOneTestCaseEclipseSeesSameStructureAs381"));
+ suite.addTest(new SuiteTest("testNoTestCaseClass"));
+ suite.addTest(new SuiteTest("testShadowedTests"));
+ suite.addTest(new SuiteTest("testAddTestSuite"));
+ suite.addTest(new SuiteTest("testCreateSuiteFromArray"));
+
+ return suite;
+ }
+
+ public void testInheritedTests() {
+ TestSuite suite = new TestSuite(InheritedTestCase.class);
+ suite.run(fResult);
+ assertTrue(fResult.wasSuccessful());
+ assertEquals(2, fResult.runCount());
+ }
+
+ public void testNoTestCaseClass() {
+ Test t = new TestSuite(NoTestCaseClass.class);
+ t.run(fResult);
+ assertEquals(1, fResult.runCount()); // warning test
+ assertTrue(!fResult.wasSuccessful());
+ }
+
+ public void testNoTestCases() {
+ Test t = new TestSuite(NoTestCases.class);
+ t.run(fResult);
+ assertTrue(fResult.runCount() == 1); // warning test
+ assertTrue(fResult.failureCount() == 1);
+ assertTrue(!fResult.wasSuccessful());
+ }
+
+ public void testNotExistingTestCase() {
+ Test t = new SuiteTest("notExistingMethod");
+ t.run(fResult);
+ assertTrue(fResult.runCount() == 1);
+ assertTrue(fResult.failureCount() == 1);
+ assertTrue(fResult.errorCount() == 0);
+ }
+
+ public void testNotPublicTestCase() {
+ TestSuite suite = new TestSuite(NotPublicTestCase.class);
+ // 1 public test case + 1 warning for the non-public test case
+ assertEquals(2, suite.countTestCases());
+ }
+
+ public void testNotVoidTestCase() {
+ TestSuite suite = new TestSuite(NotVoidTestCase.class);
+ assertTrue(suite.countTestCases() == 1);
+ }
+
+ public void testOneTestCase() {
+ TestSuite t = new TestSuite(OneTestCase.class);
+ t.run(fResult);
+ assertTrue(fResult.runCount() == 1);
+ assertTrue(fResult.failureCount() == 0);
+ assertTrue(fResult.errorCount() == 0);
+ assertTrue(fResult.wasSuccessful());
+ }
+
+ public void testOneTestCaseEclipseSeesSameStructureAs381() {
+ TestSuite t = new TestSuite(ThreeTestCases.class);
+ assertEquals(3, Collections.list(t.tests()).size());
+ }
+
+ public void testShadowedTests() {
+ TestSuite suite = new TestSuite(OverrideTestCase.class);
+ suite.run(fResult);
+ assertEquals(1, fResult.runCount());
+ }
+
+ public void testAddTestSuite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(OneTestCase.class);
+ suite.run(fResult);
+ assertEquals(1, fResult.runCount());
+ }
+
+ public void testCreateSuiteFromArray() {
+ TestSuite suite = new TestSuite(OneTestCase.class, DoublePrecisionAssertTest.class);
+ assertEquals(2, suite.testCount());
+ assertEquals("junit.tests.framework.DoublePrecisionAssertTest", ((TestSuite) suite.testAt(1)).getName());
+ assertEquals("junit.tests.framework.OneTestCase", ((TestSuite) suite.testAt(0)).getName());
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestCaseTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestCaseTest.java
new file mode 100644
index 0000000..5c10052
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestCaseTest.java
@@ -0,0 +1,205 @@
+package junit.tests.framework;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.tests.WasRun;
+
+/**
+ * A test case testing the testing framework.
+ */
+public class TestCaseTest extends TestCase {
+
+ static class TornDown extends TestCase {
+ boolean fTornDown = false;
+
+ @Override
+ protected void tearDown() {
+ fTornDown = true;
+ }
+
+ @Override
+ protected void runTest() {
+ throw new Error("running");
+ }
+ }
+
+ public void testCaseToString() {
+ // This test wins the award for twisted snake tail eating while
+ // writing self tests. And you thought those weird anonymous
+ // inner classes were bad...
+ assertEquals("testCaseToString(junit.tests.framework.TestCaseTest)", toString());
+ }
+
+ public void testError() {
+ TestCase error = new TestCase("error") {
+ @Override
+ protected void runTest() {
+ throw new Error();
+ }
+ };
+ verifyError(error);
+ }
+
+ public void testRunAndTearDownFails() {
+ TornDown fails = new TornDown() {
+ @Override
+ protected void tearDown() {
+ super.tearDown();
+ throw new Error();
+ }
+
+ @Override
+ protected void runTest() {
+ throw new Error();
+ }
+ };
+ verifyError(fails);
+ assertTrue(fails.fTornDown);
+ }
+
+ public void testSetupFails() {
+ TestCase fails = new TestCase("success") {
+ @Override
+ protected void setUp() {
+ throw new Error();
+ }
+
+ @Override
+ protected void runTest() {
+ }
+ };
+ verifyError(fails);
+ }
+
+ public void testSuccess() {
+ TestCase success = new TestCase("success") {
+ @Override
+ protected void runTest() {
+ }
+ };
+ verifySuccess(success);
+ }
+
+ public void testFailure() {
+ TestCase failure = new TestCase("failure") {
+ @Override
+ protected void runTest() {
+ fail();
+ }
+ };
+ verifyFailure(failure);
+ }
+
+ public void testTearDownAfterError() {
+ TornDown fails = new TornDown();
+ verifyError(fails);
+ assertTrue(fails.fTornDown);
+ }
+
+ public void testTearDownFails() {
+ TestCase fails = new TestCase("success") {
+ @Override
+ protected void tearDown() {
+ throw new Error();
+ }
+
+ @Override
+ protected void runTest() {
+ }
+ };
+ verifyError(fails);
+ }
+
+ public void testTearDownSetupFails() {
+ TornDown fails = new TornDown() {
+ @Override
+ protected void setUp() {
+ throw new Error();
+ }
+ };
+ verifyError(fails);
+ assertTrue(!fails.fTornDown);
+ }
+
+ public void testWasRun() {
+ WasRun test = new WasRun();
+ test.run();
+ assertTrue(test.fWasRun);
+ }
+
+ public void testExceptionRunningAndTearDown() {
+ // With 1.4, we should
+ // wrap the exception thrown while running with the exception thrown
+ // while tearing down
+ Test t = new TornDown() {
+ @Override
+ public void tearDown() {
+ throw new Error("tearingDown");
+ }
+ };
+ TestResult result = new TestResult();
+ t.run(result);
+ TestFailure failure = result.errors().nextElement();
+ assertEquals("running", failure.thrownException().getMessage());
+ }
+
+ public void testErrorTearingDownDoesntMaskErrorRunning() {
+ final Exception running = new Exception("Running");
+ TestCase t = new TestCase() {
+ @Override
+ protected void runTest() throws Throwable {
+ throw running;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ throw new Error("Tearing down");
+ }
+ };
+ try {
+ t.runBare();
+ } catch (Throwable thrown) {
+ assertSame(running, thrown);
+ }
+ }
+
+ public void testNoArgTestCasePasses() {
+ Test t = new TestSuite(NoArgTestCaseTest.class);
+ TestResult result = new TestResult();
+ t.run(result);
+ assertTrue(result.runCount() == 1);
+ assertTrue(result.failureCount() == 0);
+ assertTrue(result.errorCount() == 0);
+ }
+
+ public void testNamelessTestCase() {
+ TestCase t = new TestCase() {
+ };
+ TestResult result = t.run();
+ assertEquals(1, result.failureCount());
+ }
+
+ void verifyError(TestCase test) {
+ TestResult result = test.run();
+ assertTrue(result.runCount() == 1);
+ assertTrue(result.failureCount() == 0);
+ assertTrue(result.errorCount() == 1);
+ }
+
+ void verifyFailure(TestCase test) {
+ TestResult result = test.run();
+ assertTrue(result.runCount() == 1);
+ assertTrue(result.failureCount() == 1);
+ assertTrue(result.errorCount() == 0);
+ }
+
+ void verifySuccess(TestCase test) {
+ TestResult result = test.run();
+ assertTrue(result.runCount() == 1);
+ assertTrue(result.failureCount() == 0);
+ assertTrue(result.errorCount() == 0);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestImplementorTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestImplementorTest.java
new file mode 100644
index 0000000..73ec5f8
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestImplementorTest.java
@@ -0,0 +1,54 @@
+package junit.tests.framework;
+
+import junit.framework.Protectable;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * Test an implementor of junit.framework.Test other than TestCase or TestSuite
+ */
+public class TestImplementorTest extends TestCase {
+ public static class DoubleTestCase implements Test {
+ private TestCase fTestCase;
+
+ public DoubleTestCase(TestCase testCase) {
+ fTestCase = testCase;
+ }
+
+ public int countTestCases() {
+ return 2;
+ }
+
+ public void run(TestResult result) {
+ result.startTest(this);
+ Protectable p = new Protectable() {
+ public void protect() throws Throwable {
+ fTestCase.runBare();
+ fTestCase.runBare();
+ }
+ };
+ result.runProtected(this, p);
+ result.endTest(this);
+ }
+ }
+
+ private DoubleTestCase fTest;
+
+ public TestImplementorTest() {
+ TestCase testCase = new TestCase() {
+ @Override
+ public void runTest() {
+ }
+ };
+ fTest = new DoubleTestCase(testCase);
+ }
+
+ public void testSuccessfulRun() {
+ TestResult result = new TestResult();
+ fTest.run(result);
+ assertEquals(fTest.countTestCases(), result.runCount());
+ assertEquals(0, result.errorCount());
+ assertEquals(0, result.failureCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestListenerTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestListenerTest.java
new file mode 100644
index 0000000..d59ba26
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/TestListenerTest.java
@@ -0,0 +1,80 @@
+package junit.tests.framework;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class TestListenerTest extends TestCase implements TestListener {
+ private TestResult fResult;
+ private int fStartCount;
+ private int fEndCount;
+ private int fFailureCount;
+ private int fErrorCount;
+
+ public void addError(Test test, Throwable e) {
+ fErrorCount++;
+ }
+
+ public void addFailure(Test test, AssertionFailedError t) {
+ fFailureCount++;
+ }
+
+ public void endTest(Test test) {
+ fEndCount++;
+ }
+
+ @Override
+ protected void setUp() {
+ fResult = new TestResult();
+ fResult.addListener(this);
+
+ fStartCount = 0;
+ fEndCount = 0;
+ fFailureCount = 0;
+ fErrorCount = 0;
+ }
+
+ public void startTest(Test test) {
+ fStartCount++;
+ }
+
+ public void testError() {
+ TestCase test = new TestCase("noop") {
+ @Override
+ public void runTest() {
+ throw new Error();
+ }
+ };
+ test.run(fResult);
+ assertEquals(1, fErrorCount);
+ assertEquals(1, fEndCount);
+ }
+
+ public void testFailure() {
+ TestCase test = new TestCase("noop") {
+ @Override
+ public void runTest() {
+ fail();
+ }
+ };
+ test.run(fResult);
+ assertEquals(1, fFailureCount);
+ assertEquals(1, fEndCount);
+ }
+
+ public void testStartStop() {
+ TestCase test = new TestCase("noop") {
+ @Override
+ public void runTest() {
+ }
+ };
+ test.run(fResult);
+ assertEquals(1, fStartCount);
+ assertEquals(1, fEndCount);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/ThreeTestCases.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ThreeTestCases.java
new file mode 100644
index 0000000..c66b0db
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/ThreeTestCases.java
@@ -0,0 +1,17 @@
+package junit.tests.framework;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class used in SuiteTest
+ */
+public class ThreeTestCases extends TestCase {
+ public void testCase() {
+ }
+
+ public void testCase2() {
+ }
+
+ public void testCase3thisTimeItsPersonal() {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/framework/package-info.java b/google3/third_party/java_src/junit/test/java/junit/tests/framework/package-info.java
new file mode 100644
index 0000000..9cc0024
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/framework/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Tests the JUnit v3.x core classes.
+ */
+package junit.tests.framework;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/package-info.java b/google3/third_party/java_src/junit/test/java/junit/tests/package-info.java
new file mode 100644
index 0000000..d23121b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Tests the JUnit v3.x framework.
+ */
+package junit.tests;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/AllTests.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/AllTests.java
new file mode 100644
index 0000000..63f2a6f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/AllTests.java
@@ -0,0 +1,30 @@
+package junit.tests.runner;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestSuite that runs all the sample tests
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() { // Collect tests manually because we have to test class collection code
+ TestSuite suite = new TestSuite("Framework Tests");
+ suite.addTestSuite(StackFilterTest.class);
+ suite.addTestSuite(ResultTest.class);
+ suite.addTestSuite(BaseTestRunnerTest.class);
+ suite.addTestSuite(TextFeedbackTest.class);
+ suite.addTestSuite(TextRunnerSingleMethodTest.class);
+ suite.addTestSuite(TextRunnerTest.class);
+ return suite;
+ }
+
+ static boolean isJDK11() {
+ String version = System.getProperty("java.version");
+ return version.startsWith("1.1");
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/BaseTestRunnerTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/BaseTestRunnerTest.java
new file mode 100644
index 0000000..ea38bea
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/BaseTestRunnerTest.java
@@ -0,0 +1,52 @@
+package junit.tests.runner;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+
+public class BaseTestRunnerTest extends TestCase {
+ public static class MockRunner extends BaseTestRunner {
+ private boolean fRunFailed = false;
+
+ @Override
+ protected void runFailed(String message) {
+ fRunFailed = true;
+ }
+
+ @Override
+ public void testEnded(String testName) {
+ }
+
+ @Override
+ public void testFailed(int status, Test test, Throwable e) {
+ }
+
+ @Override
+ public void testStarted(String testName) {
+ }
+ }
+
+ public static class NonStatic {
+ public Test suite() {
+ return null;
+ }
+ }
+
+ public void testInvokeNonStaticSuite() {
+ BaseTestRunner runner = new MockRunner();
+ runner.getTest("junit.tests.runner.BaseTestRunnerTest$NonStatic"); // Used to throw NullPointerException
+ }
+
+ public static class DoesntExtendTestCase {
+ public static Test suite() {
+ return new TestSuite();
+ }
+ }
+
+ public void testInvokeSuiteOnNonSubclassOfTestCase() {
+ MockRunner runner = new MockRunner();
+ runner.getTest(DoesntExtendTestCase.class.getName());
+ assertFalse(runner.fRunFailed);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/ResultTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/ResultTest.java
new file mode 100644
index 0000000..8cd7ac2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/ResultTest.java
@@ -0,0 +1,189 @@
+package junit.tests.runner;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.tests.framework.Success;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.tests.running.methods.AnnotationTest;
+
+public class ResultTest extends TestCase {
+
+ private Result fromStream;
+
+ public void testRunFailureResultCanBeSerialised() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(AnnotationTest.FailureTest.class);
+ assertResultSerializable(result);
+ }
+
+ public void testRunFailureResultCanBeReserialised_v4_12() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(AnnotationTest.FailureTest.class);
+ assertResultReserializable(result, SerializationFormat.V4_12);
+ }
+
+ public void testRunAssumptionFailedResultCanBeSerialised() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(AssumptionFailedTest.class);
+ assertResultSerializable(result);
+ }
+
+ public void testRunAssumptionFailedResultCanBeReserialised_v4_12() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(AssumptionFailedTest.class);
+ assertResultReserializable(result, SerializationFormat.V4_12);
+ }
+
+ public void testRunAssumptionFailedResultCanBeReserialised_v4_13() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(AssumptionFailedTest.class);
+ assertResultReserializable(result, SerializationFormat.V4_13);
+ }
+
+ public void testRunSuccessResultCanBeSerialised() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(Success.class);
+ assertResultSerializable(result);
+ }
+
+ public void testRunSuccessResultCanBeReserialised_v4_12() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(Success.class);
+ assertResultReserializable(result, SerializationFormat.V4_12);
+ }
+
+ public void testRunSuccessResultCanBeReserialised_v4_13() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(Success.class);
+ assertResultReserializable(result, SerializationFormat.V4_13);
+ }
+
+ private enum SerializationFormat {
+ V4_12,
+ V4_13
+ }
+
+ private void assertResultSerializable(Result result) throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
+ objectOutputStream.writeObject(result);
+ objectOutputStream.flush();
+ byte[] bytes = byteArrayOutputStream.toByteArray();
+ ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
+ Result fromStream = (Result) objectInputStream.readObject();
+ assertSerializedCorrectly(result, fromStream, SerializationFormat.V4_13);
+ }
+
+ private void assertResultReserializable(Result result, SerializationFormat resourceSerializationFormat)
+ throws IOException, ClassNotFoundException {
+ String resourceName = getName();
+ InputStream resource = getClass().getResourceAsStream(resourceName);
+ assertNotNull("Could not read resource " + resourceName, resource);
+ ObjectInputStream objectInputStream = new ObjectInputStream(resource);
+ fromStream = (Result) objectInputStream.readObject();
+
+ assertSerializedCorrectly(new ResultWithFixedRunTime(result),
+ fromStream, resourceSerializationFormat);
+ }
+
+ public static class AssumptionFailedTest {
+ @Test
+ public void assumptionFailed() throws Exception {
+ org.junit.Assume.assumeTrue(false);
+ }
+ }
+
+ /**
+ * A version of {@code Result} that returns a hard-coded runtime.
+ * This makes values returned by the methods deterministic.
+ */
+ private static class ResultWithFixedRunTime extends Result {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Result delegate;
+
+ public ResultWithFixedRunTime(Result delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int getRunCount() {
+ return delegate.getRunCount();
+ }
+
+ @Override
+ public int getFailureCount() {
+ return delegate.getFailureCount();
+ }
+
+ @Override
+ public long getRunTime() {
+ return 2;
+ }
+
+ @Override
+ public List<Failure> getFailures() {
+ return delegate.getFailures();
+ }
+
+ @Override
+ public int getIgnoreCount() {
+ return delegate.getIgnoreCount();
+ }
+
+ @Override
+ public int getAssumptionFailureCount() {
+ return delegate.getAssumptionFailureCount();
+ }
+ }
+
+ private void assertSerializedCorrectly(
+ Result result, Result fromStream, SerializationFormat serializationFormat) {
+ assertNotNull(fromStream);
+
+ // Exceptions don't implement equals() so we need to compare field by field
+ assertEquals("failureCount", result.getFailureCount(), fromStream.getFailureCount());
+ assertEquals("ignoreCount", result.getIgnoreCount(), fromStream.getIgnoreCount());
+
+ if (serializationFormat == SerializationFormat.V4_13) {
+ // assumption failures are serialized
+ assertEquals("assumptionFailureCount",
+ result.getAssumptionFailureCount(),
+ fromStream.getAssumptionFailureCount());
+ } else {
+ // assumption failures were not serialized
+ try {
+ fromStream.getAssumptionFailureCount();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ assertEquals("runTime", result.getRunTime(), fromStream.getRunTime());
+ assertEquals("failures", result.getFailures().size(), fromStream.getFailures().size());
+ int index = 0;
+ for (Failure failure : result.getFailures()) {
+ Failure failureFromStream = fromStream.getFailures().get(index);
+ String messagePrefix = String.format("failures[%d]", index++);
+ assertEquals(messagePrefix + ".description",
+ failure.getDescription(), failureFromStream.getDescription());
+ Throwable exception = failure.getException();
+ Throwable exceptionFromStream = failureFromStream.getException();
+ assertEquals(messagePrefix + ".exception",
+ exception.getClass(), exceptionFromStream.getClass());
+ assertEquals(messagePrefix + ".exception",
+ exception.getMessage(), exceptionFromStream.getMessage());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/StackFilterTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/StackFilterTest.java
new file mode 100644
index 0000000..6aca9eb
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/StackFilterTest.java
@@ -0,0 +1,46 @@
+package junit.tests.runner;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+import junit.runner.BaseTestRunner;
+
+public class StackFilterTest extends TestCase {
+ String fFiltered;
+ String fUnfiltered;
+
+ @Override
+ protected void setUp() {
+ StringWriter swin = new StringWriter();
+ PrintWriter pwin = new PrintWriter(swin);
+ pwin.println("junit.framework.AssertionFailedError");
+ pwin.println("\tat junit.framework.Assert.fail(Assert.java:144)");
+ pwin.println("\tat junit.framework.Assert.assert(Assert.java:19)");
+ pwin.println("\tat junit.framework.Assert.assert(Assert.java:26)");
+ pwin.println("\tat MyTest.f(MyTest.java:13)");
+ pwin.println("\tat MyTest.testStackTrace(MyTest.java:8)");
+ pwin.println("\tat java.lang.reflect.Method.invoke(Native Method)");
+ pwin.println("\tat junit.framework.TestCase.runTest(TestCase.java:156)");
+ pwin.println("\tat junit.framework.TestCase.runBare(TestCase.java:130)");
+ pwin.println("\tat junit.framework.TestResult$1.protect(TestResult.java:100)");
+ pwin.println("\tat junit.framework.TestResult.runProtected(TestResult.java:118)");
+ pwin.println("\tat junit.framework.TestResult.run(TestResult.java:103)");
+ pwin.println("\tat junit.framework.TestCase.run(TestCase.java:121)");
+ pwin.println("\tat junit.framework.TestSuite.runTest(TestSuite.java:157)");
+ pwin.println("\tat junit.framework.TestSuite.run(TestSuite.java, Compiled Code)");
+ pwin.println("\tat junit.swingui.TestRunner$17.run(TestRunner.java:669)");
+ fUnfiltered = swin.toString();
+
+ StringWriter swout = new StringWriter();
+ PrintWriter pwout = new PrintWriter(swout);
+ pwout.println("junit.framework.AssertionFailedError");
+ pwout.println("\tat MyTest.f(MyTest.java:13)");
+ pwout.println("\tat MyTest.testStackTrace(MyTest.java:8)");
+ fFiltered = swout.toString();
+ }
+
+ public void testFilter() {
+ assertEquals(fFiltered, BaseTestRunner.getFilteredTrace(fUnfiltered));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextFeedbackTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextFeedbackTest.java
new file mode 100644
index 0000000..146a5ac
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextFeedbackTest.java
@@ -0,0 +1,126 @@
+package junit.tests.runner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.textui.ResultPrinter;
+import junit.textui.TestRunner;
+
+public class TextFeedbackTest extends TestCase {
+ OutputStream output;
+ TestRunner runner;
+
+ static class TestResultPrinter extends ResultPrinter {
+ TestResultPrinter(PrintStream writer) {
+ super(writer);
+ }
+
+ /* Spoof printing time so the tests are deterministic
+ */
+ @Override
+ protected String elapsedTimeAsString(long runTime) {
+ return "0";
+ }
+ }
+
+ public static void main(String[] args) {
+ TestRunner.run(TextFeedbackTest.class);
+ }
+
+ @Override
+ public void setUp() {
+ output = new ByteArrayOutputStream();
+ runner = new TestRunner(new TestResultPrinter(new PrintStream(output)));
+ }
+
+ public void testEmptySuite() {
+ String expected = expected(new String[]{"", "Time: 0", "", "OK (0 tests)", ""});
+ runner.doRun(new TestSuite());
+ assertEquals(expected, output.toString());
+ }
+
+
+ public void testOneTest() {
+ String expected = expected(new String[]{".", "Time: 0", "", "OK (1 test)", ""});
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() {
+ }
+ });
+ runner.doRun(suite);
+ assertEquals(expected, output.toString());
+ }
+
+ public void testTwoTests() {
+ String expected = expected(new String[]{"..", "Time: 0", "", "OK (2 tests)", ""});
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() {
+ }
+ });
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() {
+ }
+ });
+ runner.doRun(suite);
+ assertEquals(expected, output.toString());
+ }
+
+ public void testFailure() {
+ String expected = expected(new String[]{".F", "Time: 0", "Failures here", "", "FAILURES!!!", "Tests run: 1, Failures: 1, Errors: 0", ""});
+ ResultPrinter printer = new TestResultPrinter(new PrintStream(output)) {
+ @Override
+ public void printFailures(TestResult result) {
+ getWriter().println("Failures here");
+ }
+ };
+ runner.setPrinter(printer);
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() {
+ throw new AssertionFailedError();
+ }
+ });
+ runner.doRun(suite);
+ assertEquals(expected, output.toString());
+ }
+
+ public void testError() {
+ String expected = expected(new String[]{".E", "Time: 0", "Errors here", "", "FAILURES!!!", "Tests run: 1, Failures: 0, Errors: 1", ""});
+ ResultPrinter printer = new TestResultPrinter(new PrintStream(output)) {
+ @Override
+ public void printErrors(TestResult result) {
+ getWriter().println("Errors here");
+ }
+ };
+ runner.setPrinter(printer);
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() throws Exception {
+ throw new Exception();
+ }
+ });
+ runner.doRun(suite);
+ assertEquals(expected, output.toString());
+ }
+
+ private String expected(String[] lines) {
+ OutputStream expected = new ByteArrayOutputStream();
+ PrintStream expectedWriter = new PrintStream(expected);
+ for (int i = 0; i < lines.length; i++) {
+ expectedWriter.println(lines[i]);
+ }
+ return expected.toString();
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerSingleMethodTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerSingleMethodTest.java
new file mode 100644
index 0000000..fc3651a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerSingleMethodTest.java
@@ -0,0 +1,39 @@
+package junit.tests.runner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import junit.framework.TestCase;
+import junit.textui.ResultPrinter;
+import junit.textui.TestRunner;
+
+/**
+ * Test invoking a single test method of a TestCase.
+ */
+public class TextRunnerSingleMethodTest extends TestCase {
+
+ static boolean fgWasInvoked;
+
+ public static class InvocationTest extends TestCase {
+
+ public void testWasInvoked() {
+ TextRunnerSingleMethodTest.fgWasInvoked = true;
+ }
+
+ public void testNotInvoked() {
+ fail("Shouldn't get here.");
+ }
+ }
+
+ public void testSingle() throws Exception {
+ TestRunner t = new TestRunner();
+ t.setPrinter(new ResultPrinter(new PrintStream(new ByteArrayOutputStream())));
+ String[] args = {
+ "-m", "junit.tests.runner.TextRunnerSingleMethodTest$InvocationTest.testWasInvoked"
+ };
+ fgWasInvoked = false;
+ t.start(args);
+ assertTrue(fgWasInvoked);
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerTest.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerTest.java
new file mode 100644
index 0000000..44e16fd
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/TextRunnerTest.java
@@ -0,0 +1,62 @@
+package junit.tests.runner;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+public class TextRunnerTest extends TestCase {
+
+ public void testFailure() throws Exception {
+ execTest("junit.tests.framework.Failure", false);
+ }
+
+ public void testSuccess() throws Exception {
+ execTest("junit.tests.framework.Success", true);
+ }
+
+ public void testError() throws Exception {
+ execTest("junit.tests.BogusDude", false);
+ }
+
+ void execTest(String testClass, boolean success) throws Exception {
+ String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
+ String cp = System.getProperty("java.class.path");
+ //use -classpath for JDK 1.1.7 compatibility
+ String[] cmd = {java, "-classpath", cp, "junit.textui.TestRunner", testClass};
+ Process p = Runtime.getRuntime().exec(cmd);
+ InputStream i = p.getInputStream();
+ while ((i.read()) != -1)
+ ;
+ assertTrue((p.waitFor() == 0) == success);
+ if (success) {
+ assertTrue(p.exitValue() == 0);
+ } else {
+ assertFalse(p.exitValue() == 0);
+ }
+ }
+
+ public void testRunReturnsResult() {
+ PrintStream oldOut = System.out;
+ System.setOut(new PrintStream(
+ new OutputStream() {
+ @Override
+ public void write(int arg0) throws IOException {
+ }
+ }
+ ));
+ try {
+ TestResult result = junit.textui.TestRunner.run(new TestSuite());
+ assertTrue(result.wasSuccessful());
+ } finally {
+ System.setOut(oldOut);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/junit/tests/runner/package-info.java b/google3/third_party/java_src/junit/test/java/junit/tests/runner/package-info.java
new file mode 100644
index 0000000..fc44e8a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/junit/tests/runner/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Tests for the JUnit v3.x runner functionality.
+ */
+package junit.tests.runner;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/AssumptionViolatedExceptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/AssumptionViolatedExceptionTest.java
new file mode 100644
index 0000000..f5dbfcb
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/AssumptionViolatedExceptionTest.java
@@ -0,0 +1,207 @@
+package org.junit;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+@RunWith(Theories.class)
+public class AssumptionViolatedExceptionTest {
+ @DataPoint
+ public static Integer TWO = 2;
+
+ @DataPoint
+ public static Matcher<Integer> IS_THREE = is(3);
+
+ @DataPoint
+ public static Matcher<Integer> NULL = null;
+
+ @Rule
+ public TestName name = new TestName();
+
+ private static final String MESSAGE = "Assumption message";
+ private static Matcher<Integer> SERIALIZABLE_IS_THREE = new SerializableIsThreeMatcher<Integer>();
+ private static final UnserializableClass UNSERIALIZABLE_VALUE = new UnserializableClass();
+ private static final Matcher<UnserializableClass> UNSERIALIZABLE_MATCHER = not(is(UNSERIALIZABLE_VALUE));
+
+ @Theory
+ public void toStringReportsMatcher(Integer actual, Matcher<Integer> matcher) {
+ assumeThat(matcher, notNullValue());
+ assertThat(new AssumptionViolatedException(actual, matcher).toString(),
+ containsString(matcher.toString()));
+ }
+
+ @Theory
+ public void toStringReportsValue(Integer actual, Matcher<Integer> matcher) {
+ assertThat(new AssumptionViolatedException(actual, matcher).toString(),
+ containsString(String.valueOf(actual)));
+ }
+
+ @Test
+ public void assumptionViolatedExceptionWithMatcherDescribesItself() {
+ AssumptionViolatedException e = new AssumptionViolatedException(3, is(2));
+ assertThat(StringDescription.asString(e), is("got: <3>, expected: is <2>"));
+ }
+
+ @Test
+ public void simpleAssumptionViolatedExceptionDescribesItself() {
+ AssumptionViolatedException e = new AssumptionViolatedException("not enough money");
+ assertThat(StringDescription.asString(e), is("not enough money"));
+ }
+
+ @Test
+ public void canInitCauseWithInstanceCreatedWithString() {
+ AssumptionViolatedException e = new AssumptionViolatedException("invalid number");
+ Throwable cause = new RuntimeException("cause");
+ e.initCause(cause);
+ assertThat(e.getCause(), is(cause));
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void canSetCauseWithInstanceCreatedWithObjectAndMatcher() {
+ Throwable testObject = new Exception();
+ org.junit.internal.AssumptionViolatedException e
+ = new org.junit.internal.AssumptionViolatedException(
+ testObject, containsString("test matcher"));
+ assertThat(e.getCause(), is(testObject));
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void canSetCauseWithInstanceCreatedWithAssumptionObjectAndMatcher() {
+ Throwable testObject = new Exception();
+ org.junit.internal.AssumptionViolatedException e
+ = new org.junit.internal.AssumptionViolatedException(
+ "sample assumption", testObject, containsString("test matcher"));
+ assertThat(e.getCause(), is(testObject));
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void canSetCauseWithInstanceCreatedWithMainConstructor() {
+ Throwable testObject = new Exception();
+ org.junit.internal.AssumptionViolatedException e
+ = new org.junit.internal.AssumptionViolatedException(
+ "sample assumption", false, testObject, containsString("test matcher"));
+ assertThat(e.getCause(), is(testObject));
+ }
+
+ @Test
+ public void canSetCauseWithInstanceCreatedWithExplicitThrowableConstructor() {
+ Throwable cause = new Exception();
+ AssumptionViolatedException e = new AssumptionViolatedException("invalid number", cause);
+ assertThat(e.getCause(), is(cause));
+ }
+
+ @Test
+ public void assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13()
+ throws IOException, ClassNotFoundException {
+ assertReserializable(new AssumptionViolatedException(MESSAGE));
+ }
+
+ @Test
+ public void assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13()
+ throws IOException, ClassNotFoundException {
+ assertReserializable(new AssumptionViolatedException(MESSAGE, TWO, SERIALIZABLE_IS_THREE));
+ }
+
+ @Test
+ public void unserializableValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException {
+ AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE,
+ UNSERIALIZABLE_VALUE, UNSERIALIZABLE_MATCHER);
+
+ assertCanBeSerialized(exception);
+ }
+
+ @Test
+ public void nullValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException {
+ AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE);
+
+ assertCanBeSerialized(exception);
+ }
+
+ @Test
+ public void serializableValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException {
+ AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE,
+ TWO, SERIALIZABLE_IS_THREE);
+
+ assertCanBeSerialized(exception);
+ }
+
+ private void assertCanBeSerialized(AssumptionViolatedException exception)
+ throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(exception);
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ AssumptionViolatedException fromStream = (AssumptionViolatedException) ois.readObject();
+
+ assertSerializedCorrectly(exception, fromStream);
+ }
+
+ private void assertReserializable(AssumptionViolatedException expected)
+ throws IOException, ClassNotFoundException {
+ String resourceName = name.getMethodName();
+ InputStream resource = getClass().getResourceAsStream(resourceName);
+ assertNotNull("Could not read resource " + resourceName, resource);
+ ObjectInputStream objectInputStream = new ObjectInputStream(resource);
+ AssumptionViolatedException fromStream = (AssumptionViolatedException) objectInputStream.readObject();
+
+ assertSerializedCorrectly(expected, fromStream);
+ }
+
+ private void assertSerializedCorrectly(
+ AssumptionViolatedException expected, AssumptionViolatedException fromStream) {
+ assertNotNull(fromStream);
+
+ // Exceptions don't implement equals() so we need to compare field by field
+ assertEquals("message", expected.getMessage(), fromStream.getMessage());
+ assertEquals("description", StringDescription.asString(expected), StringDescription.asString(fromStream));
+ // We don't check the stackTrace as that will be influenced by how the test was started
+ // (e.g. by maven or directly from IDE)
+ // We also don't check the cause as that should already be serialized correctly by the superclass
+ }
+
+ private static class SerializableIsThreeMatcher<T> extends BaseMatcher<T> implements Serializable {
+
+ public boolean matches(Object item) {
+ return IS_THREE.matches(item);
+ }
+
+ public void describeTo(Description description) {
+ IS_THREE.describeTo(description);
+ }
+ }
+
+ private static class UnserializableClass {
+ @Override
+ public String toString() {
+ return "I'm not serializable";
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/AllCategoriesTests.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/AllCategoriesTests.java
new file mode 100644
index 0000000..6609bb8
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/AllCategoriesTests.java
@@ -0,0 +1,17 @@
+package org.junit.experimental.categories;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ CategoriesAndParameterizedTest.class,
+ CategoryFilterFactoryTest.class,
+ CategoryTest.class,
+ CategoryValidatorTest.class,
+ JavadocTest.class,
+ MultiCategoryTest.class
+})
+public class AllCategoriesTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java
new file mode 100644
index 0000000..3d79222
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java
@@ -0,0 +1,127 @@
+package org.junit.experimental.categories;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Categories.IncludeCategory;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Suite.SuiteClasses;
+
+public class CategoriesAndParameterizedTest {
+ public static class Token {
+
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParameterizedTestWithoutCategory {
+ @Parameters
+ public static Iterable<String> getParameters() {
+ return Arrays.asList("first", "second");
+ }
+
+ @Parameterized.Parameter
+ public String value;
+
+ @Test
+ public void testSomething() {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @Category(Token.class)
+ public static class TestThatAvoidsNoTestRemainsException {
+ @Test
+ public void testSomething() {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(Token.class)
+ @SuiteClasses({ TestThatAvoidsNoTestRemainsException.class,
+ ParameterizedTestWithoutCategory.class })
+ public static class SuiteWithParameterizedTestWithoutCategory {
+ }
+
+ @Test
+ public void doesNotRunTestsWithoutCategory() {
+ Result result = new JUnitCore()
+ .run(SuiteWithParameterizedTestWithoutCategory.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ @RunWith(Parameterized.class)
+ @Category(Token.class)
+ public static class ParameterizedTestWithCategory {
+ @Parameters
+ public static Iterable<String> getParameters() {
+ return Arrays.asList("first", "second");
+ }
+
+ @Parameterized.Parameter
+ public String value;
+
+ @Test
+ public void testSomething() {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(Token.class)
+ @SuiteClasses({ ParameterizedTestWithCategory.class })
+ public static class SuiteWithParameterizedTestWithCategory {
+ }
+
+ @Test
+ public void runsTestsWithoutCategory() {
+ Result result = new JUnitCore()
+ .run(SuiteWithParameterizedTestWithCategory.class);
+ assertEquals(2, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParameterizedTestWithMethodWithCategory {
+ @Parameters
+ public static Iterable<String> getParameters() {
+ return Arrays.asList("first", "second");
+ }
+
+ @Parameterized.Parameter
+ public String value;
+
+ @Test
+ @Category(Token.class)
+ public void testSomething() {
+ Assert.assertTrue(true);
+ }
+
+ @Test
+ public void testThatIsNotExecuted() {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(Token.class)
+ @SuiteClasses({ ParameterizedTestWithMethodWithCategory.class })
+ public static class SuiteWithParameterizedTestWithMethodWithCategory {
+ }
+
+ @Test
+ public void runsTestMethodWithCategory() {
+ Result result = new JUnitCore()
+ .run(SuiteWithParameterizedTestWithMethodWithCategory.class);
+ assertEquals(2, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryFilterFactoryTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryFilterFactoryTest.java
new file mode 100644
index 0000000..f0bd7d5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryFilterFactoryTest.java
@@ -0,0 +1,66 @@
+package org.junit.experimental.categories;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.runner.Description.createSuiteDescription;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TestName;
+import org.junit.runner.Description;
+import org.junit.runner.FilterFactory;
+import org.junit.runner.FilterFactoryParams;
+import org.junit.runner.manipulation.Filter;
+
+public class CategoryFilterFactoryTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public TestName testName = new TestName();
+
+ private final CategoryFilterFactory categoryFilterFactory = new CategoryFilterFactoryStub();
+
+ @Test
+ public void shouldCreateFilter() throws Exception {
+ FilterFactoryParams params = new FilterFactoryParams(
+ createSuiteDescription(testName.getMethodName()),
+ CategoryFilterFactoryStub.class.getName());
+ Filter filter = categoryFilterFactory.createFilter(params);
+
+ assertThat(filter, instanceOf(DummyFilter.class));
+ }
+
+ @Test
+ public void shouldThrowException() throws Exception {
+ FilterFactoryParams params = new FilterFactoryParams(
+ createSuiteDescription(testName.getMethodName()),
+ "NonExistentFilter");
+
+ expectedException.expect(FilterFactory.FilterNotCreatedException.class);
+
+ categoryFilterFactory.createFilter(params);
+ }
+
+ private static class CategoryFilterFactoryStub extends CategoryFilterFactory {
+ @Override
+ protected Filter createFilter(List<Class<?>> categories) {
+ return new DummyFilter();
+ }
+ }
+
+ private static class DummyFilter extends Filter {
+ @Override
+ public boolean shouldRun(Description description) {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return null;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryTest.java
new file mode 100644
index 0000000..6088f1d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryTest.java
@@ -0,0 +1,574 @@
+package org.junit.experimental.categories;
+
+import static java.lang.String.format;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.AnyOf.anyOf;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.experimental.categories.Categories.ExcludeCategory;
+import org.junit.experimental.categories.Categories.IncludeCategory;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.runners.model.InitializationError;
+
+public class CategoryTest {
+ public interface FastTests {
+ // category marker
+ }
+
+ public interface SlowTests {
+ // category marker
+ }
+
+ public interface ReallySlowTests {
+ // category marker
+ }
+
+ public static class OneOfEach {
+
+ @Category(FastTests.class)
+ @Test
+ public void a() {
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+ }
+
+ @Category(ReallySlowTests.class)
+ @Test
+ public void c() {
+ }
+ }
+
+ public static class A {
+ @Test
+ public void a() {
+ fail();
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+ }
+ }
+
+ @Category(SlowTests.class)
+ public static class B {
+ @Test
+ public void c() {
+
+ }
+ }
+
+ public static class C {
+ @Test
+ public void d() {
+ fail();
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses({A.class, B.class, C.class})
+ public static class SlowTestSuite {
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses({A.class})
+ public static class JustA {
+ }
+
+ @Test
+ public void testCountOnJustA() {
+ assertThat(testResult(JustA.class), isSuccessful());
+ }
+
+ @Test
+ public void testCount() {
+ assertThat(testResult(SlowTestSuite.class), isSuccessful());
+ }
+
+ public static class Category1 {
+ }
+
+ public static class Category2 {
+ }
+
+ public static class SomeAreSlow {
+ @Test
+ public void noCategory() {
+ }
+
+ @Category(Category1.class)
+ @Test
+ public void justCategory1() {
+ }
+
+ @Category(Category2.class)
+ @Test
+ public void justCategory2() {
+ }
+
+ @Category({Category1.class, Category2.class})
+ @Test
+ public void both() {
+ }
+
+ @Category({Category2.class, Category1.class})
+ @Test
+ public void bothReversed() {
+ }
+ }
+
+ @RunWith(Categories.class)
+ @ExcludeCategory(Category1.class)
+ @SuiteClasses({SomeAreSlow.class})
+ public static class SomeAreSlowSuite {
+ }
+
+ @Test
+ public void testCountOnAWithoutSlowTests() {
+ Result result = JUnitCore.runClasses(SomeAreSlowSuite.class);
+ assertThat(testResult(SomeAreSlowSuite.class), isSuccessful());
+ assertEquals(2, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @RunWith(Categories.class)
+ @ExcludeCategory(Category1.class)
+ @IncludeCategory(Category2.class)
+ @SuiteClasses({SomeAreSlow.class})
+ public static class IncludeAndExcludeSuite {
+ }
+
+ @Test
+ public void testsThatAreBothIncludedAndExcludedAreExcluded() {
+ Result result = JUnitCore.runClasses(IncludeAndExcludeSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({A.class, B.class, C.class})
+ public static class TestSuiteWithNoCategories {
+ }
+
+ @Test
+ public void testCountWithExplicitIncludeFilter() throws Throwable {
+ CategoryFilter include = CategoryFilter.include(SlowTests.class);
+ Request baseRequest = Request.aClass(TestSuiteWithNoCategories.class);
+ Result result = new JUnitCore().run(baseRequest.filterWith(include));
+ assertTrue(result.wasSuccessful());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @Test
+ public void testCountWithExplicitExcludeFilter() throws Throwable {
+ CategoryFilter include = CategoryFilter.exclude(SlowTests.class);
+ Request baseRequest = Request.aClass(TestSuiteWithNoCategories.class);
+ Result result = new JUnitCore().run(baseRequest.filterWith(include));
+ assertEquals(2, result.getFailureCount());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @Test
+ public void testCountWithExplicitExcludeFilter_usingConstructor() throws Throwable {
+ CategoryFilter include = new CategoryFilter(null, SlowTests.class);
+ Request baseRequest = Request.aClass(TestSuiteWithNoCategories.class);
+ Result result = new JUnitCore().run(baseRequest.filterWith(include));
+ assertEquals(2, result.getFailureCount());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @Test
+ public void categoryFilterLeavesOnlyMatchingMethods()
+ throws InitializationError, NoTestsRemainException {
+ CategoryFilter filter = CategoryFilter.include(SlowTests.class);
+ BlockJUnit4ClassRunner runner = new BlockJUnit4ClassRunner(A.class);
+ filter.apply(runner);
+ assertEquals(1, runner.testCount());
+ }
+
+ @Test
+ public void categoryFilterLeavesOnlyMatchingMethods_usingConstructor()
+ throws InitializationError, NoTestsRemainException {
+ CategoryFilter filter = new CategoryFilter(SlowTests.class, null);
+ BlockJUnit4ClassRunner runner = new BlockJUnit4ClassRunner(A.class);
+ filter.apply(runner);
+ assertEquals(1, runner.testCount());
+ }
+
+ public static class OneFastOneSlow {
+ @Category(FastTests.class)
+ @Test
+ public void a() {
+
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+
+ }
+ }
+
+ @Test
+ public void categoryFilterRejectsIncompatibleCategory()
+ throws InitializationError, NoTestsRemainException {
+ CategoryFilter filter = CategoryFilter.include(SlowTests.class);
+ BlockJUnit4ClassRunner runner = new BlockJUnit4ClassRunner(
+ OneFastOneSlow.class);
+ filter.apply(runner);
+ assertEquals(1, runner.testCount());
+ }
+
+ public static class OneFast {
+ @Category(FastTests.class)
+ @Test
+ public void a() {
+
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses({OneFast.class})
+ public static class OneFastSuite {
+ }
+
+ @Test
+ public void ifNoTestsToRunUseErrorRunner() {
+ Result result = JUnitCore.runClasses(OneFastSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertFalse(result.wasSuccessful());
+ }
+
+ @Test
+ public void describeACategoryFilter() {
+ CategoryFilter filter = CategoryFilter.include(SlowTests.class);
+ assertEquals("categories [" + SlowTests.class + "]", filter.describe());
+ }
+
+ @Test
+ public void describeMultipleCategoryFilter() {
+ CategoryFilter filter= CategoryFilter.include(FastTests.class, SlowTests.class);
+ String d1= format("categories [%s, %s]", FastTests.class, SlowTests.class);
+ String d2= format("categories [%s, %s]", SlowTests.class, FastTests.class);
+ assertThat(filter.describe(), is(anyOf(equalTo(d1), equalTo(d2))));
+ }
+
+
+ public static class OneThatIsBothFastAndSlow {
+ @Category({FastTests.class, SlowTests.class})
+ @Test
+ public void a() {
+
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses({OneThatIsBothFastAndSlow.class})
+ public static class ChooseSlowFromBoth {
+ }
+
+ @Test
+ public void runMethodWithTwoCategories() {
+ assertThat(testResult(ChooseSlowFromBoth.class), isSuccessful());
+ }
+
+ public interface VerySlowTests extends SlowTests {
+
+ }
+
+ public static class OneVerySlowTest {
+ @Category(VerySlowTests.class)
+ @Test
+ public void a() {
+
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses({OneVerySlowTest.class})
+ public static class RunSlowFromVerySlow {
+ }
+
+ @Test
+ public void subclassesOfIncludedCategoriesAreRun() {
+ assertThat(testResult(RunSlowFromVerySlow.class), isSuccessful());
+ }
+
+ public interface MultiA {
+ }
+
+ public interface MultiB {
+ }
+
+ public interface MultiC {
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(value= {MultiA.class, MultiB.class}, matchAny= false)
+ @SuiteClasses(AllIncludedMustMatched.class)
+ public static class AllIncludedMustBeMatchedSuite {
+ }
+
+ public static class AllIncludedMustMatched {
+ @Test
+ @Category({MultiA.class, MultiB.class})
+ public void a() {
+ }
+
+ @Test
+ @Category(MultiB.class)
+ public void b() {
+ fail("When multiple categories are included in a Suite, " +
+ "@Test method must match all include categories");
+ }
+ }
+
+ @Test
+ public void allIncludedSuiteCategoriesMustBeMatched() {
+ Result result= JUnitCore.runClasses(AllIncludedMustBeMatchedSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory({MultiA.class, MultiB.class})
+ @ExcludeCategory(MultiC.class)
+ @SuiteClasses(MultipleIncludesAndExcludeOnMethod.class)
+ public static class MultiIncludeWithExcludeCategorySuite {
+ }
+
+ public static class MultipleIncludesAndExcludeOnMethod {
+ @Test
+ @Category({MultiA.class, MultiB.class})
+ public void a() {
+ }
+
+ @Test
+ @Category({ MultiA.class, MultiB.class, MultiC.class })
+ public void b() {
+ fail("When multiple categories are included and excluded in a Suite, " +
+ "@Test method must match all include categories and contain non of the excluded");
+ }
+ }
+
+ @Test
+ public void anyMethodWithExcludedCategoryWillBeExcluded() {
+ Result result= JUnitCore.runClasses(MultiIncludeWithExcludeCategorySuite.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ public static class ClassAsCategory {
+ }
+
+ public static class OneMoreTest {
+ @Category(ClassAsCategory.class)
+ @Test
+ public void a() {
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(ClassAsCategory.class)
+ @SuiteClasses({OneMoreTest.class})
+ public static class RunClassAsCategory {
+ }
+
+ @Test
+ public void classesCanBeCategories() {
+ assertThat(testResult(RunClassAsCategory.class), isSuccessful());
+ }
+
+ @Category(SlowTests.class)
+ public abstract static class Ancestor{}
+
+ public static class Inherited extends Ancestor {
+ @Test
+ public void a(){
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses(Inherited.class)
+ public interface InheritanceSuite {}
+
+ @Test
+ public void testInheritance() {
+ Result result = JUnitCore.runClasses(InheritanceSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(Runnable.class)
+ @ExcludeCategory(Runnable.class)
+ @SuiteClasses({})
+ public static class EmptyCategoriesSuite {
+ }
+
+ @Test public void emptyCategoriesSuite() {
+ assertThat(testResult(EmptyCategoriesSuite.class), failureCountIs(1));
+ }
+
+ @Category(Runnable.class)
+ public static class NoTest {
+ }
+
+ @Category(Runnable.class)
+ public static class IgnoredTest {
+
+ @Ignore
+ @Test
+ public void test() {
+ fail();
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(Runnable.class)
+ @SuiteClasses({NoTest.class, IgnoredTest.class})
+ public static class IgnoredTestCategoriesSuite {
+ }
+
+ @Test
+ public void ignoredTest() {// behaves same as Suite
+ Result result= JUnitCore.runClasses(IgnoredTestCategoriesSuite.class);
+ assertFalse(result.wasSuccessful());
+ assertThat(result.getRunCount(), is(1));
+ assertThat(result.getFailureCount(), is(1));
+ assertThat(result.getIgnoreCount(), is(1));
+ }
+
+ @Category(Runnable.class)
+ public static class ExcludedTest1 {
+
+ @Test
+ public void test() {
+ fail();
+ }
+ }
+
+ @Category(Runnable.class)
+ public static class ExcludedTest2 {
+
+ @Test
+ @Category(Runnable.class)
+ public void test() {
+ fail();
+ }
+ }
+
+ public static class IncludedTest {
+
+ @Test
+ @Category(Object.class)
+ public void test() {
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory({Runnable.class, Object.class})
+ @ExcludeCategory(Runnable.class)
+ @SuiteClasses({ExcludedTest1.class, ExcludedTest2.class, IncludedTest.class})
+ public static class IncludedExcludedSameSuite {
+ }
+
+ @Test
+ public void oneRunnableOthersAvoided() {
+ Result result= JUnitCore.runClasses(IncludedExcludedSameSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testCountWithMultipleExcludeFilter() throws Throwable {
+ Set<Class<?>> exclusions= new HashSet<Class<?>>(2);
+ Collections.addAll(exclusions, SlowTests.class, FastTests.class);
+ CategoryFilter exclude = CategoryFilter.categoryFilter(true, null, true, exclusions);
+ Request baseRequest= Request.aClass(OneOfEach.class);
+ Result result= new JUnitCore().run(baseRequest.filterWith(exclude));
+ assertTrue(result.wasSuccessful());
+ assertEquals(1, result.getRunCount());
+ }
+
+ @Test
+ public void testCountWithMultipleIncludeFilter() throws Throwable {
+ CategoryFilter exclude = CategoryFilter.include(true, SlowTests.class, FastTests.class);
+ Request baseRequest= Request.aClass(OneOfEach.class);
+ Result result= new JUnitCore().run(baseRequest.filterWith(exclude));
+ assertTrue(result.wasSuccessful());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @RunWith(Categories.class)
+ @Categories.ExcludeCategory(String.class)
+ @Suite.SuiteClasses(NoIncludeCategoryAnnotationTest.class)
+ public static class NoIncludeCategoryAnnotationSuite {
+ }
+
+ @Category(CharSequence.class)
+ public static class NoIncludeCategoryAnnotationTest {
+
+ @Test
+ public void test2() {
+ }
+
+ @Test
+ @Category(String.class) public void test1() {
+ }
+ }
+
+ @Test
+ public void noIncludeCategoryAnnotation() {
+ Result testResult= JUnitCore.runClasses(NoIncludeCategoryAnnotationSuite.class);
+ assertTrue(testResult.wasSuccessful());
+ assertEquals(1, testResult.getRunCount());
+ }
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory(CharSequence.class)
+ @Categories.ExcludeCategory(String.class)
+ @Suite.SuiteClasses(NoIncludeCategoryAnnotationTest.class)
+ public static class SameAsNoIncludeCategoryAnnotationSuite {
+ }
+
+ @Test
+ public void sameAsNoIncludeCategoryAnnotation() {
+ Result testResult= JUnitCore.runClasses(SameAsNoIncludeCategoryAnnotationSuite.class);
+ assertTrue(testResult.wasSuccessful());
+ assertEquals(1, testResult.getRunCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryValidatorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryValidatorTest.java
new file mode 100644
index 0000000..6d7c22e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/CategoryValidatorTest.java
@@ -0,0 +1,86 @@
+package org.junit.experimental.categories;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+public class CategoryValidatorTest {
+
+ public static class SampleCategory {
+ }
+
+ public static class CategoryTest {
+ @BeforeClass
+ @Category(value = SampleCategory.class)
+ public static void methodWithCategoryAndBeforeClass() {
+ }
+
+ @AfterClass
+ @Category(value = SampleCategory.class)
+ public static void methodWithCategoryAndAfterClass() {
+ }
+
+ @Before
+ @Category(value = SampleCategory.class)
+ public static void methodWithCategoryAndBefore() {
+ }
+
+ @After
+ @Category(value = SampleCategory.class)
+ public static void methodWithCategoryAndAfter() {
+ }
+
+ @Category(value = SampleCategory.class)
+ public static void methodWithCategory() {
+ }
+ }
+
+ @Test
+ public void errorIsAddedWhenCategoryIsUsedWithBeforeClass() {
+ FrameworkMethod method = new TestClass(CategoryTest.class).getAnnotatedMethods(BeforeClass.class).get(0);
+ testAndAssertErrorMessage(method, "@BeforeClass can not be combined with @Category");
+ }
+
+ @Test
+ public void errorIsAddedWhenCategoryIsUsedWithAfterClass() {
+ FrameworkMethod method = new TestClass(CategoryTest.class).getAnnotatedMethods(AfterClass.class).get(0);
+ testAndAssertErrorMessage(method, "@AfterClass can not be combined with @Category");
+ }
+
+ @Test
+ public void errorIsAddedWhenCategoryIsUsedWithBefore() {
+ FrameworkMethod method = new TestClass(CategoryTest.class).getAnnotatedMethods(Before.class).get(0);
+ testAndAssertErrorMessage(method, "@Before can not be combined with @Category");
+ }
+
+ @Test
+ public void errorIsAddedWhenCategoryIsUsedWithAfter() {
+ FrameworkMethod method = new TestClass(CategoryTest.class).getAnnotatedMethods(After.class).get(0);
+ testAndAssertErrorMessage(method, "@After can not be combined with @Category");
+ }
+
+ private void testAndAssertErrorMessage(FrameworkMethod method, String expectedErrorMessage) {
+ List<Exception> errors = new CategoryValidator().validateAnnotatedMethod(method);
+
+ assertThat(errors.size(), is(1));
+ Exception exception = errors.get(0);
+ assertThat(exception.getMessage(), is(expectedErrorMessage));
+ }
+
+ @Test
+ public void errorIsNotAddedWhenCategoryIsNotCombinedWithIllegalCombination() throws NoSuchMethodException {
+ FrameworkMethod method = new FrameworkMethod(CategoryTest.class.getMethod("methodWithCategory"));
+ List<Exception> errors = new CategoryValidator().validateAnnotatedMethod(method);
+
+ assertThat(errors.size(), is(0));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/JavadocTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/JavadocTest.java
new file mode 100644
index 0000000..fc0df72
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/JavadocTest.java
@@ -0,0 +1,76 @@
+package org.junit.experimental.categories;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author tibor17
+ * @version 4.12
+ * @since 4.12
+ */
+public class JavadocTest {
+ public static interface FastTests {}
+ public static interface SlowTests {}
+ public static interface SmokeTests {}
+
+ public static class A {
+ public void a() {
+ fail();
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+ }
+
+ @Category({FastTests.class, SmokeTests.class})
+ @Test
+ public void c() {
+ }
+ }
+
+ @Category({SlowTests.class, FastTests.class})
+ public static class B {
+ @Test
+ public void d() {
+ }
+ }
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory(SlowTests.class)
+ @Suite.SuiteClasses({A.class, B.class})
+ public static class SlowTestSuite {
+ // Will run A.b and B.d, but not A.a and A.c
+ }
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory({FastTests.class, SmokeTests.class})
+ @Suite.SuiteClasses({A.class, B.class})
+ public static class FastOrSmokeTestSuite {
+ // Will run A.c and B.d, but not A.b because it is not any of FastTests or SmokeTests
+ }
+
+ @Test
+ public void slowTests() {
+ Result testResult= JUnitCore.runClasses(SlowTestSuite.class);
+ assertTrue(testResult.wasSuccessful());
+ assertThat("unexpected run count", testResult.getRunCount(), is(2));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(0));
+ }
+
+ @Test
+ public void fastSmokeTests() {
+ Result testResult= JUnitCore.runClasses(FastOrSmokeTestSuite.class);
+ assertTrue(testResult.wasSuccessful());
+ assertThat("unexpected run count", testResult.getRunCount(), is(2));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(0));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/MultiCategoryTest.java b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/MultiCategoryTest.java
new file mode 100644
index 0000000..68a580c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/experimental/categories/MultiCategoryTest.java
@@ -0,0 +1,169 @@
+package org.junit.experimental.categories;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author tibor17
+ * @version 4.12
+ * @since 4.12
+ */
+public final class MultiCategoryTest {
+ public interface A {}
+ public interface B {}
+ public interface C {}
+
+ /**
+ * This test is mentioned in {@code Categories} and any changes
+ * must be reflected.
+ */
+ @Test
+ public void runSuite() {
+ // Targeting Test:
+ Result testResult= JUnitCore.runClasses(MultiCategorySuite.class);
+
+ assertThat("unexpected run count", testResult.getRunCount(), is(equalTo(2)));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(equalTo(0)));
+ assertThat("unexpected failure count", testResult.getIgnoreCount(), is(equalTo(0)));
+ }
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory({A.class, B.class})
+ @Categories.ExcludeCategory(C.class)
+ @Suite.SuiteClasses({CategoriesTest.class})
+ public static final class MultiCategorySuite {}
+
+ public static final class CategoriesTest {
+
+ @Test
+ @Category(A.class)
+ public void a() {}
+
+ @Test
+ @Category(B.class)
+ public void b() {}
+
+ @Test
+ @Category(C.class)
+ public void c() {
+ fail();
+ }
+
+ @Test
+ public void anything() {
+ fail();
+ }
+ }
+
+ @Test
+ public void inheritanceAnyIncluded() {
+ Result testResult= JUnitCore.runClasses(InheritanceAny.class);
+ assertThat("unexpected run count", testResult.getRunCount(), is(equalTo(3)));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(equalTo(0)));
+ assertThat("unexpected failure count", testResult.getIgnoreCount(), is(equalTo(0)));
+ }
+
+ @Test
+ public void inheritanceAllIncluded() {
+ Result testResult= JUnitCore.runClasses(InheritanceAll.class);
+ assertThat("unexpected run count", testResult.getRunCount(), is(equalTo(1)));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(equalTo(0)));
+ assertThat("unexpected failure count", testResult.getIgnoreCount(), is(equalTo(0)));
+ }
+
+ @Test
+ public void inheritanceAnyAll() {//any included, all excluded
+ Result testResult= JUnitCore.runClasses(InheritanceAnyAll.class);
+ assertThat("unexpected run count", testResult.getRunCount(), is(equalTo(3)));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(equalTo(0)));
+ assertThat("unexpected failure count", testResult.getIgnoreCount(), is(equalTo(0)));
+ }
+
+ @Test
+ public void inheritanceAllAny() {//all included, any excluded
+ Result testResult= JUnitCore.runClasses(InheritanceAllAny.class);
+ assertThat("unexpected run count", testResult.getRunCount(), is(equalTo(1)));
+ assertThat("unexpected failure count", testResult.getFailureCount(), is(equalTo(1)));
+ assertThat("unexpected failure count", testResult.getIgnoreCount(), is(equalTo(0)));
+ assertFalse(testResult.wasSuccessful());
+ }
+
+ public static class X implements A {}
+ public static class Y implements B {}
+ public static class Z implements A, B {}
+ public static class W implements A, B, C {}
+ public static class Q implements A, C {}
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory({A.class, B.class})
+ @Categories.ExcludeCategory(C.class)
+ @Suite.SuiteClasses({InheritanceAnyTest.class})
+ public static final class InheritanceAny {}
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory(value= {A.class, B.class}, matchAny= false)
+ @Categories.ExcludeCategory(C.class)
+ @Suite.SuiteClasses({InheritanceAllTest.class})
+ public static final class InheritanceAll {}
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory({A.class, B.class})
+ @Categories.ExcludeCategory(value= {A.class, C.class}, matchAny= false)
+ @Suite.SuiteClasses({InheritanceAnyAllTest.class})
+ public static final class InheritanceAnyAll {}
+
+ @RunWith(Categories.class)
+ @Categories.IncludeCategory(value= {A.class, B.class}, matchAny= false)
+ @Categories.ExcludeCategory({A.class, C.class})
+ @Suite.SuiteClasses({InheritanceAllAnyTest.class})
+ public static final class InheritanceAllAny {}
+
+ public static final class InheritanceAnyTest {
+ @Test @Category(X.class) public void x() {}
+ @Test @Category(Y.class) public void y() {}
+ @Test @Category(Z.class) public void z() {}
+ @Test @Category(W.class) public void w() { fail(); }
+ @Test @Category(Q.class) public void q() { fail(); }
+ @Test @Category(Runnable.class) public void runnable() { fail(); }
+ @Test public void t() { fail(); }
+ }
+
+ public static final class InheritanceAllTest {
+ @Test @Category(X.class) public void x() { fail(); }
+ @Test @Category(Y.class) public void y() { fail(); }
+ @Test @Category(Z.class) public void z() {}
+ @Test @Category(W.class) public void w() { fail(); }
+ @Test @Category(Q.class) public void q() { fail(); }
+ @Test @Category(Runnable.class) public void runnable() { fail(); }
+ @Test public void t() { fail(); }
+ }
+
+ public static final class InheritanceAnyAllTest {
+ @Test @Category(X.class) public void x() {}
+ @Test @Category(Y.class) public void y() {}
+ @Test @Category(Z.class) public void z() {}
+ @Test @Category(W.class) public void w() { fail(); }
+ @Test @Category(Q.class) public void q() { fail(); }
+ @Test @Category(Runnable.class) public void runnable() { fail(); }
+ @Test public void t() { fail(); }
+ }
+
+ public static final class InheritanceAllAnyTest {
+ @Test @Category(X.class) public void x() { fail(); }
+ @Test @Category(Y.class) public void y() { fail(); }
+ @Test @Category(Z.class) public void z() { fail(); }
+ @Test @Category(W.class) public void w() { fail(); }
+ @Test @Category(Q.class) public void q() { fail(); }
+ @Test @Category(Runnable.class) public void runnable() { fail(); }
+ @Test public void t() { fail(); }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/AllInternalTests.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/AllInternalTests.java
new file mode 100644
index 0000000..270d800
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/AllInternalTests.java
@@ -0,0 +1,27 @@
+package org.junit.internal;
+
+import org.junit.internal.builders.AnnotatedBuilderTest;
+import org.junit.internal.matchers.StacktracePrintingMatcherTest;
+import org.junit.internal.matchers.ThrowableCauseMatcherTest;
+import org.junit.internal.runners.ErrorReportingRunnerTest;
+import org.junit.internal.runners.statements.ExpectExceptionTest;
+import org.junit.internal.runners.statements.FailOnTimeoutTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AnnotatedBuilderTest.class,
+ ChecksTest.class,
+ ErrorReportingRunnerTest.class,
+ ExpectExceptionTest.class,
+ FailOnTimeoutTest.class,
+ MethodSorterTest.class,
+ StacktracePrintingMatcherTest.class,
+ StackTracesTest.class,
+ ThrowableCauseMatcherTest.class,
+ ArrayComparisonFailureTest.class
+})
+public class AllInternalTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/ArrayComparisonFailureTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/ArrayComparisonFailureTest.java
new file mode 100644
index 0000000..93db649
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/ArrayComparisonFailureTest.java
@@ -0,0 +1,68 @@
+package org.junit.internal;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class ArrayComparisonFailureTest {
+
+ private static final String ARRAY_COMPARISON_FAILURE_411 = "arrayComparisonFailure_411";
+ private static final String ARRAY_COMPARISON_FAILURE_412 = "arrayComparisonFailure_412";
+
+ /*
+ Test compatibility of older versions of ArrayComparisonFailure
+ Setup:
+ - checkout prior versions of the codebase (r4.11, r4.12 in this case)
+ - catch the exception resulting from:
+ assertArrayEquals(new int[]{0, 1}, new int[]{0, 5});
+ - serialize the resulting exception to a file, moving into the test/resources path
+ Ex., for v4.11's resulting exception {@link org/junit/internal/arrayComparisonFailure_411}
+ Current unit test:
+ - deserialize the above files casting it to the current version of the class
+ (catches any forward incompatibility with missing fields)
+ - assert the results from existing methods: getCause(), toString() -> getMessage()
+ (catches incompatible usages of fields)
+
+ This does not test if an instance of the current version of the class is able to deserialize to a previous ver.
+ */
+
+ @Test
+ public void classShouldAccept411Version() throws Exception {
+ assertFailureSerializableFromOthers(ARRAY_COMPARISON_FAILURE_411);
+ }
+
+ @Test
+ public void classShouldAccept412Version() throws Exception {
+ assertFailureSerializableFromOthers(ARRAY_COMPARISON_FAILURE_412);
+ }
+
+ private void assertFailureSerializableFromOthers(String failureFileName) throws IOException,
+ ClassNotFoundException {
+ try {
+ assertArrayEquals(new int[]{0, 1}, new int[]{0, 5});
+ fail();
+ } catch (ArrayComparisonFailure e) {
+ ArrayComparisonFailure arrayComparisonFailureFromFile = deserializeFailureFromFile(failureFileName);
+ assertNotNull("ArrayComparisonFailure.getCause() should fallback to the deprecated fCause field"
+ + " for compatibility with older versions of junit4 that didn't use Throwable.initCause().",
+ arrayComparisonFailureFromFile.getCause());
+ assertEquals(e.getCause().toString(), arrayComparisonFailureFromFile.getCause().toString());
+ assertEquals(e.toString(), arrayComparisonFailureFromFile.toString());
+ }
+ }
+
+ private ArrayComparisonFailure deserializeFailureFromFile(String fileName) throws IOException,
+ ClassNotFoundException {
+ InputStream resource = getClass().getResourceAsStream(fileName);
+ ObjectInputStream objectInputStream = new ObjectInputStream(resource);
+ return (ArrayComparisonFailure) objectInputStream.readObject();
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/ChecksTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/ChecksTest.java
new file mode 100644
index 0000000..29cfbd1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/ChecksTest.java
@@ -0,0 +1,60 @@
+package org.junit.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+import static org.junit.internal.Checks.notNull;
+import org.junit.Test;
+
+/** Tests for {@link Checks}. */
+public class ChecksTest {
+
+ @Test
+ public void notNullShouldReturnNonNullValues() {
+ Double value = Double.valueOf(3.14);
+
+ Double result = notNull(value);
+
+ assertSame(value, result);
+ }
+
+ @Test
+ public void notNullShouldThrowOnNullValues() {
+ try {
+ notNull(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ assertNull("message should be null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void notNullWithMessageShouldReturnNonNullValues() {
+ Float value = Float.valueOf(3.14f);
+
+ Float result = notNull(value, "woops");
+
+ assertSame(value, result);
+ }
+
+ @Test
+ public void notNullWithMessageShouldThrowOnNullValues() {
+ try {
+ notNull(null, "woops");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ assertEquals("message does not match", "woops", e.getMessage());
+ }
+ }
+
+ @Test
+ public void notNullWithNullMessageShouldThrowOnNullValues() {
+ try {
+ notNull(null, null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ assertNull("message should be null", e.getMessage());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/MethodSorterTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/MethodSorterTest.java
new file mode 100644
index 0000000..1934fa2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/MethodSorterTest.java
@@ -0,0 +1,182 @@
+package org.junit.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+public class MethodSorterTest {
+ private static final String ALPHA = "java.lang.Object alpha(int,double,java.lang.Thread)";
+ private static final String BETA = "void beta(int[][])";
+ private static final String GAMMA_VOID = "int gamma()";
+ private static final String GAMMA_BOOLEAN = "void gamma(boolean)";
+ private static final String DELTA = "void delta()";
+ private static final String EPSILON = "void epsilon()";
+ private static final String SUPER_METHOD = "void superMario()";
+ private static final String SUB_METHOD = "void subBowser()";
+
+ static class DummySortWithoutAnnotation {
+ Object alpha(int i, double d, Thread t) {
+ return null;
+ }
+
+ void beta(int[][] x) {
+ }
+
+ int gamma() {
+ return 0;
+ }
+
+ void gamma(boolean b) {
+ }
+
+ void delta() {
+ }
+
+ void epsilon() {
+ }
+ }
+
+ static class Super {
+ void superMario() {
+ }
+ }
+
+ static class Sub extends Super {
+ void subBowser() {
+ }
+ }
+
+ private List<String> getDeclaredMethodNames(Class<?> clazz) {
+ Method[] actualMethods = MethodSorter.getDeclaredMethods(clazz);
+
+ // Obtain just the names instead of the full methods.
+ List<String> names = new ArrayList<String>();
+ for (Method m : actualMethods) {
+ // Filter out synthetic methods from, e.g., coverage tools.
+ if (!m.isSynthetic()) {
+ names.add(m.toString().replace(clazz.getName() + '.', ""));
+ }
+ }
+
+ return names;
+ }
+
+ @Test
+ public void testMethodsNullSorterSelf() {
+ List<String> expected = Arrays.asList(EPSILON, BETA, ALPHA, DELTA, GAMMA_VOID, GAMMA_BOOLEAN);
+ List<String> actual = getDeclaredMethodNames(DummySortWithoutAnnotation.class);
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testMethodsNullSorterSuper() {
+ List<String> expected = Arrays.asList(SUPER_METHOD);
+ List<String> actual = getDeclaredMethodNames(Super.class);
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testMethodsNullSorterSub() {
+ List<String> expected = Arrays.asList(SUB_METHOD);
+ List<String> actual = getDeclaredMethodNames(Sub.class);
+ assertEquals(expected, actual);
+ }
+
+ @FixMethodOrder(MethodSorters.DEFAULT)
+ static class DummySortWithDefault {
+ Object alpha(int i, double d, Thread t) {
+ return null;
+ }
+
+ void beta(int[][] x) {
+ }
+
+ int gamma() {
+ return 0;
+ }
+
+ void gamma(boolean b) {
+ }
+
+ void delta() {
+ }
+
+ void epsilon() {
+ }
+ }
+
+ @Test
+ public void testDefaultMethodSorter() {
+ List<String> expected = Arrays.asList(EPSILON, BETA, ALPHA, DELTA, GAMMA_VOID, GAMMA_BOOLEAN);
+ List<String> actual = getDeclaredMethodNames(DummySortWithDefault.class);
+ assertEquals(expected, actual);
+ }
+
+ @FixMethodOrder(MethodSorters.JVM)
+ static class DummySortJvm {
+ Object alpha(int i, double d, Thread t) {
+ return null;
+ }
+
+ void beta(int[][] x) {
+ }
+
+ int gamma() {
+ return 0;
+ }
+
+ void gamma(boolean b) {
+ }
+
+ void delta() {
+ }
+
+ void epsilon() {
+ }
+ }
+
+ @Test
+ public void testJvmMethodSorter() {
+ Method[] fromJvmWithSynthetics = DummySortJvm.class.getDeclaredMethods();
+ Method[] sorted = MethodSorter.getDeclaredMethods(DummySortJvm.class);
+ assertArrayEquals(fromJvmWithSynthetics, sorted);
+ }
+
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ static class DummySortWithNameAsc {
+ Object alpha(int i, double d, Thread t) {
+ return null;
+ }
+
+ void beta(int[][] x) {
+ }
+
+ int gamma() {
+ return 0;
+ }
+
+ void gamma(boolean b) {
+ }
+
+ void delta() {
+ }
+
+ void epsilon() {
+ }
+ }
+
+ @Test
+ public void testAscendingMethodSorter() {
+ List<String> expected = Arrays.asList(ALPHA, BETA, DELTA, EPSILON, GAMMA_VOID, GAMMA_BOOLEAN);
+ List<String> actual = getDeclaredMethodNames(DummySortWithNameAsc.class);
+ assertEquals(expected, actual);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/StackTracesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/StackTracesTest.java
new file mode 100644
index 0000000..5c0e8a1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/StackTracesTest.java
@@ -0,0 +1,332 @@
+package org.junit.internal;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.regex.Pattern;
+
+import junit.tests.SampleJUnit3Tests;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.tests.SampleJUnit4Tests.*;
+
+public class StackTracesTest {
+ private static final String EOL = System.getProperty("line.separator", "\n");
+ private static ExecutorService executorService;
+
+ @BeforeClass
+ public static void startExecutorService() {
+ executorService = Executors.newFixedThreadPool(1);
+ }
+
+ @AfterClass
+ public static void shutDownExecutorService() {
+ executorService.shutdown();
+ executorService = null;
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInTestMethod() {
+ Result result = runTest(TestWithOneThrowingTestMethod.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$TestWithOneThrowingTestMethod.alwaysThrows"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInTestMethodWithCause() {
+ Result result = runTest(TestWithOneThrowingTestMethodWithCause.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: outer"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithCause"),
+ at("org.junit.tests.SampleJUnit4Tests$TestWithOneThrowingTestMethodWithCause.alwaysThrows"),
+ framesTrimmed(),
+ message("Caused by: java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithCause"),
+ framesInCommon());
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInBeforeMethod() {
+ Result result = runTest(TestWithThrowingBeforeMethod.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$TestWithThrowingBeforeMethod.alwaysThrows"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit3TestFailingInTestMethod() {
+ Result result = runTest(SampleJUnit3Tests.TestWithOneThrowingTestMethod.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("junit.tests.SampleJUnit3Tests$TestWithOneThrowingTestMethod.testAlwaysThrows"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit3TestFailingInSetupMethod() {
+ Result result = runTest(SampleJUnit3Tests.TestWithThrowingSetUpMethod.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("junit.tests.SampleJUnit3Tests$TestWithThrowingSetUpMethod.setUp"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInTestRule() {
+ Result result = runTest(TestWithThrowingTestRule.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$ThrowingTestRule.apply"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInClassRule() {
+ Result result = runTest(TestWithThrowingClassRule.class);
+ assertEquals("No tests were executed", 0, result.getRunCount());
+ assertEquals("One failure", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$ThrowingTestRule.apply"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackForJUnit4TestFailingInMethodRule() {
+ Result result = runTest(TestWithThrowingMethodRule.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: cause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"),
+ at("org.junit.tests.SampleJUnit4Tests$ThrowingMethodRule.apply"));
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ @Test
+ public void getTrimmedStackWithSuppressedExceptions() {
+ assumeTrue("Running on 1.7+", TestWithSuppressedException.addSuppressed != null);
+ Result result = runTest(TestWithSuppressedException.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("One test should fail", 1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+
+ assertHasTrimmedTrace(failure,
+ message("java.lang.RuntimeException: error"),
+ at("org.junit.tests.SampleJUnit4Tests$TestWithSuppressedException.alwaysThrows"),
+ message("\tSuppressed: java.lang.RuntimeException: suppressed"),
+ at("org.junit.tests.SampleJUnit4Tests$TestWithSuppressedException.alwaysThrows"),
+ framesInCommon());
+ assertNotEquals(failure.getTrace(), failure.getTrimmedTrace());
+ }
+
+ private abstract static class StringMatcher extends TypeSafeMatcher<String> {
+ }
+
+ /**
+ * A matcher that matches the exception message in a stack trace.
+ */
+ private static class ExceptionMessageMatcher extends StringMatcher {
+ private final Matcher<String> matcher;
+
+ public ExceptionMessageMatcher(String message) {
+ matcher = CoreMatchers.equalTo(message);
+ }
+
+ public void describeTo(Description description) {
+ matcher.describeTo(description);
+ }
+
+ @Override
+ protected boolean matchesSafely(String line) {
+ return matcher.matches(line);
+ }
+ }
+
+ /** Returns a matcher that matches the message line in a stack trace. */
+ private static StringMatcher message(String message) {
+ return new ExceptionMessageMatcher(message);
+ }
+
+ /**
+ * A matcher that matches the "at ..." line in a stack trace.
+ */
+ private static class StackTraceLineMatcher extends StringMatcher {
+ private static final Pattern PATTERN
+ = Pattern.compile("\t*at ([a-zA-Z0-9.$]+)\\([a-zA-Z0-9]+\\.java:[0-9]+\\)");
+
+ private final String method;
+
+ public StackTraceLineMatcher(String method) {
+ this.method = method;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("A stack trace line for method " + method);
+ }
+
+ @Override
+ protected boolean matchesSafely(String line) {
+ if (!line.startsWith("\t")) {
+ return false;
+ }
+
+ line = line.substring(1);
+ java.util.regex.Matcher matcher = PATTERN.matcher(line);
+ if (!matcher.matches()) {
+ fail("Line does not look like a stack trace line: " + line);
+ }
+ String matchedMethod = matcher.group(1);
+ return method.equals(matchedMethod);
+ }
+ }
+
+ /** Returns a matcher that matches the "at ..." line in a stack trace. */
+ private static StringMatcher at(String method) {
+ return new StackTraceLineMatcher(method);
+ }
+
+ /**
+ * A matcher that matches the line printed when frames were removed from a stack trace.
+ */
+ private static class FramesRemovedMatcher extends StringMatcher {
+ private static final Pattern PATTERN
+ = Pattern.compile("\t*\\.\\.\\. [0-9]+ ([a-z]+)");
+
+ private final String suffix;
+
+ public FramesRemovedMatcher(String suffix) {
+ this.suffix = suffix;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("A line matching \"..x " + suffix + "\"");
+ }
+
+ @Override
+ protected boolean matchesSafely(String line) {
+ if (!line.startsWith("\t")) {
+ return false;
+ }
+ line = line.substring(1);
+
+ java.util.regex.Matcher matcher = PATTERN.matcher(line);
+ if (!matcher.matches()) {
+ fail("Line does not look like a stack trace line: " + line);
+ }
+ return suffix.equals(matcher.group(1));
+ }
+ }
+
+ /** Returns a matcher that matches the "\t...x more" line in a stack trace. */
+ private static StringMatcher framesInCommon() {
+ return new FramesRemovedMatcher("more");
+ }
+
+ /** Returns a matcher that matches the "\t...x trimmed" line in a stack trace. */
+ private static StringMatcher framesTrimmed() {
+ return new FramesRemovedMatcher("trimmed");
+ }
+
+ private static Result runTest(final Class<?> testClass) {
+ Future<Result> future = executorService.submit(new Callable<Result>() {
+ public Result call() throws Exception {
+ JUnitCore core = new JUnitCore();
+ return core.run(testClass);
+ }
+ });
+
+ try {
+ return future.get();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Could not run test " + testClass, e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Could not run test " + testClass, e);
+ }
+ }
+
+ private static void assertHasTrimmedTrace(Failure failure, StringMatcher... matchers) {
+ String trimmedTrace = failure.getTrimmedTrace();
+ String[] lines = trimmedTrace.split(EOL);
+
+ int index = 0;
+ for (; index < lines.length && index < matchers.length; index++) {
+ String line = lines[index];
+ StringMatcher matcher = matchers[index];
+ assertThat(line, matcher);
+ }
+ if (index < lines.length) {
+ String extraLine = lines[index];
+ fail("Extra line in trimmed trace: " + extraLine);
+ } else if (index < matchers.length) {
+ StringDescription description = new StringDescription();
+ matchers[index].describeTo(description);
+ fail("Missing line in trimmed trace: " + description.toString());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/builders/AnnotatedBuilderTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/builders/AnnotatedBuilderTest.java
new file mode 100644
index 0000000..8c8f095
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/builders/AnnotatedBuilderTest.java
@@ -0,0 +1,105 @@
+package org.junit.internal.builders;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.RunnerSpy;
+import org.junit.runners.model.RunnerBuilder;
+import org.junit.runners.model.RunnerBuilderStub;
+
+public class AnnotatedBuilderTest {
+ private AnnotatedBuilder builder = new AnnotatedBuilder(new RunnerBuilderStub());
+
+ @Test
+ public void topLevelTestClassWithoutAnnotation_isRunWithDefaultRunner() throws Exception {
+ Runner runner = builder.runnerForClass(Object.class);
+ assertThat(runner, is(nullValue()));
+ }
+
+ @Test
+ public void topLevelTestClassWithAnnotation_isRunWithAnnotatedRunner() throws Exception {
+ Runner runner = builder.runnerForClass(OuterClass.class);
+ assertThat(runner, is(instanceOf(RunnerSpy.class)));
+
+ RunnerSpy runnerSpy = (RunnerSpy) runner;
+ assertThat(runnerSpy.getInvokedTestClass(), is((Object) OuterClass.class));
+ }
+
+ @Test
+ public void memberClassInsideAnnotatedTopLevelClass_isRunWithTopLevelRunner() throws Exception {
+ Runner runner = builder.runnerForClass(OuterClass.InnerClassWithoutOwnRunWith.class);
+ assertThat(runner, is(instanceOf(RunnerSpy.class)));
+
+ RunnerSpy runnerSpy = (RunnerSpy) runner;
+ assertThat(runnerSpy.getInvokedTestClass(), is((Object) OuterClass.InnerClassWithoutOwnRunWith.class));
+ }
+
+ @Test
+ public void memberClassDeepInsideAnnotatedTopLevelClass_isRunWithTopLevelRunner() throws Exception {
+ Runner runner = builder.runnerForClass(OuterClass.InnerClassWithoutOwnRunWith.MostInnerClass.class);
+ assertThat(runner, is(instanceOf(RunnerSpy.class)));
+
+ RunnerSpy runnerSpy = (RunnerSpy) runner;
+ assertThat(runnerSpy.getInvokedTestClass(), is((Object) OuterClass.InnerClassWithoutOwnRunWith.MostInnerClass.class));
+ }
+
+ @Test
+ public void annotatedMemberClassInsideAnnotatedTopLevelClass_isRunWithOwnRunner() throws Exception {
+ Runner runner = builder.runnerForClass(OuterClass.InnerClassWithOwnRunWith.class);
+ assertThat(runner, is(instanceOf(InnerRunner.class)));
+
+ RunnerSpy runnerSpy = (RunnerSpy) runner;
+ assertThat(runnerSpy.getInvokedTestClass(), is((Object) OuterClass.InnerClassWithOwnRunWith.class));
+ }
+
+ @Test
+ public void memberClassDeepInsideAnnotatedMemberClass_isRunWithParentMemberClassRunner() throws Exception {
+ Runner runner = builder.runnerForClass(OuterClass.InnerClassWithOwnRunWith.MostInnerClass.class);
+ assertThat(runner, is(instanceOf(InnerRunner.class)));
+
+ RunnerSpy runnerSpy = (RunnerSpy) runner;
+ assertThat(runnerSpy.getInvokedTestClass(), is((Object) OuterClass.InnerClassWithOwnRunWith.MostInnerClass.class));
+ }
+
+ @RunWith(RunnerSpy.class)
+ public static class OuterClass {
+ public class InnerClassWithoutOwnRunWith {
+ @Test
+ public void test() {
+ }
+
+ public class MostInnerClass {
+ @Test
+ public void test() {
+ }
+ }
+ }
+
+ @RunWith(InnerRunner.class)
+ public class InnerClassWithOwnRunWith {
+ @Test
+ public void test() {
+ }
+
+ public class MostInnerClass {
+ @Test
+ public void test() {
+ }
+ }
+ }
+ }
+
+ public static class InnerRunner extends RunnerSpy {
+ public InnerRunner(Class<?> testClass) {
+ super(testClass);
+ }
+
+ public InnerRunner(Class<?> testClass, RunnerBuilder runnerBuilder) {
+ super(testClass, runnerBuilder);
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/StacktracePrintingMatcherTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/StacktracePrintingMatcherTest.java
new file mode 100644
index 0000000..2f22c96
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/StacktracePrintingMatcherTest.java
@@ -0,0 +1,38 @@
+package org.junit.internal.matchers;
+
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.internal.matchers.StacktracePrintingMatcher.isException;
+import static org.junit.internal.matchers.StacktracePrintingMatcher.isThrowable;
+
+import org.junit.Test;
+
+public class StacktracePrintingMatcherTest {
+
+ @Test
+ public void succeedsWhenInnerMatcherSucceeds() throws Exception {
+ assertTrue(isThrowable(any(Throwable.class)).matches(new Exception()));
+ }
+
+ @Test
+ public void failsWhenInnerMatcherFails() throws Exception {
+ assertFalse(isException(notNullValue(Exception.class)).matches(null));
+ }
+
+ @Test
+ public void assertThatIncludesStacktrace() {
+ Exception actual = new IllegalArgumentException("my message");
+ Exception expected = new NullPointerException();
+
+ try {
+ assertThat(actual, isThrowable(equalTo(expected)));
+ } catch (AssertionError e) {
+ assertThat(e.getMessage(), containsString("Stacktrace was: java.lang.IllegalArgumentException: my message"));
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/ThrowableCauseMatcherTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/ThrowableCauseMatcherTest.java
new file mode 100644
index 0000000..8a169c7
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/matchers/ThrowableCauseMatcherTest.java
@@ -0,0 +1,18 @@
+package org.junit.internal.matchers;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause;
+
+public class ThrowableCauseMatcherTest {
+
+ @Test
+ public void shouldAllowCauseOfDifferentClassFromRoot() throws Exception {
+ NullPointerException expectedCause = new NullPointerException("expected");
+ Exception actual = new Exception(expectedCause);
+
+ assertThat(actual, hasCause(is(expectedCause)));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/ErrorReportingRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/ErrorReportingRunnerTest.java
new file mode 100644
index 0000000..e8263e5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/ErrorReportingRunnerTest.java
@@ -0,0 +1,88 @@
+package org.junit.internal.runners;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InvalidTestClassError;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class ErrorReportingRunnerTest {
+
+ @Test(expected = NullPointerException.class)
+ public void cannotCreateWithNullClass() {
+ new ErrorReportingRunner(null, new RuntimeException());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void cannotCreateWithNullClass2() {
+ new ErrorReportingRunner(new RuntimeException(), (Class<?>) null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void cannotCreateWithNullClasses() {
+ new ErrorReportingRunner(new RuntimeException(), (Class<?>[]) null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void cannotCreateWithoutClass() {
+ new ErrorReportingRunner(new RuntimeException());
+ }
+
+ @Test
+ public void givenInvalidTestClassErrorAsCause() {
+ final List<Failure> firedFailures = new ArrayList<Failure>();
+ InvalidTestClassError testClassError = new InvalidTestClassError(TestClassWithErrors.class,
+ Arrays.asList(new Throwable("validation error 1"), new Throwable("validation error 2")));
+ ErrorReportingRunner sut = new ErrorReportingRunner(TestClassWithErrors.class, testClassError);
+
+ sut.run(new RunNotifier() {
+ @Override
+ public void fireTestFailure(Failure failure) {
+ super.fireTestFailure(failure);
+ firedFailures.add(failure);
+ }
+ });
+
+ assertThat(firedFailures.size(), is(1));
+ Throwable exception = firedFailures.get(0).getException();
+ assertThat(exception, instanceOf(InvalidTestClassError.class));
+ assertThat(((InvalidTestClassError) exception), is(testClassError));
+ }
+
+ @Test
+ public void givenInvalidTestClass_integrationTest() {
+ Result result = JUnitCore.runClasses(TestClassWithErrors.class);
+
+ assertThat(result.getFailureCount(), is(1));
+ Throwable failure = result.getFailures().get(0).getException();
+ assertThat(failure, instanceOf(InvalidTestClassError.class));
+ assertThat(failure.getMessage(), allOf(
+ startsWith("Invalid test class '" + TestClassWithErrors.class.getName() + "'"),
+ containsString("\n 1. "),
+ containsString("\n 2. ")
+ ));
+ }
+
+ private static class TestClassWithErrors {
+ @Before public static void staticBeforeMethod() {}
+ @After public static void staticAfterMethod() {}
+
+ @Test public String testMethodReturningString() {
+ return "this should not be allowed";
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/ExpectExceptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/ExpectExceptionTest.java
new file mode 100644
index 0000000..466e289
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/ExpectExceptionTest.java
@@ -0,0 +1,88 @@
+package org.junit.internal.runners.statements;
+
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.Statement;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * Integration tests can be found in {@link org.junit.tests.running.methods.ExpectedTest}.
+ * See e.g. {@link org.junit.tests.running.methods.ExpectedTest#expectsAssumptionViolatedException()}
+ */
+public class ExpectExceptionTest {
+
+ @Test
+ public void whenExpectingAssumptionViolatedExceptionStatementsThrowingItShouldPass() {
+ Statement delegate = new Fail(new AssumptionViolatedException("expected"));
+ ExpectException expectException = new ExpectException(delegate, AssumptionViolatedException.class);
+
+ try {
+ expectException.evaluate();
+ // then AssumptionViolatedException should not be thrown
+ } catch (Throwable e) { // need to explicitly catch and re-throw as an AssertionError or it might be skipped
+ fail("should not throw anything, but was thrown: " + e);
+ }
+ }
+
+ @Test
+ public void whenExpectingAssumptionViolatedExceptionStatementsThrowingSubclassShouldPass() {
+ Statement delegate = new Fail(new AssumptionViolatedExceptionSubclass("expected"));
+ ExpectException expectException = new ExpectException(delegate, AssumptionViolatedException.class);
+
+ try {
+ expectException.evaluate();
+ // then no exception should be thrown
+ } catch (Throwable e) {
+ fail("should not throw anything, but was thrown: " + e);
+ }
+ }
+
+ @Test
+ public void whenExpectingAssumptionViolatedExceptionStatementsThrowingDifferentExceptionShouldFail() {
+ Statement delegate = new Fail(new SomeException("not expected"));
+ ExpectException expectException = new ExpectException(delegate, AssumptionViolatedException.class);
+
+ try {
+ expectException.evaluate();
+ fail("should throw 'Unexpected exception' when statement throws an exception which is not the one expected");
+ } catch (Exception e) {
+ assertThat(e.getMessage(), equalTo("Unexpected exception, expected<org.junit.internal.AssumptionViolatedException> " +
+ "but was<org.junit.internal.runners.statements.ExpectExceptionTest$SomeException>"));
+ }
+ }
+
+ @Test
+ public void whenExpectingAssumptionViolatedExceptionStatementsPassingShouldFail() throws Exception {
+ ExpectException expectException = new ExpectException(new PassingStatement(), AssumptionViolatedException.class);
+
+ try {
+ expectException.evaluate();
+ } catch (AssertionError e) {
+ assertThat(e.getMessage(), containsString("Expected exception: " + AssumptionViolatedException.class.getName()));
+ return;
+ }
+ fail("ExpectException should throw when the given statement passes");
+ }
+
+ private static class PassingStatement extends Statement {
+ public void evaluate() throws Throwable {
+ // nop
+ }
+ }
+
+ private static class SomeException extends RuntimeException {
+ public SomeException(String message) {
+ super(message);
+ }
+ }
+
+ private static class AssumptionViolatedExceptionSubclass extends AssumptionViolatedException {
+ public AssumptionViolatedExceptionSubclass(String assumption) {
+ super(assumption);
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java
new file mode 100644
index 0000000..8bf7823
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java
@@ -0,0 +1,271 @@
+package org.junit.internal.runners.statements;
+
+import static java.lang.Long.MAX_VALUE;
+import static java.lang.Math.atan;
+import static java.lang.System.currentTimeMillis;
+import static java.lang.Thread.currentThread;
+import static java.lang.Thread.interrupted;
+import static java.lang.Thread.sleep;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.Test;
+import org.junit.function.ThrowingRunnable;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestTimedOutException;
+
+
+/**
+ * @author Asaf Ary, Stefan Birkner
+ */
+@RunWith(Parameterized.class)
+public class FailOnTimeoutTest {
+
+ @Parameters(name = "lookingForStuckThread = {0}")
+ public static Iterable<Boolean> getParameters() {
+ return Arrays.asList(Boolean.TRUE, Boolean.FALSE);
+ }
+
+ @Parameter
+ public boolean lookingForStuckThread;
+
+ @Test
+ public void noExceptionIsThrownWhenWrappedStatementFinishesBeforeTimeoutWithoutThrowingException()
+ throws Throwable {
+ FailOnTimeout failOnTimeout = failAfter50Ms(new FastStatement());
+
+ failOnTimeout.evaluate();
+
+ // test is successful when no exception is thrown
+ }
+
+ @Test
+ public void throwsTestTimedOutExceptionWithMeaningfulMessage() {
+ Exception e = assertThrows(
+ TestTimedOutException.class,
+ run(failAfter50Ms(new RunForASecond())));
+ assertEquals("test timed out after 50 milliseconds", e.getMessage());
+ }
+
+ @Test
+ public void sendUpExceptionThrownByStatement() {
+ Exception exception = new RuntimeException();
+ Exception e = assertThrows(
+ Exception.class,
+ run(failAfter50Ms(new Fail(exception))));
+ assertSame(exception, e);
+ }
+
+ @Test
+ public void throwExceptionIfTheSecondCallToEvaluateNeedsTooMuchTime()
+ throws Throwable {
+ DelegatingStatement statement = new DelegatingStatement();
+ FailOnTimeout failOnTimeout = failAfter50Ms(statement);
+
+ statement.delegate = new FastStatement();
+ failOnTimeout.evaluate();
+
+ statement.delegate = new RunForASecond();
+ assertThrows(
+ TestTimedOutException.class,
+ run(failOnTimeout));
+ }
+
+ @Test
+ public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() {
+ DelegatingStatement statement = new DelegatingStatement();
+ FailOnTimeout failOnTimeout = failAfter50Ms(statement);
+
+ statement.delegate = new Fail(new AssertionError("first execution failed"));
+ assertThrows(
+ AssertionError.class,
+ run(failOnTimeout)
+ );
+
+ statement.delegate = new RunForASecond();
+ assertThrows(
+ TestTimedOutException.class,
+ run(failOnTimeout));
+ }
+
+ @Test
+ public void throwsExceptionWithTimeoutValueAndTimeUnitSet() {
+ TestTimedOutException e = assertThrows(
+ TestTimedOutException.class,
+ run(failAfter50Ms(new RunForASecond())));
+ assertEquals(50, e.getTimeout());
+ assertEquals(MILLISECONDS, e.getTimeUnit());
+ }
+
+ @Test
+ public void statementThatCanBeInterruptedIsStoppedAfterTimeout() throws Throwable {
+ // RunForASecond can be interrupted because it checks the Thread's
+ // interrupted flag.
+ RunForASecond runForASecond = new RunForASecond();
+ assertThrows(
+ TestTimedOutException.class,
+ run(failAfter50Ms(runForASecond)));
+
+ // Thread is explicitly stopped if it finishes faster than its
+ // pre-defined execution time of one second.
+ boolean stopped = runForASecond.finished.await(50, MILLISECONDS);
+ assertTrue("Thread has not been stopped.", stopped);
+ }
+
+ @Test
+ public void stackTraceContainsRealCauseOfTimeout() {
+ TestTimedOutException timedOutException = assertThrows(
+ TestTimedOutException.class,
+ run(failAfter50Ms(new StuckStatement())));
+
+ StackTraceElement[] stackTrace = timedOutException.getStackTrace();
+ boolean stackTraceContainsTheRealCauseOfTheTimeout = false;
+ boolean stackTraceContainsOtherThanTheRealCauseOfTheTimeout = false;
+ for (StackTraceElement element : stackTrace) {
+ String methodName = element.getMethodName();
+ if ("theRealCauseOfTheTimeout".equals(methodName)) {
+ stackTraceContainsTheRealCauseOfTheTimeout = true;
+ }
+ if ("notTheRealCauseOfTheTimeout".equals(methodName)) {
+ stackTraceContainsOtherThanTheRealCauseOfTheTimeout = true;
+ }
+ }
+ assertTrue(
+ "Stack trace does not contain the real cause of the timeout",
+ stackTraceContainsTheRealCauseOfTheTimeout);
+ assertFalse(
+ "Stack trace contains other than the real cause of the timeout, which can be very misleading",
+ stackTraceContainsOtherThanTheRealCauseOfTheTimeout);
+ }
+
+ private static final class StuckStatement extends Statement {
+
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ // Must show up in stack trace
+ theRealCauseOfTheTimeout();
+ } catch (InterruptedException e) {
+ } finally {
+ // Must _not_ show up in stack trace
+ notTheRealCauseOfTheTimeout();
+ }
+ }
+
+ private void theRealCauseOfTheTimeout() throws InterruptedException {
+ sleep(MAX_VALUE);
+ }
+
+ private void notTheRealCauseOfTheTimeout() {
+ for (long now = currentTimeMillis(), eta = now + 1000L; now < eta; now = currentTimeMillis()) {
+ // Doesn't matter, just pretend to be busy
+ atan(now);
+ }
+ }
+ }
+
+ @Test
+ public void lookingForStuckThread_threadGroupNotLeaked() throws Throwable {
+ assumeTrue(lookingForStuckThread);
+ final AtomicReference<ThreadGroup> innerThreadGroup = new AtomicReference<ThreadGroup>();
+ final AtomicReference<Thread> innerThread = new AtomicReference<Thread>();
+ final ThreadGroup outerThreadGroup = currentThread().getThreadGroup();
+ FailOnTimeout failOnTimeout = failAfter50Ms(new Statement() {
+ @Override
+ public void evaluate() {
+ innerThread.set(currentThread());
+ ThreadGroup group = currentThread().getThreadGroup();
+ assertNotSame("inner thread should use a different thread group",
+ outerThreadGroup, group);
+ innerThreadGroup.set(group);
+ assertTrue("the 'FailOnTimeoutGroup' thread group should be a daemon thread group",
+ group.isDaemon());
+ }
+ });
+
+ failOnTimeout.evaluate();
+
+ assertNotNull("the Statement was never run", innerThread.get());
+ innerThread.get().join();
+ assertTrue("the 'FailOnTimeoutGroup' thread group should be destroyed after running the test",
+ innerThreadGroup.get().isDestroyed());
+ }
+
+ @Test
+ public void notLookingForStuckThread_usesSameThreadGroup() throws Throwable {
+ assumeFalse(lookingForStuckThread);
+ final AtomicBoolean statementWasExecuted = new AtomicBoolean();
+ final ThreadGroup outerThreadGroup = currentThread().getThreadGroup();
+ FailOnTimeout failOnTimeout = failAfter50Ms(new Statement() {
+ @Override
+ public void evaluate() {
+ statementWasExecuted.set(true);
+ ThreadGroup group = currentThread().getThreadGroup();
+ assertSame("inner thread should use the same thread group", outerThreadGroup, group);
+ }
+ });
+
+ failOnTimeout.evaluate();
+
+ assertTrue("the Statement was never run", statementWasExecuted.get());
+ }
+
+ private FailOnTimeout failAfter50Ms(Statement statement) {
+ return FailOnTimeout.builder()
+ .withTimeout(50, MILLISECONDS)
+ .withLookingForStuckThread(lookingForStuckThread)
+ .build(statement);
+ }
+
+ private ThrowingRunnable run(final FailOnTimeout failOnTimeout) {
+ return new ThrowingRunnable() {
+ public void run() throws Throwable {
+ failOnTimeout.evaluate();
+ }
+ };
+ }
+
+ private static class DelegatingStatement extends Statement {
+ volatile Statement delegate;
+
+ @Override
+ public void evaluate() throws Throwable {
+ delegate.evaluate();
+ }
+ }
+
+ private static class FastStatement extends Statement {
+ @Override
+ public void evaluate() throws Throwable {
+ }
+ }
+
+ private static final class RunForASecond extends Statement {
+ final CountDownLatch finished = new CountDownLatch(1);
+
+ @Override
+ public void evaluate() throws Throwable {
+ long timeout = currentTimeMillis() + 1000L;
+ while (!interrupted() && currentTimeMillis() < timeout) {
+ }
+ finished.countDown();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/AllRulesTests.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/AllRulesTests.java
new file mode 100644
index 0000000..8b63e15
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/AllRulesTests.java
@@ -0,0 +1,31 @@
+package org.junit.rules;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ BlockJUnit4ClassRunnerOverrideTest.class,
+ ClassRulesTest.class,
+ DisableOnDebugTest.class,
+ ErrorCollectorTest.class,
+ ExpectedExceptionTest.class,
+ ExternalResourceRuleTest.class,
+ MethodRulesTest.class,
+ NameRulesTest.class,
+ RuleChainTest.class,
+ RuleMemberValidatorTest.class,
+ StopwatchTest.class,
+ TempFolderRuleTest.class,
+ TemporaryFolderRuleAssuredDeletionTest.class,
+ TemporaryFolderUsageTest.class,
+ TestRuleTest.class,
+ TestWatcherTest.class,
+ TestWatchmanTest.class,
+ TestWatchmanTest.class,
+ TimeoutRuleTest.class,
+ VerifierRuleTest.class
+})
+public class AllRulesTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/BlockJUnit4ClassRunnerOverrideTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/BlockJUnit4ClassRunnerOverrideTest.java
new file mode 100644
index 0000000..4f85be0
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/BlockJUnit4ClassRunnerOverrideTest.java
@@ -0,0 +1,175 @@
+package org.junit.rules;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+public class BlockJUnit4ClassRunnerOverrideTest {
+ public static class FlipBitRule implements MethodRule {
+ public Statement apply(final Statement base, FrameworkMethod method,
+ final Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ target.getClass().getField("flipBit").set(target, true);
+ base.evaluate();
+ }
+ };
+ }
+
+ }
+
+ public static class OverrideRulesRunner extends BlockJUnit4ClassRunner {
+ public OverrideRulesRunner(Class<?> klass) throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ protected List<MethodRule> rules(Object test) {
+ final LinkedList<MethodRule> methodRules = new LinkedList<MethodRule>(
+ super.rules(test));
+ methodRules.add(new FlipBitRule());
+ return methodRules;
+ }
+ }
+
+ @RunWith(OverrideRulesRunner.class)
+ public static class OverrideRulesTest {
+ public boolean flipBit = false;
+
+ @Test
+ public void testFlipBit() {
+ assertTrue(flipBit);
+ }
+ }
+
+ @Test
+ public void overrideRulesMethod() {
+ assertThat(testResult(OverrideTestRulesTest.class), isSuccessful());
+ }
+
+ public static class OverrideTestRulesRunner extends BlockJUnit4ClassRunner {
+ public OverrideTestRulesRunner(Class<?> klass)
+ throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ protected List<TestRule> getTestRules(final Object test) {
+ final LinkedList<TestRule> methodRules = new LinkedList<TestRule>(
+ super.getTestRules(test));
+ methodRules.add(new TestRule() {
+ public Statement apply(Statement base, Description description) {
+ return new FlipBitRule().apply(base, null, test);
+ }
+ });
+ return methodRules;
+ }
+ }
+
+ @RunWith(OverrideTestRulesRunner.class)
+ public static class OverrideTestRulesTest extends OverrideRulesTest {
+ }
+
+ @Test
+ public void overrideTestRulesMethod() {
+ assertThat(testResult(OverrideRulesTest.class), isSuccessful());
+ }
+
+
+ /**
+ * Runner for testing override of {@link org.junit.runners.BlockJUnit4ClassRunner#createTest(org.junit.runners.model.FrameworkMethod)}
+ * by setting the {@link org.junit.runners.model.FrameworkMethod} in a field
+ * of the test class so it can be compared with the test method that is being
+ * executed.
+ */
+ public static class OverrideCreateTestRunner extends BlockJUnit4ClassRunner {
+ public OverrideCreateTestRunner(final Class<?> klass) throws InitializationError {
+ super(klass);
+
+ assert(klass.equals(OverrideCreateTest.class));
+ }
+
+ @Override
+ protected Object createTest(FrameworkMethod method) {
+ final OverrideCreateTest obj = new OverrideCreateTest();
+
+ obj.method = method;
+
+ return obj;
+ }
+ }
+
+ @RunWith(OverrideCreateTestRunner.class)
+ public static class OverrideCreateTest {
+ public FrameworkMethod method;
+
+ @Test
+ public void testMethodA() {
+ assertEquals("testMethodA", method.getMethod().getName());
+ }
+
+ @Test
+ public void testMethodB() {
+ assertEquals("testMethodB", method.getMethod().getName());
+ }
+ }
+
+ @Test
+ public void overrideCreateTestMethod() {
+ assertThat(testResult(OverrideCreateTest.class), isSuccessful());
+ }
+
+
+ /**
+ * Runner for testing override of {@link org.junit.runners.BlockJUnit4ClassRunner#createTest()}
+ * is still called by default if no other {@code createTest} method override
+ * is in place. This is tested by setting a boolean flag in a field of the
+ * test class so it can be checked to confirm that the createTest method was
+ * called.
+ */
+ public static class CreateTestDefersToNoArgCreateTestRunner extends BlockJUnit4ClassRunner {
+ public CreateTestDefersToNoArgCreateTestRunner(final Class<?> klass) throws InitializationError {
+ super(klass);
+
+ assert(klass.equals(CreateTestDefersToNoArgCreateTestTest.class));
+ }
+
+ @Override
+ protected Object createTest() {
+ final CreateTestDefersToNoArgCreateTestTest obj = new CreateTestDefersToNoArgCreateTestTest();
+
+ obj.createTestCalled = true;
+
+ return obj;
+ }
+ }
+
+ @RunWith(CreateTestDefersToNoArgCreateTestRunner.class)
+ public static class CreateTestDefersToNoArgCreateTestTest {
+ public boolean createTestCalled = false;
+
+ @Test
+ public void testCreateTestCalled() {
+ assertEquals(true, createTestCalled);
+ }
+ }
+
+ @Test
+ public void createTestDefersToNoArgCreateTest() {
+ assertThat(testResult(CreateTestDefersToNoArgCreateTestTest.class), isSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/ClassRulesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/ClassRulesTest.java
new file mode 100644
index 0000000..ddfb744
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/ClassRulesTest.java
@@ -0,0 +1,366 @@
+/*
+ * Created Oct 19, 2009
+ */
+package org.junit.rules;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * Tests to exercise class-level rules.
+ */
+public class ClassRulesTest {
+ public static class Counter extends ExternalResource {
+ public int count = 0;
+
+ @Override
+ protected void before() throws Throwable {
+ count++;
+ }
+ }
+
+ public static class ExampleTestWithClassRule {
+ @ClassRule
+ public static Counter counter = new Counter();
+
+ @Test
+ public void firstTest() {
+ assertEquals(1, counter.count);
+ }
+
+ @Test
+ public void secondTest() {
+ assertEquals(1, counter.count);
+ }
+ }
+
+ @Test
+ public void ruleIsAppliedOnce() {
+ ExampleTestWithClassRule.counter.count = 0;
+ JUnitCore.runClasses(ExampleTestWithClassRule.class);
+ assertEquals(1, ExampleTestWithClassRule.counter.count);
+ }
+
+ public static class SubclassOfTestWithClassRule extends
+ ExampleTestWithClassRule {
+
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluatedOnSubclass() {
+ ExampleTestWithClassRule.counter.count = 0;
+ JUnitCore.runClasses(SubclassOfTestWithClassRule.class);
+ assertEquals(1, ExampleTestWithClassRule.counter.count);
+ }
+
+ public static class CustomCounter implements TestRule {
+ public int count = 0;
+
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ count++;
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class ExampleTestWithCustomClassRule {
+ @ClassRule
+ public static CustomCounter counter = new CustomCounter();
+
+ @Test
+ public void firstTest() {
+ assertEquals(1, counter.count);
+ }
+
+ @Test
+ public void secondTest() {
+ assertEquals(1, counter.count);
+ }
+ }
+
+
+ @Test
+ public void customRuleIsAppliedOnce() {
+ ExampleTestWithCustomClassRule.counter.count = 0;
+ Result result = JUnitCore.runClasses(ExampleTestWithCustomClassRule.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(1, ExampleTestWithCustomClassRule.counter.count);
+ }
+
+ private static final List<String> orderList = new LinkedList<String>();
+
+ private static class OrderTestRule implements TestRule {
+ private String name;
+
+ public OrderTestRule(String name) {
+ this.name = name;
+ }
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ orderList.add(name);
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class UsesFieldAndMethodRule {
+ @ClassRule
+ public static OrderTestRule orderMethod() {
+ return new OrderTestRule("orderMethod");
+ }
+
+ @ClassRule
+ public static OrderTestRule orderField = new OrderTestRule("orderField");
+
+ @Test
+ public void foo() {
+ assertEquals("orderField", orderList.get(0));
+ assertEquals("orderMethod", orderList.get(1));
+ }
+ }
+
+ @Test
+ public void usesFieldAndMethodRule() {
+ orderList.clear();
+ assertThat(testResult(UsesFieldAndMethodRule.class), isSuccessful());
+ }
+
+
+ public static class MethodExampleTestWithClassRule {
+ private static Counter counter = new Counter();
+
+ @ClassRule
+ public static Counter getCounter() {
+ return counter;
+ }
+
+ @Test
+ public void firstTest() {
+ assertEquals(1, counter.count);
+ }
+
+ @Test
+ public void secondTest() {
+ assertEquals(1, counter.count);
+ }
+ }
+
+ @Test
+ public void methodRuleIsAppliedOnce() {
+ MethodExampleTestWithClassRule.counter.count = 0;
+ JUnitCore.runClasses(MethodExampleTestWithClassRule.class);
+ assertEquals(1, MethodExampleTestWithClassRule.counter.count);
+ }
+
+ public static class MethodSubclassOfTestWithClassRule extends
+ MethodExampleTestWithClassRule {
+
+ }
+
+ @Test
+ public void methodRuleIsIntroducedAndEvaluatedOnSubclass() {
+ MethodExampleTestWithClassRule.counter.count = 0;
+ JUnitCore.runClasses(MethodSubclassOfTestWithClassRule.class);
+ assertEquals(1, MethodExampleTestWithClassRule.counter.count);
+ }
+
+ public static class MethodExampleTestWithCustomClassRule {
+ private static CustomCounter counter = new CustomCounter();
+
+ @ClassRule
+ public static CustomCounter getCounter() {
+ return counter;
+ }
+
+ @Test
+ public void firstTest() {
+ assertEquals(1, counter.count);
+ }
+
+ @Test
+ public void secondTest() {
+ assertEquals(1, counter.count);
+ }
+ }
+
+
+ @Test
+ public void methodCustomRuleIsAppliedOnce() {
+ MethodExampleTestWithCustomClassRule.counter.count = 0;
+ Result result = JUnitCore.runClasses(MethodExampleTestWithCustomClassRule.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(1, MethodExampleTestWithCustomClassRule.counter.count);
+ }
+
+ public static class CallMethodOnlyOnceRule {
+ static int countOfMethodCalls = 0;
+
+ private static class Dummy implements TestRule {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ @ClassRule
+ public static Dummy both() {
+ countOfMethodCalls++;
+ return new Dummy();
+ }
+
+ @Test
+ public void onlyOnce() {
+ assertEquals(1, countOfMethodCalls);
+ }
+ }
+
+ @Test
+ public void testCallMethodOnlyOnceRule() {
+ CallMethodOnlyOnceRule.countOfMethodCalls = 0;
+ assertTrue(JUnitCore.runClasses(CallMethodOnlyOnceRule.class).wasSuccessful());
+ }
+
+ private static final StringBuilder log = new StringBuilder();
+
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class ClassRuleOrdering {
+ @ClassRule(order = 1)
+ public static TestRule a() {
+ return new LoggingTestRule(log, "outer");
+ }
+
+ @ClassRule(order = 2)
+ public static TestRule z() {
+ return new LoggingTestRule(log, "inner");
+ }
+
+ @Test
+ public void foo() {
+ log.append(" foo");
+ }
+
+ @Test
+ public void bar() {
+ log.append(" bar");
+ }
+ }
+
+ @Test
+ public void classRuleOrdering() {
+ log.setLength(0);
+ Result result = JUnitCore.runClasses(ClassRuleOrdering.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" outer.begin inner.begin bar foo inner.end outer.end", log.toString());
+ }
+
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class ClassRuleOrderingDefault {
+ @ClassRule
+ public static TestRule a() {
+ return new LoggingTestRule(log, "outer");
+ }
+
+ @ClassRule
+ public static TestRule b() {
+ return new LoggingTestRule(log, "inner");
+ }
+
+ @Test
+ public void foo() {
+ log.append(" foo");
+ }
+
+ @Test
+ public void bar() {
+ log.append(" bar");
+ }
+ }
+
+ @Test
+ public void classRuleOrderingDefault() {
+ log.setLength(0);
+ Result result = JUnitCore.runClasses(ClassRuleOrderingDefault.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" inner.begin outer.begin bar foo outer.end inner.end", log.toString());
+ }
+
+ public static class RunnerWithClassRuleAddedProgrammatically extends BlockJUnit4ClassRunner {
+ public RunnerWithClassRuleAddedProgrammatically(Class testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ @Override
+ protected List<TestRule> classRules() {
+ final List<TestRule> rules = super.classRules();
+ rules.add(new LoggingTestRule(log, "fromCode"));
+ return rules;
+ }
+ }
+
+ @RunWith(RunnerWithClassRuleAddedProgrammatically.class)
+ public static class ClassRulesModifiableListEmpty {
+ @Test
+ public void test() {
+ log.append(" test");
+ }
+ }
+
+ @Test
+ public void classRulesModifiableListEmpty() {
+ log.setLength(0);
+ Result result = JUnitCore.runClasses(ClassRulesModifiableListEmpty.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" fromCode.begin test fromCode.end", log.toString());
+ }
+
+ @RunWith(RunnerWithClassRuleAddedProgrammatically.class)
+ public static class ClassRulesModifiableList {
+ @ClassRule
+ public static TestRule classRule() {
+ return new LoggingTestRule(log, "classRule");
+ }
+
+ @Test
+ public void test() {
+ log.append(" test");
+ }
+ }
+
+ @Test
+ public void classRulesModifiableList() {
+ log.setLength(0);
+ Result result = JUnitCore.runClasses(ClassRulesModifiableList.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" fromCode.begin classRule.begin test classRule.end fromCode.end", log.toString());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/DisableOnDebugTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/DisableOnDebugTest.java
new file mode 100644
index 0000000..8bf6b9d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/DisableOnDebugTest.java
@@ -0,0 +1,164 @@
+package org.junit.rules;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runners.model.Statement;
+
+public class DisableOnDebugTest {
+ private static final List<String> WITHOUT_DEBUG_ARGUMENTS = Collections
+ .emptyList();
+
+ private static final List<String> PRE_JAVA5_DEBUG_ARGUMENTS = Arrays
+ .asList("-Xdebug",
+ "-Xrunjdwp:transport=dt_socket,server=y,address=8000");
+
+ private static final List<String> PRE_JAVA5_DEBUG_ARGUMENTS_IN_REVERSE_ORDER = Arrays
+ .asList("-Xrunjdwp:transport=dt_socket,server=y,address=8000",
+ "-Xdebug");
+
+ private static final List<String> POST_JAVA5_DEBUG_ARGUMENTS = Arrays
+ .asList("-agentlib:jdwp=transport=dt_socket,server=y,address=8000");
+
+ /**
+ * Nasty rule that always fails
+ */
+ private static class FailOnExecution implements TestRule {
+
+ public Statement apply(Statement base,
+ Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ throw new AssertionError();
+ }
+ };
+ }
+
+ }
+
+ public abstract static class AbstractDisableOnDebugTest {
+
+ @Rule
+ public TestRule failOnExecution;
+
+ public AbstractDisableOnDebugTest(List<String> arguments) {
+ this.failOnExecution = new DisableOnDebug(new FailOnExecution(),
+ arguments);
+ }
+
+ @Test
+ public void test() {
+ }
+ }
+
+ public static class PreJava5DebugArgumentsTest extends
+ AbstractDisableOnDebugTest {
+
+ public PreJava5DebugArgumentsTest() {
+ super(PRE_JAVA5_DEBUG_ARGUMENTS);
+ }
+
+ }
+
+ public static class PreJava5DebugArgumentsReversedTest extends
+ AbstractDisableOnDebugTest {
+
+ public PreJava5DebugArgumentsReversedTest() {
+ super(PRE_JAVA5_DEBUG_ARGUMENTS_IN_REVERSE_ORDER);
+ }
+
+ }
+
+ public static class PostJava5DebugArgumentsTest extends
+ AbstractDisableOnDebugTest {
+
+ public PostJava5DebugArgumentsTest() {
+ super(POST_JAVA5_DEBUG_ARGUMENTS);
+ }
+
+ }
+
+ public static class WithoutDebugArgumentsTest extends
+ AbstractDisableOnDebugTest {
+
+ public WithoutDebugArgumentsTest() {
+ super(WITHOUT_DEBUG_ARGUMENTS);
+ }
+
+ }
+
+ @Test
+ public void givenPreJava5DebugArgumentsIsDebuggingShouldReturnTrue() {
+ DisableOnDebug subject = new DisableOnDebug(
+ new FailOnExecution(), PRE_JAVA5_DEBUG_ARGUMENTS);
+ assertTrue("Should be debugging", subject.isDebugging());
+ }
+
+ @Test
+ public void givenPreJava5DebugArgumentsInReverseIsDebuggingShouldReturnTrue() {
+ DisableOnDebug subject = new DisableOnDebug(
+ new FailOnExecution(),
+ PRE_JAVA5_DEBUG_ARGUMENTS_IN_REVERSE_ORDER);
+ assertTrue("Should be debugging", subject.isDebugging());
+ }
+
+ @Test
+ public void givenPostJava5DebugArgumentsIsDebuggingShouldReturnTrue() {
+ DisableOnDebug subject = new DisableOnDebug(
+ new FailOnExecution(), POST_JAVA5_DEBUG_ARGUMENTS);
+ assertTrue("Should be debugging", subject.isDebugging());
+ }
+
+ @Test
+ public void givenArgumentsWithoutDebugFlagsIsDebuggingShouldReturnFalse() {
+ DisableOnDebug subject = new DisableOnDebug(
+ new FailOnExecution(), WITHOUT_DEBUG_ARGUMENTS);
+ Assert.assertFalse("Should not be debugging", subject.isDebugging());
+ }
+
+ @Test
+ public void whenRunWithPreJava5DebugArgumentsTestShouldFail() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(PreJava5DebugArgumentsTest.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should not have failed", 0, result.getFailureCount());
+ }
+
+ @Test
+ public void whenRunWithPreJava5DebugArgumentsInReverseOrderTestShouldFail() {
+ JUnitCore core = new JUnitCore();
+ Result result = core
+ .run(PreJava5DebugArgumentsReversedTest.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should not have failed", 0, result.getFailureCount());
+ }
+
+ @Test
+ public void whenRunWithPostJava5DebugArgumentsTestShouldFail() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(PostJava5DebugArgumentsTest.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should not have failed", 0, result.getFailureCount());
+ }
+
+ @Test
+ public void whenRunWithoutDebugFlagsTestShouldPass() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(WithoutDebugArgumentsTest.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should have failed", 1, result.getFailureCount());
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/ErrorCollectorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/ErrorCollectorTest.java
new file mode 100644
index 0000000..385a146
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/ErrorCollectorTest.java
@@ -0,0 +1,327 @@
+package org.junit.rules;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.concurrent.Callable;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.rules.EventCollector.*;
+
+@RunWith(Parameterized.class)
+public class ErrorCollectorTest {
+
+ @Parameters(name= "{0}")
+ public static Object[][] testsWithEventMatcher() {
+ return new Object[][]{
+ {
+ AddSingleError.class,
+ hasSingleFailureWithMessage("message")},
+ {
+ AddTwoErrors.class,
+ hasNumberOfFailures(2)},
+ {
+ AddInternalAssumptionViolatedException.class,
+ allOf(hasSingleFailure(), hasNoAssumptionFailure())},
+ {
+ CheckMatcherThatDoesNotFailWithoutProvidedReason.class,
+ everyTestRunSuccessful()},
+ {
+ CheckMatcherThatDoesNotFailWithProvidedReason.class,
+ everyTestRunSuccessful()},
+ {
+ CheckMatcherThatFailsWithoutProvidedReason.class,
+ hasSingleFailureWithMessage(Matchers.<String>allOf(
+ containsString("Expected: is <4>"),
+ containsString("but: was <3>")))},
+ {
+ CheckMatcherThatFailsWithProvidedReason.class,
+ hasSingleFailureWithMessage(Matchers.<String>allOf(
+ containsString("reason"),
+ containsString("Expected: is <4>"),
+ containsString("but: was <3>")))},
+ {
+ CheckTwoMatchersThatFail.class,
+ hasNumberOfFailures(2)},
+ {
+ CheckCallableThatThrowsAnException.class,
+ hasSingleFailureWithMessage("first!")},
+ {
+ CheckTwoCallablesThatThrowExceptions.class,
+ hasNumberOfFailures(2)},
+ {
+ CheckCallableThatThrowsInternalAssumptionViolatedException.class,
+ allOf(hasSingleFailure(), hasNoAssumptionFailure())},
+ {
+ CheckCallableWithFailingAssumption.class,
+ allOf(hasSingleFailure(), hasNoAssumptionFailure())},
+ {
+ CheckCallableThatDoesNotThrowAnException.class,
+ everyTestRunSuccessful()},
+ {
+ CheckRunnableThatThrowsExpectedTypeOfException.class,
+ everyTestRunSuccessful()},
+ {
+ CheckRunnableThatThrowsUnexpectedTypeOfException.class,
+ hasSingleFailureWithMessage("unexpected exception type thrown; expected:<java.lang.IllegalArgumentException> but was:<java.lang.NullPointerException>")},
+ {
+ CheckRunnableThatThrowsNoExceptionAlthoughOneIsExpected.class,
+ hasSingleFailureWithMessage("expected java.lang.IllegalArgumentException to be thrown, but nothing was thrown")},
+ {
+ ErrorCollectorNotCalledBySuccessfulTest.class,
+ everyTestRunSuccessful()},
+ {
+ ErrorCollectorNotCalledByFailingTest.class,
+ hasSingleFailure()},
+ };
+ }
+
+ @Parameter(0)
+ public Class<?> classUnderTest;
+
+ @Parameter(1)
+ public Matcher<EventCollector> matcher;
+
+ @Test
+ public void runTestClassAndVerifyEvents() {
+ EventCollector collector = new EventCollector();
+ JUnitCore core = new JUnitCore();
+ core.addListener(collector);
+ core.run(classUnderTest);
+ assertThat(collector, matcher);
+ }
+
+ public static class AddSingleError {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.addError(new Throwable("message"));
+ }
+ }
+
+ public static class AddTwoErrors {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.addError(new Throwable("first thing went wrong"));
+ collector.addError(new Throwable("second thing went wrong"));
+ }
+ }
+
+ public static class AddInternalAssumptionViolatedException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.addError(new AssumptionViolatedException("message"));
+ }
+ }
+
+ public static class CheckMatcherThatDoesNotFailWithProvidedReason {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThat("dummy reason", 3, is(3));
+ }
+ }
+
+ public static class CheckMatcherThatDoesNotFailWithoutProvidedReason {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThat(3, is(3));
+ }
+ }
+
+ public static class CheckMatcherThatFailsWithoutProvidedReason {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThat(3, is(4));
+ }
+ }
+
+ public static class CheckMatcherThatFailsWithProvidedReason {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThat("reason", 3, is(4));
+ }
+ }
+
+ public static class CheckTwoMatchersThatFail {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThat(3, is(4));
+ collector.checkThat("reason", 7, is(8));
+ }
+ }
+
+ public static class CheckCallableThatThrowsAnException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ throw new RuntimeException("first!");
+ }
+ });
+ }
+ }
+
+ public static class CheckTwoCallablesThatThrowExceptions {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ throw new RuntimeException("first!");
+ }
+ });
+ collector.checkSucceeds(new Callable<Integer>() {
+ public Integer call() throws Exception {
+ throw new RuntimeException("second!");
+ }
+ });
+ }
+ }
+
+ public static class CheckCallableThatThrowsInternalAssumptionViolatedException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ throw new AssumptionViolatedException("message");
+ }
+ });
+ }
+ }
+
+ public static class CheckCallableWithFailingAssumption {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ assumeTrue(false);
+ return null;
+ }
+ });
+ }
+ }
+
+ public static class CheckCallableThatDoesNotThrowAnException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ Object result = collector.checkSucceeds(new Callable<Object>() {
+ public Object call() throws Exception {
+ return 3;
+ }
+ });
+ assertEquals(3, result);
+ }
+ }
+
+ public static class CheckRunnableThatThrowsExpectedTypeOfException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
+ public void run() throws Throwable {
+ throw new IllegalArgumentException();
+ }
+ });
+ }
+ }
+
+ public static class CheckRunnableThatThrowsUnexpectedTypeOfException {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
+ public void run() throws Throwable {
+ throw new NullPointerException();
+ }
+ });
+ }
+ }
+
+ public static class CheckRunnableThatThrowsNoExceptionAlthoughOneIsExpected {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
+ public void run() throws Throwable {
+ }
+ });
+ }
+ }
+
+ public static class ErrorCollectorNotCalledBySuccessfulTest {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ }
+ }
+
+ public static class ErrorCollectorNotCalledByFailingTest {
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void example() {
+ fail();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/EventCollector.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/EventCollector.java
new file mode 100644
index 0000000..32c872e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/EventCollector.java
@@ -0,0 +1,191 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class EventCollector extends RunListener {
+ static Matcher<EventCollector> everyTestRunSuccessful() {
+ return allOf(hasNoFailure(), hasNoAssumptionFailure());
+ }
+
+ static Matcher<EventCollector> hasNumberOfFailures(
+ final int numberOfFailures) {
+ return new TypeSafeMatcher<EventCollector>() {
+ @Override
+ public boolean matchesSafely(EventCollector item) {
+ return item.fFailures.size() == numberOfFailures;
+ }
+
+ public void describeTo(org.hamcrest.Description description) {
+ description.appendText("has ");
+ description.appendValue(numberOfFailures);
+ description.appendText(" failures");
+ }
+
+ @Override
+ protected void describeMismatchSafely(EventCollector item,
+ org.hamcrest.Description description) {
+ description.appendValue(item.fFailures.size());
+ description.appendText(" failures");
+ }
+ };
+ }
+
+ static Matcher<EventCollector> hasSingleFailure() {
+ return hasNumberOfFailures(1);
+ }
+
+ static Matcher<EventCollector> hasNoFailure() {
+ return hasNumberOfFailures(0);
+ }
+
+ private static Matcher<EventCollector> hasNumberOfAssumptionFailures(
+ final int numberOfFailures) {
+ return new TypeSafeMatcher<EventCollector>() {
+ @Override
+ public boolean matchesSafely(EventCollector item) {
+ return item.fAssumptionFailures.size() == numberOfFailures;
+ }
+
+ public void describeTo(org.hamcrest.Description description) {
+ description.appendText("has ");
+ description.appendValue(numberOfFailures);
+ description.appendText(" assumption failures");
+ }
+ };
+ }
+
+ static Matcher<EventCollector> hasSingleAssumptionFailure() {
+ return hasNumberOfAssumptionFailures(1);
+ }
+
+ static Matcher<EventCollector> hasNoAssumptionFailure() {
+ return hasNumberOfAssumptionFailures(0);
+ }
+
+ public static Matcher<EventCollector> hasSingleFailureWithMessage(String message) {
+ return hasSingleFailureWithMessage(equalTo(message));
+ }
+
+ static Matcher<EventCollector> hasSingleFailureWithMessage(
+ final Matcher<String> messageMatcher) {
+ return new TypeSafeMatcher<EventCollector>() {
+ @Override
+ public boolean matchesSafely(EventCollector item) {
+ return hasSingleFailure().matches(item)
+ && messageMatcher.matches(item.fFailures.get(0)
+ .getMessage());
+ }
+
+ public void describeTo(org.hamcrest.Description description) {
+ description.appendText("has single failure with message ");
+ messageMatcher.describeTo(description);
+ }
+
+ @Override
+ protected void describeMismatchSafely(EventCollector item,
+ org.hamcrest.Description description) {
+ description.appendText("was ");
+ hasSingleFailure().describeMismatch(item, description);
+ description.appendText(": ");
+ boolean first= true;
+ for (Failure f : item.fFailures) {
+ if (!first) {
+ description.appendText(" ,");
+ }
+ description.appendText("'");
+ description.appendText(f.getMessage());
+ description.appendText("'");
+ first= false;
+ }
+ }
+ };
+ }
+
+ static Matcher<EventCollector> failureIs(final Matcher<? super Throwable> exceptionMatcher) {
+ return new TypeSafeMatcher<EventCollector>() {
+ @Override
+ public boolean matchesSafely(EventCollector item) {
+ for (Failure f : item.fFailures) {
+ return exceptionMatcher.matches(f.getException());
+ }
+ return false;
+ }
+
+ public void describeTo(org.hamcrest.Description description) {
+ description.appendText("failure is ");
+ exceptionMatcher.describeTo(description);
+ }
+ };
+ }
+
+ private final List<Description> fTestRunsStarted = new ArrayList<Description>();
+
+ private final List<Result> fTestRunsFinished = new ArrayList<Result>();
+
+ private final List<Description> fTestsStarted = new ArrayList<Description>();
+
+ private final List<Description> fTestsFinished = new ArrayList<Description>();
+
+ private final List<Failure> fFailures = new ArrayList<Failure>();
+
+ private final List<Failure> fAssumptionFailures = new ArrayList<Failure>();
+
+ private final List<Description> fTestsIgnored = new ArrayList<Description>();
+
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ fTestRunsStarted.add(description);
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ fTestRunsFinished.add(result);
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ fTestsStarted.add(description);
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ fTestsFinished.add(description);
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ fFailures.add(failure);
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ fAssumptionFailures.add(failure);
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ fTestsIgnored.add(description);
+ }
+
+ @Override
+ public String toString() {
+ return fTestRunsStarted.size() + " test runs started, "
+ + fTestRunsFinished.size() + " test runs finished, "
+ + fTestsStarted.size() + " tests started, "
+ + fTestsFinished.size() + " tests finished, "
+ + fFailures.size() + " failures, "
+ + fAssumptionFailures.size() + " assumption failures, "
+ + fTestsIgnored.size() + " tests ignored";
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/ExpectedExceptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/ExpectedExceptionTest.java
new file mode 100644
index 0000000..f9bf3f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/ExpectedExceptionTest.java
@@ -0,0 +1,386 @@
+package org.junit.rules;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.rules.ExpectedException.none;
+import static org.junit.rules.EventCollector.everyTestRunSuccessful;
+import static org.junit.rules.EventCollector.hasSingleAssumptionFailure;
+import static org.junit.rules.EventCollector.hasSingleFailure;
+import static org.junit.rules.EventCollector.hasSingleFailureWithMessage;
+
+import java.util.Collection;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ExpectedExceptionTest {
+ private static final String ARBITRARY_MESSAGE = "arbitrary message";
+
+ @Parameters(name= "{0}")
+ public static Collection<Object[]> testsWithEventMatcher() {
+ return asList(new Object[][]{
+ {EmptyTestExpectingNoException.class, everyTestRunSuccessful()},
+ {ThrowExceptionWithExpectedType.class,
+ everyTestRunSuccessful()},
+ {ThrowExceptionWithExpectedPartOfMessage.class,
+ everyTestRunSuccessful()},
+ {
+ ThrowExceptionWithWrongType.class,
+ hasSingleFailureWithMessage(startsWith("\nExpected: an instance of java.lang.NullPointerException"))},
+ {
+ HasWrongMessage.class,
+ hasSingleFailureWithMessage(startsWith("\nExpected: exception with message a string containing \"expectedMessage\"\n"
+ + " but: message was \"actualMessage\""))},
+ {
+ ThrowNoExceptionButExpectExceptionWithType.class,
+ hasSingleFailureWithMessage("Expected test to throw an instance of java.lang.NullPointerException")},
+ {WronglyExpectsExceptionMessage.class, hasSingleFailure()},
+ {ExpectsSubstring.class, everyTestRunSuccessful()},
+ {
+ ExpectsSubstringNullMessage.class,
+ hasSingleFailureWithMessage(startsWith("\nExpected: exception with message a string containing \"anything!\""))},
+ {ExpectsMessageMatcher.class, everyTestRunSuccessful()},
+ {
+ ExpectedMessageMatcherFails.class,
+ hasSingleFailureWithMessage(startsWith("\nExpected: exception with message \"Wrong start\""))},
+ {ExpectsMatcher.class, everyTestRunSuccessful()},
+ {ExpectAssertionErrorWhichIsNotThrown.class, hasSingleFailure()},
+ {FailedAssumptionAndExpectException.class,
+ hasSingleAssumptionFailure()},
+ {FailBeforeExpectingException.class,
+ hasSingleFailureWithMessage(ARBITRARY_MESSAGE)},
+ {
+ ExpectsMultipleMatchers.class,
+ hasSingleFailureWithMessage(startsWith("\nExpected: (an instance of java.lang.IllegalArgumentException and exception with message a string containing \"Ack!\")"))},
+ {ThrowExceptionWithMatchingCause.class, everyTestRunSuccessful()},
+ {ThrowExpectedNullCause.class, everyTestRunSuccessful()},
+ {
+ ThrowUnexpectedCause.class,
+ hasSingleFailureWithMessage(CoreMatchers.<String>allOf(
+ startsWith("\nExpected: ("),
+ containsString("exception with cause is <java.lang.NullPointerException: expected cause>"),
+ containsString("cause was <java.lang.NullPointerException: an unexpected cause>"),
+ containsString("Stacktrace was: java.lang.IllegalArgumentException: Ack!"),
+ containsString("Caused by: java.lang.NullPointerException: an unexpected cause")))},
+ {
+ UseNoCustomMessage.class,
+ hasSingleFailureWithMessage("Expected test to throw an instance of java.lang.IllegalArgumentException") },
+ {
+ UseCustomMessageWithoutPlaceHolder.class,
+ hasSingleFailureWithMessage(ARBITRARY_MESSAGE) },
+ {
+ UseCustomMessageWithPlaceHolder.class,
+ hasSingleFailureWithMessage(ARBITRARY_MESSAGE
+ + " - an instance of java.lang.IllegalArgumentException") },
+ {
+ ErrorCollectorShouldFailAlthoughExpectedExceptionDoesNot.class,
+ hasSingleFailureWithMessage(ARBITRARY_MESSAGE) }
+ });
+ }
+
+ private final Class<?> classUnderTest;
+
+ private final Matcher<EventCollector> matcher;
+
+ public ExpectedExceptionTest(Class<?> classUnderTest,
+ Matcher<EventCollector> matcher) {
+ this.classUnderTest = classUnderTest;
+ this.matcher = matcher;
+ }
+
+ @Test
+ public void runTestAndVerifyResult() {
+ EventCollector collector = new EventCollector();
+ JUnitCore core = new JUnitCore();
+ core.addListener(collector);
+ core.run(classUnderTest);
+ assertThat(collector, matcher);
+ }
+
+ public static class EmptyTestExpectingNoException {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsNothing() {
+ }
+ }
+
+ public static class ThrowExceptionWithExpectedType {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ throw new NullPointerException();
+ }
+ }
+
+ public static class ThrowExceptionWithExpectedPartOfMessage {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsNullPointerExceptionWithMessage() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage(ARBITRARY_MESSAGE);
+ throw new NullPointerException(ARBITRARY_MESSAGE + "something else");
+ }
+ }
+
+ public static class ThrowExceptionWithWrongType {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public static class HasWrongMessage {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsNullPointerException() {
+ thrown.expectMessage("expectedMessage");
+ throw new IllegalArgumentException("actualMessage");
+ }
+ }
+
+ public static class ThrowNoExceptionButExpectExceptionWithType {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void doesntThrowNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ }
+ }
+
+ public static class WronglyExpectsExceptionMessage {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void doesntThrowAnything() {
+ thrown.expectMessage("anything!");
+ }
+ }
+
+ public static class ExpectsSubstring {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expectMessage("anything!");
+ throw new NullPointerException(
+ "This could throw anything! (as long as it has the right substring)");
+ }
+ }
+
+ public static class ExpectsSubstringNullMessage {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expectMessage("anything!");
+ throw new NullPointerException();
+ }
+ }
+
+ public static class ExpectsMessageMatcher {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expectMessage(startsWith(ARBITRARY_MESSAGE));
+ throw new NullPointerException(ARBITRARY_MESSAGE + "!");
+ }
+ }
+
+ public static class ExpectedMessageMatcherFails {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expectMessage(equalTo("Wrong start"));
+ throw new NullPointerException("Back!");
+ }
+ }
+
+ public static class ExpectsMatcher {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expect(any(Exception.class));
+ throw new NullPointerException("Ack!");
+ }
+ }
+
+ public static class ExpectsMultipleMatchers {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwsMore() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Ack!");
+ throw new NullPointerException("Ack!");
+ }
+ }
+
+ //https://github.com/junit-team/junit4/pull/583
+ public static class ExpectAssertionErrorWhichIsNotThrown {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void fails() {
+ thrown.expect(AssertionError.class);
+ }
+ }
+
+ public static class FailBeforeExpectingException {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void fails() {
+ fail(ARBITRARY_MESSAGE);
+ thrown.expect(IllegalArgumentException.class);
+ }
+ }
+
+ public static class FailedAssumptionAndExpectException {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void failedAssumption() {
+ assumeTrue(false);
+ thrown.expect(NullPointerException.class);
+ }
+ }
+
+ public static class ThrowExceptionWithMatchingCause {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwExceptionWithMatchingCause() {
+ NullPointerException expectedCause = new NullPointerException("expected cause");
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Ack!");
+ thrown.expectCause(is(expectedCause));
+
+ throw new IllegalArgumentException("Ack!", expectedCause);
+ }
+ }
+
+ public static class ThrowExpectedNullCause {
+ @Rule
+ public ExpectedException thrown = none();
+
+ @Test
+ public void throwExpectedNullCause() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Ack!");
+ thrown.expectCause(nullValue(Throwable.class));
+
+ throw new IllegalArgumentException("Ack!");
+ }
+ }
+
+ public static class ThrowUnexpectedCause {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void throwWithCause() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Ack!");
+ thrown.expectCause(is(new NullPointerException("expected cause")));
+
+ throw new IllegalArgumentException("Ack!", new NullPointerException("an unexpected cause"));
+ }
+ }
+
+ public static class UseNoCustomMessage {
+
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();
+
+ @Test
+ public void noThrow() {
+ thrown.expect(IllegalArgumentException.class);
+ }
+ }
+
+ public static class UseCustomMessageWithPlaceHolder {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void noThrow() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.reportMissingExceptionWithMessage(ARBITRARY_MESSAGE
+ + " - %s");
+ }
+ }
+
+ public static class UseCustomMessageWithoutPlaceHolder {
+
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();
+
+ @Test
+ public void noThrow() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.reportMissingExceptionWithMessage(ARBITRARY_MESSAGE);
+ }
+ }
+
+ public static class ErrorCollectorShouldFailAlthoughExpectedExceptionDoesNot {
+
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Rule(order = Integer.MAX_VALUE)
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void test() {
+ collector.addError(new AssertionError(ARBITRARY_MESSAGE));
+ thrown.expect(Exception.class);
+ throw new RuntimeException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/ExternalResourceRuleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/ExternalResourceRuleTest.java
new file mode 100644
index 0000000..ba4302e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/ExternalResourceRuleTest.java
@@ -0,0 +1,168 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.TestCouldNotBeSkippedException;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.internal.runners.statements.Fail;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+public class ExternalResourceRuleTest {
+ private static String callSequence;
+
+ public static class UsesExternalResource {
+ @Rule
+ public ExternalResource resource = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ callSequence += "before ";
+ }
+
+ @Override
+ protected void after() {
+ callSequence += "after ";
+ }
+ };
+
+ @Test
+ public void testFoo() {
+ callSequence += "test ";
+ }
+ }
+
+ @Test
+ public void externalResourceGeneratesCorrectSequence() {
+ callSequence = "";
+ assertThat(testResult(UsesExternalResource.class), isSuccessful());
+ assertEquals("before test after ", callSequence);
+ }
+
+ @Test
+ public void shouldThrowMultipleFailureExceptionWhenTestFailsAndClosingResourceFails() throws Throwable {
+ // given
+ ExternalResource resourceRule = new ExternalResource() {
+ @Override
+ protected void after() {
+ throw new RuntimeException("simulating resource tear down failure");
+ }
+ };
+ Statement failingTest = new Fail(new RuntimeException("simulated test failure"));
+ Description dummyDescription = Description.createTestDescription(
+ "dummy test class name", "dummy test name");
+
+ try {
+ resourceRule.apply(failingTest, dummyDescription).evaluate();
+ fail("ExternalResource should throw");
+ } catch (MultipleFailureException e) {
+ assertThat(e.getMessage(), allOf(
+ containsString("simulated test failure"),
+ containsString("simulating resource tear down failure")
+ ));
+ }
+ }
+
+ public static class TestFailsAndTwoClosingResourcesFail {
+ @Rule
+ public ExternalResource resourceRule1 = new ExternalResource() {
+ @Override
+ protected void after() {
+ throw new RuntimeException("simulating resource1 tear down failure");
+ }
+ };
+
+ @Rule
+ public ExternalResource resourceRule2 = new ExternalResource() {
+ @Override
+ protected void after() {
+ throw new RuntimeException("simulating resource2 tear down failure");
+ }
+ };
+
+ @Test
+ public void failingTest() {
+ throw new RuntimeException("simulated test failure");
+ }
+ }
+
+ @Test
+ public void shouldThrowMultipleFailureExceptionWhenTestFailsAndTwoClosingResourcesFail() {
+ Result result = JUnitCore.runClasses(TestFailsAndTwoClosingResourcesFail.class);
+ assertEquals(3, result.getFailures().size());
+ List<String> messages = new ArrayList<String>();
+ for (Failure failure : result.getFailures()) {
+ messages.add(failure.getMessage());
+ }
+ assertThat(messages, CoreMatchers.hasItems(
+ "simulated test failure",
+ "simulating resource1 tear down failure",
+ "simulating resource2 tear down failure"
+ ));
+ }
+
+ @Test
+ public void shouldWrapAssumptionFailuresWhenClosingResourceFails() throws Throwable {
+ // given
+ final AtomicReference<Throwable> externalResourceException = new AtomicReference<Throwable>();
+ ExternalResource resourceRule = new ExternalResource() {
+ @Override
+ protected void after() {
+ RuntimeException runtimeException = new RuntimeException("simulating resource tear down failure");
+ externalResourceException.set(runtimeException);
+ throw runtimeException;
+ }
+ };
+ final AtomicReference<Throwable> assumptionViolatedException = new AtomicReference<Throwable>();
+ Statement skippedTest = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ AssumptionViolatedException assumptionFailure = new AssumptionViolatedException("skip it");
+ assumptionViolatedException.set(assumptionFailure);
+ throw assumptionFailure;
+ }
+ };
+ Description dummyDescription = Description.createTestDescription(
+ "dummy test class name", "dummy test name");
+
+ try {
+ resourceRule.apply(skippedTest, dummyDescription).evaluate();
+ fail("ExternalResource should throw");
+ } catch (MultipleFailureException e) {
+ assertThat(e.getFailures(), hasItems(
+ instanceOf(TestCouldNotBeSkippedException.class),
+ sameInstance(externalResourceException.get())
+ ));
+ assertThat(e.getFailures(), hasItems(
+ hasCause(sameInstance(assumptionViolatedException.get())),
+ sameInstance(externalResourceException.get())
+ ));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Matcher<? super List<Throwable>> hasItems(
+ Matcher<? super Throwable> one, Matcher<? super Throwable> two) {
+ return CoreMatchers.hasItems(one, two);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingMethodRule.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingMethodRule.java
new file mode 100644
index 0000000..9df2d23
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingMethodRule.java
@@ -0,0 +1,18 @@
+package org.junit.rules;
+
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+class LoggingMethodRule implements MethodRule {
+ private final StringBuilder log;
+ private final String name;
+
+ LoggingMethodRule(StringBuilder log, String name) {
+ this.name = name;
+ this.log = log;
+ }
+
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return new LoggingStatement(base, log, name);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingStatement.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingStatement.java
new file mode 100644
index 0000000..af36239
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingStatement.java
@@ -0,0 +1,24 @@
+package org.junit.rules;
+
+import org.junit.runners.model.Statement;
+
+class LoggingStatement extends Statement {
+ private final Statement base;
+ private final StringBuilder log;
+ private final String name;
+
+ LoggingStatement(Statement base, StringBuilder log, String name) {
+ this.base = base;
+ this.log = log;
+ this.name = name;
+ }
+
+ public void evaluate() throws Throwable {
+ log.append(" ").append(name).append(".begin");
+ try {
+ base.evaluate();
+ } finally {
+ log.append(" ").append(name).append(".end");
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestRule.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestRule.java
new file mode 100644
index 0000000..08792f2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestRule.java
@@ -0,0 +1,18 @@
+package org.junit.rules;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+class LoggingTestRule implements TestRule {
+ private final StringBuilder log;
+ private final String name;
+
+ LoggingTestRule(StringBuilder log, String name) {
+ this.name = name;
+ this.log = log;
+ }
+
+ public Statement apply(Statement base, Description description) {
+ return new LoggingStatement(base, log, name);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestWatcher.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestWatcher.java
new file mode 100644
index 0000000..44d32a3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/LoggingTestWatcher.java
@@ -0,0 +1,42 @@
+package org.junit.rules;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.runner.Description;
+
+class LoggingTestWatcher extends TestWatcher {
+ private final StringBuilder log;
+
+ LoggingTestWatcher(StringBuilder log) {
+ this.log = log;
+ }
+
+ @Override
+ protected void succeeded(Description description) {
+ log.append("succeeded ");
+ }
+
+ @Override
+ protected void failed(Throwable e, Description description) {
+ log.append("failed ");
+ }
+
+ @Override
+ protected void skipped(AssumptionViolatedException e, Description description) {
+ log.append("skipped ");
+ }
+
+ @Override
+ protected void skipped(org.junit.internal.AssumptionViolatedException e, Description description) {
+ log.append("deprecated skipped ");
+ }
+
+ @Override
+ protected void starting(Description description) {
+ log.append("starting ");
+ }
+
+ @Override
+ protected void finished(Description description) {
+ log.append("finished ");
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/MethodRulesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/MethodRulesTest.java
new file mode 100644
index 0000000..6c59f7e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/MethodRulesTest.java
@@ -0,0 +1,420 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+@SuppressWarnings("deprecation")
+public class MethodRulesTest {
+ private static boolean ruleWasEvaluated;
+
+ private static class TestMethodRule implements MethodRule {
+
+ public Statement apply(final Statement base, FrameworkMethod method, Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ ruleWasEvaluated = true;
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class ExampleTest {
+ @Rule
+ public MethodRule example = new TestMethodRule();
+
+ @Test
+ public void nothing() {
+ }
+ }
+
+ abstract static class NonPublicExampleTest {
+ @Rule
+ public MethodRule example = new TestMethodRule();
+
+ @Test
+ public void nothing() {
+ }
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluated() {
+ ruleWasEvaluated = false;
+ assertThat(testResult(ExampleTest.class), isSuccessful());
+ assertTrue(ruleWasEvaluated);
+ }
+
+ public static class SonOfExampleTest extends ExampleTest {
+
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluatedOnSubclass() {
+ ruleWasEvaluated = false;
+ assertThat(testResult(SonOfExampleTest.class), isSuccessful());
+ assertTrue(ruleWasEvaluated);
+ }
+
+ public static class SonOfNonPublicExampleTest extends NonPublicExampleTest {
+
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluatedOnSubclassOfNonPublicClass() {
+ ruleWasEvaluated = false;
+ assertThat(testResult(SonOfNonPublicExampleTest.class), isSuccessful());
+ assertTrue(ruleWasEvaluated);
+ }
+
+ private static int runCount;
+
+ private static class Increment implements MethodRule {
+ public Statement apply(final Statement base,
+ FrameworkMethod method, Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ runCount++;
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class MultipleRuleTest {
+
+ @Rule
+ public MethodRule incrementor1 = new Increment();
+
+ @Rule
+ public MethodRule incrementor2 = new Increment();
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void multipleRulesAreRun() {
+ runCount = 0;
+ assertThat(testResult(MultipleRuleTest.class), isSuccessful());
+ assertEquals(2, runCount);
+ }
+
+ public static class NoRulesTest {
+ public int x;
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void ignoreNonRules() {
+ assertThat(testResult(NoRulesTest.class), isSuccessful());
+ }
+
+ private static String log;
+
+ public static class OnFailureTest {
+ @Rule
+ public MethodRule watchman = new TestWatchman() {
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ log += method.getName() + " " + e.getClass().getSimpleName();
+ }
+ };
+
+ @Test
+ public void nothing() {
+ fail();
+ }
+ }
+
+ @Test
+ public void onFailure() {
+ log = "";
+ assertThat(testResult(OnFailureTest.class), failureCountIs(1));
+ assertEquals("nothing AssertionError", log);
+ }
+
+ public static class WatchmanTest {
+ private static String watchedLog;
+
+ @Rule
+ public MethodRule watchman = new TestWatchman() {
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ watchedLog += method.getName() + " "
+ + e.getClass().getSimpleName() + "\n";
+ }
+
+ @Override
+ public void succeeded(FrameworkMethod method) {
+ watchedLog += method.getName() + " " + "success!\n";
+ }
+ };
+
+ @Test
+ public void fails() {
+ fail();
+ }
+
+ @Test
+ public void succeeds() {
+ }
+ }
+
+ @Test
+ public void succeeded() {
+ WatchmanTest.watchedLog = "";
+ assertThat(testResult(WatchmanTest.class), failureCountIs(1));
+ assertThat(WatchmanTest.watchedLog, containsString("fails AssertionError"));
+ assertThat(WatchmanTest.watchedLog, containsString("succeeds success!"));
+ }
+
+ public static class BeforesAndAfters {
+ private static String watchedLog;
+
+ @Before
+ public void before() {
+ watchedLog += "before ";
+ }
+
+ @Rule
+ public MethodRule watchman = new TestWatchman() {
+ @Override
+ public void starting(FrameworkMethod method) {
+ watchedLog += "starting ";
+ }
+
+ @Override
+ public void finished(FrameworkMethod method) {
+ watchedLog += "finished ";
+ }
+
+ @Override
+ public void succeeded(FrameworkMethod method) {
+ watchedLog += "succeeded ";
+ }
+ };
+
+ @After
+ public void after() {
+ watchedLog += "after ";
+ }
+
+ @Test
+ public void succeeds() {
+ watchedLog += "test ";
+ }
+ }
+
+ @Test
+ public void beforesAndAfters() {
+ BeforesAndAfters.watchedLog = "";
+ assertThat(testResult(BeforesAndAfters.class), isSuccessful());
+ assertThat(BeforesAndAfters.watchedLog, is("starting before test after succeeded finished "));
+ }
+
+ public static class WrongTypedField {
+ @Rule
+ public int x = 5;
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void validateWrongTypedField() {
+ assertThat(testResult(WrongTypedField.class),
+ hasSingleFailureContaining("must implement MethodRule"));
+ }
+
+ public static class SonOfWrongTypedField extends WrongTypedField {
+
+ }
+
+ @Test
+ public void validateWrongTypedFieldInSuperclass() {
+ assertThat(testResult(SonOfWrongTypedField.class),
+ hasSingleFailureContaining("must implement MethodRule"));
+ }
+
+ public static class PrivateRule {
+ @Rule
+ private TestRule rule = new TestName();
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void validatePrivateRule() {
+ assertThat(testResult(PrivateRule.class),
+ hasSingleFailureContaining("must be public"));
+ }
+
+ public static class CustomTestName implements TestRule {
+ public String name = null;
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ name = description.getMethodName();
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class UsesCustomMethodRule {
+ @Rule
+ public CustomTestName counter = new CustomTestName();
+
+ @Test
+ public void foo() {
+ assertEquals("foo", counter.name);
+ }
+ }
+
+ @Test
+ public void useCustomMethodRule() {
+ assertThat(testResult(UsesCustomMethodRule.class), isSuccessful());
+ }
+
+ public static class HasMethodReturningMethodRule {
+ private MethodRule methodRule = new MethodRule() {
+ public Statement apply(final Statement base, FrameworkMethod method, Object target) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ ruleWasEvaluated = true;
+ base.evaluate();
+ }
+ };
+ }
+ };
+
+ @Rule
+ public MethodRule methodRule() {
+ return methodRule;
+ }
+
+ @Test
+ public void doNothing() {
+
+ }
+ }
+
+ /**
+ * If there are any public methods annotated with @Rule returning a {@link MethodRule}
+ * then it should also be run.
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/589">Issue #589</a> -
+ * Support @Rule for methods works only for TestRule but not for MethodRule
+ */
+ @Test
+ public void runsMethodRuleThatIsReturnedByMethod() {
+ ruleWasEvaluated = false;
+ assertThat(testResult(HasMethodReturningMethodRule.class), isSuccessful());
+ assertTrue(ruleWasEvaluated);
+ }
+
+ public static class HasMultipleMethodsReturningMethodRule {
+ @Rule
+ public Increment methodRule1() {
+ return new Increment();
+ }
+
+ @Rule
+ public Increment methodRule2() {
+ return new Increment();
+ }
+
+ @Test
+ public void doNothing() {
+
+ }
+ }
+
+ /**
+ * If there are multiple public methods annotated with @Rule returning a {@link MethodRule}
+ * then all the rules returned should be run.
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/589">Issue #589</a> -
+ * Support @Rule for methods works only for TestRule but not for MethodRule
+ */
+ @Test
+ public void runsAllMethodRulesThatAreReturnedByMethods() {
+ runCount = 0;
+ assertThat(testResult(HasMultipleMethodsReturningMethodRule.class), isSuccessful());
+ assertEquals(2, runCount);
+ }
+
+
+ public static class CallsMethodReturningRuleOnlyOnce {
+ int callCount = 0;
+
+ private static class Dummy implements MethodRule {
+ public Statement apply(final Statement base, FrameworkMethod method, Object target) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+
+ @Rule
+ public MethodRule methodRule() {
+ callCount++;
+ return new Dummy();
+ }
+
+ @Test
+ public void doNothing() {
+ assertEquals(1, callCount);
+ }
+ }
+
+ /**
+ * If there are any public methods annotated with @Rule returning a {@link MethodRule}
+ * then method should be called only once.
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/589">Issue #589</a> -
+ * Support @Rule for methods works only for TestRule but not for MethodRule
+ */
+ @Test
+ public void callsMethodReturningRuleOnlyOnce() {
+ assertThat(testResult(CallsMethodReturningRuleOnlyOnce.class), isSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/NameRulesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/NameRulesTest.java
new file mode 100644
index 0000000..9ae45ff
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/NameRulesTest.java
@@ -0,0 +1,50 @@
+package org.junit.rules;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+
+@RunWith(Enclosed.class)
+public class NameRulesTest {
+ public static class TestNames {
+ @Rule
+ public TestName name = new TestName();
+
+ @Test
+ public void testA() {
+ assertEquals("testA", name.getMethodName());
+ }
+
+ @Test
+ public void testB() {
+ assertEquals("testB", name.getMethodName());
+ }
+ }
+
+ public static class BeforeAndAfterTest {
+ @Rule
+ public TestName name = new TestName();
+
+ private final String expectedName = "x";
+
+ @Before
+ public void setUp() {
+ assertEquals(expectedName, name.getMethodName());
+ }
+
+ @Test
+ public void x() {
+ assertEquals(expectedName, name.getMethodName());
+ }
+
+ @After
+ public void tearDown() {
+ assertEquals(expectedName, name.getMethodName());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleChainTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleChainTest.java
new file mode 100644
index 0000000..54daf8d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleChainTest.java
@@ -0,0 +1,94 @@
+package org.junit.rules;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.rules.RuleChain.outerRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.internal.Throwables;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class RuleChainTest {
+ private static final List<String> LOG = new ArrayList<String>();
+
+ private static class LoggingRule extends TestWatcher {
+ private final String label;
+
+ public LoggingRule(String label) {
+ this.label = label;
+ }
+
+ @Override
+ protected void starting(Description description) {
+ LOG.add("starting " + label);
+ }
+
+ @Override
+ protected void finished(Description description) {
+ LOG.add("finished " + label);
+ }
+ }
+
+ public static class UseRuleChain {
+ @Rule
+ public final RuleChain chain = outerRule(new LoggingRule("outer rule"))
+ .around(new LoggingRule("middle rule")).around(
+ new LoggingRule("inner rule"));
+
+ @Test
+ public void example() {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void executeRulesInCorrectOrder() throws Exception {
+ testResult(UseRuleChain.class);
+ List<String> expectedLog = asList("starting outer rule",
+ "starting middle rule", "starting inner rule",
+ "finished inner rule", "finished middle rule",
+ "finished outer rule");
+ assertEquals(expectedLog, LOG);
+ }
+
+ @Test
+ public void aroundShouldNotAllowNullRules() {
+ RuleChain chain = RuleChain.emptyRuleChain();
+ try {
+ chain.around(null);
+ fail("around() should not allow null rules");
+ } catch (NullPointerException e) {
+ assertThat(e.getMessage(), equalTo("The enclosed rule must not be null"));
+ }
+ }
+
+ public static class RuleChainWithNullRules {
+ @Rule
+ public final RuleChain chain = outerRule(new LoggingRule("outer rule"))
+ .around(null);
+
+ @Test
+ public void example() {}
+ }
+
+ @Test
+ public void whenRuleChainHasNullRuleTheStacktraceShouldPointToIt() {
+ Result result = JUnitCore.runClasses(RuleChainWithNullRules.class);
+
+ assertThat(result.getFailures().size(), equalTo(1));
+ String stacktrace = Throwables.getStacktrace(result.getFailures().get(0).getException());
+ assertThat(stacktrace, containsString("\tat org.junit.rules.RuleChainTest$RuleChainWithNullRules.<init>(RuleChainTest.java:"));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleMemberValidatorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleMemberValidatorTest.java
new file mode 100644
index 0000000..01465a6
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/RuleMemberValidatorTest.java
@@ -0,0 +1,356 @@
+package org.junit.rules;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_METHOD_VALIDATOR;
+import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_VALIDATOR;
+import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_METHOD_VALIDATOR;
+import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_VALIDATOR;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+public class RuleMemberValidatorTest {
+ private final List<Throwable> errors = new ArrayList<Throwable>();
+
+ @Test
+ public void rejectProtectedClassRule() {
+ TestClass target = new TestClass(TestWithProtectedClassRule.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be public.");
+ }
+
+ public static class TestWithProtectedClassRule {
+ @ClassRule
+ protected static TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ @Test
+ public void rejectNonStaticClassRule() {
+ TestClass target = new TestClass(TestWithNonStaticClassRule.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be static.");
+ }
+
+ public static class TestWithNonStaticClassRule {
+ @ClassRule
+ public TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ @Test
+ public void acceptStaticTestRuleThatIsAlsoClassRule() {
+ TestClass target = new TestClass(TestWithStaticClassAndTestRule.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class TestWithStaticClassAndTestRule {
+ @ClassRule
+ @Rule
+ public static TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ @Test
+ public void rejectClassRuleInNonPublicClass() {
+ TestClass target = new TestClass(NonPublicTestWithClassRule.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be declared in a public class.");
+ }
+
+ static class NonPublicTestWithClassRule {
+ @ClassRule
+ public static TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ /**
+ * If there is any property annotated with @ClassRule then it must implement
+ * {@link TestRule}
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
+ */
+ @Test
+ public void rejectClassRuleThatIsImplementationOfMethodRule() {
+ TestClass target = new TestClass(TestWithClassRuleIsImplementationOfMethodRule.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'classRule' must implement TestRule.");
+ }
+
+ public static class TestWithClassRuleIsImplementationOfMethodRule {
+ @ClassRule
+ public static MethodRule classRule = new MethodRule() {
+
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return base;
+ }
+ };
+ }
+
+ /**
+ * If there is any method annotated with @ClassRule then it must return an
+ * implementation of {@link TestRule}
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
+ */
+ @Test
+ public void rejectClassRuleThatReturnsImplementationOfMethodRule() {
+ TestClass target = new TestClass(TestWithClassRuleMethodThatReturnsMethodRule.class);
+ CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'methodRule' must return an implementation of TestRule.");
+ }
+
+ public static class TestWithClassRuleMethodThatReturnsMethodRule {
+ @ClassRule
+ public static MethodRule methodRule() {
+ return new MethodRule() {
+
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return base;
+ }
+ };
+ }
+ }
+
+ /**
+ * If there is any property annotated with @ClassRule then it must implement
+ * {@link TestRule}
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
+ */
+ @Test
+ public void rejectClassRuleIsAnArbitraryObject() throws Exception {
+ TestClass target = new TestClass(TestWithClassRuleIsAnArbitraryObject.class);
+ CLASS_RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'arbitraryObject' must implement TestRule.");
+ }
+
+ public static class TestWithClassRuleIsAnArbitraryObject {
+ @ClassRule
+ public static Object arbitraryObject = 1;
+ }
+
+ /**
+ * If there is any method annotated with @ClassRule then it must return an
+ * implementation of {@link TestRule}
+ *
+ * <p>This case has been added with
+ * <a href="https://github.com/junit-team/junit4/issues/1019">Issue #1019</a>
+ */
+ @Test
+ public void rejectClassRuleMethodReturnsAnArbitraryObject() throws Exception {
+ TestClass target = new TestClass(TestWithClassRuleMethodReturnsAnArbitraryObject.class);
+ CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'arbitraryObject' must return an implementation of TestRule.");
+ }
+
+ public static class TestWithClassRuleMethodReturnsAnArbitraryObject {
+ @ClassRule
+ public static Object arbitraryObject() {
+ return 1;
+ }
+ }
+
+ @Test
+ public void acceptNonStaticTestRule() {
+ TestClass target = new TestClass(TestWithNonStaticTestRule.class);
+ RULE_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class TestWithNonStaticTestRule {
+ @Rule
+ public TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ @Test
+ public void rejectStaticTestRule() {
+ TestClass target = new TestClass(TestWithStaticTestRule.class);
+ RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'temporaryFolder' must not be static or it must be annotated with @ClassRule.");
+ }
+
+ public static class TestWithStaticTestRule {
+ @Rule
+ public static TestRule temporaryFolder = new TemporaryFolder();
+ }
+
+ @Test
+ public void rejectStaticMethodRule() {
+ TestClass target = new TestClass(TestWithStaticMethodRule.class);
+ RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'someMethodRule' must not be static.");
+ }
+
+ public static class TestWithStaticMethodRule {
+ @Rule
+ public static MethodRule someMethodRule = new SomeMethodRule();
+ }
+
+ @Test
+ public void acceptMethodRule() throws Exception {
+ TestClass target = new TestClass(TestWithMethodRule.class);
+ RULE_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class TestWithMethodRule {
+ @Rule
+ public MethodRule temporaryFolder = new MethodRule() {
+ public Statement apply(Statement base, FrameworkMethod method,
+ Object target) {
+ return null;
+ }
+ };
+ }
+
+ @Test
+ public void rejectArbitraryObjectWithRuleAnnotation() throws Exception {
+ TestClass target = new TestClass(TestWithArbitraryObjectWithRuleAnnotation.class);
+ RULE_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'arbitraryObject' must implement MethodRule or TestRule.");
+ }
+
+ public static class TestWithArbitraryObjectWithRuleAnnotation {
+ @Rule
+ public Object arbitraryObject = 1;
+ }
+
+ @Test
+ public void methodRejectProtectedClassRule() {
+ TestClass target = new TestClass(MethodTestWithProtectedClassRule.class);
+ CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be public.");
+ }
+
+ public static class MethodTestWithProtectedClassRule {
+ @ClassRule
+ protected static TestRule getTemporaryFolder() {
+ return new TemporaryFolder();
+ }
+ }
+
+ @Test
+ public void methodRejectNonStaticClassRule() {
+ TestClass target = new TestClass(MethodTestWithNonStaticClassRule.class);
+ CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be static.");
+ }
+
+ public static class MethodTestWithNonStaticClassRule {
+ @ClassRule
+ public TestRule getTemporaryFolder() {
+ return new TemporaryFolder();
+ }
+ }
+
+ @Test
+ public void acceptMethodStaticTestRuleThatIsAlsoClassRule() {
+ TestClass target = new TestClass(MethodTestWithStaticClassAndTestRule.class);
+ CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class MethodTestWithStaticClassAndTestRule {
+ @ClassRule
+ @Rule
+ public static TestRule getTemporaryFolder() {
+ return new TemporaryFolder();
+ }
+ }
+
+ @Test
+ public void acceptMethodNonStaticTestRule() {
+ TestClass target = new TestClass(TestMethodWithNonStaticTestRule.class);
+ RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class TestMethodWithNonStaticTestRule {
+ @Rule
+ public TestRule getTemporaryFolder() {
+ return new TemporaryFolder();
+ }
+ }
+
+ @Test
+ public void rejectMethodStaticTestRule() {
+ TestClass target = new TestClass(TestMethodWithStaticTestRule.class);
+ RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'getTemporaryFolder' must not be static or it must be annotated with @ClassRule.");
+ }
+
+ public static class TestMethodWithStaticTestRule {
+ @Rule
+ public static TestRule getTemporaryFolder() {
+ return new TemporaryFolder();
+ }
+ }
+
+ @Test
+ public void rejectMethodStaticMethodRule() {
+ TestClass target = new TestClass(TestMethodWithStaticMethodRule.class);
+ RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'getSomeMethodRule' must not be static.");
+ }
+
+ public static class TestMethodWithStaticMethodRule {
+ @Rule
+ public static MethodRule getSomeMethodRule() { return new SomeMethodRule(); }
+ }
+
+ @Test
+ public void methodAcceptMethodRuleMethod() throws Exception {
+ TestClass target = new TestClass(MethodTestWithMethodRule.class);
+ RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertNumberOfErrors(0);
+ }
+
+ public static class MethodTestWithMethodRule {
+ @Rule
+ public MethodRule getTemporaryFolder() {
+ return new MethodRule() {
+ public Statement apply(Statement base, FrameworkMethod method,
+ Object target) {
+ return null;
+ }
+ };
+ }
+ }
+
+ @Test
+ public void methodRejectArbitraryObjectWithRuleAnnotation() throws Exception {
+ TestClass target = new TestClass(MethodTestWithArbitraryObjectWithRuleAnnotation.class);
+ RULE_METHOD_VALIDATOR.validate(target, errors);
+ assertOneErrorWithMessage("The @Rule 'getArbitraryObject' must return an implementation of MethodRule or TestRule.");
+ }
+
+ public static class MethodTestWithArbitraryObjectWithRuleAnnotation {
+ @Rule
+ public Object getArbitraryObject() {
+ return 1;
+ }
+ }
+
+ private void assertOneErrorWithMessage(String message) {
+ assertNumberOfErrors(1);
+ assertEquals("Wrong error message:", message, errors.get(0).getMessage());
+ }
+
+ private void assertNumberOfErrors(int numberOfErrors) {
+ assertEquals("Wrong number of errors:", numberOfErrors, errors.size());
+ }
+
+ private static final class SomeMethodRule implements MethodRule {
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return base;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/StopwatchTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/StopwatchTest.java
new file mode 100644
index 0000000..5941eb9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/StopwatchTest.java
@@ -0,0 +1,212 @@
+package org.junit.rules;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+
+/**
+ * @author tibor17
+ * @since 4.12
+ */
+public class StopwatchTest {
+ private static enum TestStatus { SUCCEEDED, FAILED, SKIPPED }
+ private static Record record;
+ private static Record finishedRecord;
+ private static long fakeTimeNanos = 1234;
+
+ private static class Record {
+ final long duration;
+ final String name;
+ final TestStatus status;
+
+ Record() {
+ this(0, null, null);
+ }
+
+ Record(long duration, Description description) {
+ this(duration, null, description);
+ }
+
+ Record(long duration, TestStatus status, Description description) {
+ this.duration = duration;
+ this.status = status;
+ this.name = description == null ? null : description.getMethodName();
+ }
+ }
+
+ public abstract static class AbstractStopwatchTest {
+
+ /**
+ * Fake implementation of {@link Stopwatch.Clock} that increments the time
+ * every time it is asked.
+ */
+ private final Stopwatch.Clock fakeClock = new Stopwatch.Clock() {
+ @Override
+ public long nanoTime() {
+ return fakeTimeNanos++;
+ }
+ };
+
+ protected final Stopwatch stopwatch = new Stopwatch(fakeClock) {
+ @Override
+ protected void succeeded(long nanos, Description description) {
+ StopwatchTest.record = new Record(nanos, TestStatus.SUCCEEDED, description);
+ simulateTimePassing(1);
+ }
+
+ @Override
+ protected void failed(long nanos, Throwable e, Description description) {
+ StopwatchTest.record = new Record(nanos, TestStatus.FAILED, description);
+ simulateTimePassing(1);
+ }
+
+ @Override
+ protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
+ StopwatchTest.record = new Record(nanos, TestStatus.SKIPPED, description);
+ simulateTimePassing(1);
+ }
+
+ @Override
+ protected void finished(long nanos, Description description) {
+ StopwatchTest.finishedRecord = new Record(nanos, description);
+ }
+ };
+
+ private final TestWatcher watcher = new TestWatcher() {
+ @Override
+ protected void finished(Description description) {
+ afterStopwatchRule();
+ }
+ };
+
+ @Rule
+ public final RuleChain chain = RuleChain
+ .outerRule(watcher)
+ .around(stopwatch);
+
+ protected void afterStopwatchRule() {
+ }
+ }
+
+ public static class SuccessfulTest extends AbstractStopwatchTest {
+ @Test
+ public void successfulTest() {
+ }
+ }
+
+ public static class FailedTest extends AbstractStopwatchTest {
+ @Test
+ public void failedTest() {
+ fail();
+ }
+ }
+
+ public static class SkippedTest extends AbstractStopwatchTest {
+ @Test
+ public void skippedTest() {
+ assumeTrue(false);
+ }
+ }
+
+ public static class DurationDuringTestTest extends AbstractStopwatchTest {
+ @Test
+ public void duration() {
+ simulateTimePassing(300L);
+ assertEquals(300L, stopwatch.runtime(MILLISECONDS));
+ simulateTimePassing(500L);
+ assertEquals(800L, stopwatch.runtime(MILLISECONDS));
+ }
+ }
+
+ public static class DurationAfterTestTest extends AbstractStopwatchTest {
+ @Test
+ public void duration() {
+ simulateTimePassing(300L);
+ assertEquals(300L, stopwatch.runtime(MILLISECONDS));
+ }
+
+ @Override
+ protected void afterStopwatchRule() {
+ assertEquals(300L, stopwatch.runtime(MILLISECONDS));
+ simulateTimePassing(500L);
+ assertEquals(300L, stopwatch.runtime(MILLISECONDS));
+ }
+ }
+
+ @Before
+ public void init() {
+ record = new Record();
+ finishedRecord = new Record();
+ simulateTimePassing(1L);
+ }
+
+ private static Result runTest(Class<?> test) {
+ simulateTimePassing(1L);
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ private static void simulateTimePassing(long millis) {
+ fakeTimeNanos += TimeUnit.MILLISECONDS.toNanos(millis);
+ }
+
+ @Test
+ public void succeeded() {
+ Result result = runTest(SuccessfulTest.class);
+ assertEquals(0, result.getFailureCount());
+ assertThat(record.name, is("successfulTest"));
+ assertThat(record.name, is(finishedRecord.name));
+ assertThat(record.status, is(TestStatus.SUCCEEDED));
+ assertTrue("timeSpent > 0", record.duration > 0);
+ assertThat(record.duration, is(finishedRecord.duration));
+ }
+
+ @Test
+ public void failed() {
+ Result result = runTest(FailedTest.class);
+ assertEquals(1, result.getFailureCount());
+ assertThat(record.name, is("failedTest"));
+ assertThat(record.name, is(finishedRecord.name));
+ assertThat(record.status, is(TestStatus.FAILED));
+ assertTrue("timeSpent > 0", record.duration > 0);
+ assertThat(record.duration, is(finishedRecord.duration));
+ }
+
+ @Test
+ public void skipped() {
+ Result result = runTest(SkippedTest.class);
+ assertEquals(0, result.getFailureCount());
+ assertThat(record.name, is("skippedTest"));
+ assertThat(record.name, is(finishedRecord.name));
+ assertThat(record.status, is(TestStatus.SKIPPED));
+ assertTrue("timeSpent > 0", record.duration > 0);
+ assertThat(record.duration, is(finishedRecord.duration));
+ }
+
+ @Test
+ public void runtimeDuringTestShouldReturnTimeSinceStart() {
+ Result result = runTest(DurationDuringTestTest.class);
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void runtimeAfterTestShouldReturnRunDuration() {
+ Result result = runTest(DurationAfterTestTest.class);
+ assertTrue(result.wasSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TempFolderRuleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TempFolderRuleTest.java
new file mode 100644
index 0000000..b120e71
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TempFolderRuleTest.java
@@ -0,0 +1,281 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.junit.After;
+import org.junit.AssumptionViolatedException;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class TempFolderRuleTest {
+ private static File[] createdFiles = new File[20];
+
+ public static class HasTempFolder {
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void testUsingTempFolder() throws IOException {
+ createdFiles[0] = folder.newFile("myfile.txt");
+ assertTrue(createdFiles[0].exists());
+ }
+
+ @Test
+ public void testTempFolderLocation() throws IOException {
+ File folderRoot = folder.getRoot();
+ String tmpRoot = System.getProperty("java.io.tmpdir");
+ assertTrue(folderRoot.toString().startsWith(tmpRoot));
+ }
+ }
+
+ @Test
+ public void tempFolderIsDeleted() {
+ assertThat(testResult(HasTempFolder.class), isSuccessful());
+ assertFalse(createdFiles[0].exists());
+ }
+
+ public static class CreatesSubFolder {
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void testUsingTempFolderStringReflection() throws Exception {
+ String subfolder = "subfolder";
+ String filename = "a.txt";
+ // force usage of folder.newFolder(String),
+ // check is available and works, to avoid a potential NoSuchMethodError with non-recompiled code.
+ Method method = folder.getClass().getMethod("newFolder", new Class<?>[]{String.class});
+ createdFiles[0] = (File) method.invoke(folder, subfolder);
+ new File(createdFiles[0], filename).createNewFile();
+
+ File expectedFile = new File(folder.getRoot(), join(subfolder, filename));
+
+ assertTrue(expectedFile.exists());
+ }
+
+ @Test
+ public void testUsingTempFolderString() throws IOException {
+ String subfolder = "subfolder";
+ String filename = "a.txt";
+ // this uses newFolder(String), ensure that a single String works
+ createdFiles[0] = folder.newFolder(subfolder);
+ new File(createdFiles[0], filename).createNewFile();
+
+ File expectedFile = new File(folder.getRoot(), join(subfolder, filename));
+
+ assertTrue(expectedFile.exists());
+ }
+
+ @Test
+ public void testUsingTempTreeFolders() throws IOException {
+ String subfolder = "subfolder";
+ String anotherfolder = "anotherfolder";
+ String filename = "a.txt";
+
+ createdFiles[0] = folder.newFolder(subfolder, anotherfolder);
+ new File(createdFiles[0], filename).createNewFile();
+
+ File expectedFile = new File(folder.getRoot(), join(subfolder, anotherfolder, filename));
+
+ assertTrue(expectedFile.exists());
+ }
+
+ private String join(String... folderNames) {
+ StringBuilder path = new StringBuilder();
+ for (String folderName : folderNames) {
+ path.append(File.separator).append(folderName);
+ }
+ return path.toString();
+ }
+ }
+
+ @Test
+ public void subFolderIsDeleted() {
+ assertThat(testResult(CreatesSubFolder.class), isSuccessful());
+ assertFalse(createdFiles[0].exists());
+ }
+
+ public static class CreatesRandomSubFolders {
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void testUsingRandomTempFolders() throws IOException {
+ for (int i = 0; i < 20; i++) {
+ File newFolder = folder.newFolder();
+ assertThat(Arrays.asList(createdFiles), not(hasItem(newFolder)));
+ createdFiles[i] = newFolder;
+ new File(newFolder, "a.txt").createNewFile();
+ assertTrue(newFolder.exists());
+ }
+ }
+ }
+
+ @Test
+ public void randomSubFoldersAreDeleted() {
+ assertThat(testResult(CreatesRandomSubFolders.class), isSuccessful());
+ for (File f : createdFiles) {
+ assertFalse(f.exists());
+ }
+ }
+
+ public static class CreatesRandomFiles {
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void testUsingRandomTempFiles() throws IOException {
+ for (int i = 0; i < 20; i++) {
+ File newFile = folder.newFile();
+ assertThat(Arrays.asList(createdFiles), not(hasItem(newFile)));
+ createdFiles[i] = newFile;
+ assertTrue(newFile.exists());
+ }
+ }
+ }
+
+ @Test
+ public void randomFilesAreDeleted() {
+ assertThat(testResult(CreatesRandomFiles.class), isSuccessful());
+ for (File f : createdFiles) {
+ assertFalse(f.exists());
+ }
+ }
+
+ @Test
+ public void recursiveDeleteFolderWithOneElement() throws IOException {
+ TemporaryFolder folder = new TemporaryFolder();
+ folder.create();
+ File file = folder.newFile("a");
+ folder.delete();
+ assertFalse(file.exists());
+ assertFalse(folder.getRoot().exists());
+ }
+
+ @Test
+ public void recursiveDeleteFolderWithOneRandomElement() throws IOException {
+ TemporaryFolder folder = new TemporaryFolder();
+ folder.create();
+ File file = folder.newFile();
+ folder.delete();
+ assertFalse(file.exists());
+ assertFalse(folder.getRoot().exists());
+ }
+
+ @Test
+ public void recursiveDeleteFolderWithZeroElements() throws IOException {
+ TemporaryFolder folder = new TemporaryFolder();
+ folder.create();
+ folder.delete();
+ assertFalse(folder.getRoot().exists());
+ }
+
+ @Test
+ public void tempFolderIsOnlyAccessibleByOwner() throws IOException {
+ TemporaryFolder folder = new TemporaryFolder();
+ folder.create();
+
+ Set<String> expectedPermissions = new TreeSet<String>(Arrays.asList("OWNER_READ", "OWNER_WRITE", "OWNER_EXECUTE"));
+ Set<String> actualPermissions = getPosixFilePermissions(folder.getRoot());
+ assertEquals(expectedPermissions, actualPermissions);
+ }
+
+ private Set<String> getPosixFilePermissions(File root) {
+ try {
+ Class<?> pathClass = Class.forName("java.nio.file.Path");
+ Object linkOptionArray = Array.newInstance(Class.forName("java.nio.file.LinkOption"), 0);
+ Class<?> filesClass = Class.forName("java.nio.file.Files");
+ Object path = File.class.getDeclaredMethod("toPath").invoke(root);
+ Method posixFilePermissionsMethod = filesClass.getDeclaredMethod("getPosixFilePermissions", pathClass, linkOptionArray.getClass());
+ Set<?> permissions = (Set<?>) posixFilePermissionsMethod.invoke(null, path, linkOptionArray);
+ SortedSet<String> convertedPermissions = new TreeSet<String>();
+ for (Object item : permissions) {
+ convertedPermissions.add(item.toString());
+ }
+ return convertedPermissions;
+ } catch (Exception e) {
+ throw new AssumptionViolatedException("Test requires at least Java 1.7", e);
+ }
+ }
+
+ public static class NameClashes {
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void fileWithFileClash() throws IOException {
+ folder.newFile("something.txt");
+ folder.newFile("something.txt");
+ }
+
+ @Test
+ public void fileWithFolderTest() throws IOException {
+ folder.newFolder("dummy");
+ folder.newFile("dummy");
+ }
+ }
+
+ @Test
+ public void nameClashesResultInTestFailures() {
+ assertThat(testResult(NameClashes.class), failureCountIs(2));
+ }
+
+ private static final String GET_ROOT_DUMMY = "dummy-getRoot";
+
+ private static final String NEW_FILE_DUMMY = "dummy-newFile";
+
+ private static final String NEW_FOLDER_DUMMY = "dummy-newFolder";
+
+ public static class IncorrectUsage {
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Test
+ public void testGetRoot() throws IOException {
+ new File(folder.getRoot(), GET_ROOT_DUMMY).createNewFile();
+ }
+
+ @Test
+ public void testNewFile() throws IOException {
+ folder.newFile(NEW_FILE_DUMMY);
+ }
+
+ @Test
+ public void testNewFolder() throws IOException {
+ folder.newFolder(NEW_FOLDER_DUMMY);
+ }
+ }
+
+ @Test
+ public void incorrectUsageWithoutApplyingTheRuleShouldNotPolluteTheCurrentWorkingDirectory() {
+ assertThat(testResult(IncorrectUsage.class), failureCountIs(3));
+ assertFalse("getRoot should have failed early", new File(GET_ROOT_DUMMY).exists());
+ assertFalse("newFile should have failed early", new File(NEW_FILE_DUMMY).exists());
+ assertFalse("newFolder should have failed early", new File(NEW_FOLDER_DUMMY).exists());
+ }
+
+ @After
+ public void cleanCurrentWorkingDirectory() {
+ new File(GET_ROOT_DUMMY).delete();
+ new File(NEW_FILE_DUMMY).delete();
+ new File(NEW_FOLDER_DUMMY).delete();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderRuleAssuredDeletionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderRuleAssuredDeletionTest.java
new file mode 100644
index 0000000..48cbb44
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderRuleAssuredDeletionTest.java
@@ -0,0 +1,45 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.results.PrintableResult;
+
+public class TemporaryFolderRuleAssuredDeletionTest {
+
+ public static class TestClass {
+ static TemporaryFolder injectedRule;
+
+ @Rule
+ public TemporaryFolder folder = injectedRule;
+
+ @Test
+ public void alwaysPassesButDeletesRootFolder() {
+ //we delete the folder in the test so that it cannot be deleted by
+ //the rule
+ folder.getRoot().delete();
+ }
+ }
+
+ @Test
+ public void testFailsWhenCreatedFolderCannotBeDeletedButDeletionIsAssured() {
+ TestClass.injectedRule = TemporaryFolder.builder()
+ .assureDeletion()
+ .build();
+ PrintableResult result = testResult(TestClass.class);
+ assertThat(result, failureCountIs(1));
+ assertThat(result.toString(), containsString("Unable to clean up temporary folder"));
+ }
+
+ @Test
+ public void byDefaultTestDoesNotFailWhenCreatedFolderCannotBeDeleted() {
+ TestClass.injectedRule = new TemporaryFolder();
+ PrintableResult result = testResult(TestClass.class);
+ assertThat(result, isSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderUsageTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderUsageTest.java
new file mode 100644
index 0000000..584a296
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TemporaryFolderUsageTest.java
@@ -0,0 +1,302 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * <tt>TemporaryFolderUsageTest</tt> provides tests for API usage correctness
+ * and ensure implementation symmetry of public methods against a root folder.
+ */
+public class TemporaryFolderUsageTest {
+
+ private TemporaryFolder tempFolder;
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ tempFolder = new TemporaryFolder();
+ }
+
+ @After
+ public void tearDown() {
+ tempFolder.delete();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void getRootShouldThrowIllegalStateExceptionIfCreateWasNotInvoked() {
+ new TemporaryFolder().getRoot();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void newFileThrowsIllegalStateExceptionIfCreateWasNotInvoked()
+ throws IOException {
+ new TemporaryFolder().newFile();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void newFileWithGivenNameThrowsIllegalStateExceptionIfCreateWasNotInvoked()
+ throws IOException {
+ new TemporaryFolder().newFile("MyFile.txt");
+ }
+
+ @Test
+ public void newFileWithGivenFilenameThrowsIOExceptionIfFileExists() throws IOException {
+ tempFolder.create();
+ tempFolder.newFile("MyFile.txt");
+
+ thrown.expect(IOException.class);
+ thrown.expectMessage("a file with the name 'MyFile.txt' already exists in the test folder");
+ tempFolder.newFile("MyFile.txt");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void newFolderThrowsIllegalStateExceptionIfCreateWasNotInvoked()
+ throws IOException {
+ new TemporaryFolder().newFolder();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void newFolderWithGivenPathThrowsIllegalStateExceptionIfCreateWasNotInvoked() throws IOException {
+ new TemporaryFolder().newFolder("level1", "level2", "level3");
+ }
+
+ @Test
+ public void newFolderWithGivenFolderThrowsIOExceptionIfFolderExists() throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("level1");
+
+ thrown.expect(IOException.class);
+ thrown.expectMessage("a folder with the path 'level1' already exists");
+ tempFolder.newFolder("level1");
+ }
+
+ @Test
+ public void newFolderWithGivenFolderThrowsIOExceptionIfFileExists() throws IOException {
+ tempFolder.create();
+ File file = new File(tempFolder.getRoot(), "level1");
+ assertTrue("Could not create" + file, file.createNewFile());
+
+ thrown.expect(IOException.class);
+ thrown.expectMessage("a file with the path 'level1' exists");
+ tempFolder.newFolder("level1");
+ }
+
+ @Test
+ public void newFolderWithGivenFolderThrowsIOExceptionWhenFolderCannotBeCreated() throws IOException {
+ tempFolder.create();
+ assumeTrue("Could not make folder " + tempFolder.getRoot() + " read only.",
+ tempFolder.getRoot().setReadOnly());
+
+ thrown.expect(IOException.class);
+ thrown.expectMessage("could not create a folder with the path 'level1'");
+ tempFolder.newFolder("level1");
+ }
+
+ @Test
+ public void newFolderWithPathStartingWithFileSeparatorThrowsIOException()
+ throws IOException {
+ String fileAtRoot;
+ File[] roots = File.listRoots();
+ if (roots != null && roots.length > 0) {
+ fileAtRoot = roots[0].getAbsolutePath() + "temp1";
+ } else {
+ fileAtRoot = File.separator + "temp1";
+ }
+ tempFolder.create();
+ thrown.expect(IOException.class);
+ thrown.expectMessage("folder path '" + fileAtRoot + "' is not a relative path");
+ tempFolder.newFolder(fileAtRoot);
+ }
+
+ @Test
+ public void newFolderWithPathContainingFileSeparatorCreatesDirectories()
+ throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("temp1" + File.separator + "temp2");
+ File temp1 = new File(tempFolder.getRoot(), "temp1");
+ assertFileIsDirectory(temp1);
+ assertFileIsDirectory(new File(temp1, "temp2"));
+ }
+
+ @Test
+ public void newFolderWithPathContainingForwardSlashCreatesDirectories()
+ throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("temp1/temp2");
+ File temp1 = new File(tempFolder.getRoot(), "temp1");
+ assertFileIsDirectory(temp1);
+ assertFileIsDirectory(new File(temp1, "temp2"));
+ }
+
+ @Test
+ public void newFolderWithGivenPathThrowsIOExceptionIfFolderExists() throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("level1", "level2", "level3");
+
+ thrown.expect(IOException.class);
+ String path = "level1" + File.separator + "level2" + File.separator + "level3";
+ thrown.expectMessage("a folder with the path '" + path + "' already exists");
+ tempFolder.newFolder("level1", "level2", "level3");
+ }
+
+ @Test
+ public void newFolderWithGivenEmptyArrayThrowsIllegalArgumentException() throws IOException {
+ tempFolder.create();
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("must pass at least one path");
+ tempFolder.newFolder(new String[0]);
+ }
+
+ @Test
+ public void newFolderWithPathsContainingForwardSlashCreatesFullPath()
+ throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("temp1", "temp2", "temp3/temp4");
+
+ File directory = new File(tempFolder.getRoot(), "temp1");
+ assertFileIsDirectory(directory);
+ directory = new File(directory, "temp2/temp3/temp4");
+ assertFileIsDirectory(directory);
+ }
+
+ @Test
+ public void newFolderWithPathsContainingFileSeparatorCreatesFullPath()
+ throws IOException {
+ tempFolder.create();
+ tempFolder.newFolder("temp1", "temp2", "temp3" + File.separator + "temp4");
+
+ File directory = new File(tempFolder.getRoot(), "temp1");
+ assertFileIsDirectory(directory);
+ directory = new File(directory, "temp2/temp3/temp4");
+ assertFileIsDirectory(directory);
+ }
+
+ @Test
+ public void createInitializesRootFolder() throws IOException {
+ tempFolder.create();
+ assertFileIsDirectory(tempFolder.getRoot());
+ }
+
+ @Test
+ public void deleteShouldDoNothingIfRootFolderWasNotInitialized() {
+ tempFolder.delete();
+ }
+
+ @Test
+ public void deleteRemovesRootFolder() throws IOException {
+ tempFolder.create();
+ tempFolder.delete();
+ assertFileDoesNotExist(tempFolder.getRoot());
+ }
+
+ @Test
+ public void newRandomFileIsCreatedUnderRootFolder() throws IOException {
+ tempFolder.create();
+
+ File f = tempFolder.newFile();
+ assertFileExists(f);
+ assertFileCreatedUnderRootFolder("Random file", f);
+ }
+
+ @Test
+ public void newNamedFileIsCreatedUnderRootFolder() throws IOException {
+ final String fileName = "SampleFile.txt";
+ tempFolder.create();
+
+ File f = tempFolder.newFile(fileName);
+
+ assertFileExists(f);
+ assertFileCreatedUnderRootFolder("Named file", f);
+ assertThat("file name", f.getName(), equalTo(fileName));
+ }
+
+ @Test
+ public void newRandomFolderIsCreatedUnderRootFolder() throws IOException {
+ tempFolder.create();
+
+ File f = tempFolder.newFolder();
+ assertFileIsDirectory(f);
+ assertFileCreatedUnderRootFolder("Random folder", f);
+ }
+
+ @Test
+ public void newNestedFoldersCreatedUnderRootFolder() throws IOException {
+ tempFolder.create();
+
+ File f = tempFolder.newFolder("top", "middle", "bottom");
+ assertFileIsDirectory(f);
+ assertParentFolderForFileIs(f, new File(tempFolder.getRoot(),
+ "top/middle"));
+ assertParentFolderForFileIs(f.getParentFile(),
+ new File(tempFolder.getRoot(), "top"));
+ assertFileCreatedUnderRootFolder("top", f.getParentFile()
+ .getParentFile());
+ }
+
+ @Test
+ public void canSetTheBaseFileForATemporaryFolder() throws IOException {
+ File tempDir = createTemporaryFolder();
+
+ TemporaryFolder folder = new TemporaryFolder(tempDir);
+ folder.create();
+
+ assertThat(tempDir, is(folder.getRoot().getParentFile()));
+ }
+
+ private File createTemporaryFolder() throws IOException {
+ File tempDir = File.createTempFile("junit", "tempFolder");
+ assertTrue("Unable to delete temporary file", tempDir.delete());
+ assertTrue("Unable to create temp directory", tempDir.mkdir());
+ return tempDir;
+ }
+
+ private void assertFileDoesNotExist(File file) {
+ checkFileExists("exists", file, false);
+ }
+
+ private void checkFileExists(String msg, File file, boolean exists) {
+ assertThat("File is null", file, is(notNullValue()));
+ assertThat("File '" + file.getAbsolutePath() + "' " + msg,
+ file.exists(), is(exists));
+ }
+
+ private void checkFileIsDirectory(String msg, File file, boolean isDirectory) {
+ assertThat("File is null", file, is(notNullValue()));
+ assertThat("File '" + file.getAbsolutePath() + "' " + msg,
+ file.isDirectory(), is(isDirectory));
+ }
+
+ private void assertFileExists(File file) {
+ checkFileExists("does not exist", file, true);
+ checkFileIsDirectory("is a directory", file, false);
+ }
+
+ private void assertFileIsDirectory(File file) {
+ checkFileExists("does not exist", file, true);
+ checkFileIsDirectory("is not a directory", file, true);
+ }
+
+ private void assertFileCreatedUnderRootFolder(String msg, File f) {
+ assertParentFolderForFileIs(f, tempFolder.getRoot());
+ }
+
+ private void assertParentFolderForFileIs(File f, File parentFolder) {
+ assertThat("'" + f.getAbsolutePath() + "': not under root",
+ f.getParentFile(), is(parentFolder));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TestRuleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestRuleTest.java
new file mode 100644
index 0000000..cc6db7d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestRuleTest.java
@@ -0,0 +1,610 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class TestRuleTest {
+ private static boolean wasRun;
+
+ public static class ExampleTest {
+ @Rule
+ public TestRule example = new TestRule() {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ wasRun = true;
+ base.evaluate();
+ }
+ };
+ }
+ };
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluated() {
+ wasRun = false;
+ JUnitCore.runClasses(ExampleTest.class);
+ assertTrue(wasRun);
+ }
+
+ public static class BothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
+ public int applications = 0;
+
+ public Statement apply(Statement base, FrameworkMethod method,
+ Object target) {
+ applications++;
+ return base;
+ }
+
+ public Statement apply(Statement base, Description description) {
+ applications++;
+ return base;
+ }
+ }
+
+ public static class OneFieldTwoKindsOfRule {
+ @Rule
+ public BothKindsOfRule both = new BothKindsOfRule();
+
+ @Test
+ public void onlyOnce() {
+ assertEquals(1, both.applications);
+ }
+ }
+
+
+ @Test
+ public void onlyApplyOnceEvenIfImplementsBothInterfaces() {
+ assertTrue(JUnitCore.runClasses(OneFieldTwoKindsOfRule.class).wasSuccessful());
+ }
+
+ public static class SonOfExampleTest extends ExampleTest {
+
+ }
+
+ @Test
+ public void ruleIsIntroducedAndEvaluatedOnSubclass() {
+ wasRun = false;
+ JUnitCore.runClasses(SonOfExampleTest.class);
+ assertTrue(wasRun);
+ }
+
+ private static int runCount;
+
+ public static class MultipleRuleTest {
+ private static class Increment implements TestRule {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ runCount++;
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ @Rule
+ public TestRule incrementor1 = new Increment();
+
+ @Rule
+ public TestRule incrementor2 = new Increment();
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void multipleRulesAreRun() {
+ runCount = 0;
+ JUnitCore.runClasses(MultipleRuleTest.class);
+ assertEquals(2, runCount);
+ }
+
+ public static class NoRulesTest {
+ public int x;
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void ignoreNonRules() {
+ Result result = JUnitCore.runClasses(NoRulesTest.class);
+ assertEquals(0, result.getFailureCount());
+ }
+
+ private static String log;
+
+ public static class BeforesAndAfters {
+ private static StringBuilder watchedLog = new StringBuilder();
+
+ @Before
+ public void before() {
+ watchedLog.append("before ");
+ }
+
+ @Rule
+ public TestRule watcher = new LoggingTestWatcher(watchedLog);
+
+ @After
+ public void after() {
+ watchedLog.append("after ");
+ }
+
+ @Test
+ public void succeeds() {
+ watchedLog.append("test ");
+ }
+ }
+
+ @Test
+ public void beforesAndAfters() {
+ BeforesAndAfters.watchedLog = new StringBuilder();
+ JUnitCore.runClasses(BeforesAndAfters.class);
+ assertThat(BeforesAndAfters.watchedLog.toString(),
+ is("starting before test after succeeded finished "));
+ }
+
+ public static class WrongTypedField {
+ @Rule
+ public int x = 5;
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void validateWrongTypedField() {
+ assertThat(testResult(WrongTypedField.class),
+ hasSingleFailureContaining("must implement MethodRule"));
+ }
+
+ public static class SonOfWrongTypedField extends WrongTypedField {
+
+ }
+
+ @Test
+ public void validateWrongTypedFieldInSuperclass() {
+ assertThat(testResult(SonOfWrongTypedField.class),
+ hasSingleFailureContaining("must implement MethodRule"));
+ }
+
+ public static class PrivateRule {
+ @Rule
+ private TestRule rule = new TestName();
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void validatePrivateRule() {
+ assertThat(testResult(PrivateRule.class),
+ hasSingleFailureContaining("must be public"));
+ }
+
+ public static class CustomTestName implements TestRule {
+ public String name = null;
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ name = description.getMethodName();
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class UsesCustomMethodRule {
+ @Rule
+ public CustomTestName counter = new CustomTestName();
+
+ @Test
+ public void foo() {
+ assertEquals("foo", counter.name);
+ }
+ }
+
+ @Test
+ public void useCustomMethodRule() {
+ assertThat(testResult(UsesCustomMethodRule.class), isSuccessful());
+ }
+
+ public static class MethodExampleTest {
+ private TestRule example = new TestRule() {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ wasRun = true;
+ base.evaluate();
+ }
+ };
+ }
+ };
+
+ @Rule
+ public TestRule getExample() {
+ return example;
+ }
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void methodRuleIsIntroducedAndEvaluated() {
+ wasRun = false;
+ JUnitCore.runClasses(MethodExampleTest.class);
+ assertTrue(wasRun);
+ }
+
+ public static class MethodBothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
+ public int applications = 0;
+
+ public Statement apply(Statement base, FrameworkMethod method,
+ Object target) {
+ applications++;
+ return base;
+ }
+
+ public Statement apply(Statement base, Description description) {
+ applications++;
+ return base;
+ }
+ }
+
+ public static class MethodOneFieldTwoKindsOfRule {
+ private MethodBothKindsOfRule both = new MethodBothKindsOfRule();
+
+ @Rule
+ public MethodBothKindsOfRule getBoth() {
+ return both;
+ }
+
+ @Test
+ public void onlyOnce() {
+ assertEquals(1, both.applications);
+ }
+ }
+
+
+ @Test
+ public void methodOnlyApplyOnceEvenIfImplementsBothInterfaces() {
+ assertTrue(JUnitCore.runClasses(MethodOneFieldTwoKindsOfRule.class).wasSuccessful());
+ }
+
+ public static class MethodSonOfExampleTest extends MethodExampleTest {
+
+ }
+
+ @Test
+ public void methodRuleIsIntroducedAndEvaluatedOnSubclass() {
+ wasRun = false;
+ JUnitCore.runClasses(MethodSonOfExampleTest.class);
+ assertTrue(wasRun);
+ }
+
+ public static class MethodMultipleRuleTest {
+ private static class Increment implements TestRule {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ runCount++;
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ private TestRule incrementor1 = new Increment();
+
+ @Rule
+ public TestRule getIncrementor1() {
+ return incrementor1;
+ }
+
+ private TestRule incrementor2 = new Increment();
+
+ @Rule
+ public TestRule getIncrementor2() {
+ return incrementor2;
+ }
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void methodMultipleRulesAreRun() {
+ runCount = 0;
+ JUnitCore.runClasses(MethodMultipleRuleTest.class);
+ assertEquals(2, runCount);
+ }
+
+ public static class MethodNoRulesTest {
+ public int x;
+
+ @Test
+ public void nothing() {
+
+ }
+ }
+
+ @Test
+ public void methodIgnoreNonRules() {
+ Result result = JUnitCore.runClasses(MethodNoRulesTest.class);
+ assertEquals(0, result.getFailureCount());
+ }
+
+ public static class BeforesAndAftersAreEnclosedByRule {
+ private static StringBuilder log;
+
+ @Rule
+ public TestRule watcher = new LoggingTestWatcher(log);
+
+ @Before
+ public void before() {
+ log.append("before ");
+ }
+
+ @After
+ public void after() {
+ log.append("after ");
+ }
+
+ @Test
+ public void succeeds() {
+ log.append("test ");
+ }
+ }
+
+ @Test
+ public void beforesAndAftersAreEnclosedByRule() {
+ BeforesAndAftersAreEnclosedByRule.log = new StringBuilder();
+ JUnitCore.runClasses(BeforesAndAftersAreEnclosedByRule.class);
+ assertEquals("starting before test after succeeded finished ",
+ BeforesAndAftersAreEnclosedByRule.log.toString());
+ }
+
+ public static class MethodWrongTypedField {
+ @Rule
+ public int getX() {
+ return 5;
+ }
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void methodValidateWrongTypedField() {
+ assertThat(testResult(MethodWrongTypedField.class),
+ hasSingleFailureContaining("must return an implementation of MethodRule"));
+ }
+
+ public static class MethodSonOfWrongTypedField extends MethodWrongTypedField {
+
+ }
+
+ @Test
+ public void methodValidateWrongTypedFieldInSuperclass() {
+ assertThat(testResult(MethodSonOfWrongTypedField.class),
+ hasSingleFailureContaining("must return an implementation of MethodRule"));
+ }
+
+ public static class MethodPrivateRule {
+ @Rule
+ private TestRule getRule() {
+ return new TestName();
+ }
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void methodValidatePrivateRule() {
+ assertThat(testResult(MethodPrivateRule.class),
+ hasSingleFailureContaining("must be public"));
+ }
+
+ public static class MethodUsesCustomMethodRule {
+ private CustomTestName counter = new CustomTestName();
+
+ @Rule
+ public CustomTestName getCounter() {
+ return counter;
+ }
+
+ @Test
+ public void foo() {
+ assertEquals("foo", counter.name);
+ }
+ }
+
+ @Test
+ public void methodUseCustomMethodRule() {
+ assertThat(testResult(MethodUsesCustomMethodRule.class), isSuccessful());
+ }
+
+ private static final List<String> orderList = new LinkedList<String>();
+
+ private static class OrderTestRule implements TestRule {
+ private String name;
+
+ public OrderTestRule(String name) {
+ this.name = name;
+ }
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ orderList.add(name);
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ public static class UsesFieldAndMethodRule {
+ @Rule
+ public OrderTestRule orderMethod() {
+ return new OrderTestRule("orderMethod");
+ }
+
+ @Rule
+ public OrderTestRule orderField = new OrderTestRule("orderField");
+
+ @Test
+ public void foo() {
+ assertEquals("orderField", orderList.get(0));
+ assertEquals("orderMethod", orderList.get(1));
+ }
+ }
+
+ @Test
+ public void usesFieldAndMethodRule() {
+ orderList.clear();
+ assertThat(testResult(UsesFieldAndMethodRule.class), isSuccessful());
+ }
+
+ public static class CallMethodOnlyOnceRule {
+ int countOfMethodCalls = 0;
+
+ private static class Dummy implements TestRule {
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ }
+ };
+ }
+ }
+
+ @Rule
+ public Dummy both() {
+ countOfMethodCalls++;
+ return new Dummy();
+ }
+
+ @Test
+ public void onlyOnce() {
+ assertEquals(1, countOfMethodCalls);
+ }
+ }
+
+ @Test
+ public void testCallMethodOnlyOnceRule() {
+ assertTrue(JUnitCore.runClasses(CallMethodOnlyOnceRule.class).wasSuccessful());
+ }
+
+ private static final StringBuilder ruleLog = new StringBuilder();
+
+ public static class TestRuleIsAroundMethodRule {
+ @Rule
+ public final MethodRule z = new LoggingMethodRule(ruleLog, "methodRule");
+
+ @Rule
+ public final TestRule a = new LoggingTestRule(ruleLog, "testRule");
+
+ @Test
+ public void foo() {
+ ruleLog.append(" foo");
+ }
+ }
+
+ @Test
+ public void testRuleIsAroundMethodRule() {
+ ruleLog.setLength(0);
+ Result result = JUnitCore.runClasses(TestRuleIsAroundMethodRule.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" testRule.begin methodRule.begin foo methodRule.end testRule.end",
+ ruleLog.toString());
+ }
+
+ public static class TestRuleOrdering {
+ @Rule(order = 1)
+ public final TestRule a = new LoggingTestRule(ruleLog, "outer");
+
+ @Rule(order = 2)
+ public final TestRule z = new LoggingTestRule(ruleLog, "inner");
+
+ @Test
+ public void foo() {
+ ruleLog.append(" foo");
+ }
+ }
+
+ @Test
+ public void testRuleOrdering() {
+ ruleLog.setLength(0);
+ Result result = JUnitCore.runClasses(TestRuleOrdering.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" outer.begin inner.begin foo inner.end outer.end", ruleLog.toString());
+ }
+
+ public static class TestRuleOrderingWithMethodRule {
+ @Rule(order = 1)
+ public final MethodRule z = new LoggingMethodRule(ruleLog, "methodRule");
+
+ @Rule(order = 2)
+ public final TestRule a = new LoggingTestRule(ruleLog, "testRule");
+
+ @Test
+ public void foo() {
+ ruleLog.append(" foo");
+ }
+ }
+
+ @Test
+ public void testRuleOrderingWithMethodRule() {
+ ruleLog.setLength(0);
+ Result result = JUnitCore.runClasses(TestRuleOrderingWithMethodRule.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(" methodRule.begin testRule.begin foo testRule.end methodRule.end",
+ ruleLog.toString());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatcherTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatcherTest.java
new file mode 100644
index 0000000..e09e23c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatcherTest.java
@@ -0,0 +1,397 @@
+package org.junit.rules;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
+import static org.junit.rules.ExpectedException.none;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.model.Statement;
+
+import java.util.List;
+
+@RunWith(Enclosed.class)
+public class TestWatcherTest {
+
+ @RunWith(Parameterized.class)
+ public static class Callbacks {
+
+ @Parameters(name = "{0}")
+ public static Object[][] parameters() {
+ return new Object[][] {
+ {
+ FailingTest.class,
+ "starting failed finished ",
+ asList("starting failed", "test failed", "failed failed", "finished failed") },
+ {
+ InternalViolatedAssumptionTest.class,
+ "starting deprecated skipped finished ",
+ asList("starting failed", "don't run", "deprecated skipped failed", "finished failed") },
+ {
+ SuccessfulTest.class,
+ "starting succeeded finished ",
+ asList("starting failed", "succeeded failed", "finished failed") },
+ {
+ ViolatedAssumptionTest.class,
+ "starting skipped finished ",
+ asList("starting failed", "Test could not be skipped due to other failures", "skipped failed", "finished failed") }
+ };
+ }
+
+ @Parameter(0)
+ public Class<?> testClass;
+
+ @Parameter(1)
+ public String expectedCallbacks;
+
+ @Parameter(2)
+ public List<String> expectedFailures;
+
+ private static TestRule selectedRule; //for injecting rule into test classes
+
+ @Test
+ public void correctCallbacksCalled() {
+ StringBuilder log = new StringBuilder();
+ selectedRule = new LoggingTestWatcher(log);
+ JUnitCore.runClasses(testClass);
+ assertEquals(expectedCallbacks, log.toString());
+ }
+
+ @Test
+ public void resultHasAllFailuresThrownByCallbacks() {
+ selectedRule = new ErroneousTestWatcher();
+ PrintableResult result = testResult(testClass);
+ assertThat(result, failureCountIs(expectedFailures.size()));
+ for (String expectedFailure: expectedFailures) {
+ assertThat(result, hasFailureContaining(expectedFailure));
+ }
+ }
+
+ @Test
+ public void testWatcherDoesNotModifyResult() {
+ selectedRule = new NoOpRule();
+ Result resultNoOpRule = JUnitCore.runClasses(testClass);
+ selectedRule = new LoggingTestWatcher(new StringBuilder());
+ Result resultTestWatcher = JUnitCore.runClasses(testClass);
+ assertEquals(
+ "was successful",
+ resultNoOpRule.wasSuccessful(),
+ resultTestWatcher.wasSuccessful());
+ assertEquals(
+ "failure count",
+ resultNoOpRule.getFailureCount(),
+ resultTestWatcher.getFailureCount());
+ assertEquals(
+ "ignore count",
+ resultNoOpRule.getIgnoreCount(),
+ resultTestWatcher.getIgnoreCount());
+ assertEquals(
+ "run count",
+ resultNoOpRule.getRunCount(),
+ resultTestWatcher.getRunCount());
+ }
+
+ private static class NoOpRule implements TestRule {
+ public Statement apply(Statement base, Description description) {
+ return base;
+ }
+ }
+
+ private static class ErroneousTestWatcher extends TestWatcher {
+ @Override
+ protected void succeeded(Description description) {
+ throw new RuntimeException("succeeded failed");
+ }
+
+ @Override
+ protected void failed(Throwable e, Description description) {
+ throw new RuntimeException("failed failed");
+ }
+
+ @Override
+ protected void skipped(org.junit.AssumptionViolatedException e, Description description) {
+ throw new RuntimeException("skipped failed");
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ protected void skipped(AssumptionViolatedException e, Description description) {
+ throw new RuntimeException("deprecated skipped failed");
+ }
+
+ @Override
+ protected void starting(Description description) {
+ throw new RuntimeException("starting failed");
+ }
+
+ @Override
+ protected void finished(Description description) {
+ throw new RuntimeException("finished failed");
+ }
+ }
+
+ public static class FailingTest {
+ @Rule
+ public TestRule rule = selectedRule;
+
+ @Test
+ public void test() {
+ fail("test failed");
+ }
+ }
+
+ public static class InternalViolatedAssumptionTest {
+ @Rule
+ public TestRule watcher = selectedRule;
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void test() {
+ throw new AssumptionViolatedException("don't run");
+ }
+ }
+
+ public static class SuccessfulTest {
+ @Rule
+ public TestRule watcher = selectedRule;
+
+ @Test
+ public void test() {
+ }
+ }
+
+ public static class ViolatedAssumptionTest {
+ @Rule
+ public TestRule watcher = selectedRule;
+
+ @Test
+ public void test() {
+ assumeTrue(false);
+ }
+ }
+ }
+
+ public static class CallbackArguments {
+
+ public static class Succeeded {
+ private static Description catchedDescription;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ protected void succeeded(Description description) {
+ catchedDescription = description;
+ }
+ };
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void succeeded() {
+ JUnitCore.runClasses(Succeeded.class);
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$Succeeded)",
+ Succeeded.catchedDescription.getDisplayName());
+ }
+
+ public static class Failed {
+ private static Description catchedDescription;
+ private static Throwable catchedThrowable;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ protected void failed(Throwable e, Description description) {
+ catchedDescription = description;
+ catchedThrowable = e;
+ }
+ };
+
+ @Test
+ public void test() {
+ fail("test failed");
+ }
+ }
+
+ @Test
+ public void failed() {
+ JUnitCore.runClasses(Failed.class);
+ assertEquals("test failed", Failed.catchedThrowable.getMessage());
+ assertEquals(AssertionError.class, Failed.catchedThrowable.getClass());
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$Failed)",
+ Failed.catchedDescription.getDisplayName());
+ }
+
+ public static class Skipped {
+ private static Description catchedDescription;
+ private static org.junit.AssumptionViolatedException catchedException;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ protected void skipped(org.junit.AssumptionViolatedException e, Description description) {
+ catchedDescription = description;
+ catchedException = e;
+ }
+ };
+
+ @Test
+ public void test() {
+ assumeTrue("test skipped", false);
+ }
+ }
+
+ @Test
+ public void skipped() {
+ JUnitCore.runClasses(Skipped.class);
+ assertEquals("test skipped", Skipped.catchedException.getMessage());
+ assertEquals(org.junit.AssumptionViolatedException.class, Skipped.catchedException.getClass());
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$Skipped)",
+ Skipped.catchedDescription.getDisplayName());
+ }
+
+ public static class DeprecatedSkipped {
+ private static Description catchedDescription;
+ private static AssumptionViolatedException catchedException;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ @SuppressWarnings("deprecation")
+ protected void skipped(AssumptionViolatedException e, Description description) {
+ catchedDescription = description;
+ catchedException = e;
+ }
+ };
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void test() {
+ throw new AssumptionViolatedException("test skipped");
+ }
+ }
+
+ @Test
+ public void deprecatedSkipped() {
+ JUnitCore.runClasses(DeprecatedSkipped.class);
+ assertEquals("test skipped", DeprecatedSkipped.catchedException.getMessage());
+ assertEquals(AssumptionViolatedException.class, DeprecatedSkipped.catchedException.getClass());
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$DeprecatedSkipped)",
+ DeprecatedSkipped.catchedDescription.getDisplayName());
+ }
+
+ public static class Starting {
+ private static Description catchedDescription;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ protected void starting(Description description) {
+ catchedDescription = description;
+ }
+ };
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void starting() {
+ JUnitCore.runClasses(Starting.class);
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$Starting)",
+ Starting.catchedDescription.getDisplayName());
+ }
+
+ public static class Finished {
+ private static Description catchedDescription;
+
+ @Rule
+ public final TestRule watcher = new TestWatcher() {
+ @Override
+ protected void finished(Description description) {
+ catchedDescription = description;
+ }
+ };
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void finished() {
+ JUnitCore.runClasses(Finished.class);
+ assertEquals("test(org.junit.rules.TestWatcherTest$CallbackArguments$Finished)",
+ Finished.catchedDescription.getDisplayName());
+ }
+ }
+
+ //The following tests check the information in TestWatcher's Javadoc
+ //regarding interplay with other rules.
+ public static class InterplayWithOtherRules {
+ private static StringBuilder log;
+
+ public static class ExpectedExceptionTest {
+ @Rule(order = Integer.MIN_VALUE)
+ //the field name must be alphabetically lower than "thrown" in order
+ //to make the test failing if order is not set
+ public final TestRule a = new LoggingTestWatcher(log);
+
+ @Rule
+ public final ExpectedException thrown = none();
+
+ @Test
+ public void testWithExpectedException() {
+ thrown.expect(RuntimeException.class);
+ throw new RuntimeException("expected exception");
+ }
+ }
+
+ @Test
+ public void expectedExceptionIsSeenAsSuccessfulTest() {
+ log = new StringBuilder();
+ JUnitCore.runClasses(ExpectedExceptionTest.class);
+ assertEquals("starting succeeded finished ", log.toString());
+ }
+
+ public static class ErrorCollectorTest {
+ @Rule(order = Integer.MIN_VALUE)
+ //the field name must be alphabetically lower than "collector" in
+ //order to make the test failing if order is not set
+ public final TestRule a = new LoggingTestWatcher(log);
+
+ @Rule
+ public final ErrorCollector collector = new ErrorCollector();
+
+ @Test
+ public void test() {
+ collector.addError(new RuntimeException("expected exception"));
+ }
+ }
+
+ @Test
+ public void testIsSeenAsFailedBecauseOfCollectedError() {
+ log = new StringBuilder();
+ JUnitCore.runClasses(ErrorCollectorTest.class);
+ assertEquals("starting failed finished ", log.toString());
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatchmanTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatchmanTest.java
new file mode 100644
index 0000000..b7b76be
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TestWatchmanTest.java
@@ -0,0 +1,90 @@
+package org.junit.rules;
+
+import static junit.framework.Assert.fail;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.runner.JUnitCore.runClasses;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runners.model.FrameworkMethod;
+
+@SuppressWarnings("deprecation")
+public class TestWatchmanTest {
+ public static class ViolatedAssumptionTest {
+ static StringBuilder log;
+
+ @BeforeClass
+ public static void initLog() {
+ log = new StringBuilder();
+ }
+
+ @Rule
+ public LoggingTestWatchman watchman = new LoggingTestWatchman(log);
+
+ @Test
+ public void succeeds() {
+ assumeTrue(false);
+ }
+ }
+
+ @Test
+ public void neitherLogSuccessNorFailedForViolatedAssumption() {
+ runClasses(ViolatedAssumptionTest.class);
+ assertThat(ViolatedAssumptionTest.log.toString(),
+ is("starting finished "));
+ }
+
+ public static class FailingTest {
+ static StringBuilder log;
+
+ @BeforeClass
+ public static void initLog() {
+ log = new StringBuilder();
+ }
+
+ @Rule
+ public LoggingTestWatchman watchman = new LoggingTestWatchman(log);
+
+ @Test
+ public void succeeds() {
+ fail();
+ }
+ }
+
+ @Test
+ public void logFailingTest() {
+ runClasses(FailingTest.class);
+ assertThat(FailingTest.log.toString(),
+ is("starting failed finished "));
+ }
+
+ private static class LoggingTestWatchman extends TestWatchman {
+ private final StringBuilder log;
+
+ private LoggingTestWatchman(StringBuilder log) {
+ this.log = log;
+ }
+
+ @Override
+ public void succeeded(FrameworkMethod method) {
+ log.append("succeeded ");
+ }
+
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ log.append("failed ");
+ }
+
+ @Override
+ public void starting(FrameworkMethod method) {
+ log.append("starting ");
+ }
+
+ @Override
+ public void finished(FrameworkMethod method) {
+ log.append("finished ");
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/TimeoutRuleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/TimeoutRuleTest.java
new file mode 100644
index 0000000..6c0e349
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/TimeoutRuleTest.java
@@ -0,0 +1,162 @@
+package org.junit.rules;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+public class TimeoutRuleTest {
+ private static final ReentrantLock run1Lock = new ReentrantLock();
+
+ private static volatile boolean run4done = false;
+
+ public abstract static class AbstractTimeoutTest {
+ public static final StringBuffer logger = new StringBuffer();
+
+ @Rule
+ public final TemporaryFolder tmpFile = new TemporaryFolder();
+
+ @Test
+ public void run1() throws InterruptedException {
+ logger.append("run1");
+ TimeoutRuleTest.run1Lock.lockInterruptibly();
+ TimeoutRuleTest.run1Lock.unlock();
+ }
+
+ @Test
+ public void run2() throws InterruptedException {
+ logger.append("run2");
+ Thread.currentThread().join();
+ }
+
+ @Test
+ public synchronized void run3() throws InterruptedException {
+ logger.append("run3");
+ wait();
+ }
+
+ @Test
+ public void run4() {
+ logger.append("run4");
+ while (!run4done) {
+ }
+ }
+
+ @Test
+ public void run5() throws IOException {
+ logger.append("run5");
+ Random rnd = new Random();
+ byte[] data = new byte[1024];
+ File tmp = tmpFile.newFile();
+ while (true) {
+ RandomAccessFile randomAccessFile = new RandomAccessFile(tmp, "rw");
+ try {
+ FileChannel channel = randomAccessFile.getChannel();
+ rnd.nextBytes(data);
+ ByteBuffer buffer = ByteBuffer.wrap(data);
+ // Interrupted thread closes channel and throws ClosedByInterruptException.
+ channel.write(buffer);
+ } finally {
+ randomAccessFile.close();
+ }
+ tmp.delete();
+ }
+ }
+
+ @Test
+ public void run6() throws InterruptedIOException {
+ logger.append("run6");
+ // Java IO throws InterruptedIOException only on SUN machines.
+ throw new InterruptedIOException();
+ }
+ }
+
+ public static class HasGlobalLongTimeout extends AbstractTimeoutTest {
+
+ @Rule
+ public final TestRule globalTimeout = Timeout.millis(200);
+ }
+
+ public static class HasGlobalTimeUnitTimeout extends AbstractTimeoutTest {
+
+ @Rule
+ public final TestRule globalTimeout = new Timeout(200, TimeUnit.MILLISECONDS);
+ }
+
+ public static class HasNullTimeUnit {
+
+ @Rule
+ public final TestRule globalTimeout = new Timeout(200, null);
+
+ @Test
+ public void wouldPass() {
+ }
+ }
+
+ @Before
+ public void before() {
+ run4done = false;
+ run1Lock.lock();
+ }
+
+ @After
+ public void after() {
+ // set run4done to make sure that the thread won't continue at run4()
+ run4done = true;
+ run1Lock.unlock();
+ }
+
+ @Test
+ public void timeUnitTimeout() {
+ HasGlobalTimeUnitTimeout.logger.setLength(0);
+ Result result = JUnitCore.runClasses(HasGlobalTimeUnitTimeout.class);
+ assertEquals(6, result.getFailureCount());
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run1"));
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run2"));
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run3"));
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run4"));
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run5"));
+ assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run6"));
+ }
+
+ @Test
+ public void longTimeout() {
+ HasGlobalLongTimeout.logger.setLength(0);
+ Result result = JUnitCore.runClasses(HasGlobalLongTimeout.class);
+ assertEquals(6, result.getFailureCount());
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run1"));
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run2"));
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run3"));
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run4"));
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run5"));
+ assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run6"));
+ }
+
+ @Test
+ public void nullTimeUnit() {
+ Result result = JUnitCore.runClasses(HasNullTimeUnit.class);
+ assertEquals(1, result.getFailureCount());
+ Failure failure = result.getFailures().get(0);
+ assertThat(failure.getException().getMessage(),
+ containsString("Invalid parameters for Timeout"));
+ Throwable cause = failure.getException().getCause();
+ assertThat(cause.getMessage(), containsString("TimeUnit cannot be null"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/rules/VerifierRuleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/rules/VerifierRuleTest.java
new file mode 100644
index 0000000..4a09bc7
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/rules/VerifierRuleTest.java
@@ -0,0 +1,36 @@
+package org.junit.rules;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+public class VerifierRuleTest {
+
+ private static String sequence;
+
+ public static class UsesVerifier {
+ @Rule
+ public Verifier collector = new Verifier() {
+ @Override
+ protected void verify() {
+ sequence += "verify ";
+ }
+ };
+
+ @Test
+ public void example() {
+ sequence += "test ";
+ }
+ }
+
+ @Test
+ public void verifierRunsAfterTest() {
+ sequence = "";
+ assertThat(testResult(UsesVerifier.class), isSuccessful());
+ assertEquals("test verify ", sequence);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/AllRunnerTests.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/AllRunnerTests.java
new file mode 100644
index 0000000..3334b40
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/AllRunnerTests.java
@@ -0,0 +1,18 @@
+package org.junit.runner;
+
+
+import org.junit.runner.notification.AllNotificationTests;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllNotificationTests.class,
+ FilterFactoriesTest.class,
+ FilterOptionIntegrationTest.class,
+ OrderWithValidatorTest.class,
+ JUnitCommandLineParseResultTest.class,
+ JUnitCoreTest.class, RequestTest.class
+})
+public class AllRunnerTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterFactoriesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterFactoriesTest.java
new file mode 100644
index 0000000..c00efde
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterFactoriesTest.java
@@ -0,0 +1,137 @@
+package org.junit.runner;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeThat;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.ExcludeCategories;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TestName;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+public class FilterFactoriesTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public TestName testName = new TestName();
+
+ private Request createSuiteRequest() {
+ return Request.aClass(DummySuite.class);
+ }
+
+ @Test
+ public void shouldCreateFilterWithArguments() throws Exception {
+ Filter filter = FilterFactories.createFilterFromFilterSpec(
+ createSuiteRequest(),
+ ExcludeCategories.class.getName() + "=" + DummyCategory.class.getName());
+
+ assertThat(filter.describe(), startsWith("excludes "));
+ }
+
+ @Test
+ public void shouldCreateFilterWithNoArguments() throws Exception {
+ Filter filter = FilterFactories.createFilterFromFilterSpec(
+ createSuiteRequest(), FilterFactoryStub.class.getName());
+
+ assertThat(filter, instanceOf(DummyFilter.class));
+ }
+
+ @Test
+ public void shouldPassOnDescriptionToFilterFactory() throws Exception {
+ Request request = createSuiteRequest();
+ Description description = request.getRunner().getDescription();
+ Filter filter = FilterFactories.createFilterFromFilterSpec(
+ request, FilterFactoryStub.class.getName());
+
+ // This assumption tested in shouldCreateFilterWithNoArguments()
+ assumeThat(filter, instanceOf(DummyFilter.class));
+
+ DummyFilter dummyFilter = (DummyFilter) filter;
+ assertThat(dummyFilter.getTopLevelDescription(), is(description));
+ }
+
+ @Test
+ public void shouldCreateFilter() throws Exception {
+ Filter filter = FilterFactories.createFilter(
+ FilterFactoryStub.class,
+ new FilterFactoryParams(
+ Description.createSuiteDescription(testName.getMethodName()),
+ ""));
+
+ assertThat(filter, instanceOf(DummyFilter.class));
+ }
+
+ @Test
+ public void shouldThrowExceptionIfNotFilterFactory() throws Exception {
+ expectedException.expect(FilterFactory.FilterNotCreatedException.class);
+
+ FilterFactories.createFilterFactory(NonFilterFactory.class.getName());
+ }
+
+ @Test
+ public void shouldThrowExceptionIfNotInstantiable() throws Exception {
+ expectedException.expect(FilterFactory.FilterNotCreatedException.class);
+
+ FilterFactories.createFilterFactory(NonInstantiableFilterFactory.class);
+ }
+
+ public static class NonFilterFactory {
+ }
+
+ public static class NonInstantiableFilterFactory implements FilterFactory {
+ private NonInstantiableFilterFactory() {
+ }
+
+ public Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException {
+ throw new FilterNotCreatedException(new Exception("not implemented"));
+ }
+ }
+
+ public static class FilterFactoryStub implements FilterFactory {
+ public Filter createFilter(FilterFactoryParams params) {
+ return new DummyFilter(params.getTopLevelDescription());
+ }
+ }
+
+ private static class DummyFilter extends Filter {
+ private final Description fTopLevelDescription;
+
+ public DummyFilter(Description topLevelDescription) {
+ fTopLevelDescription = topLevelDescription;
+ }
+
+ public Description getTopLevelDescription() {
+ return fTopLevelDescription;
+ }
+
+ @Override
+ public boolean shouldRun(Description description) {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return null;
+ }
+ }
+
+ public static class DummyCategory {
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses(DummyTest.class)
+ public static class DummySuite {
+ }
+
+ public static class DummyTest {
+ @Test
+ public void passes() {
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterOptionIntegrationTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterOptionIntegrationTest.java
new file mode 100644
index 0000000..25cde87
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/FilterOptionIntegrationTest.java
@@ -0,0 +1,190 @@
+package org.junit.runner;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.experimental.categories.ExcludeCategories;
+import org.junit.experimental.categories.IncludeCategories;
+import org.junit.runner.notification.RunListener;
+import org.junit.tests.TestSystem;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class FilterOptionIntegrationTest {
+ private static final String INCLUDES_DUMMY_CATEGORY_0 = "--filter=" +
+ IncludeCategories.class.getName() + "=" + DummyCategory0.class.getName();
+ private static final String EXCLUDES_DUMMY_CATEGORY_1 = "--filter=" +
+ ExcludeCategories.class.getName() + "=" + DummyCategory1.class.getName();
+
+ private JUnitCore jUnitCore = new JUnitCore();
+ private TestListener testListener = new TestListener();
+
+ @Before
+ public void setUp() {
+ jUnitCore.addListener(testListener);
+ }
+
+ @Test
+ public void shouldRunAllTests() {
+ Result result = runJUnit(
+ DummyTestClass.class.getName(),
+ DummyTestClass0.class.getName(),
+ DummyTestClass1.class.getName(),
+ DummyTestClass01.class.getName(),
+ DummyTestClass0TestMethod1.class.getName());
+
+ assertWasRun(DummyTestClass.class);
+ assertWasRun(DummyTestClass0.class);
+ assertWasRun(DummyTestClass1.class);
+ assertWasRun(DummyTestClass01.class);
+ assertWasRun(DummyTestClass0TestMethod1.class);
+ assertThat("runCount does not match", result.getRunCount(), is(5));
+ assertThat("failureCount does not match", result.getFailureCount(), is(0));
+ }
+
+ @Test
+ public void shouldExcludeSomeTests() {
+ Result result = runJUnit(
+ EXCLUDES_DUMMY_CATEGORY_1,
+ DummyTestClass.class.getName(),
+ DummyTestClass0.class.getName(),
+ DummyTestClass1.class.getName(),
+ DummyTestClass01.class.getName(),
+ DummyTestClass0TestMethod1.class.getName());
+
+ assertWasRun(DummyTestClass.class);
+ assertWasRun(DummyTestClass0.class);
+ assertWasNotRun(DummyTestClass1.class);
+ assertWasNotRun(DummyTestClass01.class);
+ assertWasNotRun(DummyTestClass0TestMethod1.class);
+ assertThat("runCount does not match", result.getRunCount(), is(2));
+ assertThat("failureCount does not match", result.getFailureCount(), is(0));
+ }
+
+ @Test
+ public void shouldIncludeSomeTests() {
+ Result result = runJUnit(
+ INCLUDES_DUMMY_CATEGORY_0,
+ DummyTestClass.class.getName(),
+ DummyTestClass0.class.getName(),
+ DummyTestClass1.class.getName(),
+ DummyTestClass01.class.getName(),
+ DummyTestClass0TestMethod1.class.getName());
+
+ assertWasNotRun(DummyTestClass.class);
+ assertWasRun(DummyTestClass0.class);
+ assertWasNotRun(DummyTestClass1.class);
+ assertWasRun(DummyTestClass01.class);
+ assertWasRun(DummyTestClass0TestMethod1.class);
+ assertThat("runCount does not match", result.getRunCount(), is(3));
+ assertThat("failureCount does not match", result.getFailureCount(), is(0));
+ }
+
+ @Test
+ public void shouldCombineFilters() {
+ Result result = runJUnit(
+ INCLUDES_DUMMY_CATEGORY_0,
+ EXCLUDES_DUMMY_CATEGORY_1,
+ DummyTestClass.class.getName(),
+ DummyTestClass0.class.getName(),
+ DummyTestClass1.class.getName(),
+ DummyTestClass01.class.getName(),
+ DummyTestClass0TestMethod1.class.getName());
+
+ assertWasNotRun(DummyTestClass.class);
+ assertWasRun(DummyTestClass0.class);
+ assertWasNotRun(DummyTestClass1.class);
+ assertWasNotRun(DummyTestClass01.class);
+ assertWasNotRun(DummyTestClass0TestMethod1.class);
+ assertThat("runCount does not match", result.getRunCount(), is(1));
+ assertThat("failureCount does not match", result.getFailureCount(), is(0));
+ }
+
+ private Result runJUnit(final String... args) {
+ return jUnitCore.runMain(new TestSystem(), args);
+ }
+
+ private void assertWasRun(Class<?> testClass) {
+ assertTrue(testClass.getName() + " expected to finish but did not", testListener.wasRun(testClass));
+ }
+
+ private void assertWasNotRun(Class<?> testClass) {
+ assertFalse(
+ testClass.getName() + " expected not to have been started but was",
+ testListener.wasRun(testClass));
+ }
+
+ private static class TestListener extends RunListener {
+ private Set<String> startedTests = new HashSet<String>();
+ private Set<String> finishedTests = new HashSet<String>();
+
+ @Override
+ public void testFinished(final Description description) {
+ finishedTests.add(description.getClassName());
+ }
+
+ private boolean testFinished(final Class<?> testClass) {
+ return finishedTests.contains(testClass.getName());
+ }
+
+ @Override
+ public void testStarted(final Description description) {
+ startedTests.add(description.getClassName());
+ }
+
+ private boolean testStarted(final Class<?> testClass) {
+ return startedTests.contains(testClass.getName());
+ }
+
+ public boolean wasRun(final Class<?> testClass) {
+ return testStarted(testClass) && testFinished(testClass);
+ }
+ }
+
+ public static class DummyTestClass {
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Category(DummyCategory0.class)
+ public static class DummyTestClass0 {
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Category(DummyCategory1.class)
+ public static class DummyTestClass1 {
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Category({DummyCategory0.class, DummyCategory1.class})
+ public static class DummyTestClass01 {
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Category(DummyCategory0.class)
+ public static class DummyTestClass0TestMethod1 {
+ @Category(DummyCategory1.class)
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ public static interface DummyCategory0 {
+ }
+
+ public static interface DummyCategory1 {
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCommandLineParseResultTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCommandLineParseResultTest.java
new file mode 100644
index 0000000..065f7bf
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCommandLineParseResultTest.java
@@ -0,0 +1,146 @@
+package org.junit.runner;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.IncludeCategories;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.manipulation.Filter;
+
+public class JUnitCommandLineParseResultTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private final JUnitCommandLineParseResult jUnitCommandLineParseResult = new JUnitCommandLineParseResult();
+
+ @Test
+ public void shouldStopParsingOptionsUponDoubleHyphenArg() throws Exception {
+ String[] restOfArgs = jUnitCommandLineParseResult.parseOptions(
+ "--0", "--1", "--", "--2", "--3");
+
+ assertThat(restOfArgs, is(new String[]{"--2", "--3"}));
+ }
+
+ @Test
+ public void shouldParseFilterArgWithEqualsSyntax() throws Exception {
+ String value= IncludeCategories.class.getName() + "=" + DummyCategory0.class.getName();
+ jUnitCommandLineParseResult.parseOptions("--filter=" + value);
+
+ List<String> specs= jUnitCommandLineParseResult.getFilterSpecs();
+
+ assertThat(specs, hasItems(value));
+ }
+
+ @Test
+ public void shouldCreateFailureUponBaldFilterOptionNotFollowedByValue() {
+ jUnitCommandLineParseResult.parseOptions("--filter");
+
+ Runner runner = jUnitCommandLineParseResult.createRequest(new Computer()).getRunner();
+ Description description = runner.getDescription().getChildren().get(0);
+
+ assertThat(description.toString(), containsString("initializationError"));
+ }
+
+ @Test
+ public void shouldParseFilterArgInWhichValueIsASeparateArg() throws Exception {
+ String value= IncludeCategories.class.getName() + "=" + DummyCategory0.class.getName();
+ jUnitCommandLineParseResult.parseOptions("--filter", value);
+
+ List<String> specs= jUnitCommandLineParseResult.getFilterSpecs();
+
+ assertThat(specs, hasItems(value));
+ }
+
+ @Test
+ public void shouldStopParsingOptionsUponNonOption() throws Exception {
+ String[] restOfArgs = jUnitCommandLineParseResult.parseOptions(new String[]{
+ "--0", "--1", "2", "3"
+ });
+
+ assertThat(restOfArgs, is(new String[]{"2", "3"}));
+ }
+
+ @Test
+ public void shouldCreateFailureUponUnknownOption() throws Exception {
+ String unknownOption = "--unknown-option";
+ jUnitCommandLineParseResult.parseOptions(new String[]{
+ unknownOption
+ });
+
+ Runner runner = jUnitCommandLineParseResult.createRequest(new Computer()).getRunner();
+ Description description = runner.getDescription().getChildren().get(0);
+
+ assertThat(description.toString(), containsString("initializationError"));
+ }
+
+ @Test
+ public void shouldCreateFailureUponUncreatedFilter() throws Exception {
+ jUnitCommandLineParseResult.parseOptions(new String[]{
+ "--filter=" + FilterFactoryStub.class.getName()
+ });
+
+ Runner runner = jUnitCommandLineParseResult.createRequest(new Computer()).getRunner();
+ Description description = runner.getDescription().getChildren().get(0);
+
+ assertThat(description.toString(), containsString("initializationError"));
+ }
+
+ @Test
+ public void shouldCreateFailureUponUnfoundFilterFactory() throws Exception {
+ String nonExistentFilterFactory = "NonExistentFilterFactory";
+ jUnitCommandLineParseResult.parseOptions(new String[]{
+ "--filter=" + nonExistentFilterFactory
+ });
+
+ Runner runner = jUnitCommandLineParseResult.createRequest(new Computer()).getRunner();
+ Description description = runner.getDescription().getChildren().get(0);
+
+ assertThat(description.toString(), containsString("initializationError"));
+ }
+
+ @Test
+ public void shouldAddToClasses() {
+ jUnitCommandLineParseResult.parseParameters(new String[]{
+ DummyTest.class.getName()
+ });
+
+ List<Class<?>> classes = jUnitCommandLineParseResult.getClasses();
+ Class<?> testClass = classes.get(0);
+
+ assertThat(testClass.getName(), is(DummyTest.class.getName()));
+ }
+
+ @Test
+ public void shouldCreateFailureUponUnknownTestClass() throws Exception {
+ String unknownTestClass = "UnknownTestClass";
+ jUnitCommandLineParseResult.parseParameters(new String[]{
+ unknownTestClass
+ });
+
+ Runner runner = jUnitCommandLineParseResult.createRequest(new Computer()).getRunner();
+ Description description = runner.getDescription().getChildren().get(0);
+
+ assertThat(description.toString(), containsString("initializationError"));
+ }
+
+ public static class FilterFactoryStub implements FilterFactory {
+ public Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException {
+ throw new FilterNotCreatedException(new Exception("stub"));
+ }
+ }
+
+ public static interface DummyCategory0 {
+ }
+
+ public static class DummyTest {
+ @Test
+ public void dummyTest() {
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCoreTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCoreTest.java
new file mode 100644
index 0000000..2c5e408
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/JUnitCoreTest.java
@@ -0,0 +1,20 @@
+package org.junit.runner;
+
+import org.junit.Test;
+import org.junit.tests.TestSystem;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class JUnitCoreTest {
+ @Test
+ public void shouldAddFailuresToResult() {
+ JUnitCore jUnitCore = new JUnitCore();
+
+ Result result = jUnitCore.runMain(new TestSystem(), "NonExistentTest");
+
+ assertThat(result.getFailureCount(), is(1));
+ assertThat(result.getFailures().get(0).getException(), instanceOf(IllegalArgumentException.class));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/OrderWithValidatorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/OrderWithValidatorTest.java
new file mode 100644
index 0000000..cfa3c5e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/OrderWithValidatorTest.java
@@ -0,0 +1,50 @@
+package org.junit.runner;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.List;
+
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.manipulation.Alphanumeric;
+import org.junit.runners.JUnit4;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.model.TestClass;
+
+public class OrderWithValidatorTest {
+ private final OrderWithValidator validator = new OrderWithValidator();
+
+ @RunWith(JUnit4.class)
+ @OrderWith(Alphanumeric.class)
+ public static class TestWithNoValidationErrors {
+ @Test
+ public void passes() {}
+ }
+
+ @RunWith(JUnit4.class)
+ @OrderWith(Alphanumeric.class)
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class TestAnnotatedWithFixMethodOrder {
+ @Test
+ public void passes() {}
+ }
+
+ @Test
+ public void noErrorIsAddedForTestWithoutValdationErrors() {
+ List<Exception> errors = validator.validateAnnotatedClass(
+ new TestClass(TestWithNoValidationErrors.class));
+
+ assertThat(errors.size(), is(0));
+ }
+
+ @Test
+ public void errorIsAddedWhenTestAnnotatedWithFixMethodOrder() {
+ List<Exception> errors = validator.validateAnnotatedClass(
+ new TestClass(TestAnnotatedWithFixMethodOrder.class));
+
+ assertThat(errors.size(), is(1));
+ Exception exception = errors.get(0);
+ assertThat(exception.getMessage(), is("@FixMethodOrder cannot be combined with @OrderWith"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/RequestTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/RequestTest.java
new file mode 100644
index 0000000..dc6a811
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/RequestTest.java
@@ -0,0 +1,50 @@
+package org.junit.runner;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.rules.EventCollector.hasSingleFailureWithMessage;
+
+import org.junit.Test;
+import org.junit.rules.EventCollector;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+public class RequestTest {
+
+ /**
+ * #1320 A root of a {@link Description} produced by
+ * {@link Request#classes(Class...)} should be named "classes"
+ */
+ @Test
+ public void createsADescriptionWithANameForClasses() {
+ Description description = Request
+ .classes(RequestTest.class, RequestTest.class).getRunner()
+ .getDescription();
+ assertThat(description.toString(), is("classes"));
+ }
+
+ @Test
+ public void reportsInitializationErrorThrownWhileCreatingSuite() {
+ EventCollector collector = new EventCollector();
+ JUnitCore core = new JUnitCore();
+ core.addListener(collector);
+
+ core.run(new FailingComputer(), FooTest.class, BarTest.class);
+
+ assertThat(collector, hasSingleFailureWithMessage("cannot create suite"));
+ }
+
+ private static class FailingComputer extends Computer {
+ @Override
+ public Runner getSuite(RunnerBuilder builder, Class<?>[] classes)
+ throws InitializationError {
+ throw new InitializationError("cannot create suite");
+ }
+ }
+
+ private static class FooTest {
+ }
+
+ private static class BarTest {
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/RunnerSpy.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/RunnerSpy.java
new file mode 100644
index 0000000..939cd75
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/RunnerSpy.java
@@ -0,0 +1,37 @@
+package org.junit.runner;
+
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.RunnerBuilder;
+
+public class RunnerSpy extends Runner {
+ public static final Description DESCRIPTION = Description.TEST_MECHANISM;
+
+ private RunnerBuilder invokedRunnerBuilder;
+ private Class<?> invokedTestClass;
+
+ public RunnerSpy(Class<?> testClass) {
+ invokedTestClass = testClass;
+ }
+
+ public RunnerSpy(Class<?> testClass, RunnerBuilder runnerBuilder) {
+ invokedTestClass = testClass;
+ invokedRunnerBuilder = runnerBuilder;
+ }
+
+ @Override
+ public Description getDescription() {
+ return DESCRIPTION;
+ }
+
+ @Override
+ public void run(RunNotifier runNotifier) {
+ }
+
+ public RunnerBuilder getInvokedRunnerBuilder() {
+ return invokedRunnerBuilder;
+ }
+
+ public Class<?> getInvokedTestClass() {
+ return invokedTestClass;
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/AllNotificationTests.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/AllNotificationTests.java
new file mode 100644
index 0000000..1c991a9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/AllNotificationTests.java
@@ -0,0 +1,14 @@
+package org.junit.runner.notification;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ConcurrentRunNotifierTest.class,
+ RunNotifierTest.class,
+ SynchronizedRunListenerTest.class
+})
+public class AllNotificationTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/ConcurrentRunNotifierTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/ConcurrentRunNotifierTest.java
new file mode 100644
index 0000000..b7386e3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/ConcurrentRunNotifierTest.java
@@ -0,0 +1,180 @@
+package org.junit.runner.notification;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testing RunNotifier in concurrent access.
+ *
+ * @author Tibor Digana (tibor17)
+ * @version 4.12
+ * @since 4.12
+ */
+public final class ConcurrentRunNotifierTest {
+ private static final long TIMEOUT = 3;
+ private final RunNotifier fNotifier = new RunNotifier();
+
+ private static class ConcurrentRunListener extends RunListener {
+ final AtomicInteger fTestStarted = new AtomicInteger(0);
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ fTestStarted.incrementAndGet();
+ }
+ }
+
+ @Test
+ public void realUsage() throws Exception {
+ ConcurrentRunListener listener1 = new ConcurrentRunListener();
+ ConcurrentRunListener listener2 = new ConcurrentRunListener();
+ fNotifier.addListener(listener1);
+ fNotifier.addListener(listener2);
+
+ final int numParallelTests = 4;
+ ExecutorService pool = Executors.newFixedThreadPool(numParallelTests);
+ for (int i = 0; i < numParallelTests; ++i) {
+ pool.submit(new Runnable() {
+ public void run() {
+ fNotifier.fireTestStarted(null);
+ }
+ });
+ }
+ pool.shutdown();
+ assertTrue(pool.awaitTermination(TIMEOUT, TimeUnit.SECONDS));
+
+ fNotifier.removeListener(listener1);
+ fNotifier.removeListener(listener2);
+
+ assertThat(listener1.fTestStarted.get(), is(numParallelTests));
+ assertThat(listener2.fTestStarted.get(), is(numParallelTests));
+ }
+
+ private static class ExaminedListener extends RunListener {
+ final boolean throwFromTestStarted;
+ volatile boolean hasTestFailure = false;
+
+ ExaminedListener(boolean throwFromTestStarted) {
+ this.throwFromTestStarted = throwFromTestStarted;
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ if (throwFromTestStarted) {
+ throw new Exception();
+ }
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ hasTestFailure = true;
+ }
+ }
+
+ private abstract class AbstractConcurrentFailuresTest {
+
+ protected abstract void addListener(ExaminedListener listener);
+
+ public void test() throws Exception {
+ int totalListenersFailures = 0;
+
+ Random random = new Random(42);
+ ExaminedListener[] examinedListeners = new ExaminedListener[1000];
+ for (int i = 0; i < examinedListeners.length; ++i) {
+ boolean fail = random.nextDouble() >= 0.5d;
+ if (fail) {
+ ++totalListenersFailures;
+ }
+ examinedListeners[i] = new ExaminedListener(fail);
+ }
+
+ final AtomicBoolean condition = new AtomicBoolean(true);
+ final CyclicBarrier trigger = new CyclicBarrier(2);
+ final CountDownLatch latch = new CountDownLatch(10);
+
+ ExecutorService notificationsPool = Executors.newFixedThreadPool(4);
+ notificationsPool.submit(new Callable<Void>() {
+ public Void call() throws Exception {
+ trigger.await();
+ while (condition.get()) {
+ fNotifier.fireTestStarted(null);
+ latch.countDown();
+ }
+ fNotifier.fireTestStarted(null);
+ return null;
+ }
+ });
+
+ // Wait for callable to start
+ trigger.await(TIMEOUT, TimeUnit.SECONDS);
+
+ // Wait for callable to fire a few events
+ latch.await(TIMEOUT, TimeUnit.SECONDS);
+
+ for (ExaminedListener examinedListener : examinedListeners) {
+ addListener(examinedListener);
+ }
+
+ notificationsPool.shutdown();
+ condition.set(false);
+ assertTrue(notificationsPool.awaitTermination(TIMEOUT, TimeUnit.SECONDS));
+
+ if (totalListenersFailures != 0) {
+ // If no listener failures, then all the listeners do not report any failure.
+ int countTestFailures = examinedListeners.length - countReportedTestFailures(examinedListeners);
+ assertThat(totalListenersFailures, is(countTestFailures));
+ }
+ }
+ }
+
+ /**
+ * Verifies that listeners added while tests are run concurrently are
+ * notified about test failures.
+ */
+ @Test
+ public void reportConcurrentFailuresAfterAddListener() throws Exception {
+ new AbstractConcurrentFailuresTest() {
+ @Override
+ protected void addListener(ExaminedListener listener) {
+ fNotifier.addListener(listener);
+ }
+ }.test();
+ }
+
+ /**
+ * Verifies that listeners added with addFirstListener() while tests are run concurrently are
+ * notified about test failures.
+ */
+ @Test
+ public void reportConcurrentFailuresAfterAddFirstListener() throws Exception {
+ new AbstractConcurrentFailuresTest() {
+ @Override
+ protected void addListener(ExaminedListener listener) {
+ fNotifier.addFirstListener(listener);
+ }
+ }.test();
+ }
+
+ private static int countReportedTestFailures(ExaminedListener[] listeners) {
+ int count = 0;
+ for (ExaminedListener listener : listeners) {
+ if (listener.hasTestFailure) {
+ ++count;
+ }
+ }
+ return count;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/RunNotifierTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/RunNotifierTest.java
new file mode 100644
index 0000000..c3a4a88
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/RunNotifierTest.java
@@ -0,0 +1,131 @@
+package org.junit.runner.notification;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+
+public class RunNotifierTest {
+ private final RunNotifier fNotifier = new RunNotifier();
+
+ @Test
+ public void notifiesSecondListenerIfFirstThrowsException() {
+ FailureListener failureListener = new FailureListener();
+ fNotifier.addListener(new CorruptListener());
+ fNotifier.addListener(failureListener);
+ fNotifier.fireTestFailure(new Failure(null, null));
+ assertNotNull("The FailureListener registered no failure.",
+ failureListener.failure);
+ }
+
+ @Test
+ public void hasNoProblemsWithFailingListeners() { // see issues 209 and 395
+ fNotifier.addListener(new CorruptListener());
+ fNotifier.addListener(new FailureListener());
+ fNotifier.addListener(new CorruptListener());
+ fNotifier.fireTestRunFinished(new Result());
+ }
+
+ private static class CorruptListener extends RunListener {
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ throw new RuntimeException();
+ }
+ }
+
+ @Test
+ public void addAndRemoveWithNonThreadSafeListener() {
+ CountingListener listener = new CountingListener();
+ assertThat(listener.fTestStarted.get(), is(0));
+ fNotifier.addListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ fNotifier.removeListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ }
+
+ @Test
+ public void addFirstAndRemoveWithNonThreadSafeListener() {
+ CountingListener listener = new CountingListener();
+ assertThat(listener.fTestStarted.get(), is(0));
+ fNotifier.addFirstListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ fNotifier.removeListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ }
+
+ @Test
+ public void addAndRemoveWithThreadSafeListener() {
+ ThreadSafeListener listener = new ThreadSafeListener();
+ assertThat(listener.fTestStarted.get(), is(0));
+ fNotifier.addListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ fNotifier.removeListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ }
+
+ @Test
+ public void addFirstAndRemoveWithThreadSafeListener() {
+ ThreadSafeListener listener = new ThreadSafeListener();
+ assertThat(listener.fTestStarted.get(), is(0));
+ fNotifier.addFirstListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ fNotifier.removeListener(listener);
+ fNotifier.fireTestStarted(null);
+ assertThat(listener.fTestStarted.get(), is(1));
+ }
+
+ @Test
+ public void wrapIfNotThreadSafeShouldNotWrapThreadSafeListeners() {
+ ThreadSafeListener listener = new ThreadSafeListener();
+ assertSame(listener, new RunNotifier().wrapIfNotThreadSafe(listener));
+ }
+
+ @Test
+ public void wrapIfNotThreadSafeShouldWrapNonThreadSafeListeners() {
+ CountingListener listener = new CountingListener();
+ RunListener wrappedListener = new RunNotifier().wrapIfNotThreadSafe(listener);
+ assertThat(wrappedListener, instanceOf(SynchronizedRunListener.class));
+ }
+
+ private static class FailureListener extends RunListener {
+ private Failure failure;
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ this.failure = failure;
+ }
+ }
+
+ private static class CountingListener extends RunListener {
+ final AtomicInteger fTestStarted = new AtomicInteger(0);
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ fTestStarted.incrementAndGet();
+ }
+ }
+
+ @RunListener.ThreadSafe
+ private static class ThreadSafeListener extends CountingListener {
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/SynchronizedRunListenerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/SynchronizedRunListenerTest.java
new file mode 100644
index 0000000..6bd39b7
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runner/notification/SynchronizedRunListenerTest.java
@@ -0,0 +1,156 @@
+package org.junit.runner.notification;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link SynchronizedRunListener}.
+ *
+ * @author kcooney (Kevin Cooney)
+ */
+public class SynchronizedRunListenerTest {
+
+ private static class MethodSignature {
+ private final Method fMethod;
+ private final String fName;
+ private final List<Class<?>> fParameterTypes;
+
+ public MethodSignature(Method method) {
+ fMethod = method;
+ fName = method.getName();
+ fParameterTypes = Arrays.asList(method.getParameterTypes());
+ }
+
+ @Override
+ public String toString() {
+ return fMethod.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return fName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof MethodSignature)) {
+ return false;
+ }
+ MethodSignature that = (MethodSignature) obj;
+ return fName.equals(that.fName) && fParameterTypes.equals(that.fParameterTypes);
+ }
+ }
+
+ private Set<MethodSignature> getAllDeclaredMethods(Class<?> type) {
+ Set<MethodSignature> methods = new HashSet<MethodSignature>();
+ for (Method method : type.getDeclaredMethods()) {
+ methods.add(new MethodSignature(method));
+ }
+ return methods;
+ }
+
+ @Test
+ public void overridesAllMethodsInRunListener() {
+ Set<MethodSignature> runListenerMethods = getAllDeclaredMethods(RunListener.class);
+ Set<MethodSignature> synchronizedRunListenerMethods = getAllDeclaredMethods(
+ SynchronizedRunListener.class);
+
+ assertTrue(synchronizedRunListenerMethods.containsAll(runListenerMethods));
+ }
+
+ private static class NamedListener extends RunListener {
+ private final String fName;
+
+ public NamedListener(String name) {
+ fName = name;
+ }
+
+ @Override
+ public String toString() {
+ return "NamedListener";
+ }
+
+ @Override
+ public int hashCode() {
+ return fName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof NamedListener)) {
+ return false;
+ }
+ NamedListener that = (NamedListener) obj;
+ return this.fName.equals(that.fName);
+ }
+ }
+
+ @Test
+ public void namedListenerCorrectlyImplementsEqualsAndHashCode() {
+ NamedListener listener1 = new NamedListener("blue");
+ NamedListener listener2 = new NamedListener("blue");
+ NamedListener listener3 = new NamedListener("red");
+
+ assertTrue(listener1.equals(listener1));
+ assertTrue(listener2.equals(listener2));
+ assertTrue(listener3.equals(listener3));
+
+ assertFalse(listener1.equals(null));
+ assertFalse(listener1.equals(new Object()));
+
+ assertTrue(listener1.equals(listener2));
+ assertTrue(listener2.equals(listener1));
+ assertFalse(listener1.equals(listener3));
+ assertFalse(listener3.equals(listener1));
+
+ assertEquals(listener1.hashCode(), listener2.hashCode());
+ assertNotEquals(listener1.hashCode(), listener3.hashCode());
+ }
+
+ @Test
+ public void toStringDelegates() {
+ NamedListener listener = new NamedListener("blue");
+
+ assertEquals("NamedListener", listener.toString());
+ assertEquals("NamedListener (with synchronization wrapper)", wrap(listener).toString());
+ }
+
+ @Test
+ public void equalsDelegates() {
+ NamedListener listener1 = new NamedListener("blue");
+ NamedListener listener2 = new NamedListener("blue");
+ NamedListener listener3 = new NamedListener("red");
+
+ assertEquals(wrap(listener1), wrap(listener1));
+ assertEquals(wrap(listener1), wrap(listener2));
+ assertNotEquals(wrap(listener1), wrap(listener3));
+ assertNotEquals(wrap(listener1), listener1);
+ assertNotEquals(listener1, wrap(listener1));
+ }
+
+ @Test
+ public void hashCodeDelegates() {
+ NamedListener listener = new NamedListener("blue");
+ assertEquals(listener.hashCode(), wrap(listener).hashCode());
+ }
+
+ private SynchronizedRunListener wrap(RunListener listener) {
+ return new SynchronizedRunListener(listener, this);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/AllRunnersTests.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/AllRunnersTests.java
new file mode 100644
index 0000000..5464fb2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/AllRunnersTests.java
@@ -0,0 +1,16 @@
+package org.junit.runners;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.runners.model.AllModelTests;
+import org.junit.runners.parameterized.AllParameterizedTests;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllModelTests.class,
+ AllParameterizedTests.class,
+ RuleContainerTest.class,
+ CustomBlockJUnit4ClassRunnerTest.class
+})
+public class AllRunnersTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/CustomBlockJUnit4ClassRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/CustomBlockJUnit4ClassRunnerTest.java
new file mode 100644
index 0000000..d9f072b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/CustomBlockJUnit4ClassRunnerTest.java
@@ -0,0 +1,90 @@
+package org.junit.runners;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * Tests that verify proper behavior for custom runners that extend
+ * {@link BlockJUnit4ClassRunner}.
+ *
+ * @author Sam Brannen
+ * @since 4.13
+ */
+public class CustomBlockJUnit4ClassRunnerTest {
+
+ @Test
+ public void exceptionsFromMethodBlockMustNotResultInUnrootedTests() throws Exception {
+ TrackingRunListener listener = new TrackingRunListener();
+ RunNotifier notifier = new RunNotifier();
+ notifier.addListener(listener);
+
+ new CustomBlockJUnit4ClassRunner(CustomBlockJUnit4ClassRunnerTestCase.class).run(notifier);
+ assertEquals("tests started.", 2, listener.testStartedCount.get());
+ assertEquals("tests failed.", 1, listener.testFailureCount.get());
+ assertEquals("tests finished.", 2, listener.testFinishedCount.get());
+ }
+
+
+ public static class CustomBlockJUnit4ClassRunnerTestCase {
+ @Test public void shouldPass() { /* no-op */ }
+ @Test public void throwException() { /* no-op */ }
+ }
+
+ /**
+ * Custom extension of {@link BlockJUnit4ClassRunner} that always throws
+ * an exception from the {@code methodBlock()} if a test method is named
+ * exactly {@code "throwException"}.
+ */
+ private static class CustomBlockJUnit4ClassRunner extends BlockJUnit4ClassRunner {
+
+ CustomBlockJUnit4ClassRunner(Class<?> testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ @Override
+ protected Statement methodBlock(FrameworkMethod method) {
+ if ("throwException".equals(method.getName())) {
+ throw new RuntimeException("throwException() test method invoked");
+ }
+ return super.methodBlock(method);
+ }
+ }
+
+ /**
+ * Simple {@link RunListener} that tracks the number of times that
+ * certain callbacks are invoked.
+ */
+ private static class TrackingRunListener extends RunListener {
+
+ final AtomicInteger testStartedCount = new AtomicInteger();
+ final AtomicInteger testFailureCount = new AtomicInteger();
+ final AtomicInteger testFinishedCount = new AtomicInteger();
+
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ testStartedCount.incrementAndGet();
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ testFailureCount.incrementAndGet();
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ testFinishedCount.incrementAndGet();
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/RuleContainerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/RuleContainerTest.java
new file mode 100644
index 0000000..8c6649c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/RuleContainerTest.java
@@ -0,0 +1,68 @@
+package org.junit.runners;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+public class RuleContainerTest {
+ private final RuleContainer container = new RuleContainer();
+
+ @Test
+ public void methodRulesOnly() {
+ container.add(MRule.M1);
+ container.add(MRule.M2);
+ assertEquals("[M1, M2]", container.getSortedRules().toString());
+ container.setOrder(MRule.M2, 1);
+ assertEquals("[M2, M1]", container.getSortedRules().toString());
+ }
+
+ @Test
+ public void testRuleAroundMethodRule() {
+ container.add(MRule.M1);
+ container.add(Rule.A);
+ assertEquals("[M1, A]", container.getSortedRules().toString());
+ }
+
+ @Test
+ public void ordering1() {
+ container.add(MRule.M1);
+ container.add(Rule.A);
+ container.setOrder(Rule.A, 1);
+ assertEquals("[A, M1]", container.getSortedRules().toString());
+ }
+
+ @Test
+ public void ordering2() {
+ container.add(Rule.A);
+ container.add(Rule.B);
+ container.add(Rule.C);
+ assertEquals("[A, B, C]", container.getSortedRules().toString());
+ container.setOrder(Rule.B, 1);
+ container.setOrder(Rule.C, 2);
+ assertEquals("[C, B, A]", container.getSortedRules().toString());
+ }
+
+ private enum Rule implements TestRule {
+ A,
+ B,
+ C;
+
+ public Statement apply(Statement base, Description description) {
+ return base;
+ }
+ }
+
+ private enum MRule implements MethodRule {
+ M1,
+ M2;
+
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return base;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/AllModelTests.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/AllModelTests.java
new file mode 100644
index 0000000..b0c50d5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/AllModelTests.java
@@ -0,0 +1,15 @@
+package org.junit.runners.model;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ FrameworkFieldTest.class,
+ FrameworkMethodTest.class,
+ InvalidTestClassErrorTest.class,
+ TestClassTest.class
+})
+public class AllModelTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkFieldTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkFieldTest.java
new file mode 100644
index 0000000..55ba75e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkFieldTest.java
@@ -0,0 +1,58 @@
+package org.junit.runners.model;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.rules.ExpectedException.none;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class FrameworkFieldTest {
+ @Rule
+ public final ExpectedException thrown = none();
+
+ @Test
+ public void cannotBeCreatedWithoutUnderlyingField() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("FrameworkField cannot be created without an underlying field.");
+ new FrameworkField(null);
+ }
+
+ @Test
+ public void hasToStringWhichPrintsFieldName() throws Exception {
+ Field field = ClassWithDummyField.class.getField("dummyField");
+ FrameworkField frameworkField = new FrameworkField(field);
+ assertTrue(frameworkField.toString().contains("dummyField"));
+ }
+
+ @Test
+ public void presentAnnotationIsAvailable() throws Exception {
+ Field field = ClassWithDummyField.class.getField("annotatedField");
+ FrameworkField frameworkField = new FrameworkField(field);
+ Annotation annotation = frameworkField.getAnnotation(Rule.class);
+ assertTrue(Rule.class.isAssignableFrom(annotation.getClass()));
+ }
+
+ @Test
+ public void missingAnnotationIsNotAvailable() throws Exception {
+ Field field = ClassWithDummyField.class.getField("annotatedField");
+ FrameworkField frameworkField = new FrameworkField(field);
+ Annotation annotation = frameworkField.getAnnotation(ClassRule.class);
+ assertThat(annotation, is(nullValue()));
+ }
+
+ private static class ClassWithDummyField {
+ @SuppressWarnings("unused")
+ public final int dummyField = 0;
+
+ @Rule
+ public final int annotatedField = 0;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkMethodTest.java
new file mode 100644
index 0000000..b97df82
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/FrameworkMethodTest.java
@@ -0,0 +1,60 @@
+package org.junit.runners.model;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.rules.ExpectedException.none;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class FrameworkMethodTest {
+ @Rule
+ public final ExpectedException thrown = none();
+
+ @Test
+ public void cannotBeCreatedWithoutUnderlyingField() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("FrameworkMethod cannot be created without an underlying method.");
+ new FrameworkMethod(null);
+ }
+
+ @Test
+ public void hasToStringWhichPrintsMethodName() throws Exception {
+ Method method = ClassWithDummyMethod.class.getMethod("dummyMethod");
+ FrameworkMethod frameworkMethod = new FrameworkMethod(method);
+ assertTrue(frameworkMethod.toString().contains("dummyMethod"));
+ }
+
+ @Test
+ public void presentAnnotationIsAvailable() throws Exception {
+ Method method = ClassWithDummyMethod.class.getMethod("annotatedDummyMethod");
+ FrameworkMethod frameworkMethod = new FrameworkMethod(method);
+ Annotation annotation = frameworkMethod.getAnnotation(Rule.class);
+ assertTrue(Rule.class.isAssignableFrom(annotation.getClass()));
+ }
+
+ @Test
+ public void missingAnnotationIsNotAvailable() throws Exception {
+ Method method = ClassWithDummyMethod.class.getMethod("annotatedDummyMethod");
+ FrameworkMethod frameworkMethod = new FrameworkMethod(method);
+ Annotation annotation = frameworkMethod.getAnnotation(ClassRule.class);
+ assertThat(annotation, is(nullValue()));
+ }
+
+ private static class ClassWithDummyMethod {
+ @SuppressWarnings("unused")
+ public void dummyMethod() {
+ }
+
+ @Rule
+ public void annotatedDummyMethod() {
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/InvalidTestClassErrorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/InvalidTestClassErrorTest.java
new file mode 100644
index 0000000..7d92dd4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/InvalidTestClassErrorTest.java
@@ -0,0 +1,23 @@
+package org.junit.runners.model;
+
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class InvalidTestClassErrorTest {
+
+ @Test
+ public void invalidTestClassErrorShouldListAllValidationErrorsInItsMessage() {
+ InvalidTestClassError sut = new InvalidTestClassError(SampleTestClass.class,
+ asList(new Throwable("validation error 1"), new Throwable("validation error 2")));
+
+ assertThat(sut.getMessage(), equalTo("Invalid test class '" + SampleTestClass.class.getName() + "':" +
+ "\n 1. validation error 1" +
+ "\n 2. validation error 2"));
+ }
+
+ private static class SampleTestClass {
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/RunnerBuilderStub.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/RunnerBuilderStub.java
new file mode 100644
index 0000000..2e11137
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/RunnerBuilderStub.java
@@ -0,0 +1,11 @@
+package org.junit.runners.model;
+
+import org.junit.runner.Runner;
+import org.junit.runner.RunnerSpy;
+
+public class RunnerBuilderStub extends RunnerBuilder {
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Throwable {
+ return new RunnerSpy(testClass, this);
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/model/TestClassTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/TestClassTest.java
new file mode 100644
index 0000000..6b5cb28
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/model/TestClassTest.java
@@ -0,0 +1,263 @@
+package org.junit.runners.model;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+public class TestClassTest {
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ public static class TwoConstructors {
+ public TwoConstructors() {
+ }
+
+ public TwoConstructors(int x) {
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void complainIfMultipleConstructors() {
+ new TestClass(TwoConstructors.class);
+ }
+
+ public static class SuperclassWithField {
+ @Rule
+ public TestRule x;
+ }
+
+ public static class SubclassWithField extends SuperclassWithField {
+ @Rule
+ public TestRule x;
+ }
+
+ @Test
+ public void fieldsOnSubclassesShadowSuperclasses() {
+ assertThat(new TestClass(SubclassWithField.class).getAnnotatedFields(
+ Rule.class).size(), is(1));
+ }
+
+ public static class OuterClass {
+ public class NonStaticInnerClass {
+ }
+ }
+
+ @Test
+ public void identifyNonStaticInnerClass() {
+ assertThat(
+ new TestClass(OuterClass.NonStaticInnerClass.class)
+ .isANonStaticInnerClass(),
+ is(true));
+ }
+
+ public static class OuterClass2 {
+ public static class StaticInnerClass {
+ }
+ }
+
+ @Test
+ public void dontMarkStaticInnerClassAsNonStatic() {
+ assertThat(
+ new TestClass(OuterClass2.StaticInnerClass.class)
+ .isANonStaticInnerClass(),
+ is(false));
+ }
+
+ public static class SimpleClass {
+ }
+
+ @Test
+ public void dontMarkNonInnerClassAsInnerClass() {
+ assertThat(new TestClass(SimpleClass.class).isANonStaticInnerClass(),
+ is(false));
+ }
+
+ public static class FieldAnnotated {
+ @Rule
+ public String fieldC= "andromeda";
+
+ @Rule
+ public boolean fieldA;
+
+ @Rule
+ public boolean fieldB;
+ }
+
+ @Test
+ public void providesAnnotatedFieldsSortedByName() {
+ TestClass tc= new TestClass(FieldAnnotated.class);
+ List<FrameworkField> annotatedFields= tc.getAnnotatedFields();
+ assertThat("Wrong number of annotated fields.", annotatedFields.size(), is(3));
+ assertThat("First annotated field is wrong.", annotatedFields
+ .iterator().next().getName(), is("fieldA"));
+ }
+
+ @Test
+ public void annotatedFieldValues() {
+ TestClass tc = new TestClass(FieldAnnotated.class);
+ List<String> values = tc.getAnnotatedFieldValues(new FieldAnnotated(), Rule.class, String.class);
+ assertThat(values, hasItem("andromeda"));
+ assertThat(values.size(), is(1));
+ }
+
+ public static class MethodsAnnotated {
+ @Ignore
+ @Test
+ public int methodC() {
+ return 0;
+ }
+
+ @Ignore
+ @Test
+ public String methodA() {
+ return "jupiter";
+ }
+
+ @Ignore
+ @Test
+ public int methodB() {
+ return 0;
+ }
+
+ public int methodWithoutAnnotation() {
+ return 0;
+ }
+ }
+
+ @Test
+ public void providesAnnotatedMethodsSortedByName() {
+ TestClass tc = new TestClass(MethodsAnnotated.class);
+ List<FrameworkMethod> annotatedMethods = tc.getAnnotatedMethods();
+ List<String> methodNames = extractNames(annotatedMethods);
+ assertThat(methodNames.indexOf("methodA"),
+ lessThan(methodNames.indexOf("methodB")));
+ }
+
+ @Test
+ public void getAnnotatedMethodsDoesNotReturnMethodWithoutAnnotation() {
+ TestClass tc = new TestClass(MethodsAnnotated.class);
+ List<FrameworkMethod> annotatedMethods = tc.getAnnotatedMethods();
+ List<String> methodNames = extractNames(annotatedMethods);
+ assertThat(methodNames, not(hasItem("methodWithoutAnnotation")));
+ }
+
+ private List<String> extractNames(List<FrameworkMethod> methods) {
+ List<String> names = new ArrayList<String>();
+ for (FrameworkMethod method: methods) {
+ names.add(method.getName());
+ }
+ return names;
+ }
+
+ @Test
+ public void annotatedMethodValues() {
+ TestClass tc = new TestClass(MethodsAnnotated.class);
+ List<String> values = tc.getAnnotatedMethodValues(
+ new MethodsAnnotated(), Ignore.class, String.class);
+ assertThat(values, hasItem("jupiter"));
+ assertThat(values.size(), is(1));
+ }
+
+ @Test
+ public void isEqualToTestClassThatWrapsSameJavaClass() {
+ TestClass testClass = new TestClass(DummyClass.class);
+ TestClass testClassThatWrapsSameJavaClass = new TestClass(
+ DummyClass.class);
+ assertTrue(testClass.equals(testClassThatWrapsSameJavaClass));
+ }
+
+ @Test
+ public void isEqualToTestClassThatWrapsNoJavaClassToo() {
+ TestClass testClass = new TestClass(null);
+ TestClass testClassThatWrapsNoJavaClassToo = new TestClass(null);
+ assertTrue(testClass.equals(testClassThatWrapsNoJavaClassToo));
+ }
+
+ @Test
+ public void isNotEqualToTestClassThatWrapsADifferentJavaClass() {
+ TestClass testClass = new TestClass(DummyClass.class);
+ TestClass testClassThatWrapsADifferentJavaClass = new TestClass(
+ AnotherDummyClass.class);
+ assertFalse(testClass.equals(testClassThatWrapsADifferentJavaClass));
+ }
+
+ @Test
+ public void isNotEqualToNull() {
+ TestClass testClass = new TestClass(DummyClass.class);
+ assertFalse(testClass.equals(null));
+ }
+
+ private static class DummyClass {
+ }
+
+ private static class AnotherDummyClass {
+ }
+
+ @Test
+ public void hasSameHashCodeAsTestClassThatWrapsSameJavaClass() {
+ TestClass testClass = new TestClass(DummyClass.class);
+ TestClass testClassThatWrapsSameJavaClass = new TestClass(
+ DummyClass.class);
+ assertEquals(testClass.hashCode(),
+ testClassThatWrapsSameJavaClass.hashCode());
+ }
+
+ @Test
+ public void hasHashCodeWithoutJavaClass() {
+ TestClass testClass = new TestClass(null);
+ testClass.hashCode();
+ // everything is fine if no exception is thrown.
+ }
+
+ public static class PublicClass {
+
+ }
+
+ @Test
+ public void identifiesPublicModifier() {
+ TestClass tc = new TestClass(PublicClass.class);
+ assertEquals("Wrong flag 'public',", true, tc.isPublic());
+ }
+
+ static class NonPublicClass {
+
+ }
+
+ @Test
+ public void identifiesNonPublicModifier() {
+ TestClass tc = new TestClass(NonPublicClass.class);
+ assertEquals("Wrong flag 'public',", false, tc.isPublic());
+ }
+
+ @Ignore
+ static class AnnotatedClass {
+ }
+
+ @Test
+ public void presentAnnotationIsAvailable() {
+ TestClass tc = new TestClass(AnnotatedClass.class);
+ Annotation annotation = tc.getAnnotation(Ignore.class);
+ assertTrue(Ignore.class.isAssignableFrom(annotation.getClass()));
+ }
+
+ @Test
+ public void missingAnnotationIsNotAvailable() {
+ TestClass tc = new TestClass(AnnotatedClass.class);
+ Annotation annotation = tc.getAnnotation(RunWith.class);
+ assertThat(annotation, is(nullValue()));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/AllParameterizedTests.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/AllParameterizedTests.java
new file mode 100644
index 0000000..9a0f261
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/AllParameterizedTests.java
@@ -0,0 +1,14 @@
+package org.junit.runners.parameterized;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ BlockJUnit4ClassRunnerWithParametersTest.class,
+ ParameterizedNamesTest.class,
+ TestWithParametersTest.class
+})
+public class AllParameterizedTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersTest.java
new file mode 100644
index 0000000..0896c1f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParametersTest.java
@@ -0,0 +1,80 @@
+package org.junit.runners.parameterized;
+
+import static java.util.Collections.emptyList;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.rules.ExpectedException.none;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.model.TestClass;
+
+public class BlockJUnit4ClassRunnerWithParametersTest {
+ private static final List<Object> NO_PARAMETERS = emptyList();
+
+ @Rule
+ public final ExpectedException thrown = none();
+
+ @RunWith(Parameterized.class)
+ @DummyAnnotation
+ public static class ClassWithParameterizedAnnotation {
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Test
+ public void hasAllAnnotationsExceptRunWith() throws Exception {
+ TestWithParameters testWithParameters = new TestWithParameters(
+ "dummy name", new TestClass(
+ ClassWithParameterizedAnnotation.class), NO_PARAMETERS);
+ BlockJUnit4ClassRunnerWithParameters runner = new BlockJUnit4ClassRunnerWithParameters(
+ testWithParameters);
+ Annotation[] annotations = runner.getRunnerAnnotations();
+ assertEquals(1, annotations.length);
+ assertEquals(annotations[0].annotationType(), DummyAnnotation.class);
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ private static @interface DummyAnnotation {
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ClassWithPrivateParameter {
+ @Parameterized.Parameter
+ private String parameter;
+
+ @Test
+ public void dummyTest() {
+ }
+ }
+
+ @Test
+ public void providesHelpfulMessageIfParameterFieldCannotBeSet()
+ throws Exception {
+ TestWithParameters testWithParameters = new TestWithParameters(
+ "dummy name",
+ new TestClass(ClassWithPrivateParameter.class),
+ Collections.<Object>singletonList("dummy parameter"));
+ BlockJUnit4ClassRunnerWithParameters runner = new BlockJUnit4ClassRunnerWithParameters(
+ testWithParameters);
+
+ thrown.expect(IllegalAccessException.class);
+ thrown.expectCause(instanceOf(IllegalAccessException.class));
+ thrown.expectMessage("Cannot set parameter 'parameter'. Ensure that the field 'parameter' is public.");
+
+ runner.createTest();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/ParameterizedNamesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/ParameterizedNamesTest.java
new file mode 100644
index 0000000..e04fb76
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/ParameterizedNamesTest.java
@@ -0,0 +1,51 @@
+package org.junit.runners.parameterized;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Dmitry Baev charlie@yandex-team.ru
+ * Date: 03.05.14
+ */
+public class ParameterizedNamesTest {
+ @RunWith(Parameterized.class)
+ public static class ParameterizedWithSpecialCharsInName {
+
+ public ParameterizedWithSpecialCharsInName(String s) {
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[]{"\n"},
+ new Object[]{"\r\n"},
+ new Object[]{"\r"},
+ new Object[]{"\u0085"},
+ new Object[]{"\u2028"},
+ new Object[]{"\u2029"}
+ );
+ }
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void parameterizedTestsWithSpecialCharsInName() {
+ Request request = Request.aClass(ParameterizedWithSpecialCharsInName.class);
+ for (Description parent : request.getRunner().getDescription().getChildren()) {
+ for (Description description : parent.getChildren()) {
+ assertEquals("test" + parent.getDisplayName(), description.getMethodName());
+ }
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/TestWithParametersTest.java b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/TestWithParametersTest.java
new file mode 100644
index 0000000..b8156e9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/runners/parameterized/TestWithParametersTest.java
@@ -0,0 +1,137 @@
+package org.junit.runners.parameterized;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.rules.ExpectedException.none;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runners.model.TestClass;
+
+public class TestWithParametersTest {
+ private static final String DUMMY_NAME = "dummy name";
+
+ private static final TestClass DUMMY_TEST_CLASS = new TestClass(
+ DummyClass.class);
+
+ private static final List<Object> DUMMY_PARAMETERS = Arrays
+ .<Object> asList("a", "b");
+
+ @Rule
+ public final ExpectedException thrown = none();
+
+ @Test
+ public void cannotBeCreatedWithoutAName() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The name is missing.");
+ new TestWithParameters(null, DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ }
+
+ @Test
+ public void cannotBeCreatedWithoutTestClass() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The test class is missing.");
+ new TestWithParameters(DUMMY_NAME, null, DUMMY_PARAMETERS);
+ }
+
+ @Test
+ public void cannotBeCreatedWithoutParameters() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The parameters are missing.");
+ new TestWithParameters(DUMMY_NAME, DUMMY_TEST_CLASS,
+ (List<Object>) null);
+ }
+
+ @Test
+ public void doesNotAllowToModifyProvidedParameters() {
+ TestWithParameters test = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ thrown.expect(UnsupportedOperationException.class);
+ test.getParameters().set(0, "another parameter");
+ }
+
+ @Test
+ public void doesNotConsiderParametersWhichChangedAfterTestInstantiation() {
+ List<Object> parameters = Arrays.<Object> asList("dummy parameter");
+ TestWithParameters test = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, parameters);
+ parameters.set(0, "another parameter");
+ assertEquals(asList("dummy parameter"), test.getParameters());
+ }
+
+ @Test
+ public void isEqualToTestWithSameNameAndTestClassAndParameters() {
+ TestWithParameters firstTest = new TestWithParameters(DUMMY_NAME,
+ new TestClass(DummyClass.class), Arrays.<Object> asList("a",
+ "b"));
+ TestWithParameters secondTest = new TestWithParameters(DUMMY_NAME,
+ new TestClass(DummyClass.class), Arrays.<Object> asList("a",
+ "b"));
+ assertEquals(firstTest, secondTest);
+ }
+
+ @Test
+ public void isNotEqualToTestWithDifferentName() {
+ TestWithParameters firstTest = new TestWithParameters("name",
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ TestWithParameters secondTest = new TestWithParameters("another name",
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ assertNotEquals(firstTest, secondTest);
+ }
+
+ @Test
+ public void isNotEqualToTestWithDifferentTestClass() {
+ TestWithParameters firstTest = new TestWithParameters(DUMMY_NAME,
+ new TestClass(DummyClass.class), DUMMY_PARAMETERS);
+ TestWithParameters secondTest = new TestWithParameters(DUMMY_NAME,
+ new TestClass(AnotherDummyClass.class), DUMMY_PARAMETERS);
+ assertNotEquals(firstTest, secondTest);
+ }
+
+ @Test
+ public void isNotEqualToTestWithDifferentParameters() {
+ TestWithParameters firstTest = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, Arrays.<Object> asList("a"));
+ TestWithParameters secondTest = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, Arrays.<Object> asList("b"));
+ assertNotEquals(firstTest, secondTest);
+ }
+
+ @Test
+ public void isNotEqualToObjectWithDifferentClass() {
+ TestWithParameters test = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ assertNotEquals(test, new Integer(3));
+ }
+
+ @Test
+ public void hasSameHashCodeAsEqualTest() {
+ TestWithParameters firstTest = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ TestWithParameters secondTest = new TestWithParameters(DUMMY_NAME,
+ DUMMY_TEST_CLASS, DUMMY_PARAMETERS);
+ assertEquals(firstTest.hashCode(), secondTest.hashCode());
+ }
+
+ @Test
+ public void hasMeaningfulToString() {
+ TestWithParameters test = new TestWithParameters("name", new TestClass(
+ DummyClass.class), Arrays.<Object> asList("first parameter",
+ "second parameter"));
+ assertEquals(
+ "Wrong toString().",
+ "org.junit.runners.parameterized.TestWithParametersTest$DummyClass 'name' with parameters [first parameter, second parameter]",
+ test.toString());
+ }
+
+ private static class DummyClass {
+ }
+
+ private static class AnotherDummyClass {
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/AllSamplesTests.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/AllSamplesTests.java
new file mode 100644
index 0000000..cbd5fce
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/AllSamplesTests.java
@@ -0,0 +1,14 @@
+package org.junit.samples;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.samples.money.MoneyTest;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ListTest.class,
+ MoneyTest.class
+})
+public class AllSamplesTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/ListTest.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/ListTest.java
new file mode 100644
index 0000000..02ade82
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/ListTest.java
@@ -0,0 +1,91 @@
+package org.junit.samples;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.JUnit4TestAdapter;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * A sample test case, testing {@link java.util.ArrayList}.
+ */
+public class ListTest {
+ protected List<Integer> fEmpty;
+ protected List<Integer> fFull;
+ protected static List<Integer> fgHeavy;
+
+ public static void main(String... args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ @BeforeClass
+ public static void setUpOnce() {
+ fgHeavy = new ArrayList<Integer>();
+ for (int i = 0; i < 1000; i++) {
+ fgHeavy.add(i);
+ }
+ }
+
+ @Before
+ public void setUp() {
+ fEmpty = new ArrayList<Integer>();
+ fFull = new ArrayList<Integer>();
+ fFull.add(1);
+ fFull.add(2);
+ fFull.add(3);
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(ListTest.class);
+ }
+
+ @Ignore("not today")
+ @Test
+ public void capacity() {
+ int size = fFull.size();
+ for (int i = 0; i < 100; i++) {
+ fFull.add(i);
+ }
+ assertTrue(fFull.size() == 100 + size);
+ }
+
+ @Test
+ public void testCopy() {
+ List<Integer> copy = new ArrayList<Integer>(fFull.size());
+ copy.addAll(fFull);
+ assertTrue(copy.size() == fFull.size());
+ assertTrue(copy.contains(1));
+ }
+
+ @Test
+ public void contains() {
+ assertTrue(fFull.contains(1));
+ assertTrue(!fEmpty.contains(1));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void elementAt() {
+ int i = fFull.get(0);
+ assertTrue(i == 1);
+ fFull.get(fFull.size()); // Should throw IndexOutOfBoundsException
+ }
+
+ @Test
+ public void removeAll() {
+ fFull.removeAll(fFull);
+ fEmpty.removeAll(fEmpty);
+ assertTrue(fFull.isEmpty());
+ assertTrue(fEmpty.isEmpty());
+ }
+
+ @Test
+ public void removeElement() {
+ fFull.remove(new Integer(3));
+ assertTrue(!fFull.contains(3));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/SimpleTest.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/SimpleTest.java
new file mode 100644
index 0000000..02bae09
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/SimpleTest.java
@@ -0,0 +1,47 @@
+package org.junit.samples;
+
+import static org.junit.Assert.assertEquals;
+
+import junit.framework.JUnit4TestAdapter;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Some simple tests.
+ *
+ * <p>This test is expected to fail.
+ */
+public class SimpleTest {
+ protected int fValue1;
+ protected int fValue2;
+
+ @Before
+ public void setUp() {
+ fValue1 = 2;
+ fValue2 = 3;
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(SimpleTest.class);
+ }
+
+ public int unused;
+
+ @Test
+ public void divideByZero() {
+ int zero = 0;
+ int result = 8 / zero;
+ unused = result; // avoid warning for not using result
+ }
+
+ @Test
+ public void testEquals() {
+ assertEquals(12, 12);
+ assertEquals(12L, 12L);
+ assertEquals(new Long(12), new Long(12));
+
+ assertEquals("Size", 12, 13);
+ assertEquals("Capacity", 12.0, 11.99, 0.0);
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/money/MoneyTest.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/money/MoneyTest.java
new file mode 100644
index 0000000..617bcec
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/money/MoneyTest.java
@@ -0,0 +1,205 @@
+package org.junit.samples.money;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.samples.money.IMoney;
+import junit.samples.money.Money;
+import junit.samples.money.MoneyBag;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MoneyTest {
+ private Money f12CHF;
+ private Money f14CHF;
+ private Money f7USD;
+ private Money f21USD;
+
+ private IMoney fMB1;
+ private IMoney fMB2;
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(MoneyTest.class);
+ }
+
+ @Before
+ public void setUp() {
+ f12CHF = new Money(12, "CHF");
+ f14CHF = new Money(14, "CHF");
+ f7USD = new Money(7, "USD");
+ f21USD = new Money(21, "USD");
+
+ fMB1 = MoneyBag.create(f12CHF, f7USD);
+ fMB2 = MoneyBag.create(f14CHF, f21USD);
+ }
+
+ @Test
+ public void testBagMultiply() {
+ // {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]}
+ IMoney expected = MoneyBag.create(new Money(24, "CHF"), new Money(14, "USD"));
+ assertEquals(expected, fMB1.multiply(2));
+ assertEquals(fMB1, fMB1.multiply(1));
+ assertTrue(fMB1.multiply(0).isZero());
+ }
+
+ @Test
+ public void testBagNegate() {
+ // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]}
+ IMoney expected = MoneyBag.create(new Money(-12, "CHF"), new Money(-7, "USD"));
+ assertEquals(expected, fMB1.negate());
+ }
+
+ @Test
+ public void testBagSimpleAdd() {
+ // {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD"));
+ assertEquals(expected, fMB1.add(f14CHF));
+ }
+
+ @Test
+ public void testBagSubtract() {
+ // {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]}
+ IMoney expected = MoneyBag.create(new Money(-2, "CHF"), new Money(-14, "USD"));
+ assertEquals(expected, fMB1.subtract(fMB2));
+ }
+
+ @Test
+ public void testBagSumAdd() {
+ // {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(28, "USD"));
+ assertEquals(expected, fMB1.add(fMB2));
+ }
+
+ @Test
+ public void testIsZero() {
+ assertTrue(fMB1.subtract(fMB1).isZero());
+ assertTrue(MoneyBag.create(new Money(0, "CHF"), new Money(0, "USD")).isZero());
+ }
+
+ @Test
+ public void testMixedSimpleAdd() {
+ // [12 CHF] + [7 USD] == {[12 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(f12CHF, f7USD);
+ assertEquals(expected, f12CHF.add(f7USD));
+ }
+
+ @Test
+ public void testBagNotEquals() {
+ IMoney bag = MoneyBag.create(f12CHF, f7USD);
+ assertFalse(bag.equals(new Money(12, "DEM").add(f7USD)));
+ }
+
+ @Test
+ public void testMoneyBagEquals() {
+ assertTrue(!fMB1.equals(null));
+
+ assertEquals(fMB1, fMB1);
+ IMoney equal = MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD"));
+ assertTrue(fMB1.equals(equal));
+ assertTrue(!fMB1.equals(f12CHF));
+ assertTrue(!f12CHF.equals(fMB1));
+ assertTrue(!fMB1.equals(fMB2));
+ }
+
+ @Test
+ public void testMoneyBagHash() {
+ IMoney equal = MoneyBag.create(new Money(12, "CHF"), new Money(7, "USD"));
+ assertEquals(fMB1.hashCode(), equal.hashCode());
+ }
+
+ @Test
+ public void testMoneyEquals() {
+ assertTrue(!f12CHF.equals(null));
+ Money equalMoney = new Money(12, "CHF");
+ assertEquals(f12CHF, f12CHF);
+ assertEquals(f12CHF, equalMoney);
+ assertEquals(f12CHF.hashCode(), equalMoney.hashCode());
+ assertTrue(!f12CHF.equals(f14CHF));
+ }
+
+ @Test
+ public void zeroMoniesAreEqualRegardlessOfCurrency() {
+ Money zeroDollars = new Money(0, "USD");
+ Money zeroFrancs = new Money(0, "CHF");
+
+ assertEquals(zeroDollars, zeroFrancs);
+ assertEquals(zeroDollars.hashCode(), zeroFrancs.hashCode());
+ }
+
+ @Test
+ public void testMoneyHash() {
+ assertTrue(!f12CHF.equals(null));
+ Money equal = new Money(12, "CHF");
+ assertEquals(f12CHF.hashCode(), equal.hashCode());
+ }
+
+ @Test
+ public void testSimplify() {
+ IMoney money = MoneyBag.create(new Money(26, "CHF"), new Money(28, "CHF"));
+ assertEquals(new Money(54, "CHF"), money);
+ }
+
+ @Test
+ public void testNormalize2() {
+ // {[12 CHF][7 USD]} - [12 CHF] == [7 USD]
+ Money expected = new Money(7, "USD");
+ assertEquals(expected, fMB1.subtract(f12CHF));
+ }
+
+ @Test
+ public void testNormalize3() {
+ // {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD]
+ IMoney ms1 = MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD"));
+ Money expected = new Money(4, "USD");
+ assertEquals(expected, fMB1.subtract(ms1));
+ }
+
+ @Test
+ public void testNormalize4() { // [12 CHF] - {[12 CHF][3 USD]} == [-3 USD]
+ IMoney ms1 = MoneyBag.create(new Money(12, "CHF"), new Money(3, "USD"));
+ Money expected = new Money(-3, "USD");
+ assertEquals(expected, f12CHF.subtract(ms1));
+ }
+
+ @Test
+ public void testPrint() {
+ assertEquals("[12 CHF]", f12CHF.toString());
+ }
+
+ @Test
+ public void testSimpleAdd() {
+ // [12 CHF] + [14 CHF] == [26 CHF]
+ Money expected = new Money(26, "CHF");
+ assertEquals(expected, f12CHF.add(f14CHF));
+ }
+
+ @Test
+ public void testSimpleBagAdd() {
+ // [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]}
+ IMoney expected = MoneyBag.create(new Money(26, "CHF"), new Money(7, "USD"));
+ assertEquals(expected, f14CHF.add(fMB1));
+ }
+
+ @Test
+ public void testSimpleMultiply() {
+ // [14 CHF] *2 == [28 CHF]
+ Money expected = new Money(28, "CHF");
+ assertEquals(expected, f14CHF.multiply(2));
+ }
+
+ @Test
+ public void testSimpleNegate() {
+ // [14 CHF] negate == [-14 CHF]
+ Money expected = new Money(-14, "CHF");
+ assertEquals(expected, f14CHF.negate());
+ }
+
+ @Test
+ public void testSimpleSubtract() {
+ // [14 CHF] - [12 CHF] == [2 CHF]
+ Money expected = new Money(2, "CHF");
+ assertEquals(expected, f14CHF.subtract(f12CHF));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/money/package-info.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/money/package-info.java
new file mode 100644
index 0000000..2429514
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/money/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * JUnit v4.x Test for the Money example.
+ *
+ * @since 4.0
+ * @see junit.samples.money.Money
+ */
+package org.junit.samples.money;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/samples/package-info.java b/google3/third_party/java_src/junit/test/java/org/junit/samples/package-info.java
new file mode 100644
index 0000000..ec52263
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/samples/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Provides examples on how to use JUnit 4.
+ *
+ * @since 4.0
+ */
+package org.junit.samples;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/AllTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/AllTests.java
new file mode 100644
index 0000000..fd91691
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/AllTests.java
@@ -0,0 +1,49 @@
+package org.junit.tests;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.Test;
+import org.junit.AssumptionViolatedExceptionTest;
+import org.junit.internal.AllInternalTests;
+import org.junit.rules.AllRulesTests;
+import org.junit.runner.AllRunnerTests;
+import org.junit.runner.RunWith;
+import org.junit.runners.AllRunnersTests;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.samples.AllSamplesTests;
+import org.junit.tests.assertion.AllAssertionTests;
+import org.junit.tests.deprecated.AllDeprecatedTests;
+import org.junit.tests.description.AllDescriptionTests;
+import org.junit.tests.experimental.AllExperimentalTests;
+import org.junit.tests.junit3compatibility.AllJUnit3CompatibilityTests;
+import org.junit.tests.listening.AllListeningTests;
+import org.junit.tests.manipulation.AllManipulationTests;
+import org.junit.tests.running.AllRunningTests;
+import org.junit.tests.validation.AllValidationTests;
+import org.junit.validator.AllValidatorTests;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllAssertionTests.class,
+ AllDeprecatedTests.class,
+ AllDescriptionTests.class,
+ AllExperimentalTests.class,
+ AllInternalTests.class,
+ AllJUnit3CompatibilityTests.class,
+ AllListeningTests.class,
+ AllManipulationTests.class,
+ AllRulesTests.class,
+ AllRunnersTests.class,
+ AllRunnerTests.class,
+ AllRunningTests.class,
+ AllSamplesTests.class,
+ AllValidationTests.class,
+ AllValidatorTests.class,
+ AssumptionViolatedExceptionTest.class,
+ ObjectContractTest.class
+})
+public class AllTests {
+ public static Test suite() {
+ return new JUnit4TestAdapter(AllTests.class);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/ObjectContractTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/ObjectContractTest.java
new file mode 100644
index 0000000..541a25b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/ObjectContractTest.java
@@ -0,0 +1,46 @@
+package org.junit.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeThat;
+
+import java.lang.reflect.Method;
+
+import org.junit.Test;
+import org.junit.Test.None;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.FrameworkMethod;
+
+@RunWith(Theories.class)
+public class ObjectContractTest {
+ @DataPoints
+ public static Object[] objects = {new FrameworkMethod(toStringMethod()),
+ new FrameworkMethod(toStringMethod()), 3, null};
+
+ @Theory
+ @Test(expected = None.class)
+ public void equalsThrowsNoException(Object a, Object b) {
+ assumeNotNull(a);
+ a.equals(b);
+ }
+
+ @Theory
+ public void equalsMeansEqualHashCodes(Object a, Object b) {
+ assumeNotNull(a, b);
+ assumeThat(a, is(b));
+ assertThat(a.hashCode(), is(b.hashCode()));
+ }
+
+ private static Method toStringMethod() {
+ try {
+ return Object.class.getMethod("toString");
+ } catch (SecurityException e) {
+ } catch (NoSuchMethodException e) {
+ }
+ return null;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/SampleJUnit4Tests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/SampleJUnit4Tests.java
new file mode 100644
index 0000000..739f17b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/SampleJUnit4Tests.java
@@ -0,0 +1,136 @@
+package org.junit.tests;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+import java.lang.reflect.Method;
+
+/**
+ * Container for sample JUnit4-style tests used in integration tests.
+ */
+public class SampleJUnit4Tests {
+
+ public static class TestWithOneThrowingTestMethod {
+
+ @Test
+ public void alwaysThrows() {
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ }
+ }
+
+ public static class TestWithOneThrowingTestMethodWithCause {
+
+ @Test
+ public void alwaysThrows() {
+ new FakeClassUnderTest().throwsExceptionWithCause();
+ }
+ }
+
+ public static class TestWithThrowingBeforeMethod {
+
+ @Before
+ public void alwaysThrows() {
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ }
+
+ @Test
+ public void alwaysPasses() {
+ }
+ }
+
+ public static class ThrowingTestRule implements TestRule {
+
+ public Statement apply(
+ Statement base, org.junit.runner.Description description) {
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ return base;
+ }
+ }
+
+ public static class TestWithThrowingTestRule {
+
+ @Rule
+ public final TestRule rule = new ThrowingTestRule();
+
+ @Test
+ public void alwaysPasses() {
+ }
+ }
+
+ public static class TestWithThrowingClassRule {
+
+ @ClassRule
+ public static final TestRule rule = new ThrowingTestRule();
+
+ @Test
+ public void alwaysPasses() {
+ }
+ }
+
+ public static class ThrowingMethodRule implements MethodRule {
+
+ public Statement apply(
+ Statement base, FrameworkMethod method, Object target) {
+ new FakeClassUnderTest().throwsExceptionWithoutCause();
+ return base;
+ }
+ }
+
+ public static class TestWithThrowingMethodRule {
+
+ @Rule
+ public final ThrowingMethodRule rule = new ThrowingMethodRule();
+
+ @Test
+ public void alwaysPasses() {
+ }
+ }
+
+ public static class TestWithSuppressedException {
+ public static final Method addSuppressed = initAddSuppressed();
+
+ static Method initAddSuppressed() {
+ try {
+ return Throwable.class.getMethod("addSuppressed", Throwable.class);
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ @Test
+ public void alwaysThrows() throws Exception {
+ final RuntimeException exception = new RuntimeException("error");
+ addSuppressed.invoke(exception, new RuntimeException("suppressed"));
+ throw exception;
+ }
+ }
+
+ private static class FakeClassUnderTest {
+
+ public void throwsExceptionWithCause() {
+ doThrowExceptionWithCause();
+ }
+
+ public void throwsExceptionWithoutCause() {
+ doThrowExceptionWithoutCause();
+ }
+
+ private void doThrowExceptionWithCause() {
+ try {
+ throwsExceptionWithoutCause();
+ } catch (Exception e) {
+ throw new RuntimeException("outer", e);
+ }
+ }
+
+ private void doThrowExceptionWithoutCause() {
+ throw new RuntimeException("cause");
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/TestSystem.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/TestSystem.java
new file mode 100644
index 0000000..d74166c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/TestSystem.java
@@ -0,0 +1,35 @@
+package org.junit.tests;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.junit.internal.JUnitSystem;
+
+public class TestSystem implements JUnitSystem {
+ private PrintStream out;
+ public int fCode;
+ private ByteArrayOutputStream fOutContents;
+
+ public TestSystem() {
+ fOutContents = new ByteArrayOutputStream();
+ out = new PrintStream(fOutContents);
+ }
+
+ /**
+ * Will be removed in the next major release
+ */
+ @Deprecated
+ public void exit(int code) {
+ fCode = code;
+ }
+
+ public PrintStream out() {
+ return out;
+ }
+
+ public OutputStream outContents() {
+ return fOutContents;
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AllAssertionTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AllAssertionTests.java
new file mode 100644
index 0000000..5190e94
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AllAssertionTests.java
@@ -0,0 +1,14 @@
+package org.junit.tests.assertion;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AssertionTest.class,
+ ComparisonFailureTest.class,
+ MultipleFailureExceptionTest.class
+})
+public class AllAssertionTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AssertionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AssertionTest.java
new file mode 100644
index 0000000..22907e0
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/AssertionTest.java
@@ -0,0 +1,1005 @@
+package org.junit.tests.assertion;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+import org.junit.Test;
+import org.junit.function.ThrowingRunnable;
+import org.junit.internal.ArrayComparisonFailure;
+
+/**
+ * Tests for {@link org.junit.Assert}
+ */
+public class AssertionTest {
+// If you want to use 1.4 assertions, they will be reported correctly.
+// However, you need to add the -ea VM argument when running.
+
+// @Test (expected=AssertionError.class) public void error() {
+// assert false;
+// }
+
+ private static final String ASSERTION_ERROR_EXPECTED = "AssertionError expected";
+
+ @Test(expected = AssertionError.class)
+ public void fails() {
+ Assert.fail();
+ }
+
+ @Test
+ public void failWithNoMessageToString() {
+ try {
+ Assert.fail();
+ } catch (AssertionError exception) {
+ assertEquals("java.lang.AssertionError", exception.toString());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void failWithMessageToString() {
+ try {
+ Assert.fail("woops!");
+ } catch (AssertionError exception) {
+ assertEquals("java.lang.AssertionError: woops!", exception.toString());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void arraysNotEqual() {
+ assertArrayEqualsFailure(
+ new Object[]{"right"},
+ new Object[]{"wrong"},
+ "arrays first differed at element [0]; expected:<[right]> but was:<[wrong]>");
+ }
+
+ @Test
+ public void arraysNotEqualWithMessage() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[]{"right"},
+ new Object[]{"wrong"},
+ "not equal: arrays first differed at element [0]; expected:<[right]> but was:<[wrong]>");
+ }
+
+ @Test
+ public void arraysExpectedNullMessage() {
+ try {
+ assertArrayEquals("not equal", null, new Object[]{new Object()});
+ } catch (AssertionError exception) {
+ assertEquals("not equal: expected array was null", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void arraysActualNullMessage() {
+ try {
+ assertArrayEquals("not equal", new Object[]{new Object()}, null);
+ } catch (AssertionError exception) {
+ assertEquals("not equal: actual array was null", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void arraysDifferentLengthDifferingAtStartMessage() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[]{true},
+ new Object[]{false, true},
+ "not equal: array lengths differed, expected.length=1 actual.length=2; arrays first differed at element [0]; expected:<true> but was:<false>");
+ }
+
+ @Test
+ public void arraysDifferentLengthDifferingAtEndMessage() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[]{true},
+ new Object[]{true, false},
+ "not equal: array lengths differed, expected.length=1 actual.length=2; arrays first differed at element [1]; expected:<end of array> but was:<false>");
+ }
+
+ @Test
+ public void arraysDifferentLengthDifferingAtEndAndExpectedArrayLongerMessage() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[]{true, false},
+ new Object[]{true},
+ "not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<false> but was:<end of array>");
+ }
+
+ @Test
+ public void arraysElementsDiffer() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[]{"this is a very long string in the middle of an array"},
+ new Object[]{"this is another very long string in the middle of an array"},
+ "not equal: arrays first differed at element [0]; expected:<this is a[] very long string in...> but was:<this is a[nother] very long string in...>");
+ }
+
+ @Test
+ public void arraysDifferAtElement0nullMessage() {
+ assertArrayEqualsFailure(
+ new Object[]{true},
+ new Object[]{false},
+ "arrays first differed at element [0]; expected:<true> but was:<false>"
+ );
+ }
+
+ @Test
+ public void arraysDifferAtElement1nullMessage() {
+ assertArrayEqualsFailure(
+ new Object[]{true, true},
+ new Object[]{true, false},
+ "arrays first differed at element [1]; expected:<true> but was:<false>"
+ );
+ }
+
+ @Test
+ public void arraysDifferAtElement0withMessage() {
+ assertArrayEqualsFailure(
+ "message",
+ new Object[]{true},
+ new Object[]{false},
+ "message: arrays first differed at element [0]; expected:<true> but was:<false>"
+ );
+ }
+
+ @Test
+ public void arraysDifferAtElement1withMessage() {
+ assertArrayEqualsFailure(
+ "message",
+ new Object[]{true, true},
+ new Object[]{true, false},
+ "message: arrays first differed at element [1]; expected:<true> but was:<false>"
+ );
+ }
+
+ @Test
+ public void multiDimensionalArraysAreEqual() {
+ assertArrayEquals((new Object[][]{{true, true}, {false, false}}), (new Object[][]{{true, true}, {false, false}}));
+ }
+
+ @Test
+ public void multiDimensionalIntArraysAreEqual() {
+ int[][] int1 = {{1, 2, 3}, {4, 5, 6}};
+ int[][] int2 = {{1, 2, 3}, {4, 5, 6}};
+ assertArrayEquals(int1, int2);
+ }
+
+ @Test
+ public void oneDimensionalPrimitiveArraysAreEqual() {
+ assertArrayEquals(new boolean[]{true}, new boolean[]{true});
+ assertArrayEquals(new byte[]{1}, new byte[]{1});
+ assertArrayEquals(new char[]{1}, new char[]{1});
+ assertArrayEquals(new short[]{1}, new short[]{1});
+ assertArrayEquals(new int[]{1}, new int[]{1});
+ assertArrayEquals(new long[]{1}, new long[]{1});
+ assertArrayEquals(new double[]{1.0}, new double[]{1.0}, 1.0);
+ assertArrayEquals(new float[]{1.0f}, new float[]{1.0f}, 1.0f);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void oneDimensionalDoubleArraysAreNotEqual() {
+ assertArrayEquals(new double[]{1.0}, new double[]{2.5}, 1.0);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void oneDimensionalFloatArraysAreNotEqual() {
+ assertArrayEquals(new float[]{1.0f}, new float[]{2.5f}, 1.0f);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void oneDimensionalBooleanArraysAreNotEqual() {
+ assertArrayEquals(new boolean[]{true}, new boolean[]{false});
+ }
+
+ @Test(expected = AssertionError.class)
+ public void IntegerDoesNotEqualLong() {
+ assertEquals(new Integer(1), new Long(1));
+ }
+
+ @Test
+ public void intsEqualLongs() {
+ assertEquals(1, 1L);
+ }
+
+ @Test
+ public void multiDimensionalArraysDeclaredAsOneDimensionalAreEqual() {
+ assertArrayEquals((new Object[]{new Object[]{true, true}, new Object[]{false, false}}), (new Object[]{new Object[]{true, true}, new Object[]{false, false}}));
+ }
+
+ @Test
+ public void multiDimensionalArraysAreNotEqual() {
+ assertArrayEqualsFailure(
+ "message",
+ new Object[][]{{true, true}, {false, false}},
+ new Object[][]{{true, true}, {true, false}},
+ "message: arrays first differed at element [1][0]; expected:<false> but was:<true>");
+ }
+
+ @Test
+ public void multiDimensionalArraysAreNotEqualNoMessage() {
+ assertArrayEqualsFailure(
+ new Object[][]{{true, true}, {false, false}},
+ new Object[][]{{true, true}, {true, false}},
+ "arrays first differed at element [1][0]; expected:<false> but was:<true>");
+ }
+
+ @Test
+ public void twoDimensionalArraysDifferentOuterLengthNotEqual() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{true}, {}},
+ new Object[][]{{}},
+ "not equal: array lengths differed, expected.length=1 actual.length=0; arrays first differed at element [0][0]; expected:<true> but was:<end of array>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}, {true}},
+ new Object[][]{{}},
+ "not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<java.lang.Object[1]> but was:<end of array>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}},
+ new Object[][]{{true}, {}},
+ "not equal: array lengths differed, expected.length=0 actual.length=1; arrays first differed at element [0][0]; expected:<end of array> but was:<true>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}},
+ new Object[][]{{}, {true}},
+ "not equal: array lengths differed, expected.length=1 actual.length=2; arrays first differed at element [1]; expected:<end of array> but was:<java.lang.Object[1]>");
+ }
+
+ @Test
+ public void primitiveArraysConvertedToStringCorrectly() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new boolean[][]{{}, {true}},
+ new boolean[][]{{}},
+ "not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<boolean[1]> but was:<end of array>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new int[][]{{}, {23}},
+ new int[][]{{}},
+ "not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<int[1]> but was:<end of array>");
+ }
+
+ @Test
+ public void twoDimensionalArraysConvertedToStringCorrectly() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][][]{{}, {{true}}},
+ new Object[][][]{{}},
+ "not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<java.lang.Object[][1]> but was:<end of array>");
+ }
+
+ @Test
+ public void twoDimensionalArraysDifferentInnerLengthNotEqual() {
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{true}, {}},
+ new Object[][]{{}, {}},
+ "not equal: array lengths differed, expected.length=1 actual.length=0; arrays first differed at element [0][0]; expected:<true> but was:<end of array>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}, {true}},
+ new Object[][]{{}, {}},
+ "not equal: array lengths differed, expected.length=1 actual.length=0; arrays first differed at element [1][0]; expected:<true> but was:<end of array>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}, {}},
+ new Object[][]{{true}, {}},
+ "not equal: array lengths differed, expected.length=0 actual.length=1; arrays first differed at element [0][0]; expected:<end of array> but was:<true>");
+ assertArrayEqualsFailure(
+ "not equal",
+ new Object[][]{{}, {}},
+ new Object[][]{{}, {true}},
+ "not equal: array lengths differed, expected.length=0 actual.length=1; arrays first differed at element [1][0]; expected:<end of array> but was:<true>");
+ }
+
+ private void assertArrayEqualsFailure(Object[] expecteds, Object[] actuals, String expectedMessage) {
+ try {
+ assertArrayEquals(expecteds, actuals);
+ } catch (ArrayComparisonFailure e) {
+ assertEquals(expectedMessage, e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ private void assertArrayEqualsFailure(String message, Object[] expecteds, Object[] actuals, String expectedMessage) {
+ try {
+ assertArrayEquals(message, expecteds, actuals);
+ } catch (ArrayComparisonFailure e) {
+ assertEquals(expectedMessage, e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void multiDimensionalArraysDifferentLengthMessage() {
+ try {
+ assertArrayEquals("message", new Object[][]{{true, true}, {false, false}}, new Object[][]{{true, true}, {false}});
+ } catch (AssertionError exception) {
+ assertEquals("message: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1][1]; expected:<false> but was:<end of array>", exception.getMessage());
+ return;
+ }
+
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void multiDimensionalArraysDifferentLengthNoMessage() {
+ try {
+ assertArrayEquals(new Object[][]{{true, true}, {false, false}}, new Object[][]{{true, true}, {false}});
+ } catch (AssertionError exception) {
+ assertEquals("array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1][1]; expected:<false> but was:<end of array>", exception.getMessage());
+ return;
+ }
+
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void arraysWithNullElementEqual() {
+ Object[] objects1 = new Object[]{null};
+ Object[] objects2 = new Object[]{null};
+ assertArrayEquals(objects1, objects2);
+ }
+
+ @Test
+ public void stringsDifferWithUserMessage() {
+ try {
+ assertEquals("not equal", "one", "two");
+ } catch (ComparisonFailure exception) {
+ assertEquals("not equal expected:<[one]> but was:<[two]>", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void arraysEqual() {
+ Object element = new Object();
+ Object[] objects1 = new Object[]{element};
+ Object[] objects2 = new Object[]{element};
+ assertArrayEquals(objects1, objects2);
+ }
+
+ @Test
+ public void arraysEqualWithMessage() {
+ Object element = new Object();
+ Object[] objects1 = new Object[]{element};
+ Object[] objects2 = new Object[]{element};
+ assertArrayEquals("equal", objects1, objects2);
+ }
+
+ @Test
+ public void equals() {
+ Object o = new Object();
+ assertEquals(o, o);
+ assertEquals("abc", "abc");
+ assertEquals(true, true);
+ assertEquals((byte) 1, (byte) 1);
+ assertEquals('a', 'a');
+ assertEquals((short) 1, (short) 1);
+ assertEquals(1, 1); // int by default, cast is unnecessary
+ assertEquals(1l, 1l);
+ assertEquals(1.0, 1.0, 0.0);
+ assertEquals(1.0d, 1.0d, 0.0d);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void notEqualsObjectWithNull() {
+ assertEquals(new Object(), null);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void notEqualsNullWithObject() {
+ assertEquals(null, new Object());
+ }
+
+ @Test
+ public void notEqualsObjectWithNullWithMessage() {
+ Object o = new Object();
+ try {
+ assertEquals("message", null, o);
+ } catch (AssertionError e) {
+ assertEquals("message expected:<null> but was:<" + o.toString() + ">", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void notEqualsNullWithObjectWithMessage() {
+ Object o = new Object();
+ try {
+ assertEquals("message", o, null);
+ } catch (AssertionError e) {
+ assertEquals("message expected:<" + o.toString() + "> but was:<null>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void objectsNotEquals() {
+ assertEquals(new Object(), new Object());
+ }
+
+ @Test(expected = ComparisonFailure.class)
+ public void stringsNotEqual() {
+ assertEquals("abc", "def");
+ }
+
+ @Test(expected = AssertionError.class)
+ public void booleansNotEqual() {
+ assertEquals(true, false);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void bytesNotEqual() {
+ assertEquals((byte) 1, (byte) 2);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void charsNotEqual() {
+ assertEquals('a', 'b');
+ }
+
+ @Test(expected = AssertionError.class)
+ public void shortsNotEqual() {
+ assertEquals((short) 1, (short) 2);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void intsNotEqual() {
+ assertEquals(1, 2);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void longsNotEqual() {
+ assertEquals(1l, 2l);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void floatsNotEqual() {
+ assertEquals(1.0, 2.0, 0.9);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test(expected = AssertionError.class)
+ public void floatsNotEqualWithoutDelta() {
+ assertEquals(1.0, 1.1);
+ }
+
+ @Test
+ public void floatsNotDoublesInArrays() {
+ float delta = 4.444f;
+ float[] f1 = new float[]{1.111f};
+ float[] f2 = new float[]{5.555f};
+ Assert.assertArrayEquals(f1, f2, delta);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void bigDecimalsNotEqual() {
+ assertEquals(new BigDecimal("123.4"), new BigDecimal("123.0"));
+ }
+
+
+ @Test(expected = AssertionError.class)
+ public void doublesNotEqual() {
+ assertEquals(1.0d, 2.0d, 0.9d);
+ }
+
+ @Test
+ public void naNsAreEqual() {
+ assertEquals(Float.NaN, Float.NaN, Float.POSITIVE_INFINITY);
+ assertEquals(Double.NaN, Double.NaN, Double.POSITIVE_INFINITY);
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void nullNullmessage() {
+ try {
+ assertNull("junit");
+ } catch (AssertionError e) {
+ assertEquals("expected null, but was:<junit>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @SuppressWarnings("unused")
+ @Test
+ public void nullWithMessage() {
+ try {
+ assertNull("message", "hello");
+ } catch (AssertionError exception) {
+ assertEquals("message expected null, but was:<hello>", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void same() {
+ Object o1 = new Object();
+ assertSame(o1, o1);
+ }
+
+ @Test
+ public void notSame() {
+ Object o1 = new Object();
+ Object o2 = new Object();
+ assertNotSame(o1, o2);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void objectsNotSame() {
+ assertSame(new Object(), new Object());
+ }
+
+ @Test(expected = AssertionError.class)
+ public void objectsAreSame() {
+ Object o = new Object();
+ assertNotSame(o, o);
+ }
+
+ @Test
+ public void sameWithMessage() {
+ try {
+ assertSame("not same", "hello", "good-bye");
+ } catch (AssertionError exception) {
+ assertEquals("not same expected same:<hello> was not:<good-bye>",
+ exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void sameNullMessage() {
+ try {
+ assertSame("hello", "good-bye");
+ } catch (AssertionError exception) {
+ assertEquals("expected same:<hello> was not:<good-bye>", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void notSameWithMessage() {
+ Object o = new Object();
+ try {
+ assertNotSame("message", o, o);
+ } catch (AssertionError exception) {
+ assertEquals("message expected not same", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void notSameNullMessage() {
+ Object o = new Object();
+ try {
+ assertNotSame(o, o);
+ } catch (AssertionError exception) {
+ assertEquals("expected not same", exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void nullMessage() {
+ try {
+ fail(null);
+ } catch (AssertionError exception) {
+ // we used to expect getMessage() to return ""; see failWithNoMessageToString()
+ assertNull(exception.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void nullMessageDisappearsWithStringAssertEquals() {
+ try {
+ assertEquals(null, "a", "b");
+ } catch (ComparisonFailure e) {
+ assertEquals("expected:<[a]> but was:<[b]>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void nullMessageDisappearsWithAssertEquals() {
+ try {
+ assertEquals(null, 1, 2);
+ } catch (AssertionError e) {
+ assertEquals("expected:<1> but was:<2>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void arraysDeclaredAsObjectAreComparedAsObjects() {
+ Object a1 = new Object[]{"abc"};
+ Object a2 = new Object[]{"abc"};
+ assertEquals(a1, a2);
+ }
+
+ @Test
+ public void implicitTypecastEquality() {
+ byte b = 1;
+ short s = 1;
+ int i = 1;
+ long l = 1L;
+ float f = 1.0f;
+ double d = 1.0;
+
+ assertEquals(b, s);
+ assertEquals(b, i);
+ assertEquals(b, l);
+ assertEquals(s, i);
+ assertEquals(s, l);
+ assertEquals(i, l);
+ assertEquals(f, d, 0);
+ }
+
+ @Test
+ public void errorMessageDistinguishesDifferentValuesWithSameToString() {
+ try {
+ assertEquals("4", new Integer(4));
+ } catch (AssertionError e) {
+ assertEquals("expected: java.lang.String<4> but was: java.lang.Integer<4>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThatIncludesDescriptionOfTestedValueInErrorMessage() {
+ String expected = "expected";
+ String actual = "actual";
+
+ String expectedMessage = "identifier\nExpected: \"expected\"\n but: was \"actual\"";
+
+ try {
+ assertThat("identifier", actual, equalTo(expected));
+ } catch (AssertionError e) {
+ assertEquals(expectedMessage, e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThatIncludesAdvancedMismatch() {
+ String expectedMessage = "identifier\nExpected: is an instance of java.lang.Integer\n but: \"actual\" is a java.lang.String";
+
+ try {
+ assertThat("identifier", "actual", is(instanceOf(Integer.class)));
+ } catch (AssertionError e) {
+ assertEquals(expectedMessage, e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThatDescriptionCanBeElided() {
+ String expected = "expected";
+ String actual = "actual";
+
+ String expectedMessage = "\nExpected: \"expected\"\n but: was \"actual\"";
+
+ try {
+ assertThat(actual, equalTo(expected));
+ } catch (AssertionError e) {
+ assertEquals(expectedMessage, e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void nullAndStringNullPrintCorrectError() {
+ try {
+ assertEquals(null, "null");
+ } catch (AssertionError e) {
+ assertEquals("expected: null<null> but was: java.lang.String<null>", e.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void stringNullAndNullWorksToo() {
+ assertEquals("null", null);
+ }
+
+ private static class NullToString {
+ @Override
+ public String toString() {
+ return null;
+ }
+ }
+
+ @Test
+ public void nullToString() {
+ try {
+ assertEquals(new NullToString(), new NullToString());
+ } catch (AssertionError e) {
+ assertEquals("expected: org.junit.tests.assertion.AssertionTest$NullToString<null> but "
+ + "was: org.junit.tests.assertion.AssertionTest$NullToString<null>",
+ e.getMessage());
+ return;
+ }
+
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void compareBigDecimalAndInteger() {
+ final BigDecimal bigDecimal = new BigDecimal("1.2");
+ final Integer integer = Integer.valueOf("1");
+ assertEquals(bigDecimal, integer);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void sameObjectIsNotEqual() {
+ Object o = new Object();
+ assertNotEquals(o, o);
+ }
+
+ @Test
+ public void objectsWithDifferentReferencesAreNotEqual() {
+ assertNotEquals(new Object(), new Object());
+ }
+
+ @Test
+ public void assertNotEqualsIncludesCorrectMessage() {
+ Integer value1 = new Integer(1);
+ Integer value2 = new Integer(1);
+ String message = "The values should be different";
+
+ try {
+ assertNotEquals(message, value1, value2);
+ } catch (AssertionError e) {
+ assertEquals(message + ". Actual: " + value1, e.getMessage());
+ return;
+ }
+
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertNotEqualsIncludesTheValueBeingTested() {
+ Integer value1 = new Integer(1);
+ Integer value2 = new Integer(1);
+
+ try {
+ assertNotEquals(value1, value2);
+ } catch (AssertionError e) {
+ assertTrue(e.getMessage().contains(value1.toString()));
+ return;
+ }
+
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertNotEqualsWorksWithPrimitiveTypes() {
+ assertNotEquals(1L, 2L);
+ assertNotEquals("The values should be different", 1L, 2L);
+ assertNotEquals(1.0, 2.0, 0);
+ assertNotEquals("The values should be different", 1.0, 2.0, 0);
+ assertNotEquals(1.0f, 2.0f, 0f);
+ assertNotEquals("The values should be different", 1.0f, 2.0f, 0f);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertNotEqualsConsidersDeltaCorrectly() {
+ assertNotEquals(1.0, 0.9, 0.1);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertNotEqualsConsidersFloatDeltaCorrectly() {
+ assertNotEquals(1.0f, 0.75f, 0.25f);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertNotEqualsIgnoresDeltaOnNaN() {
+ assertNotEquals(Double.NaN, Double.NaN, 1);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertNotEqualsIgnoresFloatDeltaOnNaN() {
+ assertNotEquals(Float.NaN, Float.NaN, 1f);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertThrowsRequiresAnExceptionToBeThrown() {
+ assertThrows(Throwable.class, nonThrowingRunnable());
+ }
+
+ @Test
+ public void assertThrowsIncludesAnInformativeDefaultMessage() {
+ try {
+ assertThrows(Throwable.class, nonThrowingRunnable());
+ } catch (AssertionError ex) {
+ assertEquals("expected java.lang.Throwable to be thrown, but nothing was thrown", ex.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsIncludesTheSpecifiedMessage() {
+ try {
+ assertThrows("Foobar", Throwable.class, nonThrowingRunnable());
+ } catch (AssertionError ex) {
+ assertEquals(
+ "Foobar: expected java.lang.Throwable to be thrown, but nothing was thrown",
+ ex.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsReturnsTheSameObjectThrown() {
+ NullPointerException npe = new NullPointerException();
+
+ Throwable throwable = assertThrows(Throwable.class, throwingRunnable(npe));
+
+ assertSame(npe, throwable);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void assertThrowsDetectsTypeMismatchesViaExplicitTypeHint() {
+ NullPointerException npe = new NullPointerException();
+
+ assertThrows(IOException.class, throwingRunnable(npe));
+ }
+
+ @Test
+ public void assertThrowsWrapsAndPropagatesUnexpectedExceptions() {
+ NullPointerException npe = new NullPointerException("inner-message");
+
+ try {
+ assertThrows(IOException.class, throwingRunnable(npe));
+ } catch (AssertionError ex) {
+ assertSame(npe, ex.getCause());
+ assertEquals("inner-message", ex.getCause().getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsSuppliesACoherentErrorMessageUponTypeMismatch() {
+ NullPointerException npe = new NullPointerException();
+
+ try {
+ assertThrows(IOException.class, throwingRunnable(npe));
+ } catch (AssertionError error) {
+ assertEquals("unexpected exception type thrown; expected:<java.io.IOException> but was:<java.lang.NullPointerException>",
+ error.getMessage());
+ assertSame(npe, error.getCause());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsSuppliesTheSpecifiedMessageUponTypeMismatch() {
+ NullPointerException npe = new NullPointerException();
+
+ try {
+ assertThrows("Foobar", IOException.class, throwingRunnable(npe));
+ } catch (AssertionError error) {
+ assertEquals("Foobar: unexpected exception type thrown; expected:<java.io.IOException> but was:<java.lang.NullPointerException>",
+ error.getMessage());
+ assertSame(npe, error.getCause());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsUsesCanonicalNameUponTypeMismatch() {
+ NullPointerException npe = new NullPointerException();
+
+ try {
+ assertThrows(NestedException.class, throwingRunnable(npe));
+ } catch (AssertionError error) {
+ assertEquals(
+ "unexpected exception type thrown; expected:<org.junit.tests.assertion.AssertionTest.NestedException>"
+ + " but was:<java.lang.NullPointerException>",
+ error.getMessage());
+ assertSame(npe, error.getCause());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsUsesNameUponTypeMismatchWithAnonymousClass() {
+ NullPointerException npe = new NullPointerException() {
+ };
+
+ try {
+ assertThrows(IOException.class, throwingRunnable(npe));
+ } catch (AssertionError error) {
+ assertEquals(
+ "unexpected exception type thrown; expected:<java.io.IOException>"
+ + " but was:<org.junit.tests.assertion.AssertionTest$1>",
+ error.getMessage());
+ assertSame(npe, error.getCause());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ @Test
+ public void assertThrowsUsesCanonicalNameWhenRequiredExceptionNotThrown() {
+ try {
+ assertThrows(NestedException.class, nonThrowingRunnable());
+ } catch (AssertionError error) {
+ assertEquals(
+ "expected org.junit.tests.assertion.AssertionTest.NestedException to be thrown,"
+ + " but nothing was thrown", error.getMessage());
+ return;
+ }
+ throw new AssertionError(ASSERTION_ERROR_EXPECTED);
+ }
+
+ private static class NestedException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ private static ThrowingRunnable nonThrowingRunnable() {
+ return new ThrowingRunnable() {
+ public void run() throws Throwable {
+ }
+ };
+ }
+
+ private static ThrowingRunnable throwingRunnable(final Throwable t) {
+ return new ThrowingRunnable() {
+ public void run() throws Throwable {
+ throw t;
+ }
+ };
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/ComparisonFailureTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/ComparisonFailureTest.java
new file mode 100644
index 0000000..17ff2af
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/ComparisonFailureTest.java
@@ -0,0 +1,78 @@
+package org.junit.tests.assertion;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.ComparisonFailure;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ComparisonFailureTest {
+
+ private String expected, actual, message;
+
+ public ComparisonFailureTest(String e, String a, String m) {
+ expected = e;
+ actual = a;
+ message = m;
+ }
+
+ @Parameters(name = "compact-msg-{index}, exp=\"{1}\"")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ // simple base case
+ { "a", "b", "expected:<[a]> but was:<[b]>" },
+
+ // common prefix
+ { "ba", "bc", "expected:<b[a]> but was:<b[c]>" },
+
+ // common suffix
+ { "ab", "cb", "expected:<[a]b> but was:<[c]b>" },
+
+ // common pre and suffix
+ { "abc", "adc", "expected:<a[b]c> but was:<a[d]c>" },
+
+ // expected is subset of actual
+ { "ab", "abc", "expected:<ab[]> but was:<ab[c]>" },
+
+ // expected is superset of actual
+ { "abc", "ab", "expected:<ab[c]> but was:<ab[]>" },
+
+ // overlapping matches.
+ { "abc", "abbc", "expected:<ab[]c> but was:<ab[b]c>" },
+
+ // long prefix yielding "..."
+ { "01234567890123456789PRE:hello:POST",
+ "01234567890123456789PRE:world:POST",
+ "expected:<...4567890123456789PRE:[hello]:POST> but was:<...4567890123456789PRE:[world]:POST>" },
+
+ // long suffix yielding "..."
+ { "PRE:hello:01234567890123456789POST",
+ "PRE:world:01234567890123456789POST",
+ "expected:<PRE:[hello]:0123456789012345678...> but was:<PRE:[world]:0123456789012345678...>"
+ },
+
+ // bug609972
+ { "S&P500", "0", "expected:<[S&P50]0> but was:<[]0>" },
+
+ // empty expected string
+ { "", "a", "expected:<[]> but was:<[a]>" },
+
+ // empty actual string
+ { "a", "", "expected:<[a]> but was:<[]>" }
+
+ });
+ }
+
+ @Test
+ public void compactFailureMessage() {
+ ComparisonFailure failure = new ComparisonFailure("", expected, actual);
+ assertEquals(message, failure.getMessage());
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/MultipleFailureExceptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/MultipleFailureExceptionTest.java
new file mode 100644
index 0000000..18880b7
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/assertion/MultipleFailureExceptionTest.java
@@ -0,0 +1,118 @@
+package org.junit.tests.assertion;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.TestCouldNotBeSkippedException;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.MultipleFailureException;
+
+
+/**
+ * Tests for {@link org.junit.runners.model.MultipleFailureException}
+ *
+ * @author kcooney@google.com (Kevin Cooney)
+ */
+public class MultipleFailureExceptionTest {
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ @Test
+ public void assertEmptyDoesNotThrowForEmptyList() throws Exception {
+ MultipleFailureException.assertEmpty(Collections.<Throwable>emptyList());
+ }
+
+ @Test
+ public void assertEmptyRethrowsSingleRuntimeException() throws Exception {
+ Throwable exception= new ExpectedException("pesto");
+ List<Throwable> errors= Collections.singletonList(exception);
+ try {
+ MultipleFailureException.assertEmpty(errors);
+ fail();
+ } catch (ExpectedException e) {
+ assertSame(e, exception);
+ }
+ }
+
+ @Test
+ public void assertEmptyRethrowsSingleError() throws Exception {
+ Throwable exception= new AnnotationFormatError("changeo");
+ List<Throwable> errors= Collections.singletonList(exception);
+ try {
+ MultipleFailureException.assertEmpty(errors);
+ fail();
+ } catch (AnnotationFormatError e) {
+ assertSame(e, exception);
+ }
+ }
+
+ @Test
+ public void assertEmptyThrowsMultipleFailureExceptionForManyThrowables() throws Exception {
+ List<Throwable> errors = new ArrayList<Throwable>();
+ errors.add(new ExpectedException("basil"));
+ errors.add(new RuntimeException("garlic"));
+
+ try {
+ MultipleFailureException.assertEmpty(errors);
+ fail();
+ } catch (MultipleFailureException expected) {
+ assertThat(expected.getFailures(), equalTo(errors));
+ assertTrue(expected.getMessage().startsWith("There were 2 errors:" + LINE_SEPARATOR));
+ assertTrue(expected.getMessage().contains("ExpectedException(basil)" + LINE_SEPARATOR));
+ assertTrue(expected.getMessage().contains("RuntimeException(garlic)"));
+ }
+ }
+
+ @Test
+ public void assertEmptyErrorListConstructorFailure() {
+ try {
+ new MultipleFailureException(Collections.<Throwable>emptyList());
+ fail();
+ } catch (IllegalArgumentException expected) {
+ assertThat(expected.getMessage(),
+ containsString("List of Throwables must not be empty"));
+ }
+ }
+
+ @Test
+ public void assertEmptyWrapsAssumptionFailuresForManyThrowables() throws Exception {
+ List<Throwable> errors = new ArrayList<Throwable>();
+ AssumptionViolatedException assumptionViolatedException = new AssumptionViolatedException("skip it");
+ errors.add(assumptionViolatedException);
+ errors.add(new RuntimeException("garlic"));
+
+ try {
+ MultipleFailureException.assertEmpty(errors);
+ fail();
+ } catch (MultipleFailureException expected) {
+ assertThat(expected.getFailures().size(), equalTo(2));
+ assertTrue(expected.getMessage().startsWith("There were 2 errors:" + LINE_SEPARATOR));
+ assertTrue(expected.getMessage().contains("TestCouldNotBeSkippedException(Test could not be skipped"));
+ assertTrue(expected.getMessage().contains("RuntimeException(garlic)"));
+ Throwable first = expected.getFailures().get(0);
+ assertThat(first, instanceOf(TestCouldNotBeSkippedException.class));
+ Throwable cause = ((TestCouldNotBeSkippedException) first).getCause();
+ assertThat(cause, instanceOf(AssumptionViolatedException.class));
+ assertThat((AssumptionViolatedException) cause, CoreMatchers.sameInstance(assumptionViolatedException));
+ }
+ }
+
+ private static class ExpectedException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public ExpectedException(String message) {
+ super(message);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/AllDeprecatedTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/AllDeprecatedTests.java
new file mode 100644
index 0000000..4e1a3f4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/AllDeprecatedTests.java
@@ -0,0 +1,13 @@
+package org.junit.tests.deprecated;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@SuppressWarnings("deprecation")
+@RunWith(Suite.class)
+@SuiteClasses({
+ JUnit4ClassRunnerTest.class
+})
+public class AllDeprecatedTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/JUnit4ClassRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/JUnit4ClassRunnerTest.java
new file mode 100644
index 0000000..c0c081d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/deprecated/JUnit4ClassRunnerTest.java
@@ -0,0 +1,64 @@
+package org.junit.tests.deprecated;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.internal.runners.JUnit4ClassRunner;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+
+/**
+ * @deprecated This is a simple smoke test to make sure the old JUnit4ClassRunner basically works.
+ * Delete this test when JUnit4ClassRunner goes to the Great Heap In The Sky.
+ */
+@Deprecated
+public class JUnit4ClassRunnerTest {
+
+ @SuppressWarnings("deprecation")
+ @RunWith(JUnit4ClassRunner.class)
+ public static class Example {
+ @Test
+ public void success() {
+ }
+
+ @Test
+ public void failure() {
+ fail();
+ }
+ }
+
+ @Test
+ public void runWithOldJUnit4ClassRunner() {
+ Result result = JUnitCore.runClasses(Example.class);
+ assertThat(result.getRunCount(), is(2));
+ assertThat(result.getFailureCount(), is(1));
+ }
+
+ @SuppressWarnings("deprecation")
+ @RunWith(JUnit4ClassRunner.class)
+ public static class UnconstructableExample {
+ public UnconstructableExample() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Test
+ public void success() {
+ }
+
+ @Test
+ public void failure() {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void runWithOldJUnit4ClassRunnerAndBadConstructor() {
+ Result result = JUnitCore.runClasses(UnconstructableExample.class);
+ assertThat(result.getRunCount(), is(2));
+ assertThat(result.getFailureCount(), is(2));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AllDescriptionTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AllDescriptionTests.java
new file mode 100644
index 0000000..6de5efb
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AllDescriptionTests.java
@@ -0,0 +1,15 @@
+package org.junit.tests.description;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AnnotatedDescriptionTest.class,
+ SuiteDescriptionTest.class,
+ TestDescriptionMethodNameTest.class,
+ TestDescriptionTest.class
+})
+public class AllDescriptionTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AnnotatedDescriptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AnnotatedDescriptionTest.java
new file mode 100644
index 0000000..cbe3522
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/AnnotatedDescriptionTest.java
@@ -0,0 +1,96 @@
+package org.junit.tests.description;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+
+public class AnnotatedDescriptionTest {
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MyOwnAnnotation {
+
+ }
+
+ @MyOwnAnnotation
+ public static class AnnotatedClass {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void annotationsExistOnDescriptionsOfClasses() {
+ assertTrue((describe(AnnotatedClass.class).getAnnotation(
+ MyOwnAnnotation.class) != null));
+ }
+
+ @Test
+ public void getAnnotationsReturnsAllAnnotations() {
+ assertEquals(1, describe(ValueAnnotatedClass.class).getAnnotations()
+ .size());
+ }
+
+ @Ignore
+ public static class IgnoredClass {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void annotationsExistOnDescriptionsOfIgnoredClass() {
+ assertTrue((describe(IgnoredClass.class).getAnnotation(Ignore.class) != null));
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ValuedAnnotation {
+ String value();
+ }
+
+ @ValuedAnnotation("hello")
+ public static class ValueAnnotatedClass {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void descriptionOfTestClassHasValuedAnnotation() {
+ Description description = describe(ValueAnnotatedClass.class);
+ assertEquals("hello", description.getAnnotation(ValuedAnnotation.class)
+ .value());
+ }
+
+ @Test
+ public void childlessCopyOfDescriptionStillHasAnnotations() {
+ Description description = describe(ValueAnnotatedClass.class);
+ assertEquals("hello", description.childlessCopy().getAnnotation(ValuedAnnotation.class)
+ .value());
+ }
+
+ @Test
+ public void characterizeCreatingMyOwnAnnotation() {
+ Annotation annotation = new Ignore() {
+ public String value() {
+ return "message";
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return Ignore.class;
+ }
+ };
+
+ assertEquals(Ignore.class, annotation.annotationType());
+ }
+
+ private Description describe(Class<?> testClass) {
+ return Request.aClass(testClass).getRunner().getDescription();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/description/SuiteDescriptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/SuiteDescriptionTest.java
new file mode 100644
index 0000000..5b17d1e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/SuiteDescriptionTest.java
@@ -0,0 +1,38 @@
+package org.junit.tests.description;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+
+public class SuiteDescriptionTest {
+ Description childless = Description.createSuiteDescription("a");
+ Description anotherChildless = Description.createSuiteDescription("a");
+ Description namedB = Description.createSuiteDescription("b");
+
+ Description twoKids = descriptionWithTwoKids("foo", "bar");
+ Description anotherTwoKids = descriptionWithTwoKids("foo", "baz");
+
+ @Test
+ public void equalsIsCorrect() {
+ assertEquals(childless, anotherChildless);
+ assertFalse(childless.equals(namedB));
+ assertEquals(childless, twoKids);
+ assertEquals(twoKids, anotherTwoKids);
+ assertFalse(twoKids.equals(new Integer(5)));
+ }
+
+ @Test
+ public void hashCodeIsReasonable() {
+ assertEquals(childless.hashCode(), anotherChildless.hashCode());
+ assertFalse(childless.hashCode() == namedB.hashCode());
+ }
+
+ private Description descriptionWithTwoKids(String first, String second) {
+ Description twoKids = Description.createSuiteDescription("a");
+ twoKids.addChild(Description.createTestDescription(getClass(), first));
+ twoKids.addChild(Description.createTestDescription(getClass(), second));
+ return twoKids;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionMethodNameTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionMethodNameTest.java
new file mode 100644
index 0000000..21943e9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionMethodNameTest.java
@@ -0,0 +1,50 @@
+package org.junit.tests.description;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Dmitry Baev charlie@yandex-team.ru
+ * Date: 03.05.14
+ */
+@RunWith(Parameterized.class)
+public class TestDescriptionMethodNameTest {
+
+ private String methodName;
+
+ public TestDescriptionMethodNameTest(String methodName) {
+ this.methodName = methodName;
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> getMethodNames() {
+ return Arrays.asList(
+ new Object[]{"simple"},
+ new Object[]{"with space"},
+ new Object[]{"[]!@#$%^&*()"},
+ new Object[]{""},
+ new Object[]{"\t"},
+ new Object[]{"\n"},
+ new Object[]{"\r\n"},
+ new Object[]{"\r"},
+ new Object[]{"\u0085"},
+ new Object[]{"\u2028"},
+ new Object[]{"\u2029"}
+ );
+ }
+
+ @Test
+ public void methodNameTest() throws Exception {
+ Description description = Description.createTestDescription("some-class-name", methodName);
+ assertNotNull("Method name should be not null", description.getMethodName());
+ assertEquals(methodName, description.getMethodName());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionTest.java
new file mode 100644
index 0000000..3bc07f4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/description/TestDescriptionTest.java
@@ -0,0 +1,24 @@
+package org.junit.tests.description;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+
+public class TestDescriptionTest {
+ @Test
+ public void equalsIsFalseForNonTestDescription() {
+ assertFalse(Description.createTestDescription(getClass(), "a").equals(new Integer(5)));
+ }
+
+ @Test
+ public void equalsIsTrueForSameNameAndNoExplicitUniqueId() {
+ assertTrue(Description.createSuiteDescription("Hello").equals(Description.createSuiteDescription("Hello")));
+ }
+
+ @Test
+ public void equalsIsFalseForSameNameAndDifferentUniqueId() {
+ assertFalse(Description.createSuiteDescription("Hello", 2).equals(Description.createSuiteDescription("Hello", 3)));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AllExperimentalTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AllExperimentalTests.java
new file mode 100644
index 0000000..b20ae9d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AllExperimentalTests.java
@@ -0,0 +1,25 @@
+package org.junit.tests.experimental;
+
+import org.junit.experimental.categories.AllCategoriesTests;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.tests.experimental.max.AllMaxTests;
+import org.junit.tests.experimental.parallel.AllParallelTests;
+import org.junit.tests.experimental.results.AllResultsTests;
+import org.junit.tests.experimental.theories.AllTheoriesTests;
+import org.junit.tests.experimental.theories.extendingwithstubs.StubbedTheoriesTest;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllCategoriesTests.class,
+ AllMaxTests.class,
+ AllParallelTests.class,
+ AllResultsTests.class,
+ AllTheoriesTests.class,
+ AssumptionTest.class,
+ MatcherTest.class,
+ StubbedTheoriesTest.class
+})
+public class AllExperimentalTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AssumptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AssumptionTest.java
new file mode 100644
index 0000000..e011619
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/AssumptionTest.java
@@ -0,0 +1,312 @@
+package org.junit.tests.experimental;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assume;
+import org.junit.AssumptionViolatedException;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class AssumptionTest {
+ public static class HasFailingAssumption {
+ @Test
+ public void assumptionsFail() {
+ assumeThat(3, is(4));
+ fail();
+ }
+ }
+
+ @Test
+ public void failedAssumptionsMeanPassing() {
+ Result result = JUnitCore.runClasses(HasFailingAssumption.class);
+ assertThat(result.getRunCount(), is(1));
+ assertThat(result.getIgnoreCount(), is(0));
+ assertThat(result.getFailureCount(), is(0));
+ }
+
+ private static int assumptionFailures = 0;
+
+ @Test
+ public void failedAssumptionsCanBeDetectedByListeners() {
+ assumptionFailures = 0;
+ JUnitCore core = new JUnitCore();
+ core.addListener(new RunListener() {
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ assumptionFailures++;
+ }
+ });
+ core.run(HasFailingAssumption.class);
+
+ assertThat(assumptionFailures, is(1));
+ }
+
+ public static class HasPassingAssumption {
+ @Test
+ public void assumptionsFail() {
+ assumeThat(3, is(3));
+ fail();
+ }
+ }
+
+ @Test
+ public void passingAssumptionsScootThrough() {
+ Result result = JUnitCore.runClasses(HasPassingAssumption.class);
+ assertThat(result.getRunCount(), is(1));
+ assertThat(result.getIgnoreCount(), is(0));
+ assertThat(result.getFailureCount(), is(1));
+ }
+
+ @Test
+ public void assumeThatWorks() {
+ try {
+ assumeThat(1, is(2));
+ fail("should throw AssumptionViolatedException");
+ } catch (AssumptionViolatedException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assumeThatPasses() {
+ assumeThat(1, is(1));
+ assertCompletesNormally();
+ }
+
+ @Test
+ public void assumeThatPassesOnStrings() {
+ assumeThat("x", is("x"));
+ assertCompletesNormally();
+ }
+
+ @Test
+ public void assumeNotNullThrowsException() {
+ Object[] objects = {1, 2, null};
+ try {
+ assumeNotNull(objects);
+ fail("should throw AssumptionViolatedException");
+ } catch (AssumptionViolatedException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assumeNotNullThrowsExceptionForNullArray() {
+ try {
+ assumeNotNull((Object[]) null);
+ fail("should throw AssumptionViolatedException");
+ } catch (AssumptionViolatedException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void assumeNotNullPasses() {
+ Object[] objects = {1, 2};
+ assumeNotNull(objects);
+ assertCompletesNormally();
+ }
+
+ @Test
+ public void assumeNotNullIncludesParameterList() {
+ try {
+ Object[] objects = {1, 2, null};
+ assumeNotNull(objects);
+ } catch (AssumptionViolatedException e) {
+ assertThat(e.getMessage(), containsString("1, 2, null"));
+ } catch (Exception e) {
+ fail("Should have thrown AssumptionViolatedException");
+ }
+ }
+
+ @Test
+ public void assumeNoExceptionThrows() {
+ final Throwable exception = new NullPointerException();
+ try {
+ assumeNoException(exception);
+ fail("Should have thrown exception");
+ } catch (AssumptionViolatedException e) {
+ assertThat(e.getCause(), is(exception));
+ }
+ }
+
+ private void assertCompletesNormally() {
+ }
+
+ @Test
+ public void assumeTrueWorks() {
+ try {
+ Assume.assumeTrue(false);
+ fail("should throw AssumptionViolatedException");
+ } catch (AssumptionViolatedException e) {
+ assertEquals("got: <false>, expected: is <true>", e.getMessage());
+ }
+ }
+
+ @Test
+ public void assumeFalseWorks() {
+ try {
+ Assume.assumeFalse(true);
+ fail("should throw AssumptionViolatedException");
+ } catch (AssumptionViolatedException e) {
+ assertEquals("got: <true>, expected: is <false>", e.getMessage());
+ }
+ }
+
+ public static class HasFailingAssumeInBefore {
+ @Before
+ public void checkForSomethingThatIsntThere() {
+ assumeTrue(false);
+ }
+
+ @Test
+ public void failing() {
+ fail();
+ }
+ }
+
+ @Test
+ public void failingAssumptionInBeforePreventsTestRun() {
+ assertThat(testResult(HasFailingAssumeInBefore.class), isSuccessful());
+ }
+
+ public static class HasFailingAssumeInBeforeClass {
+ @BeforeClass
+ public static void checkForSomethingThatIsntThere() {
+ assumeTrue(false);
+ }
+
+ @Test
+ public void failing() {
+ fail();
+ }
+ }
+
+ @Test
+ public void failingAssumptionInBeforeClassIgnoresClass() {
+ assertThat(testResult(HasFailingAssumeInBeforeClass.class), isSuccessful());
+ }
+
+ public static class AssumptionFailureInConstructor {
+ public AssumptionFailureInConstructor() {
+ assumeTrue(false);
+ }
+
+ @Test
+ public void shouldFail() {
+ fail();
+ }
+ }
+
+ @Test
+ public void failingAssumptionInConstructorIgnoresClass() {
+ assertThat(testResult(AssumptionFailureInConstructor.class), isSuccessful());
+ }
+
+ public static class TestClassWithAssumptionFailure {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void assumeWithExpectedException() {
+ assumeTrue(false);
+ }
+ }
+
+ @Test
+ public void assumeWithExpectedExceptionShouldThrowAssumptionViolatedException() {
+ Result result = JUnitCore.runClasses(TestClassWithAssumptionFailure.class);
+ assertThat(result.getAssumptionFailureCount(), is(1));
+ }
+
+ static final String message = "Some random message string.";
+ static final Throwable e = new Throwable();
+
+ /**
+ * @see AssumptionTest#assumptionsWithMessage()
+ */
+ public static class HasAssumeWithMessage {
+ @Test
+ public void testMethod() {
+ assumeTrue(message, false);
+ }
+ }
+
+ @Test
+ public void assumptionsWithMessage() {
+ final List<Failure> failures =
+ runAndGetAssumptionFailures(HasAssumeWithMessage.class);
+
+ assertTrue(failures.get(0).getMessage().contains(message));
+ }
+
+ /**
+ * @see AssumptionTest#assumptionsWithMessageAndCause()
+ */
+ public static class HasAssumeWithMessageAndCause {
+ @Test
+ public void testMethod() {
+ assumeNoException(message, e);
+ }
+ }
+
+ @Test
+ public void assumptionsWithMessageAndCause() {
+ final List<Failure> failures =
+ runAndGetAssumptionFailures(HasAssumeWithMessageAndCause.class);
+ assertTrue(failures.get(0).getMessage().contains(message));
+ assertSame(failures.get(0).getException().getCause(), e);
+ }
+
+ public static class HasFailingAssumptionWithMessage {
+ @Test
+ public void assumptionsFail() {
+ assumeThat(message, 3, is(4));
+ fail();
+ }
+ }
+
+ @Test
+ public void failedAssumptionsWithMessage() {
+ final List<Failure> failures =
+ runAndGetAssumptionFailures(HasFailingAssumptionWithMessage.class);
+
+ assertEquals(1, failures.size());
+ assertTrue(failures.get(0).getMessage().contains(message));
+ }
+
+ /**
+ * Helper method that runs tests on <code>clazz</code> and returns any
+ * {@link Failure} objects that were {@link AssumptionViolatedException}s.
+ */
+ private static List<Failure> runAndGetAssumptionFailures(Class<?> clazz) {
+ final List<Failure> failures = new ArrayList<Failure>();
+ final JUnitCore core = new JUnitCore();
+ core.addListener(new RunListener() {
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ failures.add(failure);
+ }
+ });
+ core.run(clazz);
+ return failures;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/MatcherTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/MatcherTest.java
new file mode 100644
index 0000000..10f13a4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/MatcherTest.java
@@ -0,0 +1,44 @@
+package org.junit.tests.experimental;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeThat;
+import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+
+import java.util.Arrays;
+
+import org.hamcrest.Matcher;
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+
+@RunWith(Theories.class)
+public class MatcherTest {
+ @DataPoint
+ public static Matcher<Object> SINGLE_FAILURE = hasSingleFailureContaining("cheese");
+
+ @DataPoint
+ public static Matcher<PrintableResult> ANY_FAILURE = hasFailureContaining("cheese");
+
+ @DataPoint
+ public static PrintableResult TWO_FAILURES_ONE_CHEESE = new PrintableResult(
+ Arrays.asList(failure("cheese"), failure("mustard")));
+
+ @Theory
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void differentMatchersHaveDifferentDescriptions(
+ Matcher matcher1, Matcher matcher2, Object value) {
+ assumeThat(value, matcher1);
+ assumeThat(value, not(matcher2));
+ assertThat(matcher1.toString(), not(matcher2.toString()));
+ }
+
+ private static Failure failure(String string) {
+ return new Failure(Description.EMPTY, new Error(string));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/AllMaxTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/AllMaxTests.java
new file mode 100644
index 0000000..d78ca36
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/AllMaxTests.java
@@ -0,0 +1,14 @@
+package org.junit.tests.experimental.max;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ DescriptionTest.class,
+ JUnit38SortingTest.class,
+ MaxStarterTest.class
+})
+public class AllMaxTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/DescriptionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/DescriptionTest.java
new file mode 100644
index 0000000..607bb81
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/DescriptionTest.java
@@ -0,0 +1,123 @@
+package org.junit.tests.experimental.max;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.Description;
+
+public class DescriptionTest {
+
+ @Test
+ public void parseClass_whenCantParse() {
+ assertNull(Description.TEST_MECHANISM.getTestClass());
+ }
+
+ @Test
+ public void parseMethod_whenCantParse() {
+ assertNull(Description.TEST_MECHANISM.getMethodName());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void createSuiteDescription_whenZeroLength() {
+ Description.createSuiteDescription("");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void createSuiteDescription_whenNull() {
+ Description.createSuiteDescription((String) null);
+ }
+
+ @Test
+ public void parseClassAndMethodNoAnnotations() throws Exception {
+ Description description = Description.createTestDescription(Description.class, "aTestMethod");
+
+ assertThat(description.getClassName(), equalTo("org.junit.runner.Description"));
+ assertThat(description.getMethodName(), equalTo("aTestMethod"));
+ assertThat(description.getAnnotations().size(), equalTo(0));
+ }
+
+ @Test
+ public void parseClassAndMethodWithAnnotations() throws Exception {
+ Annotation[] annotations =
+ DescriptionTest.class.getMethod("parseClassAndMethodWithAnnotations").getDeclaredAnnotations();
+
+ Description description = Description.createTestDescription(Description.class, "aTestMethod", annotations);
+
+ assertThat(description.getClassName(), equalTo("org.junit.runner.Description"));
+ assertThat(description.getMethodName(), equalTo("aTestMethod"));
+ assertThat(description.getAnnotations().size(), equalTo(1));
+ }
+
+ @Test
+ public void parseClassNameAndMethodUniqueId() throws Exception {
+ Description description = Description.createTestDescription("not a class name", "aTestMethod", 123);
+
+ assertThat(description.getClassName(), equalTo("not a class name"));
+ assertThat(description.getMethodName(), equalTo("aTestMethod"));
+ assertThat(description.getAnnotations().size(), equalTo(0));
+ }
+
+ @Test
+ public void sameNamesButDifferentUniqueIdAreNotEqual() throws Exception {
+ assertThat(Description.createTestDescription("not a class name", "aTestMethod", 1),
+ not(equalTo(Description.createTestDescription("not a class name", "aTestMethod", 2))));
+ }
+
+ @Test
+ public void usesPassedInClassObject() throws Exception {
+ class URLClassLoader2 extends URLClassLoader {
+ URLClassLoader2(URL... urls) {
+ super(urls);
+ }
+
+ @Override // just making public
+ public Class<?> findClass(String name) throws ClassNotFoundException {
+ return super.findClass(name);
+ }
+ }
+ URL classpath = Sweet.class.getProtectionDomain().getCodeSource().getLocation();
+ URLClassLoader2 loader = new URLClassLoader2(classpath);
+ Class<?> clazz = loader.findClass(Sweet.class.getName());
+ assertEquals(loader, clazz.getClassLoader());
+
+ Description d = Description.createSuiteDescription(clazz);
+ assertEquals(clazz, d.getTestClass());
+ assertNull(d.getMethodName());
+ assertEquals(1, d.getAnnotations().size());
+ assertEquals(Ignore.class, d.getAnnotations().iterator().next().annotationType());
+
+ d = Description.createTestDescription(clazz, "tessed");
+ assertEquals(clazz, d.getTestClass());
+ assertEquals("tessed", d.getMethodName());
+ assertEquals(0, d.getAnnotations().size());
+
+ d = Description.createTestDescription(clazz, "tessed", clazz.getMethod("tessed").getAnnotations());
+ assertEquals(clazz, d.getTestClass());
+ assertEquals("tessed", d.getMethodName());
+ assertEquals(1, d.getAnnotations().size());
+ assertEquals(Test.class, d.getAnnotations().iterator().next().annotationType());
+
+ d = d.childlessCopy();
+ assertEquals(clazz, d.getTestClass());
+ assertEquals("tessed", d.getMethodName());
+ assertEquals(1, d.getAnnotations().size());
+ assertEquals(Test.class, d.getAnnotations().iterator().next().annotationType());
+ }
+
+ @Ignore
+ private static class Sweet {
+ @Test
+ public void tessed() {
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/JUnit38SortingTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/JUnit38SortingTest.java
new file mode 100644
index 0000000..0d893fb
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/JUnit38SortingTest.java
@@ -0,0 +1,62 @@
+package org.junit.tests.experimental.max;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.util.List;
+
+import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.max.MaxCore;
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+
+public class JUnit38SortingTest {
+ private MaxCore fMax;
+ private File fMaxFile;
+
+ @Before
+ public void createMax() {
+ fMaxFile = new File("MaxCore.ser");
+ if (fMaxFile.exists()) {
+ fMaxFile.delete();
+ }
+ fMax = MaxCore.storedLocally(fMaxFile);
+ }
+
+ @After
+ public void forgetMax() {
+ fMaxFile.delete();
+ }
+
+ public static class JUnit4Test {
+ @Test
+ public void pass() {
+ }
+ }
+
+ public static class JUnit38Test extends TestCase {
+ public void testFails() {
+ fail();
+ }
+
+ public void testSucceeds() {
+ }
+
+ public void testSucceedsToo() {
+ }
+ }
+
+ @Test
+ public void preferRecentlyFailed38Test() {
+ Request request = Request.classes(JUnit4Test.class, JUnit38Test.class);
+ fMax.run(request);
+ List<Description> tests = fMax.sortedLeavesForTest(request);
+ Description dontSucceed = Description.createTestDescription(
+ JUnit38Test.class, "testFails");
+ assertEquals(dontSucceed, tests.get(0));
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/MaxStarterTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/MaxStarterTest.java
new file mode 100644
index 0000000..d1bde45
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/max/MaxStarterTest.java
@@ -0,0 +1,292 @@
+package org.junit.tests.experimental.max;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.max.MaxCore;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Computer;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.tests.AllTests;
+
+public class MaxStarterTest {
+ private MaxCore fMax;
+
+ private File fMaxFile;
+
+ @Before
+ public void createMax() {
+ fMaxFile = new File("MaxCore.ser");
+ if (fMaxFile.exists()) {
+ fMaxFile.delete();
+ }
+ fMax = MaxCore.storedLocally(fMaxFile);
+ }
+
+ @After
+ public void forgetMax() {
+ fMaxFile.delete();
+ }
+
+ public static class TwoTests {
+ @Test
+ public void succeed() {
+ }
+
+ @Test
+ public void dontSucceed() {
+ fail();
+ }
+ }
+
+ @Test
+ public void twoTestsNotRunComeBackInRandomOrder() {
+ Request request = Request.aClass(TwoTests.class);
+ List<Description> things = fMax.sortedLeavesForTest(request);
+ Description succeed = Description.createTestDescription(TwoTests.class,
+ "succeed");
+ Description dontSucceed = Description.createTestDescription(
+ TwoTests.class, "dontSucceed");
+ assertTrue(things.contains(succeed));
+ assertTrue(things.contains(dontSucceed));
+ assertEquals(2, things.size());
+ }
+
+ @Test
+ public void preferNewTests() {
+ Request one = Request.method(TwoTests.class, "succeed");
+ fMax.run(one);
+ Request two = Request.aClass(TwoTests.class);
+ List<Description> things = fMax.sortedLeavesForTest(two);
+ Description dontSucceed = Description.createTestDescription(
+ TwoTests.class, "dontSucceed");
+ assertEquals(dontSucceed, things.get(0));
+ assertEquals(2, things.size());
+ }
+
+ // This covers a seemingly-unlikely case, where you had a test that failed
+ // on the
+ // last run and you also introduced new tests. In such a case it pretty much
+ // doesn't matter
+ // which order they run, you just want them both to be early in the sequence
+ @Test
+ public void preferNewTestsOverTestsThatFailed() {
+ Request one = Request.method(TwoTests.class, "dontSucceed");
+ fMax.run(one);
+ Request two = Request.aClass(TwoTests.class);
+ List<Description> things = fMax.sortedLeavesForTest(two);
+ Description succeed = Description.createTestDescription(TwoTests.class,
+ "succeed");
+ assertEquals(succeed, things.get(0));
+ assertEquals(2, things.size());
+ }
+
+ @Test
+ public void preferRecentlyFailed() {
+ Request request = Request.aClass(TwoTests.class);
+ fMax.run(request);
+ List<Description> tests = fMax.sortedLeavesForTest(request);
+ Description dontSucceed = Description.createTestDescription(
+ TwoTests.class, "dontSucceed");
+ assertEquals(dontSucceed, tests.get(0));
+ }
+
+ @Test
+ public void sortTestsInMultipleClasses() {
+ Request request = Request.classes(Computer.serial(), TwoTests.class,
+ TwoTests.class);
+ fMax.run(request);
+ List<Description> tests = fMax.sortedLeavesForTest(request);
+ Description dontSucceed = Description.createTestDescription(
+ TwoTests.class, "dontSucceed");
+ assertEquals(dontSucceed, tests.get(0));
+ assertEquals(dontSucceed, tests.get(1));
+ }
+
+ public static class TwoUnEqualTests {
+ @Test
+ public void slow() throws InterruptedException {
+ Thread.sleep(100);
+ fail();
+ }
+
+ @Test
+ public void fast() {
+ fail();
+ }
+
+ }
+
+ @Test
+ public void rememberOldRuns() {
+ fMax.run(TwoUnEqualTests.class);
+
+ MaxCore reincarnation = MaxCore.storedLocally(fMaxFile);
+ List<Failure> failures = reincarnation.run(TwoUnEqualTests.class)
+ .getFailures();
+ assertEquals("fast", failures.get(0).getDescription().getMethodName());
+ assertEquals("slow", failures.get(1).getDescription().getMethodName());
+ }
+
+ @Test
+ public void preferFast() {
+ Request request = Request.aClass(TwoUnEqualTests.class);
+ fMax.run(request);
+ Description thing = fMax.sortedLeavesForTest(request).get(1);
+ assertEquals(Description.createTestDescription(TwoUnEqualTests.class,
+ "slow"), thing);
+ }
+
+ @Test
+ public void listenersAreCalledCorrectlyInTheFaceOfFailures()
+ throws Exception {
+ JUnitCore core = new JUnitCore();
+ final List<Failure> failures = new ArrayList<Failure>();
+ core.addListener(new RunListener() {
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ failures.addAll(result.getFailures());
+ }
+ });
+ fMax.run(Request.aClass(TwoTests.class), core);
+ assertEquals(1, failures.size());
+ }
+
+ @Test
+ public void testsAreOnlyIncludedOnceWhenExpandingForSorting()
+ throws Exception {
+ Result result = fMax.run(Request.aClass(TwoTests.class));
+ assertEquals(2, result.getRunCount());
+ }
+
+ public static class TwoOldTests extends TestCase {
+ public void testOne() {
+ }
+
+ public void testTwo() {
+ }
+ }
+
+ @Test
+ public void junit3TestsAreRunOnce() throws Exception {
+ Result result = fMax.run(Request.aClass(TwoOldTests.class),
+ new JUnitCore());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @Test
+ public void filterSingleMethodFromOldTestClass() throws Exception {
+ final Description method = Description.createTestDescription(
+ TwoOldTests.class, "testOne");
+ Filter filter = Filter.matchMethodDescription(method);
+ JUnit38ClassRunner child = new JUnit38ClassRunner(TwoOldTests.class);
+ child.filter(filter);
+ assertEquals(1, child.testCount());
+ }
+
+ @Test
+ public void testCountsStandUpToFiltration() {
+ assertFilterLeavesTestUnscathed(AllTests.class);
+ }
+
+ private void assertFilterLeavesTestUnscathed(Class<?> testClass) {
+ Request oneClass = Request.aClass(testClass);
+ Request filtered = oneClass.filterWith(new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return true;
+ }
+
+ @Override
+ public String describe() {
+ return "Everything";
+ }
+ });
+
+ int filterCount = filtered.getRunner().testCount();
+ int coreCount = oneClass.getRunner().testCount();
+ assertEquals("Counts match up in " + testClass, coreCount, filterCount);
+ }
+
+ private static class MalformedJUnit38Test {
+ private MalformedJUnit38Test() {
+ }
+
+ @SuppressWarnings("unused")
+ public void testSucceeds() {
+ }
+ }
+
+ @Test
+ public void maxShouldSkipMalformedJUnit38Classes() {
+ Request request = Request.aClass(MalformedJUnit38Test.class);
+ fMax.run(request);
+ }
+
+ public static class MalformedJUnit38TestMethod extends TestCase {
+ @SuppressWarnings("unused")
+ private void testNothing() {
+ }
+ }
+
+ @Test
+ public void correctErrorFromMalformedTest() {
+ Request request = Request.aClass(MalformedJUnit38TestMethod.class);
+ JUnitCore core = new JUnitCore();
+ Request sorted = fMax.sortRequest(request);
+ Runner runner = sorted.getRunner();
+ Result result = core.run(runner);
+ Failure failure = result.getFailures().get(0);
+ assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod"));
+ assertThat(failure.toString(), containsString("testNothing"));
+ assertThat(failure.toString(), containsString("isn't public"));
+ }
+
+ public static class HalfMalformedJUnit38TestMethod extends TestCase {
+ public void testSomething() {
+ }
+
+ @SuppressWarnings("unused")
+ private void testNothing() {
+ }
+ }
+
+ @Test
+ public void halfMalformed() {
+ assertThat(JUnitCore.runClasses(HalfMalformedJUnit38TestMethod.class)
+ .getFailureCount(), is(1));
+ }
+
+
+ @Test
+ public void correctErrorFromHalfMalformedTest() {
+ Request request = Request.aClass(HalfMalformedJUnit38TestMethod.class);
+ JUnitCore core = new JUnitCore();
+ Request sorted = fMax.sortRequest(request);
+ Runner runner = sorted.getRunner();
+ Result result = core.run(runner);
+ Failure failure = result.getFailures().get(0);
+ assertThat(failure.toString(), containsString("MalformedJUnit38TestMethod"));
+ assertThat(failure.toString(), containsString("testNothing"));
+ assertThat(failure.toString(), containsString("isn't public"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/AllParallelTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/AllParallelTests.java
new file mode 100644
index 0000000..ef21dd2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/AllParallelTests.java
@@ -0,0 +1,13 @@
+package org.junit.tests.experimental.parallel;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ParallelClassTest.class,
+ ParallelMethodTest.class
+})
+public class AllParallelTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelClassTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelClassTest.java
new file mode 100644
index 0000000..86a2646
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelClassTest.java
@@ -0,0 +1,79 @@
+package org.junit.tests.experimental.parallel;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.ParallelComputer;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class ParallelClassTest {
+ private static final long TIMEOUT = 15;
+ private static volatile Thread fExample1One = null;
+ private static volatile Thread fExample1Two = null;
+ private static volatile Thread fExample2One = null;
+ private static volatile Thread fExample2Two = null;
+ private static volatile CountDownLatch fSynchronizer;
+
+ public static class Example1 {
+ @Test
+ public void one() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fExample1One = Thread.currentThread();
+ }
+
+ @Test
+ public void two() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fExample1Two = Thread.currentThread();
+ }
+ }
+
+ public static class Example2 {
+ @Test
+ public void one() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fExample2One = Thread.currentThread();
+ }
+
+ @Test
+ public void two() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fExample2Two = Thread.currentThread();
+ }
+ }
+
+ @Before
+ public void init() {
+ fExample1One = null;
+ fExample1Two = null;
+ fExample2One = null;
+ fExample2Two = null;
+ fSynchronizer = new CountDownLatch(2);
+ }
+
+ @Test
+ public void testsRunInParallel() {
+ Result result = JUnitCore.runClasses(ParallelComputer.classes(), Example1.class, Example2.class);
+ assertTrue(result.wasSuccessful());
+ assertNotNull(fExample1One);
+ assertNotNull(fExample1Two);
+ assertNotNull(fExample2One);
+ assertNotNull(fExample2Two);
+ assertThat(fExample1One, is(fExample1Two));
+ assertThat(fExample2One, is(fExample2Two));
+ assertThat(fExample1One, is(not(fExample2One)));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelMethodTest.java
new file mode 100644
index 0000000..fd4b4de
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/parallel/ParallelMethodTest.java
@@ -0,0 +1,61 @@
+package org.junit.tests.experimental.parallel;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.ParallelComputer;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class ParallelMethodTest {
+ private static final long TIMEOUT = 15;
+ private static volatile Thread fOne = null;
+ private static volatile Thread fTwo = null;
+
+ public static class Example {
+ private static volatile CountDownLatch fSynchronizer;
+
+ @BeforeClass
+ public static void init() {
+ fSynchronizer = new CountDownLatch(2);
+ }
+
+ @Test
+ public void one() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fOne = Thread.currentThread();
+ }
+
+ @Test
+ public void two() throws InterruptedException {
+ fSynchronizer.countDown();
+ assertTrue(fSynchronizer.await(TIMEOUT, TimeUnit.SECONDS));
+ fTwo = Thread.currentThread();
+ }
+ }
+
+ @Before
+ public void init() {
+ fOne = null;
+ fTwo = null;
+ }
+
+ @Test
+ public void testsRunInParallel() {
+ Result result = JUnitCore.runClasses(ParallelComputer.methods(), Example.class);
+ assertTrue(result.wasSuccessful());
+ assertNotNull(fOne);
+ assertNotNull(fTwo);
+ assertThat(fOne, is(not(fTwo)));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/AllResultsTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/AllResultsTests.java
new file mode 100644
index 0000000..f197569
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/AllResultsTests.java
@@ -0,0 +1,13 @@
+package org.junit.tests.experimental.results;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ PrintableResultTest.class,
+ ResultMatchersTest.class
+})
+public class AllResultsTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/PrintableResultTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/PrintableResultTest.java
new file mode 100644
index 0000000..3a6e366
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/PrintableResultTest.java
@@ -0,0 +1,50 @@
+package org.junit.tests.experimental.results;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Arrays;
+
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+
+@RunWith(Theories.class)
+public class PrintableResultTest {
+ @Theory(nullsAccepted = false)
+ public void backTraceHasGoodToString(String descriptionName,
+ final String stackTraceClassName) {
+ Failure failure = new Failure(Description
+ .createSuiteDescription(descriptionName), new Throwable() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public StackTraceElement[] getStackTrace() {
+ return new StackTraceElement[]{new StackTraceElement(
+ stackTraceClassName, "methodName", "fileName", 1)};
+ }
+ });
+
+ assertThat(new PrintableResult(asList(failure)).toString(), allOf(
+ containsString(descriptionName), containsString(stackTraceClassName)));
+ }
+
+ @DataPoint
+ public static String SHELL_POINT = "Shell Point";
+
+ @Theory
+ public void includeMultipleFailures(String secondExceptionName) {
+ PrintableResult backtrace = new PrintableResult(Arrays.asList(
+ new Failure(Description.createSuiteDescription("firstName"),
+ new RuntimeException("firstException")), new Failure(
+ Description.createSuiteDescription("secondName"),
+ new RuntimeException(secondExceptionName))));
+ assertThat(backtrace.toString(), containsString(secondExceptionName));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/ResultMatchersTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/ResultMatchersTest.java
new file mode 100644
index 0000000..768bfba
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/results/ResultMatchersTest.java
@@ -0,0 +1,46 @@
+package org.junit.tests.experimental.results;
+
+import org.junit.Test;
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.results.ResultMatchers;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class ResultMatchersTest {
+
+ @Test
+ public void hasFailuresHasGoodDescription() {
+ assertThat(ResultMatchers.failureCountIs(3).toString(),
+ is("has 3 failures"));
+ }
+
+ @Theory
+ public void hasFailuresDescriptionReflectsInput(int i) {
+ assertThat(ResultMatchers.failureCountIs(i).toString(),
+ containsString("" + i));
+ }
+
+ @Test
+ public void hasFailureContaining_givenResultWithNoFailures() {
+ PrintableResult resultWithNoFailures = new PrintableResult(new ArrayList<Failure>());
+
+ assertThat(ResultMatchers.hasFailureContaining("").matches(resultWithNoFailures), is(false));
+ }
+
+ @Test
+ public void hasFailureContaining_givenResultWithOneFailure() {
+ PrintableResult resultWithOneFailure = new PrintableResult(Collections.singletonList(
+ new Failure(Description.EMPTY, new RuntimeException("my failure"))));
+
+ assertThat(ResultMatchers.hasFailureContaining("my failure").matches(resultWithOneFailure), is(true));
+ assertThat(ResultMatchers.hasFailureContaining("his failure").matches(resultWithOneFailure), is(false));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AllTheoriesTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AllTheoriesTests.java
new file mode 100644
index 0000000..41d653b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AllTheoriesTests.java
@@ -0,0 +1,19 @@
+package org.junit.tests.experimental.theories;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.tests.experimental.theories.internal.AllTheoriesInternalTests;
+import org.junit.tests.experimental.theories.runner.AllTheoriesRunnerTests;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllTheoriesInternalTests.class,
+ AllTheoriesRunnerTests.class,
+ ParameterSignatureTest.class,
+ TestedOnSupplierTest.class,
+ AssumingInTheoriesTest.class,
+ PotentialAssignmentTest.class
+})
+public class AllTheoriesTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java
new file mode 100644
index 0000000..099b50f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java
@@ -0,0 +1,42 @@
+package org.junit.tests.experimental.theories;
+
+import static org.junit.tests.experimental.theories.TheoryTestUtils.runTheoryClass;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+@RunWith(Theories.class)
+public class AssumingInTheoriesTest {
+
+ @Test
+ public void noTheoryAnnotationMeansAssumeShouldIgnore() {
+ Assume.assumeTrue(false);
+ }
+
+ @Test
+ public void theoryMeansOnlyAssumeShouldFail() throws InitializationError {
+ Result result = runTheoryClass(TheoryWithNoUnassumedParameters.class);
+ Assert.assertEquals(1, result.getFailureCount());
+ }
+
+ /**
+ * Simple class that SHOULD fail because no parameters are met.
+ */
+ public static class TheoryWithNoUnassumedParameters {
+
+ @DataPoint
+ public static final boolean FALSE = false;
+
+ @Theory
+ public void theoryWithNoUnassumedParameters(boolean value) {
+ Assume.assumeTrue(value);
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/ParameterSignatureTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/ParameterSignatureTest.java
new file mode 100644
index 0000000..cf786ba
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/ParameterSignatureTest.java
@@ -0,0 +1,92 @@
+package org.junit.tests.experimental.theories;
+
+import static org.hamcrest.CoreMatchers.isA;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.experimental.theories.suppliers.TestedOn;
+import org.junit.runner.RunWith;
+
+@RunWith(Theories.class)
+public class ParameterSignatureTest {
+ @DataPoint
+ public static Method getType() throws SecurityException,
+ NoSuchMethodException {
+ return ParameterSignatureTest.class.getMethod("getType", Method.class,
+ int.class);
+ }
+
+ @DataPoint
+ public static int ZERO = 0;
+
+ @DataPoint
+ public static int ONE = 1;
+
+ @Theory
+ public void getType(Method method, int index) {
+ assumeTrue(index < method.getParameterTypes().length);
+ assertEquals(method.getParameterTypes()[index], ParameterSignature
+ .signatures(method).get(index).getType());
+ }
+
+ public void foo(@TestedOn(ints = {1, 2, 3}) int x) {
+ }
+
+ @Test
+ public void getAnnotations() throws SecurityException,
+ NoSuchMethodException {
+ Method method = getClass().getMethod("foo", int.class);
+ List<Annotation> annotations = ParameterSignature.signatures(method)
+ .get(0).getAnnotations();
+ assertThat(annotations,
+ CoreMatchers.<TestedOn>hasItem(isA(TestedOn.class)));
+ }
+
+ public void intMethod(int param) {
+ }
+
+ public void integerMethod(Integer param) {
+ }
+
+ public void numberMethod(Number param) {
+ }
+
+ @Test
+ public void primitiveTypesShouldBeAcceptedAsWrapperTypes() throws Exception {
+ List<ParameterSignature> signatures = ParameterSignature
+ .signatures(getClass().getMethod("integerMethod", Integer.class));
+ ParameterSignature integerSignature = signatures.get(0);
+
+ assertTrue(integerSignature.canAcceptType(int.class));
+ }
+
+ @Test
+ public void primitiveTypesShouldBeAcceptedAsWrapperTypeAssignables() throws Exception {
+ List<ParameterSignature> signatures = ParameterSignature
+ .signatures(getClass().getMethod("numberMethod", Number.class));
+ ParameterSignature numberSignature = signatures.get(0);
+
+ assertTrue(numberSignature.canAcceptType(int.class));
+ }
+
+ @Test
+ public void wrapperTypesShouldBeAcceptedAsPrimitiveTypes() throws Exception {
+ List<ParameterSignature> signatures = ParameterSignature
+ .signatures(getClass().getMethod("intMethod", int.class));
+ ParameterSignature intSignature = signatures.get(0);
+
+ assertTrue(intSignature.canAcceptType(Integer.class));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/PotentialAssignmentTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/PotentialAssignmentTest.java
new file mode 100644
index 0000000..45071ed
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/PotentialAssignmentTest.java
@@ -0,0 +1,57 @@
+package org.junit.tests.experimental.theories;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException;
+
+public class PotentialAssignmentTest {
+
+ @Test
+ public void shouldUseQuotedValueInDescription() throws CouldNotGenerateValueException {
+ String name = "stringDatapoint";
+ Object value = new Object() {
+ @Override
+ public String toString() {
+ return "string value";
+ }
+ };
+
+ PotentialAssignment assignment = PotentialAssignment.forValue(name, value);
+
+ assertEquals("\"string value\" <from stringDatapoint>", assignment.getDescription());
+ }
+
+ @Test
+ public void shouldNotUseQuotesForNullValueDescriptions() throws CouldNotGenerateValueException {
+ String name = "nullDatapoint";
+ Object value = null;
+
+ PotentialAssignment assignment = PotentialAssignment.forValue(name, value);
+
+ assertEquals("null <from nullDatapoint>", assignment.getDescription());
+ }
+
+ @Test
+ public void shouldIncludeFailureInDescriptionIfToStringFails() throws CouldNotGenerateValueException {
+ String name = "explodingValue";
+ Object value = new Object() {
+ @Override
+ public String toString() {
+ throw new RuntimeException("Oh no!");
+ }
+ };
+
+ PotentialAssignment assignment = PotentialAssignment.forValue(name, value);
+
+ assertEquals("[toString() threw RuntimeException: Oh no!] <from explodingValue>", assignment.getDescription());
+ }
+
+ @Test
+ public void shouldReturnGivenValue() throws CouldNotGenerateValueException {
+ Object value = new Object();
+ PotentialAssignment assignment = PotentialAssignment.forValue("name", value);
+ assertEquals(value, assignment.getValue());
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TestedOnSupplierTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TestedOnSupplierTest.java
new file mode 100644
index 0000000..1376171
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TestedOnSupplierTest.java
@@ -0,0 +1,32 @@
+package org.junit.tests.experimental.theories;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.suppliers.TestedOn;
+import org.junit.experimental.theories.suppliers.TestedOnSupplier;
+
+public class TestedOnSupplierTest {
+
+ public void foo(@TestedOn(ints = {1}) int x) {
+ }
+
+ @Test
+ public void descriptionStatesParameterName() throws Exception {
+ TestedOnSupplier supplier = new TestedOnSupplier();
+ List<PotentialAssignment> assignments = supplier.getValueSources(signatureOfFoo());
+ assertThat(assignments.get(0).getDescription(), is("\"1\" <from ints>"));
+ }
+
+ private ParameterSignature signatureOfFoo() throws NoSuchMethodException {
+ Method method = getClass().getMethod("foo", int.class);
+ return ParameterSignature.signatures(method).get(0);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TheoryTestUtils.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TheoryTestUtils.java
new file mode 100644
index 0000000..6e1b351
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/TheoryTestUtils.java
@@ -0,0 +1,33 @@
+package org.junit.tests.experimental.theories;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.internal.Assignments;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.TestClass;
+
+public final class TheoryTestUtils {
+
+ private TheoryTestUtils() { }
+
+ public static List<PotentialAssignment> potentialAssignments(Method method)
+ throws Throwable {
+ return Assignments.allUnassigned(method,
+ new TestClass(method.getDeclaringClass()))
+ .potentialsForNextUnassigned();
+ }
+
+ public static Result runTheoryClass(Class<?> testClass) throws InitializationError {
+ Runner theoryRunner = new Theories(testClass);
+ Request request = Request.runner(theoryRunner);
+ return new JUnitCore().run(request);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Correspondent.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Correspondent.java
new file mode 100644
index 0000000..81297b5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Correspondent.java
@@ -0,0 +1,7 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+public interface Correspondent {
+
+ String getAnswer(String question, String... bucket);
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Guesser.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Guesser.java
new file mode 100644
index 0000000..e57a3b3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Guesser.java
@@ -0,0 +1,126 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Random;
+
+import org.hamcrest.BaseDescription;
+import org.hamcrest.Description;
+import org.junit.internal.AssumptionViolatedException;
+
+public class Guesser<T> extends ReguessableValue {
+ static class GuessMap extends HashMap<MethodCall, Object> implements
+ InvocationHandler {
+ private static final long serialVersionUID = 1L;
+
+ public GuessMap(GuessMap guesses) {
+ super(guesses);
+ }
+
+ public GuessMap() {
+ }
+
+ GuessMap replaceGuess(Object oldValue, Object newValue) {
+ GuessMap newGuesses = new GuessMap(this);
+ for (Entry<MethodCall, Object> entry : newGuesses.entrySet()) {
+ if (entry.getValue().equals(oldValue)) {
+ entry.setValue(newValue);
+ }
+ }
+ return newGuesses;
+ }
+
+ protected Object generateGuess(Class<?> returnType) {
+ if (returnType.equals(String.class)) {
+ return "GUESS" + new Random().nextInt();
+ }
+ if (returnType.equals(Integer.class)
+ || returnType.equals(int.class)) {
+ return new Random().nextInt();
+ }
+ return null;
+ }
+
+ Object getGuess(MethodCall call) {
+ if (!containsKey(call)) {
+ put(call, generateGuess(call.getReturnType()));
+ }
+ return get(call);
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return getGuess(new MethodCall(method, args));
+ }
+ }
+
+ private final GuessMap guesses;
+
+ private final Class<? extends T> type;
+
+ public Guesser(Class<? extends T> type) {
+ this(type, new GuessMap());
+ }
+
+ public Guesser(Class<? extends T> type2, GuessMap guesses) {
+ this.type = type2;
+ this.guesses = guesses;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getProxy() {
+ return (T) Proxy.newProxyInstance(getClass().getClassLoader(),
+ new Class[]{getType()}, guesses);
+ }
+
+ @Override
+ public List<ReguessableValue> reguesses(AssumptionViolatedException e) {
+ final ArrayList<ReguessableValue> returnThis = new ArrayList<ReguessableValue>();
+ e.describeTo(new BaseDescription() {
+ @Override
+ protected void append(char arg0) {
+ }
+
+ boolean expectedSeen = false;
+ Object expected = null;
+
+ @Override
+ public Description appendValue(Object value) {
+ noteValue(value);
+ return super.appendValue(value);
+ }
+
+ private void noteValue(Object value) {
+ if (!expectedSeen) {
+ expected = value;
+ expectedSeen = true;
+ return;
+ }
+
+ GuessMap newGuesses = guesses.replaceGuess(expected, value);
+ returnThis.add(new Guesser<T>(getType(), newGuesses));
+ }
+ });
+ return returnThis;
+ }
+
+ @Override
+ public Object getValue() throws CouldNotGenerateValueException {
+ return getProxy();
+ }
+
+ public Class<? extends T> getType() {
+ return type;
+ }
+
+ @Override
+ public String getDescription() throws CouldNotGenerateValueException {
+ return "guesser[" + type + "]";
+ }
+
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/GuesserQueue.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/GuesserQueue.java
new file mode 100644
index 0000000..2722631
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/GuesserQueue.java
@@ -0,0 +1,58 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.internal.AssumptionViolatedException;
+
+public class GuesserQueue extends ArrayList<ReguessableValue> {
+ static class ReguessableDecorator extends ReguessableValue {
+ private final PotentialAssignment delegate;
+
+ public ReguessableDecorator(PotentialAssignment delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public List<ReguessableValue> reguesses(AssumptionViolatedException e) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Object getValue() throws CouldNotGenerateValueException {
+ return delegate.getValue();
+ }
+
+ @Override
+ public String getDescription() throws CouldNotGenerateValueException {
+ return delegate.getDescription();
+ }
+ }
+
+ static GuesserQueue forSingleValues(
+ List<PotentialAssignment> potentials) {
+ GuesserQueue returnThis = new GuesserQueue();
+ for (PotentialAssignment potentialParameterValue : potentials) {
+ returnThis
+ .add(new GuesserQueue.ReguessableDecorator(potentialParameterValue));
+ }
+ return returnThis;
+ }
+
+ private static final long serialVersionUID = 1L;
+ private ReguessableValue lastRemoved;
+
+ public void update(AssumptionViolatedException e) {
+ if (lastRemoved != null) {
+ addAll(lastRemoved.reguesses(e));
+ }
+ }
+
+ @Override
+ public ReguessableValue remove(int index) {
+ lastRemoved = super.remove(index);
+ return lastRemoved;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/MethodCall.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/MethodCall.java
new file mode 100644
index 0000000..b79ac2b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/MethodCall.java
@@ -0,0 +1,55 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MethodCall {
+ private final Method method;
+ private final Object[] args;
+
+ public MethodCall(Method method, Object... args) {
+ this.method = method;
+ this.args = args;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ MethodCall call = (MethodCall) obj;
+ return call.method.equals(method) && Arrays.deepEquals(call.args, args);
+ }
+
+ @Override
+ public int hashCode() {
+ return 1;
+ }
+
+ public Class<?> getReturnType() {
+ return method.getReturnType();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s(%s)", method.getName(), argListString());
+ }
+
+ private String argListString() {
+ if (args == null) {
+ return null;
+ }
+ return argList().toString().substring(1, argList().toString().length() - 1);
+ }
+
+ private List<Object> argList() {
+ ArrayList<Object> list = new ArrayList<Object>();
+ for (Object arg : args) {
+ list.add(new StringableObject(arg));
+ }
+ return list;
+ }
+
+ public Object stringableObject(Object arg) {
+ return new StringableObject(arg).stringableObject();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/ReguessableValue.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/ReguessableValue.java
new file mode 100644
index 0000000..6c1fe75
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/ReguessableValue.java
@@ -0,0 +1,16 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.util.List;
+
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.internal.AssumptionViolatedException;
+
+public abstract class ReguessableValue extends PotentialAssignment {
+
+ public ReguessableValue() {
+ super();
+ }
+
+ public abstract List<ReguessableValue> reguesses(
+ AssumptionViolatedException e);
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StringableObject.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StringableObject.java
new file mode 100644
index 0000000..de3ce98
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StringableObject.java
@@ -0,0 +1,29 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.util.Arrays;
+
+public class StringableObject {
+ public Object obj;
+
+ public StringableObject(Object obj) {
+ this.obj = obj;
+ }
+
+ public Object stringableObject() {
+ if (isListableArray()) {
+ return Arrays.asList((Object[]) obj);
+ } else {
+ return obj;
+ }
+ }
+
+ private boolean isListableArray() {
+ Class<?> type = obj.getClass();
+ return type.isArray() && !type.getComponentType().isPrimitive();
+ }
+
+ @Override
+ public String toString() {
+ return stringableObject().toString();
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Stub.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Stub.java
new file mode 100644
index 0000000..aa320d5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/Stub.java
@@ -0,0 +1,8 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Stub {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheories.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheories.java
new file mode 100644
index 0000000..cf6a6ef
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheories.java
@@ -0,0 +1,65 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.internal.Assignments;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+public class StubbedTheories extends Theories {
+ public StubbedTheories(Class<?> klass) throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ public Statement methodBlock(FrameworkMethod method) {
+ return new StubbedTheoryAnchor(method, getTestClass());
+ }
+
+ public static class StubbedTheoryAnchor extends TheoryAnchor {
+ public StubbedTheoryAnchor(FrameworkMethod method, TestClass testClass) {
+ super(method, testClass);
+ }
+
+ private List<GuesserQueue> queues = new ArrayList<GuesserQueue>();
+
+ @Override
+ protected void handleAssumptionViolation(AssumptionViolatedException e) {
+ super.handleAssumptionViolation(e);
+ for (GuesserQueue queue : queues) {
+ queue.update(e);
+ }
+ }
+
+ @Override
+ protected void runWithIncompleteAssignment(Assignments incomplete)
+ throws Throwable {
+ GuesserQueue guessers = createGuesserQueue(incomplete);
+ queues.add(guessers);
+ while (!guessers.isEmpty())
+ runWithAssignment(incomplete.assignNext(guessers.remove(0)));
+ queues.remove(guessers);
+ }
+
+ private GuesserQueue createGuesserQueue(Assignments incomplete)
+ throws Throwable {
+ ParameterSignature nextUnassigned = incomplete.nextUnassigned();
+
+ if (nextUnassigned.hasAnnotation(Stub.class)) {
+ GuesserQueue queue = new GuesserQueue();
+ queue.add(new Guesser<Object>(nextUnassigned.getType()));
+ return queue;
+ }
+
+ return GuesserQueue.forSingleValues(incomplete.potentialsForNextUnassigned());
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheoriesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheoriesTest.java
new file mode 100644
index 0000000..a86bcd6
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/extendingwithstubs/StubbedTheoriesTest.java
@@ -0,0 +1,16 @@
+package org.junit.tests.experimental.theories.extendingwithstubs;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assume.assumeThat;
+
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+@RunWith(StubbedTheories.class)
+public class StubbedTheoriesTest {
+ @Theory
+ public void ask(@Stub Correspondent correspondent) {
+ assumeThat(correspondent.getAnswer("What is five?", "four", "five"),
+ is("five"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllMembersSupplierTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllMembersSupplierTest.java
new file mode 100644
index 0000000..64e77b1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllMembersSupplierTest.java
@@ -0,0 +1,209 @@
+package org.junit.tests.experimental.theories.internal;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.tests.experimental.theories.TheoryTestUtils.potentialAssignments;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.Theory;
+import org.junit.experimental.theories.internal.AllMembersSupplier;
+import org.junit.rules.ExpectedException;
+import org.junit.runners.model.TestClass;
+
+public class AllMembersSupplierTest {
+ @Rule
+ public ExpectedException expected = ExpectedException.none();
+
+ public static class HasDataPointsArrayField {
+ @DataPoints
+ public static String[] list = new String[] { "qwe", "asd" };
+
+ @Theory
+ public void theory(String param) {
+ }
+ }
+
+ @Test
+ public void dataPointsArrayShouldBeRecognized() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsArrayField.class.getMethod("theory", String.class));
+
+ assertEquals(2, assignments.size());
+ }
+
+ public static class HasDataPointsArrayWithMatchingButInaccurateTypes {
+ @DataPoints
+ public static Object[] objects = {1, "string!", 2};
+
+ @Theory
+ public void theory(Integer param) {
+ }
+ }
+
+ @Test
+ public void dataPointsArrayShouldBeRecognizedOnValueTypeNotFieldType() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsArrayWithMatchingButInaccurateTypes.class.getMethod("theory", Integer.class));
+
+ assertEquals(2, assignments.size());
+ }
+
+ public static class HasDataPointMethodWithOverlyGeneralTypes {
+ @DataPoint
+ public static Integer object() {
+ return 1;
+ }
+
+ @Theory
+ public void theory(Object param) {
+ }
+ }
+
+ @Test
+ public void dataPointMethodShouldBeRecognizedForOverlyGeneralParameters() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointMethodWithOverlyGeneralTypes.class.getMethod("theory", Object.class));
+
+ assertEquals(1, assignments.size());
+ }
+
+ public static class HasDataPointsWithObjectParameter {
+ @DataPoints
+ public static Object[] objectField = {1, 2};
+
+ @Theory
+ public void theory(Object obj) {
+ }
+ }
+
+ @Test
+ public void dataPointsAnnotationMeansTreatAsArrayOnly() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsWithObjectParameter.class.getMethod("theory", Object.class));
+
+ assertEquals(2, assignments.size());
+ for (PotentialAssignment assignment : assignments) {
+ assertNotEquals(HasDataPointsWithObjectParameter.objectField, assignment.getValue());
+ }
+ }
+
+ public static class HasDataPointsFieldWithNullValue {
+ @DataPoints
+ public static Object[] objects = {null, "a"};
+
+ public HasDataPointsFieldWithNullValue(Object obj) {
+ }
+ }
+
+ @Test
+ public void dataPointsArrayFieldMayContainNullValue() throws Throwable {
+ List<PotentialAssignment> valueSources = allMemberValuesFor(
+ HasDataPointsFieldWithNullValue.class, Object.class);
+ assertThat(valueSources.size(), is(2));
+ }
+
+ public static class HasDataPointsMethodWithNullValue {
+ @DataPoints
+ public static Integer[] getObjects() {
+ return new Integer[] {null, 1};
+ }
+
+ public HasDataPointsMethodWithNullValue(Integer i) {
+ }
+ }
+
+ @Test
+ public void dataPointsArrayMethodMayContainNullValue() throws Throwable {
+ List<PotentialAssignment> valueSources = allMemberValuesFor(
+ HasDataPointsMethodWithNullValue.class, Integer.class);
+ assertThat(valueSources.size(), is(2));
+ }
+
+ public static class HasFailingDataPointsArrayMethod {
+ @DataPoints
+ public static Object[] objects() {
+ throw new RuntimeException("failing method");
+ }
+
+ public HasFailingDataPointsArrayMethod(Object obj) {
+ }
+ }
+
+ @Test
+ public void allMembersFailsOnFailingDataPointsArrayMethod() throws Throwable {
+ expected.expect(RuntimeException.class);
+ expected.expectMessage("failing method");
+ allMemberValuesFor(HasFailingDataPointsArrayMethod.class, Object.class);
+ }
+
+ private List<PotentialAssignment> allMemberValuesFor(Class<?> testClass,
+ Class<?>... constructorParameterTypes) throws Throwable {
+ return new AllMembersSupplier(new TestClass(testClass))
+ .getValueSources(ParameterSignature.signatures(
+ testClass.getConstructor(constructorParameterTypes))
+ .get(0));
+ }
+
+ public static class HasDataPointsListField {
+ @DataPoints
+ public static List<String> list = Arrays.asList("one", "two");
+
+ @Theory
+ public void theory(String param) {
+ }
+ }
+
+ @Test
+ public void dataPointsCollectionFieldsShouldBeRecognized() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsListField.class.getMethod("theory", String.class));
+
+ assertEquals(2, assignments.size());
+ }
+
+ public static class HasDataPointsListMethod {
+ @DataPoints
+ public static List<String> getList() {
+ return Arrays.asList("one", "two");
+ }
+
+ @Theory
+ public void theory(String param) {
+ }
+ }
+
+ @Test
+ public void dataPointsCollectionMethodShouldBeRecognized() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsListMethod.class.getMethod("theory", String.class));
+
+ assertEquals(2, assignments.size());
+ }
+
+ public static class HasDataPointsListFieldWithOverlyGenericTypes {
+ @DataPoints
+ public static List<Object> list = Arrays.asList("string", new Object());
+
+ @Theory
+ public void theory(String param) {
+ }
+ }
+
+ @Test
+ public void dataPointsCollectionShouldBeRecognizedIgnoringStrangeTypes() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(
+ HasDataPointsListFieldWithOverlyGenericTypes.class.getMethod("theory", String.class));
+
+ assertEquals(1, assignments.size());
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllTheoriesInternalTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllTheoriesInternalTests.java
new file mode 100644
index 0000000..7c87afa
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/AllTheoriesInternalTests.java
@@ -0,0 +1,14 @@
+package org.junit.tests.experimental.theories.internal;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllMembersSupplierTest.class,
+ ParameterizedAssertionErrorTest.class,
+ SpecificDataPointsSupplierTest.class
+})
+public class AllTheoriesInternalTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/ParameterizedAssertionErrorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/ParameterizedAssertionErrorTest.java
new file mode 100644
index 0000000..285ebf5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/ParameterizedAssertionErrorTest.java
@@ -0,0 +1,95 @@
+package org.junit.tests.experimental.theories.internal;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeThat;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.experimental.theories.internal.ParameterizedAssertionError;
+import org.junit.runner.RunWith;
+
+@RunWith(Theories.class)
+public class ParameterizedAssertionErrorTest {
+ @DataPoint
+ public static final String METHOD_NAME = "methodName";
+
+ @DataPoint
+ public static final NullPointerException NULL_POINTER_EXCEPTION = new NullPointerException();
+
+ @DataPoint
+ public static Object[] NO_OBJECTS = new Object[0];
+
+ @DataPoint
+ public static ParameterizedAssertionError A = new ParameterizedAssertionError(
+ NULL_POINTER_EXCEPTION, METHOD_NAME);
+
+ @DataPoint
+ public static ParameterizedAssertionError B = new ParameterizedAssertionError(
+ NULL_POINTER_EXCEPTION, METHOD_NAME);
+
+ @DataPoint
+ public static ParameterizedAssertionError B2 = new ParameterizedAssertionError(
+ NULL_POINTER_EXCEPTION, "methodName2");
+
+ @Theory
+ public void equalParameterizedAssertionErrorsHaveSameToString(
+ ParameterizedAssertionError a, ParameterizedAssertionError b) {
+ assumeThat(a, is(b));
+ assertThat(a.toString(), is(b.toString()));
+ }
+
+ @Theory
+ public void differentParameterizedAssertionErrorsHaveDifferentToStrings(
+ ParameterizedAssertionError a, ParameterizedAssertionError b) {
+ assumeThat(a, not(b));
+ assertThat(a.toString(), not(b.toString()));
+ }
+
+ @Theory
+ public void equalsReturnsTrue(Throwable targetException, String methodName,
+ Object[] params) {
+ assertThat(
+ new ParameterizedAssertionError(targetException, methodName, params),
+ is(new ParameterizedAssertionError(targetException, methodName, params)));
+ }
+
+ @Theory
+ public void sameHashCodeWhenEquals(Throwable targetException, String methodName,
+ Object[] params) {
+ ParameterizedAssertionError one = new ParameterizedAssertionError(
+ targetException, methodName, params);
+ ParameterizedAssertionError two = new ParameterizedAssertionError(
+ targetException, methodName, params);
+ assumeThat(one, is(two));
+
+ assertThat(one.hashCode(), is(two.hashCode()));
+ }
+
+ @Theory(nullsAccepted = false)
+ public void buildParameterizedAssertionError(String methodName, String param) {
+ assertThat(new ParameterizedAssertionError(
+ new RuntimeException(), methodName, param).toString(),
+ containsString(methodName));
+ }
+
+ @Theory
+ public void isNotEqualToNull(ParameterizedAssertionError a) {
+ assertFalse(a.equals(null));
+ }
+
+ @Test
+ public void canJoinWhenToStringFails() {
+ assertThat(ParameterizedAssertionError.join(" ", new Object() {
+ @Override
+ public String toString() {
+ throw new UnsupportedOperationException();
+ }
+ }), is("[toString failed]"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/SpecificDataPointsSupplierTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/SpecificDataPointsSupplierTest.java
new file mode 100644
index 0000000..1ba6136
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/internal/SpecificDataPointsSupplierTest.java
@@ -0,0 +1,156 @@
+package org.junit.tests.experimental.theories.internal;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException;
+import org.junit.experimental.theories.internal.SpecificDataPointsSupplier;
+import org.junit.runners.model.TestClass;
+
+public class SpecificDataPointsSupplierTest {
+
+ public static class TestClassWithNamedDataPoints {
+
+ @DataPoints({"field", "named"})
+ public static String[] values = new String[] { "named field" };
+
+ @DataPoints
+ public static String[] otherValues = new String[] { "other" };
+
+ @DataPoints({"method", "named"})
+ public static String[] getValues() {
+ return new String[] { "named method" };
+ }
+
+ @DataPoint({"single", "named"})
+ public static String singleValue = "named single value";
+
+ @DataPoint
+ public static String otherSingleValue = "other value";
+
+ @DataPoint({"singlemethod", "named"})
+ public static String getSingleValue() {
+ return "named single method value";
+ }
+
+ @DataPoint
+ public static String getSingleOtherValue() {
+ return "other single method value";
+ }
+
+ @DataPoints
+ public static String[] getOtherValues() {
+ return new String[] { "other method" };
+ }
+ }
+
+ @Test
+ public void shouldReturnOnlyTheNamedDataPoints() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingAllNamedStrings"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(4, assignedStrings.size());
+ assertThat(assignedStrings, hasItems("named field", "named method", "named single value", "named single method value"));
+ }
+
+ @Test
+ public void shouldReturnOnlyTheNamedFieldDataPoints() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingNamedFieldString"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(1, assignedStrings.size());
+ assertThat(assignedStrings, hasItem("named field"));
+ }
+
+ @Test
+ public void shouldReturnOnlyTheNamedMethodDataPoints() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingNamedMethodString"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(1, assignedStrings.size());
+ assertThat(assignedStrings, hasItem("named method"));
+ }
+
+ @Test
+ public void shouldReturnOnlyTheNamedSingleFieldDataPoints() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingNamedSingleFieldString"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(1, assignedStrings.size());
+ assertThat(assignedStrings, hasItem("named single value"));
+ }
+
+ @Test
+ public void shouldReturnOnlyTheNamedSingleMethodDataPoints() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingNamedSingleMethodString"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(1, assignedStrings.size());
+ assertThat(assignedStrings, hasItem("named single method value"));
+ }
+
+ @Test
+ public void shouldReturnNothingIfTheNamedDataPointsAreMissing() throws Throwable {
+ SpecificDataPointsSupplier supplier = new SpecificDataPointsSupplier(new TestClass(TestClassWithNamedDataPoints.class));
+
+ List<PotentialAssignment> assignments = supplier.getValueSources(signature("methodWantingWrongNamedString"));
+ List<String> assignedStrings = getStringValuesFromAssignments(assignments);
+
+ assertEquals(0, assignedStrings.size());
+ }
+
+ private List<String> getStringValuesFromAssignments(List<PotentialAssignment> assignments) throws CouldNotGenerateValueException {
+ List<String> stringValues = new ArrayList<String>();
+ for (PotentialAssignment assignment : assignments) {
+ stringValues.add((String) assignment.getValue());
+ }
+ return stringValues;
+ }
+
+ private ParameterSignature signature(String methodName) throws Exception {
+ return ParameterSignature.signatures(this.getClass().getMethod(methodName, String.class)).get(0);
+ }
+
+ public void methodWantingAnyString(String input) {
+ }
+
+ public void methodWantingNamedFieldString(@FromDataPoints("field") String input) {
+ }
+
+ public void methodWantingNamedMethodString(@FromDataPoints("method") String input) {
+ }
+
+ public void methodWantingNamedSingleFieldString(@FromDataPoints("single") String input) {
+ }
+
+ public void methodWantingNamedSingleMethodString(@FromDataPoints("singlemethod") String input) {
+ }
+
+ public void methodWantingAllNamedStrings(@FromDataPoints("named") String input) {
+ }
+
+ public void methodWantingWrongNamedString(@FromDataPoints("invalid name") String input) {
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/AllTheoriesRunnerTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/AllTheoriesRunnerTests.java
new file mode 100644
index 0000000..26465ca
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/AllTheoriesRunnerTests.java
@@ -0,0 +1,24 @@
+package org.junit.tests.experimental.theories.runner;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ FailingDataPointMethods.class,
+ SuccessfulWithDataPointFields.class,
+ TheoriesPerformanceTest.class,
+ TypeMatchingBetweenMultiDataPointsMethod.class,
+ UnsuccessfulWithDataPointFields.class,
+ WhenNoParametersMatch.class,
+ WithAutoGeneratedDataPoints.class,
+ WithDataPointMethod.class,
+ WithExtendedParameterSources.class,
+ WithNamedDataPoints.class,
+ WithOnlyTestAnnotations.class,
+ WithParameterSupplier.class,
+ WithUnresolvedGenericTypeVariablesOnTheoryParms.class
+})
+public class AllTheoriesRunnerTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/FailingDataPointMethods.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/FailingDataPointMethods.java
new file mode 100644
index 0000000..f69e502
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/FailingDataPointMethods.java
@@ -0,0 +1,136 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+public class FailingDataPointMethods {
+
+ @RunWith(Theories.class)
+ public static class HasFailingSingleDataPointMethod {
+ @DataPoint
+ public static int num = 10;
+
+ @DataPoint
+ public static int failingDataPoint() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldFailFromExceptionsInSingleDataPointMethods() {
+ assertThat(testResult(HasWronglyIgnoredFailingSingleDataPointMethod.class), not(isSuccessful()));
+ }
+
+ @RunWith(Theories.class)
+ public static class HasFailingDataPointArrayMethod {
+ @DataPoints
+ public static int[] num = { 1, 2, 3 };
+
+ @DataPoints
+ public static int[] failingDataPoints() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldFailFromExceptionsInDataPointArrayMethods() {
+ assertThat(testResult(HasFailingDataPointArrayMethod.class), not(isSuccessful()));
+ }
+
+ @RunWith(Theories.class)
+ public static class HasIgnoredFailingSingleDataPointMethod {
+ @DataPoint
+ public static int num = 10;
+
+ @DataPoint(ignoredExceptions=Throwable.class)
+ public static int failingDataPoint() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldIgnoreSingleDataPointMethodExceptionsOnRequest() {
+ assertThat(testResult(HasIgnoredFailingSingleDataPointMethod.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class HasIgnoredFailingMultipleDataPointMethod {
+ @DataPoint
+ public static int num = 10;
+
+ @DataPoints(ignoredExceptions=Throwable.class)
+ public static int[] failingDataPoint() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldIgnoreMultipleDataPointMethodExceptionsOnRequest() {
+ assertThat(testResult(HasIgnoredFailingMultipleDataPointMethod.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class HasWronglyIgnoredFailingSingleDataPointMethod {
+ @DataPoint
+ public static int num = 10;
+
+ @DataPoint(ignoredExceptions=NullPointerException.class)
+ public static int failingDataPoint() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldNotIgnoreNonMatchingSingleDataPointExceptions() {
+ assertThat(testResult(HasWronglyIgnoredFailingSingleDataPointMethod.class), not(isSuccessful()));
+ }
+
+ @RunWith(Theories.class)
+ public static class HasWronglyIgnoredFailingMultipleDataPointMethod {
+ @DataPoint
+ public static int num = 10;
+
+ @DataPoint(ignoredExceptions=NullPointerException.class)
+ public static int failingDataPoint() {
+ throw new RuntimeException();
+ }
+
+ @Theory
+ public void theory(int x) {
+ }
+ }
+
+ @Test
+ public void shouldNotIgnoreNonMatchingMultipleDataPointExceptions() {
+ assertThat(testResult(HasWronglyIgnoredFailingMultipleDataPointMethod.class), not(isSuccessful()));
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java
new file mode 100644
index 0000000..80cfd89
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java
@@ -0,0 +1,211 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+@RunWith(Enclosed.class)
+public class SuccessfulWithDataPointFields {
+ @RunWith(Theories.class)
+ public static class HasATwoParameterTheory {
+ @DataPoint
+ public static int ONE = 1;
+
+ @Theory
+ public void allIntsAreEqual(int x, int y) {
+ assertThat(x, is(y));
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class BeforeAndAfterOnSameInstance {
+ @DataPoint
+ public static String A = "A";
+
+ private int befores = 0;
+
+ @Before
+ public void incrementBefore() {
+ befores++;
+ }
+
+ @Theory
+ public void stringsAreOK(String string) {
+ assertTrue(befores == 1);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class NewObjectEachTime {
+ @DataPoint
+ public static String A = "A";
+
+ @DataPoint
+ public static String B = "B";
+
+ private List<String> list = new ArrayList<String>();
+
+ @Theory
+ public void addToEmptyList(String string) {
+ list.add(string);
+ assertThat(list.size(), is(1));
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class PositiveInts {
+ @DataPoint
+ public static final int ONE = 1;
+
+ private int x;
+
+ public PositiveInts(int x) {
+ assumeTrue(x > 0);
+ this.x = x;
+ }
+
+ @Theory
+ public void haveAPostiveSquare() {
+ assertTrue(x * x > 0);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class PositiveIntsWithNegativeField {
+ @DataPoint
+ public static final int ONE = 1;
+ @DataPoint
+ public static final int NEGONE = -1;
+
+ private int x;
+
+ public PositiveIntsWithNegativeField(int x) {
+ assumeTrue(x > 0);
+ this.x = x;
+ }
+
+ @Theory
+ public void haveAPostiveSquare() {
+ assertTrue(x > 0);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class PositiveIntsWithMethodParams {
+ @DataPoint
+ public static final int ONE = 1;
+
+ private int x;
+
+ public PositiveIntsWithMethodParams(int x) {
+ assumeTrue(x > 0);
+ this.x = x;
+ }
+
+ @Theory
+ public void haveAPostiveSquare(int y) {
+ assumeTrue(y > 0);
+ assertTrue(x * y > 0);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class DifferentTypesInConstructor {
+ @DataPoint
+ public static final int ONE = 1;
+
+ @DataPoint
+ public static final String A = "A";
+
+ public DifferentTypesInConstructor(int x) {
+ }
+
+ @Theory
+ public void yesIndeed(String a) {
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class BeforeAndAfterEachTime {
+ public static int befores = 0;
+
+ @DataPoint
+ public static String A = "A";
+
+ @DataPoint
+ public static String B = "B";
+
+ @Before
+ public void incrementBefore() {
+ befores++;
+ }
+
+ @BeforeClass
+ public static void resetCalls() {
+ befores = 0;
+ }
+
+ @Theory
+ public void stringsAreOK(String string) {
+ }
+
+ @AfterClass
+ public static void calledTwice() {
+ assertEquals(2, befores);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class OneTestTwoAnnotations {
+ public static int tests = 0;
+
+ @DataPoint
+ public static String A = "A";
+
+ @BeforeClass
+ public static void resetCalls() {
+ tests = 0;
+ }
+
+ @Theory
+ @Test
+ public void stringsAreOK(String string) {
+ tests++;
+ }
+
+ @AfterClass
+ public static void calledTwice() {
+ assertEquals(1, tests);
+ }
+ }
+
+ @RunWith(Theories.class)
+ public static class StaticPublicNonDataPoints {
+ // DataPoint which passes the test
+ @DataPoint
+ public static int ZERO = 0;
+
+ // Not annotated as a DataPoint and therefore should be ignored:
+ public static int ONE = 1;
+
+ @Theory
+ public void onlyAnnotatedFields(int i) {
+ assertTrue(i == 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TheoriesPerformanceTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TheoriesPerformanceTest.java
new file mode 100644
index 0000000..9275524
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TheoriesPerformanceTest.java
@@ -0,0 +1,38 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+public class TheoriesPerformanceTest {
+ @RunWith(Theories.class)
+ public static class UpToTen {
+ @DataPoints
+ public static int[] ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+ @Theory
+ public void threeInts(int x, int y, int z) {
+ // pass always
+ }
+ }
+
+ private static final boolean TESTING_PERFORMANCE = false;
+
+ // If we do not share the same instance of TestClass, repeatedly parsing the
+ // class's annotations looking for @Befores and @Afters gets really costly.
+ //
+ // Likewise, the TestClass must be passed into AllMembersSupplier, or the
+ // annotation parsing is again costly.
+ @Test
+ public void tryCombinationsQuickly() {
+ assumeTrue(TESTING_PERFORMANCE);
+ assertThat(testResult(UpToTen.class), isSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TypeMatchingBetweenMultiDataPointsMethod.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TypeMatchingBetweenMultiDataPointsMethod.java
new file mode 100644
index 0000000..4b7e878
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/TypeMatchingBetweenMultiDataPointsMethod.java
@@ -0,0 +1,57 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+public class TypeMatchingBetweenMultiDataPointsMethod {
+
+ @RunWith(Theories.class)
+ public static class WithWrongfullyTypedDataPointsMethod {
+ @DataPoint
+ public static String[] correctlyTyped = {"Good", "Morning"};
+
+ @DataPoints
+ public static String[] wrongfullyTyped() {
+ return new String[]{"Hello", "World"};
+ }
+
+ @Theory
+ public void testTheory(String[] array) {
+ }
+ }
+
+ @Test
+ public void ignoreWrongTypedDataPointsMethod() {
+ assertThat(testResult(WithWrongfullyTypedDataPointsMethod.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class WithCorrectlyTypedDataPointsMethod {
+ @DataPoint
+ public static String[] correctlyTyped = {"Good", "Morning"};
+
+ @DataPoints
+ public static String[][] anotherCorrectlyTyped() {
+ return new String[][]{
+ {"Hello", "World"}
+ };
+ }
+
+ @Theory
+ public void testTheory(String[] array) {
+ }
+ }
+
+ @Test
+ public void pickUpMultiPointDataPointMethods() throws Exception {
+ assertThat(testResult(WithCorrectlyTypedDataPointsMethod.class), isSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/UnsuccessfulWithDataPointFields.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/UnsuccessfulWithDataPointFields.java
new file mode 100644
index 0000000..57dec2d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/UnsuccessfulWithDataPointFields.java
@@ -0,0 +1,243 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.TestClass;
+
+public class UnsuccessfulWithDataPointFields {
+ @RunWith(Theories.class)
+ public static class HasAFailingTheory {
+ @DataPoint
+ public static int ONE = 1;
+
+ @Theory
+ public void everythingIsZero(int x) {
+ assertThat(x, is(0));
+ }
+ }
+
+ @Test
+ public void theoryClassMethodsShowUp() throws Exception {
+ assertThat(new Theories(HasAFailingTheory.class).getDescription()
+ .getChildren().size(), is(1));
+ }
+
+ @Test
+ public void theoryAnnotationsAreRetained() throws Exception {
+ assertThat(new TestClass(HasAFailingTheory.class).getAnnotatedMethods(
+ Theory.class).size(), is(1));
+ }
+
+ @Test
+ public void canRunTheories() throws Exception {
+ assertThat(testResult(HasAFailingTheory.class),
+ hasSingleFailureContaining("Expected"));
+ }
+
+ @RunWith(Theories.class)
+ public static class DoesntUseParams {
+ @DataPoint
+ public static int ONE = 1;
+
+ @Theory
+ public void everythingIsZero(int x, int y) {
+ assertThat(2, is(3));
+ }
+ }
+
+ @Test
+ public void reportBadParams() throws Exception {
+ assertThat(testResult(DoesntUseParams.class),
+ hasSingleFailureContaining("everythingIsZero(\"1\" <from ONE>, \"1\" <from ONE>)"));
+ }
+
+ @RunWith(Theories.class)
+ public static class NullsOK {
+ @DataPoint
+ public static String NULL = null;
+
+ @DataPoint
+ public static String A = "A";
+
+ @Theory
+ public void everythingIsA(String a) {
+ assertThat(a, is("A"));
+ }
+ }
+
+ @Test
+ public void nullsUsedUnlessProhibited() throws Exception {
+ assertThat(testResult(NullsOK.class),
+ hasSingleFailureContaining("null"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TheoriesMustBePublic {
+ @DataPoint
+ public static int THREE = 3;
+
+ @Theory
+ void numbers(int x) {
+
+ }
+ }
+
+ @Test
+ public void theoriesMustBePublic() {
+ assertThat(
+ testResult(TheoriesMustBePublic.class),
+ hasSingleFailureContaining("public"));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointFieldsMustBeStatic {
+ @DataPoint
+ public int THREE = 3;
+
+ @DataPoints
+ public int[] FOURS = new int[] { 4 };
+
+ @Theory
+ public void numbers(int x) {
+
+ }
+ }
+
+ @Test
+ public void dataPointFieldsMustBeStatic() {
+ assertThat(
+ testResult(DataPointFieldsMustBeStatic.class),
+ CoreMatchers.<PrintableResult>both(hasFailureContaining("DataPoint field THREE must be static"))
+ .and(hasFailureContaining("DataPoint field FOURS must be static")));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointMethodsMustBeStatic {
+ @DataPoint
+ public int singleDataPointMethod() {
+ return 1;
+ }
+
+ @DataPoints
+ public int[] dataPointArrayMethod() {
+ return new int[] { 1, 2, 3 };
+ }
+
+ @Theory
+ public void numbers(int x) {
+
+ }
+ }
+
+ @Test
+ public void dataPointMethodsMustBeStatic() {
+ assertThat(
+ testResult(DataPointMethodsMustBeStatic.class),
+ CoreMatchers.<PrintableResult>both(
+ hasFailureContaining("DataPoint method singleDataPointMethod must be static"))
+ .and(
+ hasFailureContaining("DataPoint method dataPointArrayMethod must be static")));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointFieldsMustBePublic {
+ @DataPoint
+ static int THREE = 3;
+
+ @DataPoints
+ static int[] THREES = new int[] { 3 };
+
+ @DataPoint
+ protected static int FOUR = 4;
+
+ @DataPoints
+ protected static int[] FOURS = new int[] { 4 };
+
+ @DataPoint
+ private static int FIVE = 5;
+
+ @DataPoints
+ private static int[] FIVES = new int[] { 5 };
+
+ @Theory
+ public void numbers(int x) {
+
+ }
+ }
+
+ @Test
+ public void dataPointFieldsMustBePublic() {
+ PrintableResult result = testResult(DataPointFieldsMustBePublic.class);
+
+ assertThat(result,
+ allOf(hasFailureContaining("DataPoint field THREE must be public"),
+ hasFailureContaining("DataPoint field THREES must be public"),
+ hasFailureContaining("DataPoint field FOUR must be public"),
+ hasFailureContaining("DataPoint field FOURS must be public"),
+ hasFailureContaining("DataPoint field FIVE must be public"),
+ hasFailureContaining("DataPoint field FIVES must be public")));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointMethodsMustBePublic {
+ @DataPoint
+ static int three() {
+ return 3;
+ }
+
+ @DataPoints
+ static int[] threes() {
+ return new int[] { 3 };
+ }
+
+ @DataPoint
+ protected static int four() {
+ return 4;
+ }
+
+ @DataPoints
+ protected static int[] fours() {
+ return new int[] { 4 };
+ }
+
+ @DataPoint
+ private static int five() {
+ return 5;
+ }
+
+ @DataPoints
+ private static int[] fives() {
+ return new int[] { 5 };
+ }
+
+ @Theory
+ public void numbers(int x) {
+
+ }
+ }
+
+ @Test
+ public void dataPointMethodsMustBePublic() {
+ PrintableResult result = testResult(DataPointMethodsMustBePublic.class);
+
+ assertThat(result,
+ allOf(hasFailureContaining("DataPoint method three must be public"),
+ hasFailureContaining("DataPoint method threes must be public"),
+ hasFailureContaining("DataPoint method four must be public"),
+ hasFailureContaining("DataPoint method fours must be public"),
+ hasFailureContaining("DataPoint method five must be public"),
+ hasFailureContaining("DataPoint method fives must be public")));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WhenNoParametersMatch.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WhenNoParametersMatch.java
new file mode 100644
index 0000000..a8e3a84
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WhenNoParametersMatch.java
@@ -0,0 +1,51 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+
+import org.hamcrest.Matcher;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+@RunWith(Theories.class)
+public class WhenNoParametersMatch {
+ @DataPoints
+ public static int[] ints = {0, 1, 3, 5, 1776};
+
+ @DataPoints
+ public static Matcher<?>[] matchers = {not(0), is(1)};
+
+ @RunWith(Theories.class)
+ public static class AssumptionsFail {
+ @DataPoint
+ public static int DATA = 0;
+
+ @DataPoint
+ public static Matcher<Integer> MATCHER = null;
+
+ @Theory
+ public void nonZeroIntsAreFun(int x) {
+ assumeThat(x, MATCHER);
+ }
+ }
+
+ @Theory
+ public void showFailedAssumptionsWhenNoParametersFound(int data,
+ Matcher<Integer> matcher) throws Exception {
+ assumeThat(data, not(matcher));
+ AssumptionsFail.DATA = data;
+ AssumptionsFail.MATCHER = matcher;
+
+ String result = testResult(AssumptionsFail.class).toString();
+
+ assertThat(result, containsString(matcher.toString()));
+ assertThat(result, containsString("" + data));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithAutoGeneratedDataPoints.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithAutoGeneratedDataPoints.java
new file mode 100644
index 0000000..53cab04
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithAutoGeneratedDataPoints.java
@@ -0,0 +1,71 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.tests.experimental.theories.TheoryTestUtils.potentialAssignments;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.runner.RunWith;
+
+public class WithAutoGeneratedDataPoints {
+
+ private enum ENUM { VALUE, OTHER_VALUE, THIRD_VALUE }
+
+ @RunWith(Theories.class)
+ public static class TheoryTestClassWithAutogeneratedParameterValues {
+
+ public void theory(ENUM e) {
+ }
+
+ public void theory(boolean b) {
+ }
+
+ }
+
+ @Test
+ public void shouldAutomaticallyGenerateEnumDataPoints() throws Throwable {
+ assertEquals(ENUM.values().length, potentialAssignments(
+ TheoryTestClassWithAutogeneratedParameterValues.class.getMethod("theory", ENUM.class)).size());
+ }
+
+ @Test
+ public void shouldAutomaticallyGenerateBooleanDataPoints() throws Throwable {
+ assertEquals(2, potentialAssignments(
+ TheoryTestClassWithAutogeneratedParameterValues.class.getMethod("theory", boolean.class)).size());
+ }
+
+ @RunWith(Theories.class)
+ public static class TheoryTestClassWithSpecificEnumDataPoint {
+
+ @DataPoint
+ public static ENUM value = ENUM.OTHER_VALUE;
+
+ public void theory(ENUM e) {
+ }
+
+ }
+
+ @Test
+ public void shouldNotAutogenerateEnumDataPointsWhenSpecificDataPointGiven() throws Throwable {
+ assertEquals(1, potentialAssignments(
+ TheoryTestClassWithSpecificEnumDataPoint.class.getMethod("theory", ENUM.class)).size());
+ }
+
+ @RunWith(Theories.class)
+ public static class TheoryTestClassWithSpecificBooleanDataPoint {
+
+ @DataPoint
+ public static boolean value = true;
+
+ public void theory(boolean b) {
+ }
+
+ }
+
+ @Test
+ public void shouldNotAutogenerateBooleanDataPointsWhenSpecificDataPointGiven() throws Throwable {
+ assertEquals(1, potentialAssignments(
+ TheoryTestClassWithSpecificBooleanDataPoint.class.getMethod("theory", boolean.class)).size());
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithDataPointMethod.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithDataPointMethod.java
new file mode 100644
index 0000000..f2b2753
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithDataPointMethod.java
@@ -0,0 +1,114 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+import static org.junit.tests.experimental.theories.TheoryTestUtils.potentialAssignments;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+
+public class WithDataPointMethod {
+ @RunWith(Theories.class)
+ public static class HasDataPointMethod {
+ @DataPoint
+ public static int oneHundred() {
+ return 100;
+ }
+
+ @Theory
+ public void allIntsOk(int x) {
+ }
+ }
+
+ @Test
+ public void pickUpDataPointMethods() {
+ assertThat(testResult(HasDataPointMethod.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointMethodReturnsMutableObject {
+ @DataPoint
+ public static List<Object> empty() {
+ return new ArrayList<Object>();
+ }
+
+ @DataPoint
+ public static int ONE = 1;
+
+ @DataPoint
+ public static int TWO = 2;
+
+ @Theory
+ public void everythingsEmpty(List<Object> first, int number) {
+ assertThat(first.size(), is(0));
+ first.add("a");
+ }
+ }
+
+ @Test
+ public void mutableObjectsAreCreatedAfresh() {
+ assertThat(failures(DataPointMethodReturnsMutableObject.class), empty());
+ }
+
+ @RunWith(Theories.class)
+ public static class HasDateMethod {
+ @DataPoint
+ public static int oneHundred() {
+ return 100;
+ }
+
+ public static Date notADataPoint() {
+ return new Date();
+ }
+
+ @Theory
+ public void allIntsOk(int x) {
+ }
+
+ @Theory
+ public void onlyStringsOk(String s) {
+ }
+
+ @Theory
+ public void onlyDatesOk(Date d) {
+ }
+ }
+
+ @Test
+ public void ignoreDataPointMethodsWithWrongTypes() throws Throwable {
+ assertThat(potentialAssignments(
+ HasDateMethod.class.getMethod("onlyStringsOk", String.class))
+ .toString(), not(containsString("100")));
+ }
+
+ @Test
+ public void ignoreDataPointMethodsWithoutAnnotation() throws Throwable {
+ assertThat(potentialAssignments(
+ HasDateMethod.class.getMethod("onlyDatesOk", Date.class))
+ .size(), is(0));
+ }
+
+ private List<Failure> failures(Class<?> type) {
+ return JUnitCore.runClasses(type).getFailures();
+ }
+
+ private Matcher<Iterable<Failure>> empty() {
+ return everyItem(nullValue(Failure.class));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithExtendedParameterSources.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithExtendedParameterSources.java
new file mode 100644
index 0000000..c08839f
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithExtendedParameterSources.java
@@ -0,0 +1,180 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Test;
+import org.junit.experimental.results.ResultMatchers;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.experimental.theories.suppliers.TestedOn;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+
+public class WithExtendedParameterSources {
+ @RunWith(Theories.class)
+ public static class ParameterAnnotations {
+ @Theory
+ public void everythingIsOne(@TestedOn(ints = {1})
+ int number) {
+ assertThat(number, is(1));
+ }
+ }
+
+ @Test
+ public void testedOnLimitsParameters() throws Exception {
+ assertThat(testResult(ParameterAnnotations.class), ResultMatchers
+ .isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class ShouldFilterOutNullSingleDataPoints {
+
+ @DataPoint
+ public static String A = "a";
+
+ @DataPoint
+ public static String NULL = null;
+
+ @Theory(nullsAccepted = false)
+ public void allStringsAreNonNull(String s) {
+ assertThat(s, notNullValue());
+ }
+ }
+
+ @Test
+ public void shouldFilterOutNullSingleDataPoints() {
+ assertThat(testResult(ShouldFilterOutNullSingleDataPoints.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class ShouldFilterOutNullElementsFromDataPointArrays {
+ @DataPoints
+ public static String[] SOME_NULLS = { "non-null", null };
+
+ @Theory(nullsAccepted = false)
+ public void allStringsAreNonNull(String s) {
+ assertThat(s, notNullValue());
+ }
+ }
+
+ @Test
+ public void shouldFilterOutNullElementsFromDataPointArrays() {
+ assertThat(testResult(ShouldFilterOutNullElementsFromDataPointArrays.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class ShouldRejectTheoriesWithOnlyDisallowedNullData {
+ @DataPoints
+ public static String value = null;
+
+ @Theory(nullsAccepted = false)
+ public void allStringsAreNonNull(String s) {
+ }
+ }
+
+ @Test
+ public void ShouldRejectTheoriesWithOnlyDisallowedNullData() {
+ assertThat(testResult(ShouldRejectTheoriesWithOnlyDisallowedNullData.class), not(isSuccessful()));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointArrays {
+ public static String log = "";
+
+ @DataPoints
+ public static String[] STRINGS = new String[]{"A", "B"};
+
+ @Theory
+ public void addToLog(String string) {
+ log += string;
+ }
+ }
+
+ @Test
+ public void getDataPointsFromArray() {
+ DataPointArrays.log = "";
+ JUnitCore.runClasses(DataPointArrays.class);
+ assertThat(DataPointArrays.log, is("AB"));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointArrayMethod {
+ public static String log = "";
+
+ @DataPoints
+ public static String[] STRINGS() {
+ return new String[]{"A", "B"};
+ }
+
+ @Theory
+ public void addToLog(String string) {
+ log += string;
+ }
+ }
+
+ @Test
+ public void getDataPointsFromArrayMethod() {
+ DataPointArrayMethod.log = "";
+ JUnitCore.runClasses(DataPointArrayMethod.class);
+ assertThat(DataPointArrayMethod.log, is("AB"));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointMalformedArrayMethods {
+ public static String log = "";
+
+ @DataPoints
+ public static String[] STRINGS() {
+ return new String[]{"A", "B"};
+ }
+
+ @DataPoints
+ public static String STRING() {
+ return "C";
+ }
+
+ @DataPoints
+ public static int[] INTS() {
+ return new int[]{1, 2, 3};
+ }
+
+ @Theory
+ public void addToLog(String string) {
+ log += string;
+ }
+ }
+
+ @Test
+ public void getDataPointsFromArrayMethodInSpiteOfMalformedness() {
+ DataPointArrayMethod.log = "";
+ JUnitCore.runClasses(DataPointArrayMethod.class);
+ assertThat(DataPointArrayMethod.log, is("AB"));
+ }
+
+ @RunWith(Theories.class)
+ public static class DataPointArrayToBeUsedForWholeParameter {
+ public static String log = "";
+
+ @DataPoint
+ public static String[] STRINGS = new String[]{"A", "B"};
+
+ @Theory
+ public void addToLog(String[] strings) {
+ log += strings[0];
+ }
+ }
+
+ @Test
+ public void dataPointCanBeArray() {
+ DataPointArrayToBeUsedForWholeParameter.log = "";
+ JUnitCore.runClasses(DataPointArrayToBeUsedForWholeParameter.class);
+ assertThat(DataPointArrayToBeUsedForWholeParameter.log, is("A"));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithNamedDataPoints.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithNamedDataPoints.java
new file mode 100644
index 0000000..8383a47
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithNamedDataPoints.java
@@ -0,0 +1,73 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.tests.experimental.theories.TheoryTestUtils.potentialAssignments;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.FromDataPoints;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+public class WithNamedDataPoints {
+
+ @RunWith(Theories.class)
+ public static class HasSpecificDatapointsParameters {
+
+ @DataPoints
+ public static String[] badStrings = new String[] { "bad" };
+
+ @DataPoint
+ public static String badString = "also bad";
+
+ @DataPoints("named")
+ public static String[] goodStrings = new String[] { "expected", "also expected" };
+
+ @DataPoint("named")
+ public static String goodString = "expected single value";
+
+ @DataPoints("named")
+ public static String[] methodStrings() {
+ return new String[] { "expected method value" };
+ }
+
+ @DataPoint("named")
+ public static String methodString() {
+ return "expected single method string";
+ }
+
+ @DataPoints
+ public static String[] otherMethod() {
+ return new String[] { "other method value" };
+ }
+
+ @DataPoint
+ public static String otherSingleValueMethod() {
+ return "other single value string";
+ }
+
+ @Theory
+ public void theory(@FromDataPoints("named") String param) {
+ }
+
+ }
+
+ @Test
+ public void onlyUseSpecificDataPointsIfSpecified() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(HasSpecificDatapointsParameters.class
+ .getMethod("theory", String.class));
+
+ assertEquals(5, assignments.size());
+ for (PotentialAssignment assignment : assignments) {
+ assertThat((String) assignment.getValue(), containsString("expected"));
+ }
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithOnlyTestAnnotations.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithOnlyTestAnnotations.java
new file mode 100644
index 0000000..17b2665
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithOnlyTestAnnotations.java
@@ -0,0 +1,82 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+
+public class WithOnlyTestAnnotations {
+ @RunWith(Theories.class)
+ public static class HonorExpectedException {
+ @Test(expected = NullPointerException.class)
+ public void shouldThrow() {
+
+ }
+ }
+
+ @Test
+ public void honorExpected() throws Exception {
+ assertThat(testResult(HonorExpectedException.class).failureCount(), is(1));
+ }
+
+ @RunWith(Theories.class)
+ public static class HonorExpectedExceptionPasses {
+ @Test(expected = NullPointerException.class)
+ public void shouldThrow() {
+ throw new NullPointerException();
+ }
+ }
+
+ @Test
+ public void honorExpectedPassing() throws Exception {
+ assertThat(testResult(HonorExpectedExceptionPasses.class), isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class HonorTimeout {
+ @Test(timeout = 5)
+ public void shouldStop() {
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+
+ }
+ }
+ }
+ }
+
+ @Test
+ public void honorTimeout() throws Exception {
+ assertThat(testResult(HonorTimeout.class), failureCountIs(1));
+ }
+
+ @RunWith(Theories.class)
+ static public class ErrorWhenTestHasParametersDespiteTheories {
+ @DataPoint
+ public static int ZERO = 0;
+
+ @Test
+ public void testMethod(int i) {
+ }
+ }
+
+ @Test
+ public void testErrorWhenTestHasParametersDespiteTheories() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(ErrorWhenTestHasParametersDespiteTheories.class);
+ assertEquals(1, result.getFailureCount());
+ String message = result.getFailures().get(0).getMessage();
+ assertThat(message, containsString("should have no parameters"));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithParameterSupplier.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithParameterSupplier.java
new file mode 100644
index 0000000..1802390
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithParameterSupplier.java
@@ -0,0 +1,165 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.tests.experimental.theories.TheoryTestUtils.potentialAssignments;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.theories.ParameterSignature;
+import org.junit.experimental.theories.ParameterSupplier;
+import org.junit.experimental.theories.ParametersSuppliedBy;
+import org.junit.experimental.theories.PotentialAssignment;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.TestClass;
+
+public class WithParameterSupplier {
+
+ @Rule
+ public ExpectedException expected = ExpectedException.none();
+
+ private static class SimplePotentialAssignment extends PotentialAssignment {
+ private String description;
+ private Object value;
+
+ public SimplePotentialAssignment(Object value, String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ @Override
+ public Object getValue() throws CouldNotGenerateValueException {
+ return value;
+ }
+
+ @Override
+ public String getDescription() throws CouldNotGenerateValueException {
+ return description;
+ }
+ }
+
+ private static final List<String> DATAPOINTS = Arrays.asList("qwe", "asd");
+
+ public static class SimpleSupplier extends ParameterSupplier {
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ List<PotentialAssignment> assignments = new ArrayList<PotentialAssignment>();
+
+ for (String datapoint : DATAPOINTS) {
+ assignments.add(new SimplePotentialAssignment(datapoint,
+ datapoint));
+ }
+
+ return assignments;
+ }
+
+ }
+
+ @RunWith(Theories.class)
+ public static class TestClassUsingParameterSupplier {
+
+ @Theory
+ public void theoryMethod(@ParametersSuppliedBy(SimpleSupplier.class) String param) {
+ }
+
+ }
+
+ @Test
+ public void shouldPickUpDataPointsFromParameterSupplier() throws Throwable {
+ List<PotentialAssignment> assignments = potentialAssignments(TestClassUsingParameterSupplier.class
+ .getMethod("theoryMethod", String.class));
+
+ assertEquals(2, assignments.size());
+ assertEquals(DATAPOINTS.get(0), assignments.get(0).getValue());
+ assertEquals(DATAPOINTS.get(1), assignments.get(1).getValue());
+ }
+
+ public static class SupplierWithUnknownConstructor extends ParameterSupplier {
+
+ public SupplierWithUnknownConstructor(String param) {
+ }
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ return null;
+ }
+
+ }
+
+ @RunWith(Theories.class)
+ public static class TestClassUsingSupplierWithUnknownConstructor {
+
+ @Theory
+ public void theory(@ParametersSuppliedBy(SupplierWithUnknownConstructor.class) String param) {
+ }
+
+ }
+
+ @Test
+ public void shouldRejectSuppliersWithUnknownConstructors() throws Exception {
+ expected.expect(InitializationError.class);
+ new Theories(TestClassUsingSupplierWithUnknownConstructor.class);
+ }
+
+ public static class SupplierWithTwoConstructors extends ParameterSupplier {
+
+ public SupplierWithTwoConstructors(String param) {
+ }
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ return null;
+ }
+
+ }
+
+ @RunWith(Theories.class)
+ public static class TestClassUsingSupplierWithTwoConstructors {
+
+ @Theory
+ public void theory(@ParametersSuppliedBy(SupplierWithTwoConstructors.class) String param) {
+ }
+
+ }
+
+ @Test
+ public void shouldRejectSuppliersWithTwoConstructors() throws Exception {
+ expected.expect(InitializationError.class);
+ new Theories(TestClassUsingSupplierWithTwoConstructors.class);
+ }
+
+ public static class SupplierWithTestClassConstructor extends ParameterSupplier {
+
+ public SupplierWithTestClassConstructor(TestClass param) {
+ }
+
+ @Override
+ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
+ return null;
+ }
+
+ }
+
+ @RunWith(Theories.class)
+ public static class TestClassUsingSupplierWithTestClassConstructor {
+
+ @Theory
+ public void theory(@ParametersSuppliedBy(SupplierWithTestClassConstructor.class) String param) {
+ }
+
+ }
+
+ @Test
+ public void shouldAcceptSuppliersWithTestClassConstructor() throws Exception {
+ new Theories(TestClassUsingSupplierWithTestClassConstructor.class);
+ }
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithUnresolvedGenericTypeVariablesOnTheoryParms.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithUnresolvedGenericTypeVariablesOnTheoryParms.java
new file mode 100644
index 0000000..5d46699
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/experimental/theories/runner/WithUnresolvedGenericTypeVariablesOnTheoryParms.java
@@ -0,0 +1,180 @@
+package org.junit.tests.experimental.theories.runner;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.failureCountIs;
+import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.experimental.results.PrintableResult;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+
+public class WithUnresolvedGenericTypeVariablesOnTheoryParms {
+ @Test
+ public void whereTypeVariableIsOnTheTheory() {
+ PrintableResult result = testResult(TypeVariableOnTheoryOnly.class);
+ assertThat(result, isSuccessful());
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnTheoryOnly {
+ @DataPoint
+ public static List<String> strings = Arrays.asList("foo", "bar");
+
+ @Theory
+ public <T> void forItems(Collection<?> items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable T"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnTheoryParm {
+ @DataPoint
+ public static String string = "foo";
+
+ @Theory
+ public <T> void forItem(T item) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnParameterizedTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnParameterizedTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable T"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnParameterizedTheoryParm {
+ @DataPoint
+ public static List<String> strings = Arrays.asList("foo", "bar");
+
+ @Theory
+ public <T> void forItems(Collection<T> items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnWildcardUpperBoundOnTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnWildcardUpperBoundOnTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable U"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnWildcardUpperBoundOnTheoryParm {
+ @DataPoint
+ public static List<String> strings = Arrays.asList("foo", "bar");
+
+ @Theory
+ public <U> void forItems(Collection<? extends U> items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnWildcardLowerBoundOnTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnWildcardLowerBoundOnTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable V"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnWildcardLowerBoundOnTheoryParm {
+ @DataPoint
+ public static List<String> strings = Arrays.asList("foo", "bar");
+
+ @Theory
+ public <V> void forItems(Collection<? super V> items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnArrayTypeOnTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnArrayTypeOnTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable T"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnArrayTypeOnTheoryParm {
+ @DataPoints
+ public static String[][] items() {
+ return new String[][]{new String[]{"foo"}, new String[]{"bar"}};
+ }
+
+ @Theory
+ public <T> void forItems(T[] items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnComponentOfArrayTypeOnTheoryParm() {
+ PrintableResult result = testResult(TypeVariableOnComponentOfArrayTypeOnTheoryParm.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable U"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnComponentOfArrayTypeOnTheoryParm {
+ @DataPoints
+ public static List<?>[][] items() {
+ return new List<?>[][]{
+ new List<?>[]{Arrays.asList("foo")},
+ new List<?>[]{Arrays.asList("bar")}
+ };
+ }
+
+ @Theory
+ public <U> void forItems(Collection<U>[] items) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariableIsOnTheoryClass() {
+ PrintableResult result = testResult(TypeVariableOnTheoryClass.class);
+ assertThat(result, hasSingleFailureContaining("unresolved type variable T"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariableOnTheoryClass<T> {
+ @DataPoint
+ public static String item = "bar";
+
+ @Theory
+ public void forItem(T item) {
+ }
+ }
+
+ @Test
+ public void whereTypeVariablesAbound() {
+ PrintableResult result = testResult(TypeVariablesAbound.class);
+ assertThat(result, failureCountIs(1));
+ assertThat(result, hasFailureContaining("unresolved type variable A"));
+ assertThat(result, hasFailureContaining("unresolved type variable B"));
+ assertThat(result, hasFailureContaining("unresolved type variable C"));
+ assertThat(result, hasFailureContaining("unresolved type variable D"));
+ assertThat(result, hasFailureContaining("unresolved type variable E"));
+ assertThat(result, hasFailureContaining("unresolved type variable F"));
+ assertThat(result, hasFailureContaining("unresolved type variable G"));
+ }
+
+ @RunWith(Theories.class)
+ public static class TypeVariablesAbound<A, B extends A, C extends Collection<B>> {
+ @Theory
+ public <D, E extends D, F, G> void forItem(A first, Collection<B> second,
+ Map<C, ? extends D> third, List<? super E> fourth, F[] fifth,
+ Collection<G>[] sixth) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllJUnit3CompatibilityTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllJUnit3CompatibilityTests.java
new file mode 100644
index 0000000..c85d01a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllJUnit3CompatibilityTests.java
@@ -0,0 +1,21 @@
+package org.junit.tests.junit3compatibility;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllTestsTest.class,
+ ClassRequestTest.class,
+ ForwardCompatibilityPrintingTest.class,
+ ForwardCompatibilityTest.class,
+ InitializationErrorForwardCompatibilityTest.class,
+ JUnit38ClassRunnerTest.class,
+ JUnit4TestAdapterTest.class,
+ OldTestClassAdaptingListenerTest.class,
+ OldTests.class,
+ SuiteMethodTest.class
+})
+public class AllJUnit3CompatibilityTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java
new file mode 100644
index 0000000..3f4a7f4
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java
@@ -0,0 +1,87 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.AllTests;
+
+public class AllTestsTest {
+
+ private static boolean run;
+
+ public static class OneTest extends TestCase {
+ public void testSomething() {
+ run = true;
+ }
+ }
+
+ @RunWith(AllTests.class)
+ public static class All {
+ public static junit.framework.Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(OneTest.class);
+ return suite;
+ }
+ }
+
+ @org.junit.Test
+ public void ensureTestIsRun() {
+ JUnitCore runner = new JUnitCore();
+ run = false; // Have to explicitly set run here because the runner might independently run OneTest above
+ runner.run(All.class);
+ assertTrue(run);
+ }
+
+ @org.junit.Test
+ public void correctTestCount() throws Throwable {
+ AllTests tests = new AllTests(All.class);
+ assertEquals(1, tests.testCount());
+ }
+
+ @org.junit.Test
+ public void someUsefulDescription() throws Throwable {
+ AllTests tests = new AllTests(All.class);
+ assertThat(tests.getDescription().toString(), containsString("OneTest"));
+ }
+
+ public static class JUnit4Test {
+ @org.junit.Test
+ public void testSomething() {
+ run = true;
+ }
+ }
+
+ @RunWith(AllTests.class)
+ public static class AllJUnit4 {
+ public static junit.framework.Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new JUnit4TestAdapter(JUnit4Test.class));
+ return suite;
+ }
+ }
+
+ @org.junit.Test
+ public void correctTestCountAdapted() throws Throwable {
+ AllTests tests = new AllTests(AllJUnit4.class);
+ assertEquals(1, tests.testCount());
+ }
+
+ @RunWith(AllTests.class)
+ public static class BadSuiteMethod {
+ public static junit.framework.Test suite() {
+ throw new RuntimeException("can't construct");
+ }
+ }
+
+ @org.junit.Test(expected = RuntimeException.class)
+ public void exceptionThrownWhenSuiteIsBad() throws Throwable {
+ new AllTests(BadSuiteMethod.class);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ClassRequestTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ClassRequestTest.java
new file mode 100644
index 0000000..4c5c2ce
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ClassRequestTest.java
@@ -0,0 +1,20 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.internal.builders.SuiteMethodBuilder;
+
+public class ClassRequestTest {
+ public static class PrivateSuiteMethod {
+ static junit.framework.Test suite() {
+ return null;
+ }
+ }
+
+ @Test
+ public void noSuiteMethodIfMethodPrivate() throws Throwable {
+ assertNull(new SuiteMethodBuilder()
+ .runnerForClass(PrivateSuiteMethod.class));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityPrintingTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityPrintingTest.java
new file mode 100644
index 0000000..cf40916
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityPrintingTest.java
@@ -0,0 +1,91 @@
+package org.junit.tests.junit3compatibility;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.textui.ResultPrinter;
+import junit.textui.TestRunner;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ForwardCompatibilityPrintingTest extends TestCase {
+ static class TestResultPrinter extends ResultPrinter {
+ TestResultPrinter(PrintStream writer) {
+ super(writer);
+ }
+
+ /*
+ * Spoof printing time so the tests are deterministic
+ */
+ @Override
+ protected String elapsedTimeAsString(long runTime) {
+ return "0";
+ }
+ }
+
+ public void testError() {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ TestRunner runner = new TestRunner(new TestResultPrinter(
+ new PrintStream(output)));
+
+ String expected = expected(new String[]{".E", "Time: 0",
+ "Errors here", "", "FAILURES!!!",
+ "Tests run: 1, Failures: 0, Errors: 1", ""});
+ ResultPrinter printer = new TestResultPrinter(new PrintStream(output)) {
+ @Override
+ public void printErrors(TestResult result) {
+ getWriter().println("Errors here");
+ }
+ };
+ runner.setPrinter(printer);
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestCase() {
+ @Override
+ public void runTest() throws Exception {
+ throw new Exception();
+ }
+ });
+ runner.doRun(suite);
+ assertEquals(expected, output.toString());
+ }
+
+ public static class ATest {
+ @Test
+ public void error() {
+ Assert.fail();
+ }
+ }
+
+ public void testErrorAdapted() {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ TestRunner runner = new TestRunner(new TestResultPrinter(
+ new PrintStream(output)));
+
+ String expected = expected(new String[]{".E", "Time: 0",
+ "Errors here", "", "FAILURES!!!",
+ "Tests run: 1, Failures: 0, Errors: 1", ""});
+ ResultPrinter printer = new TestResultPrinter(new PrintStream(output)) {
+ @Override
+ public void printErrors(TestResult result) {
+ getWriter().println("Errors here");
+ }
+ };
+ runner.setPrinter(printer);
+ runner.doRun(new JUnit4TestAdapter(ATest.class));
+ assertEquals(expected, output.toString());
+ }
+
+ private String expected(String[] lines) {
+ OutputStream expected = new ByteArrayOutputStream();
+ PrintStream expectedWriter = new PrintStream(expected);
+ for (int i = 0; i < lines.length; i++) {
+ expectedWriter.println(lines[i]);
+ }
+ return expected.toString();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java
new file mode 100644
index 0000000..79539d1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java
@@ -0,0 +1,254 @@
+package org.junit.tests.junit3compatibility;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+public class ForwardCompatibilityTest extends TestCase {
+ static String fLog;
+
+ public static class NewTest {
+ @Before
+ public void before() {
+ fLog += "before ";
+ }
+
+ @After
+ public void after() {
+ fLog += "after ";
+ }
+
+ @Test
+ public void test() {
+ fLog += "test ";
+ }
+ }
+
+ public void testCompatibility() {
+ fLog = "";
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(NewTest.class);
+ adapter.run(result);
+ assertEquals("before test after ", fLog);
+ }
+
+ public void testToString() {
+ JUnit4TestAdapter adapter = new JUnit4TestAdapter(NewTest.class);
+ junit.framework.Test test = adapter.getTests().get(0);
+ assertEquals(String.format("test(%s)", NewTest.class.getName()), test.toString());
+ }
+
+ public void testUseGlobalCache() {
+ JUnit4TestAdapter adapter1 = new JUnit4TestAdapter(NewTest.class);
+ JUnit4TestAdapter adapter2 = new JUnit4TestAdapter(NewTest.class);
+ assertSame(adapter1.getTests().get(0), adapter2.getTests().get(0));
+ }
+
+ static Exception exception = new Exception();
+
+ public static class ErrorTest {
+ @Test
+ public void error() throws Exception {
+ throw exception;
+ }
+ }
+
+ public void testException() {
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(ErrorTest.class);
+ adapter.run(result);
+ assertEquals(exception, result.errors().nextElement().thrownException());
+ }
+
+ public void testNotifyResult() {
+ JUnit4TestAdapter adapter = new JUnit4TestAdapter(ErrorTest.class);
+ TestResult result = new TestResult();
+ final StringBuffer log = new StringBuffer();
+ result.addListener(new TestListener() {
+
+ public void startTest(junit.framework.Test test) {
+ log.append(" start ").append(test);
+ }
+
+ public void endTest(junit.framework.Test test) {
+ log.append(" end ").append(test);
+ }
+
+ public void addFailure(junit.framework.Test test, AssertionFailedError t) {
+ log.append(" failure ").append(test);
+ }
+
+ public void addError(junit.framework.Test test, Throwable e) {
+ log.append(" error " + test);
+ }
+ });
+ adapter.run(result);
+ String testName = String.format("error(%s)", ErrorTest.class.getName());
+ assertEquals(String.format(" start %s error %s end %s", testName, testName, testName), log.toString());
+ }
+
+
+ public static class NoExceptionTest {
+ @Test(expected = Exception.class)
+ public void succeed() throws Exception {
+ }
+ }
+
+ public void testNoException() {
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(NoExceptionTest.class);
+ adapter.run(result);
+ assertFalse(result.wasSuccessful());
+ }
+
+ public static class ExpectedTest {
+ @Test(expected = Exception.class)
+ public void expected() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ public void testExpected() {
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(ExpectedTest.class);
+ adapter.run(result);
+ assertTrue(result.wasSuccessful());
+ }
+
+ public static class UnExpectedExceptionTest {
+ @Test(expected = Exception.class)
+ public void expected() throws Exception {
+ throw new Error();
+ }
+ }
+
+ static String log;
+
+ public static class BeforeClassTest {
+ @BeforeClass
+ public static void beforeClass() {
+ log += "before class ";
+ }
+
+ @Before
+ public void before() {
+ log += "before ";
+ }
+
+ @Test
+ public void one() {
+ log += "test ";
+ }
+
+ @Test
+ public void two() {
+ log += "test ";
+ }
+
+ @After
+ public void after() {
+ log += "after ";
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ log += "after class ";
+ }
+ }
+
+ public void testBeforeAndAfterClass() {
+ log = "";
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(BeforeClassTest.class);
+ adapter.run(result);
+ assertEquals("before class before test after before test after after class ", log);
+ }
+
+ public static class ExceptionInBeforeTest {
+ @Before
+ public void error() {
+ throw new Error();
+ }
+
+ @Test
+ public void nothing() {
+ }
+ }
+
+ public void testExceptionInBefore() {
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(ExceptionInBeforeTest.class);
+ adapter.run(result);
+ assertEquals(1, result.errorCount());
+ }
+
+ public static class InvalidMethodTest {
+ @BeforeClass
+ public void shouldBeStatic() {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ public void testInvalidMethod() {
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(InvalidMethodTest.class);
+ adapter.run(result);
+ assertEquals(1, result.errorCount());
+ TestFailure failure = result.errors().nextElement();
+ assertTrue(failure.exceptionMessage().contains("Method shouldBeStatic() should be static"));
+ }
+
+ private static boolean wasRun = false;
+
+ public static class MarkerRunner extends Runner {
+ public MarkerRunner(Class<?> klass) {
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ wasRun = true;
+ }
+
+ @Override
+ public int testCount() {
+ return 0;
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.EMPTY;
+ }
+ }
+
+ @RunWith(MarkerRunner.class)
+ public static class NoTests {
+ }
+
+ public void testRunWithClass() {
+ wasRun = false;
+ TestResult result = new TestResult();
+ junit.framework.Test adapter = new JUnit4TestAdapter(NoTests.class);
+ adapter.run(result);
+ assertTrue(wasRun);
+ }
+
+ public void testToStringSuite() {
+ junit.framework.Test adapter = new JUnit4TestAdapter(NoTests.class);
+ assertEquals(NoTests.class.getName(), adapter.toString());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/InitializationErrorForwardCompatibilityTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/InitializationErrorForwardCompatibilityTest.java
new file mode 100644
index 0000000..ec49701
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/InitializationErrorForwardCompatibilityTest.java
@@ -0,0 +1,102 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+public class InitializationErrorForwardCompatibilityTest {
+ public static class CantInitialize extends Runner {
+ private static final String UNIQUE_ERROR_MESSAGE = "Unique error message";
+
+ public CantInitialize(Class<?> klass) throws Exception {
+ throw new Exception(UNIQUE_ERROR_MESSAGE);
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.EMPTY;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ }
+ }
+
+ @RunWith(CantInitialize.class)
+ public static class CantInitializeTests {
+ }
+
+ private JUnit4TestAdapter fAdapter;
+
+ @Before
+ public void createAdapter() {
+ fAdapter = new JUnit4TestAdapter(
+ CantInitializeTests.class);
+ }
+
+ @Test
+ public void initializationErrorsShowUpAsWarnings() {
+ assertEquals(1, fAdapter.getTests().size());
+ }
+
+ @Test
+ public void initializationErrorsAreThrownAtRuntime() {
+ TestResult result = new TestResult();
+ fAdapter.run(result);
+ assertEquals(1, result.errorCount());
+ assertEquals(CantInitialize.UNIQUE_ERROR_MESSAGE, result.errors()
+ .nextElement().exceptionMessage());
+ }
+
+ private final class ErrorRememberingListener implements TestListener {
+ private junit.framework.Test fError;
+
+ public void addError(junit.framework.Test test, Throwable e) {
+ fError = test;
+ }
+
+ public void addFailure(junit.framework.Test test,
+ AssertionFailedError t) {
+ }
+
+ public void endTest(junit.framework.Test test) {
+ }
+
+ public void startTest(junit.framework.Test test) {
+ }
+
+ public junit.framework.Test getError() {
+ return fError;
+ }
+ }
+
+ @Test
+ public void generatedErrorTestsMatchUp() {
+ junit.framework.Test shouldFail = fAdapter.getTests().get(0);
+ TestResult result = new TestResult();
+ ErrorRememberingListener listener = new ErrorRememberingListener();
+ result.addListener(listener);
+ fAdapter.run(result);
+ assertNotNull(listener.getError());
+ assertTrue(shouldFail == listener.getError());
+ }
+
+ public static class InitializesWithError extends BlockJUnit4ClassRunner {
+ public InitializesWithError(Class<?> klass) throws Exception {
+ super(klass);
+ throw new Exception();
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java
new file mode 100644
index 0000000..429bde6
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java
@@ -0,0 +1,155 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import junit.extensions.TestDecorator;
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+
+public class JUnit38ClassRunnerTest {
+ public static class MyTest extends TestCase {
+ public void testA() {
+
+ }
+ }
+
+ @Test
+ public void plansDecoratorCorrectly() {
+ JUnit38ClassRunner runner = new JUnit38ClassRunner(new TestDecorator(new TestSuite(MyTest.class)));
+ assertEquals(1, runner.testCount());
+ }
+
+ public static class AnnotatedTest {
+ @Test
+ public void foo() {
+ Assert.fail();
+ }
+ }
+
+ @Test
+ public void canUnadaptAnAdapter() {
+ JUnit38ClassRunner runner = new JUnit38ClassRunner(new JUnit4TestAdapter(AnnotatedTest.class));
+ Result result = new JUnitCore().run(runner);
+ Failure failure = result.getFailures().get(0);
+ assertEquals(Description.createTestDescription(AnnotatedTest.class, "foo"), failure.getDescription());
+ }
+
+ static int count;
+
+ public static class OneTest extends TestCase {
+ public void testOne() {
+ }
+ }
+
+ @Test
+ public void testListener() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ RunListener listener = new RunListener() {
+ @Override
+ public void testStarted(Description description) {
+ assertEquals(Description.createTestDescription(OneTest.class, "testOne"),
+ description);
+ count++;
+ }
+ };
+
+ runner.addListener(listener);
+ count = 0;
+ Result result = runner.run(OneTest.class);
+ assertEquals(1, count);
+ assertEquals(1, result.getRunCount());
+ }
+
+ public static class ClassWithInvalidMethod extends TestCase {
+ @SuppressWarnings("unused")
+ private void testInvalid() {
+ }
+ }
+
+ @Test
+ public void invalidTestMethodReportedCorrectly() {
+ Result result = JUnitCore.runClasses(ClassWithInvalidMethod.class);
+ Failure failure = result.getFailures().get(0);
+ assertEquals("warning", failure.getDescription().getMethodName());
+ assertEquals("junit.framework.TestSuite$1", failure.getDescription().getClassName());
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public static @interface MyAnnotation {
+ }
+
+ public static class JUnit3ClassWithAnnotatedMethod extends TestCase {
+ @MyAnnotation
+ public void testAnnotated() {
+ }
+
+ public void testNotAnnotated() {
+ }
+ }
+
+ public static class DerivedAnnotatedMethod extends JUnit3ClassWithAnnotatedMethod {
+ }
+
+ @Test
+ public void getDescriptionWithAnnotation() {
+ JUnit38ClassRunner runner = new JUnit38ClassRunner(JUnit3ClassWithAnnotatedMethod.class);
+ assertAnnotationFiltering(runner);
+ }
+
+ @Test
+ public void getDescriptionWithAnnotationInSuper() {
+ JUnit38ClassRunner runner = new JUnit38ClassRunner(DerivedAnnotatedMethod.class);
+ assertAnnotationFiltering(runner);
+ }
+
+ private void assertAnnotationFiltering(JUnit38ClassRunner runner) {
+ Description d = runner.getDescription();
+ assertEquals(2, d.testCount());
+ for (Description methodDesc : d.getChildren()) {
+ if (methodDesc.getMethodName().equals("testAnnotated")) {
+ assertNotNull(methodDesc.getAnnotation(MyAnnotation.class));
+ } else {
+ assertNull(methodDesc.getAnnotation(MyAnnotation.class));
+ }
+ }
+ }
+
+ public static class RejectAllTestsFilter extends Filter {
+ @Override
+ public boolean shouldRun(Description description) {
+ return description.isSuite();
+ }
+
+ @Override
+ public String describe() {
+ return "filter all";
+ }
+ }
+
+ /**
+ * Test that NoTestsRemainException is thrown when all methods have been filtered.
+ */
+ @Test(expected = NoTestsRemainException.class)
+ public void filterNoTestsRemain() throws NoTestsRemainException {
+ JUnit38ClassRunner runner = new JUnit38ClassRunner(OneTest.class);
+ runner.filter(new RejectAllTestsFilter());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit4TestAdapterTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit4TestAdapterTest.java
new file mode 100644
index 0000000..8d20f33
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/JUnit4TestAdapterTest.java
@@ -0,0 +1,82 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collections;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+public class JUnit4TestAdapterTest {
+
+ private static void doTest(Class<?> clazz) {
+ // JUnit 4 runner:
+ Result result = JUnitCore.runClasses(clazz);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+
+ // JUnit 3 runner:
+ TestResult testResult = new TestResult();
+ new JUnit4TestAdapter(clazz).run(testResult);
+ assertEquals(1, testResult.runCount());
+ assertEquals(0, testResult.failureCount());
+ assertEquals(Collections.emptyList(), Collections.list(testResult.errors()));
+ }
+
+ public static class Test4 {
+ @Test
+ public void pass() throws Exception {
+ //pass
+ }
+ }
+
+ @RunWith(Suite.class)
+ @Suite.SuiteClasses(Test4.class)
+ public static class TestSuiteFor4 {
+ }
+
+ @Test
+ public void testJUnit4Suite() {
+ doTest(TestSuiteFor4.class);
+ }
+
+ public static class Test3 extends TestCase {
+ public void testPass() throws Exception {
+ //pass
+ }
+ }
+
+ @RunWith(Suite.class)
+ @Suite.SuiteClasses(Test3.class)
+ public static class TestSuiteFor3 {
+ }
+
+ @Test
+ public void testJUnit3Suite() {
+ doTest(TestSuiteFor3.class);
+ }
+
+ public static class TestSuite3 {
+ public static junit.framework.Test suite() {
+ return new TestSuite(Test3.class);
+ }
+ }
+
+ @RunWith(Suite.class)
+ @Suite.SuiteClasses(TestSuite3.class)
+ public static class TestSuite4ForTestSuite3 {
+ }
+
+ @Test
+ public void testJUnit4SuiteThatContainsJUnit3SuiteClass() {
+ doTest(TestSuite4ForTestSuite3.class);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTestClassAdaptingListenerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTestClassAdaptingListenerTest.java
new file mode 100644
index 0000000..9822b14
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTestClassAdaptingListenerTest.java
@@ -0,0 +1,28 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertEquals;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import org.junit.Test;
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.runner.Result;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+public class OldTestClassAdaptingListenerTest {
+ @Test
+ public void addFailureDelegatesToNotifier() {
+ Result result = new Result();
+ RunListener listener = result.createListener();
+ RunNotifier notifier = new RunNotifier();
+ notifier.addFirstListener(listener);
+ TestCase testCase = new TestCase() {
+ };
+ TestListener adaptingListener = new JUnit38ClassRunner(testCase)
+ .createAdaptingListener(notifier);
+ adaptingListener.addFailure(testCase, new AssertionFailedError());
+ assertEquals(1, result.getFailureCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTests.java
new file mode 100644
index 0000000..bee32f5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/OldTests.java
@@ -0,0 +1,12 @@
+package org.junit.tests.junit3compatibility;
+
+import junit.framework.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.AllTests;
+
+@RunWith(AllTests.class)
+public class OldTests {
+ public static Test suite() {
+ return junit.tests.AllTests.suite();
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java
new file mode 100644
index 0000000..55c1cd1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java
@@ -0,0 +1,134 @@
+package org.junit.tests.junit3compatibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+
+public class SuiteMethodTest {
+ public static boolean wasRun;
+
+ public static class OldTest extends TestCase {
+ public OldTest(String name) {
+ super(name);
+ }
+
+ public static junit.framework.Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new OldTest("notObviouslyATest"));
+ return suite;
+ }
+
+ public void notObviouslyATest() {
+ wasRun = true;
+ }
+ }
+
+ @Test
+ public void makeSureSuiteIsCalled() {
+ wasRun = false;
+ JUnitCore.runClasses(OldTest.class);
+ assertTrue(wasRun);
+ }
+
+ public static class NewTest {
+ @Test
+ public void sample() {
+ wasRun = true;
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(NewTest.class);
+ }
+ }
+
+ @Test
+ public void makeSureSuiteWorksWithJUnit4Classes() {
+ wasRun = false;
+ JUnitCore.runClasses(NewTest.class);
+ assertTrue(wasRun);
+ }
+
+
+ public static class CompatibilityTest {
+ @Ignore
+ @Test
+ public void ignored() {
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(CompatibilityTest.class);
+ }
+ }
+
+ // when executing as JUnit 3, ignored tests are stripped out before execution
+ @Test
+ public void descriptionAndRunNotificationsAreConsistent() {
+ Result result = JUnitCore.runClasses(CompatibilityTest.class);
+ assertEquals(0, result.getIgnoreCount());
+
+ Description description = Request.aClass(CompatibilityTest.class).getRunner().getDescription();
+ assertEquals(0, description.getChildren().size());
+ }
+
+ public static class NewTestSuiteFails {
+ @Test
+ public void sample() {
+ wasRun = true;
+ }
+
+ public static junit.framework.Test suite() {
+ fail("called with JUnit 4 runner");
+ return null;
+ }
+ }
+
+ @Test
+ public void suiteIsUsedWithJUnit4Classes() {
+ wasRun = false;
+ Result result = JUnitCore.runClasses(NewTestSuiteFails.class);
+ assertEquals(1, result.getFailureCount());
+ assertFalse(wasRun);
+ }
+
+ public static class NewTestSuiteNotUsed {
+ private static boolean wasIgnoredRun;
+
+ @Test
+ public void sample() {
+ wasRun = true;
+ }
+
+ @Ignore
+ @Test
+ public void ignore() {
+ wasIgnoredRun = true;
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(NewTestSuiteNotUsed.class);
+ }
+ }
+
+ @Test
+ public void makeSureSuiteNotUsedWithJUnit4Classes2() {
+ wasRun = false;
+ NewTestSuiteNotUsed.wasIgnoredRun = false;
+ Result res = JUnitCore.runClasses(NewTestSuiteNotUsed.class);
+ assertTrue(wasRun);
+ assertFalse(NewTestSuiteNotUsed.wasIgnoredRun);
+ assertEquals(0, res.getFailureCount());
+ assertEquals(1, res.getRunCount());
+ assertEquals(0, res.getIgnoreCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/AllListeningTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/AllListeningTests.java
new file mode 100644
index 0000000..cadbd2e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/AllListeningTests.java
@@ -0,0 +1,16 @@
+package org.junit.tests.listening;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ListenerTest.class,
+ RunnerTest.class,
+ TestListenerTest.class,
+ TextListenerTest.class,
+ UserStopTest.class
+})
+public class AllListeningTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/ListenerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/ListenerTest.java
new file mode 100644
index 0000000..b300339
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/ListenerTest.java
@@ -0,0 +1,38 @@
+package org.junit.tests.listening;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.notification.RunListener;
+
+public class ListenerTest {
+ private static String log;
+
+ public static class OneTest {
+ @Test
+ public void nothing() {
+ }
+ }
+
+ @Test
+ public void notifyListenersInTheOrderInWhichTheyAreAdded() {
+ JUnitCore core = new JUnitCore();
+ log = "";
+ core.addListener(new RunListener() {
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ log += "first ";
+ }
+ });
+ core.addListener(new RunListener() {
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ log += "second ";
+ }
+ });
+ core.run(OneTest.class);
+ assertEquals("first second ", log);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/RunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/RunnerTest.java
new file mode 100644
index 0000000..cd12c35
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/RunnerTest.java
@@ -0,0 +1,75 @@
+package org.junit.tests.listening;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.notification.RunListener;
+
+public class RunnerTest {
+
+ private boolean wasRun;
+
+ public class MyListener extends RunListener {
+
+ int testCount;
+
+ @Override
+ public void testRunStarted(Description description) {
+ this.testCount = description.testCount();
+ }
+ }
+
+ public static class Example {
+ @Test
+ public void empty() {
+ }
+ }
+
+ @Test
+ public void newTestCount() {
+ JUnitCore runner = new JUnitCore();
+ MyListener listener = new MyListener();
+ runner.addListener(listener);
+ runner.run(Example.class);
+ assertEquals(1, listener.testCount);
+ }
+
+ public static class ExampleTest extends TestCase {
+ public void testEmpty() {
+ }
+ }
+
+ @Test
+ public void oldTestCount() {
+ JUnitCore runner = new JUnitCore();
+ MyListener listener = new MyListener();
+ runner.addListener(listener);
+ runner.run(ExampleTest.class);
+ assertEquals(1, listener.testCount);
+ }
+
+ public static class NewExample {
+ @Test
+ public void empty() {
+ }
+ }
+
+ @Test
+ public void testFinished() {
+ JUnitCore runner = new JUnitCore();
+ wasRun = false;
+ RunListener listener = new MyListener() {
+ @Override
+ public void testFinished(Description description) {
+ wasRun = true;
+ }
+ };
+ runner.addListener(listener);
+ runner.run(NewExample.class);
+ assertTrue(wasRun);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TestListenerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TestListenerTest.java
new file mode 100644
index 0000000..693c15e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TestListenerTest.java
@@ -0,0 +1,65 @@
+package org.junit.tests.listening;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class TestListenerTest {
+
+ int count;
+
+ class ErrorListener extends RunListener {
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ throw new Error();
+ }
+ }
+
+ public static class OneTest {
+ @Test
+ public void nothing() {
+ }
+ }
+
+ @Test(expected = Error.class)
+ public void failingListener() {
+ JUnitCore runner = new JUnitCore();
+ runner.addListener(new ErrorListener());
+ runner.run(OneTest.class);
+ }
+
+ class ExceptionListener extends ErrorListener {
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ count++;
+ throw new Exception();
+ }
+ }
+
+ @Test
+ public void reportsFailureOfListener() {
+ JUnitCore core = new JUnitCore();
+ core.addListener(new ExceptionListener());
+
+ count = 0;
+ Result result = core.run(OneTest.class);
+ assertEquals(1, count);
+ assertEquals(1, result.getFailureCount());
+ Failure testFailure = result.getFailures().get(0);
+ assertEquals(Description.TEST_MECHANISM, testFailure.getDescription());
+ }
+
+ @Test
+ public void freshResultEachTime() {
+ JUnitCore core = new JUnitCore();
+ Result first = core.run(OneTest.class);
+ Result second = core.run(OneTest.class);
+ assertNotSame(first, second);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TextListenerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TextListenerTest.java
new file mode 100644
index 0000000..0cb1aff
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/TextListenerTest.java
@@ -0,0 +1,73 @@
+package org.junit.tests.listening;
+
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.internal.TextListener;
+import org.junit.runner.JUnitCore;
+import org.junit.tests.TestSystem;
+
+public class TextListenerTest extends TestCase {
+
+ private JUnitCore runner;
+ private OutputStream results;
+
+ @Override
+ public void setUp() {
+ runner = new JUnitCore();
+ TestSystem system = new TestSystem();
+ results = system.outContents();
+ runner.addListener(new TextListener(system));
+ }
+
+ public static class OneTest {
+ @Test
+ public void one() {
+ }
+ }
+
+ public void testSuccess() throws Exception {
+ runner.run(OneTest.class);
+ assertTrue(results.toString().startsWith(convert(".\nTime: ")));
+ assertTrue(results.toString().endsWith(convert("\n\nOK (1 test)\n\n")));
+ }
+
+ public static class ErrorTest {
+ @Test
+ public void error() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ public void testError() throws Exception {
+ runner.run(ErrorTest.class);
+ assertTrue(results.toString().startsWith(convert(".E\nTime: ")));
+ assertTrue(results.toString().indexOf(convert("\nThere was 1 failure:\n1) error(org.junit.tests.listening.TextListenerTest$ErrorTest)\njava.lang.Exception")) != -1);
+ }
+
+ public static class Time {
+ @Test
+ public void time() {
+ }
+ }
+
+ public void testTime() {
+ runner.run(Time.class);
+ assertThat(results.toString(), containsString("Time: "));
+ assertThat(results.toString(), not(containsString(convert("Time: \n"))));
+ }
+
+ private String convert(String string) {
+ OutputStream resultsStream = new ByteArrayOutputStream();
+ PrintStream writer = new PrintStream(resultsStream);
+ writer.println();
+ return string.replace("\n", resultsStream.toString());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/UserStopTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/UserStopTest.java
new file mode 100644
index 0000000..1233cce
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/listening/UserStopTest.java
@@ -0,0 +1,33 @@
+package org.junit.tests.listening;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.Request;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runner.notification.StoppedByUserException;
+
+public class UserStopTest {
+ private RunNotifier fNotifier;
+
+ @Before
+ public void createNotifier() {
+ fNotifier = new RunNotifier();
+ fNotifier.pleaseStop();
+ }
+
+ @Test(expected = StoppedByUserException.class)
+ public void userStop() {
+ fNotifier.fireTestStarted(null);
+ }
+
+ public static class OneTest {
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test(expected = StoppedByUserException.class)
+ public void stopClassRunner() throws Exception {
+ Request.aClass(OneTest.class).getRunner().run(fNotifier);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AllManipulationTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AllManipulationTests.java
new file mode 100644
index 0000000..5989e1b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AllManipulationTests.java
@@ -0,0 +1,17 @@
+package org.junit.tests.manipulation;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ FilterableTest.class,
+ FilterTest.class,
+ OrderableTest.class,
+ OrderWithTest.class,
+ SingleMethodTest.class,
+ SortableTest.class
+})
+public class AllManipulationTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AlphanumericOrdering.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AlphanumericOrdering.java
new file mode 100644
index 0000000..ff1a513
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/AlphanumericOrdering.java
@@ -0,0 +1,15 @@
+package org.junit.tests.manipulation;
+
+import org.junit.runner.manipulation.Ordering;
+
+/**
+ * An ordering that orders tests alphanumerically by test name.
+ */
+public final class AlphanumericOrdering implements Ordering.Factory {
+ public static final ComparatorBasedOrdering INSTANCE = new ComparatorBasedOrdering(
+ Comparators.alphanumeric());
+
+ public Ordering create(Ordering.Context context) {
+ return INSTANCE;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ComparatorBasedOrdering.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ComparatorBasedOrdering.java
new file mode 100644
index 0000000..6eff4a9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ComparatorBasedOrdering.java
@@ -0,0 +1,28 @@
+package org.junit.tests.manipulation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Ordering;
+
+/**
+ * An ordering that internally uses a {@link Comparator}.
+ */
+class ComparatorBasedOrdering extends Ordering {
+ private final Comparator<Description> comparator;
+
+ protected ComparatorBasedOrdering(Comparator<Description> comparator) {
+ this.comparator = comparator;
+ }
+
+ @Override
+ protected List<Description> orderItems(Collection<Description> descriptions) {
+ List<Description> ordered = new ArrayList<Description>(descriptions);
+ Collections.sort(ordered, comparator);
+ return ordered;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/Comparators.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/Comparators.java
new file mode 100644
index 0000000..8c61e89
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/Comparators.java
@@ -0,0 +1,19 @@
+package org.junit.tests.manipulation;
+
+import java.util.Comparator;
+
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Alphanumeric;
+
+/**
+ * Factory and utility methods for creating {@link Comparator} instances for tests.
+ */
+class Comparators {
+ private static final Comparator<Description> ALPHANUMERIC = new Alphanumeric();
+
+ private Comparators() {}
+
+ public static Comparator<Description> alphanumeric() {
+ return ALPHANUMERIC;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterTest.java
new file mode 100644
index 0000000..a9c0136
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterTest.java
@@ -0,0 +1,50 @@
+package org.junit.tests.manipulation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.manipulation.Filter;
+
+public class FilterTest {
+ public static class NamedFilter extends Filter {
+ private final String fName;
+
+ public NamedFilter(String name) {
+ fName = name;
+ }
+
+ @Override
+ public boolean shouldRun(Description description) {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return fName;
+ }
+ }
+
+ @Test
+ public void intersectionText() {
+ NamedFilter a = new NamedFilter("a");
+ NamedFilter b = new NamedFilter("b");
+ assertEquals("a and b", a.intersect(b).describe());
+ assertEquals("b and a", b.intersect(a).describe());
+ }
+
+ @Test
+ public void intersectSelf() {
+ NamedFilter a = new NamedFilter("a");
+ assertSame(a, a.intersect(a));
+ }
+
+ @Test
+ public void intersectAll() {
+ NamedFilter a = new NamedFilter("a");
+ assertSame(a, a.intersect(Filter.ALL));
+ assertSame(a, Filter.ALL.intersect(a));
+ assertSame(Filter.ALL, Filter.ALL.intersect(Filter.ALL));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterableTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterableTest.java
new file mode 100644
index 0000000..f1f5060
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/FilterableTest.java
@@ -0,0 +1,62 @@
+package org.junit.tests.manipulation;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+public class FilterableTest {
+ public static class FilteredRunner extends Parameterized {
+ public FilteredRunner(Class<?> klass) throws Throwable {
+ super(klass);
+ filter(new Filter() {
+
+ @Override
+ public boolean shouldRun(Description description) {
+ return !description.getDisplayName().contains("skip");
+ }
+
+ @Override
+ public String describe() {
+ return "skip methods containing the word 'skip'";
+ }
+ });
+ }
+ }
+
+ @RunWith(FilteredRunner.class)
+ public static class FilteredTest {
+ @Parameters
+ public static List<Object[]> parameters() {
+ return Arrays.asList(new Object[]{3}, new Object[]{4});
+ }
+
+ public FilteredTest(int x) {
+ }
+
+ @Test
+ public void skipThis() {
+ Assert.fail();
+ }
+
+ @Test
+ public void runThis() {
+ }
+ }
+
+ @Test
+ public void testFilterInRunnerConstructor() {
+ Result result = JUnitCore.runClasses(FilteredTest.class);
+ assertTrue(result.wasSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderWithTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderWithTest.java
new file mode 100644
index 0000000..bfefeb3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderWithTest.java
@@ -0,0 +1,268 @@
+package org.junit.tests.manipulation;
+
+import static org.junit.Assert.assertEquals;
+import junit.framework.JUnit4TestAdapter;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.OrderWith;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Alphanumeric;
+import org.junit.runner.notification.RunNotifier;
+
+@RunWith(Enclosed.class)
+public class OrderWithTest {
+
+ public static class TestClassRunnerIsOrderableViaOrderWith {
+ private static String log = "";
+
+ public static class Unordered {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @OrderWith(AlphanumericOrdering.class)
+ public static class OrderedAlphanumerically extends Unordered {
+ }
+
+ @OrderWith(ReverseAlphanumericOrdering.class)
+ public static class OrderedReverseAlphanumerically extends Unordered {
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void orderingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(OrderedAlphanumerically.class);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(OrderedReverseAlphanumerically.class);
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+
+ @RunWith(Enclosed.class)
+ public static class UnorderedSuite {
+ public static class A {
+ @Test
+ public void a() {
+ log += "Aa";
+ }
+
+ @Test
+ public void b() {
+ log += "Ab";
+ }
+
+ @Test
+ public void c() {
+ log += "Ac";
+ }
+ }
+
+ public static class B {
+ @Test
+ public void a() {
+ log += "Ba";
+ }
+
+ @Test
+ public void b() {
+ log += "Bb";
+ }
+
+ @Test
+ public void c() {
+ log += "Bc";
+ }
+ }
+ }
+
+ @OrderWith(AlphanumericOrdering.class)
+ public static class SuiteOrderedAlphanumerically extends UnorderedSuite {
+ }
+
+ @OrderWith(ReverseAlphanumericOrdering.class)
+ public static class SuiteOrderedReverseAlphanumerically extends UnorderedSuite {
+ }
+
+ @Test
+ public void orderingForwardWorksOnSuite() {
+ Request forward = Request.aClass(SuiteOrderedAlphanumerically.class);
+
+ new JUnitCore().run(forward);
+ assertEquals("AaAbAcBaBbBc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnSuite() {
+ Request backward = Request.aClass(SuiteOrderedReverseAlphanumerically.class);
+
+ new JUnitCore().run(backward);
+ assertEquals("BcBbBaAcAbAa", log);
+ }
+ }
+
+ public static class TestClassRunnerIsSortableViaOrderWith {
+ private static String log = "";
+
+ public static class Unordered {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @OrderWith(Alphanumeric.class)
+ public static class SortedAlphanumerically extends Unordered {
+ }
+
+ @OrderWith(ReverseAlphanumericSorter.class)
+ public static class SortedReverseAlphanumerically extends Unordered {
+ }
+
+ @Test
+ public void sortingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(SortedAlphanumerically.class);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void sortingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(SortedReverseAlphanumerically.class);
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+
+ public static class TestClassRunnerIsOrderableWithSuiteMethod {
+ private static String log = "";
+
+ public static class Unordered {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @OrderWith(AlphanumericOrdering.class)
+ public static class OrderedAlphanumerically extends Unordered {
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(OrderedAlphanumerically.class);
+ }
+ }
+
+ @OrderWith(ReverseAlphanumericOrdering.class)
+ public static class OrderedReverseAlphanumerically extends Unordered {
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(OrderedReverseAlphanumerically.class);
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void orderingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(OrderedAlphanumerically.class);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(OrderedReverseAlphanumerically.class);
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+
+ public static class UnOrderableRunnersAreHandledWithoutCrashing {
+ public static class UnOrderableRunner extends Runner {
+ public UnOrderableRunner(Class<?> klass) {
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.EMPTY;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ }
+ }
+
+ @RunWith(UnOrderableRunner.class)
+ public static class UnOrderable {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void unOrderablesAreHandledWithoutCrashing() {
+ Request unordered = Request.aClass(UnOrderable.class).orderWith(
+ AlphanumericOrdering.INSTANCE);
+ new JUnitCore().run(unordered);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderableTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderableTest.java
new file mode 100644
index 0000000..4adfac2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/OrderableTest.java
@@ -0,0 +1,301 @@
+package org.junit.tests.manipulation;
+
+import static org.junit.Assert.assertEquals;
+import junit.framework.JUnit4TestAdapter;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.MethodSorters;
+
+@RunWith(Enclosed.class)
+public class OrderableTest {
+
+ public static class TestClassRunnerIsOrderable {
+ private static String log = "";
+
+ public static class OrderMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class DoNotOrderMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void orderingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(OrderMe.class).orderWith(
+ AlphanumericOrdering.INSTANCE);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(OrderMe.class).orderWith(
+ new ReverseAlphanumericOrdering());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+
+ @Test
+ public void orderingBackwardDoesNothingOnTestClassRunnerWithFixMethodOrder() {
+ Request backward = Request.aClass(DoNotOrderMe.class).orderWith(
+ new ReverseAlphanumericOrdering());
+
+ new JUnitCore().run(backward);
+ assertEquals("abc", log);
+ }
+
+ @RunWith(Enclosed.class)
+ public static class Enclosing {
+ public static class A {
+ @Test
+ public void a() {
+ log += "Aa";
+ }
+
+ @Test
+ public void b() {
+ log += "Ab";
+ }
+
+ @Test
+ public void c() {
+ log += "Ac";
+ }
+ }
+
+ public static class B {
+ @Test
+ public void a() {
+ log += "Ba";
+ }
+
+ @Test
+ public void b() {
+ log += "Bb";
+ }
+
+ @Test
+ public void c() {
+ log += "Bc";
+ }
+ }
+ }
+
+ @Test
+ public void orderingForwardWorksOnSuite() {
+ Request forward = Request.aClass(Enclosing.class).orderWith(
+ AlphanumericOrdering.INSTANCE);
+
+ new JUnitCore().run(forward);
+ assertEquals("AaAbAcBaBbBc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnSuite() {
+ Request backward = Request.aClass(Enclosing.class).orderWith(
+ new ReverseAlphanumericOrdering());
+
+ new JUnitCore().run(backward);
+ assertEquals("BcBbBaAcAbAa", log);
+ }
+ }
+
+ public static class TestOrderableClassRunnerIsSortable {
+ private static String log = "";
+
+ /**
+ * A Runner that implements {@link Orderable}.
+ */
+ public static class OrderableRunner extends Runner implements Orderable {
+ private final BlockJUnit4ClassRunner delegate;
+
+ public OrderableRunner(Class<?> klass) throws Throwable {
+ delegate = new BlockJUnit4ClassRunner(klass);
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ delegate.run(notifier);
+ }
+
+ @Override
+ public Description getDescription() {
+ return delegate.getDescription();
+ }
+
+ public void order(Orderer orderer) throws InvalidOrderingException {
+ delegate.order(orderer);
+ }
+
+ public void sort(Sorter sorter) {
+ delegate.sort(sorter);
+ }
+ }
+
+ @RunWith(OrderableRunner.class)
+ public static class OrderMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void orderingorwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(OrderMe.class).orderWith(
+ AlphanumericOrdering.INSTANCE);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void orderedBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(OrderMe.class).orderWith(
+ new ReverseAlphanumericOrdering());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+
+ public static class TestClassRunnerIsOrderableWithSuiteMethod {
+ private static String log = "";
+
+ public static class OrderMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(OrderMe.class);
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void orderingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(OrderMe.class).orderWith(AlphanumericOrdering.INSTANCE);
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void orderingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(OrderMe.class).orderWith(
+ new ReverseAlphanumericOrdering());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+
+ public static class UnOrderableRunnersAreHandledWithoutCrashing {
+ public static class UnOrderableRunner extends Runner {
+ public UnOrderableRunner(Class<?> klass) {
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.EMPTY;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ }
+ }
+
+ @RunWith(UnOrderableRunner.class)
+ public static class UnOrderable {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void unOrderablesAreHandledWithoutCrashing() {
+ Request unordered = Request.aClass(UnOrderable.class).orderWith(
+ AlphanumericOrdering.INSTANCE);
+ new JUnitCore().run(unordered);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericOrdering.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericOrdering.java
new file mode 100644
index 0000000..b93d5c6
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericOrdering.java
@@ -0,0 +1,20 @@
+package org.junit.tests.manipulation;
+
+import static java.util.Collections.reverseOrder;
+
+import org.junit.runner.manipulation.Ordering;
+
+/**
+ * An ordering that orders tests reverse alphanumerically by test name.
+ */
+public final class ReverseAlphanumericOrdering extends ComparatorBasedOrdering
+ implements Ordering.Factory {
+
+ public ReverseAlphanumericOrdering() {
+ super(reverseOrder(Comparators.alphanumeric()));
+ }
+
+ public Ordering create(Context context) {
+ return this;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericSorter.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericSorter.java
new file mode 100644
index 0000000..415253e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/ReverseAlphanumericSorter.java
@@ -0,0 +1,16 @@
+package org.junit.tests.manipulation;
+
+import static java.util.Collections.reverseOrder;
+
+import org.junit.runner.manipulation.Ordering;
+import org.junit.runner.manipulation.Sorter;
+
+/**
+ * A sorter that orders tests reverse alphanumerically by test name.
+ */
+public final class ReverseAlphanumericSorter implements Ordering.Factory {
+
+ public Ordering create(Ordering.Context context) {
+ return new Sorter(reverseOrder(Comparators.alphanumeric()));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SingleMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SingleMethodTest.java
new file mode 100644
index 0000000..a153407
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SingleMethodTest.java
@@ -0,0 +1,190 @@
+package org.junit.tests.manipulation;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.JUnit4TestAdapter;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+public class SingleMethodTest {
+ public static int count;
+
+ public static class OneTimeSetup {
+ @BeforeClass
+ public static void once() {
+ count++;
+ }
+
+ @Test
+ public void one() {
+ }
+
+ @Test
+ public void two() {
+ }
+ }
+
+ @Test
+ public void oneTimeSetup() throws Exception {
+ count = 0;
+ Runner runner = Request.method(OneTimeSetup.class, "one").getRunner();
+ Result result = new JUnitCore().run(runner);
+
+ assertEquals(1, count);
+ assertEquals(1, result.getRunCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParameterizedOneTimeSetup {
+ @Parameters
+ public static List<Object[]> params() {
+ return Arrays.asList(new Object[]{1}, new Object[]{2});
+ }
+
+ public ParameterizedOneTimeSetup(int x) {
+ }
+
+ @Test
+ public void one() {
+ }
+ }
+
+ @Test
+ public void parameterizedFilterToSingleMethod() throws Exception {
+ count = 0;
+ Runner runner = Request.method(ParameterizedOneTimeSetup.class,
+ "one[0]").getRunner();
+ Result result = new JUnitCore().run(runner);
+
+ assertEquals(1, result.getRunCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParameterizedOneTimeBeforeClass {
+ @Parameters
+ public static List<Object[]> params() {
+ return Arrays.asList(new Object[]{1}, new Object[]{2});
+ }
+
+ public ParameterizedOneTimeBeforeClass(int x) {
+ }
+
+ @BeforeClass
+ public static void once() {
+ count++;
+ }
+
+ @Test
+ public void one() {
+ }
+ }
+
+
+ @Test
+ public void parameterizedBeforeClass() throws Exception {
+ count = 0;
+ JUnitCore.runClasses(ParameterizedOneTimeBeforeClass.class);
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void filteringAffectsPlan() throws Exception {
+ Runner runner = Request.method(OneTimeSetup.class, "one").getRunner();
+ assertEquals(1, runner.testCount());
+ }
+
+ @Test
+ public void nonexistentMethodCreatesFailure() throws Exception {
+ assertEquals(1, new JUnitCore().run(
+ Request.method(OneTimeSetup.class, "thisMethodDontExist"))
+ .getFailureCount());
+ }
+
+ @Test(expected = NoTestsRemainException.class)
+ public void filteringAwayEverythingThrowsException() throws NoTestsRemainException {
+ Filterable runner = (Filterable) Request.aClass(OneTimeSetup.class).getRunner();
+ runner.filter(new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ return null;
+ }
+ });
+ }
+
+ public static class TestOne {
+ @Test
+ public void a() {
+ }
+
+ @Test
+ public void b() {
+ }
+ }
+
+ public static class TestTwo {
+ @Test
+ public void a() {
+ }
+
+ @Test
+ public void b() {
+ }
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({TestOne.class, TestTwo.class})
+ public static class OneTwoSuite {
+ }
+
+ @Test
+ public void eliminateUnnecessaryTreeBranches() throws Exception {
+ Runner runner = Request.aClass(OneTwoSuite.class).filterWith(
+ Description.createTestDescription(TestOne.class, "a"))
+ .getRunner();
+ Description description = runner.getDescription();
+ assertEquals(1, description.getChildren().size());
+ }
+
+ public static class HasSuiteMethod {
+ @Test
+ public void a() {
+ }
+
+ @Test
+ public void b() {
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(HasSuiteMethod.class);
+ }
+ }
+
+ @Test
+ public void classesWithSuiteMethodsAreFiltered() {
+ int testCount = Request.method(HasSuiteMethod.class, "a").getRunner().getDescription().testCount();
+ assertThat(testCount, is(1));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SortableTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SortableTest.java
new file mode 100644
index 0000000..5857ca0
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/manipulation/SortableTest.java
@@ -0,0 +1,302 @@
+package org.junit.tests.manipulation;
+
+import static java.util.Collections.reverseOrder;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Comparator;
+
+import junit.framework.JUnit4TestAdapter;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.MethodSorters;
+
+@RunWith(Enclosed.class)
+public class SortableTest {
+ private static Comparator<Description> forward() {
+ return Comparators.alphanumeric();
+ }
+
+ private static Comparator<Description> backward() {
+ return reverseOrder(Comparators.alphanumeric());
+ }
+
+ public static class TestClassRunnerIsSortable {
+ private static String log = "";
+
+ public static class SortMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class DoNotSortMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void sortingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(SortMe.class).sortWith(forward());
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void sortingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(SortMe.class).sortWith(backward());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+
+ @Test
+ public void sortingBackwardDoesNothingOnTestClassRunnerWithFixMethodOrder() {
+ Request backward = Request.aClass(DoNotSortMe.class).sortWith(backward());
+
+ new JUnitCore().run(backward);
+ assertEquals("abc", log);
+ }
+
+ @RunWith(Enclosed.class)
+ public static class Enclosing {
+ public static class A {
+ @Test
+ public void a() {
+ log += "Aa";
+ }
+
+ @Test
+ public void b() {
+ log += "Ab";
+ }
+
+ @Test
+ public void c() {
+ log += "Ac";
+ }
+ }
+
+ public static class B {
+ @Test
+ public void a() {
+ log += "Ba";
+ }
+
+ @Test
+ public void b() {
+ log += "Bb";
+ }
+
+ @Test
+ public void c() {
+ log += "Bc";
+ }
+ }
+ }
+
+ @Test
+ public void sortingForwardWorksOnSuite() {
+ Request forward = Request.aClass(Enclosing.class).sortWith(forward());
+
+ new JUnitCore().run(forward);
+ assertEquals("AaAbAcBaBbBc", log);
+ }
+
+ @Test
+ public void sortingBackwardWorksOnSuite() {
+ Request backward = Request.aClass(Enclosing.class).sortWith(backward());
+
+ new JUnitCore().run(backward);
+ assertEquals("BcBbBaAcAbAa", log);
+ }
+ }
+
+ public static class TestClassRunnerIsSortableWithSuiteMethod {
+ private static String log = "";
+
+ public static class SortMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(SortMe.class);
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void sortingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(SortMe.class).sortWith(forward());
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void sortingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(SortMe.class).sortWith(backward());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+
+ public static class UnsortableRunnersAreHandledWithoutCrashing {
+ public static class UnsortableRunner extends Runner {
+ public UnsortableRunner(Class<?> klass) {
+ }
+
+ @Override
+ public Description getDescription() {
+ return Description.EMPTY;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ }
+ }
+
+ @RunWith(UnsortableRunner.class)
+ public static class Unsortable {
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test
+ public void unsortablesAreHandledWithoutCrashing() {
+ Request unsorted = Request.aClass(Unsortable.class).sortWith(forward());
+ new JUnitCore().run(unsorted);
+ }
+ }
+
+ public static class TestOnlySortableClassRunnerIsSortable {
+ private static String log = "";
+
+ /**
+ * A Runner that implements {@link Sortable} but not {@link Orderable}.
+ */
+ public static class SortableRunner extends Runner implements Sortable {
+ private final BlockJUnit4ClassRunner delegate;
+
+ public SortableRunner(Class<?> klass) throws Throwable {
+ delegate = new BlockJUnit4ClassRunner(klass);
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ delegate.run(notifier);
+ }
+
+ @Override
+ public Description getDescription() {
+ return delegate.getDescription();
+ }
+
+ public void sort(Sorter sorter) {
+ delegate.sort(sorter);
+ }
+ }
+
+ @RunWith(SortableRunner.class)
+ public static class SortMe {
+ @Test
+ public void a() {
+ log += "a";
+ }
+
+ @Test
+ public void b() {
+ log += "b";
+ }
+
+ @Test
+ public void c() {
+ log += "c";
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(SortMe.class);
+ }
+ }
+
+ @Before
+ public void resetLog() {
+ log = "";
+ }
+
+ @Test
+ public void sortingForwardWorksOnTestClassRunner() {
+ Request forward = Request.aClass(SortMe.class).sortWith(forward());
+
+ new JUnitCore().run(forward);
+ assertEquals("abc", log);
+ }
+
+ @Test
+ public void sortingBackwardWorksOnTestClassRunner() {
+ Request backward = Request.aClass(SortMe.class).sortWith(backward());
+
+ new JUnitCore().run(backward);
+ assertEquals("cba", log);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/package-info.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/package-info.java
new file mode 100644
index 0000000..fc5bdf6
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Tests the JUnit functionality.
+ *
+ * Corresponds to {@link junit.tests.AllTests} in Junit 3.x.
+ *
+ * @since 4.0
+ */
+package org.junit.tests;
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/AllRunningTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/AllRunningTests.java
new file mode 100644
index 0000000..0c05c92
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/AllRunningTests.java
@@ -0,0 +1,17 @@
+package org.junit.tests.running;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.tests.running.classes.AllClassesTests;
+import org.junit.tests.running.core.AllCoreTests;
+import org.junit.tests.running.methods.AllMethodsTests;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllClassesTests.class,
+ AllCoreTests.class,
+ AllMethodsTests.class
+})
+public class AllRunningTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/AllClassesTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/AllClassesTests.java
new file mode 100644
index 0000000..793090c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/AllClassesTests.java
@@ -0,0 +1,24 @@
+package org.junit.tests.running.classes;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.tests.running.classes.parent.ParentRunnerClassLoaderTest;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ BlockJUnit4ClassRunnerTest.class,
+ ClassLevelMethodsWithIgnoredTestsTest.class,
+ EnclosedTest.class,
+ IgnoreClassTest.class,
+ ParameterizedTestTest.class,
+ ParentRunnerFilteringTest.class,
+ ParentRunnerTest.class,
+ ParentRunnerClassLoaderTest.class,
+ RunWithTest.class,
+ SuiteTest.class,
+ UseSuiteAsASuperclassTest.class,
+ ThreadsTest.class
+})
+public class AllClassesTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/BlockJUnit4ClassRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/BlockJUnit4ClassRunnerTest.java
new file mode 100644
index 0000000..9a4e87a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/BlockJUnit4ClassRunnerTest.java
@@ -0,0 +1,68 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.notification.RunListener;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+public class BlockJUnit4ClassRunnerTest {
+ public static class OuterClass {
+ public class Enclosed {
+ @Test
+ public void test() {
+ }
+ }
+ }
+
+ @Test
+ public void detectNonStaticEnclosedClass() throws Exception {
+ try {
+ new BlockJUnit4ClassRunner(OuterClass.Enclosed.class);
+ } catch (InitializationError e) {
+ List<Throwable> causes = e.getCauses();
+ assertEquals("Wrong number of causes.", 1, causes.size());
+ assertEquals(
+ "Wrong exception.",
+ "The inner class org.junit.tests.running.classes.BlockJUnit4ClassRunnerTest$OuterClass$Enclosed is not static.",
+ causes.get(0).getMessage());
+ }
+ }
+
+ private static String log;
+
+ public static class MethodBlockAfterFireTestStarted {
+ public MethodBlockAfterFireTestStarted() {
+ log += " init";
+ }
+
+ @Test
+ public void test() {
+ log += " test";
+ }
+ }
+
+ @Test
+ public void methodBlockAfterFireTestStarted() {
+ log = "";
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new RunListener() {
+ @Override
+ public void testStarted(Description description) throws Exception {
+ log += " testStarted(" + description.getMethodName() + ")";
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ log += " testFinished(" + description.getMethodName() + ")";
+ }
+ });
+ junit.run(MethodBlockAfterFireTestStarted.class);
+ assertEquals(" testStarted(test) init test testFinished(test)", log);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ClassLevelMethodsWithIgnoredTestsTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ClassLevelMethodsWithIgnoredTestsTest.java
new file mode 100644
index 0000000..076988b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ClassLevelMethodsWithIgnoredTestsTest.java
@@ -0,0 +1,165 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Categories.CategoryFilter;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.model.Statement;
+
+/**
+ * Tests verifying that class-level fixtures ({@link BeforeClass} and
+ * {@link AfterClass}) and rules ({@link ClassRule}) are not executed when there
+ * are no test methods to be run in a test class because they have been ignored.
+ *
+ */
+public class ClassLevelMethodsWithIgnoredTestsTest {
+ private static final String FAILURE_MESSAGE = "This should not have happened!";
+
+ public static class BeforeClassWithIgnoredTest {
+ @BeforeClass
+ public static void beforeClass() {
+ fail(FAILURE_MESSAGE);
+ }
+
+ @Ignore
+ @Test
+ public void test() throws Exception {
+ fail("test() should not run");
+ }
+ }
+
+ @Test
+ public void beforeClassShouldNotRunWhenAllTestsAreIgnored() {
+ runClassAndVerifyNoFailures(BeforeClassWithIgnoredTest.class,
+ "BeforeClass should not have been executed because the test method is ignored!");
+ }
+
+ @Ignore
+ public static class BeforeClassWithIgnoredClass {
+ @BeforeClass
+ public static void beforeClass() {
+ fail(FAILURE_MESSAGE);
+ }
+
+ @Test
+ public void test() throws Exception {
+ fail("test() should not run");
+ }
+ }
+
+ @Test
+ public void beforeClassShouldNotRunWhenWholeClassIsIgnored() {
+ runClassAndVerifyNoFailures(
+ BeforeClassWithIgnoredClass.class,
+ "BeforeClass should not have been executed because the whole test class is ignored!");
+ }
+
+ public static class AfterClassWithIgnoredTest {
+ @Ignore
+ @Test
+ public void test() throws Exception {
+ fail("test() should not run");
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ fail(FAILURE_MESSAGE);
+ }
+ }
+
+ @Test
+ public void afterClassShouldNotRunWhenAllTestsAreIgnored() {
+ runClassAndVerifyNoFailures(AfterClassWithIgnoredTest.class,
+ "AfterClass should not have been executed because the test method is ignored!");
+ }
+
+ public interface FilteredTests {
+ }
+
+ public static class BeforeClassWithFilteredTest {
+ @BeforeClass
+ public static void setUpClass() {
+ fail(FAILURE_MESSAGE);
+ }
+
+ @Category(FilteredTests.class)
+ @Test
+ public void test() throws Exception {
+ fail("test() should not run");
+ }
+ }
+
+ public static class HasUnfilteredTest {
+ @Test
+ public void unfilteredTest() {
+ // to prevent errors when all other tests have been filtered
+ }
+ }
+
+ @Test
+ public void beforeClassShouldNotRunWhenAllTestsAreFiltered() {
+ Result result = new JUnitCore().run(Request.classes(
+ BeforeClassWithFilteredTest.class, HasUnfilteredTest.class)
+ .filterWith(CategoryFilter.exclude(FilteredTests.class)));
+ analyseResult(
+ result,
+ "BeforeClass should not have been executed because the test method is filtered!");
+ }
+
+ public static class BrokenRule implements TestRule {
+ public Statement apply(Statement base, Description description) {
+ throw new RuntimeException("this rule is broken");
+ }
+ }
+
+ public static class ClassRuleWithIgnoredTest {
+ @ClassRule
+ public static BrokenRule brokenRule = new BrokenRule();
+
+ @Ignore
+ @Test
+ public void test() throws Exception {
+ fail("test() should not be run");
+ }
+ }
+
+ @Test
+ public void classRuleShouldNotBeAppliedWhenAllTestsAreIgnored() {
+ runClassAndVerifyNoFailures(ClassRuleWithIgnoredTest.class,
+ "The class rule should have been applied because the test method is ignored!");
+ }
+
+ private void runClassAndVerifyNoFailures(Class<?> klass,
+ String testFailureDescription) {
+ Result result = JUnitCore.runClasses(klass);
+ analyseResult(result, testFailureDescription);
+ }
+
+ private void analyseResult(Result result, String testFailureDescription) {
+ List<Failure> failures = result.getFailures();
+ if (failures.isEmpty() == false) {
+ analyzeFailure(failures.get(0), testFailureDescription);
+ }
+ }
+
+ private void analyzeFailure(Failure failure, String testFailureDescription) {
+ String actualFailureMsg = failure.getMessage();
+ if (FAILURE_MESSAGE.equals(actualFailureMsg)) {
+ fail(testFailureDescription);
+ }
+ fail("Unexpected failure : " + actualFailureMsg);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/EnclosedTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/EnclosedTest.java
new file mode 100644
index 0000000..9a8165a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/EnclosedTest.java
@@ -0,0 +1,55 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+
+public class EnclosedTest {
+ @RunWith(Enclosed.class)
+ public static class Enclosing {
+ public static class A {
+ @Test
+ public void a() {}
+
+ @Test
+ public void b() {}
+ }
+ public static class B {
+ @Test
+ public void a() {}
+
+ @Test
+ public void b() {}
+
+ @Test
+ public void c() {}
+ }
+ public abstract static class C {
+ @Test public void a() {}
+ }
+ }
+
+ @Test
+ public void enclosedRunnerPlansConcreteEnclosedClasses() throws Exception {
+ Runner runner= Request.aClass(Enclosing.class).getRunner();
+ assertEquals(5, runner.testCount());
+ }
+
+ @Test
+ public void enclosedRunnerRunsConcreteEnclosedClasses() throws Exception {
+ Result result= JUnitCore.runClasses(Enclosing.class);
+ assertEquals(5, result.getRunCount());
+ }
+
+ @Test
+ public void enclosedRunnerIsNamedForEnclosingClass() throws Exception {
+ assertEquals(Enclosing.class.getName(), Request.aClass(Enclosing.class)
+ .getRunner().getDescription().getDisplayName());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/IgnoreClassTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/IgnoreClassTest.java
new file mode 100644
index 0000000..28cbe76
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/IgnoreClassTest.java
@@ -0,0 +1,31 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class IgnoreClassTest {
+ @Ignore("For a good reason")
+ public static class IgnoreMe {
+ @Test
+ public void iFail() {
+ fail();
+ }
+
+ @Test
+ public void iFailToo() {
+ fail();
+ }
+ }
+
+ @Test
+ public void ignoreClass() {
+ Result result = JUnitCore.runClasses(IgnoreMe.class);
+ assertEquals(0, result.getFailureCount());
+ assertEquals(1, result.getIgnoreCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java
new file mode 100644
index 0000000..6288dbc
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java
@@ -0,0 +1,809 @@
+package org.junit.tests.running.classes;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.experimental.results.PrintableResult.testResult;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.parameterized.ParametersRunnerFactory;
+import org.junit.runners.parameterized.TestWithParameters;
+
+public class ParameterizedTestTest {
+ @RunWith(Parameterized.class)
+ public static class AdditionTest {
+ @Parameters(name = "{index}: {0} + {1} = {2}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
+ { 3, 2, 5 }, { 4, 3, 7 } });
+ }
+
+ private int firstSummand;
+
+ private int secondSummand;
+
+ private int sum;
+
+ public AdditionTest(int firstSummand, int secondSummand, int sum) {
+ this.firstSummand = firstSummand;
+ this.secondSummand = secondSummand;
+ this.sum = sum;
+ }
+
+ @Test
+ public void test() {
+ assertEquals(sum, firstSummand + secondSummand);
+ }
+ }
+
+ @Test
+ public void countsRuns() {
+ Result result = JUnitCore.runClasses(AdditionTest.class);
+ assertEquals(4, result.getRunCount());
+ }
+
+ @Test
+ public void countBeforeRun() throws Exception {
+ Runner runner = Request.aClass(AdditionTest.class).getRunner();
+ assertEquals(4, runner.testCount());
+ }
+
+ @Test
+ public void plansNamedCorrectly() throws Exception {
+ Runner runner = Request.aClass(AdditionTest.class).getRunner();
+ Description description = runner.getDescription();
+ assertEquals("[2: 3 + 2 = 5]", description.getChildren().get(2)
+ .getDisplayName());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ThreeFailures {
+ @Parameters(name = "{index}: x={0}")
+ public static Collection<Integer> data() {
+ return Arrays.asList(1, 2, 3);
+ }
+
+ @Parameter(0)
+ public int unused;
+
+ @Test
+ public void testSomething() {
+ fail();
+ }
+ }
+
+ @Test
+ public void countsFailures() throws Exception {
+ Result result = JUnitCore.runClasses(ThreeFailures.class);
+ assertEquals(3, result.getFailureCount());
+ }
+
+ @Test
+ public void failuresNamedCorrectly() {
+ Result result = JUnitCore.runClasses(ThreeFailures.class);
+ assertEquals(
+ "testSomething[0: x=1](" + ThreeFailures.class.getName() + ")",
+ result.getFailures().get(0).getTestHeader());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParameterizedWithoutSpecialTestname {
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{{3}, {3}});
+ }
+
+ public ParameterizedWithoutSpecialTestname(Object something) {
+ }
+
+ @Test
+ public void testSomething() {
+ }
+ }
+
+ @Test
+ public void usesIndexAsTestName() {
+ Runner runner = Request
+ .aClass(ParameterizedWithoutSpecialTestname.class).getRunner();
+ Description description = runner.getDescription();
+ assertEquals("[1]", description.getChildren().get(1).getDisplayName());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class AdditionTestWithAnnotatedFields {
+ @Parameters(name = "{index}: {0} + {1} = {2}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
+ { 3, 2, 5 }, { 4, 3, 7 } });
+ }
+
+ @Parameter(0)
+ public int firstSummand;
+
+ @Parameter(1)
+ public int secondSummand;
+
+ @Parameter(2)
+ public int sum;
+
+ @Test
+ public void test() {
+ assertEquals(sum, firstSummand + secondSummand);
+ }
+ }
+
+ @Test
+ public void providesDataByAnnotatedFields() {
+ Result result = JUnitCore.runClasses(AdditionTestWithAnnotatedFields.class);
+ assertEquals(4, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class BadIndexForAnnotatedFieldTest {
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{{0}});
+ }
+
+ @Parameter(2)
+ public int fInput;
+
+ public int fExpected;
+
+ @Test
+ public void test() {
+ assertEquals(fExpected, fib(fInput));
+ }
+
+ private int fib(int x) {
+ return 0;
+ }
+ }
+
+ @Test
+ public void failureOnInitialization() {
+ Result result = JUnitCore.runClasses(BadIndexForAnnotatedFieldTest.class);
+ assertEquals(1, result.getFailureCount());
+ List<Failure> failures = result.getFailures();
+ assertThat(failures.get(0).getException().getMessage(), allOf(
+ containsString("Invalid @Parameter value: 2. @Parameter fields counted: 1. Please use an index between 0 and 0."),
+ containsString("@Parameter(0) is never used.")));
+ }
+
+ @RunWith(Parameterized.class)
+ public static class BadNumberOfAnnotatedFieldTest {
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{{0, 0}});
+ }
+
+ @Parameter(0)
+ public int fInput;
+
+ public int fExpected;
+
+ @Test
+ public void test() {
+ assertEquals(fExpected, fib(fInput));
+ }
+
+ private int fib(int x) {
+ return 0;
+ }
+ }
+
+ @Test
+ public void numberOfFieldsAndParametersShouldMatch() {
+ Result result = JUnitCore.runClasses(BadNumberOfAnnotatedFieldTest.class);
+ assertEquals(1, result.getFailureCount());
+ List<Failure> failures = result.getFailures();
+ assertTrue(failures.get(0).getException().getMessage().contains("Wrong number of parameters and @Parameter fields. @Parameter fields counted: 1, available parameters: 2."));
+ }
+
+ private static String fLog;
+
+ @RunWith(Parameterized.class)
+ public static class BeforeAndAfter {
+ @BeforeClass
+ public static void before() {
+ fLog += "before ";
+ }
+
+ @AfterClass
+ public static void after() {
+ fLog += "after ";
+ }
+
+ public BeforeAndAfter(int x) {
+
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{{3}});
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void beforeAndAfterClassAreRun() {
+ fLog = "";
+ JUnitCore.runClasses(BeforeAndAfter.class);
+ assertEquals("before after ", fLog);
+ }
+
+ @RunWith(Parameterized.class)
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class BeforeParamAndAfterParam {
+ @BeforeClass
+ public static void before() {
+ fLog += "beforeClass ";
+ }
+
+ @Parameterized.BeforeParam
+ public static void beforeParam(String x) {
+ fLog += "before(" + x + ") ";
+ }
+
+ @Parameterized.AfterParam
+ public static void afterParam() {
+ fLog += "afterParam ";
+ }
+
+ @AfterClass
+ public static void after() {
+ fLog += "afterClass ";
+ }
+
+ private final String x;
+
+ public BeforeParamAndAfterParam(String x) {
+ this.x = x;
+ }
+
+ @Parameters
+ public static Collection<String> data() {
+ return Arrays.asList("A", "B");
+ }
+
+ @Test
+ public void first() {
+ fLog += "first(" + x + ") ";
+ }
+
+ @Test
+ public void second() {
+ fLog += "second(" + x + ") ";
+ }
+ }
+
+ @Test
+ public void beforeParamAndAfterParamAreRun() {
+ fLog = "";
+ Result result = JUnitCore.runClasses(BeforeParamAndAfterParam.class);
+ assertEquals(0, result.getFailureCount());
+ assertEquals("beforeClass before(A) first(A) second(A) afterParam "
+ + "before(B) first(B) second(B) afterParam afterClass ", fLog);
+ }
+
+ @RunWith(Parameterized.class)
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class MultipleBeforeParamAndAfterParam {
+ @Parameterized.BeforeParam
+ public static void before1() {
+ fLog += "before1() ";
+ }
+
+ @Parameterized.BeforeParam
+ public static void before2(String x) {
+ fLog += "before2(" + x + ") ";
+ }
+
+ @Parameterized.AfterParam
+ public static void after2() {
+ fLog += "after2() ";
+ }
+
+ @Parameterized.AfterParam
+ public static void after1(String x) {
+ fLog += "after1(" + x + ") ";
+ }
+
+ private final String x;
+
+ public MultipleBeforeParamAndAfterParam(String x) {
+ this.x = x;
+ }
+
+ @Parameters
+ public static Collection<String> data() {
+ return Arrays.asList("A", "B");
+ }
+
+ @Test
+ public void first() {
+ fLog += "first(" + x + ") ";
+ }
+
+ @Test
+ public void second() {
+ fLog += "second(" + x + ") ";
+ }
+ }
+
+ @Test
+ public void multipleBeforeParamAndAfterParamAreRun() {
+ fLog = "";
+ Result result = JUnitCore.runClasses(MultipleBeforeParamAndAfterParam.class);
+ assertEquals(0, result.getFailureCount());
+ assertEquals("before1() before2(A) first(A) second(A) after1(A) after2() "
+ + "before1() before2(B) first(B) second(B) after1(B) after2() ", fLog);
+ }
+
+ @RunWith(Parameterized.class)
+ @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+ public static class MultipleParametersBeforeParamAndAfterParam {
+ @Parameterized.BeforeParam
+ public static void before(String x, int y) {
+ fLog += "before(" + x + "," + y + ") ";
+ }
+
+ @Parameterized.AfterParam
+ public static void after(String x, int y) {
+ fLog += "after(" + x + "," + y + ") ";
+ }
+
+ private final String x;
+ private final int y;
+
+ public MultipleParametersBeforeParamAndAfterParam(String x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[]{"A", 1}, new Object[]{"B", 2});
+ }
+
+ @Test
+ public void first() {
+ fLog += "first(" + x + "," + y + ") ";
+ }
+
+ @Test
+ public void second() {
+ fLog += "second(" + x + "," + y + ") ";
+ }
+ }
+
+ @Test
+ public void multipleParametersBeforeParamAndAfterParamAreRun() {
+ fLog = "";
+ Result result = JUnitCore.runClasses(MultipleParametersBeforeParamAndAfterParam.class);
+ assertEquals(0, result.getFailureCount());
+ assertEquals("before(A,1) first(A,1) second(A,1) after(A,1) "
+ + "before(B,2) first(B,2) second(B,2) after(B,2) ", fLog);
+ }
+
+ @RunWith(Parameterized.class)
+ public static class BeforeParamAndAfterParamError {
+ @Parameterized.BeforeParam
+ public void beforeParam(String x) {
+ }
+
+ @Parameterized.AfterParam
+ private static void afterParam() {
+ }
+
+ public BeforeParamAndAfterParamError(String x) {
+ }
+
+ @Parameters
+ public static Collection<String> data() {
+ return Arrays.asList("A", "B");
+ }
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void beforeParamAndAfterParamValidation() {
+ fLog = "";
+ Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class);
+ assertEquals(1, result.getFailureCount());
+ List<Failure> failures = result.getFailures();
+ assertThat(failures.get(0).getMessage(), containsString("beforeParam() should be static"));
+ assertThat(failures.get(0).getMessage(), containsString("afterParam() should be public"));
+ }
+
+ @RunWith(Parameterized.class)
+ public static class BeforeParamAndAfterParamErrorNumberOfParameters {
+ @Parameterized.BeforeParam
+ public static void beforeParam(String x, String y) {
+ }
+
+ @Parameterized.AfterParam
+ public static void afterParam(String x, String y, String z) {
+ }
+
+ public BeforeParamAndAfterParamErrorNumberOfParameters(String x) {
+ }
+
+ @Parameters
+ public static Collection<String> data() {
+ return Arrays.asList("A", "B", "C", "D");
+ }
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void beforeParamAndAfterParamValidationNumberOfParameters() {
+ fLog = "";
+ Result result = JUnitCore.runClasses(BeforeParamAndAfterParamErrorNumberOfParameters.class);
+ assertEquals(1, result.getFailureCount());
+ List<Failure> failures = result.getFailures();
+ assertThat(failures.get(0).getMessage(),
+ containsString("Method beforeParam() should have 0 or 1 parameter(s)"));
+ assertThat(failures.get(0).getMessage(),
+ containsString("Method afterParam() should have 0 or 1 parameter(s)"));
+ }
+
+ @RunWith(Parameterized.class)
+ public static class EmptyTest {
+ @BeforeClass
+ public static void before() {
+ fLog += "before ";
+ }
+
+ @AfterClass
+ public static void after() {
+ fLog += "after ";
+ }
+ }
+
+ @Test
+ public void validateClassCatchesNoParameters() {
+ Result result = JUnitCore.runClasses(EmptyTest.class);
+ assertEquals(1, result.getFailureCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class IncorrectTest {
+ @Test
+ public int test() {
+ return 0;
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Collections.singletonList(new Object[]{1});
+ }
+ }
+
+ @Test
+ public void failuresAddedForBadTestMethod() throws Exception {
+ Result result = JUnitCore.runClasses(IncorrectTest.class);
+ assertEquals(1, result.getFailureCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ProtectedParametersTest {
+ @Parameters
+ protected static Collection<Object[]> data() {
+ return Collections.emptyList();
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void meaningfulFailureWhenParametersNotPublic() {
+ assertTestCreatesSingleFailureWithMessage(ProtectedParametersTest.class,
+ "No public static parameters method on class "
+ + ProtectedParametersTest.class.getName());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class ParametersNotIterable {
+ @Parameters
+ public static String data() {
+ return "foo";
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void meaningfulFailureWhenParametersAreNotAnIterable() {
+ assertThat(
+ testResult(ParametersNotIterable.class).toString(),
+ containsString("ParametersNotIterable.data() must return an Iterable of arrays."));
+ }
+
+ @RunWith(Parameterized.class)
+ public static class PrivateConstructor {
+ private PrivateConstructor(int x) {
+
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{{3}});
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test(expected = InitializationError.class)
+ public void exceptionWhenPrivateConstructor() throws Throwable {
+ new Parameterized(PrivateConstructor.class);
+ }
+
+ @RunWith(Parameterized.class)
+ public static class AdditionTestWithArray {
+ @Parameters(name = "{index}: {0} + {1} = {2}")
+ public static Object[][] data() {
+ return new Object[][] { { 0, 0, 0 }, { 1, 1, 2 }, { 3, 2, 5 },
+ { 4, 3, 7 } };
+ }
+
+ @Parameter(0)
+ public int firstSummand;
+
+ @Parameter(1)
+ public int secondSummand;
+
+ @Parameter(2)
+ public int sum;
+
+ @Test
+ public void test() {
+ assertEquals(sum, firstSummand + secondSummand);
+ }
+ }
+
+ @Test
+ public void runsEveryTestOfArray() {
+ Result result= JUnitCore.runClasses(AdditionTestWithArray.class);
+ assertEquals(4, result.getRunCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class SingleArgumentTestWithArray {
+ @Parameters
+ public static Object[] data() {
+ return new Object[] { "first test", "second test" };
+ }
+
+ public SingleArgumentTestWithArray(Object argument) {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void runsForEverySingleArgumentOfArray() {
+ Result result= JUnitCore.runClasses(SingleArgumentTestWithArray.class);
+ assertEquals(2, result.getRunCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class SingleArgumentTestWithIterable {
+ private static final AtomicBoolean dataCalled = new AtomicBoolean(false);
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ if (!dataCalled.compareAndSet(false, true)) {
+ fail("Should not call @Parameters method more than once");
+ }
+ return new OneShotIterable<String>(asList("first test", "second test"));
+ }
+
+ public SingleArgumentTestWithIterable(Object argument) {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ private static class OneShotIterable<T> implements Iterable<T> {
+ private final Iterable<T> delegate;
+ private final AtomicBoolean iterated = new AtomicBoolean(false);
+
+ OneShotIterable(Iterable<T> delegate) {
+ this.delegate = delegate;
+ }
+
+ public Iterator<T> iterator() {
+ if (iterated.compareAndSet(false, true)) {
+ return delegate.iterator();
+ }
+ throw new IllegalStateException("Cannot call iterator() more than once");
+ }
+ }
+
+ @Test
+ public void runsForEverySingleArgumentOfIterable() {
+ Result result= JUnitCore
+ .runClasses(SingleArgumentTestWithIterable.class);
+ assertEquals(2, result.getRunCount());
+ }
+
+ @RunWith(Parameterized.class)
+ public static class SingleArgumentTestWithCollection {
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return Collections.unmodifiableCollection(asList("first test", "second test"));
+ }
+
+ public SingleArgumentTestWithCollection(Object argument) {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void runsForEverySingleArgumentOfCollection() {
+ Result result= JUnitCore
+ .runClasses(SingleArgumentTestWithCollection.class);
+ assertEquals(2, result.getRunCount());
+ }
+
+
+ public static class ExceptionThrowingRunnerFactory implements
+ ParametersRunnerFactory {
+ public Runner createRunnerForTestWithParameters(TestWithParameters test)
+ throws InitializationError {
+ throw new InitializationError(
+ "Called ExceptionThrowingRunnerFactory.");
+ }
+ }
+
+ @RunWith(Parameterized.class)
+ @UseParametersRunnerFactory(ExceptionThrowingRunnerFactory.class)
+ public static class TestWithUseParametersRunnerFactoryAnnotation {
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return asList("single test");
+ }
+
+ public TestWithUseParametersRunnerFactoryAnnotation(Object argument) {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ @Test
+ public void usesParametersRunnerFactoryThatWasSpecifiedByAnnotation() {
+ assertTestCreatesSingleFailureWithMessage(
+ TestWithUseParametersRunnerFactoryAnnotation.class,
+ "Called ExceptionThrowingRunnerFactory.");
+ }
+
+ private void assertTestCreatesSingleFailureWithMessage(Class<?> test, String message) {
+ Result result = JUnitCore.runClasses(test);
+ assertEquals(1, result.getFailures().size());
+ assertEquals(message, result.getFailures().get(0).getMessage());
+ }
+
+ @RunWith(Parameterized.class)
+ @UseParametersRunnerFactory(ExceptionThrowingRunnerFactory.class)
+ public abstract static class UseParameterizedFactoryAbstractTest {
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return asList("single test");
+ }
+ }
+
+ public static class UseParameterizedFactoryTest extends
+ UseParameterizedFactoryAbstractTest {
+
+ public UseParameterizedFactoryTest(String parameter) {
+
+ }
+
+ @Test
+ public void parameterizedTest() {
+ }
+ }
+
+ @Test
+ public void usesParametersRunnerFactoryThatWasSpecifiedByAnnotationInSuperClass() {
+ assertTestCreatesSingleFailureWithMessage(
+ UseParameterizedFactoryTest.class,
+ "Called ExceptionThrowingRunnerFactory.");
+ }
+
+ @RunWith(Parameterized.class)
+ public static class AssumptionInParametersMethod {
+ static boolean assumptionFails;
+
+ @Parameters
+ public static Iterable<String> data() {
+ assumeFalse(assumptionFails);
+ return Collections.singletonList("foobar");
+ }
+
+ public AssumptionInParametersMethod(String parameter) {
+ }
+
+ @Test
+ public void test1() {
+ }
+
+ @Test
+ public void test2() {
+ }
+ }
+
+ @Test
+ public void testsAreExecutedWhenAssumptionInParametersMethodDoesNotFail() {
+ AssumptionInParametersMethod.assumptionFails = false;
+ Result result = JUnitCore.runClasses(AssumptionInParametersMethod.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(0, result.getAssumptionFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(2, result.getRunCount());
+ }
+
+ @Test
+ public void testsAreNotExecutedWhenAssumptionInParametersMethodFails() {
+ AssumptionInParametersMethod.assumptionFails = true;
+ Result result = JUnitCore.runClasses(AssumptionInParametersMethod.class);
+ assertTrue(result.wasSuccessful());
+ assertEquals(1, result.getAssumptionFailureCount());
+ assertEquals(0, result.getIgnoreCount());
+ assertEquals(0, result.getRunCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerFilteringTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerFilteringTest.java
new file mode 100644
index 0000000..1c1d9d1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerFilteringTest.java
@@ -0,0 +1,171 @@
+package org.junit.tests.running.classes;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import static org.junit.runner.Description.createSuiteDescription;
+import static org.junit.runner.Description.createTestDescription;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+public class ParentRunnerFilteringTest {
+ private static Filter notThisMethodName(final String methodName) {
+ return new Filter() {
+ @Override
+ public boolean shouldRun(Description description) {
+ return description.getMethodName() == null
+ || !description.getMethodName().equals(methodName);
+ }
+
+ @Override
+ public String describe() {
+ return "don't run method name: " + methodName;
+ }
+ };
+ }
+
+ private static class CountingFilter extends Filter {
+ private final Map<Description, Integer> countMap = new HashMap<Description, Integer>();
+
+ @Override
+ public boolean shouldRun(Description description) {
+ Integer count = countMap.get(description);
+ if (count == null) {
+ countMap.put(description, 1);
+ } else {
+ countMap.put(description, count + 1);
+ }
+ return true;
+ }
+
+ @Override
+ public String describe() {
+ return "filter counter";
+ }
+
+ public int getCount(final Description desc) {
+ if (!countMap.containsKey(desc)) {
+ throw new IllegalArgumentException("Looking for " + desc
+ + ", but only contains: " + countMap.keySet());
+ }
+ return countMap.get(desc);
+ }
+ }
+
+ public static class ExampleTest {
+ @Test
+ public void test1() throws Exception {
+ // passes
+ }
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({ExampleTest.class})
+ public static class ExampleSuite {
+ }
+
+ @Test
+ public void testSuiteFiltering() throws Exception {
+ Runner runner = Request.aClass(ExampleSuite.class).getRunner();
+ Filter filter = notThisMethodName("test1");
+ try {
+ filter.apply(runner);
+ } catch (NoTestsRemainException e) {
+ return;
+ }
+ fail("Expected 'NoTestsRemainException' due to complete filtering");
+ }
+
+ public static class SuiteWithUnmodifiableChildList extends Suite {
+
+ public SuiteWithUnmodifiableChildList(
+ Class<?> klass, RunnerBuilder builder)
+ throws InitializationError {
+ super(klass, builder);
+ }
+
+ @Override
+ protected List<Runner> getChildren() {
+ return Collections.unmodifiableList(super.getChildren());
+ }
+ }
+
+ @RunWith(SuiteWithUnmodifiableChildList.class)
+ @SuiteClasses({ExampleTest.class})
+ public static class ExampleSuiteWithUnmodifiableChildList {
+ }
+
+ @Test
+ public void testSuiteFilteringWithUnmodifiableChildList() throws Exception {
+ Runner runner = Request.aClass(ExampleSuiteWithUnmodifiableChildList.class)
+ .getRunner();
+ Filter filter = notThisMethodName("test1");
+ try {
+ filter.apply(runner);
+ } catch (NoTestsRemainException e) {
+ return;
+ }
+ fail("Expected 'NoTestsRemainException' due to complete filtering");
+ }
+
+ @Test
+ public void testRunSuiteFiltering() throws Exception {
+ Request request = Request.aClass(ExampleSuite.class);
+ Request requestFiltered = request.filterWith(notThisMethodName("test1"));
+ assertThat(testResult(requestFiltered),
+ hasSingleFailureContaining("don't run method name: test1"));
+ }
+
+ @Test
+ public void testCountClassFiltering() throws Exception {
+ JUnitCore junitCore = new JUnitCore();
+ Request request = Request.aClass(ExampleTest.class);
+ CountingFilter countingFilter = new CountingFilter();
+ Request requestFiltered = request.filterWith(countingFilter);
+ Result result = junitCore.run(requestFiltered);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+
+ Description desc = createTestDescription(ExampleTest.class, "test1");
+ assertEquals(1, countingFilter.getCount(desc));
+ }
+
+ @Test
+ public void testCountSuiteFiltering() throws Exception {
+ Class<ExampleSuite> suiteClazz = ExampleSuite.class;
+ Class<ExampleTest> clazz = ExampleTest.class;
+
+ JUnitCore junitCore = new JUnitCore();
+ Request request = Request.aClass(suiteClazz);
+ CountingFilter countingFilter = new CountingFilter();
+ Request requestFiltered = request.filterWith(countingFilter);
+ Result result = junitCore.run(requestFiltered);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+
+ Description suiteDesc = createSuiteDescription(clazz);
+ assertEquals(1, countingFilter.getCount(suiteDesc));
+
+ Description desc = createTestDescription(ExampleTest.class, "test1");
+ assertEquals(1, countingFilter.getCount(desc));
+ }
+}
\ No newline at end of file
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerTest.java
new file mode 100644
index 0000000..9b18ed1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ParentRunnerTest.java
@@ -0,0 +1,310 @@
+package org.junit.tests.running.classes;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerScheduler;
+import org.junit.rules.RuleMemberValidatorTest.TestWithNonStaticClassRule;
+import org.junit.rules.RuleMemberValidatorTest.TestWithProtectedClassRule;
+
+public class ParentRunnerTest {
+ public static String log = "";
+
+ public static class FruitTest {
+ @Test
+ public void apple() {
+ log += "apple ";
+ }
+
+ @Test
+ public void /* must hash-sort after "apple" */Banana() {
+ log += "banana ";
+ }
+ }
+
+ @Test
+ public void useChildHarvester() throws InitializationError {
+ log = "";
+ ParentRunner<?> runner = new BlockJUnit4ClassRunner(FruitTest.class);
+ runner.setScheduler(new RunnerScheduler() {
+ public void schedule(Runnable childStatement) {
+ log += "before ";
+ childStatement.run();
+ log += "after ";
+ }
+
+ public void finished() {
+ log += "afterAll ";
+ }
+ });
+
+ runner.run(new RunNotifier());
+ assertEquals("before apple after before banana after afterAll ", log);
+ }
+
+ @Test
+ public void testMultipleFilters() throws Exception {
+ JUnitCore junitCore = new JUnitCore();
+ Request request = Request.aClass(ExampleTest.class);
+ Request requestFiltered = request.filterWith(new Exclude("test1"));
+ Request requestFilteredFiltered = requestFiltered
+ .filterWith(new Exclude("test2"));
+ Result result = junitCore.run(requestFilteredFiltered);
+ assertThat(result.getFailures(), isEmpty());
+ assertEquals(1, result.getRunCount());
+ }
+
+ private Matcher<List<?>> isEmpty() {
+ return new TypeSafeMatcher<List<?>>() {
+ public void describeTo(org.hamcrest.Description description) {
+ description.appendText("is empty");
+ }
+
+ @Override
+ public boolean matchesSafely(List<?> item) {
+ return item.size() == 0;
+ }
+ };
+ }
+
+ private static class Exclude extends Filter {
+ private final String methodName;
+
+ public Exclude(String methodName) {
+ this.methodName = methodName;
+ }
+
+ @Override
+ public boolean shouldRun(Description description) {
+ return !description.getMethodName().equals(methodName);
+ }
+
+ @Override
+ public String describe() {
+ return "filter method name: " + methodName;
+ }
+ }
+
+ public static class ExampleTest {
+ @Test
+ public void test1() throws Exception {
+ }
+
+ @Test
+ public void test2() throws Exception {
+ }
+
+ @Test
+ public void test3() throws Exception {
+ }
+ }
+
+ @Test
+ public void failWithHelpfulMessageForProtectedClassRule() {
+ assertClassHasFailureMessage(TestWithProtectedClassRule.class,
+ "The @ClassRule 'temporaryFolder' must be public.");
+ }
+
+ @Test
+ public void failWithHelpfulMessageForNonStaticClassRule() {
+ assertClassHasFailureMessage(TestWithNonStaticClassRule.class,
+ "The @ClassRule 'temporaryFolder' must be static.");
+ }
+
+ static class NonPublicTestClass {
+ public NonPublicTestClass() {
+ }
+
+ @Test
+ public void alwaysPasses() {}
+ }
+
+ @Test
+ public void cannotBeCreatedWithNonPublicTestClass() {
+ assertClassHasFailureMessage(
+ NonPublicTestClass.class,
+ "The class org.junit.tests.running.classes.ParentRunnerTest$NonPublicTestClass is not public.");
+ }
+
+ private void assertClassHasFailureMessage(Class<?> klass, String message) {
+ JUnitCore junitCore = new JUnitCore();
+ Request request = Request.aClass(klass);
+ Result result = junitCore.run(request);
+ assertThat(result.getFailureCount(), is(1));
+ assertThat(result.getFailures().get(0).getMessage(),
+ containsString(message));
+ }
+
+ public static class AssertionErrorAtParentLevelTest {
+ @BeforeClass
+ public static void beforeClass() throws Throwable {
+ throw new AssertionError("Thrown from @BeforeClass");
+ }
+
+ @Test
+ public void test() {}
+ }
+
+ @Test
+ public void assertionErrorAtParentLevelTest() throws InitializationError {
+ CountingRunListener countingRunListener = runTestWithParentRunner(AssertionErrorAtParentLevelTest.class);
+ Assert.assertEquals(1, countingRunListener.testSuiteStarted);
+ Assert.assertEquals(1, countingRunListener.testSuiteFinished);
+ Assert.assertEquals(1, countingRunListener.testSuiteFailure);
+ Assert.assertEquals(0, countingRunListener.testSuiteAssumptionFailure);
+
+ Assert.assertEquals(0, countingRunListener.testStarted);
+ Assert.assertEquals(0, countingRunListener.testFinished);
+ Assert.assertEquals(0, countingRunListener.testFailure);
+ Assert.assertEquals(0, countingRunListener.testAssumptionFailure);
+ Assert.assertEquals(0, countingRunListener.testIgnored);
+ }
+
+ public static class AssumptionViolatedAtParentLevelTest {
+ @SuppressWarnings("deprecation")
+ @BeforeClass
+ public static void beforeClass() {
+ throw new AssumptionViolatedException("Thrown from @BeforeClass");
+ }
+
+ @Test
+ public void test() {}
+ }
+
+ @Test
+ public void assumptionViolatedAtParentLevel() throws InitializationError {
+ CountingRunListener countingRunListener = runTestWithParentRunner(AssumptionViolatedAtParentLevelTest.class);
+ Assert.assertEquals(1, countingRunListener.testSuiteStarted);
+ Assert.assertEquals(1, countingRunListener.testSuiteFinished);
+ Assert.assertEquals(0, countingRunListener.testSuiteFailure);
+ Assert.assertEquals(1, countingRunListener.testSuiteAssumptionFailure);
+
+ Assert.assertEquals(0, countingRunListener.testStarted);
+ Assert.assertEquals(0, countingRunListener.testFinished);
+ Assert.assertEquals(0, countingRunListener.testFailure);
+ Assert.assertEquals(0, countingRunListener.testAssumptionFailure);
+ Assert.assertEquals(0, countingRunListener.testIgnored);
+ }
+
+ public static class TestTest {
+ @Test
+ public void pass() {}
+
+ @Test
+ public void fail() {
+ throw new AssertionError("Thrown from @Test");
+ }
+
+ @Ignore
+ @Test
+ public void ignore() {}
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void assumptionFail() {
+ throw new AssumptionViolatedException("Thrown from @Test");
+ }
+ }
+
+ @Test
+ public void parentRunnerTestMethods() throws InitializationError {
+ CountingRunListener countingRunListener = runTestWithParentRunner(TestTest.class);
+ Assert.assertEquals(1, countingRunListener.testSuiteStarted);
+ Assert.assertEquals(1, countingRunListener.testSuiteFinished);
+ Assert.assertEquals(0, countingRunListener.testSuiteFailure);
+ Assert.assertEquals(0, countingRunListener.testSuiteAssumptionFailure);
+
+ Assert.assertEquals(3, countingRunListener.testStarted);
+ Assert.assertEquals(3, countingRunListener.testFinished);
+ Assert.assertEquals(1, countingRunListener.testFailure);
+ Assert.assertEquals(1, countingRunListener.testAssumptionFailure);
+ Assert.assertEquals(1, countingRunListener.testIgnored);
+ }
+
+ private CountingRunListener runTestWithParentRunner(Class<?> testClass) throws InitializationError {
+ CountingRunListener listener = new CountingRunListener();
+ RunNotifier runNotifier = new RunNotifier();
+ runNotifier.addListener(listener);
+ ParentRunner<?> runner = new BlockJUnit4ClassRunner(testClass);
+ runner.run(runNotifier);
+ return listener;
+ }
+
+ private static class CountingRunListener extends RunListener {
+ private int testSuiteStarted = 0;
+ private int testSuiteFinished = 0;
+ private int testSuiteFailure = 0;
+ private int testSuiteAssumptionFailure = 0;
+
+ private int testStarted = 0;
+ private int testFinished = 0;
+ private int testFailure = 0;
+ private int testAssumptionFailure = 0;
+ private int testIgnored = 0;
+
+ @Override
+ public void testSuiteStarted(Description description) throws Exception {
+ testSuiteStarted++;
+ }
+
+ @Override
+ public void testSuiteFinished(Description description) throws Exception {
+ testSuiteFinished++;
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ testStarted++;
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ testFinished++;
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ if (failure.getDescription().isSuite()) {
+ testSuiteFailure++;
+ } else {
+ testFailure++;
+ }
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ if (failure.getDescription().isSuite()) {
+ testSuiteAssumptionFailure++;
+ } else {
+ testAssumptionFailure++;
+ }
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ testIgnored++;
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/RunWithTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/RunWithTest.java
new file mode 100644
index 0000000..c41a40a
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/RunWithTest.java
@@ -0,0 +1,88 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+
+public class RunWithTest {
+
+ private static String log;
+
+ public static class ExampleRunner extends Runner {
+ public ExampleRunner(Class<?> klass) {
+ log += "initialize";
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ log += "run";
+ }
+
+ @Override
+ public int testCount() {
+ log += "count";
+ return 0;
+ }
+
+ @Override
+ public Description getDescription() {
+ log += "plan";
+ return Description.createSuiteDescription("example");
+ }
+ }
+
+ @RunWith(ExampleRunner.class)
+ public static class ExampleTest {
+ }
+
+ @Test
+ public void run() {
+ log = "";
+
+ JUnitCore.runClasses(ExampleTest.class);
+ assertTrue(log.contains("plan"));
+ assertTrue(log.contains("initialize"));
+ assertTrue(log.contains("run"));
+ }
+
+ public static class SubExampleTest extends ExampleTest {
+ }
+
+ @Test
+ public void runWithExtendsToSubclasses() {
+ log = "";
+
+ JUnitCore.runClasses(SubExampleTest.class);
+ assertTrue(log.contains("run"));
+ }
+
+ public static class BadRunner extends Runner {
+ @Override
+ public Description getDescription() {
+ return null;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ // do nothing
+ }
+ }
+
+ @RunWith(BadRunner.class)
+ public static class Empty {
+ }
+
+ @Test
+ public void characterizeErrorMessageFromBadRunner() {
+ assertEquals(
+ "Custom runner class BadRunner should have a public constructor with signature BadRunner(Class testClass)",
+ JUnitCore.runClasses(Empty.class).getFailures().get(0)
+ .getMessage());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/SuiteTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/SuiteTest.java
new file mode 100644
index 0000000..42b492e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/SuiteTest.java
@@ -0,0 +1,218 @@
+package org.junit.tests.running.classes;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.List;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestResult;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+public class SuiteTest {
+ public static class TestA {
+ @Test
+ public void pass() {
+ }
+ }
+
+ public static class TestB {
+ @Test
+ public void fail() {
+ Assert.fail();
+ }
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({TestA.class, TestB.class})
+ public static class All {
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses(TestA.class)
+ static class NonPublicSuite {
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses(TestA.class)
+ static class NonPublicSuiteWithBeforeClass {
+ @BeforeClass
+ public static void doesNothing() {}
+ }
+
+ public static class InheritsAll extends All {
+ }
+
+ @Test
+ public void ensureTestIsRun() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(All.class);
+ assertEquals(2, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ }
+
+ @Test
+ public void ensureInheritedTestIsRun() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(InheritsAll.class);
+ assertEquals(2, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ }
+
+ @Test
+ public void suiteTestCountIsCorrect() throws Exception {
+ Runner runner = Request.aClass(All.class).getRunner();
+ assertEquals(2, runner.testCount());
+ }
+
+ @Test
+ public void suiteClassDoesNotNeedToBePublic() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(NonPublicSuite.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ @Test
+ public void nonPublicSuiteClassWithBeforeClassPasses() {
+ assertThat(testResult(NonPublicSuiteWithBeforeClass.class), isSuccessful());
+ }
+
+ @Test
+ public void ensureSuitesWorkWithForwardCompatibility() {
+ junit.framework.Test test = new JUnit4TestAdapter(All.class);
+ TestResult result = new TestResult();
+ test.run(result);
+ assertEquals(2, result.runCount());
+ }
+
+ @Test
+ public void forwardCompatibilityWorksWithGetTests() {
+ JUnit4TestAdapter adapter = new JUnit4TestAdapter(All.class);
+ List<? extends junit.framework.Test> tests = adapter.getTests();
+ assertEquals(2, tests.size());
+ }
+
+ @Test
+ public void forwardCompatibilityWorksWithTestCount() {
+ JUnit4TestAdapter adapter = new JUnit4TestAdapter(All.class);
+ assertEquals(2, adapter.countTestCases());
+ }
+
+
+ private static String log = "";
+
+ @RunWith(Suite.class)
+ @SuiteClasses({TestA.class, TestB.class})
+ public static class AllWithBeforeAndAfterClass {
+ @BeforeClass
+ public static void before() {
+ log += "before ";
+ }
+
+ @AfterClass
+ public static void after() {
+ log += "after ";
+ }
+ }
+
+ @Test
+ public void beforeAndAfterClassRunOnSuite() {
+ log = "";
+ JUnitCore.runClasses(AllWithBeforeAndAfterClass.class);
+ assertEquals("before after ", log);
+ }
+
+ @RunWith(Suite.class)
+ public static class AllWithOutAnnotation {
+ }
+
+ @Test
+ public void withoutSuiteClassAnnotationProducesFailure() {
+ Result result = JUnitCore.runClasses(AllWithOutAnnotation.class);
+ assertEquals(1, result.getFailureCount());
+ String expected = String.format(
+ "class '%s' must have a SuiteClasses annotation",
+ AllWithOutAnnotation.class.getName());
+ assertEquals(expected, result.getFailures().get(0).getMessage());
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses(InfiniteLoop.class)
+ static public class InfiniteLoop {
+ }
+
+ @Test
+ public void whatHappensWhenASuiteHasACycle() {
+ Result result = JUnitCore.runClasses(InfiniteLoop.class);
+ assertEquals(1, result.getFailureCount());
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({BiInfiniteLoop.class, BiInfiniteLoop.class})
+ static public class BiInfiniteLoop {
+ }
+
+ @Test
+ public void whatHappensWhenASuiteHasAForkingCycle() {
+ Result result = JUnitCore.runClasses(BiInfiniteLoop.class);
+ assertEquals(2, result.getFailureCount());
+ }
+
+ // The interesting case here is that Hydra indirectly contains two copies of
+ // itself (if it only contains one, Java's StackOverflowError eventually
+ // bails us out)
+
+ @RunWith(Suite.class)
+ @SuiteClasses({Hercules.class})
+ static public class Hydra {
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({Hydra.class, Hydra.class})
+ static public class Hercules {
+ }
+
+ @Test
+ public void whatHappensWhenASuiteContainsItselfIndirectly() {
+ Result result = JUnitCore.runClasses(Hydra.class);
+ assertEquals(2, result.getFailureCount());
+ }
+
+ @RunWith(Suite.class)
+ @SuiteClasses({})
+ public class WithoutDefaultConstructor {
+ public WithoutDefaultConstructor(int i) {
+
+ }
+ }
+
+ @Test
+ public void suiteShouldBeOKwithNonDefaultConstructor() throws Exception {
+ Result result = JUnitCore.runClasses(WithoutDefaultConstructor.class);
+ assertTrue(result.wasSuccessful());
+ }
+
+ @RunWith(Suite.class)
+ public class NoSuiteClassesAnnotation {
+ }
+
+ @Test
+ public void suiteShouldComplainAboutNoSuiteClassesAnnotation() {
+ assertThat(testResult(NoSuiteClassesAnnotation.class), hasSingleFailureContaining("SuiteClasses"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ThreadsTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ThreadsTest.java
new file mode 100644
index 0000000..2965187
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/ThreadsTest.java
@@ -0,0 +1,83 @@
+package org.junit.tests.running.classes;
+
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.RunListener;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertEquals;
+
+public class ThreadsTest {
+
+ private List<Boolean> interruptedFlags = new ArrayList<Boolean>();
+ private JUnitCore core = new JUnitCore();
+
+ public static class TestWithInterrupt {
+
+ @Test
+ public void interruptCurrentThread() {
+ Thread.currentThread().interrupt();
+ }
+
+ @Test
+ public void otherTestCaseInterruptingCurrentThread() {
+ Thread.currentThread().interrupt();
+ }
+
+ }
+
+ @Test
+ public void currentThreadInterruptedStatusIsClearedAfterEachTestExecution() {
+ core.addListener(new RunListener() {
+ @Override
+ public void testFinished(Description description) {
+ interruptedFlags.add(Thread.currentThread().isInterrupted());
+ }
+ });
+
+ Result result = core.run(TestWithInterrupt.class);
+
+ assertEquals(0, result.getFailureCount());
+ assertEquals(asList(false, false), interruptedFlags);
+ }
+
+ @RunWith(BlockJUnit4ClassRunner.class)
+ public static class TestWithInterruptFromAfterClass {
+ @AfterClass
+ public static void interruptCurrentThread() {
+ Thread.currentThread().interrupt();
+ }
+
+ @Test
+ public void test() {
+ // no-op
+ }
+ }
+
+ @Test
+ public void currentThreadInterruptStatusIsClearedAfterSuiteExecution() {
+ core.addListener(new RunListener() {
+ @Override
+ public void testSuiteFinished(Description description) {
+ interruptedFlags.add(Thread.currentThread().isInterrupted());
+ }
+ });
+
+ Request request = Request.aClass(TestWithInterruptFromAfterClass.class);
+
+ Result result = core.run(request);
+
+ assertEquals(0, result.getFailureCount());
+ assertEquals(singletonList(false), interruptedFlags);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/UseSuiteAsASuperclassTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/UseSuiteAsASuperclassTest.java
new file mode 100644
index 0000000..c55a8ab
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/UseSuiteAsASuperclassTest.java
@@ -0,0 +1,45 @@
+package org.junit.tests.running.classes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+
+public class UseSuiteAsASuperclassTest {
+
+ public static class TestA {
+ @Test
+ public void pass() {
+ }
+ }
+
+ public static class TestB {
+ @Test
+ public void dontPass() {
+ fail();
+ }
+ }
+
+ public static class MySuite extends Suite {
+ public MySuite(Class<?> klass) throws InitializationError {
+ super(klass, new Class[]{TestA.class, TestB.class});
+ }
+ }
+
+ @RunWith(MySuite.class)
+ public static class AllWithMySuite {
+ }
+
+ @Test
+ public void ensureTestsAreRun() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(AllWithMySuite.class);
+ assertEquals(2, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java
new file mode 100644
index 0000000..1644336
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java
@@ -0,0 +1,94 @@
+package org.junit.tests.running.classes.parent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+
+public class ParentRunnerClassLoaderTest {
+ @Test
+ public void testClassRuleAccessToClassInAnotherClassLoader() throws Exception {
+ Class<?> testClassWithOwnClassLoader = wrapToClassLoader(TestWithClassRule.class);
+
+ runTestWithParentRunner(testClassWithOwnClassLoader);
+
+ Field fieldWithReference = testClassWithOwnClassLoader.getDeclaredField("applyTestClass");
+ Class<?> usedClass = (Class<?>) fieldWithReference.get(null);
+
+ assertEquals("JUnitRunner can be located in own classLoader, so, " +
+ "Class.forName org.junit.runner.Description.getTestClass can not see " +
+ "in current classloader by execute Class.forName",
+ testClassWithOwnClassLoader, usedClass
+ );
+ }
+
+ @Test
+ public void testDescriptionContainCorrectTestClass() throws Exception {
+ Class<?> testClassWithOwnClassLoader = wrapToClassLoader(TestWithClassRule.class);
+ ParentRunner<?> runner = new BlockJUnit4ClassRunner(testClassWithOwnClassLoader);
+
+ Description description = runner.getDescription();
+ assertEquals("ParentRunner accept already instantiate Class<?> with tests, if we lost it instance, and will " +
+ "use Class.forName we can not find test class again, because tests can be " +
+ "located in different ClassLoader",
+ description.getTestClass(), testClassWithOwnClassLoader
+ );
+ }
+
+ @Test
+ public void testBackwardCompatibilityWithOverrideGetName() throws Exception {
+ final Class<TestWithClassRule> originalTestClass = TestWithClassRule.class;
+ final Class<?> waitClass = ParentRunnerClassLoaderTest.class;
+
+ ParentRunner<FrameworkMethod> subParentRunner = new BlockJUnit4ClassRunner(originalTestClass) {
+ @Override
+ protected String getName() {
+ return waitClass.getName();
+ }
+ };
+
+ Description description = subParentRunner.getDescription();
+ Class<?> result = description.getTestClass();
+
+ assertEquals("Subclass of ParentRunner can override getName method and specify another test class for run, " +
+ "we should maintain backwards compatibility with JUnit 4.12",
+ waitClass, result
+ );
+ }
+
+ private void runTestWithParentRunner(Class<?> testClass) throws InitializationError {
+ ParentRunner<?> runner = new BlockJUnit4ClassRunner(testClass);
+ runner.run(new RunNotifier());
+ }
+
+ private Class<?> wrapToClassLoader(Class<?> sourceClass) throws ClassNotFoundException {
+ URL classpath = sourceClass.getProtectionDomain().getCodeSource().getLocation();
+ VisibleClassLoader loader = new VisibleClassLoader(new URL[]{classpath}, this.getClass().getClassLoader());
+ Class<?> testClassWithOwnClassLoader = loader.findClass(sourceClass.getName());
+
+ assert testClassWithOwnClassLoader != sourceClass;
+
+ return testClassWithOwnClassLoader;
+ }
+
+
+ private static class VisibleClassLoader extends URLClassLoader {
+ public VisibleClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
+
+ @Override // just making public
+ public Class<?> findClass(String name) throws ClassNotFoundException {
+ return super.findClass(name);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/TestWithClassRule.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/TestWithClassRule.java
new file mode 100644
index 0000000..62c892c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/classes/parent/TestWithClassRule.java
@@ -0,0 +1,42 @@
+package org.junit.tests.running.classes.parent;
+
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.lang.reflect.Field;
+
+/**
+ * Test class for validate run tests that was load in own ClassLoader
+ */
+public class TestWithClassRule {
+ public static Class<?> applyTestClass;
+
+ @ClassRule
+ public static TestRule rule = new CustomRule();
+
+ @Test
+ public void testClassRuleExecuted() throws Exception {
+ Assert.assertNotNull("Description should contain reference to TestClass", applyTestClass);
+ }
+
+ public static final class CustomRule implements TestRule {
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ Class<?> testClass = description.getTestClass();
+ if(testClass != null) {
+ Field field = testClass.getDeclaredField("applyTestClass");
+ field.set(null, description.getTestClass());
+ }
+ base.evaluate();
+ }
+ };
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/AllCoreTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/AllCoreTests.java
new file mode 100644
index 0000000..a17a7e2
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/AllCoreTests.java
@@ -0,0 +1,14 @@
+package org.junit.tests.running.core;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ CommandLineTest.class,
+ JUnitCoreReturnsCorrectExitCodeTest.class,
+ SystemExitTest.class
+})
+public class AllCoreTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/CommandLineTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/CommandLineTest.java
new file mode 100644
index 0000000..37f0659
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/CommandLineTest.java
@@ -0,0 +1,78 @@
+package org.junit.tests.running.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+
+public class CommandLineTest {
+ private ByteArrayOutputStream results;
+ private PrintStream oldOut;
+ private static boolean testWasRun;
+
+ @Before
+ public void before() {
+ oldOut = System.out;
+ results = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(results));
+ }
+
+ @After
+ public void after() {
+ System.setOut(oldOut);
+ }
+
+ public static class Example {
+ @Test
+ public void test() {
+ testWasRun = true;
+ }
+ }
+
+ @Test
+ public void runATest() {
+ testWasRun = false;
+ new MainRunner().runWithCheckForSystemExit(new Runnable() {
+ public void run() {
+ JUnitCore.main("org.junit.tests.running.core.CommandLineTest$Example");
+ }
+ });
+ assertTrue(testWasRun);
+ }
+
+ @Test
+ public void runAClass() {
+ testWasRun = false;
+ JUnitCore.runClasses(Example.class);
+ assertTrue(testWasRun);
+ }
+
+ private static int fCount;
+
+ public static class Count {
+ @Test
+ public void increment() {
+ fCount++;
+ }
+ }
+
+ @Test
+ public void runTwoClassesAsArray() {
+ fCount = 0;
+ JUnitCore.runClasses(new Class[]{Count.class, Count.class});
+ assertEquals(2, fCount);
+ }
+
+ @Test
+ public void runTwoClasses() {
+ fCount = 0;
+ JUnitCore.runClasses(Count.class, Count.class);
+ assertEquals(2, fCount);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java
new file mode 100644
index 0000000..64af301
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java
@@ -0,0 +1,47 @@
+package org.junit.tests.running.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+
+public class JUnitCoreReturnsCorrectExitCodeTest {
+
+ public static class Fail {
+ @Test
+ public void kaboom() {
+ fail();
+ }
+ }
+
+ @Test
+ public void failureCausesExitCodeOf1() throws Exception {
+ runClass(getClass().getName() + "$Fail", 1);
+ }
+
+ @Test
+ public void missingClassCausesExitCodeOf1() throws Exception {
+ runClass("Foo", 1);
+ }
+
+ public static class Succeed {
+ @Test
+ public void peacefulSilence() {
+ }
+ }
+
+ @Test
+ public void successCausesExitCodeOf0() throws Exception {
+ runClass(getClass().getName() + "$Succeed", 0);
+ }
+
+ private void runClass(final String className, int returnCode) {
+ Integer exitValue = new MainRunner().runWithCheckForSystemExit(new Runnable() {
+ public void run() {
+ JUnitCore.main(className);
+ }
+ });
+ assertEquals(Integer.valueOf(returnCode), exitValue);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/MainRunner.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/MainRunner.java
new file mode 100644
index 0000000..ea90886
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/MainRunner.java
@@ -0,0 +1,67 @@
+package org.junit.tests.running.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.security.Permission;
+
+public class MainRunner {
+ private static class ExitException extends SecurityException {
+ private static final long serialVersionUID = -9104651568237766642L;
+
+ private final int status;
+
+ public ExitException(int status) {
+ super("");
+ this.status = status;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+ }
+
+ /**
+ * A {@code NoExitSecurityManager} throws a {@link ExitException} exception
+ * whenever {@link #checkExit(int)} is called; all other permissions are allowed.
+ */
+ public class NoExitSecurityManager extends SecurityManager {
+
+ @Override
+ public void checkExit(int status) {
+ throw new ExitException(status);
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ if (perm.getName().startsWith("exitVM")) {
+ super.checkPermission(perm);
+ }
+ }
+ }
+
+ /**
+ * Execute runnable.run(), preventing System.exit(). If System.exit() is called
+ * in runnable.run(), the value is returned. If System.exit()
+ * is not called, null is returned.
+ *
+ * @return null if System.exit() is not called, Integer.valueof(status) if not
+ */
+ public Integer runWithCheckForSystemExit(Runnable runnable) {
+ SecurityManager oldSecurityManager = System.getSecurityManager();
+ System.setSecurityManager(new NoExitSecurityManager());
+ PrintStream oldOut = System.out;
+
+ System.setOut(new PrintStream(new ByteArrayOutputStream()));
+ try {
+ runnable.run();
+ System.out.println("System.exit() not called, return null");
+ return null;
+ } catch (ExitException e) {
+ System.out.println("System.exit() called, value=" + e.getStatus());
+ return e.getStatus();
+ } finally {
+ System.setSecurityManager(oldSecurityManager);
+ System.setOut(oldOut);
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/SystemExitTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/SystemExitTest.java
new file mode 100644
index 0000000..3e2dc7c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/core/SystemExitTest.java
@@ -0,0 +1,31 @@
+package org.junit.tests.running.core;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+// Make sure System.exit works as expected. We've had problems with this on some platforms.
+public class SystemExitTest {
+
+ private static final int EXIT_CODE = 5;
+
+ static public class Exit {
+ public static void main(String[] args) {
+ System.exit(EXIT_CODE);
+ }
+ }
+
+ @Test
+ public void failureCausesExitCodeOf1() throws Exception {
+ String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
+ String classPath = getClass().getClassLoader().getResource(".").getFile() + File.pathSeparator + System.getProperty("java.class.path");
+ String[] cmd = {java, "-cp", classPath, getClass().getName() + "$Exit"};
+ Process process = Runtime.getRuntime().exec(cmd);
+ InputStream input = process.getInputStream();
+ while ((input.read()) != -1) ;
+ assertEquals(EXIT_CODE, process.waitFor());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AllMethodsTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AllMethodsTests.java
new file mode 100644
index 0000000..533bb5e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AllMethodsTests.java
@@ -0,0 +1,17 @@
+package org.junit.tests.running.methods;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AnnotationTest.class,
+ ExpectedTest.class,
+ InheritedTestTest.class,
+ ParameterizedTestMethodTest.class,
+ TestMethodTest.class,
+ TimeoutTest.class
+})
+public class AllMethodsTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AnnotationTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AnnotationTest.java
new file mode 100644
index 0000000..0025178
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/AnnotationTest.java
@@ -0,0 +1,842 @@
+package org.junit.tests.running.methods;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.experimental.results.PrintableResult.testResult;
+import static org.junit.experimental.results.ResultMatchers.isSuccessful;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class AnnotationTest extends TestCase {
+ static boolean run;
+
+ @Override
+ public void setUp() {
+ run = false;
+ }
+
+ public static class SimpleTest {
+ @Test
+ public void success() {
+ run = true;
+ }
+ }
+
+ public void testAnnotatedMethod() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(SimpleTest.class);
+ assertTrue(run);
+ }
+
+ @RunWith(JUnit4.class)
+ public static class SimpleTestWithFutureProofExplicitRunner {
+ @Test
+ public void success() {
+ run = true;
+ }
+ }
+
+ public void testAnnotatedMethodWithFutureProofExplicitRunner() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(SimpleTestWithFutureProofExplicitRunner.class);
+ assertTrue(run);
+ }
+
+ public static class SetupTest {
+ @Before
+ public void before() {
+ run = true;
+ }
+
+ @Test
+ public void success() {
+ }
+ }
+
+ public void testSetup() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(SetupTest.class);
+ assertTrue(run);
+ }
+
+ public static class TeardownTest {
+ @After
+ public void after() {
+ run = true;
+ }
+
+ @Test
+ public void success() {
+ }
+ }
+
+ public void testTeardown() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(TeardownTest.class);
+ assertTrue(run);
+ }
+
+ public static class FailureTest {
+ @Test
+ public void error() throws Exception {
+ org.junit.Assert.fail();
+ }
+ }
+
+ public void testRunFailure() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(FailureTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(AssertionError.class, result.getFailures().get(0).getException().getClass());
+ }
+
+ public static class SetupFailureTest {
+ @Before
+ public void before() {
+ throw new Error();
+ }
+
+ @Test
+ public void test() {
+ run = true;
+ }
+ }
+
+ public void testSetupFailure() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result runner = core.run(SetupFailureTest.class);
+ assertEquals(1, runner.getRunCount());
+ assertEquals(1, runner.getFailureCount());
+ assertEquals(Error.class, runner.getFailures().get(0).getException().getClass());
+ assertFalse(run);
+ }
+
+ public static class TeardownFailureTest {
+ @After
+ public void after() {
+ throw new Error();
+ }
+
+ @Test
+ public void test() {
+ }
+ }
+
+ public void testTeardownFailure() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result runner = core.run(TeardownFailureTest.class);
+ assertEquals(1, runner.getRunCount());
+ assertEquals(1, runner.getFailureCount());
+ assertEquals(Error.class, runner.getFailures().get(0).getException().getClass());
+ }
+
+ public static class TestAndTeardownFailureTest {
+ @After
+ public void after() {
+ throw new Error("hereAfter");
+ }
+
+ @Test
+ public void test() throws Exception {
+ throw new Exception("inTest");
+ }
+ }
+
+ public void testTestAndTeardownFailure() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result runner = core.run(TestAndTeardownFailureTest.class);
+ assertEquals(1, runner.getRunCount());
+ assertEquals(2, runner.getFailureCount());
+ assertThat(runner.getFailures().toString(), allOf(containsString("hereAfter"), containsString("inTest")));
+ }
+
+ public static class TeardownAfterFailureTest {
+ @After
+ public void after() {
+ run = true;
+ }
+
+ @Test
+ public void test() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ public void testTeardownAfterFailure() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(TeardownAfterFailureTest.class);
+ assertTrue(run);
+ }
+
+ static int count;
+ static Collection<Object> tests;
+
+ public static class TwoTests {
+ @Test
+ public void one() {
+ count++;
+ tests.add(this);
+ }
+
+ @Test
+ public void two() {
+ count++;
+ tests.add(this);
+ }
+ }
+
+ public void testTwoTests() throws Exception {
+ count = 0;
+ tests = new HashSet<Object>();
+ JUnitCore runner = new JUnitCore();
+ runner.run(TwoTests.class);
+ assertEquals(2, count);
+ assertEquals(2, tests.size());
+ }
+
+ public static class OldTest extends TestCase {
+ public void test() {
+ run = true;
+ }
+ }
+
+ public void testOldTest() throws Exception {
+ JUnitCore runner = new JUnitCore();
+ runner.run(OldTest.class);
+ assertTrue(run);
+ }
+
+ public static class OldSuiteTest extends TestCase {
+ public void testOne() {
+ run = true;
+ }
+ }
+
+ public void testOldSuiteTest() throws Exception {
+ TestSuite suite = new TestSuite(OldSuiteTest.class);
+ JUnitCore runner = new JUnitCore();
+ runner.run(suite);
+ assertTrue(run);
+ }
+
+ public static class ExceptionTest {
+ @Test(expected = Error.class)
+ public void expectedException() {
+ throw new Error();
+ }
+ }
+
+ public void testException() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(ExceptionTest.class);
+ assertEquals(0, result.getFailureCount());
+ }
+
+ public static class NoExceptionTest {
+ @Test(expected = Error.class)
+ public void expectedException() {
+ }
+ }
+
+ public void testExceptionNotThrown() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(NoExceptionTest.class);
+ assertEquals(1, result.getFailureCount());
+ assertEquals("Expected exception: java.lang.Error", result.getFailures().get(0).getMessage());
+ }
+
+ public static class OneTimeSetup {
+ @BeforeClass
+ public static void once() {
+ count++;
+ }
+
+ @Test
+ public void one() {
+ }
+
+ @Test
+ public void two() {
+ }
+ }
+
+ public void testOneTimeSetup() throws Exception {
+ count = 0;
+ JUnitCore core = new JUnitCore();
+ core.run(OneTimeSetup.class);
+ assertEquals(1, count);
+ }
+
+ public static class OneTimeTeardown {
+ @AfterClass
+ public static void once() {
+ count++;
+ }
+
+ @Test
+ public void one() {
+ }
+
+ @Test
+ public void two() {
+ }
+ }
+
+ public void testOneTimeTeardown() throws Exception {
+ count = 0;
+ JUnitCore core = new JUnitCore();
+ core.run(OneTimeTeardown.class);
+ assertEquals(1, count);
+ }
+
+ static String log;
+
+ public static class OrderTest {
+ @BeforeClass
+ public static void onceBefore() {
+ log += "beforeClass ";
+ }
+
+ @Before
+ public void before() {
+ log += "before ";
+ }
+
+ @Test
+ public void test() {
+ log += "test ";
+ }
+
+ @After
+ public void after() {
+ log += "after ";
+ }
+
+ @AfterClass
+ public static void onceAfter() {
+ log += "afterClass ";
+ }
+ }
+
+ public void testOrder() throws Exception {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ core.run(OrderTest.class);
+ assertEquals("beforeClass before test after afterClass ", log);
+ }
+
+ public static class NonStaticOneTimeSetup {
+ @BeforeClass
+ public void once() {
+ }
+
+ @Test
+ public void aTest() {
+ }
+ }
+
+ public void testNonStaticOneTimeSetup() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(NonStaticOneTimeSetup.class);
+ assertEquals(1, result.getFailureCount());
+ }
+
+ public static class ErrorInBeforeClass {
+ @BeforeClass
+ public static void before() throws Exception {
+ throw new Exception();
+ }
+
+ @Test
+ public void test() {
+ run = true;
+ }
+ }
+
+ public void testErrorInBeforeClass() throws Exception {
+ run = false;
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(ErrorInBeforeClass.class);
+ assertFalse(run);
+ assertEquals(1, result.getFailureCount());
+ Description description = result.getFailures().get(0).getDescription();
+ assertEquals(ErrorInBeforeClass.class.getName(), description.getDisplayName());
+ }
+
+ public static class ErrorInAfterClass {
+ @Test
+ public void test() {
+ run = true;
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ public void testErrorInAfterClass() throws Exception {
+ run = false;
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(ErrorInAfterClass.class);
+ assertTrue(run);
+ assertEquals(1, result.getFailureCount());
+ }
+
+ static class SuperInheritance {
+ @BeforeClass
+ public static void beforeClassSuper() {
+ log += "Before class super ";
+ }
+
+ @AfterClass
+ public static void afterClassSuper() {
+ log += "After class super ";
+ }
+
+ @Before
+ public void beforeSuper() {
+ log += "Before super ";
+ }
+
+ @After
+ public void afterSuper() {
+ log += "After super ";
+ }
+ }
+
+ public static class SubInheritance extends SuperInheritance {
+ @BeforeClass
+ public static void beforeClassSub() {
+ log += "Before class sub ";
+ }
+
+ @AfterClass
+ public static void afterClassSub() {
+ log += "After class sub ";
+ }
+
+ @Before
+ public void beforeSub() {
+ log += "Before sub ";
+ }
+
+ @After
+ public void afterSub() {
+ log += "After sub ";
+ }
+
+ @Test
+ public void test() {
+ log += "Test ";
+ }
+ }
+
+ public void testOrderingOfInheritance() throws Exception {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ core.run(SubInheritance.class);
+ assertEquals("Before class super Before class sub Before super Before sub Test After sub After super After class sub After class super ", log);
+ }
+
+ public abstract static class SuperShadowing {
+
+ @Rule
+ public TestRule rule() {
+ return new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "super.rule().before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "super.rule().after() ";
+ }
+ };
+ }
+
+ @Before
+ public void before() {
+ log += "super.before() ";
+ }
+
+ @After
+ public void after() {
+ log += "super.after() ";
+ }
+ }
+
+ public static class SubShadowing extends SuperShadowing {
+
+ @Override
+ @Rule
+ public TestRule rule() {
+ return new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "sub.rule().before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "sub.rule().after() ";
+ }
+ };
+ }
+
+ @Override
+ @Before
+ public void before() {
+ super.before();
+ log += "sub.before() ";
+ }
+
+ @Before
+ public void anotherBefore() {
+ log += "sub.anotherBefore() ";
+ }
+
+ @Override
+ @After
+ public void after() {
+ log += "sub.after() ";
+ super.after();
+ }
+
+ @After
+ public void anotherAfter() {
+ log += "sub.anotherAfter() ";
+ }
+
+ @Test
+ public void test() {
+ log += "Test ";
+ }
+ }
+
+ public void testShadowing() throws Exception {
+ log = "";
+ assertThat(testResult(SubShadowing.class), isSuccessful());
+ assertEquals(
+ "sub.rule().before() sub.anotherBefore() super.before() sub.before() "
+ + "Test "
+ + "sub.anotherAfter() sub.after() super.after() sub.rule().after() ",
+ log);
+ }
+
+ public abstract static class SuperStaticMethodShadowing {
+
+ @ClassRule
+ public static TestRule rule() {
+ return new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "super.rule().before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "super.rule().after() ";
+ }
+ };
+ }
+ }
+
+ public static class SubStaticMethodShadowing extends SuperStaticMethodShadowing {
+
+ @ClassRule
+ public static TestRule rule() {
+ return new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "sub.rule().before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "sub.rule().after() ";
+ }
+ };
+ }
+
+ @Test
+ public void test() {
+ log += "Test ";
+ }
+ }
+
+ public void testStaticMethodsCanBeTreatedAsShadowed() throws Exception {
+ log = "";
+ assertThat(testResult(SubStaticMethodShadowing.class), isSuccessful());
+ assertEquals(
+ "sub.rule().before() "
+ + "Test "
+ + "sub.rule().after() ",
+ log);
+ }
+
+ public abstract static class SuperFieldShadowing {
+
+ @Rule
+ public final TestRule rule = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "super.rule.before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "super.rule.after() ";
+ }
+ };
+ }
+
+ public static class SubFieldShadowing extends SuperFieldShadowing {
+
+ @Rule
+ public final TestRule rule = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "sub.rule.before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "sub.rule.after() ";
+ }
+ };
+
+ @Test
+ public void test() {
+ log += "Test ";
+ }
+ }
+
+ public void testFieldsShadowFieldsFromParent() throws Exception {
+ log = "";
+ assertThat(testResult(SubFieldShadowing.class), isSuccessful());
+ assertEquals(
+ "sub.rule.before() "
+ + "Test "
+ + "sub.rule.after() ",
+ log);
+ }
+
+ public abstract static class SuperStaticFieldShadowing {
+
+ @ClassRule
+ public static TestRule rule = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "super.rule.before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "super.rule.after() ";
+ }
+ };
+ }
+
+ public static class SubStaticFieldShadowing extends SuperStaticFieldShadowing {
+
+ @ClassRule
+ public static TestRule rule = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ log += "sub.rule.before() ";
+ }
+
+ @Override
+ protected void after() {
+ log += "sub.rule.after() ";
+ }
+ };
+
+ @Test
+ public void test() {
+ log += "Test ";
+ }
+ }
+
+ public void testStaticFieldsCanBeTreatedAsShadowed() throws Exception {
+ log = "";
+ assertThat(testResult(SubStaticFieldShadowing.class), isSuccessful());
+ assertEquals(
+ "sub.rule.before() "
+ + "Test "
+ + "sub.rule.after() ",
+ log);
+ }
+
+ public static class SuperTest {
+ @Test
+ public void one() {
+ log += "Super";
+ }
+
+ @Test
+ public void two() {
+ log += "Two";
+ }
+ }
+
+ public static class SubTest extends SuperTest {
+ @Override
+ @Test
+ public void one() {
+ log += "Sub";
+ }
+ }
+
+ public void testTestInheritance() throws Exception {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ core.run(SubTest.class);
+ // The order in which the test methods are called is unspecified
+ assertTrue(log.contains("Sub"));
+ assertTrue(log.contains("Two"));
+ assertFalse(log.contains("Super"));
+ }
+
+ public static class RunAllAfters {
+ @Before
+ public void good() {
+ }
+
+ @Before
+ public void bad() {
+ throw new Error();
+ }
+
+ @Test
+ public void empty() {
+ }
+
+ @After
+ public void one() {
+ log += "one";
+ }
+
+ @After
+ public void two() {
+ log += "two";
+ }
+ }
+
+ public void testRunAllAfters() {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ core.run(RunAllAfters.class);
+ assertTrue(log.contains("one"));
+ assertTrue(log.contains("two"));
+ }
+
+ public static class RunAllAftersRegardless {
+ @Test
+ public void empty() {
+ }
+
+ @After
+ public void one() {
+ log += "one";
+ throw new Error();
+ }
+
+ @After
+ public void two() {
+ log += "two";
+ throw new Error();
+ }
+ }
+
+ public void testRunAllAftersRegardless() {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(RunAllAftersRegardless.class);
+ assertTrue(log.contains("one"));
+ assertTrue(log.contains("two"));
+ assertEquals(2, result.getFailureCount());
+ }
+
+ public static class RunAllAfterClasses {
+ @Before
+ public void good() {
+ }
+
+ @BeforeClass
+ public static void bad() {
+ throw new Error();
+ }
+
+ @Test
+ public void empty() {
+ }
+
+ @AfterClass
+ public static void one() {
+ log += "one";
+ }
+
+ @AfterClass
+ public static void two() {
+ log += "two";
+ }
+ }
+
+ public void testRunAllAfterClasses() {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ core.run(RunAllAfterClasses.class);
+ assertTrue(log.contains("one"));
+ assertTrue(log.contains("two"));
+ }
+
+ public static class RunAllAfterClassesRegardless {
+ @Test
+ public void empty() {
+ }
+
+ @AfterClass
+ public static void one() {
+ log += "one";
+ throw new Error();
+ }
+
+ @AfterClass
+ public static void two() {
+ log += "two";
+ throw new Error();
+ }
+ }
+
+ public void testRunAllAfterClassesRegardless() {
+ log = "";
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(RunAllAfterClassesRegardless.class);
+ assertTrue(log.contains("one"));
+ assertTrue(log.contains("two"));
+ assertEquals(2, result.getFailureCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ExpectedTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ExpectedTest.java
new file mode 100644
index 0000000..90e55f3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ExpectedTest.java
@@ -0,0 +1,83 @@
+package org.junit.tests.running.methods;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+public class ExpectedTest {
+
+ public static class Expected {
+ @Test(expected = Exception.class)
+ public void expected() throws Exception {
+ throw new Exception();
+ }
+ }
+
+ @Test
+ public void expected() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(Expected.class);
+ assertTrue(result.wasSuccessful());
+ }
+
+ public static class Unexpected {
+ @Test(expected = Exception.class)
+ public void expected() throws Exception {
+ throw new Error();
+ }
+ }
+
+ @Test
+ public void unexpected() {
+ Result result = JUnitCore.runClasses(Unexpected.class);
+ Failure failure = result.getFailures().get(0);
+ String message = failure.getMessage();
+ assertTrue(message.contains("expected<java.lang.Exception> but was<java.lang.Error>"));
+ assertEquals(Error.class, failure.getException().getCause().getClass());
+ }
+
+ public static class NoneThrown {
+ @Test(expected = Exception.class)
+ public void nothing() {
+ }
+ }
+
+ @Test
+ public void noneThrown() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(NoneThrown.class);
+ assertFalse(result.wasSuccessful());
+ String message = result.getFailures().get(0).getMessage();
+ assertTrue(message.contains("Expected exception: java.lang.Exception"));
+ }
+
+ public static class ExpectSuperclass {
+ @Test(expected = RuntimeException.class)
+ public void throwsSubclass() {
+ throw new ClassCastException();
+ }
+ }
+
+ @Test
+ public void expectsSuperclass() {
+ assertTrue(new JUnitCore().run(ExpectSuperclass.class).wasSuccessful());
+ }
+
+ public static class ExpectAssumptionViolatedException {
+ @Test(expected = AssumptionViolatedException.class)
+ public void throwsAssumptionViolatedException() {
+ throw new AssumptionViolatedException("expected");
+ }
+ }
+
+ @Test
+ public void expectsAssumptionViolatedException() {
+ assertTrue(new JUnitCore().run(ExpectAssumptionViolatedException.class).wasSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/InheritedTestTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/InheritedTestTest.java
new file mode 100644
index 0000000..53f858b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/InheritedTestTest.java
@@ -0,0 +1,39 @@
+package org.junit.tests.running.methods;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class InheritedTestTest {
+ public abstract static class Super {
+ @Test
+ public void nothing() {
+ }
+ }
+
+ public static class Sub extends Super {
+ }
+
+ @Test
+ public void subclassWithOnlyInheritedTestsRuns() {
+ Result result = JUnitCore.runClasses(Sub.class);
+ assertTrue(result.wasSuccessful());
+ }
+
+ public static class SubWithBefore extends Super {
+ @Before
+ public void gack() {
+ fail();
+ }
+ }
+
+ @Test
+ public void subclassWithInheritedTestAndOwnBeforeRunsBefore() {
+ assertFalse(JUnitCore.runClasses(SubWithBefore.class).wasSuccessful());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java
new file mode 100644
index 0000000..4e24958
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java
@@ -0,0 +1,188 @@
+package org.junit.tests.running.methods;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.JUnit4TestAdapter;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.model.InitializationError;
+
+@RunWith(Parameterized.class)
+public class ParameterizedTestMethodTest {
+
+ @SuppressWarnings("all")
+ public static class EverythingWrong {
+ private EverythingWrong() {
+ }
+
+ @BeforeClass
+ public void notStaticBC() {
+ }
+
+ @BeforeClass
+ static void notPublicBC() {
+ }
+
+ @BeforeClass
+ public static int nonVoidBC() {
+ return 0;
+ }
+
+ @BeforeClass
+ public static void argumentsBC(int i) {
+ }
+
+ @BeforeClass
+ public static void fineBC() {
+ }
+
+ @AfterClass
+ public void notStaticAC() {
+ }
+
+ @AfterClass
+ static void notPublicAC() {
+ }
+
+ @AfterClass
+ public static int nonVoidAC() {
+ return 0;
+ }
+
+ @AfterClass
+ public static void argumentsAC(int i) {
+ }
+
+ @AfterClass
+ public static void fineAC() {
+ }
+
+ @After
+ public static void staticA() {
+ }
+
+ @After
+ void notPublicA() {
+ }
+
+ @After
+ public int nonVoidA() {
+ return 0;
+ }
+
+ @After
+ public void argumentsA(int i) {
+ }
+
+ @After
+ public void fineA() {
+ }
+
+ @Before
+ public static void staticB() {
+ }
+
+ @Before
+ void notPublicB() {
+ }
+
+ @Before
+ public int nonVoidB() {
+ return 0;
+ }
+
+ @Before
+ public void argumentsB(int i) {
+ }
+
+ @Before
+ public void fineB() {
+ }
+
+ @Test
+ public static void staticT() {
+ }
+
+ @Test
+ void notPublicT() {
+ }
+
+ @Test
+ public int nonVoidT() {
+ return 0;
+ }
+
+ @Test
+ public void argumentsT(int i) {
+ }
+
+ @Test
+ public void fineT() {
+ }
+ }
+
+ private Class<?> fClass;
+ private int fErrorCount;
+
+ public static class SuperWrong {
+ @Test
+ void notPublic() {
+ }
+ }
+
+ public static class SubWrong extends SuperWrong {
+ @Test
+ public void justFine() {
+ }
+ }
+
+ public static class SubShadows extends SuperWrong {
+ @Override
+ @Test
+ public void notPublic() {
+ }
+ }
+
+ public ParameterizedTestMethodTest(Class<?> class1, int errorCount) {
+ fClass = class1;
+ fErrorCount = errorCount;
+ }
+
+ @Parameters
+ public static Collection<Object[]> params() {
+ return Arrays.asList(new Object[][]{
+ {EverythingWrong.class, 1 + 4 * 5}, {SubWrong.class, 1},
+ {SubShadows.class, 0}});
+ }
+
+ private List<Throwable> validateAllMethods(Class<?> clazz) {
+ try {
+ new BlockJUnit4ClassRunner(clazz);
+ } catch (InitializationError e) {
+ return e.getCauses();
+ }
+ return Collections.emptyList();
+ }
+
+ @Test
+ public void testFailures() throws Exception {
+ List<Throwable> problems = validateAllMethods(fClass);
+ assertEquals(fErrorCount, problems.size());
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(ParameterizedTestMethodTest.class);
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TestMethodTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TestMethodTest.java
new file mode 100644
index 0000000..69a437e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TestMethodTest.java
@@ -0,0 +1,255 @@
+package org.junit.tests.running.methods;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestResult;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+public class TestMethodTest {
+
+ @SuppressWarnings("all")
+ public static class EverythingWrong {
+ private EverythingWrong() {
+ }
+
+ @BeforeClass
+ public void notStaticBC() {
+ }
+
+ @BeforeClass
+ static void notPublicBC() {
+ }
+
+ @BeforeClass
+ public static int nonVoidBC() {
+ return 0;
+ }
+
+ @BeforeClass
+ public static void argumentsBC(int i) {
+ }
+
+ @BeforeClass
+ public static void fineBC() {
+ }
+
+ @AfterClass
+ public void notStaticAC() {
+ }
+
+ @AfterClass
+ static void notPublicAC() {
+ }
+
+ @AfterClass
+ public static int nonVoidAC() {
+ return 0;
+ }
+
+ @AfterClass
+ public static void argumentsAC(int i) {
+ }
+
+ @AfterClass
+ public static void fineAC() {
+ }
+
+ @After
+ public static void staticA() {
+ }
+
+ @After
+ void notPublicA() {
+ }
+
+ @After
+ public int nonVoidA() {
+ return 0;
+ }
+
+ @After
+ public void argumentsA(int i) {
+ }
+
+ @After
+ public void fineA() {
+ }
+
+ @Before
+ public static void staticB() {
+ }
+
+ @Before
+ void notPublicB() {
+ }
+
+ @Before
+ public int nonVoidB() {
+ return 0;
+ }
+
+ @Before
+ public void argumentsB(int i) {
+ }
+
+ @Before
+ public void fineB() {
+ }
+
+ @Test
+ public static void staticT() {
+ }
+
+ @Test
+ void notPublicT() {
+ }
+
+ @Test
+ public int nonVoidT() {
+ return 0;
+ }
+
+ @Test
+ public void argumentsT(int i) {
+ }
+
+ @Test
+ public void fineT() {
+ }
+ }
+
+ @Test
+ public void testFailures() throws Exception {
+ List<Throwable> problems = validateAllMethods(EverythingWrong.class);
+ int errorCount = 1 + 4 * 5; // missing constructor plus four invalid methods for each annotation */
+ assertEquals(errorCount, problems.size());
+ }
+
+ static public class SuperWrong {
+ @Test
+ void notPublic() {
+ }
+ }
+
+ static public class SubWrong extends SuperWrong {
+ @Test
+ public void justFine() {
+ }
+ }
+
+ @Test
+ public void validateInheritedMethods() throws Exception {
+ List<Throwable> problems = validateAllMethods(SubWrong.class);
+ assertEquals(1, problems.size());
+ }
+
+ static public class SubShadows extends SuperWrong {
+ @Override
+ @Test
+ public void notPublic() {
+ }
+ }
+
+ @Test
+ public void dontValidateShadowedMethods() throws Exception {
+ List<Throwable> problems = validateAllMethods(SubShadows.class);
+ assertTrue(problems.isEmpty());
+ }
+
+ private List<Throwable> validateAllMethods(Class<?> clazz) {
+ try {
+ new BlockJUnit4ClassRunner(clazz);
+ } catch (InitializationError e) {
+ return e.getCauses();
+ }
+ return Collections.emptyList();
+ }
+
+ static public class IgnoredTest {
+ @Test
+ public void valid() {
+ }
+
+ @Ignore
+ @Test
+ public void ignored() {
+ }
+
+ @Ignore("For testing purposes")
+ @Test
+ public void withReason() {
+ }
+ }
+
+ @Test
+ public void ignoreRunner() {
+ JUnitCore runner = new JUnitCore();
+ Result result = runner.run(IgnoredTest.class);
+ assertEquals(2, result.getIgnoreCount());
+ assertEquals(1, result.getRunCount());
+ }
+
+ @Test
+ public void compatibility() {
+ TestResult result = new TestResult();
+ new JUnit4TestAdapter(IgnoredTest.class).run(result);
+ assertEquals(1, result.runCount());
+ }
+
+ public static class Confused {
+ @Test
+ public void a(Object b) {
+ }
+
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test(expected = InitializationError.class)
+ public void overloaded() throws InitializationError {
+ new BlockJUnit4ClassRunner(Confused.class);
+ }
+
+ public static class ConstructorParameter {
+ public ConstructorParameter(Object something) {
+ }
+
+ @Test
+ public void a() {
+ }
+ }
+
+ @Test(expected = InitializationError.class)
+ public void constructorParameter() throws InitializationError {
+ new BlockJUnit4ClassRunner(ConstructorParameter.class);
+ }
+
+ public static class OnlyTestIsIgnored {
+ @Ignore
+ @Test
+ public void ignored() {
+ }
+ }
+
+ @Test
+ public void onlyIgnoredMethodsIsStillFineTestClass() {
+ Result result = JUnitCore.runClasses(OnlyTestIsIgnored.class);
+ assertEquals(0, result.getFailureCount());
+ assertEquals(1, result.getIgnoreCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TimeoutTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TimeoutTest.java
new file mode 100644
index 0000000..21095fd
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/running/methods/TimeoutTest.java
@@ -0,0 +1,334 @@
+package org.junit.tests.running.methods;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestResult;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class TimeoutTest {
+
+ public static class FailureWithTimeoutTest {
+ @Test(timeout = 1000)
+ public void failure() {
+ fail();
+ }
+ }
+
+ @Test
+ public void failureWithTimeout() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(FailureWithTimeoutTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(AssertionError.class, result.getFailures().get(0).getException().getClass());
+ }
+
+ public static class FailureWithTimeoutRunTimeExceptionTest {
+ @Test(timeout = 1000)
+ public void failure() {
+ throw new NullPointerException();
+ }
+ }
+
+ @Test
+ public void failureWithTimeoutRunTimeException() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(FailureWithTimeoutRunTimeExceptionTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(NullPointerException.class, result.getFailures().get(0).getException().getClass());
+ }
+
+ public static class SuccessWithTimeoutTest {
+ @Test(timeout = 1000)
+ public void success() {
+ }
+ }
+
+ @Test
+ public void successWithTimeout() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(SuccessWithTimeoutTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(0, result.getFailureCount());
+ }
+
+ public static class TimeoutFailureTest {
+ @Test(timeout = 100)
+ public void success() throws InterruptedException {
+ Thread.sleep(40000);
+ }
+ }
+
+ @Ignore("was breaking gump")
+ @Test
+ public void timeoutFailure() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(TimeoutFailureTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ assertEquals(InterruptedException.class, result.getFailures().get(0).getException().getClass());
+ }
+
+ public static class InfiniteLoopTest {
+ @Test(timeout = 100)
+ public void failure() {
+ infiniteLoop();
+ }
+
+ private void infiniteLoop() {
+ for (; ; ) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
+ @Test
+ public void infiniteLoop() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(InfiniteLoopTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ Throwable exception = result.getFailures().get(0).getException();
+ assertTrue(exception.getMessage().contains("test timed out after 100 milliseconds"));
+ }
+
+ public static class ImpatientLoopTest {
+ @Test(timeout = 1)
+ public void failure() {
+ infiniteLoop();
+ }
+
+ private void infiniteLoop() {
+ for (; ; ) ;
+ }
+ }
+
+ @Ignore("This breaks sporadically with time differences just slightly more than 200ms")
+ @Test
+ public void infiniteLoopRunsForApproximatelyLengthOfTimeout() throws Exception {
+ // "prime the pump": running these beforehand makes the runtimes more predictable
+ // (because of class loading?)
+ JUnitCore.runClasses(InfiniteLoopTest.class, ImpatientLoopTest.class);
+ long longTime = runAndTime(InfiniteLoopTest.class);
+ long shortTime = runAndTime(ImpatientLoopTest.class);
+ long difference = longTime - shortTime;
+ assertTrue(String.format("Difference was %sms", difference), difference < 200);
+ }
+
+ private long runAndTime(Class<?> clazz) {
+ JUnitCore core = new JUnitCore();
+ long startTime = System.currentTimeMillis();
+ core.run(clazz);
+ long totalTime = System.currentTimeMillis() - startTime;
+ return totalTime;
+ }
+
+ private String stackForException(Throwable exception) {
+ Writer buffer = new StringWriter();
+ PrintWriter writer = new PrintWriter(buffer);
+ exception.printStackTrace(writer);
+ return buffer.toString();
+ }
+
+ @Test
+ public void stalledThreadAppearsInStackTrace() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(InfiniteLoopTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ Throwable exception = result.getFailures().get(0).getException();
+ assertThat(stackForException(exception), containsString("infiniteLoop")); // Make sure we have the stalled frame on the stack somewhere
+ }
+
+ public static class InfiniteLoopMultithreaded {
+
+ private static class ThreadTest implements Runnable {
+ private boolean fStall;
+
+ public ThreadTest(boolean stall) {
+ fStall = stall;
+ }
+
+ public void run() {
+ if (fStall)
+ for (; ; ) ;
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public void failure(boolean mainThreadStalls) throws Exception {
+ Thread t1 = new Thread(new ThreadTest(false), "timeout-thr1");
+ Thread t2 = new Thread(new ThreadTest(!mainThreadStalls), "timeout-thr2");
+ Thread t3 = new Thread(new ThreadTest(false), "timeout-thr3");
+ t1.start();
+ t2.start();
+ t3.start();
+ if (mainThreadStalls)
+ for (; ; ) ;
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ }
+
+ public static class InfiniteLoopWithStuckThreadTest {
+ @Rule
+ public TestRule globalTimeout = Timeout.builder()
+ .withTimeout(100, TimeUnit.MILLISECONDS)
+ .withLookingForStuckThread(true)
+ .build();
+
+ @Test
+ public void failure() throws Exception {
+ (new InfiniteLoopMultithreaded()).failure(false);
+ }
+ }
+
+ public static class InfiniteLoopStuckInMainThreadTest {
+ @Rule
+ public TestRule globalTimeout = Timeout.builder()
+ .withTimeout(100, TimeUnit.MILLISECONDS)
+ .withLookingForStuckThread(true)
+ .build();
+
+ @Test
+ public void failure() throws Exception {
+ (new InfiniteLoopMultithreaded()).failure(true);
+ }
+ }
+
+ @Test
+ public void timeoutFailureMultithreaded() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(InfiniteLoopWithStuckThreadTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(2, result.getFailureCount());
+ Throwable exception[] = new Throwable[2];
+ for (int i = 0; i < 2; i++)
+ exception[i] = result.getFailures().get(i).getException();
+ assertThat(exception[0].getMessage(), containsString("test timed out after 100 milliseconds"));
+ assertThat(stackForException(exception[0]), containsString("Thread.join"));
+ assertThat(exception[1].getMessage(), containsString("Appears to be stuck in thread timeout-thr2"));
+ }
+
+ @Test
+ public void timeoutFailureMultithreadedStuckInMain() throws Exception {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(InfiniteLoopStuckInMainThreadTest.class);
+ assertEquals(1, result.getRunCount());
+ assertEquals(1, result.getFailureCount());
+ Throwable exception = result.getFailures().get(0).getException();
+ assertThat(exception.getMessage(), containsString("test timed out after 100 milliseconds"));
+ assertThat(exception.getMessage(), not(containsString("Appears to be stuck")));
+ }
+
+ @Test
+ public void compatibility() {
+ TestResult result = new TestResult();
+ new JUnit4TestAdapter(InfiniteLoopTest.class).run(result);
+ assertEquals(1, result.errorCount());
+ }
+
+ public static class WillTimeOut {
+ static boolean afterWasCalled = false;
+
+ @Test(timeout = 1)
+ public void test() {
+ for (; ; ) {
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ // ok, tests are over
+ }
+ }
+ }
+
+ @After
+ public void after() {
+ afterWasCalled = true;
+ }
+ }
+
+ @Test
+ public void makeSureAfterIsCalledAfterATimeout() {
+ JUnitCore.runClasses(WillTimeOut.class);
+ assertThat(WillTimeOut.afterWasCalled, is(true));
+ }
+
+ public static class TimeOutZero {
+ @Rule
+ public Timeout timeout = Timeout.seconds(0);
+
+ @Test
+ public void test() {
+ try {
+ Thread.sleep(200); // long enough to suspend thread execution
+ } catch (InterruptedException e) {
+ // Don't care
+ }
+ }
+ }
+
+ @Test
+ public void testZeroTimeoutIsIgnored() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(TimeOutZero.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should not have failed", 0, result.getFailureCount());
+ }
+
+ private static class TimeoutSubclass extends Timeout {
+
+ public TimeoutSubclass(long timeout, TimeUnit timeUnit) {
+ super(timeout, timeUnit);
+ }
+
+ public long getTimeoutFromSuperclass(TimeUnit unit) {
+ return super.getTimeout(unit);
+ }
+ }
+
+ public static class TimeOutOneSecond {
+ @Rule
+ public TimeoutSubclass timeout = new TimeoutSubclass(1, TimeUnit.SECONDS);
+
+ @Test
+ public void test() {
+ assertEquals(1000, timeout.getTimeoutFromSuperclass(TimeUnit.MILLISECONDS));
+ }
+ }
+
+ @Test
+ public void testGetTimeout() {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(TimeOutOneSecond.class);
+ assertEquals("Should run the test", 1, result.getRunCount());
+ assertEquals("Test should not have failed", 0, result.getFailureCount());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/AllValidationTests.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/AllValidationTests.java
new file mode 100644
index 0000000..f04723e
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/AllValidationTests.java
@@ -0,0 +1,14 @@
+package org.junit.tests.validation;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ BadlyFormedClassesTest.class,
+ FailedConstructionTest.class,
+ ValidationTest.class
+})
+public class AllValidationTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/BadlyFormedClassesTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/BadlyFormedClassesTest.java
new file mode 100644
index 0000000..d35de2c
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/BadlyFormedClassesTest.java
@@ -0,0 +1,71 @@
+package org.junit.tests.validation;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.runners.JUnit4ClassRunner;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+
+@SuppressWarnings("deprecation")
+public class BadlyFormedClassesTest {
+ public static class FaultyConstructor {
+ public FaultyConstructor() throws Exception {
+ throw new Exception("Thrown during construction");
+ }
+
+ @Test
+ public void someTest() {
+ /*
+ * Empty test just to fool JUnit and IDEs into running this class as
+ * a JUnit test
+ */
+ }
+ }
+
+ @RunWith(JUnit4ClassRunner.class)
+ public static class BadBeforeMethodWithLegacyRunner {
+ @Before
+ void before() {
+
+ }
+
+ @Test
+ public void someTest() {
+ }
+ }
+
+ public static class NoTests {
+ // class without tests
+ }
+
+ @Test
+ public void constructorException() {
+ String message = exceptionMessageFrom(FaultyConstructor.class);
+ assertEquals("Thrown during construction", message);
+ }
+
+ @Test
+ public void noRunnableMethods() {
+ assertThat(exceptionMessageFrom(NoTests.class), containsString("No runnable methods"));
+ }
+
+ @Test
+ public void badBeforeMethodWithLegacyRunner() {
+ assertEquals("Method before should be public",
+ exceptionMessageFrom(BadBeforeMethodWithLegacyRunner.class));
+ }
+
+ private String exceptionMessageFrom(Class<?> testClass) {
+ JUnitCore core = new JUnitCore();
+ Result result = core.run(testClass);
+ Failure failure = result.getFailures().get(0);
+ String message = failure.getException().getMessage();
+ return message;
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/FailedConstructionTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/FailedConstructionTest.java
new file mode 100644
index 0000000..a7aa1a5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/FailedConstructionTest.java
@@ -0,0 +1,28 @@
+package org.junit.tests.validation;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+public class FailedConstructionTest {
+ public static class CantConstruct {
+ public CantConstruct() {
+ throw new RuntimeException();
+ }
+
+ @Test
+ public void foo() {
+ }
+ }
+
+ @Test
+ public void failedConstructionIsTestFailure() {
+ Result result = JUnitCore.runClasses(CantConstruct.class);
+ Failure failure = result.getFailures().get(0);
+ Description expected = Description.createTestDescription(CantConstruct.class, "foo");
+ Assert.assertEquals(expected, failure.getDescription());
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/ValidationTest.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/ValidationTest.java
new file mode 100644
index 0000000..7a81b50
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/ValidationTest.java
@@ -0,0 +1,42 @@
+package org.junit.tests.validation;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+
+public class ValidationTest {
+ public static class WrongBeforeClass {
+ @BeforeClass
+ protected int a() {
+ return 0;
+ }
+ }
+
+ @Test
+ public void initializationErrorIsOnCorrectClass() {
+ assertEquals(WrongBeforeClass.class.getName(),
+ Request.aClass(WrongBeforeClass.class).getRunner().getDescription().getDisplayName());
+ }
+
+ public static class NonStaticBeforeClass {
+ @BeforeClass
+ public void before() {
+ }
+
+ @Test
+ public void hereBecauseEveryTestClassNeedsATest() {
+ }
+ }
+
+ @Test
+ public void nonStaticBeforeClass() {
+ Result result = JUnitCore.runClasses(NonStaticBeforeClass.class);
+ assertThat(result.getFailures().get(0).getMessage(), containsString("Method before() should be static"));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Sub.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Sub.java
new file mode 100644
index 0000000..d02a39d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Sub.java
@@ -0,0 +1,5 @@
+package org.junit.tests.validation.anotherpackage;
+
+public class Sub extends Super {
+
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Super.java b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Super.java
new file mode 100644
index 0000000..bfd193b
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/tests/validation/anotherpackage/Super.java
@@ -0,0 +1,9 @@
+package org.junit.tests.validation.anotherpackage;
+
+import org.junit.Test;
+
+class Super {
+ @Test
+ public void a() {
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/validator/AllValidatorTests.java b/google3/third_party/java_src/junit/test/java/org/junit/validator/AllValidatorTests.java
new file mode 100644
index 0000000..f9c1ca9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/validator/AllValidatorTests.java
@@ -0,0 +1,14 @@
+package org.junit.validator;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AnnotationsValidatorTest.class,
+ AnnotationValidatorFactoryTest.class,
+ PublicClassValidatorTest.class
+})
+public class AllValidatorTests {
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationValidatorFactoryTest.java b/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationValidatorFactoryTest.java
new file mode 100644
index 0000000..064d4a3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationValidatorFactoryTest.java
@@ -0,0 +1,47 @@
+package org.junit.validator;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class AnnotationValidatorFactoryTest {
+
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void createAnnotationValidator() {
+ ValidateWith validateWith = SampleAnnotationWithValidator.class.getAnnotation(ValidateWith.class);
+ AnnotationValidator annotationValidator = new AnnotationValidatorFactory().createAnnotationValidator(validateWith);
+ assertThat(annotationValidator, is(instanceOf(Validator.class)));
+ }
+
+ @ValidateWith(value = Validator.class)
+ public @interface SampleAnnotationWithValidator {
+ }
+
+ public static class Validator extends AnnotationValidator {
+ }
+
+ @Test
+ public void exceptionWhenAnnotationValidatorCantBeCreated() {
+ ValidateWith validateWith = SampleAnnotationWithValidatorThatThrowsException.class.getAnnotation(ValidateWith.class);
+ exception.expect(RuntimeException.class);
+ exception.expectMessage("Exception received when creating AnnotationValidator class " +
+ "org.junit.validator.AnnotationValidatorFactoryTest$ValidatorThatThrowsException");
+ new AnnotationValidatorFactory().createAnnotationValidator(validateWith);
+ }
+
+ @ValidateWith(value = ValidatorThatThrowsException.class)
+ public @interface SampleAnnotationWithValidatorThatThrowsException {
+ }
+
+ public static class ValidatorThatThrowsException extends AnnotationValidator {
+ public ValidatorThatThrowsException() throws InstantiationException {
+ throw new InstantiationException("Simulating exception in test");
+ }
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationsValidatorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationsValidatorTest.java
new file mode 100644
index 0000000..0be3cec
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/validator/AnnotationsValidatorTest.java
@@ -0,0 +1,98 @@
+package org.junit.validator;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+public class AnnotationsValidatorTest {
+ public static class ExampleAnnotationValidator extends AnnotationValidator {
+ private static final String ANNOTATED_METHOD_CALLED= "annotated method called";
+
+ private static final String ANNOTATED_FIELD_CALLED= "annotated field called";
+
+ private static final String ANNOTATED_CLASS_CALLED= "annotated class called";
+
+ @Override
+ public List<Exception> validateAnnotatedClass(TestClass testClass) {
+ return asList(new Exception(ANNOTATED_CLASS_CALLED));
+ }
+
+ @Override
+ public List<Exception> validateAnnotatedField(FrameworkField field) {
+ return asList(new Exception(ANNOTATED_FIELD_CALLED));
+ }
+
+ @Override
+ public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
+ return asList(new Exception(ANNOTATED_METHOD_CALLED));
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Inherited
+ @ValidateWith(ExampleAnnotationValidator.class)
+ public @interface ExampleAnnotationWithValidator {
+ }
+
+ public static class AnnotationValidatorMethodTest {
+ @ExampleAnnotationWithValidator
+ @Test
+ public void test() {
+ }
+ }
+
+ public static class AnnotationValidatorFieldTest {
+ @ExampleAnnotationWithValidator
+ private String field;
+
+ @Test
+ public void test() {
+ }
+ }
+
+ @ExampleAnnotationWithValidator
+ public static class AnnotationValidatorClassTest {
+ @Test
+ public void test() {
+ }
+ }
+
+ @Test
+ public void validatorIsCalledForAClass() {
+ assertClassHasFailureMessage(AnnotationValidatorClassTest.class,
+ ExampleAnnotationValidator.ANNOTATED_CLASS_CALLED);
+ }
+
+ @Test
+ public void validatorIsCalledForAMethod() {
+ assertClassHasFailureMessage(AnnotationValidatorMethodTest.class,
+ ExampleAnnotationValidator.ANNOTATED_METHOD_CALLED);
+ }
+
+ @Test
+ public void validatorIsCalledForAField() {
+ assertClassHasFailureMessage(AnnotationValidatorFieldTest.class,
+ ExampleAnnotationValidator.ANNOTATED_FIELD_CALLED);
+ }
+
+ private void assertClassHasFailureMessage(Class<?> klass,
+ String expectedFailure) {
+ AnnotationsValidator validator= new AnnotationsValidator();
+ Collection<Exception> errors= validator
+ .validateTestClass(new TestClass(klass));
+ assertThat(errors.size(), is(1));
+ assertThat(errors.iterator().next().getMessage(),
+ is(expectedFailure));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/java/org/junit/validator/PublicClassValidatorTest.java b/google3/third_party/java_src/junit/test/java/org/junit/validator/PublicClassValidatorTest.java
new file mode 100644
index 0000000..dfecbbc
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/java/org/junit/validator/PublicClassValidatorTest.java
@@ -0,0 +1,41 @@
+package org.junit.validator;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runners.model.TestClass;
+
+public class PublicClassValidatorTest {
+ private final PublicClassValidator validator = new PublicClassValidator();
+
+ public static class PublicClass {
+
+ }
+
+ @Test
+ public void acceptsPublicClass() {
+ TestClass testClass = new TestClass(PublicClass.class);
+ List<Exception> validationErrors = validator
+ .validateTestClass(testClass);
+ assertThat(validationErrors,
+ is(equalTo(Collections.<Exception> emptyList())));
+ }
+
+ static class NonPublicClass {
+
+ }
+
+ @Test
+ public void rejectsNonPublicClass() {
+ TestClass testClass = new TestClass(NonPublicClass.class);
+ List<Exception> validationErrors = validator
+ .validateTestClass(testClass);
+ assertThat("Wrong number of errors.", validationErrors.size(),
+ is(equalTo(1)));
+ }
+}
diff --git a/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12 b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12
new file mode 100644
index 0000000..5eb4ef9
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13 b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13
new file mode 100644
index 0000000..6fa2a06
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunFailureResultCanBeReserialised_v4_12 b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunFailureResultCanBeReserialised_v4_12
new file mode 100644
index 0000000..79d8c01
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunFailureResultCanBeReserialised_v4_12
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_12 b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_12
new file mode 100644
index 0000000..e5163d1
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_12
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13 b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13
new file mode 100644
index 0000000..6c3e1b3
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 b/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13
new file mode 100644
index 0000000..1409545
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13 b/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13
new file mode 100644
index 0000000..199c36d
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_411 b/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_411
new file mode 100644
index 0000000..11fe0c5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_411
Binary files differ
diff --git a/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_412 b/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_412
new file mode 100644
index 0000000..11fe0c5
--- /dev/null
+++ b/google3/third_party/java_src/junit/test/resources/org/junit/internal/arrayComparisonFailure_412
Binary files differ