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