org.jnario.runner.FeatureRunner.java Source code

Java tutorial

Introduction

Here is the source code for org.jnario.runner.FeatureRunner.java

Source

/*******************************************************************************
 * 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 org.jnario.runner.ExtensionRule.createExtensionRule;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;

import org.eclipse.xtext.xbase.lib.Exceptions;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;

/**
 * A spec {@link Runner} for Jnario features. It does not reset the scenario's
 * state between the execution of each step.
 * 
 * @author Birgit Engelmann - Initial contribution and API
 * @author Sebastian Benz - Added support for {@link Rule} and  {@link Extension}s.
 */
public class FeatureRunner extends ExampleGroupRunner {

    private final class TestInstantiatorRule implements TestRule {
        private final SpecCreator testInstantiator;

        private TestInstantiatorRule(SpecCreator testInstantiator) {
            this.testInstantiator = testInstantiator;
        }

        public Statement apply(final Statement base, Description description) {
            return new Statement() {

                @Override
                public void evaluate() throws Throwable {
                    testInstantiator.beforeSpecRun();
                    base.evaluate();
                    testInstantiator.afterSpecRun();
                }
            };
        }
    }

    private Object scenario;
    private SpecCreator testInstantiator;

    public FeatureRunner(Class<?> klass, NameProvider nameProvider, Set<Method> setups) throws InitializationError {
        super(klass, nameProvider, setups);
    }

    public FeatureRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Predicate<FrameworkMethod> isTestMethod() {
        return Predicates.alwaysTrue();
    }

    @Override
    protected ExampleRunner createExampleRunner(Class<?> testClass, FrameworkMethod from)
            throws InitializationError, NoTestsRemainException {
        if (scenario == null) {
            scenario = getOrCreateTestInstantiator().createSpec(targetClass());
        }
        return new StepRunner(testClass, from, getNameProvider(), scenario);
    }

    public SpecCreator getOrCreateTestInstantiator() {
        if (testInstantiator == null) {
            try {
                testInstantiator = createTestInstantiator();
            } catch (InitializationError e) {
                Exceptions.sneakyThrow(e);
                return null; // not reachable
            }
        }
        return testInstantiator;
    }

    @Override
    protected Statement classBlock(RunNotifier notifier) {
        Statement classBlock = super.classBlock(notifier);
        for (TestRule rule : getTestRules()) {
            classBlock = rule.apply(classBlock, getDescription());
        }
        return classBlock;
    }

    protected List<TestRule> getTestRules() {
        List<TestRule> rules = getTestClass().getAnnotatedFieldValues(scenario, Rule.class, TestRule.class);
        rules.add(createExtensionRule(getExtensions(), scenario));
        rules.add(0, createInstantiatorRule());
        return rules;
    }

    private TestRule createInstantiatorRule() {
        return new TestInstantiatorRule(getOrCreateTestInstantiator());
    }

}