sft.UseCase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of SimpleFunctionalTest Show documentation
Show all versions of SimpleFunctionalTest Show documentation
A JUnit extension to easily adopt functional testing and acceptance testing
/*******************************************************************************
* Copyright (c) 2013, 2014 Sylvain Lézier.
* 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
*
* Contributors:
* Sylvain Lézier - initial implementation
*******************************************************************************/
package sft;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import sft.decorators.Decorator;
import sft.decorators.DecoratorExtractor;
import sft.javalang.JavaToHumanTranslator;
import sft.javalang.parser.UseCaseJavaParser;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import static java.lang.reflect.Modifier.isPrivate;
import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic;
public class UseCase extends FixturesHolder {
public final UseCase parent;
public final Decorator useCaseDecorator;
public final ArrayList scenarios;
public final ArrayList subUseCases;
public final ArrayList fixturesHelpers;
public final ContextHandler beforeUseCase;
public final ContextHandler afterUseCase;
public final ContextHandler beforeScenario;
public final ContextHandler afterScenario;
public final DisplayedContext displayedContext;
public final DefaultConfiguration configuration;
private final JavaToHumanTranslator javaToHumanTranslator;
private String comment;
public UseCase(Class> classUnderTest) throws Exception {
this(null,classUnderTest.newInstance(), new DefaultConfiguration());
}
public UseCase(UseCase useCase,Class> classUnderTest) throws Exception {
this(useCase, classUnderTest.newInstance(), new DefaultConfiguration());
}
private UseCase(UseCase useCase, Object object, DefaultConfiguration configuration) throws Exception {
super(object, FixturesVisibility.PrivateOrProtectedOnly,configuration);
parent = useCase;
this.configuration = extractConfiguration(configuration);
javaToHumanTranslator = new JavaToHumanTranslator();
useCaseDecorator = DecoratorExtractor.getDecorator(this.configuration,classUnderTest.getDeclaredAnnotations());
scenarios = extractScenarios();
subUseCases = extractSubUseCases();
fixturesHelpers = extractFixturesHelpers();
beforeUseCase = extractBeforeClassContextHandler();
afterUseCase = extractAfterClassContextHandler();
beforeScenario = extractBeforeContextHandler();
afterScenario = extractAfterContextHandler();
displayedContext = extractDisplayedContext(object);
UseCaseJavaParser javaClassParser = new UseCaseJavaParser(configuration, classUnderTest);
javaClassParser.feed(this);
}
private DefaultConfiguration extractConfiguration(DefaultConfiguration defaultConfiguration) throws IllegalAccessException, InstantiationException {
Using explicitConfiguration = classUnderTest.getAnnotation(Using.class);
if (explicitConfiguration != null) {
return explicitConfiguration.value().newInstance();
}
return defaultConfiguration;
}
private DisplayedContext extractDisplayedContext(Object object) {
return new DisplayedContext(object, extractDisplayableFields());
}
private ContextHandler extractBeforeClassContextHandler() {
Method method = getBeforeClassMethod();
if (method == null) {
return null;
} else {
return new ContextHandler(this, method);
}
}
private ContextHandler extractAfterClassContextHandler() {
Method method = getAfterClassMethod();
if (method == null) {
return null;
} else {
return new ContextHandler(this, method);
}
}
private ContextHandler extractBeforeContextHandler() {
Method method = getBeforeMethod();
if (method == null) {
return null;
} else {
return new ContextHandler(this, method);
}
}
private ContextHandler extractAfterContextHandler() {
Method method = getAfterMethod();
if (method == null) {
return null;
} else {
return new ContextHandler(this, method);
}
}
private ArrayList extractScenarios() throws Exception {
ArrayList scenarios = new ArrayList();
for (Method method : getTestMethods()) {
scenarios.add(new Scenario(this, method));
}
return scenarios;
}
private ArrayList extractSubUseCases() throws Exception {
ArrayList subUseCases = new ArrayList();
for (Field field : getPublicFields()) {
Object subUseCaseObject = field.get(object);
if (subUseCaseObject == null) {
subUseCases.add(new UseCase(this,field.getType().getClass().newInstance(), configuration));
} else {
subUseCases.add(new UseCase(this,subUseCaseObject, configuration));
}
}
return subUseCases;
}
private ArrayList extractFixturesHelpers() throws Exception {
ArrayList helpers = new ArrayList();
for (Field field : getHelperFields()) {
field.setAccessible(true);
Object helperObject = field.get(this.object);
helpers.add(new Helper(helperObject,configuration));
}
return helpers;
}
private ArrayList getPublicFields() {
ArrayList fields = new ArrayList();
for (Field field : classUnderTest.getFields()) {
if (Modifier.isPublic(field.getModifiers())) {
fields.add(field);
}
}
return fields;
}
private ArrayList getHelperFields() {
ArrayList helpersFields = new ArrayList();
for (Field field : classUnderTest.getDeclaredFields()) {
for (Annotation annotation : field.getDeclaredAnnotations()) {
if (annotation instanceof FixturesHelper) {
if (Modifier.isPublic(field.getModifiers())) {
throw new RuntimeException("The FixturesHelper field " + field.getName() + " shall not be public");
} else {
helpersFields.add(field);
}
}
}
}
return helpersFields;
}
private ArrayList getTestMethods() {
ArrayList testMethods = new ArrayList();
for (Method method : classUnderTest.getDeclaredMethods()) {
if (method.isAnnotationPresent(Test.class) && isPublic(method.getModifiers())) {
testMethods.add(method);
}
}
return testMethods;
}
private ArrayList extractDisplayableFields() {
ArrayList displayableFields = new ArrayList();
for (Field field : classUnderTest.getDeclaredFields()) {
if (field.isAnnotationPresent(Displayable.class) &&
isPrivate(field.getModifiers())) {
displayableFields.add(field);
}
}
return displayableFields;
}
private Method getBeforeClassMethod() {
for (Method method : classUnderTest.getDeclaredMethods()) {
if (method.isAnnotationPresent(BeforeClass.class)) {
assertIsAPublicStaticMethod("BeforeClass", method);
return method;
}
}
return null;
}
private Method getAfterClassMethod() {
for (Method method : classUnderTest.getDeclaredMethods()) {
if (method.isAnnotationPresent(AfterClass.class)) {
assertIsAPublicStaticMethod("AfterClass", method);
return method;
}
}
return null;
}
private Method getBeforeMethod() {
for (Method method : classUnderTest.getDeclaredMethods()) {
if (method.isAnnotationPresent(Before.class)) {
assertIsAPublicAndNotStaticMethod("Before", method);
return method;
}
}
return null;
}
private Method getAfterMethod() {
for (Method method : classUnderTest.getDeclaredMethods()) {
if (method.isAnnotationPresent(After.class)) {
assertIsAPublicAndNotStaticMethod("After", method);
return method;
}
}
return null;
}
private void assertIsAPublicStaticMethod(String annotation, Method method) {
int modifiers = method.getModifiers();
if (isPublic(modifiers) && isStatic(modifiers)) {
//OK
} else {
throw new RuntimeException("Method " + method.getDeclaringClass().getCanonicalName() + "." + method.getName() + " annotated with @" + annotation + " should be public and static.");
}
}
private void assertIsAPublicAndNotStaticMethod(String annotation, Method method) {
int modifiers = method.getModifiers();
if (isPublic(modifiers) && !isStatic(modifiers)) {
//OK
} else {
throw new RuntimeException("Method " + method.getDeclaringClass().getCanonicalName() + "." + method.getName() + " annotated with @" + annotation + " should be public and not static.");
}
}
public String getName() {
return javaToHumanTranslator.humanize(classUnderTest);
}
public Fixture getFixtureByMethodName(String methodName) {
for (Fixture fixture : fixtures) {
if (methodName.equals(fixture.method.getName())) {
return fixture;
}
}
for (Helper fixturesHelper : fixturesHelpers) {
for (Fixture fixture : fixturesHelper.fixtures) {
if (methodName.endsWith("." + fixture.method.getName())) {
return fixture;
}
}
}
throw new RuntimeException("No fixture found matching the private or protected method " + methodName + " in class " + classUnderTest.getCanonicalName() + "(use case: " + getName() + ")");
}
public boolean shouldBeIgnored() {
return classUnderTest.getAnnotation(Ignore.class) != null;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public boolean haveComment() {
return comment != null;
}
}