IntegrationTestPlugin.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.integrationtest
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.IntegrationTest
028 
029 import static org.kordamp.gradle.PluginUtils.resolveSourceSets
030 
031 /**
032  @author Andres Almiray
033  @since 0.2.0
034  */
035 class IntegrationTestPlugin 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 integrationTestImplementation = project.configurations.findByName('integrationTestImplementation')
057         if (!integrationTestImplementation) {
058             integrationTestImplementation = project.configurations.create('integrationTestImplementation')
059         }
060         integrationTestImplementation.extendsFrom project.configurations.testImplementation
061 
062         Configuration integrationTestRuntimeOnly = project.configurations.findByName('integrationTestRuntimeOnly')
063         if (!integrationTestRuntimeOnly) {
064             integrationTestRuntimeOnly = project.configurations.create('integrationTestRuntimeOnly')
065         }
066         integrationTestRuntimeOnly.extendsFrom integrationTestImplementation, project.configurations.testRuntimeOnly
067 
068         if (project.plugins.findPlugin('idea')) {
069             project.idea {
070                 module {
071                     scopes.TEST.plus += [integrationTestImplementation]
072                     scopes.TEST.plus += [integrationTestRuntimeOnly]
073                     testSourceDirs += resolveSourceSets(project).integrationTest.allSource.srcDirs
074                 }
075             }
076         }
077     }
078 
079     private void createSourceSetsIfNeeded(Project project) {
080         if (!project.sourceSets.findByName('integrationTest')) {
081             project.sourceSets {
082                 integrationTest {
083                     if (project.file('src/integration-test/java').exists()) {
084                         java.srcDirs project.file('src/integration-test/java')
085                     }
086                     if (project.file('src/integration-test/groovy').exists()) {
087                         groovy.srcDirs project.file('src/integration-test/groovy')
088                     }
089                     if (project.file('src/integration-test/kotlin').exists()) {
090                         kotlin.srcDirs project.file('src/integration-test/kotlin')
091                     }
092                     if (project.file('src/integration-test/scala').exists()) {
093                         scala.srcDirs project.file('src/integration-test/scala')
094                     }
095                     if (project.file('src/integration-test/resources').exists()) {
096                         resources.srcDir project.file('src/integration-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         IntegrationTest integrationTest = project.tasks.findByName('integrationTest')
111         if (!integrationTest) {
112             integrationTest = project.tasks.create('integrationTest', IntegrationTest) {
113                 dependsOn jarTask
114                 group 'Verification'
115                 description 'Runs the integration tests.'
116                 testClassesDirs = resolveSourceSets(project).integrationTest.output.classesDirs
117                 classpath = resolveSourceSets(project).integrationTest.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 integrationTestReport = project.tasks.findByName('integrationTestReport')
128         if (!integrationTestReport) {
129             integrationTestReport = project.tasks.create('integrationTestReport', TestReport) {
130                 group 'Reporting'
131                 description 'Generates a report on integration tests.'
132                 destinationDir = project.file("${project.reporting.baseDir.path}/integration-tests")
133                 reportOn integrationTest.binResultsDir
134             }
135         }
136 
137         integrationTest.mustRunAfter project.tasks.test
138         integrationTest.finalizedBy integrationTestReport
139         project.tasks.check.dependsOn integrationTestReport
140     }
141 
142     static void applyIfMissing(Project project) {
143         if (!project.plugins.findPlugin(IntegrationTestPlugin)) {
144             project.plugins.apply(IntegrationTestPlugin)
145         }
146     }
147 }