From 066e1d6242ac7a4e956162ee5788b903cced2d00 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Sat, 1 Apr 2017 18:28:13 +0700 Subject: [PATCH 01/18] @BeforeParam/@AfterParam for Parameterized runner --- .../java/org/junit/runners/Parameterized.java | 42 +++++++++ .../BlockJUnit4ClassRunnerWithParameters.java | 71 ++++++++++++++- .../classes/ParameterizedTestTest.java | 90 ++++++++++++++++++- 3 files changed, 200 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index cc7c804f4daa..667e3219b209 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -1,5 +1,6 @@ package org.junit.runners; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; @@ -234,6 +235,32 @@ public class Parameterized extends Suite { Class value() default BlockJUnit4ClassRunnerWithParametersFactory.class; } + /** + * Annotation for {@code public static void} methods which should be executed before + * evaluating tests with a particular parameter. + * + * @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 a particular parameter. + * + * @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. */ @@ -241,6 +268,21 @@ public Parameterized(Class klass) throws Throwable { super(klass, RunnersFactory.createRunnersForClass(klass)); } + @Override + protected void collectInitializationErrors(List errors) { + super.collectInitializationErrors(errors); + validatePublicStaticVoidMethods(Parameterized.BeforeParam.class, errors); + validatePublicStaticVoidMethods(Parameterized.AfterParam.class, errors); + } + + private void validatePublicStaticVoidMethods(Class annotation, + List errors) { + final List methods = getTestClass().getAnnotatedMethods(annotation); + for (FrameworkMethod eachTestMethod : methods) { + eachTestMethod.validatePublicVoid(true, errors); + } + } + private static class RunnersFactory { private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java index ffed4beaf6bb..f28a43cb8a4a 100644 --- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java @@ -2,15 +2,18 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.List; 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.MultipleFailureException; import org.junit.runners.model.Statement; /** @@ -134,8 +137,72 @@ protected void validateFields(List errors) { } @Override - protected Statement classBlock(RunNotifier notifier) { - return childrenInvoker(notifier); + protected Statement classBlock(final RunNotifier notifier) { + Statement statement = childrenInvoker(notifier); + statement = withBeforeParams(statement); + statement = withAfterParams(statement); + return statement; + } + + private Statement withBeforeParams(Statement statement) { + final List befores = getTestClass() + .getAnnotatedMethods(Parameterized.BeforeParam.class); + return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores); + } + + private class RunBeforeParams extends Statement { + private final Statement next; + private final List befores; + + RunBeforeParams(Statement next, List befores) { + this.next = next; + this.befores = befores; + } + + @Override + public void evaluate() throws Throwable { + for (FrameworkMethod before : befores) { + final int paramCount = before.getMethod().getParameterTypes().length; + before.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); + } + next.evaluate(); + } + } + + private Statement withAfterParams(Statement statement) { + final List afters = getTestClass() + .getAnnotatedMethods(Parameterized.AfterParam.class); + return afters.isEmpty() ? statement : new RunAfterParams(statement, afters); + } + + private class RunAfterParams extends Statement { + private final Statement next; + private final List afters; + + RunAfterParams(Statement next, List afters) { + this.next = next; + this.afters = afters; + } + + @Override + public void evaluate() throws Throwable { + final List errors = new ArrayList(); + try { + next.evaluate(); + } catch (Throwable e) { + errors.add(e); + } finally { + for (FrameworkMethod each : afters) { + try { + final int paramCount = each.getMethod().getParameterTypes().length; + each.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); + } catch (Throwable e) { + errors.add(e); + } + } + } + MultipleFailureException.assertEmpty(errors); + } } @Override diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 14916c6f5565..5ada119031c9 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -3,8 +3,8 @@ 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.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.experimental.results.PrintableResult.testResult; @@ -16,6 +16,7 @@ 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; @@ -24,6 +25,7 @@ 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; @@ -259,6 +261,92 @@ public void beforeAndAfterClassAreRun() { 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 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 = ""; + final 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) + 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 data() { + return Arrays.asList("A", "B"); + } + + @Test + public void test() { + } + } + + @Test + public void beforeParamAndAfterParamValidation() { + fLog = ""; + final Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class); + assertEquals(1, result.getFailureCount()); + assertThat(result.getFailures().get(0).getMessage(), containsString("beforeParam() should be static")); + assertThat(result.getFailures().get(0).getMessage(), containsString("afterParam() should be public")); + } + @RunWith(Parameterized.class) static public class EmptyTest { @BeforeClass From 45064f7904d58264bcf1c3ae7368c7731006f215 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Sun, 16 Apr 2017 01:06:36 -0700 Subject: [PATCH 02/18] Fix minor style issues --- .../java/org/junit/runners/Parameterized.java | 6 +++--- .../BlockJUnit4ClassRunnerWithParameters.java | 18 ++++++++++-------- .../running/classes/ParameterizedTestTest.java | 6 +++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 667e3219b209..121c954daa9f 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -275,9 +275,9 @@ protected void collectInitializationErrors(List errors) { validatePublicStaticVoidMethods(Parameterized.AfterParam.class, errors); } - private void validatePublicStaticVoidMethods(Class annotation, - List errors) { - final List methods = getTestClass().getAnnotatedMethods(annotation); + private void validatePublicStaticVoidMethods( + Class annotation, List errors) { + List methods = getTestClass().getAnnotatedMethods(annotation); for (FrameworkMethod eachTestMethod : methods) { eachTestMethod.validatePublicVoid(true, errors); } diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java index f28a43cb8a4a..b842ee0666a4 100644 --- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java @@ -137,7 +137,7 @@ protected void validateFields(List errors) { } @Override - protected Statement classBlock(final RunNotifier notifier) { + protected Statement classBlock(RunNotifier notifier) { Statement statement = childrenInvoker(notifier); statement = withBeforeParams(statement); statement = withAfterParams(statement); @@ -145,7 +145,7 @@ protected Statement classBlock(final RunNotifier notifier) { } private Statement withBeforeParams(Statement statement) { - final List befores = getTestClass() + List befores = getTestClass() .getAnnotatedMethods(Parameterized.BeforeParam.class); return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores); } @@ -162,15 +162,16 @@ private class RunBeforeParams extends Statement { @Override public void evaluate() throws Throwable { for (FrameworkMethod before : befores) { - final int paramCount = before.getMethod().getParameterTypes().length; - before.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); + int paramCount = before.getMethod().getParameterTypes().length; + before.invokeExplosively( + null, paramCount == 0 ? (Object[]) null : parameters); } next.evaluate(); } } private Statement withAfterParams(Statement statement) { - final List afters = getTestClass() + List afters = getTestClass() .getAnnotatedMethods(Parameterized.AfterParam.class); return afters.isEmpty() ? statement : new RunAfterParams(statement, afters); } @@ -186,7 +187,7 @@ private class RunAfterParams extends Statement { @Override public void evaluate() throws Throwable { - final List errors = new ArrayList(); + List errors = new ArrayList(); try { next.evaluate(); } catch (Throwable e) { @@ -194,8 +195,9 @@ public void evaluate() throws Throwable { } finally { for (FrameworkMethod each : afters) { try { - final int paramCount = each.getMethod().getParameterTypes().length; - each.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); + int paramCount = each.getMethod().getParameterTypes().length; + each.invokeExplosively( + null, paramCount == 0 ? (Object[]) null : parameters); } catch (Throwable e) { errors.add(e); } diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 5ada119031c9..c96c998869e8 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -309,7 +309,7 @@ public void second() { @Test public void beforeParamAndAfterParamAreRun() { fLog = ""; - final Result result = JUnitCore.runClasses(BeforeParamAndAfterParam.class); + 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); @@ -341,7 +341,7 @@ public void test() { @Test public void beforeParamAndAfterParamValidation() { fLog = ""; - final Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class); + Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class); assertEquals(1, result.getFailureCount()); assertThat(result.getFailures().get(0).getMessage(), containsString("beforeParam() should be static")); assertThat(result.getFailures().get(0).getMessage(), containsString("afterParam() should be public")); @@ -581,4 +581,4 @@ public void usesParametersRunnerFactoryThatWasSpecifiedByAnnotationInSuperClass( UseParameterizedFactoryTest.class, "Called ExceptionThrowingRunnerFactory."); } -} \ No newline at end of file +} From 3390335dcf03cd0ff16bd950384518e8246b92cd Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Tue, 18 Apr 2017 15:18:08 +0200 Subject: [PATCH 03/18] test for multiple @BeforeParam/@AfterParam --- .../classes/ParameterizedTestTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index c96c998869e8..a104d2f98563 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -315,6 +315,60 @@ public void beforeParamAndAfterParamAreRun() { + "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 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) public static class BeforeParamAndAfterParamError { @Parameterized.BeforeParam From 1de231154126e1675fdb558cea1190f773a784e4 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Tue, 18 Apr 2017 16:01:37 +0200 Subject: [PATCH 04/18] test for @BeforeParam/@AfterParam with multiple parameters --- .../classes/ParameterizedTestTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index a104d2f98563..98e580b591e2 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -369,6 +369,52 @@ public void multipleBeforeParamAndAfterParamAreRun() { + "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 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 From 15ac6ad218c56ddc52b15b0ffca6264feca96a4f Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Tue, 18 Apr 2017 16:50:09 +0200 Subject: [PATCH 05/18] Validate number of parameters in @BeforeParam/@AfterParam --- .../java/org/junit/runners/Parameterized.java | 72 ++++++++++++++----- .../classes/ParameterizedTestTest.java | 34 +++++++++ 2 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 121c954daa9f..944c0753d115 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -10,10 +10,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; - import org.junit.runner.Runner; 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; @@ -265,21 +266,37 @@ public class Parameterized extends Suite { * Only called reflectively. Do not use programmatically. */ public Parameterized(Class klass) throws Throwable { - super(klass, RunnersFactory.createRunnersForClass(klass)); + this(klass, new RunnersFactory(klass)); } - @Override - protected void collectInitializationErrors(List errors) { - super.collectInitializationErrors(errors); - validatePublicStaticVoidMethods(Parameterized.BeforeParam.class, errors); - validatePublicStaticVoidMethods(Parameterized.AfterParam.class, errors); + private Parameterized(Class klass, RunnersFactory runnersFactory) throws Throwable { + super(klass, runnersFactory.createRunners()); + validateBeforeParamAndAfterParamMethods(runnersFactory.getParameterCount()); + } + + private void validateBeforeParamAndAfterParamMethods(Integer parameterCount) + throws InvalidTestClassError { + List errors = new ArrayList(); + 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 annotation, List errors) { + Class annotation, Integer parameterCount, + List errors) { List methods = getTestClass().getAnnotatedMethods(annotation); - for (FrameworkMethod eachTestMethod : methods) { - eachTestMethod.validatePublicVoid(true, errors); + for (FrameworkMethod fm : methods) { + fm.validatePublicVoid(true, errors); + if (parameterCount != null) { + final 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)")); + } + } } } @@ -287,24 +304,37 @@ private static class RunnersFactory { private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); private final TestClass testClass; - - static List createRunnersForClass(Class klass) - throws Throwable { - return new RunnersFactory(klass).createRunners(); - } + private Iterable allParameters; private RunnersFactory(Class klass) { testClass = new TestClass(klass); } + private void evaluateParameters() throws Throwable { + if (allParameters == null) { + allParameters = allParameters(); + } + } + private List createRunners() throws Throwable { + evaluateParameters(); Parameters parameters = getParametersMethod().getAnnotation( Parameters.class); return Collections.unmodifiableList(createRunnersForParameters( - allParameters(), parameters.name(), + allParameters, parameters.name(), getParametersRunnerFactory())); } + private Integer getParameterCount() throws Throwable { + evaluateParameters(); + Iterator iterator = allParameters.iterator(); + if (iterator.hasNext()) { + return normalizeParameters(iterator.next()).length; + } else { + return null; + } + } + private ParametersRunnerFactory getParametersRunnerFactory() throws InstantiationException, IllegalAccessException { UseParametersRunnerFactory annotation = testClass @@ -320,10 +350,14 @@ private ParametersRunnerFactory getParametersRunnerFactory() private TestWithParameters createTestWithNotNormalizedParameters( String pattern, int index, Object parametersOrSingleParameter) { - Object[] parameters = (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter - : new Object[] { parametersOrSingleParameter }; return createTestWithParameters(testClass, pattern, index, - parameters); + normalizeParameters(parametersOrSingleParameter)); + } + + private static Object[] normalizeParameters(Object parametersOrSingleParameter) { + return parametersOrSingleParameter instanceof Object[] + ? (Object[]) parametersOrSingleParameter + : new Object[] { parametersOrSingleParameter }; } @SuppressWarnings("unchecked") diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 98e580b591e2..55cb0899d842 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -447,6 +447,40 @@ public void beforeParamAndAfterParamValidation() { assertThat(result.getFailures().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 data() { + return Arrays.asList("A", "B"); + } + + @Test + public void test() { + } + } + + @Test + public void beforeParamAndAfterParamValidationNumberOfParameters() { + fLog = ""; + Result result = JUnitCore.runClasses(BeforeParamAndAfterParamErrorNumberOfParameters.class); + assertEquals(1, result.getFailureCount()); + assertThat(result.getFailures().get(0).getMessage(), + containsString("Method beforeParam() should have 0 or 1 parameter(s)")); + assertThat(result.getFailures().get(0).getMessage(), + containsString("Method afterParam() should have 0 or 1 parameter(s)")); + } + @RunWith(Parameterized.class) static public class EmptyTest { @BeforeClass From 70245b3221d79506e64a2929c63f4a648bb8ae9d Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Tue, 18 Apr 2017 16:51:54 +0200 Subject: [PATCH 06/18] code style --- src/main/java/org/junit/runners/Parameterized.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 944c0753d115..c1e00918d34a 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; + import org.junit.runner.Runner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InvalidTestClassError; From e270f2cf45165fefe364a610d69dc0b8532f2eb7 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Wed, 19 Apr 2017 09:24:03 +0200 Subject: [PATCH 07/18] iterate parameters once --- .../java/org/junit/runners/Parameterized.java | 38 +++++-------------- .../classes/ParameterizedTestTest.java | 17 +++++---- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index c1e00918d34a..10a1f466bbf7 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Iterator; import java.util.List; import org.junit.runner.Runner; @@ -272,7 +271,7 @@ public Parameterized(Class klass) throws Throwable { private Parameterized(Class klass, RunnersFactory runnersFactory) throws Throwable { super(klass, runnersFactory.createRunners()); - validateBeforeParamAndAfterParamMethods(runnersFactory.getParameterCount()); + validateBeforeParamAndAfterParamMethods(runnersFactory.parameterCount); } private void validateBeforeParamAndAfterParamMethods(Integer parameterCount) @@ -305,37 +304,19 @@ private static class RunnersFactory { private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); private final TestClass testClass; - private Iterable allParameters; private RunnersFactory(Class klass) { testClass = new TestClass(klass); } - private void evaluateParameters() throws Throwable { - if (allParameters == null) { - allParameters = allParameters(); - } - } - private List createRunners() throws Throwable { - evaluateParameters(); Parameters parameters = getParametersMethod().getAnnotation( Parameters.class); return Collections.unmodifiableList(createRunnersForParameters( - allParameters, parameters.name(), + allParameters(), parameters.name(), getParametersRunnerFactory())); } - private Integer getParameterCount() throws Throwable { - evaluateParameters(); - Iterator iterator = allParameters.iterator(); - if (iterator.hasNext()) { - return normalizeParameters(iterator.next()).length; - } else { - return null; - } - } - private ParametersRunnerFactory getParametersRunnerFactory() throws InstantiationException, IllegalAccessException { UseParametersRunnerFactory annotation = testClass @@ -349,16 +330,17 @@ private ParametersRunnerFactory getParametersRunnerFactory() } } + private Integer parameterCount; + private TestWithParameters createTestWithNotNormalizedParameters( String pattern, int index, Object parametersOrSingleParameter) { - return createTestWithParameters(testClass, pattern, index, - normalizeParameters(parametersOrSingleParameter)); - } - - private static Object[] normalizeParameters(Object parametersOrSingleParameter) { - return parametersOrSingleParameter instanceof Object[] - ? (Object[]) parametersOrSingleParameter + final Object[] parameters = (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter : new Object[] { parametersOrSingleParameter }; + if (parameterCount == null) { + parameterCount = parameters.length; + } + return createTestWithParameters(testClass, pattern, index, + parameters); } @SuppressWarnings("unchecked") diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 55cb0899d842..382a0906243b 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -4,6 +4,7 @@ import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -442,9 +443,10 @@ public void test() { public void beforeParamAndAfterParamValidation() { fLog = ""; Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class); - assertEquals(1, result.getFailureCount()); - assertThat(result.getFailures().get(0).getMessage(), containsString("beforeParam() should be static")); - assertThat(result.getFailures().get(0).getMessage(), containsString("afterParam() should be public")); + final List failures = result.getFailures(); + assertThat(failures, hasSize(1)); + assertThat(failures.get(0).getMessage(), containsString("beforeParam() should be static")); + assertThat(failures.get(0).getMessage(), containsString("afterParam() should be public")); } @RunWith(Parameterized.class) @@ -462,7 +464,7 @@ public BeforeParamAndAfterParamErrorNumberOfParameters(String x) { @Parameters public static Collection data() { - return Arrays.asList("A", "B"); + return Arrays.asList("A", "B", "C", "D"); } @Test @@ -474,10 +476,11 @@ public void test() { public void beforeParamAndAfterParamValidationNumberOfParameters() { fLog = ""; Result result = JUnitCore.runClasses(BeforeParamAndAfterParamErrorNumberOfParameters.class); - assertEquals(1, result.getFailureCount()); - assertThat(result.getFailures().get(0).getMessage(), + final List failures = result.getFailures(); + assertThat(failures, hasSize(1)); + assertThat(failures.get(0).getMessage(), containsString("Method beforeParam() should have 0 or 1 parameter(s)")); - assertThat(result.getFailures().get(0).getMessage(), + assertThat(failures.get(0).getMessage(), containsString("Method afterParam() should have 0 or 1 parameter(s)")); } From 570ec3080d0a849296a8f6a2f27d3f93d4d68420 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Wed, 19 Apr 2017 09:27:34 +0200 Subject: [PATCH 08/18] style changes --- src/main/java/org/junit/runners/Parameterized.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 10a1f466bbf7..cb2a2f6f5c0c 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -334,7 +334,7 @@ private ParametersRunnerFactory getParametersRunnerFactory() private TestWithParameters createTestWithNotNormalizedParameters( String pattern, int index, Object parametersOrSingleParameter) { - final Object[] parameters = (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter + Object[] parameters = (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter : new Object[] { parametersOrSingleParameter }; if (parameterCount == null) { parameterCount = parameters.length; From 754732b0a40e6ca5233cce1b16705265814d3b43 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Wed, 19 Apr 2017 15:42:03 -0700 Subject: [PATCH 09/18] Style fixes --- src/main/java/org/junit/runners/Parameterized.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index cb2a2f6f5c0c..e77fa37b5b4d 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -291,7 +291,7 @@ private void validatePublicStaticVoidMethods( for (FrameworkMethod fm : methods) { fm.validatePublicVoid(true, errors); if (parameterCount != null) { - final int methodParameterCount = fm.getMethod().getParameterTypes().length; + 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)")); From 35bbd8f498dcca775a5263afd41077cc4848afca Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Wed, 19 Apr 2017 20:16:50 -0700 Subject: [PATCH 10/18] Make RunnersFactory.parameterCount final --- .../java/org/junit/runners/Parameterized.java | 62 ++++++++++++------- .../classes/ParameterizedTestTest.java | 9 ++- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index e77fa37b5b4d..f214fa5d3773 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -9,6 +9,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -269,7 +270,7 @@ public Parameterized(Class klass) throws Throwable { this(klass, new RunnersFactory(klass)); } - private Parameterized(Class klass, RunnersFactory runnersFactory) throws Throwable { + private Parameterized(Class klass, RunnersFactory runnersFactory) throws Exception { super(klass, runnersFactory.createRunners()); validateBeforeParamAndAfterParamMethods(runnersFactory.parameterCount); } @@ -304,16 +305,23 @@ private static class RunnersFactory { private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); private final TestClass testClass; + private final FrameworkMethod parametersMethod; + private final List allParameters; + private final int parameterCount; - private RunnersFactory(Class klass) { + + private RunnersFactory(Class klass) throws Throwable { testClass = new TestClass(klass); + parametersMethod = getParametersMethod(testClass); + allParameters = allParameters(testClass, parametersMethod); + parameterCount = + allParameters.isEmpty() ? 0 : normalizeParameters(allParameters.get(0)).length; } - private List createRunners() throws Throwable { - Parameters parameters = getParametersMethod().getAnnotation( - Parameters.class); + private List createRunners() throws Exception { + Parameters parameters = parametersMethod.getAnnotation(Parameters.class); return Collections.unmodifiableList(createRunnersForParameters( - allParameters(), parameters.name(), + allParameters, parameters.name(), getParametersRunnerFactory())); } @@ -330,32 +338,39 @@ private ParametersRunnerFactory getParametersRunnerFactory() } } - private Integer parameterCount; - private TestWithParameters createTestWithNotNormalizedParameters( String pattern, int index, Object parametersOrSingleParameter) { - Object[] parameters = (parametersOrSingleParameter instanceof Object[]) ? (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 }; - if (parameterCount == null) { - parameterCount = parameters.length; - } - return createTestWithParameters(testClass, pattern, index, - parameters); } @SuppressWarnings("unchecked") - private Iterable allParameters() throws Throwable { - Object parameters = getParametersMethod().invokeExplosively(null); - if (parameters instanceof Iterable) { - return (Iterable) parameters; + private static List allParameters( + TestClass testClass, FrameworkMethod parametersMethod) throws Throwable { + Object parameters = parametersMethod.invokeExplosively(null); + if (parameters instanceof List) { + return (List) parameters; + } else if (parameters instanceof Collection) { + return new ArrayList((Collection) parameters); + } else if (parameters instanceof Iterable) { + List result = new ArrayList(); + for (Object entry : ((Iterable) parameters)) { + result.add(entry); + } + return result; } else if (parameters instanceof Object[]) { return Arrays.asList((Object[]) parameters); } else { - throw parametersMethodReturnedWrongType(); + throw parametersMethodReturnedWrongType(testClass, parametersMethod); } } - private FrameworkMethod getParametersMethod() throws Exception { + private static FrameworkMethod getParametersMethod(TestClass testClass) throws Exception { List methods = testClass .getAnnotatedMethods(Parameters.class); for (FrameworkMethod each : methods) { @@ -381,7 +396,7 @@ private List createRunnersForParameters( } return runners; } catch (ClassCastException e) { - throw parametersMethodReturnedWrongType(); + throw parametersMethodReturnedWrongType(testClass, parametersMethod); } } @@ -397,9 +412,10 @@ private List createTestsForParameters( return children; } - private Exception parametersMethodReturnedWrongType() throws Exception { + private static Exception parametersMethodReturnedWrongType( + TestClass testClass, FrameworkMethod parametersMethod) throws Exception { String className = testClass.getName(); - String methodName = getParametersMethod().getName(); + String methodName = parametersMethod.getName(); String message = MessageFormat.format( "{0}.{1}() must return an Iterable of arrays.", className, methodName); diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 382a0906243b..d182bbe550ee 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -4,7 +4,6 @@ import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -443,8 +442,8 @@ public void test() { public void beforeParamAndAfterParamValidation() { fLog = ""; Result result = JUnitCore.runClasses(BeforeParamAndAfterParamError.class); - final List failures = result.getFailures(); - assertThat(failures, hasSize(1)); + assertEquals(1, result.getFailureCount()); + List failures = result.getFailures(); assertThat(failures.get(0).getMessage(), containsString("beforeParam() should be static")); assertThat(failures.get(0).getMessage(), containsString("afterParam() should be public")); } @@ -476,8 +475,8 @@ public void test() { public void beforeParamAndAfterParamValidationNumberOfParameters() { fLog = ""; Result result = JUnitCore.runClasses(BeforeParamAndAfterParamErrorNumberOfParameters.class); - final List failures = result.getFailures(); - assertThat(failures, hasSize(1)); + assertEquals(1, result.getFailureCount()); + List failures = result.getFailures(); assertThat(failures.get(0).getMessage(), containsString("Method beforeParam() should have 0 or 1 parameter(s)")); assertThat(failures.get(0).getMessage(), From 301a6e09657863d0420d5d297d46a8c1ad6489e9 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Wed, 19 Apr 2017 22:10:55 -0700 Subject: [PATCH 11/18] Add test cases for @Parameters methods returning Collection and one-shot Iterables. --- .../classes/ParameterizedTestTest.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index d182bbe550ee..b7d7cbb260d7 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -12,7 +12,9 @@ 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; @@ -632,9 +634,14 @@ public void runsForEverySingleArgumentOfArray() { @RunWith(Parameterized.class) static public class SingleArgumentTestWithIterable { + private static final AtomicBoolean dataCalled = new AtomicBoolean(false); + @Parameters public static Iterable data() { - return asList("first test", "second test"); + if (!dataCalled.compareAndSet(false, true)) { + fail("Should not call @Parameters method more than once"); + } + return new OneShotIterable(asList("first test", "second test")); } public SingleArgumentTestWithIterable(Object argument) { @@ -645,6 +652,22 @@ public void aTest() { } } + private static class OneShotIterable implements Iterable { + private final Iterable delegate; + private final AtomicBoolean iterated = new AtomicBoolean(false); + + OneShotIterable(Iterable delegate) { + this.delegate = delegate; + } + + public Iterator 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 @@ -652,6 +675,29 @@ public void runsForEverySingleArgumentOfIterable() { assertEquals(2, result.getRunCount()); } + @RunWith(Parameterized.class) + static public class SingleArgumentTestWithCollection { + @Parameters + public static Iterable 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()); + } + + static public class ExceptionThrowingRunnerFactory implements ParametersRunnerFactory { public Runner createRunnerForTestWithParameters(TestWithParameters test) From 98e061a177013783c7482e435dc670b9d163c501 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 11:12:17 +0200 Subject: [PATCH 12/18] reuse RunBefores/RunAfters --- .../runners/statements/RunAfters.java | 6 ++- .../runners/statements/RunBefores.java | 6 ++- .../BlockJUnit4ClassRunnerWithParameters.java | 51 +++++-------------- 3 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/junit/internal/runners/statements/RunAfters.java b/src/main/java/org/junit/internal/runners/statements/RunAfters.java index 7512a7d61f40..b08e67464dd0 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunAfters.java +++ b/src/main/java/org/junit/internal/runners/statements/RunAfters.java @@ -30,7 +30,7 @@ public void evaluate() throws Throwable { } finally { for (FrameworkMethod each : afters) { try { - each.invokeExplosively(target); + invokeMethod(each); } catch (Throwable e) { errors.add(e); } @@ -38,4 +38,8 @@ public void evaluate() throws Throwable { } MultipleFailureException.assertEmpty(errors); } + + protected void invokeMethod(FrameworkMethod method) throws Throwable { + method.invokeExplosively(target); + } } \ No newline at end of file diff --git a/src/main/java/org/junit/internal/runners/statements/RunBefores.java b/src/main/java/org/junit/internal/runners/statements/RunBefores.java index 238fbe7d07a5..c29dd62f6d0e 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunBefores.java +++ b/src/main/java/org/junit/internal/runners/statements/RunBefores.java @@ -21,8 +21,12 @@ public RunBefores(Statement next, List befores, Object target) @Override public void evaluate() throws Throwable { for (FrameworkMethod before : befores) { - before.invokeExplosively(target); + invokeMethod(before); } next.evaluate(); } + + protected void invokeMethod(FrameworkMethod before) throws Throwable { + before.invokeExplosively(target); + } } \ No newline at end of file diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java index b842ee0666a4..590705e7129a 100644 --- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java @@ -2,9 +2,10 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.util.ArrayList; 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; @@ -13,7 +14,6 @@ import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** @@ -150,23 +150,15 @@ private Statement withBeforeParams(Statement statement) { return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores); } - private class RunBeforeParams extends Statement { - private final Statement next; - private final List befores; - + private class RunBeforeParams extends RunBefores { RunBeforeParams(Statement next, List befores) { - this.next = next; - this.befores = befores; + super(next, befores, null); } @Override - public void evaluate() throws Throwable { - for (FrameworkMethod before : befores) { - int paramCount = before.getMethod().getParameterTypes().length; - before.invokeExplosively( - null, paramCount == 0 ? (Object[]) null : parameters); - } - next.evaluate(); + protected void invokeMethod(FrameworkMethod before) throws Throwable { + int paramCount = before.getMethod().getParameterTypes().length; + before.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); } } @@ -176,34 +168,15 @@ private Statement withAfterParams(Statement statement) { return afters.isEmpty() ? statement : new RunAfterParams(statement, afters); } - private class RunAfterParams extends Statement { - private final Statement next; - private final List afters; - + private class RunAfterParams extends RunAfters { RunAfterParams(Statement next, List afters) { - this.next = next; - this.afters = afters; + super(next, afters, null); } @Override - public void evaluate() throws Throwable { - List errors = new ArrayList(); - try { - next.evaluate(); - } catch (Throwable e) { - errors.add(e); - } finally { - for (FrameworkMethod each : afters) { - try { - int paramCount = each.getMethod().getParameterTypes().length; - each.invokeExplosively( - null, paramCount == 0 ? (Object[]) null : parameters); - } catch (Throwable e) { - errors.add(e); - } - } - } - MultipleFailureException.assertEmpty(errors); + protected void invokeMethod(FrameworkMethod method) throws Throwable { + int paramCount = method.getMethod().getParameterTypes().length; + method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); } } From f40697029460131c66e12f3b21617ec93eb5cb72 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 11:13:37 +0200 Subject: [PATCH 13/18] style --- .../org/junit/internal/runners/statements/RunBefores.java | 4 ++-- .../parameterized/BlockJUnit4ClassRunnerWithParameters.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/junit/internal/runners/statements/RunBefores.java b/src/main/java/org/junit/internal/runners/statements/RunBefores.java index c29dd62f6d0e..d1fa0f003be6 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunBefores.java +++ b/src/main/java/org/junit/internal/runners/statements/RunBefores.java @@ -26,7 +26,7 @@ public void evaluate() throws Throwable { next.evaluate(); } - protected void invokeMethod(FrameworkMethod before) throws Throwable { - before.invokeExplosively(target); + protected void invokeMethod(FrameworkMethod method) throws Throwable { + method.invokeExplosively(target); } } \ No newline at end of file diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java index 590705e7129a..1b56b3a0788e 100644 --- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java @@ -156,9 +156,9 @@ private class RunBeforeParams extends RunBefores { } @Override - protected void invokeMethod(FrameworkMethod before) throws Throwable { - int paramCount = before.getMethod().getParameterTypes().length; - before.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); + protected void invokeMethod(FrameworkMethod method) throws Throwable { + int paramCount = method.getMethod().getParameterTypes().length; + method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); } } From f7e3ad3af219007cdd7fef94b0d876ba37f1e93d Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 12:08:41 +0200 Subject: [PATCH 14/18] javadoc for @BeforeParam/@AfterParam --- src/main/java/org/junit/runners/Parameterized.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index f214fa5d3773..ea0dd4da49af 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -137,6 +137,19 @@ * } * * + *

Executing code before/after executing tests for a specific parameter

+ *

+ * 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 @BeforeParam/@AfterParam, + * such methods should either have no parameters or have same parameters as the test. + *

+ * @BeforeParam
+ * public static void beforeTestsForParameter(String onlyParameter) {
+ *     System.out.println("Testing " + onlyParameter);
+ * }
+ * 
+ *

+ * *

Create different runners

*

* By default the {@code Parameterized} runner creates a slightly modified From 76c1779e0ad4a633e0697d6e8693fe26ecafd29c Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 16:13:20 +0200 Subject: [PATCH 15/18] update javadoc --- src/main/java/org/junit/runners/Parameterized.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index ea0dd4da49af..28087b80ac6a 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -139,16 +139,16 @@ * *

Executing code before/after executing tests for a specific parameter

*

- * 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 @BeforeParam/@AfterParam, - * such methods should either have no parameters or have same parameters as the test. + * 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. *

  * @BeforeParam
  * public static void beforeTestsForParameter(String onlyParameter) {
  *     System.out.println("Testing " + onlyParameter);
  * }
  * 
- *

* *

Create different runners

*

From 03e598fe91e23371f511695fdc40b8fe24296d12 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 16:14:40 +0200 Subject: [PATCH 16/18] update header in javadoc --- src/main/java/org/junit/runners/Parameterized.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 28087b80ac6a..469c8d6fb42e 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -137,7 +137,7 @@ * } * * - *

Executing code before/after executing tests for a specific parameter

+ *

Executing code before/after executing tests for specific parameters

*

* 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 From 4958ea8692ad1d436d0dbf78aa6908e66a49d70a Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 16:16:10 +0200 Subject: [PATCH 17/18] javadoc: "parameters" --- src/main/java/org/junit/runners/Parameterized.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 469c8d6fb42e..34683cd83319 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -252,7 +252,7 @@ public class Parameterized extends Suite { /** * Annotation for {@code public static void} methods which should be executed before - * evaluating tests with a particular parameter. + * evaluating tests with particular parameters. * * @see org.junit.BeforeClass * @see org.junit.Before @@ -265,7 +265,7 @@ public class Parameterized extends Suite { /** * Annotation for {@code public static void} methods which should be executed after - * evaluating tests with a particular parameter. + * evaluating tests with particular parameters. * * @see org.junit.AfterClass * @see org.junit.After From ab15e7e1b71faaee92f2a45b8facce2134147492 Mon Sep 17 00:00:00 2001 From: Alex Panchenko Date: Thu, 20 Apr 2017 18:53:59 +0200 Subject: [PATCH 18/18] since 4.13 --- .../java/org/junit/internal/runners/statements/RunAfters.java | 3 +++ .../java/org/junit/internal/runners/statements/RunBefores.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/org/junit/internal/runners/statements/RunAfters.java b/src/main/java/org/junit/internal/runners/statements/RunAfters.java index b08e67464dd0..5e56c3350ac1 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunAfters.java +++ b/src/main/java/org/junit/internal/runners/statements/RunAfters.java @@ -39,6 +39,9 @@ public void evaluate() throws Throwable { MultipleFailureException.assertEmpty(errors); } + /** + * @since 4.13 + */ protected void invokeMethod(FrameworkMethod method) throws Throwable { method.invokeExplosively(target); } diff --git a/src/main/java/org/junit/internal/runners/statements/RunBefores.java b/src/main/java/org/junit/internal/runners/statements/RunBefores.java index d1fa0f003be6..bd835c772530 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunBefores.java +++ b/src/main/java/org/junit/internal/runners/statements/RunBefores.java @@ -26,6 +26,9 @@ public void evaluate() throws Throwable { next.evaluate(); } + /** + * @since 4.13 + */ protected void invokeMethod(FrameworkMethod method) throws Throwable { method.invokeExplosively(target); }