Revision: 290
Author:
kr...@google.com
Date: Mon Apr 15 20:51:56 2013
Log: Add basic JUnit4 support
This adds basic support for JUnit4 test cases. It can do all the basic
assertions and also supports the "RunWith" annotation with the
"Parameterized" and "Suite" runners.
It doesn't properly implement BeforeClass and AfterClass yet. Instead
it runs those once for each test. This can be improved in the future,
but should run correctly until then.
This was written without looking at the JUnit source code so it may
have compatibility bugs.
http://code.google.com/p/vogar/source/detail?r=290
Added:
/trunk/src/org
/trunk/src/org/junit
/trunk/src/org/junit/After.java
/trunk/src/org/junit/AfterClass.java
/trunk/src/org/junit/Assert.java
/trunk/src/org/junit/Before.java
/trunk/src/org/junit/BeforeClass.java
/trunk/src/org/junit/Test.java
/trunk/src/org/junit/runner
/trunk/src/org/junit/runner/RunWith.java
/trunk/src/org/junit/runners
/trunk/src/org/junit/runners/Parameterized.java
/trunk/src/org/junit/runners/Suite.java
/trunk/src/vogar/target/junit/ConfigurationError.java
/trunk/src/vogar/target/junit/Junit3.java
/trunk/src/vogar/target/junit/Junit4.java
/trunk/test/vogar/target/junit4
/trunk/test/vogar/target/junit4/FailTest.java
/trunk/test/vogar/target/junit4/ParameterizedTest.java
/trunk/test/vogar/target/junit4/SimpleTest.java
/trunk/test/vogar/target/junit4/SimpleTest2.java
/trunk/test/vogar/target/junit4/SimpleTest3.java
/trunk/test/vogar/target/junit4/SuiteTest.java
/trunk/test/vogar/target/junit4/WrongSuiteTest.java
Deleted:
/trunk/src/vogar/target/junit/Junit.java
Modified:
/trunk/src/junit/framework/Assert.java
/trunk/src/junit/framework/TestSuite.java
/trunk/src/vogar/target/TestEnvironment.java
/trunk/src/vogar/target/junit/JUnitRunner.java
=======================================
--- /dev/null
+++ /trunk/src/org/junit/After.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the junit code
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface After {
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/AfterClass.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the org.junit code
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AfterClass {
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/Assert.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the junit code
+
+import java.util.Arrays;
+
+public class Assert extends junit.framework.Assert {
+ protected Assert() {
+ }
+
+ public static void assertArrayEquals(byte[] expecteds, byte[] actuals)
{
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, byte[] expecteds,
byte[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+
+ public static void assertArrayEquals(char[] expecteds, char[] actuals)
{
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, char[] expecteds,
char[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+
+ public static void assertArrayEquals(int[] expecteds, int[] actuals) {
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, int[] expecteds,
int[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+
+ public static void assertArrayEquals(long[] expecteds, long[] actuals)
{
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, long[] expecteds,
long[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+
+ public static void assertArrayEquals(Object[] expecteds, Object[]
actuals) {
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, Object[]
expecteds, Object[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+
+ public static void assertArrayEquals(short[] expecteds, short[]
actuals) {
+ assertArrayEquals("", expecteds, actuals);
+ }
+
+ public static void assertArrayEquals(String message, short[]
expecteds, short[] actuals) {
+ String expectedString = Arrays.toString(expecteds);
+ String actualString = Arrays.toString(actuals);
+
+ if (!expectedString.equals(actualString)) {
+ fail(message, "expected " + expectedString + " but was " +
actualString);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/Before.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the org.junit code
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Before {
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/BeforeClass.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the org.junit code
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface BeforeClass {
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/Test.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit;
+
+//Note: this class was written without inspecting the org.junit code
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Test {
+ public static class None extends Throwable {
+ }
+
+ Class<? extends Throwable> expected() default None.class;
+ long timeout() default 0L;
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/runner/RunWith.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit.runner;
+
+//Note: this class was written without inspecting the junit code
+
+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;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface RunWith {
+ Class<?> value();
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/runners/Parameterized.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit.runners;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+//Note: this class was written without inspecting the junit code
+
+public class Parameterized {
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public static @interface Parameters {
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/org/junit/runners/Suite.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.junit.runners;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+//Note: this class was written without inspecting the junit code
+
+public class Suite {
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public static @interface SuiteClasses {
+ Class<?>[] value();
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/vogar/target/junit/ConfigurationError.java Mon Apr 15
20:51:56 2013
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit;
+
+class ConfigurationError implements VogarTest {
+ private final String name;
+ private final Throwable cause;
+
+ ConfigurationError(String name, Throwable cause) {
+
this.name = name;
+ this.cause = cause;
+ }
+
+ @Override
+ public void run() throws Throwable {
+ throw cause;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/vogar/target/junit/Junit3.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit;
+
+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.Collections;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import vogar.ClassAnalyzer;
+
+/**
+ * Utilities for manipulating JUnit tests.
+ */
+public final class Junit3 {
+ private Junit3() {}
+
+ private static final Method setUp;
+ private static final Method tearDown;
+ private static final Method runTest;
+ static {
+ try {
+ setUp = TestCase.class.getDeclaredMethod("setUp");
+ setUp.setAccessible(true);
+ tearDown = TestCase.class.getDeclaredMethod("tearDown");
+ tearDown.setAccessible(true);
+ runTest = TestCase.class.getDeclaredMethod("runTest");
+ runTest.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Creates eager JUnit Test instances from the given test case or test
+ * suite.
+ */
+ public static List<Test> classToJunitTests(Class<?> testClass) {
+ try {
+ try {
+ Method suiteMethod = testClass.getMethod("suite");
+ return Collections.singletonList((Test)
suiteMethod.invoke(null));
+ } catch (NoSuchMethodException ignored) {
+ }
+
+ if (TestCase.class.isAssignableFrom(testClass)) {
+ List<Test> result = new ArrayList<Test>();
+ for (Method m : testClass.getMethods()) {
+ if (!m.getName().startsWith("test")) {
+ continue;
+ }
+ if (m.getParameterTypes().length == 0) {
+ TestCase testCase = (TestCase)
testClass.newInstance();
+ testCase.setMethod(m);
+ result.add(testCase);
+ } else {
+ // TODO: warn
+ }
+ }
+ return result;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ throw new IllegalArgumentException("Unknown test class: " +
testClass);
+ }
+
+ /**
+ * Creates lazy vogar test instances from the given test case or test
+ * suite.
+ *
+ * @param args if non-empty, this is the list of test method names.
+ */
+ public static List<VogarTest> classToVogarTests(Class<?> testClass,
String... args) {
+ List<VogarTest> result = new ArrayList<VogarTest>();
+ getSuiteMethods(result, testClass, args);
+ return result;
+ }
+
+ public static boolean isJunit3Test(Class<?> klass) {
+ // public class FooTest extends TestCase {...}
+ // or
+ // public class FooSuite {
+ // public static Test suite() {...}
+ // }
+ return (TestCase.class.isAssignableFrom(klass)
&& !Modifier.isAbstract(klass.getModifiers()))
+ || new ClassAnalyzer(klass).hasMethod(true,
Test.class, "suite");
+ }
+
+ private static void getSuiteMethods(List<VogarTest> out, Class<?>
testClass, String... args) {
+ /*
+ * Handle classes assignable to TestCase
+ */
+ if (TestCase.class.isAssignableFrom(testClass)) {
+ @SuppressWarnings("unchecked")
+ Class<? extends TestCase> testCaseClass = (Class<? extends
TestCase>) testClass;
+
+ if (args.length == 0) {
+ for (Method m : testClass.getMethods()) {
+ if (!m.getName().startsWith("test")) {
+ continue;
+ }
+ if (m.getParameterTypes().length == 0) {
+ out.add(TestMethod.create(testCaseClass, m));
+ } else {
+ out.add(new ConfigurationError(testClass.getName()
+ "#" + m.getName(),
+ new IllegalStateException("Tests may not
have parameters!")));
+ }
+ }
+ } else {
+ for (String arg : args) {
+ try {
+ out.add(TestMethod.create(testCaseClass,
testClass.getMethod(arg)));
+ } catch (final NoSuchMethodException e) {
+ out.add(new ConfigurationError(testClass.getName()
+ "#" + arg, e));
+ }
+ }
+ }
+
+ return;
+ }
+
+ /*
+ * Handle classes that define suite()
+ */
+ try {
+ Method suiteMethod = testClass.getMethod("suite");
+ junit.framework.Test test;
+ try {
+ test = (junit.framework.Test) suiteMethod.invoke(null);
+ } catch (Throwable e) {
+ out.add(new ConfigurationError(testClass.getName()
+ "#suite", e));
+ return;
+ }
+
+ if (test instanceof TestCase) {
+ out.add(createForTestCase((TestCase) test));
+ } else if (test instanceof TestSuite) {
+ getTestSuiteTests(out, (TestSuite) test);
+ } else {
+ out.add(new ConfigurationError(testClass.getName()
+ "#suite",
+ new IllegalStateException("Unknown suite()
result: " + test)));
+ }
+ return;
+ } catch (NoSuchMethodException ignored) {
+ }
+
+ out.add(new ConfigurationError(testClass.getName() + "#suite",
+ new IllegalStateException("Not a test case: " +
testClass)));
+ }
+
+ private static void getTestSuiteTests(List<VogarTest> out, TestSuite
suite) {
+ for (Object testsOrSuite : suite.getTestsAndSuites()) {
+ if (testsOrSuite instanceof Class) {
+ getSuiteMethods(out, (Class<?>) testsOrSuite);
+ } else if (testsOrSuite instanceof TestCase) {
+ out.add(createForTestCase((TestCase) testsOrSuite));
+ } else if (testsOrSuite instanceof TestSuite) {
+ getTestSuiteTests(out, (TestSuite) testsOrSuite);
+ } else if (testsOrSuite != null) {
+ out.add(new
ConfigurationError(testsOrSuite.getClass().getName() + "#getClass",
+ new IllegalStateException("Unknown test: " +
testsOrSuite)));
+ }
+ }
+ }
+
+ private static VogarTest createForTestCase(TestCase testCase) {
+ return new TestCaseInstance(testCase, testCase.getMethod());
+ }
+
+ private static class ConfigurationError implements VogarTest {
+ private final String name;
+ private final Throwable cause;
+
+ private ConfigurationError(String name, Throwable cause) {
+
this.name = name;
+ this.cause = cause;
+ }
+
+ @Override public void run() throws Throwable {
+ throw cause;
+ }
+
+ @Override public String toString() {
+ return name;
+ }
+ }
+
+ private abstract static class VogarJUnitTest implements VogarTest {
+ protected final Class<? extends TestCase> testClass;
+ protected final Method method;
+
+ protected VogarJUnitTest(Class<? extends TestCase> testClass,
Method method) {
+ this.testClass = testClass;
+ this.method = method;
+ }
+
+ public void run() throws Throwable {
+ TestCase testCase = getTestCase();
+ Throwable failure = null;
+ try {
+ setUp.invoke(testCase);
+ method.invoke(testCase);
+ } catch (InvocationTargetException t) {
+ failure = t.getCause();
+ } catch (Throwable t) {
+ failure = t;
+ }
+
+ try {
+ tearDown.invoke(testCase);
+ } catch (InvocationTargetException t) {
+ if (failure == null) {
+ failure = t.getCause();
+ }
+ } catch (Throwable t) {
+ if (failure == null) {
+ failure = t;
+ }
+ }
+
+ if (failure != null) {
+ throw failure;
+ }
+ }
+
+ protected abstract TestCase getTestCase() throws Exception;
+ }
+
+ /**
+ * A JUnit TestCase constructed on demand and then released.
+ */
+ private static class TestMethod extends VogarJUnitTest {
+ private final Constructor<? extends TestCase> constructor;
+ private final Object[] constructorArgs;
+
+ private TestMethod(Class<? extends TestCase> testClass, Method
method,
+ Constructor<? extends TestCase> constructor, Object[]
constructorArgs) {
+ super(testClass, method);
+ this.constructor = constructor;
+ this.constructorArgs = constructorArgs;
+ }
+
+ public static VogarTest create(Class<? extends TestCase>
testClass, Method method) {
+ try {
+ return new TestMethod(testClass, method,
testClass.getConstructor(), new Object[0]);
+ } catch (NoSuchMethodException ignored) {
+ }
+ try {
+ return new TestMethod(testClass, method,
testClass.getConstructor(String.class),
+ new Object[] { method.getName() });
+ } catch (NoSuchMethodException ignored) {
+ }
+ return new ConfigurationError(testClass.getName() + "#" +
method.getName(),
+ new Exception("Test cases must have a no-arg or string
constructor."));
+ }
+
+ @Override protected TestCase getTestCase() throws Exception {
+ return constructor.newInstance(constructorArgs);
+ }
+
+ @Override public String toString() {
+ return testClass.getName() + "#" + method.getName();
+ }
+ }
+
+ /**
+ * A JUnit TestCase already constructed.
+ */
+ private static class TestCaseInstance extends VogarJUnitTest {
+ private final TestCase testCase;
+
+ private TestCaseInstance(TestCase testCase, Method method) {
+ super(testCase.getClass(), method);
+ this.testCase = testCase;
+ }
+
+ @Override protected TestCase getTestCase() throws Exception {
+ return testCase;
+ }
+
+ @Override public String toString() {
+ return testCase.getClass().getName() + "#" +
testCase.getName();
+ }
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/vogar/target/junit/Junit4.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import junit.framework.AssertionFailedError;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Utilities for manipulating JUnit4 tests.
+ */
+public final class Junit4 {
+ private Junit4() {}
+
+ /**
+ * Creates lazy vogar test instances from the given test case or test
+ * suite.
+ *
+ * @param args if non-empty, this is the list of test method names.
+ */
+ public static List<VogarTest> classToVogarTests(Class<?> testClass,
String... args) {
+ List<VogarTest> result = new ArrayList<VogarTest>();
+ getSuiteMethods(result, testClass, args);
+ return result;
+ }
+
+ private static void getSuiteMethods(List<VogarTest> out, Class<?>
testClass, String... args) {
+ boolean isJunit4TestClass = false;
+
+ Collection<Object[]> argCollection = findParameters(testClass);
+
+ /* JUnit 4.x: methods marked with @Test annotation. */
+ if (args.length == 0) {
+ for (Method m : testClass.getMethods()) {
+ boolean isTest = false;
+ for (Annotation a : m.getAnnotations()) {
+ if
(org.junit.Test.class.isAssignableFrom(a.annotationType())) {
+ isTest = true;
+ }
+ }
+ if (!isTest) {
+ continue;
+ }
+
+ isJunit4TestClass = true;
+
+ if (m.getParameterTypes().length == 0) {
+ addAllParameterizedTests(out, testClass, m,
argCollection);
+ } else {
+ out.add(new ConfigurationError(testClass.getName()
+ "#" + m.getName(),
+ new IllegalStateException("Tests may not have
parameters!")));
+ }
+ }
+ } else {
+ for (String arg : args) {
+ try {
+ addAllParameterizedTests(out, testClass,
testClass.getMethod(arg),
+ argCollection);
+ } catch (final NoSuchMethodException e) {
+ out.add(new ConfigurationError(testClass.getName()
+ "#" + arg, e));
+ }
+ }
+ }
+
+ isJunit4TestClass |= getSuiteTests(out, testClass);
+
+ if (!isJunit4TestClass) {
+ out.add(new ConfigurationError(testClass.getName(),
+ new IllegalStateException("Not a test case: " +
testClass)));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Collection<Object[]> findParameters(Class<?> testClass)
{
+ for (Method m : testClass.getMethods()) {
+ for (Annotation a : m.getAnnotations()) {
+ if (Parameters.class.isAssignableFrom(a.annotationType()))
{
+ try {
+ return (Collection<Object[]>) m.invoke(testClass);
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static void addAllParameterizedTests(List<VogarTest> out,
Class<?> testClass, Method m,
+ Collection<Object[]> argCollection) {
+ if (argCollection == null) {
+ out.add(TestMethod.create(testClass, m, null));
+ } else {
+ for (Object[] args : argCollection) {
+ out.add(TestMethod.create(testClass, m, args));
+ }
+ }
+ }
+
+ public static boolean isJunit4Test(Class<?> klass) {
+ boolean isTestSuite = false;
+ boolean hasSuiteClasses = false;
+
+ // @RunWith(Suite.class)
+ // @SuiteClasses( ... )
+ // public class MyTest { ... }
+ // or
+ // @RunWith(Parameterized.class)
+ // public class MyTest { ... }
+ for (Annotation a : klass.getAnnotations()) {
+ Class<?> annotationClass = a.annotationType();
+
+ if (Parameterized.class.isAssignableFrom(annotationClass)) {
+ return true;
+ } else if (RunWith.class.isAssignableFrom(annotationClass)
+ && Suite.class.isAssignableFrom(((RunWith)
a).value())) {
+ isTestSuite = true;
+ } else if
(Suite.SuiteClasses.class.isAssignableFrom(annotationClass)) {
+ hasSuiteClasses = true;
+ }
+
+ if (isTestSuite && hasSuiteClasses) {
+ return true;
+ }
+ }
+
+ // public class MyTest {
+ // @Test
+ // public void example() { ... }
+ // }
+ for (Method m : klass.getDeclaredMethods()) {
+ for (Annotation a : m.getAnnotations()) {
+ if
(org.junit.Test.class.isAssignableFrom(a.annotationType())) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean getSuiteTests(List<VogarTest> out, Class<?>
suite) {
+ boolean isSuite = false;
+
+ /* Check for @RunWith(Suite.class) */
+ for (Annotation a : suite.getAnnotations()) {
+ if (RunWith.class.isAssignableFrom(a.annotationType())) {
+ if (Suite.class.isAssignableFrom(((RunWith) a).value())) {
+ isSuite = true;
+ }
+ break;
+ }
+ }
+
+ if (!isSuite) {
+ return false;
+ }
+
+ /* Extract classes to run */
+ for (Annotation a : suite.getAnnotations()) {
+ if (SuiteClasses.class.isAssignableFrom(a.annotationType())) {
+ for (Class<?> clazz : ((SuiteClasses) a).value()) {
+ getSuiteMethods(out, clazz);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private abstract static class VogarJUnitTest implements VogarTest {
+ protected final Class<?> testClass;
+ protected final Method method;
+
+ protected VogarJUnitTest(Class<?> testClass, Method method) {
+ this.testClass = testClass;
+ this.method = method;
+ }
+
+ public void run() throws Throwable {
+ Object testCase = getTestCase();
+ Throwable failure = null;
+
+ // TODO: add @Ignore support
+
+ try {
+ Class.forName("org.mockito.MockitoAnnotations")
+ .getMethod("initMocks", Object.class)
+ .invoke(null, testCase);
+ } catch (Exception ignored) {
+ }
+
+ try {
+ invokeMethodWithAnnotation(testCase, BeforeClass.class);
+ invokeMethodWithAnnotation(testCase, Before.class);
+ method.invoke(testCase);
+ } catch (InvocationTargetException t) {
+ failure = t.getCause();
+ } catch (Throwable t) {
+ failure = t;
+ }
+
+ try {
+ invokeMethodWithAnnotation(testCase, After.class);
+ } catch (InvocationTargetException t) {
+ if (failure == null) {
+ failure = t.getCause();
+ }
+ } catch (Throwable t) {
+ if (failure == null) {
+ failure = t;
+ }
+ }
+
+ try {
+ invokeMethodWithAnnotation(testCase, AfterClass.class);
+ } catch (InvocationTargetException t) {
+ if (failure == null) {
+ failure = t.getCause();
+ }
+ } catch (Throwable t) {
+ if (failure == null) {
+ failure = t;
+ }
+ }
+
+ if (!meetsExpectations(failure, method)) {
+ if (failure == null) {
+ throw new AssertionFailedError("Expected exception not
thrown");
+ } else {
+ throw failure;
+ }
+ }
+ }
+
+ private void invokeMethodWithAnnotation(Object testCase, Class<?>
annotation)
+ throws IllegalAccessException, InvocationTargetException {
+ for (Method m : testCase.getClass().getDeclaredMethods()) {
+ for (Annotation a : m.getAnnotations()) {
+ if (annotation.isAssignableFrom(a.annotationType())) {
+ m.invoke(testCase);
+ }
+ }
+ }
+ }
+
+ protected boolean meetsExpectations(Throwable failure, Method
method) {
+ Class<?> expected = null;
+ for (Annotation a : method.getAnnotations()) {
+ if
(org.junit.Test.class.isAssignableFrom(a.annotationType())) {
+ expected = ((org.junit.Test) a).expected();
+ }
+ }
+ return expected == null ||
org.junit.Test.None.class.isAssignableFrom(expected)
+ ? (failure == null)
+ : (failure != null &&
expected.isAssignableFrom(failure.getClass()));
+ }
+
+ protected abstract Object getTestCase() throws Exception;
+ }
+
+ /**
+ * A JUnit TestCase constructed on demand and then released.
+ */
+ private static class TestMethod extends VogarJUnitTest {
+ private final Constructor<?> constructor;
+ private final Object[] constructorArgs;
+
+ private TestMethod(Class<?> testClass, Method method,
+ Constructor<?> constructor, Object[] constructorArgs) {
+ super(testClass, method);
+ this.constructor = constructor;
+ this.constructorArgs = constructorArgs;
+ }
+
+ public static VogarTest create(Class<?> testClass, Method method,
+ Object[] constructorArgs) {
+ if (constructorArgs != null) {
+ for (Constructor<?> c : testClass.getConstructors()) {
+ if (c.getParameterTypes().length ==
constructorArgs.length) {
+ return new TestMethod(testClass, method, c,
constructorArgs);
+ }
+ }
+
+ return new ConfigurationError(testClass.getName() + "#" +
method.getName(),
+ new Exception("Parameterized test cases must have "
+ + constructorArgs.length + " arg
constructor"));
+ }
+
+ try {
+ return new TestMethod(testClass, method,
testClass.getConstructor(), null);
+ } catch (NoSuchMethodException ignored) {
+ }
+ try {
+ return new TestMethod(testClass, method,
+ testClass.getConstructor(String.class), new
Object[] { method.getName() });
+ } catch (NoSuchMethodException ignored) {
+ }
+
+ return new ConfigurationError(testClass.getName() + "#" +
method.getName(),
+ new Exception("Test cases must have a no-arg or string
constructor."));
+ }
+
+ @Override protected Object getTestCase() throws Exception {
+ return constructor.newInstance(constructorArgs);
+ }
+
+ @Override public String toString() {
+ return testClass.getName() + "#" + method.getName();
+ }
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/FailTest.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class FailTest {
+ @Test
+ public void success() {
+ }
+
+ @Test
+ public void failure() {
+ fail("failed.");
+ }
+
+ @Test
+ public void throwException() {
+ throw new RuntimeException("exceptrion");
+ }
+
+ @Test(expected = AwesomeException.class)
+ public void throwExpectedException() throws Exception {
+ throw new AwesomeException();
+ }
+
+ @Test(expected = AwesomeException.class)
+ public void throwAnotherExpectedException() throws Exception {
+ throw new EvenMoreAwesomeException();
+ }
+
+ private static class AwesomeException extends Exception {
+ }
+
+ private static class EvenMoreAwesomeException extends AwesomeException
{
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/ParameterizedTest.java Mon Apr 15
20:51:56 2013
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+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 ParameterizedTest {
+ private final int field1;
+ private final int field2;
+
+ public ParameterizedTest(int field1, int field2) {
+ this.field1 = field1;
+ this.field2 = field2;
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ Object[][] data = new Object[][] { { 5, 10 } };
+ return Arrays.asList(data);
+ }
+
+ @Test
+ public void params() {
+ assertEquals(5, field1);
+ assertEquals(10, field2);
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/SimpleTest.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({SimpleTest3.class})
+public class SimpleTest {
+ @Test
+ public void simple() {
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/SimpleTest2.java Mon Apr 15 20:51:56
2013
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.Test;
+
+public class SimpleTest2 {
+ @Test
+ public void simple1() {
+ }
+
+ @Test
+ public void simple2() {
+ }
+
+ @Test
+ public void Simple3() {
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/SimpleTest3.java Mon Apr 15 20:51:56
2013
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.Test;
+
+public class SimpleTest3 {
+ @Test
+ public void simple() {
+ }
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/SuiteTest.java Mon Apr 15 20:51:56 2013
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({SimpleTest.class, SimpleTest2.class})
+public class SuiteTest {
+}
=======================================
--- /dev/null
+++ /trunk/test/vogar/target/junit4/WrongSuiteTest.java Mon Apr 15 20:51:56
2013
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target.junit4;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+public class WrongSuiteTest {
+}
=======================================
--- /trunk/src/vogar/target/junit/Junit.java Wed Mar 30 18:10:10 2011
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *
http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package vogar.target.junit;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Utilities for manipulating JUnit tests.
- */
-public final class Junit {
- private Junit() {}
-
- private static final Method setUp;
- private static final Method tearDown;
- private static final Method runTest;
- static {
- try {
- setUp = TestCase.class.getDeclaredMethod("setUp");
- setUp.setAccessible(true);
- tearDown = TestCase.class.getDeclaredMethod("tearDown");
- tearDown.setAccessible(true);
- runTest = TestCase.class.getDeclaredMethod("runTest");
- runTest.setAccessible(true);
- } catch (NoSuchMethodException e) {
- throw new AssertionError();
- }
- }
-
- /**
- * Creates eager JUnit Test instances from the given test case or test
- * suite.
- */
- public static List<Test> classToJunitTests(Class<?> testClass) {
- try {
- try {
- Method suiteMethod = testClass.getMethod("suite");
- return Collections.singletonList((Test)
suiteMethod.invoke(null));
- } catch (NoSuchMethodException ignored) {
- }
-
- if (TestCase.class.isAssignableFrom(testClass)) {
- List<Test> result = new ArrayList<Test>();
- for (Method m : testClass.getMethods()) {
- if (!m.getName().startsWith("test")) {
- continue;
- }
- if (m.getParameterTypes().length == 0) {
- TestCase testCase = (TestCase)
testClass.newInstance();
- testCase.setMethod(m);
- result.add(testCase);
- } else {
- // TODO: warn
- }
- }
- return result;
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- throw new IllegalArgumentException("Unknown test class: " +
testClass);
- }
-
- /**
- * Creates lazy vogar test instances from the given test case or test
- * suite.
- *
- * @param args if non-empty, this is the list of test method names.
- */
- public static List<VogarTest> classToVogarTests(Class<?> testClass,
String... args) {
- List<VogarTest> result = new ArrayList<VogarTest>();
- getSuiteMethods(result, testClass, args);
- return result;
- }
-
- private static void getSuiteMethods(List<VogarTest> out, Class<?>
testClass, String... args) {
- /*
- * Handle classes assignable to TestCase
- */
- if (TestCase.class.isAssignableFrom(testClass)) {
- @SuppressWarnings("unchecked")
- Class<? extends TestCase> testCaseClass = (Class<? extends
TestCase>) testClass;
-
- if (args.length == 0) {
- for (Method m : testClass.getMethods()) {
- if (!m.getName().startsWith("test")) {
- continue;
- }
- if (m.getParameterTypes().length == 0) {
- out.add(TestMethod.create(testCaseClass, m));
- } else {
- out.add(new ConfigurationError(testClass.getName()
+ "#" + m.getName(),
- new IllegalStateException("Tests may not
have parameters!")));
- }
- }
- } else {
- for (String arg : args) {
- try {
- out.add(TestMethod.create(testCaseClass,
testClass.getMethod(arg)));
- } catch (final NoSuchMethodException e) {
- out.add(new ConfigurationError(testClass.getName()
+ "#" + arg, e));
- }
- }
- }
-
- return;
- }
-
- /*
- * Handle classes that define suite()
- */
- try {
- Method suiteMethod = testClass.getMethod("suite");
- junit.framework.Test test;
- try {
- test = (junit.framework.Test) suiteMethod.invoke(null);
- } catch (Throwable e) {
- out.add(new ConfigurationError(testClass.getName()
+ "#suite", e));
- return;
- }
-
- if (test instanceof TestCase) {
- out.add(createForTestCase((TestCase) test));
- } else if (test instanceof TestSuite) {
- getTestSuiteTests(out, (TestSuite) test);
- } else {
- out.add(new ConfigurationError(testClass.getName()
+ "#suite",
- new IllegalStateException("Unknown suite()
result: " + test)));
- }
- return;
- } catch (NoSuchMethodException ignored) {
- }
-
- out.add(new ConfigurationError(testClass.getName() + "#suite",
- new IllegalStateException("Not a test case: " +
testClass)));
- }
-
- private static void getTestSuiteTests(List<VogarTest> out, TestSuite
suite) {
- for (Object testsOrSuite : suite.getTestsAndSuites()) {
- if (testsOrSuite instanceof Class) {
- getSuiteMethods(out, (Class<?>) testsOrSuite);
- } else if (testsOrSuite instanceof TestCase) {
- out.add(createForTestCase((TestCase) testsOrSuite));
- } else if (testsOrSuite instanceof TestSuite) {
- getTestSuiteTests(out, (TestSuite) testsOrSuite);
- } else if (testsOrSuite != null) {
- out.add(new
ConfigurationError(testsOrSuite.getClass().getName() + "#getClass",
- new IllegalStateException("Unknown test: " +
testsOrSuite)));
- }
- }
- }
-
- private static VogarTest createForTestCase(TestCase testCase) {
- return new TestCaseInstance(testCase, testCase.getMethod());
- }
-
- private static class ConfigurationError implements VogarTest {
- private final String name;
- private final Throwable cause;
-
- private ConfigurationError(String name, Throwable cause) {
-
this.name = name;
- this.cause = cause;
- }
-
- @Override public void run() throws Throwable {
- throw cause;
- }
-
- @Override public String toString() {
- return name;
- }
- }
-
- private abstract static class VogarJUnitTest implements VogarTest {
- protected final Class<? extends TestCase> testClass;
- protected final Method method;
-
- protected VogarJUnitTest(Class<? extends TestCase> testClass,
Method method) {
- this.testClass = testClass;
- this.method = method;
- }
-
- public void run() throws Throwable {
- TestCase testCase = getTestCase();
- Throwable failure = null;
- try {
- setUp.invoke(testCase);
- method.invoke(testCase);
- } catch (InvocationTargetException t) {
- failure = t.getCause();
- } catch (Throwable t) {
- failure = t;
- }
-
- try {
- tearDown.invoke(testCase);
- } catch (InvocationTargetException t) {
- if (failure == null) {
- failure = t.getCause();
- }
- } catch (Throwable t) {
- if (failure == null) {
- failure = t;
- }
- }
-
- if (failure != null) {
- throw failure;
- }
- }
-
- protected abstract TestCase getTestCase() throws Exception;
- }
-
- /**
- * A JUnit TestCase constructed on demand and then released.
- */
- private static class TestMethod extends VogarJUnitTest {
- private final Constructor<? extends TestCase> constructor;
- private final Object[] constructorArgs;
-
- private TestMethod(Class<? extends TestCase> testClass, Method
method,
- Constructor<? extends TestCase> constructor, Object[]
constructorArgs) {
- super(testClass, method);
- this.constructor = constructor;
- this.constructorArgs = constructorArgs;
- }
-
- public static VogarTest create(Class<? extends TestCase>
testClass, Method method) {
- try {
- return new TestMethod(testClass, method,
testClass.getConstructor(), new Object[0]);
- } catch (NoSuchMethodException ignored) {
- }
- try {
- return new TestMethod(testClass, method,
testClass.getConstructor(String.class),
- new Object[] { method.getName() });
- } catch (NoSuchMethodException ignored) {
- }
- return new ConfigurationError(testClass.getName() + "#" +
method.getName(),
- new Exception("Test cases must have a no-arg or string
constructor."));
- }
-
- @Override protected TestCase getTestCase() throws Exception {
- return constructor.newInstance(constructorArgs);
- }
-
- @Override public String toString() {
- return testClass.getName() + "#" + method.getName();
- }
- }
-
- /**
- * A JUnit TestCase already constructed.
- */
- private static class TestCaseInstance extends VogarJUnitTest {
- private final TestCase testCase;
-
- private TestCaseInstance(TestCase testCase, Method method) {
- super(testCase.getClass(), method);
- this.testCase = testCase;
- }
-
- @Override protected TestCase getTestCase() throws Exception {
- return testCase;
- }
-
- @Override public String toString() {
- return testCase.getClass().getName() + "#" +
testCase.getName();
- }
- }
-}
=======================================
--- /trunk/src/junit/framework/Assert.java Mon Mar 7 14:32:15 2011
+++ /trunk/src/junit/framework/Assert.java Mon Apr 15 20:51:56 2013
@@ -205,7 +205,7 @@
throw new AssertionFailedError();
}
- private static void fail(String message, String detail) {
+ protected static void fail(String message, String detail) {
if (message == null || message.isEmpty()) {
throw new AssertionFailedError(detail);
} else {
=======================================
--- /trunk/src/junit/framework/TestSuite.java Mon Mar 7 14:32:15 2011
+++ /trunk/src/junit/framework/TestSuite.java Mon Apr 15 20:51:56 2013
@@ -23,7 +23,7 @@
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;
-import vogar.target.junit.Junit;
+import vogar.target.junit.Junit3;
public class TestSuite implements Test {
/** A heterogeneous list containing of tests and test classes. */
@@ -81,7 +81,7 @@
Object o = i.next();
if (o instanceof Class) {
i.remove();
- for (Test test : Junit.classToJunitTests((Class<?>) o)) {
+ for (Test test : Junit3.classToJunitTests((Class<?>) o)) {
i.add(test);
}
}
=======================================
--- /trunk/src/vogar/target/TestEnvironment.java Tue Dec 6 16:25:31 2011
+++ /trunk/src/vogar/target/TestEnvironment.java Mon Apr 15 20:51:56 2013
@@ -59,6 +59,14 @@
// Reset system properties.
System.setProperties(null);
+
+ System.setProperty("java.runtime.version", "x");
+ System.setProperty("
java.vm.info", "x");
+ System.setProperty("java.vm.version", "x");
+ System.setProperty("java.vm.vendor", "x");
+ System.setProperty("
java.vm.name", "x");
+
+
// Require writable java.home and user.dir directories for
preferences
String tmpDir = System.getProperty("java.io.tmpdir");
if ("Dalvik".equals(System.getProperty("
java.vm.name"))) {
@@ -84,7 +92,7 @@
boolean usedParentHandlers = loggerToMute.getUseParentHandlers();
loggerToMute.setUseParentHandlers(false);
try {
- resetPreferences(Preferences.systemRoot());
+ // resetPreferences(Preferences.systemRoot());
resetPreferences(Preferences.userRoot());
} finally {
loggerToMute.setUseParentHandlers(usedParentHandlers);
=======================================
--- /trunk/src/vogar/target/junit/JUnitRunner.java Thu Apr 7 12:16:11 2011
+++ /trunk/src/vogar/target/junit/JUnitRunner.java Mon Apr 15 20:51:56 2013
@@ -16,7 +16,6 @@
package vogar.target.junit;
-import java.lang.reflect.Modifier;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@@ -25,9 +24,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import vogar.ClassAnalyzer;
+
+import junit.framework.AssertionFailedError;
import vogar.Result;
import vogar.monitor.TargetMonitor;
import vogar.target.Profiler;
@@ -65,9 +63,18 @@
}
public boolean run(String actionName, Profiler profiler, String[]
args) {
- List<VogarTest> tests = qualification != null
- ? Junit.classToVogarTests(testClass, qualification)
- : Junit.classToVogarTests(testClass, args);
+ final List<VogarTest> tests;
+ if (Junit3.isJunit3Test(testClass)) {
+ tests = qualification != null
+ ? Junit3.classToVogarTests(testClass, qualification)
+ : Junit3.classToVogarTests(testClass, args);
+ } else if (Junit4.isJunit4Test(testClass)) {
+ tests = qualification != null
+ ? Junit4.classToVogarTests(testClass, qualification)
+ : Junit4.classToVogarTests(testClass, args);
+ } else {
+ throw new AssertionFailedError("Unknown JUnit type: " +
testClass.getName());
+ }
for (VogarTest test : tests) {
String skipPast = skipPastReference.get();
@@ -207,16 +214,6 @@
}
public boolean supports(Class<?> klass) {
- return isJunit3Test(klass);
- }
-
- static boolean isJunit3Test(Class<?> klass) {
- // public class FooTest extends TestCase {...}
- // or
- // public class FooSuite {
- // public static Test suite() {...}
- // }
- return (TestCase.class.isAssignableFrom(klass)
&& !Modifier.isAbstract(klass.getModifiers()))
- || new ClassAnalyzer(klass).hasMethod(true,
Test.class, "suite");
+ return Junit3.isJunit3Test(klass) || Junit4.isJunit4Test(klass);
}
}