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

dev.gradleplugins.internal.GradlePluginDevelopmentTestSuiteInternal Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
package dev.gradleplugins.internal;

import dev.gradleplugins.*;
import lombok.Getter;
import org.gradle.api.Action;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.component.SoftwareComponent;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.PluginManager;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.reflect.HasPublicType;
import org.gradle.api.reflect.TypeOf;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.testing.Test;
import org.gradle.internal.Actions;
import org.gradle.plugin.devel.tasks.PluginUnderTestMetadata;
import org.gradle.util.GradleVersion;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.stream.StreamSupport;

import static dev.gradleplugins.internal.DefaultDependencyVersions.SPOCK_FRAMEWORK_VERSION;

public abstract class GradlePluginDevelopmentTestSuiteInternal implements GradlePluginDevelopmentTestSuite, SoftwareComponent, HasPublicType, FinalizableComponent {
    private final GradlePluginTestingStrategyFactory strategyFactory;
    private final Dependencies dependencies;
    private final String name;
    @Getter private final List> testTaskActions = new ArrayList<>();
    private final Action finalizeAction;
    private final TestTaskView testTasks;
    private boolean finalized = false;

    @Inject
    protected abstract ObjectFactory getObjects();

    @Inject
    protected abstract TaskContainer getTasks();

    @Inject
    public GradlePluginDevelopmentTestSuiteInternal(String name, TaskContainer tasks, ObjectFactory objects, PluginManager pluginManager, ProviderFactory providers, Provider minimumGradleVersion) {
        this.strategyFactory = new GradlePluginTestingStrategyFactoryInternal(minimumGradleVersion);
        this.name = name;
        this.dependencies = getObjects().newInstance(Dependencies.class, getSourceSet(), pluginManager, minimumGradleVersion.orElse(GradleVersion.current().getVersion()).map(GradleRuntimeCompatibility::groovyVersionOf));
        getTasks().withType(PluginUnderTestMetadata.class).configureEach(task -> {
            if (task.getName().equals("pluginUnderTestMetadata")) {
                task.getPluginClasspath().from((Callable) dependencies::pluginUnderTestMetadata);
            }
        });
        this.testTaskActions.add(new RegisterTestingStrategyPropertyExtensionRule(objects));
        this.testTasks = getObjects().newInstance(TestTaskView.class, testTaskActions, providers.provider(new FinalizeComponentCallable<>()).orElse(getTestTaskCollection()));
        this.finalizeAction = Actions.composite(new TestSuiteSourceSetExtendsFromTestedSourceSetIfPresentRule(), new CreateTestTasksFromTestingStrategiesRule(tasks, objects, getTestTaskCollection()), new AttachTestTasksToCheckTaskIfPresent(pluginManager, tasks), new FinalizeTestSuiteProperties());
        getSourceSet().finalizeValueOnRead();
        getTestingStrategies().finalizeValueOnRead();
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public TypeOf getPublicType() {
        return TypeOf.typeOf(GradlePluginDevelopmentTestSuite.class);
    }

    @Override
    public GradlePluginTestingStrategyFactory getStrategies() {
        return strategyFactory;
    }

    public abstract SetProperty getTestTaskCollection();

    @Override
    public String toString() {
        return "test suite '" + name + "'";
    }

    @Override
    public TaskView getTestTasks() {
        return testTasks;
    }

    protected static /*final*/ abstract class TestTaskView implements TaskView {
        private final List> testTaskActions;
        private final Provider> elementsProvider;

        @Inject
        public TestTaskView(List> testTaskActions, Provider> elementsProvider) {
            this.testTaskActions = testTaskActions;
            this.elementsProvider = elementsProvider;
        }

        @Override
        public void configureEach(Action action) {
            testTaskActions.add(action);
        }

        @Override
        public Provider> getElements() {
            return elementsProvider;
        }
    }

    @Override
    public void finalizeComponent() {
        if (!finalized) {
            finalized = true;
            finalizeAction.execute(this);
            getSourceSet().finalizeValue();
        }
    }

    @Override
    public Dependencies getDependencies() {
        return dependencies;
    }

    @Override
    public void dependencies(Action action) {
        action.execute(dependencies);
    }

    protected abstract static class Dependencies implements GradlePluginDevelopmentTestSuiteDependencies {
        private final Provider sourceSetProvider;
        private final PluginManager pluginManager;
        private final Provider defaultGroovyVersion;

        @Inject
        protected abstract ConfigurationContainer getConfigurations();

        @Inject
        protected abstract DependencyHandler getDependencies();

        private SourceSet sourceSet() {
            return sourceSetProvider.get();
        }

        private Configuration pluginUnderTestMetadata() {
            return getConfigurations().maybeCreate(sourceSet().getName() + "PluginUnderTestMetadata");
        }

        @Inject
        public Dependencies(Provider sourceSetProvider, PluginManager pluginManager, Provider defaultGroovyVersion) {
            this.sourceSetProvider = sourceSetProvider;
            this.pluginManager = pluginManager;
            this.defaultGroovyVersion = defaultGroovyVersion;
        }

        @Override
        public void implementation(Object notation) {
            GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).add(sourceSet().getImplementationConfigurationName(), notation);
        }

        @Override
        public void implementation(Object notation, Action action) {
            ModuleDependency dependency = (ModuleDependency) getDependencies().create(notation);
            action.execute(dependency);
            getDependencies().add(sourceSet().getImplementationConfigurationName(), dependency);
        }

        @Override
        public void compileOnly(Object notation) {
            GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).add(sourceSet().getCompileOnlyConfigurationName(), notation);
        }

        @Override
        public void runtimeOnly(Object notation) {
            GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).add(sourceSet().getRuntimeOnlyConfigurationName(), notation);
        }

        @Override
        public void annotationProcessor(Object notation) {
            getDependencies().add(sourceSet().getAnnotationProcessorConfigurationName(), notation);
        }

        @Override
        public void pluginUnderTestMetadata(Object notation) {
            getDependencies().add(pluginUnderTestMetadata().getName(), notation);
        }

        @Override
        public Object testFixtures(Object notation) {
            return getDependencies().testFixtures(notation);
        }

        @Override
        public Object platform(Object notation) {
            return getDependencies().platform(notation);
        }

        @Override
        public Object spockFramework() {
            return spockFramework(SPOCK_FRAMEWORK_VERSION);
        }

        @Override
        public Object spockFramework(String version) {
            pluginManager.apply("groovy-base"); // Spock framework imply Groovy implementation language
            return GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).spockFramework(version);
        }

        @Override
        public Object gradleFixtures() {
            return GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).gradleFixtures();
        }

        @Override
        public Object gradleTestKit() {
            return getDependencies().gradleTestKit();
        }

        @Override
        public Object groovy() {
            return defaultGroovyVersion.map(GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies())::groovy);
        }

        @Override
        public Object groovy(String version) {
            return GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).groovy(version);
        }

        @Override
        public Object gradleApi(String version) {
            return GradlePluginDevelopmentDependencyExtensionInternal.of(getDependencies()).gradleApi(version);
        }
    }

    private final class FinalizeComponentCallable implements Callable {
        @Override
        public T call() throws Exception {
            finalizeComponent();
            return null;
        }
    }
}