[Gradle][KT-53342] Implement MultiplatformAndroidSourceSetLayoutV2Test
This commit is contained in:
committed by
Space
parent
e307b96671
commit
f68c05c1fb
+1
-1
@@ -113,6 +113,6 @@ fun Project.enableDefaultStdlibDependency(enabled: Boolean = true) {
|
||||
project.propertiesExtension.set(KOTLIN_STDLIB_DEFAULT_DEPENDENCY, enabled.toString())
|
||||
}
|
||||
|
||||
fun Project.setAndroidMultiplatformSourceSetLayoutVersion(version: Int) {
|
||||
fun Project.setMultiplatformAndroidSourceSetLayoutVersion(version: Int) {
|
||||
project.propertiesExtension.set(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION, version.toString())
|
||||
}
|
||||
+6
-6
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.android.kotlinAndroidSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV1
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.multiplatformAndroidSourceSetLayoutV2
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.singleTargetAndroidSourceSetLayout
|
||||
import org.jetbrains.kotlin.gradle.setAndroidMultiplatformSourceSetLayoutVersion
|
||||
import org.jetbrains.kotlin.gradle.setMultiplatformAndroidSourceSetLayoutVersion
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
@@ -27,10 +27,10 @@ class KotlinAndroidSourceSetLayoutExtensionTest {
|
||||
project.plugins.apply(KotlinAndroidPluginWrapper::class.java)
|
||||
assertEquals(singleTargetAndroidSourceSetLayout, project.kotlinAndroidSourceSetLayout)
|
||||
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(1)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(1)
|
||||
assertEquals(singleTargetAndroidSourceSetLayout, project.kotlinAndroidSourceSetLayout)
|
||||
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(2)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(2)
|
||||
assertEquals(singleTargetAndroidSourceSetLayout, project.kotlinAndroidSourceSetLayout)
|
||||
}
|
||||
|
||||
@@ -43,14 +43,14 @@ class KotlinAndroidSourceSetLayoutExtensionTest {
|
||||
"Expected v1 being set as default"
|
||||
)
|
||||
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(2)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(2)
|
||||
assertEquals(multiplatformAndroidSourceSetLayoutV2, project.kotlinAndroidSourceSetLayout)
|
||||
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(1)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(1)
|
||||
assertEquals(multiplatformAndroidSourceSetLayoutV1, project.kotlinAndroidSourceSetLayout)
|
||||
|
||||
/* Test unhappy path: Layout version 0 is unknown/unsupported */
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(0)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(0)
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
project.kotlinAndroidSourceSetLayout
|
||||
}
|
||||
|
||||
+4
-17
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.findKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.setAndroidMultiplatformSourceSetLayoutVersion
|
||||
import org.jetbrains.kotlin.gradle.setMultiplatformAndroidSourceSetLayoutVersion
|
||||
import kotlin.test.*
|
||||
|
||||
class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
@@ -31,7 +31,7 @@ class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
fun setup() {
|
||||
project = ProjectBuilder.builder().build() as ProjectInternal
|
||||
addBuildEventsListenerRegistryMock(project)
|
||||
project.setAndroidMultiplatformSourceSetLayoutVersion(1)
|
||||
project.setMultiplatformAndroidSourceSetLayoutVersion(1)
|
||||
|
||||
project.plugins.apply("kotlin-multiplatform")
|
||||
project.plugins.apply("android-library")
|
||||
@@ -141,7 +141,7 @@ class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
kotlin.android()
|
||||
project.evaluate()
|
||||
|
||||
kotlin.sourceSets.toSet().allPairs()
|
||||
kotlin.sourceSets.toSet().generatePairs()
|
||||
.forEach { (sourceSetA, sourceSetB) ->
|
||||
val sourceDirsInBothSourceSets = sourceSetA.kotlin.srcDirs.intersect(sourceSetB.kotlin.srcDirs)
|
||||
assertTrue(
|
||||
@@ -151,7 +151,7 @@ class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
)
|
||||
}
|
||||
|
||||
android.sourceSets.toSet().allPairs()
|
||||
android.sourceSets.toSet().generatePairs()
|
||||
.forEach { (sourceSetA, sourceSetB) ->
|
||||
val sourceDirsInBothSourceSets = sourceSetA.java.srcDirs.intersect(sourceSetB.java.srcDirs)
|
||||
assertTrue(
|
||||
@@ -200,16 +200,3 @@ class MultiplatformAndroidSourceSetLayoutV1Test {
|
||||
private val AndroidSourceSet.kotlinSourceSet
|
||||
get() = project.findKotlinSourceSet(this) ?: fail("Missing KotlinSourceSet for AndroidSourceSet: $name")
|
||||
}
|
||||
|
||||
private fun <T> Set<T>.allPairs(): Sequence<Pair<T, T>> {
|
||||
val values = this.toList()
|
||||
return sequence {
|
||||
for (index in values.indices) {
|
||||
val first = values[index]
|
||||
for (remainingIndex in (index + 1)..values.lastIndex) {
|
||||
val second = values[remainingIndex]
|
||||
yield(first to second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("FunctionName", "DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.sources.android
|
||||
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import com.android.build.gradle.LibraryPlugin
|
||||
import com.android.builder.model.SourceProvider
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.jetbrains.kotlin.gradle.applyMultiplatformPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.forEachVariant
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.androidTest
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.main
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.test
|
||||
import org.jetbrains.kotlin.gradle.setMultiplatformAndroidSourceSetLayoutVersion
|
||||
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class MultiplatformAndroidSourceSetLayoutV2Test {
|
||||
|
||||
private val project = ProjectBuilder.builder().build()
|
||||
.run { this as ProjectInternal }
|
||||
.also { project -> project.setMultiplatformAndroidSourceSetLayoutVersion(2) }
|
||||
|
||||
private val kotlin = project.applyMultiplatformPlugin()
|
||||
|
||||
private val android: LibraryExtension = run {
|
||||
project.plugins.apply(LibraryPlugin::class.java)
|
||||
project.androidExtension as LibraryExtension
|
||||
}
|
||||
|
||||
init {
|
||||
android.compileSdk = 31
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - main SourceSet - is called 'androidMain'`() {
|
||||
kotlin.android()
|
||||
assertEquals("androidMain", project.getKotlinSourceSetOrFail(android.sourceSets.main).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - main SourceSet name - with custom targetName`() {
|
||||
kotlin.android("foo")
|
||||
assertEquals("fooMain", project.getKotlinSourceSetOrFail(android.sourceSets.main).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - unitTest SourceSet - is called 'androidUnitTest'`() {
|
||||
kotlin.android()
|
||||
assertEquals("androidUnitTest", project.getKotlinSourceSetOrFail(android.sourceSets.test).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - unitTest SourceSet name - with custom targetName`() {
|
||||
kotlin.android("foo")
|
||||
assertEquals("fooUnitTest", project.getKotlinSourceSetOrFail(android.sourceSets.test).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - instrumentedTest SourceSet - is called 'androidInstrumentedTest'`() {
|
||||
kotlin.android()
|
||||
assertEquals("androidInstrumentedTest", project.getKotlinSourceSetOrFail(android.sourceSets.androidTest).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test instrumentedTest SourceSet - with custom targetName`() {
|
||||
kotlin.android("foo")
|
||||
assertEquals("fooInstrumentedTest", project.getKotlinSourceSetOrFail(android.sourceSets.androidTest).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test SourceSet names - with two flavorDimensions`() {
|
||||
kotlin.android()
|
||||
android.flavorDimensions.add("market")
|
||||
android.flavorDimensions.add("price")
|
||||
android.productFlavors.create("german").dimension = "market"
|
||||
android.productFlavors.create("usa").dimension = "market"
|
||||
android.productFlavors.create("paid").dimension = "price"
|
||||
android.productFlavors.create("free").dimension = "price"
|
||||
|
||||
project.evaluate()
|
||||
|
||||
fun assertKotlinSourceSetNameEquals(
|
||||
androidSourceSetName: String, kotlinSourceSetName: String
|
||||
) {
|
||||
val androidSourceSet = android.sourceSets.getByName(androidSourceSetName)
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(
|
||||
kotlinSourceSetName, kotlinSourceSet.name,
|
||||
"Expected KotlinSourceSet name: $kotlinSourceSetName for AndroidSourceSet name: $androidSourceSetName"
|
||||
)
|
||||
}
|
||||
|
||||
assertKotlinSourceSetNameEquals("germanPaidDebug", "androidGermanPaidDebug")
|
||||
assertKotlinSourceSetNameEquals("germanPaid", "androidGermanPaid")
|
||||
assertKotlinSourceSetNameEquals("german", "androidGerman")
|
||||
|
||||
assertKotlinSourceSetNameEquals("testGermanPaidDebug", "androidUnitTestGermanPaidDebug")
|
||||
assertKotlinSourceSetNameEquals("testGermanPaid", "androidUnitTestGermanPaid")
|
||||
assertKotlinSourceSetNameEquals("testGerman", "androidUnitTestGerman")
|
||||
|
||||
assertKotlinSourceSetNameEquals("androidTestGermanPaidDebug", "androidInstrumentedTestGermanPaidDebug")
|
||||
assertKotlinSourceSetNameEquals("androidTestGermanPaid", "androidInstrumentedTestGermanPaid")
|
||||
assertKotlinSourceSetNameEquals("androidTestGerman", "androidInstrumentedTestGerman")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - all source directories - are disjoint in source sets`() {
|
||||
kotlin.android()
|
||||
android.flavorDimensions.add("market")
|
||||
android.flavorDimensions.add("price")
|
||||
android.productFlavors.create("german").dimension = "market"
|
||||
android.productFlavors.create("usa").dimension = "market"
|
||||
android.productFlavors.create("paid").dimension = "price"
|
||||
android.productFlavors.create("free").dimension = "price"
|
||||
|
||||
project.evaluate()
|
||||
|
||||
kotlin.sourceSets.toSet().generatePairs()
|
||||
.forEach { (sourceSetA, sourceSetB) ->
|
||||
val sourceDirsInBothSourceSets = sourceSetA.kotlin.srcDirs.intersect(sourceSetB.kotlin.srcDirs)
|
||||
assertTrue(
|
||||
sourceDirsInBothSourceSets.isEmpty(),
|
||||
"Expected disjoint source directories in source sets. " +
|
||||
"Found $sourceDirsInBothSourceSets present in ${sourceSetA.name}(Kotlin) and ${sourceSetB.name}(Kotlin)"
|
||||
)
|
||||
}
|
||||
|
||||
android.sourceSets.toSet().generatePairs()
|
||||
.forEach { (sourceSetA, sourceSetB) ->
|
||||
val sourceDirsInBothSourceSets = sourceSetA.java.srcDirs.intersect(sourceSetB.java.srcDirs)
|
||||
assertTrue(
|
||||
sourceDirsInBothSourceSets.isEmpty(),
|
||||
"Expected disjoint source directories in source sets. " +
|
||||
"Found $sourceDirsInBothSourceSets present in ${sourceSetA.name}(Android) and ${sourceSetB.name}(Android)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - default dependsOn edges`() {
|
||||
kotlin.android()
|
||||
project.evaluate()
|
||||
|
||||
android.libraryVariants.all { libraryVariant ->
|
||||
libraryVariant.sourceSets.forEach { androidSourceSet ->
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(
|
||||
setOf("commonMain"), kotlinSourceSet.dependsOn.map { it.name }.toSet(),
|
||||
"Expected KotlinSourceSet: ${kotlinSourceSet.name} to dependsOn commonMain"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
android.unitTestVariants.all { libraryVariant ->
|
||||
libraryVariant.sourceSets.forEach { androidSourceSet ->
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(
|
||||
setOf("commonTest"), kotlinSourceSet.dependsOn.map { it.name }.toSet(),
|
||||
"Expected KotlinSourceSet: ${kotlinSourceSet.name} to dependsOn commonTest"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
android.testVariants.all { libraryVariant ->
|
||||
libraryVariant.sourceSets.forEach { androidSourceSet ->
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(
|
||||
emptySet(), kotlinSourceSet.dependsOn.map { it.name }.toSet(),
|
||||
"Expected KotlinSourceSet: ${kotlinSourceSet.name} to have no dependsOn edges"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - kotlin source directories - are in sync between KotlinSourceSet and AndroidSourceSet`() {
|
||||
kotlin.android()
|
||||
|
||||
forEachVariant(project) { variant ->
|
||||
variant.sourceSets.forEach { androidSourceSet ->
|
||||
androidSourceSet as SourceProvider
|
||||
|
||||
/* Check if KotlinSourceSet and AndroidSourceSet contain the same srcDirs */
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(
|
||||
androidSourceSet.kotlinDirectories.toSet(), kotlinSourceSet.kotlin.srcDirs,
|
||||
"Expected same kotlin srcDirs for KotlinSourceSet: ${kotlinSourceSet.name} " +
|
||||
"and AndroidSourceSet: ${androidSourceSet.name}"
|
||||
)
|
||||
|
||||
|
||||
/* Check if androidSourceSet.kotlinDirectories is live and includes sources from Kotlin */
|
||||
val adhocSrcDir = project.file("src/${kotlinSourceSet.name}/adhoc/${variant.name}")
|
||||
assertFalse(adhocSrcDir in androidSourceSet.kotlinDirectories)
|
||||
kotlinSourceSet.kotlin.srcDir(adhocSrcDir)
|
||||
assertTrue(adhocSrcDir in androidSourceSet.kotlinDirectories)
|
||||
}
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - kotlin source directories - supports AGP default location`() {
|
||||
kotlin.android()
|
||||
|
||||
forEachVariant(project) { variant ->
|
||||
variant.sourceSets.forEach { androidSourceSet ->
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertTrue(
|
||||
project.file("src/${androidSourceSet.name}/kotlin") in kotlinSourceSet.kotlin.srcDirs,
|
||||
"Expected 'src/${androidSourceSet.name}/kotlin to be supported by KotlinSourceSet: ${kotlinSourceSet.name}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - main - default AndroidManifest location`() {
|
||||
kotlin.android()
|
||||
|
||||
assertEquals(
|
||||
project.file("src/androidMain/AndroidManifest.xml"),
|
||||
android.sourceSets.main.manifest.srcFile,
|
||||
"Expected default AndroidManifest to be placed in 'androidMain'"
|
||||
)
|
||||
|
||||
|
||||
/* Check if default can be overwritten */
|
||||
android.sourceSets.main.manifest.srcFile(project.file("custom.xml"))
|
||||
project.evaluate()
|
||||
assertEquals(project.file("custom.xml"), android.sourceSets.main.manifest.srcFile)
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -37,7 +37,7 @@ class SingleTargetAndroidSourceSetLayoutTest {
|
||||
|
||||
@Test
|
||||
fun `test - default configuration - AndroidSourceSet has associated KotlinSourceSet`() {
|
||||
android.sourceSets.all { androidSourceSet -> project.assertSingleKotlinSourceSet(androidSourceSet) }
|
||||
android.sourceSets.all { androidSourceSet -> project.getKotlinSourceSetOrFail(androidSourceSet) }
|
||||
project.evaluate()
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class SingleTargetAndroidSourceSetLayoutTest {
|
||||
fun `test - default configuration - AndroidSourceSet has KotlinSourceSet as convention`() {
|
||||
android.sourceSets.all { androidSourceSet ->
|
||||
assertSame(
|
||||
project.assertSingleKotlinSourceSet(androidSourceSet),
|
||||
project.getKotlinSourceSetOrFail(androidSourceSet),
|
||||
(androidSourceSet as org.gradle.api.internal.HasConvention).convention.plugins["kotlin"] as? KotlinSourceSet,
|
||||
"Expected Convention 'kotlin' on AndroidSourceSet: ${androidSourceSet.name}"
|
||||
)
|
||||
@@ -66,7 +66,7 @@ class SingleTargetAndroidSourceSetLayoutTest {
|
||||
}
|
||||
|
||||
android.sourceSets.all { androidSourceSet ->
|
||||
val kotlinSourceSet = project.assertSingleKotlinSourceSet(androidSourceSet)
|
||||
val kotlinSourceSet = project.getKotlinSourceSetOrFail(androidSourceSet)
|
||||
assertEquals(androidSourceSet.name, kotlinSourceSet.name)
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.sources.android
|
||||
|
||||
fun <T> Set<T>.generatePairs(): Sequence<Pair<T, T>> {
|
||||
val values = this.toList()
|
||||
return sequence {
|
||||
for (index in values.indices) {
|
||||
val first = values[index]
|
||||
for (remainingIndex in (index + 1)..values.lastIndex) {
|
||||
val second = values[remainingIndex]
|
||||
yield(first to second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -8,13 +8,15 @@
|
||||
package org.jetbrains.kotlin.gradle.sources.android
|
||||
|
||||
import com.android.build.gradle.api.AndroidSourceSet
|
||||
import com.android.builder.model.SourceProvider
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.androidSourceSetInfoOrNull
|
||||
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
||||
import kotlin.test.fail
|
||||
|
||||
fun Project.assertSingleKotlinSourceSet(androidSourceSet: AndroidSourceSet): KotlinSourceSet {
|
||||
fun Project.getKotlinSourceSetOrFail(androidSourceSet: AndroidSourceSet): KotlinSourceSet {
|
||||
val kotlinSourceSets = kotlinExtension.sourceSets
|
||||
.filter { kotlinSourceSet -> kotlinSourceSet.androidSourceSetInfoOrNull?.androidSourceSetName == androidSourceSet.name }
|
||||
|
||||
@@ -30,4 +32,8 @@ fun Project.assertSingleKotlinSourceSet(androidSourceSet: AndroidSourceSet): Kot
|
||||
}
|
||||
|
||||
return kotlinSourceSets.single()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.getKotlinSourceSetOrFail(androidSourceSet: SourceProvider): KotlinSourceSet {
|
||||
return getKotlinSourceSetOrFail(androidExtension.sourceSets.getByName(androidSourceSet.name))
|
||||
}
|
||||
Reference in New Issue
Block a user