blob: f829981c7782de8ddfee6e305fe62ee92905bfd0 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.test.params;
import org.junit.Test;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.TestClass;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Factory to generate delegate class runners for ParameterizedRunner
*/
public class ParameterizedRunnerDelegateFactory {
/**
* Create a runner that implements ParameterizedRunner and extends BlockJUnit4ClassRunner
*
* @param testClass the TestClass object for current test class
* @param classParameterSet A parameter set for test constructor arguments
* @param parameterizedRunnerDelegateClass the parameterized runner delegate class specified
* through {@code @UseRunnerDelegate}
*/
<T extends ParameterizedRunnerDelegate> T createRunner(TestClass testClass,
ParameterSet classParameterSet, Class<T> parameterizedRunnerDelegateClass)
throws ParameterizedRunnerDelegateInstantiationException {
String testMethodPostfix = classParameterSet == null ? null : classParameterSet.getName();
List<FrameworkMethod> unmodifiableFrameworkMethodList =
generateUnmodifiableFrameworkMethodList(testClass, testMethodPostfix);
ParameterizedRunnerDelegateCommon delegateCommon = new ParameterizedRunnerDelegateCommon(
testClass, classParameterSet, unmodifiableFrameworkMethodList);
try {
return parameterizedRunnerDelegateClass
.getDeclaredConstructor(Class.class, ParameterizedRunnerDelegateCommon.class)
.newInstance(testClass.getJavaClass(), delegateCommon);
} catch (Exception e) {
throw new ParameterizedRunnerDelegateInstantiationException(
parameterizedRunnerDelegateClass.toString(), e);
}
}
/**
* Match test methods annotated by @UseMethodParameter(X) with
* ParameterSetList annotated by @MethodParameter(X)
*
* @param testClass a {@code TestClass} that wraps around the actual java
* test class
* @param postFix a name postfix for each test
* @return a list of ParameterizedFrameworkMethod
*/
static List<FrameworkMethod> generateUnmodifiableFrameworkMethodList(
TestClass testClass, String postFix) {
// Represent the list of all ParameterizedFrameworkMethod in this test class
List<FrameworkMethod> returnList = new ArrayList<>();
for (FrameworkMethod method : testClass.getAnnotatedMethods(Test.class)) {
if (method.getMethod().isAnnotationPresent(UseMethodParameter.class)) {
Iterable<ParameterSet> parameterSets =
getParameters(method.getAnnotation(UseMethodParameter.class).value());
returnList.addAll(createParameterizedMethods(method, parameterSets, postFix));
} else {
// If test method is not parameterized (does not have UseMethodParameter annotation)
returnList.add(new ParameterizedFrameworkMethod(method.getMethod(), null, postFix));
}
}
return Collections.unmodifiableList(returnList);
}
/**
* Exception caused by instantiating the provided Runner delegate
* Potentially caused by not overriding collecInitializationErrors() method
* to be empty
*/
public static class ParameterizedRunnerDelegateInstantiationException extends Exception {
private ParameterizedRunnerDelegateInstantiationException(
String runnerDelegateClass, Exception e) {
super(String.format("Current class runner delegate %s can not be instantiated.",
runnerDelegateClass),
e);
}
}
private static Iterable<ParameterSet> getParameters(Class<? extends ParameterProvider> clazz) {
ParameterProvider parameterProvider;
try {
parameterProvider = clazz.getDeclaredConstructor().newInstance();
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed instantiating " + clazz.getCanonicalName(), e);
} catch (InstantiationException e) {
throw new IllegalStateException("Failed instantiating " + clazz.getCanonicalName(), e);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Failed instantiating " + clazz.getCanonicalName(), e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Failed instantiating " + clazz.getCanonicalName(), e);
}
return parameterProvider.getParameters();
}
private static List<FrameworkMethod> createParameterizedMethods(
FrameworkMethod baseMethod, Iterable<ParameterSet> parameterSetList, String suffix) {
ParameterizedRunner.validateWidth(parameterSetList);
List<FrameworkMethod> returnList = new ArrayList<>();
for (ParameterSet set : parameterSetList) {
returnList.add(new ParameterizedFrameworkMethod(baseMethod.getMethod(), set, suffix));
}
return returnList;
}
}