Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more return types for the @Parameters method. Fixes #700. #702

Merged
merged 1 commit into from
Jul 16, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 48 additions & 5 deletions src/main/java/org/junit/runners/Parameterized.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -98,6 +99,37 @@
* and fields annotated by <code>&#064;Parameter</code> will be initialized
* with the data values in the <code>&#064;Parameters</code> method.
*
* <p>
* The parameters can be provided as an array, too:
*
* <pre>
* &#064;Parameters
* public static Object[][] data() {
* return new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 },
* { 5, 5 }, { 6, 8 } };
* }
* </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>
* &#064;Parameters
* public static Iterable&lt;? extends Object&gt; data() {
* return Arrays.asList(&quot;first test&quot;, &quot;second test&quot;);
* }
* </pre>
* <p>
* or
* <pre>
* &#064;Parameters
* public static Object[] data() {
* return new Object[] { &quot;first test&quot;, &quot;second test&quot; };
* }
* </pre>
*
* @since 4.0
*/
public class Parameterized extends Suite {
Expand Down Expand Up @@ -281,15 +313,25 @@ protected List<Runner> getChildren() {
return fRunners;
}

private Runner createRunnerWithNotNormalizedParameters(String pattern,
int index, Object parametersOrSingleParameter)
throws InitializationError {
Object[] parameters= (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter
: new Object[] { parametersOrSingleParameter };
return createRunner(pattern, index, parameters);
}

protected Runner createRunner(String pattern, int index, Object[] parameters) throws InitializationError {
return new TestClassRunnerForParameters(getTestClass().getJavaClass(), pattern, index, parameters);
}

@SuppressWarnings("unchecked")
private Iterable<Object[]> allParameters() throws Throwable {
private Iterable<Object> allParameters() throws Throwable {
Object parameters = getParametersMethod().invokeExplosively(null);
if (parameters instanceof Iterable) {
return (Iterable<Object[]>) parameters;
return (Iterable<Object>) parameters;
} else if (parameters instanceof Object[]) {
return Arrays.asList((Object[]) parameters);
} else {
throw parametersMethodReturnedWrongType();
}
Expand All @@ -308,12 +350,13 @@ private FrameworkMethod getParametersMethod() throws Exception {
+ getTestClass().getName());
}

private List<Runner> createRunnersForParameters(Iterable<Object[]> allParameters, String namePattern) throws Exception {
private List<Runner> createRunnersForParameters(Iterable<Object> allParameters, String namePattern) throws Exception {
try {
int i = 0;
List<Runner> children = new ArrayList<Runner>();
for (Object[] parametersOfSingleTest : allParameters) {
children.add(createRunner(namePattern, i++, parametersOfSingleTest));
for (Object parametersOfSingleTest : allParameters) {
children.add(createRunnerWithNotNormalizedParameters(
namePattern, i++, parametersOfSingleTest));
}
return children;
} catch (ClassCastException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.junit.tests.running.classes;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
Expand Down Expand Up @@ -314,25 +315,6 @@ public void meaningfulFailureWhenParametersNotPublic() throws Exception {
assertEquals(expected, result.getFailures().get(0).getMessage());
}

@RunWith(Parameterized.class)
static public class WrongElementType {
@Parameters
public static Iterable<String> data() {
return Arrays.asList("a", "b", "c");
}

@Test
public void aTest() {
}
}

@Test
public void meaningfulFailureWhenParametersAreNotArrays() {
assertThat(
testResult(WrongElementType.class).toString(),
containsString("WrongElementType.data() must return an Iterable of arrays."));
}

@RunWith(Parameterized.class)
static public class ParametersNotIterable {
@Parameters
Expand Down Expand Up @@ -372,4 +354,80 @@ public void aTest() {
public void exceptionWhenPrivateConstructor() throws Throwable {
new Parameterized(PrivateConstructor.class);
}

@RunWith(Parameterized.class)
static public class FibonacciTestWithArray {
@Parameters(name= "{index}: fib({0})={1}")
public static Object[][] data() {
return new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } };
}

private final int fInput;

private final int fExpected;

public FibonacciTestWithArray(int input, int expected) {
fInput= input;
fExpected= expected;
}

@Test
public void test() {
assertEquals(fExpected, fib(fInput));
}

private int fib(int x) {
return 0;
}
}

@Test
public void runsEveryTestOfArray() {
Result result= JUnitCore.runClasses(FibonacciTestWithArray.class);
assertEquals(7, result.getRunCount());
}

@RunWith(Parameterized.class)
static public 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)
static public class SingleArgumentTestWithIterable {
@Parameters
public static Iterable<? extends Object> data() {
return asList("first test", "second test");
}

public SingleArgumentTestWithIterable(Object argument) {
}

@Test
public void aTest() {
}
}

@Test
public void runsForEverySingleArgumentOfIterable() {
Result result= JUnitCore
.runClasses(SingleArgumentTestWithIterable.class);
assertEquals(2, result.getRunCount());
}
}