/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.util; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import org.junit.After; import org.junit.Before; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters; import org.junit.runners.parameterized.TestWithParameters; /** * */ public class ParameterizedRunner extends BlockJUnit4ClassRunnerWithParameters { public ParameterizedRunner(TestWithParameters test) throws InitializationError { super(test); } // workaround for: https://github.com/junit-team/junit/issues/1046 private static final ConcurrentHashMap<Class<?>, TestClass> testClasses = new ConcurrentHashMap<>(); @Override protected TestClass createTestClass(Class<?> clazz) { TestClass testClass = testClasses.get(clazz); if (testClass == null) { testClasses.put(clazz, testClass = new TestClass(clazz)); } return testClass; } // playing whack-a-mole with new TLAB allocations by re-defining with{Befores,Afters}... @Override protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) { List<FrameworkMethod> list = getTestClass().getAnnotatedMethods(Before.class); if (list.isEmpty()) { return statement; } return new BeforesStatement(target, statement, list); } @Override protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) { List<FrameworkMethod> list = getTestClass().getAnnotatedMethods(After.class); if (list.isEmpty()) { return statement; } return new AftersStatement(target, statement, list); } private static final class BeforesStatement extends Statement { private static final Object[] EMPTY_ARGS = new Object[0]; private final Object target; private final Statement statement; private final List<FrameworkMethod> list; BeforesStatement(Object target, Statement statement, List<FrameworkMethod> list) { this.target = target; this.statement = statement; this.list = list; } @Override public void evaluate() throws Throwable { // (1) Avoid ImmutableCollections#iterator() for (int i = 0, size = list.size(); i < size; ++i) { list.get(i).invokeExplosively(target, EMPTY_ARGS); } statement.evaluate(); } } private static final class AftersStatement extends Statement { private static final Object[] EMPTY_ARGS = new Object[0]; private final Object target; private final Statement statement; private final List<FrameworkMethod> list; AftersStatement(Object target, Statement statement, List<FrameworkMethod> list) { this.target = target; this.statement = statement; this.list = list; } @Override public void evaluate() throws Throwable { // (2) Lazily create ArrayList ArrayList<Throwable> throwables = null; try { statement.evaluate(); } catch (Throwable e) { throwables = new ArrayList<Throwable>(); throwables.add(e); } finally { for (int i = 0, size = list.size(); i < size; ++i) { try { list.get(i).invokeExplosively(target, EMPTY_ARGS); } catch (Throwable e) { if (throwables == null) { throwables = new ArrayList<Throwable>(); } throwables.add(e); } } } if (throwables != null) { MultipleFailureException.assertEmpty(throwables); } } } }