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

io.cucumber.core.options.PluginOption Maven / Gradle / Ivy

There is a newer version: 7.18.0
Show newest version
package io.cucumber.core.options;

import io.cucumber.core.exception.CucumberException;
import io.cucumber.core.logging.Logger;
import io.cucumber.core.logging.LoggerFactory;
import io.cucumber.core.plugin.DefaultSummaryPrinter;
import io.cucumber.core.plugin.HtmlFormatter;
import io.cucumber.core.plugin.JUnitFormatter;
import io.cucumber.core.plugin.JsonFormatter;
import io.cucumber.core.plugin.MessageFormatter;
import io.cucumber.core.plugin.NullSummaryPrinter;
import io.cucumber.core.plugin.Options;
import io.cucumber.core.plugin.PrettyFormatter;
import io.cucumber.core.plugin.ProgressFormatter;
import io.cucumber.core.plugin.RerunFormatter;
import io.cucumber.core.plugin.TeamCityPlugin;
import io.cucumber.core.plugin.TestNGFormatter;
import io.cucumber.core.plugin.TimelineFormatter;
import io.cucumber.core.plugin.UnusedStepsSummaryPrinter;
import io.cucumber.core.plugin.UsageFormatter;
import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.EventListener;
import io.cucumber.plugin.Plugin;
import io.cucumber.plugin.SummaryPrinter;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PluginOption implements Options.Plugin {

    private static final Logger log = LoggerFactory.getLogger(PluginOption.class);

    private static final Pattern PLUGIN_WITH_ARGUMENT_PATTERN = Pattern.compile("([^:]+):(.*)");
    private static final HashMap>> PLUGIN_CLASSES = new HashMap>>() {
        {
            put("default_summary", () -> DefaultSummaryPrinter.class);
            put("html", () -> HtmlFormatter.class);
            put("json", () -> JsonFormatter.class);
            put("junit", () -> JUnitFormatter.class);
            put("null_summary", () -> NullSummaryPrinter.class);
            put("pretty", () -> PrettyFormatter.class);
            put("progress", () -> ProgressFormatter.class);
            put("message", () -> MessageFormatter.class);
            put("rerun", () -> RerunFormatter.class);
            put("summary", () -> DefaultSummaryPrinter.class);
            put("testng", () -> TestNGFormatter.class);
            put("timeline", () -> TimelineFormatter.class);
            put("unused", () -> UnusedStepsSummaryPrinter.class);
            put("usage", () -> UsageFormatter.class);
            put("teamcity", () -> TeamCityPlugin.class);
        }
    };

    // Replace IDEA plugin with TeamCity
    private static final Set INCOMPATIBLE_INTELLIJ_IDEA_PLUGIN_CLASSES = new HashSet() {
        {
            add("org.jetbrains.plugins.cucumber.java.run.CucumberJvmSMFormatter");
            add("org.jetbrains.plugins.cucumber.java.run.CucumberJvm2SMFormatter");
            add("org.jetbrains.plugins.cucumber.java.run.CucumberJvm3SMFormatter");
            add("org.jetbrains.plugins.cucumber.java.run.CucumberJvm4SMFormatter");
            add("org.jetbrains.plugins.cucumber.java.run.CucumberJvm5SMFormatter");
        }
    };

    // Refuse plugins known to implement the old API
    private static final Set INCOMPATIBLE_PLUGIN_CLASSES = new HashSet() {
        {
            add("io.qameta.allure.cucumberjvm.AllureCucumberJvm");
            add("io.qameta.allure.cucumber2jvm.AllureCucumber2Jvm");
            add("io.qameta.allure.cucumber3jvm.AllureCucumber3Jvm");
            add("io.qameta.allure.cucumber4jvm.AllureCucumber4Jvm");
        }
    };

    private final String pluginString;
    private final Class pluginClass;
    private final String argument;

    private PluginOption(String pluginString, Class pluginClass, String argument) {
        this.pluginString = pluginString;
        this.pluginClass = pluginClass;
        this.argument = argument;
    }

    public static PluginOption parse(String pluginArgumentPattern) {
        Matcher pluginWithFile = PLUGIN_WITH_ARGUMENT_PATTERN.matcher(pluginArgumentPattern);
        if (!pluginWithFile.matches()) {
            return new PluginOption(pluginArgumentPattern, parsePluginName(pluginArgumentPattern), null);
        }

        Class pluginClass = parsePluginName(pluginWithFile.group(1));
        return new PluginOption(pluginArgumentPattern, pluginClass, pluginWithFile.group(2));
    }

    private static Class parsePluginName(String pluginName) {
        if (INCOMPATIBLE_PLUGIN_CLASSES.contains(pluginName)) {
            throw new IllegalArgumentException("Plugin is not compatible with this version of Cucumber: " + pluginName);
        }

        if (INCOMPATIBLE_INTELLIJ_IDEA_PLUGIN_CLASSES.contains(pluginName)) {
            log.debug(() -> "Incompatible IntelliJ IDEA Plugin detected. Falling back to teamcity plugin");
            return TeamCityPlugin.class;
        }
        return PLUGIN_CLASSES.getOrDefault(pluginName, () -> loadClass(pluginName)).get();
    }

    @SuppressWarnings("unchecked")
    private static Class loadClass(String className) {
        try {
            Class aClass = Thread.currentThread().getContextClassLoader().loadClass(className);

            if (Plugin.class.isAssignableFrom(aClass)) {
                return (Class) aClass;
            }
            throw new CucumberException(
                "Couldn't load plugin class: " + className + ". It does not implement " + Plugin.class.getName());
        } catch (ClassNotFoundException | NoClassDefFoundError e) {
            throw new CucumberException("Couldn't load plugin class: " + className, e);
        }
    }

    @Override
    public Class pluginClass() {
        return pluginClass;
    }

    @Override
    public String argument() {
        return argument;
    }

    @Override
    public String pluginString() {
        return pluginString;
    }

    boolean isFormatter() {
        return EventListener.class.isAssignableFrom(pluginClass)
                || ConcurrentEventListener.class.isAssignableFrom(pluginClass);
    }

    boolean isSummaryPrinter() {
        return SummaryPrinter.class.isAssignableFrom(pluginClass);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy