Skip to content

Commit

Permalink
Merge pull request #702 from stefanbirkner/parameterized-with-one-arg
Browse files Browse the repository at this point in the history
Support more return types for the @parameters method. Fixes #700.
  • Loading branch information
David Saff committed Jul 16, 2013
2 parents e1bf14b + f6a3d74 commit 2a010a8
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 24 deletions.
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());
}
}

0 comments on commit 2a010a8

Please sign in to comment.