Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for KMP/JVM targets #196

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
alias(libs.plugins.android.test) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.publicationsReport)
}

Expand Down
2 changes: 1 addition & 1 deletion demo-project/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ dependencies {
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.navigation.ui)

testImplementation(libs.junit)
testImplementation(libs.kotlin.test)
testImplementation(libs.robolectric)
}
7 changes: 6 additions & 1 deletion demo-project/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ plugins {

testAggregation {
modules {
include(projects.demoProject.app, projects.demoProject.domain, projects.demoProject.login)
include(
projects.demoProject.app,
projects.demoProject.domain,
projects.demoProject.login,
projects.demoProject.kmp,
)
exclude(rootProject)
}
coverage {
Expand Down
2 changes: 1 addition & 1 deletion demo-project/domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ plugins {
java.toolchain.languageVersion.set(JavaLanguageVersion.of(11))

dependencies {
testImplementation(libs.junit)
testImplementation(libs.kotlin.test)
}
34 changes: 34 additions & 0 deletions demo-project/kmp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension

plugins {
alias(libs.plugins.android.lib)
alias(libs.plugins.kotlin.multiplatform)
}

afterEvaluate {
rootProject.the<NodeJsRootExtension>().download = false
rootProject.the<YarnRootExtension>().download = false
}

java.toolchain.languageVersion.set(JavaLanguageVersion.of(11))

android {
namespace = "com.example.login"

compileSdk = libs.versions.android.compileSDK.get().toInt()
defaultConfig {
minSdk = libs.versions.android.minSDK.get().toInt()
}
}

kotlin {
androidTarget()
jvm()
js { nodejs() }
}

dependencies {
commonTestImplementation(libs.kotlin.test)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.kmp

object KMPObjectAndroid {

val platform = PLATFORM

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.example.kmp

internal actual val PLATFORM = "android"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.kmp

import kotlin.test.Test
import kotlin.test.assertEquals

class KMPObjectAndroidTest {

@Test
fun testKMPObject() {
assertEquals(PLATFORM, KMPObjectAndroid.platform)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.kmp

object KMPObject {

val platform = PLATFORM

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.example.kmp

internal expect val PLATFORM: String
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.kmp

import kotlin.test.Test
import kotlin.test.assertEquals

class KMPObjectTest {

@Test
fun testKMPObject() {
assertEquals(PLATFORM, KMPObject.platform)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.kmp

object KMPObjectJS {

val platform = PLATFORM

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.example.kmp

internal actual val PLATFORM = "js"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.kmp

import kotlin.test.Test
import kotlin.test.assertEquals

class KMPObjectJSTest {

@Test
fun testKMPObject() {
assertEquals(PLATFORM, KMPObjectJS.platform)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.kmp

object KMPObjectJVM {

val platform = PLATFORM

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.example.kmp

internal actual val PLATFORM = "jvm"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.kmp

import kotlin.test.Test
import kotlin.test.assertEquals

class KMPObjectJVMTest {

@Test
fun testKMPObject() {
assertEquals(PLATFORM, KMPObjectJVM.platform)
}

}
2 changes: 1 addition & 1 deletion demo-project/login/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ dependencies {
implementation(libs.androidx.livedata)
implementation(libs.androidx.viewmodel)

testImplementation(libs.junit)
testImplementation(libs.kotlin.test)

androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.androidx.test.espresso)
Expand Down
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ androidx-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", ve
androidx-test-junit = "androidx.test.ext:junit:1.2.1"
androidx-test-espresso = "androidx.test.espresso:espresso-core:3.6.1"
google-material = "com.google.android.material:material:1.12.0"
junit = "junit:junit:4.13.2"
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
robolectric = "org.robolectric:robolectric:4.14.1"

[plugins]
Expand All @@ -28,6 +28,7 @@ android-test = { id = "com.android.test", version.ref = "agp" }
android-baseline = { id = "androidx.baselineprofile", version = "1.3.3" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-samReceiver = { id = "org.jetbrains.kotlin.plugin.sam.with.receiver", version.ref = "kotlin" }
gradle-pluginPublish = { id = "com.gradle.plugin-publish", version = "1.3.0" }
publicationsReport = { id = "io.github.gmazzo.publications.report", version = "1.2.8" }
4 changes: 3 additions & 1 deletion plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ dependencies {

compileOnly(gradleKotlinDsl())
compileOnly(plugin(libs.plugins.android))
compileOnly(plugin(libs.plugins.kotlin.multiplatform))

testImplementation(gradleKotlinDsl())
testImplementation(plugin(libs.plugins.android))
testImplementation(plugin(libs.plugins.kotlin.multiplatform))
}

testing.suites.withType<JvmTestSuite>() {
testing.suites.withType<JvmTestSuite> {
useKotlinTest(libs.versions.kotlin)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

package io.github.gmazzo.android.test.aggregation

import com.android.build.api.dsl.BuildType
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Property
import org.gradle.kotlin.dsl.aggregateTestCoverage
import org.gradle.kotlin.dsl.apply
Expand All @@ -29,6 +31,13 @@ internal abstract class AndroidTestBaseAggregationPlugin : Plugin<Project> {
objects.property<Boolean>()
)
}
onKotlinJVMTargets {
(this as ExtensionAware).extensions.add(
typeOf<Property<Boolean>>(),
::aggregateTestCoverage.name,
objects.property<Boolean>()
)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ import org.gradle.api.attributes.VerificationType
import org.gradle.api.file.Directory
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.file.RegularFile
import org.gradle.api.internal.provider.Providers
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Sync
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.testing.AbstractTestTask
import org.gradle.kotlin.dsl.USAGE_TEST_AGGREGATION
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
Expand All @@ -31,7 +35,10 @@ import org.gradle.kotlin.dsl.property
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.registering
import org.gradle.kotlin.dsl.the
import org.gradle.kotlin.dsl.invoke
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME

abstract class AndroidTestCoverageAggregationPlugin : Plugin<Project> {

Expand All @@ -55,7 +62,7 @@ abstract class AndroidTestCoverageAggregationPlugin : Plugin<Project> {
})
}

configurations.create("codeCoverageExecutionData") {
val codeCoverageExecutionData by configurations.registering {
isCanBeConsumed = true
isCanBeResolved = false
isVisible = false
Expand All @@ -73,10 +80,7 @@ abstract class AndroidTestCoverageAggregationPlugin : Plugin<Project> {
}
afterEvaluate {
jacocoVariants.all variant@{
val execData = unitTestTaskOf(this@variant)!!
.map { it.the<JacocoTaskExtension>().destinationFile!! }

outgoing.artifact(execData) {
outgoing.artifact(unitTestTaskOf(this@variant)!!.execData) {
type = ArtifactTypeDefinition.BINARY_DATA_TYPE
}
}
Expand Down Expand Up @@ -154,6 +158,24 @@ abstract class AndroidTestCoverageAggregationPlugin : Plugin<Project> {
type = ArtifactTypeDefinition.JVM_CLASS_DIRECTORY
}
}

onKotlinJVMTargets variant@{
val main = compilations[MAIN_COMPILATION_NAME]

codeCoverageExecutionData.configure {
outgoing.artifact(unitTestTaskOf(this@variant).execData) {
type = ArtifactTypeDefinition.BINARY_DATA_TYPE
}
}
allVariantsSourcesForCoverageReport.configure {
main.allKotlinSourceSets.forAll {
from(it.kotlin.srcDirs)
}
}
allVariantsClassesForCoverageReport.configure {
from(main.output.classesDirs)
}
}
}

private fun Project.addRobolectricTestsSupport() {
Expand All @@ -178,4 +200,7 @@ abstract class AndroidTestCoverageAggregationPlugin : Plugin<Project> {
}
}

private val TaskProvider<AbstractTestTask>.execData
get() = map { it.the<JacocoTaskExtension>().destinationFile!! }

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package io.github.gmazzo.android.test.aggregation
import com.android.build.api.variant.HasUnitTest
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.attributes.Usage
import org.gradle.api.attributes.VerificationType
import org.gradle.kotlin.dsl.USAGE_TEST_AGGREGATION
import org.gradle.kotlin.dsl.aggregateTestCoverage
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.named

Expand Down Expand Up @@ -41,6 +43,14 @@ abstract class AndroidTestResultsAggregationPlugin : Plugin<Project> {
if (aggregate) listOf(unitTestTaskOf(variant)!!.flatMap { it.binaryResultsDirectory }) else emptyList()
})
}

onKotlinJVMTargets target@{
testResultsElements.outgoing.artifacts(provider {
val aggregate = [email protected](true)

if (aggregate) listOf(unitTestTaskOf(this@target).flatMap { it.binaryResultsDirectory }) else emptyList()
})
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ import org.gradle.kotlin.dsl.aggregateTestCoverage
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.withType
import org.gradle.kotlin.dsl.getByName
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.testAggregation
import org.gradle.kotlin.dsl.the
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainer
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget

internal val Project.android
get() = the<BaseExtension>()
Expand Down Expand Up @@ -62,4 +68,12 @@ private fun TestAggregationExtension.Modules.includes(project: Project) =

internal fun Project.unitTestTaskOf(variant: Variant) = (variant as? HasUnitTest)
?.unitTest
?.let { tasks.named<AbstractTestTask>("test${it.name.capitalized()}") }
?.let { tasks.named<AbstractTestTask>("test${it.name.replaceFirstChar { it.uppercase() }}") }

internal fun Project.unitTestTaskOf(target: KotlinTarget) =
tasks.named<AbstractTestTask>("${(target.disambiguationClassifier ?: target.name)}Test")

internal fun Project.onKotlinJVMTargets(action: KotlinJvmTarget.() -> Unit) = plugins.withId("kotlin-multiplatform") {
the<KotlinTargetsContainer>().targets
.withType<KotlinJvmTarget>(action)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.attributes.Usage
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.Property
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget

const val USAGE_TEST_AGGREGATION = "test-aggregation"

Expand All @@ -26,3 +28,6 @@ val BuildType.aggregateTestCoverage: Property<Boolean>

val ProductFlavor.aggregateTestCoverage: Property<Boolean>
get() = extensions.getByName<Property<Boolean>>(::aggregateTestCoverage.name)

val KotlinTarget.aggregateTestCoverage: Property<Boolean>
get() = (this as ExtensionAware).extensions.getByName<Property<Boolean>>(::aggregateTestCoverage.name)
Loading
Loading