Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.junit4.parameterized;
import static org.eclipse.xtext.util.Exceptions.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.junit4.IInjectorProvider;
import org.eclipse.xtext.junit4.IRegistryConfigurator;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IExpectation;
import org.eclipse.xtext.junit4.parameterized.IParameterProvider.IParameterAcceptor;
import org.eclipse.xtext.junit4.parameterized.ParameterizedXtextRunner.ResourceRunner;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.ITestExpectationValidator;
import org.eclipse.xtext.junit4.parameterized.TestExpectationValidator.TestResult;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.Exceptions;
import org.eclipse.xtext.util.ReflectionUtil;
import org.eclipse.xtext.util.Strings;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.TestClass;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
/**
* use org.xpect.runner.XpectRunner from www.xpect-tests.org instead.
*
* This class will be removed in the next release after 2.4.2
*
* @author Moritz Eysholdt - Initial contribution and API
*/
@Deprecated
public class ParameterizedXtextRunner extends ParentRunner {
protected static class MethodWithExpectation {
protected Method method;
protected ITestExpectationValidator validator;
public MethodWithExpectation(Method method) throws Throwable {
super();
this.method = method;
this.validator = findValidator();
}
protected ITestExpectationValidator extends Object> createValidator(Test annotation) {
if (method.getReturnType() != void.class)
throw new RuntimeException("The method is expected to return void. Method: " + method);
return new TestExpectationValidator.NullTestResultValidator(annotation);
}
protected ITestExpectationValidator extends Object> createValidator(TestExpectationValidator trv,
Annotation annotation) throws Throwable {
Class extends ITestExpectationValidator>> validatorClass = trv.validator();
Class> expectedResultType = getExpectedResultType(validatorClass);
boolean voidExpected = expectedResultType == Void.TYPE || expectedResultType == Void.class;
boolean returnsExpected = method.getReturnType() == Void.TYPE || method.getReturnType() == Void.class;
if (!expectedResultType.isAssignableFrom(method.getReturnType()) && (!voidExpected || !returnsExpected))
throw new RuntimeException("The return type of " + method + " is expected to be "
+ expectedResultType.getName());
Constructor extends ITestExpectationValidator>> c = validatorClass.getConstructor(annotation
.annotationType());
return c.newInstance(annotation);
}
@SuppressWarnings("unchecked")
protected ITestExpectationValidator findValidator() throws Throwable {
for (Annotation an : method.getAnnotations())
if (an instanceof Test)
return (ITestExpectationValidator) createValidator((Test) an);
else {
TestExpectationValidator trv = an.annotationType().getAnnotation(TestExpectationValidator.class);
if (trv != null)
return (ITestExpectationValidator) createValidator(trv, an);
}
Class>[] annotations = { Test.class, Xpect.class, XpectString.class, XpectLines.class,
XpectCommaSeparatedValues.class };
List names = Lists.newArrayList();
for (Class> o : annotations)
names.add("@" + o.getSimpleName());
throw new RuntimeException("Annotation missing: " + Joiner.on(", ").join(names) + ", etc. in: " + method);
}
protected Class> getExpectedResultType(Class extends ITestExpectationValidator>> clazz) {
for (Method meth : clazz.getMethods()) {
Annotation[][] annotations = meth.getParameterAnnotations();
for (int i = 0; i < annotations.length; i++)
for (Annotation an : annotations[i])
if (an instanceof TestResult)
return meth.getParameterTypes()[i];
}
throw new RuntimeException("One of the method parameters of " + clazz.getName()
+ " must be annotated with @" + TestResult.class.getSimpleName());
}
public Method getMethod() {
return method;
}
public ITestExpectationValidator getValidator() {
return validator;
}
}
protected static class ParameterSetRunner {
protected Description description;
protected IExpectation expectation;
protected boolean ignore;
protected int index = -1;
protected String methodName;
protected Multimap params;
protected ResourceRunner runner;
protected String title;
public Description getDescription() {
if (description == null)
description = Description.createTestDescription(runner.clazz.getJavaClass(), getFullTitle());
return description;
}
public IExpectation getExpectation() {
return expectation;
}
public String getFullTitle() {
StringBuilder result = new StringBuilder();
result.append(methodName);
if (!Strings.isEmpty(title)) {
result.append(" ");
result.append(title);
}
if (index > -1) {
result.append("#");
result.append(index);
}
result.append(" - ");
result.append(runner.resource.getURI().lastSegment());
return result.toString();
}
public IInjectorProvider getInjectorProvider() {
return runner.injectorProvider;
}
public String getMethdoName() {
return methodName;
}
public Multimap getParams() {
return params;
}
public XtextResource getResource() {
return runner.resource;
}
public Class> getTestClass() {
return runner.clazz.getJavaClass();
}
public void init(ResourceRunner runner, String title, String method, Multimap params,
IExpectation expectation, boolean ignore) {
this.runner = runner;
this.title = title;
this.methodName = method;
this.params = params;
this.expectation = expectation;
this.ignore = ignore;
}
public boolean isIgnore() {
return ignore;
}
}
protected static class ResourceRunner implements IParameterAcceptor {
protected TestClass clazz;
protected Description description;
protected IInjectorProvider injectorProvider;
protected List parameterSets = Lists.newArrayList();
protected XtextResource resource;
protected ResourceSet resourceSet;
public void acceptImportURI(URI uri) {
resourceSet.getResource(uri, true);
}
public void acceptTest(String title, String method, Multimap params, IExpectation expectation,
boolean ignore) {
ParameterSetRunner runner = injectorProvider.getInjector().getInstance(ParameterSetRunner.class);
runner.init(this, title, method, params, expectation, ignore);
parameterSets.add(runner);
}
protected void collectParameters() {
IParameterProvider parameterProvider = injectorProvider.getInjector().getInstance(IParameterProvider.class);
parameterProvider.collectParameters(clazz.getJavaClass(), resource, this);
}
public Description getDescription() {
if (description == null) {
description = Description.createSuiteDescription(resource.getURI().lastSegment());
for (ParameterSetRunner child : parameterSets)
description.addChild(child.getDescription());
}
return description;
}
public List getParameterSets() {
return parameterSets;
}
public void init(TestClass clazz, IInjectorProvider injector, URI uri) {
this.clazz = clazz;
this.injectorProvider = injector;
this.resourceSet = injectorProvider.getInjector().getInstance(ResourceSet.class);
this.resource = (XtextResource) resourceSet.getResource(uri, true);
collectParameters();
setIndex();
}
protected void setIndex() {
Set visited = Sets.newHashSet();
Set duplicate = Sets.newHashSet();
for (ParameterSetRunner r : getParameterSets())
if (!visited.add(r.getFullTitle()))
duplicate.add(r.getFullTitle());
Map counter = Maps.newHashMap();
for (ParameterSetRunner r : getParameterSets())
if (duplicate.contains(r.getFullTitle())) {
String title = r.getFullTitle();
Integer count = counter.get(title);
if (count == null)
count = 1;
else
count++;
counter.put(title, count);
r.index = count;
}
}
}
private static Map, IInjectorProvider> injectorProviderClassCache = Maps.newHashMap();
protected List children;
protected Filter filter = null;
protected Map methods = Maps.newHashMap();
public ParameterizedXtextRunner(Class> testClass) throws InitializationError {
super(testClass);
}
protected IInjectorProvider createInjectorProvider() {
IInjectorProvider injectorProvider = null;
InjectWith injectWith = getTestClass().getJavaClass().getAnnotation(InjectWith.class);
if (injectWith != null) {
try {
injectorProvider = injectWith.value().newInstance();
} catch (Exception e) {
throwUncheckedException(e);
}
}
return injectorProvider;
}
@Override
protected Description describeChild(ResourceRunner child) {
return child.getDescription();
}
@Override
public void filter(Filter filter) throws NoTestsRemainException {
super.filter(filter);
this.filter = filter;
}
protected MethodWithExpectation findTestMethod(String name) throws Throwable {
MethodWithExpectation result = methods.get(name);
if (result == null) {
Method method = getTestClass().getJavaClass().getMethod(name);
if (method == null)
throw new RuntimeException("Method " + name + "() not found in " + getTestClass().getName());
result = new MethodWithExpectation(method);
methods.put(name, result);
}
return result;
}
@Override
protected List getChildren() {
if (children == null) {
children = Lists.newArrayList();
IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
for (URI uri : getURIs()) {
ResourceRunner child = injectorProvider.getInjector().getInstance(ResourceRunner.class);
child.init(getTestClass(), injectorProvider, uri);
children.add(child);
}
}
return children;
}
protected IInjectorProvider getInjectorProvider() {
return injectorProviderClassCache.get(getTestClass().getJavaClass());
}
protected IInjectorProvider getOrCreateInjectorProvider() {
IInjectorProvider injectorProvider = getInjectorProvider();
if (injectorProvider == null) {
injectorProvider = createInjectorProvider();
injectorProviderClassCache.put(getTestClass().getJavaClass(), injectorProvider);
}
return injectorProvider;
}
protected List getURIs() {
ResourceURIs classAnnotation = getTestClass().getJavaClass().getAnnotation(ResourceURIs.class);
if (classAnnotation != null)
return getURIs(classAnnotation);
for (FrameworkMethod method : getTestClass().getAnnotatedMethods(ResourceURIs.class)) {
int modifiers = method.getMethod().getModifiers();
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
return getURIs(method);
}
throw new RuntimeException("The class " + getTestClass().getJavaClass()
+ " or one of its static public methods needs to be annotated with @"
+ ResourceURIs.class.getSimpleName());
}
@SuppressWarnings("unchecked")
protected List getURIs(FrameworkMethod method) {
try {
return (List) method.invokeExplosively(null);
} catch (Throwable e) {
Exceptions.throwUncheckedException(e);
return Collections.emptyList();
}
}
protected List getURIs(ResourceURIs uris) {
List result = Lists.newArrayList();
ResourceURICollector collector = new ResourceURICollector();
if (uris.files().length > 0)
result.addAll(collector.collectFiles(uris.files()));
if (!Strings.isEmpty(uris.baseDir()) || uris.fileExtensions().length > 0) {
Assert.assertFalse("@ResourceURIs needs a baseURI", Strings.isEmpty(uris.baseDir()));
Assert.assertTrue("@ResourceURIs needs at least one fileExtension", uris.fileExtensions().length > 0);
result.addAll(collector.collectFiles(uris.baseDir(), uris.fileExtensions()));
}
return result;
}
protected Object newTestInstance() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor> constructor = getTestClass().getJavaClass().getConstructor();
return constructor.newInstance();
}
protected void injectParameters(Object test, Multimap params) {
List fields = Lists.newArrayList();
Class> clazz = test.getClass();
while (clazz != null && clazz != Object.class) {
fields.addAll(Lists.newArrayList(clazz.getDeclaredFields()));
clazz = clazz.getSuperclass();
}
for (Field field : fields) {
InjectParameter annotation = field.getAnnotation(InjectParameter.class);
if (annotation != null) {
String name = Strings.isEmpty(annotation.value()) ? field.getName() : annotation.value();
Class> fieldType = ReflectionUtil.getObjectType(field.getType());
for (Object value : params.get(name))
if (fieldType.isInstance(value)) {
field.setAccessible(true);
try {
field.set(test, value);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
}
}
}
}
// protected Object newTestInstance(Object[][] allParams) throws IllegalArgumentException, InstantiationException,
// IllegalAccessException, InvocationTargetException {
// for (Object[] params : allParams)
// ROOT: for (Constructor> candidate : getTestClass().getJavaClass().getConstructors())
// if (candidate.getParameterTypes().length == params.length) {
// for (int i = 0; i < params.length; i++)
// if (params[i] != null
// && !ReflectionUtil.getObjectType(candidate.getParameterTypes()[i])
// .isInstance(params[i]))
// continue ROOT;
// return candidate.newInstance(params);
// }
// List alternatives = Lists.newArrayList();
// for (Object[] params : allParams) {
// List types = Lists.newArrayList();
// for (Object p : params)
// types.add(p == null ? "?" : p.getClass().getName());
// alternatives.add(Joiner.on(", ").join(types));
// }
// throw new RuntimeException("No valid constructor found in class " + getTestClass().getJavaClass().getName()
// + " for types " + Joiner.on(" or ").join(alternatives));
// }
protected void runChild(ParameterSetRunner ps) throws Throwable {
MethodWithExpectation method = findTestMethod(ps.getMethdoName());
Object test = newTestInstance();
if (ps.getInjectorProvider() instanceof IRegistryConfigurator)
((IRegistryConfigurator) ps.getInjectorProvider()).setupRegistry();
try {
injectParameters(test, ps.getParams());
ps.getInjectorProvider().getInjector().injectMembers(test);
Object result = method.getMethod().invoke(test);
method.getValidator().validate(ps.getResource(), ps.getExpectation(), result);
} catch (InvocationTargetException e) {
throw e.getCause();
} finally {
if (ps.getInjectorProvider() instanceof IRegistryConfigurator)
((IRegistryConfigurator) ps.getInjectorProvider()).restoreRegistry();
}
}
@Override
protected void runChild(ResourceRunner arg0, RunNotifier notifier) {
for (ParameterSetRunner ps : arg0.getParameterSets())
if (filter == null || filter.shouldRun(ps.getDescription())) {
notifier.fireTestStarted(ps.getDescription());
if (ps.isIgnore())
notifier.fireTestIgnored(ps.getDescription());
else
try {
runChild(ps);
} catch (Throwable e) {
notifier.fireTestFailure(new Failure(ps.getDescription(), e));
}
notifier.fireTestFinished(ps.getDescription());
}
}
}