All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tatateo.test.DependencyRunner Maven / Gradle / Ivy

The newest version!
package com.tatateo.test;

import org.junit.Assume;
import org.junit.internal.runners.statements.RunBefores;
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.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

import java.util.*;
import java.util.logging.Logger;

/**
 * @author teo
 * @since 24.01.16
 */
public class DependencyRunner extends BlockJUnit4ClassRunner {
    static final Logger L = Logger.getLogger(DependencyRunner.class.getName());

    //static {L.setLevel(Level.ALL);}

    private List children;
    protected Map methods;

    final HashSet failed = new HashSet();
    final HashSet success = new HashSet();

    public DependencyRunner(Class klass) throws InitializationError {
        super(klass);
    }

    //
    @Override
    protected List getChildren() {
        if (null == methods) {
            children = ExtendedMethod.extend(super.getChildren());
            L.finest("initial order: " + methods2String(children));

            Collections.sort(children, new PriorityComparator());
            L.finest("Sorted (reversed) By Priority: " + methods2String(children));

            methods = new LinkedHashMap(children.size());
            for (ExtendedMethod d : children) {
                methods.put(d.getName(), d);
            }

            ExtendedMethod.computeFollowers(methods);

            children = ExtendedMethod.sortByDependencies(methods);

            L.finer("reorder with deps: " + methods.keySet());
        }

        return (List) children;
    }

    @Override
    public void run(final RunNotifier notifier) {
        notifier.addFirstListener(listener);
        super.run(notifier);
    }

    RunListener listener = new RunListener() {

        @Override
        public void testFinished(Description description) throws Exception {
            if (!failed.contains(description.getMethodName())) {
                success.add(description.getMethodName());
            }
        }

        @Override
        public void testFailure(Failure failure) throws Exception {
            failed.add(failure.getDescription().getMethodName());
        }

        @Override
        public void testAssumptionFailure(Failure failure) {
            failed.add(failure.getDescription().getMethodName());
        }

        @Override
        public void testIgnored(Description description) throws Exception {
            failed.add(description.getMethodName());
        }
    };

    @Override
    public void filter(final Filter original) throws NoTestsRemainException {
        super.filter(new Filter() {
            Set allowedMethods = new HashSet();

            {
                for (FrameworkMethod m : getChildren()) {
                    Description d = DependencyRunner.super.describeChild(m);
                    if (original.shouldRun(d)) {
                        allowedMethods.addAll(getDependencyHierarchy((ExtendedMethod) m));
                    }
                }
            }

            @Override
            public boolean shouldRun(Description description) {
                return allowedMethods.contains(description.getMethodName());
            }

            @Override
            public String describe() {
                return "original filter + dependencies";
            }
        });
    }

    public List getDependencyHierarchy(ExtendedMethod method) {
        ArrayList list = new ArrayList();
        list.add(method.getName());
        if (method.dependencies != null) {
            for (String d : method.dependencies) {
                list.addAll(getDependencyHierarchy(getExtendedMethodByName(d)));
            }
        }
        return list;
    }

    @Override
    protected Statement withBefores(final FrameworkMethod method, Object target, Statement statement) {
        final Statement s = super.withBefores(method, target, statement);

        final ExtendedMethod extMethod = (ExtendedMethod) method;

        if (extMethod.dependencies.size() > 0) {
            return (s instanceof RunBefores) ? (RunBefores) s : new Statement() {
                @Override
                public void evaluate() throws Throwable {

                    L.info("Evaluating the dependencies...");

                    final List missingDeps = minus(extMethod.dependencies, success);
                    if (missingDeps.size() > 0) {
                        Assume.assumeTrue("Method " + method.getName() + "() has unsatisfied dependencies: " + missingDeps, false);
                    }

                    // continue to run the test
                    s.evaluate();
                }
            };
        }

        return s;
    }

    public static  List minus(Collection c, Collection d) {
        final List list = new ArrayList();
        for (T t : c) {
            if (!d.contains(t)) {
                list.add(t);
            }
        }
        return list;
    }

    private String methods2String(List children) {
        StringBuilder sb = new StringBuilder("[");
        for (FrameworkMethod m : children) {
            sb.append(m.getName()).append("\n");
        }
        return sb.append("]").toString();
    }

    /**
     * @deprecated
     */
    public ExtendedMethod getExtendedMethodByName(String name) {
        for (ExtendedMethod m : this.methods.values()) {
            if (name.equals(m.getName())) {
                return m;
            }
        }
        throw new AssertionError("The annotation '" + Conditions.class.getSimpleName() + "' should only be used on test methods.");
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy