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

cucumber.runtime.arquillian.lifecycle.CucumberLifecycle Maven / Gradle / Ivy

package cucumber.runtime.arquillian.lifecycle;

import cucumber.api.java.en.And;
import cucumber.api.java.en.But;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import cucumber.runtime.arquillian.shared.ClientServerFiles;
import cucumber.runtime.arquillian.stream.NotCloseablePrintStream;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.core.spi.ServiceLoader;
import org.jboss.arquillian.test.spi.TestEnricher;
import org.jboss.arquillian.test.spi.event.suite.AfterClass;
import org.jboss.arquillian.test.spi.event.suite.Before;
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * These observers are for:
 * 1. get cucumber annotations from a client scan (avoid server scan hacks/specific modules)
 * -> it is done as late as possible to be able a good TCCL even in embedded mode
 * 2. hack System.out for IDE integration
 * 3. get test enricher to enrich additional glues
 */
public class CucumberLifecycle {
    private static final PrintStream ORIGINAL_OUT = System.out;
    private static final PrintStream NOT_CLOSEABLE_OUT = new NotCloseablePrintStream(ORIGINAL_OUT);
    private static final Collection> CUCUMBER_ANNOTATIONS = new CopyOnWriteArrayList>();
    private static final Collection TEST_ENRICHERS = new CopyOnWriteArrayList();

    @Inject
    private Instance serviceLoader;

    public void init(final @Observes BeforeClass beforeClass) {
        System.setOut(NOT_CLOSEABLE_OUT);
    }

    public void reset(final @Observes AfterClass afterClass) {
        System.setOut(ORIGINAL_OUT);
        CUCUMBER_ANNOTATIONS.clear();
        TEST_ENRICHERS.clear();
    }

    // do it lazily to get the right classloader + be sure contexts are started (drone...)
    public void loadCucumberAnnotationsAndEnrichers(final @Observes(precedence = 1) Before before) {
        if (!CUCUMBER_ANNOTATIONS.isEmpty()) { // don't do it N times
            return;
        }

        // enrichers
        TEST_ENRICHERS.addAll(serviceLoader.get().all(TestEnricher.class));

        // cucumber annotations
        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        final InputStream is = tccl.getResourceAsStream(ClientServerFiles.ANNOTATION_LIST);
        if (is != null) {
            String line;
            try {
                final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                while ((line = reader.readLine()) != null) {
                    try {
                        CUCUMBER_ANNOTATIONS.add((Class) tccl.loadClass(line));
                    } catch (ClassNotFoundException e) {
                        // no-op
                    }
                }
            } catch (final IOException e) {
                // no-op
            } finally {
                try {
                    is.close();
                } catch (final IOException e) {
                    // no-op
                }
            }
        }
    }

    public static Collection> cucumberAnnotations() {
        if (!CUCUMBER_ANNOTATIONS.isEmpty()) {
            return CUCUMBER_ANNOTATIONS;
        }

        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        final ResourceLoaderClassFinder finder = new ResourceLoaderClassFinder(new MultiLoader(loader), loader);
        CUCUMBER_ANNOTATIONS.addAll(finder.getDescendants(Annotation.class, "cucumber.api"));

        if (CUCUMBER_ANNOTATIONS.isEmpty()) {
            return Arrays.asList(Given.class, When.class, Then.class, And.class, But.class);
        }
        return CUCUMBER_ANNOTATIONS;
    }

    public static Object enrich(final Object instance) {
        for (final TestEnricher enricher : TEST_ENRICHERS) {
            try {
                enricher.enrich(instance);
            } catch (final Exception e) {
                // no-op: don't make all enrichment fail because of one enricher
            }
        }
        return instance;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy