FunctionalTestPlugin.groovy
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2018-2019 Andres Almiray.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package org.kordamp.gradle.plugin.functionaltest
019 
020 import org.gradle.api.Project
021 import org.gradle.api.Task
022 import org.gradle.api.artifacts.Configuration
023 import org.gradle.api.plugins.JavaBasePlugin
024 import org.gradle.api.tasks.testing.TestReport
025 import org.kordamp.gradle.plugin.AbstractKordampPlugin
026 import org.kordamp.gradle.plugin.base.BasePlugin
027 import org.kordamp.gradle.plugin.test.tasks.FunctionalTest
028 
029 import static org.kordamp.gradle.PluginUtils.resolveSourceSets
030 
031 /**
032  @author Andres Almiray
033  @since 0.2.0
034  */
035 class FunctionalTestPlugin extends AbstractKordampPlugin {
036     Project project
037 
038     void apply(Project project) {
039         this.project = project
040 
041         if (hasBeenVisited(project)) {
042             return
043         }
044         setVisited(project, true)
045 
046         BasePlugin.applyIfMissing(project)
047 
048         project.plugins.withType(JavaBasePlugin) {
049             createSourceSetsIfNeeded(project)
050             createConfigurationsIfNeeded(project)
051             createTasksIfNeeded(project)
052         }
053     }
054 
055     private void createConfigurationsIfNeeded(Project project) {
056         Configuration functionalTestImplementation = project.configurations.findByName('functionalTestImplementation')
057         if (!functionalTestImplementation) {
058             functionalTestImplementation = project.configurations.create('functionalTestImplementation')
059         }
060         functionalTestImplementation.extendsFrom project.configurations.implementation
061 
062         Configuration functionalTestRuntimeOnly = project.configurations.findByName('functionalTestRuntimeOnly')
063         if (!functionalTestRuntimeOnly) {
064             functionalTestRuntimeOnly = project.configurations.create('functionalTestRuntimeOnly')
065         }
066         functionalTestRuntimeOnly.extendsFrom project.configurations.runtimeOnly
067 
068         if (project.plugins.findPlugin('idea')) {
069             project.idea {
070                 module {
071                     scopes.TEST.plus += [functionalTestImplementation]
072                     scopes.TEST.plus += [functionalTestRuntimeOnly]
073                     testSourceDirs += resolveSourceSets(project).functionalTest.allSource.srcDirs
074                 }
075             }
076         }
077     }
078 
079     private void createSourceSetsIfNeeded(Project project) {
080         if (!project.sourceSets.findByName('functionalTest')) {
081             project.sourceSets {
082                 functionalTest {
083                     if (project.file('src/functional-test/java').exists()) {
084                         java.srcDirs project.file('src/functional-test/java')
085                     }
086                     if (project.file('src/functional-test/groovy').exists()) {
087                         groovy.srcDirs project.file('src/functional-test/groovy')
088                     }
089                     if (project.file('src/functional-test/kotlin').exists()) {
090                         kotlin.srcDirs project.file('src/functional-test/kotlin')
091                     }
092                     if (project.file('src/functional-test/scala').exists()) {
093                         scala.srcDirs project.file('src/functional-test/scala')
094                     }
095                     if (project.file('src/functional-test/resources').exists()) {
096                         resources.srcDir project.file('src/functional-test/resources')
097                     }
098                     compileClasspath += resolveSourceSets(project).main.output
099                     compileClasspath += project.configurations.compileOnly
100                     compileClasspath += project.configurations.testCompileOnly
101                     runtimeClasspath += compileClasspath
102                 }
103             }
104         }
105     }
106 
107     private void createTasksIfNeeded(Project project) {
108         Task jarTask = project.tasks.findByName('jar')
109 
110         FunctionalTest functionalTest = project.tasks.findByName('functionalTest')
111         if (!functionalTest) {
112             functionalTest = project.tasks.create('functionalTest', FunctionalTest) {
113                 dependsOn jarTask
114                 group 'Verification'
115                 description 'Runs the functional tests.'
116                 testClassesDirs = resolveSourceSets(project).functionalTest.output.classesDirs
117                 classpath = resolveSourceSets(project).functionalTest.runtimeClasspath
118                 reports.html.enabled = false
119                 forkEvery = Runtime.runtime.availableProcessors()
120 
121                 testLogging {
122                     events 'passed', 'skipped', 'failed'
123                 }
124             }
125         }
126 
127         TestReport functionalTestReport = project.tasks.findByName('functionalTestReport')
128         if (!functionalTestReport) {
129             functionalTestReport = project.tasks.create('functionalTestReport', TestReport) {
130                 group 'Reporting'
131                 description 'Generates a report on functional tests.'
132                 destinationDir = project.file("${project.reporting.baseDir.path}/functional-tests")
133                 reportOn functionalTest.binResultsDir
134             }
135         }
136 
137         functionalTest.mustRunAfter project.tasks.test
138         functionalTest.finalizedBy functionalTestReport
139         project.tasks.check.dependsOn functionalTestReport
140     }
141 
142     static void applyIfMissing(Project project) {
143         if (!project.plugins.findPlugin(FunctionalTestPlugin)) {
144             project.plugins.apply(FunctionalTestPlugin)
145         }
146     }
147 }