org.jnario.runner.ExtensionRule Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2012 BMW Car IT 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.jnario.runner;
import static com.google.common.collect.Iterables.filter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jnario.runner.internal.ExtensionClass;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
public class ExtensionRule implements TestRule {
private final class ExtensionInvocation extends Statement {
private final Object extensionValue;
private Iterable toExecuteBefore;
private Iterable toExecuteAfter;
private Statement next;
private ExtensionInvocation(Statement next, Object extensionValue,
Iterable toExecuteBefore, Iterable toExecuteAfter) {
this.next = next;
this.extensionValue = extensionValue;
this.toExecuteBefore = toExecuteBefore;
this.toExecuteAfter = toExecuteAfter;
}
@Override
public void evaluate() throws Throwable {
run(toExecuteBefore);
next.evaluate();
run(toExecuteAfter);
}
private void run(Iterable toExecute) throws Throwable {
for (FrameworkMethod method : toExecute) {
method.invokeExplosively(extensionValue);
}
}
}
private final Iterable extensions;
private final Object target;
private final Class extends Annotation> beforeAnnotation;
private final Class extends Annotation> afterAnnotation;
private Set alreadyScheduled;
public static ExtensionRule createClassExtensionRule(Iterable extensions, Object target, Set alreadyScheduled){
return new ExtensionRule(extensions, target, BeforeClass.class, AfterClass.class, alreadyScheduled);
}
public static ExtensionRule createExtensionRule(Iterable extensions, Object target){
return new ExtensionRule(extensions, target, Before.class, After.class, new HashSet());
}
public ExtensionRule(Iterable extensions, Object target,
Class extends Annotation> beforeAnnotation,
Class extends Annotation> afterAnnotation, Set alreadyScheduled) {
this.extensions = extensions;
this.target = target;
this.beforeAnnotation = beforeAnnotation;
this.afterAnnotation = afterAnnotation;
this.alreadyScheduled = alreadyScheduled;
}
public Statement apply(Statement next, Description description) {
for (ExtensionClass extension : extensions) {
final Iterable toExecuteBefore = filterAlreadyScheduled(extension.allMethodsWithAnnotation(beforeAnnotation));
final Iterable toExecuteAfter = filterAlreadyScheduled(extension.allMethodsWithAnnotation(afterAnnotation));
try {
final Object extensionValue = extension.get(target);
if (extensionValue == null) {
throw new IllegalStateException(extension.getName() + " is not initialized");
}
next = new ExtensionInvocation(next, extensionValue, toExecuteBefore, toExecuteAfter);
} catch (IllegalAccessException e) {
throw new IllegalStateException(
extension.getName() + " is not accessible. Extension fields must be public.");
}
}
return next;
}
private Iterable filterAlreadyScheduled(
List candidates) {
return Lists.newArrayList(filter(candidates, new Predicate() {
public boolean apply(FrameworkMethod candidate){
boolean result = !alreadyScheduled.contains(candidate.getMethod());
if(result){
alreadyScheduled.add(candidate.getMethod());
}
return result;
}
}));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy