Skip to content

Commit 3b6148e

Browse files
Extract a helper class for testing Gradle builds (#164)
Co-authored-by: Jesse Wilson <jwilson@squareup.com>
1 parent df6cc01 commit 3b6148e

File tree

2 files changed

+102
-98
lines changed

2 files changed

+102
-98
lines changed

burst-gradle-plugin/src/test/kotlin/app/cash/burst/gradle/BurstGradlePluginTest.kt

Lines changed: 36 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ import assertk.assertThat
2020
import assertk.assertions.containsExactlyInAnyOrder
2121
import assertk.assertions.isEqualTo
2222
import assertk.assertions.isFalse
23-
import assertk.assertions.isIn
2423
import java.io.File
25-
import org.gradle.testkit.runner.GradleRunner
26-
import org.gradle.testkit.runner.TaskOutcome
2724
import org.jetbrains.kotlin.konan.target.HostManager
2825
import org.jetbrains.kotlin.konan.target.presetName
2926
import org.junit.Test
@@ -61,19 +58,16 @@ class BurstGradlePluginTest {
6158
platformName: String,
6259
checkKlibMetadata: Boolean = false,
6360
) {
64-
val projectDir = File("src/test/projects/multiplatform")
61+
val tester = GradleTester("multiplatform")
6562

6663
val taskName = ":lib:$testTaskName"
67-
val result = createRunner(projectDir, "clean", taskName).build()
68-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
69-
70-
val testResults = projectDir.resolve("lib/build/test-results")
64+
tester.cleanAndBuild(taskName)
7165

7266
// There's no default specialization.
73-
assertThat(testResults.resolve("$testTaskName/TEST-CoffeeTest.xml").exists()).isFalse()
67+
assertThat(tester.hasTestSuite("CoffeeTest", testTaskName)).isFalse()
7468

7569
// Each test class is executed normally with nothing skipped.
76-
with(readTestSuite(testResults.resolve("$testTaskName/TEST-CoffeeTest_Regular.xml"))) {
70+
with(tester.readTestSuite("CoffeeTest_Regular", testTaskName)) {
7771
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
7872
"test_Milk[$platformName]",
7973
"test_None[$platformName]",
@@ -86,7 +80,7 @@ class BurstGradlePluginTest {
8680

8781
if (checkKlibMetadata) {
8882
val klib = readKlib(
89-
projectDir.resolve("lib/build/classes/kotlin/$platformName/test/klib/lib_test"),
83+
File("src/test/projects/multiplatform").resolve("lib/build/classes/kotlin/$platformName/test/klib/lib_test"),
9084
)
9185
val klibMetadata = klib.moduleMetadata()
9286
val coffeeTestMetadata = klibMetadata.classes.first { it.name == "CoffeeTest" }
@@ -102,16 +96,12 @@ class BurstGradlePluginTest {
10296

10397
@Test
10498
fun functionParameters() {
105-
val projectDir = File("src/test/projects/functionParameters")
99+
val tester = GradleTester("functionParameters")
106100

107101
val taskName = ":lib:test"
108-
val result = createRunner(projectDir, "clean", taskName).build()
109-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
110-
111-
val testResults = projectDir.resolve("lib/build/test-results")
112-
val testXmlFile = testResults.resolve("test/TEST-CoffeeTest.xml")
102+
tester.cleanAndBuild(taskName)
113103

114-
val testSuite = readTestSuite(testXmlFile)
104+
val testSuite = tester.readTestSuite("CoffeeTest")
115105

116106
assertThat(testSuite.testCases.map { it.name }).containsExactlyInAnyOrder(
117107
"test_Decaf_Milk",
@@ -131,16 +121,11 @@ class BurstGradlePluginTest {
131121

132122
@Test
133123
fun abstractClasses() {
134-
val projectDir = File("src/test/projects/abstractClasses")
124+
val tester = GradleTester("abstractClasses")
135125

136-
val taskName = ":lib:test"
137-
val result = createRunner(projectDir, "clean", taskName).build()
138-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
126+
tester.cleanAndBuild(":lib:test")
139127

140-
val testResults = projectDir.resolve("lib/build/test-results")
141-
val testXmlFile = testResults.resolve("test/TEST-CoffeeTest.xml")
142-
143-
val testSuite = readTestSuite(testXmlFile)
128+
val testSuite = tester.readTestSuite("CoffeeTest")
144129

145130
assertThat(testSuite.testCases.map { it.name }).containsExactlyInAnyOrder(
146131
"test_Milk",
@@ -151,18 +136,14 @@ class BurstGradlePluginTest {
151136

152137
@Test
153138
fun classParameters() {
154-
val projectDir = File("src/test/projects/classParameters")
155-
156-
val taskName = ":lib:test"
157-
val result = createRunner(projectDir, "clean", taskName).build()
158-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
139+
val tester = GradleTester("classParameters")
159140

160-
val testResults = projectDir.resolve("lib/build/test-results")
141+
tester.cleanAndBuild(":lib:test")
161142

162143
// There's no default specialization.
163-
assertThat(testResults.resolve("test/TEST-CoffeeTest.xml").exists()).isFalse()
144+
assertThat(tester.hasTestSuite("CoffeeTest")).isFalse()
164145

165-
val sampleTest = readTestSuite(testResults.resolve("test/TEST-CoffeeTest_Regular_Milk.xml"))
146+
val sampleTest = tester.readTestSuite("CoffeeTest_Regular_Milk")
166147
val sampleTestTest = sampleTest.testCases.single()
167148
assertThat(sampleTestTest.name).isEqualTo("test")
168149
assertThat(sampleTestTest.skipped).isFalse()
@@ -177,26 +158,18 @@ class BurstGradlePluginTest {
177158

178159
@Test
179160
fun android() {
180-
val projectDir = File("src/test/projects/android")
181-
182-
val testTaskName = ":lib:test"
183-
val androidTestTaskName = ":lib:assembleAndroidTest"
184-
val result = createRunner(projectDir, "clean", testTaskName, androidTestTaskName).build()
185-
assertThat(result.task(testTaskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
186-
assertThat(result.task(androidTestTaskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
161+
val tester = GradleTester("android")
162+
tester.cleanAndBuild(":lib:test", ":lib:assembleAndroidTest")
187163
}
188164

189165
@Test
190166
fun defaultArguments() {
191-
val projectDir = File("src/test/projects/defaultArguments")
192-
193-
val result = createRunner(projectDir, "clean", ":lib:test").build()
194-
assertThat(result.task(":lib:test")!!.outcome).isIn(*SUCCESS_OUTCOMES)
167+
val tester = GradleTester("defaultArguments")
195168

196-
val testResults = projectDir.resolve("lib/build/test-results")
169+
tester.cleanAndBuild(":lib:test")
197170

198171
// The original test class runs the default specialization.
199-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest.xml"))) {
172+
with(tester.readTestSuite("CoffeeTest")) {
200173
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
201174
"test",
202175
"test_None",
@@ -211,10 +184,10 @@ class BurstGradlePluginTest {
211184
}
212185

213186
// No subclass is generated for the default specialization.
214-
assertThat(testResults.resolve("test/TEST-CoffeeTest_Regular.xml").exists()).isFalse()
187+
assertThat(tester.hasTestSuite("CoffeeTest_Regular")).isFalse()
215188

216189
// Another test class is executed normally with nothing skipped.
217-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest_Double.xml"))) {
190+
with(tester.readTestSuite("CoffeeTest_Double")) {
218191
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
219192
"test",
220193
"test_None",
@@ -231,15 +204,11 @@ class BurstGradlePluginTest {
231204

232205
@Test
233206
fun burstValues() {
234-
val projectDir = File("src/test/projects/burstValues")
235-
236-
val taskName = ":lib:test"
237-
val result = createRunner(projectDir, "clean", taskName).build()
238-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
207+
val tester = GradleTester("burstValues")
239208

240-
val testResults = projectDir.resolve("lib/build/test-results")
209+
tester.cleanAndBuild(":lib:test")
241210

242-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest.xml"))) {
211+
with(tester.readTestSuite("CoffeeTest")) {
243212
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
244213
"test",
245214
"test_12",
@@ -258,7 +227,7 @@ class BurstGradlePluginTest {
258227
)
259228
}
260229

261-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest_Regular.xml"))) {
230+
with(tester.readTestSuite("CoffeeTest_Regular")) {
262231
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
263232
"test",
264233
"test_12",
@@ -280,15 +249,11 @@ class BurstGradlePluginTest {
280249

281250
@Test
282251
fun junit5() {
283-
val projectDir = File("src/test/projects/junit5")
252+
val tester = GradleTester("junit5")
284253

285-
val taskName = ":lib:test"
286-
val result = createRunner(projectDir, "clean", taskName).build()
287-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
288-
289-
val testResults = projectDir.resolve("lib/build/test-results")
254+
tester.cleanAndBuild(":lib:test")
290255

291-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest_Regular.xml"))) {
256+
with(tester.readTestSuite("CoffeeTest_Regular")) {
292257
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
293258
"kotlinTestTest_Milk()",
294259
"kotlinTestTest_None()",
@@ -306,14 +271,11 @@ class BurstGradlePluginTest {
306271
/** https://github.com/cashapp/burst/issues/90 */
307272
@Test
308273
fun subclass() {
309-
val projectDir = File("src/test/projects/subclass")
274+
val tester = GradleTester("subclass")
310275

311-
val taskName = ":lib:test"
312-
val result = createRunner(projectDir, "clean", taskName).build()
313-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
276+
tester.cleanAndBuild(":lib:test")
314277

315-
val testResults = projectDir.resolve("lib/build/test-results")
316-
with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest.xml"))) {
278+
with(tester.readTestSuite("CoffeeTest")) {
317279
assertThat(testCases.map { it.name }).containsExactlyInAnyOrder(
318280
"hasFakeOverride",
319281
"hasFakeOverride_Oat",
@@ -331,18 +293,14 @@ class BurstGradlePluginTest {
331293

332294
@Test
333295
fun valueClassConstructor() {
334-
val projectDir = File("src/test/projects/valueClassConstructor")
335-
336-
val taskName = ":lib:test"
337-
val result = createRunner(projectDir, "clean", taskName).build()
338-
assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES)
296+
val tester = GradleTester("valueClassConstructor")
339297

340-
val testResults = projectDir.resolve("lib/build/test-results")
298+
tester.cleanAndBuild(":lib:test")
341299

342300
// There's no default specialization.
343-
assertThat(testResults.resolve("test/TEST-CoffeeTest.xml").exists()).isFalse()
301+
assertThat(tester.hasTestSuite("CoffeeTest")).isFalse()
344302

345-
val sampleTest = readTestSuite(testResults.resolve("test/TEST-CoffeeTest_Decaf.xml"))
303+
val sampleTest = tester.readTestSuite("CoffeeTest_Decaf")
346304
val sampleTestTest = sampleTest.testCases.single()
347305
assertThat(sampleTestTest.name).isEqualTo("test")
348306
assertThat(sampleTestTest.skipped).isFalse()
@@ -353,24 +311,4 @@ class BurstGradlePluginTest {
353311
""".trimMargin(),
354312
)
355313
}
356-
357-
private fun createRunner(
358-
projectDir: File,
359-
vararg taskNames: String,
360-
): GradleRunner {
361-
val gradleRoot = projectDir.resolve("gradle").also { it.mkdir() }
362-
File("../gradle/wrapper").copyRecursively(gradleRoot.resolve("wrapper"), true)
363-
File(projectDir, "kotlin-js-store/yarn.lock").delete()
364-
val arguments = arrayOf("--info", "--stacktrace", "--continue")
365-
return GradleRunner.create()
366-
.withProjectDir(projectDir)
367-
.withDebug(true) // Run in-process.
368-
.withArguments(*arguments, *taskNames, versionProperty)
369-
.forwardOutput()
370-
}
371-
372-
companion object {
373-
val SUCCESS_OUTCOMES = arrayOf(TaskOutcome.SUCCESS, TaskOutcome.UP_TO_DATE)
374-
val versionProperty = "-PburstVersion=${System.getProperty("burstVersion")}"
375-
}
376314
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (C) 2024 Cash App
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package app.cash.burst.gradle
17+
18+
import assertk.assertThat
19+
import assertk.assertions.isIn
20+
import java.io.File
21+
import org.gradle.testkit.runner.GradleRunner
22+
import org.gradle.testkit.runner.TaskOutcome
23+
24+
class GradleTester(
25+
projectName: String,
26+
) {
27+
private val projectDir = File("src/test/projects/$projectName")
28+
29+
fun createRunner(vararg taskNames: String): GradleRunner {
30+
val gradleRoot = projectDir.resolve("gradle").also { it.mkdir() }
31+
File("../gradle/wrapper").copyRecursively(gradleRoot.resolve("wrapper"), true)
32+
File(projectDir, "kotlin-js-store/yarn.lock").delete()
33+
val arguments = arrayOf("--info", "--stacktrace", "--continue")
34+
return GradleRunner.create()
35+
.withProjectDir(projectDir)
36+
.withDebug(true) // Run in-process.
37+
.withArguments(*arguments, *taskNames, versionProperty)
38+
.forwardOutput()
39+
}
40+
41+
fun cleanAndBuild(vararg taskNames: String) {
42+
val result = createRunner("clean", *taskNames).build()
43+
for (taskName in taskNames) {
44+
assertThat(result.task(taskName)!!.outcome).isIn(TaskOutcome.SUCCESS, TaskOutcome.UP_TO_DATE)
45+
}
46+
}
47+
48+
fun readTestSuite(
49+
className: String,
50+
testTaskName: String = "test",
51+
): TestSuite = readTestSuite(testSuitePath(className, testTaskName))
52+
53+
fun hasTestSuite(
54+
className: String,
55+
testTaskName: String = "test",
56+
) = testSuitePath(className, testTaskName).exists()
57+
58+
private fun testSuitePath(
59+
className: String,
60+
testTaskName: String,
61+
) = projectDir.resolve("lib/build/test-results/$testTaskName/TEST-$className.xml")
62+
63+
private companion object {
64+
val versionProperty = "-PburstVersion=${System.getProperty("burstVersion")}"
65+
}
66+
}

0 commit comments

Comments
 (0)