Merge pull request #1782 from element-hq/feature/bma/upgradeKover
Upgrade kover
This commit is contained in:
commit
ae424ffe6a
12 changed files with 229 additions and 249 deletions
6
.github/renovate.json
vendored
6
.github/renovate.json
vendored
|
|
@ -18,12 +18,6 @@
|
||||||
],
|
],
|
||||||
"groupName" : "kotlin"
|
"groupName" : "kotlin"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"matchPackageNames" : [
|
|
||||||
"org.jetbrains.kotlinx.kover"
|
|
||||||
],
|
|
||||||
"enabled" : false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"matchPackagePatterns" : [
|
"matchPackagePatterns" : [
|
||||||
"^org.maplibre"
|
"^org.maplibre"
|
||||||
|
|
|
||||||
4
.github/workflows/nightlyReports.yml
vendored
4
.github/workflows/nightlyReports.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: 📈 Generate kover report and verify coverage
|
- name: 📈 Generate kover report and verify coverage
|
||||||
run: ./gradlew koverMergedReport koverMergedVerify $CI_GRADLE_ARG_PROPERTIES -Pci-build=true
|
run: ./gradlew :app:koverHtmlReport :app:koverXmlReport :app:koverVerify $CI_GRADLE_ARG_PROPERTIES -Pci-build=true
|
||||||
|
|
||||||
- name: ✅ Upload kover report
|
- name: ✅ Upload kover report
|
||||||
if: always()
|
if: always()
|
||||||
|
|
@ -41,7 +41,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: kover-results
|
name: kover-results
|
||||||
path: |
|
path: |
|
||||||
**/build/reports/kover/merged
|
**/build/reports/kover
|
||||||
|
|
||||||
- name: 🔊 Publish results to Sonar
|
- name: 🔊 Publish results to Sonar
|
||||||
env:
|
env:
|
||||||
|
|
|
||||||
6
.github/workflows/tests.yml
vendored
6
.github/workflows/tests.yml
vendored
|
|
@ -55,7 +55,7 @@ jobs:
|
||||||
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: 📈Generate kover report and verify coverage
|
- name: 📈Generate kover report and verify coverage
|
||||||
run: ./gradlew koverMergedReport koverMergedVerify $CI_GRADLE_ARG_PROPERTIES -Pci-build=true
|
run: ./gradlew :app:koverHtmlReport :app:koverXmlReport :app:koverVerify $CI_GRADLE_ARG_PROPERTIES -Pci-build=true
|
||||||
|
|
||||||
- name: 🚫 Upload kover failed coverage reports
|
- name: 🚫 Upload kover failed coverage reports
|
||||||
if: failure()
|
if: failure()
|
||||||
|
|
@ -63,7 +63,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: kover-error-report
|
name: kover-error-report
|
||||||
path: |
|
path: |
|
||||||
**/kover/merged/verification/errors.txt
|
app/build/reports/kover/verify.err
|
||||||
|
|
||||||
- name: ✅ Upload kover report (disabled)
|
- name: ✅ Upload kover report (disabled)
|
||||||
if: always()
|
if: always()
|
||||||
|
|
@ -83,4 +83,4 @@ jobs:
|
||||||
if: always()
|
if: always()
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
# with:
|
# with:
|
||||||
# files: build/reports/kover/merged/xml/report.xml
|
# files: build/reports/kover/xml/report.xml
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.android.build.api.variant.FilterConfiguration.FilterType.ABI
|
||||||
import extension.allFeaturesImpl
|
import extension.allFeaturesImpl
|
||||||
import extension.allLibrariesImpl
|
import extension.allLibrariesImpl
|
||||||
import extension.allServicesImpl
|
import extension.allServicesImpl
|
||||||
|
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.element.android-compose-application")
|
id("io.element.android-compose-application")
|
||||||
|
|
@ -190,6 +191,220 @@ knit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kover configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Add all sub projects to kover except some of them
|
||||||
|
project.rootProject.subprojects
|
||||||
|
.filter {
|
||||||
|
it.project.projectDir.resolve("build.gradle.kts").exists()
|
||||||
|
}
|
||||||
|
.map { it.path }
|
||||||
|
.sorted()
|
||||||
|
.filter {
|
||||||
|
it !in listOf(
|
||||||
|
":app",
|
||||||
|
":samples",
|
||||||
|
":anvilannotations",
|
||||||
|
":anvilcodegen",
|
||||||
|
":samples:minimal",
|
||||||
|
":tests:testutils",
|
||||||
|
// Exclude `:libraries:matrix:impl` module, it contains only wrappers to access the Rust Matrix
|
||||||
|
// SDK api, so it is not really relevant to unit test it: there is no logic to test.
|
||||||
|
":libraries:matrix:impl",
|
||||||
|
// Exclude modules which are not Android libraries
|
||||||
|
// See https://github.com/Kotlin/kotlinx-kover/issues/312
|
||||||
|
":appconfig",
|
||||||
|
":libraries:core",
|
||||||
|
":libraries:coroutines",
|
||||||
|
":libraries:di",
|
||||||
|
":libraries:rustsdk",
|
||||||
|
":libraries:textcomposer:lib",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.forEach {
|
||||||
|
// println("Add $it to kover")
|
||||||
|
kover(project(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val ciBuildProperty = "ci-build"
|
||||||
|
val isCiBuild = if (project.hasProperty(ciBuildProperty)) {
|
||||||
|
val raw = project.property(ciBuildProperty) as? String
|
||||||
|
raw?.toBooleanLenient() == true || raw?.toIntOrNull() == 1
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
kover {
|
||||||
|
// When running on the CI, run only debug test variants
|
||||||
|
if (isCiBuild) {
|
||||||
|
excludeTests {
|
||||||
|
// Disable instrumentation for debug test tasks
|
||||||
|
tasks(
|
||||||
|
"testDebugUnitTest",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://kotlin.github.io/kotlinx-kover/
|
||||||
|
// Run `./gradlew :app:koverHtmlReport` to get report at ./app/build/reports/kover
|
||||||
|
// Run `./gradlew :app:koverXmlReport` to get XML report
|
||||||
|
koverReport {
|
||||||
|
filters {
|
||||||
|
excludes {
|
||||||
|
classes(
|
||||||
|
// Exclude generated classes.
|
||||||
|
"*_ModuleKt",
|
||||||
|
"anvil.hint.binding.io.element.*",
|
||||||
|
"anvil.hint.merge.*",
|
||||||
|
"anvil.hint.multibinding.io.element.*",
|
||||||
|
"anvil.module.*",
|
||||||
|
"com.airbnb.android.showkase*",
|
||||||
|
"io.element.android.libraries.designsystem.showkase.*",
|
||||||
|
"io.element.android.x.di.DaggerAppComponent*",
|
||||||
|
"*_Factory",
|
||||||
|
"*_Factory_Impl",
|
||||||
|
"*_Factory$*",
|
||||||
|
"*_Module",
|
||||||
|
"*_Module$*",
|
||||||
|
"*Module_Provides*",
|
||||||
|
"Dagger*Component*",
|
||||||
|
"*ComposableSingletons$*",
|
||||||
|
"*_AssistedFactory_Impl*",
|
||||||
|
"*BuildConfig",
|
||||||
|
// Generated by Showkase
|
||||||
|
"*Ioelementandroid*PreviewKt$*",
|
||||||
|
"*Ioelementandroid*PreviewKt",
|
||||||
|
// Other
|
||||||
|
// We do not cover Nodes (normally covered by maestro, but code coverage is not computed with maestro)
|
||||||
|
"*Node",
|
||||||
|
"*Node$*",
|
||||||
|
"*Presenter\$present\$*",
|
||||||
|
// Forked from compose
|
||||||
|
"io.element.android.libraries.designsystem.theme.components.bottomsheet.*",
|
||||||
|
)
|
||||||
|
annotatedBy(
|
||||||
|
"io.element.android.libraries.designsystem.preview.PreviewsDayNight",
|
||||||
|
"io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults {
|
||||||
|
// add reports of both 'debug' and 'release' Android build variants to default reports
|
||||||
|
mergeWith("debug")
|
||||||
|
mergeWith("release")
|
||||||
|
|
||||||
|
verify {
|
||||||
|
onCheck = true
|
||||||
|
// General rule: minimum code coverage.
|
||||||
|
rule("Global minimum code coverage.") {
|
||||||
|
isEnabled = true
|
||||||
|
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.APPLICATION
|
||||||
|
bound {
|
||||||
|
minValue = 65
|
||||||
|
// Setting a max value, so that if coverage is bigger, it means that we have to change minValue.
|
||||||
|
// For instance if we have minValue = 20 and maxValue = 30, and current code coverage is now 31.32%, update
|
||||||
|
// minValue to 25 and maxValue to 35.
|
||||||
|
maxValue = 75
|
||||||
|
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
||||||
|
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rule to ensure that coverage of Presenters is sufficient.
|
||||||
|
rule("Check code coverage of presenters") {
|
||||||
|
isEnabled = true
|
||||||
|
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
||||||
|
filters {
|
||||||
|
includes {
|
||||||
|
classes(
|
||||||
|
"*Presenter",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
excludes {
|
||||||
|
classes(
|
||||||
|
"*Fake*Presenter",
|
||||||
|
"io.element.android.appnav.loggedin.LoggedInPresenter$*",
|
||||||
|
// Some options can't be tested at the moment
|
||||||
|
"io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*",
|
||||||
|
"*Presenter\$present\$*",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bound {
|
||||||
|
minValue = 85
|
||||||
|
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
||||||
|
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rule to ensure that coverage of States is sufficient.
|
||||||
|
rule("Check code coverage of states") {
|
||||||
|
isEnabled = true
|
||||||
|
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
||||||
|
filters {
|
||||||
|
includes {
|
||||||
|
classes(
|
||||||
|
"^*State$",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
excludes {
|
||||||
|
classes(
|
||||||
|
"io.element.android.appnav.root.RootNavState*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.OtherState$*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.EventSendState$*",
|
||||||
|
"io.element.android.libraries.matrix.api.room.RoomMembershipState*",
|
||||||
|
"io.element.android.libraries.matrix.api.room.MatrixRoomMembersState*",
|
||||||
|
"io.element.android.libraries.push.impl.notifications.NotificationState*",
|
||||||
|
"io.element.android.features.messages.impl.media.local.pdf.PdfViewerState",
|
||||||
|
"io.element.android.features.messages.impl.media.local.LocalMediaViewState",
|
||||||
|
"io.element.android.features.location.impl.map.MapState*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*",
|
||||||
|
"io.element.android.libraries.designsystem.swipe.SwipeableActionsState*",
|
||||||
|
"io.element.android.features.messages.impl.timeline.components.ExpandableState*",
|
||||||
|
"io.element.android.features.messages.impl.timeline.model.bubble.BubbleState*",
|
||||||
|
"io.element.android.libraries.maplibre.compose.CameraPositionState*",
|
||||||
|
"io.element.android.libraries.maplibre.compose.SaveableCameraPositionState",
|
||||||
|
"io.element.android.libraries.maplibre.compose.SymbolState*",
|
||||||
|
"io.element.android.features.ftue.api.state.*",
|
||||||
|
"io.element.android.features.ftue.impl.welcome.state.*",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bound {
|
||||||
|
minValue = 90
|
||||||
|
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
||||||
|
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rule to ensure that coverage of Views is sufficient (deactivated for now).
|
||||||
|
rule("Check code coverage of views") {
|
||||||
|
isEnabled = true
|
||||||
|
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
||||||
|
filters {
|
||||||
|
includes {
|
||||||
|
classes(
|
||||||
|
"*ViewKt",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bound {
|
||||||
|
// TODO Update this value, for now there are too many missing tests.
|
||||||
|
minValue = 0
|
||||||
|
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
||||||
|
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
androidReports("release") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
allLibrariesImpl()
|
allLibrariesImpl()
|
||||||
allServicesImpl()
|
allServicesImpl()
|
||||||
|
|
|
||||||
176
build.gradle.kts
176
build.gradle.kts
|
|
@ -1,7 +1,5 @@
|
||||||
import com.google.devtools.ksp.gradle.KspTask
|
import com.google.devtools.ksp.gradle.KspTask
|
||||||
import kotlinx.kover.api.KoverTaskExtension
|
|
||||||
import org.apache.tools.ant.taskdefs.optional.ReplaceRegExp
|
import org.apache.tools.ant.taskdefs.optional.ReplaceRegExp
|
||||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
@ -41,7 +39,7 @@ plugins {
|
||||||
alias(libs.plugins.ktlint)
|
alias(libs.plugins.ktlint)
|
||||||
alias(libs.plugins.dependencygraph)
|
alias(libs.plugins.dependencygraph)
|
||||||
alias(libs.plugins.sonarqube)
|
alias(libs.plugins.sonarqube)
|
||||||
alias(libs.plugins.kover)
|
alias(libs.plugins.kover) apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Delete>("clean").configure {
|
tasks.register<Delete>("clean").configure {
|
||||||
|
|
@ -164,177 +162,7 @@ allprojects {
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply(plugin = "kover")
|
apply(plugin = "org.jetbrains.kotlinx.kover")
|
||||||
}
|
|
||||||
|
|
||||||
// https://kotlin.github.io/kotlinx-kover/
|
|
||||||
// Run `./gradlew koverMergedHtmlReport` to get report at ./build/reports/kover
|
|
||||||
// Run `./gradlew koverMergedReport` to also get XML report
|
|
||||||
koverMerged {
|
|
||||||
enable()
|
|
||||||
|
|
||||||
filters {
|
|
||||||
classes {
|
|
||||||
excludes.addAll(
|
|
||||||
listOf(
|
|
||||||
// Exclude generated classes.
|
|
||||||
"*_ModuleKt",
|
|
||||||
"anvil.hint.binding.io.element.*",
|
|
||||||
"anvil.hint.merge.*",
|
|
||||||
"anvil.hint.multibinding.io.element.*",
|
|
||||||
"anvil.module.*",
|
|
||||||
"com.airbnb.android.showkase*",
|
|
||||||
"io.element.android.libraries.designsystem.showkase.*",
|
|
||||||
"io.element.android.x.di.DaggerAppComponent*",
|
|
||||||
"*_Factory",
|
|
||||||
"*_Factory_Impl",
|
|
||||||
"*_Factory$*",
|
|
||||||
"*_Module",
|
|
||||||
"*_Module$*",
|
|
||||||
"*Module_Provides*",
|
|
||||||
"Dagger*Component*",
|
|
||||||
"*ComposableSingletons$*",
|
|
||||||
"*_AssistedFactory_Impl*",
|
|
||||||
"*BuildConfig",
|
|
||||||
// Generated by Showkase
|
|
||||||
"*Ioelementandroid*PreviewKt$*",
|
|
||||||
"*Ioelementandroid*PreviewKt",
|
|
||||||
// Other
|
|
||||||
// We do not cover Nodes (normally covered by maestro, but code coverage is not computed with maestro)
|
|
||||||
"*Node",
|
|
||||||
"*Node$*",
|
|
||||||
// Exclude `:libraries:matrix:impl` module, it contains only wrappers to access the Rust Matrix SDK api, so it is not really relevant to unit test it: there is no logic to test.
|
|
||||||
"io.element.android.libraries.matrix.impl.*",
|
|
||||||
"*Presenter\$present\$*",
|
|
||||||
// Forked from compose
|
|
||||||
"io.element.android.libraries.designsystem.theme.components.bottomsheet.*",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
annotations {
|
|
||||||
excludes.addAll(
|
|
||||||
listOf(
|
|
||||||
"*Preview",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
projects {
|
|
||||||
excludes.addAll(
|
|
||||||
listOf(
|
|
||||||
":anvilannotations",
|
|
||||||
":anvilcodegen",
|
|
||||||
":samples:minimal",
|
|
||||||
":tests:testutils",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run ./gradlew koverMergedVerify to check the rules.
|
|
||||||
verify {
|
|
||||||
// Does not seems to work, so also run the task manually on the workflow.
|
|
||||||
onCheck.set(true)
|
|
||||||
// General rule: minimum code coverage.
|
|
||||||
rule {
|
|
||||||
name = "Global minimum code coverage."
|
|
||||||
target = kotlinx.kover.api.VerificationTarget.ALL
|
|
||||||
bound {
|
|
||||||
minValue = 65
|
|
||||||
// Setting a max value, so that if coverage is bigger, it means that we have to change minValue.
|
|
||||||
// For instance if we have minValue = 20 and maxValue = 30, and current code coverage is now 31.32%, update
|
|
||||||
// minValue to 25 and maxValue to 35.
|
|
||||||
maxValue = 75
|
|
||||||
counter = kotlinx.kover.api.CounterType.INSTRUCTION
|
|
||||||
valueType = kotlinx.kover.api.VerificationValueType.COVERED_PERCENTAGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rule to ensure that coverage of Presenters is sufficient.
|
|
||||||
rule {
|
|
||||||
name = "Check code coverage of presenters"
|
|
||||||
target = kotlinx.kover.api.VerificationTarget.CLASS
|
|
||||||
overrideClassFilter {
|
|
||||||
includes += "*Presenter"
|
|
||||||
excludes += "*Fake*Presenter"
|
|
||||||
excludes += "io.element.android.appnav.loggedin.LoggedInPresenter$*"
|
|
||||||
// Some options can't be tested at the moment
|
|
||||||
excludes += "io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*"
|
|
||||||
excludes += "*Presenter\$present\$*"
|
|
||||||
}
|
|
||||||
bound {
|
|
||||||
minValue = 85
|
|
||||||
counter = kotlinx.kover.api.CounterType.INSTRUCTION
|
|
||||||
valueType = kotlinx.kover.api.VerificationValueType.COVERED_PERCENTAGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rule to ensure that coverage of States is sufficient.
|
|
||||||
rule {
|
|
||||||
name = "Check code coverage of states"
|
|
||||||
target = kotlinx.kover.api.VerificationTarget.CLASS
|
|
||||||
overrideClassFilter {
|
|
||||||
includes += "^*State$"
|
|
||||||
excludes += "io.element.android.appnav.root.RootNavState*"
|
|
||||||
excludes += "io.element.android.libraries.matrix.api.timeline.item.event.OtherState$*"
|
|
||||||
excludes += "io.element.android.libraries.matrix.api.timeline.item.event.EventSendState$*"
|
|
||||||
excludes += "io.element.android.libraries.matrix.api.room.RoomMembershipState*"
|
|
||||||
excludes += "io.element.android.libraries.matrix.api.room.MatrixRoomMembersState*"
|
|
||||||
excludes += "io.element.android.libraries.push.impl.notifications.NotificationState*"
|
|
||||||
excludes += "io.element.android.features.messages.impl.media.local.pdf.PdfViewerState"
|
|
||||||
excludes += "io.element.android.features.messages.impl.media.local.LocalMediaViewState"
|
|
||||||
excludes += "io.element.android.features.location.impl.map.MapState*"
|
|
||||||
excludes += "io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*"
|
|
||||||
excludes += "io.element.android.libraries.designsystem.swipe.SwipeableActionsState*"
|
|
||||||
excludes += "io.element.android.features.messages.impl.timeline.components.ExpandableState*"
|
|
||||||
excludes += "io.element.android.features.messages.impl.timeline.model.bubble.BubbleState*"
|
|
||||||
excludes += "io.element.android.libraries.maplibre.compose.CameraPositionState*"
|
|
||||||
excludes += "io.element.android.libraries.maplibre.compose.SaveableCameraPositionState"
|
|
||||||
excludes += "io.element.android.libraries.maplibre.compose.SymbolState*"
|
|
||||||
excludes += "io.element.android.features.ftue.api.state.*"
|
|
||||||
excludes += "io.element.android.features.ftue.impl.welcome.state.*"
|
|
||||||
}
|
|
||||||
bound {
|
|
||||||
minValue = 90
|
|
||||||
counter = kotlinx.kover.api.CounterType.INSTRUCTION
|
|
||||||
valueType = kotlinx.kover.api.VerificationValueType.COVERED_PERCENTAGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rule to ensure that coverage of Views is sufficient (deactivated for now).
|
|
||||||
rule {
|
|
||||||
name = "Check code coverage of views"
|
|
||||||
target = kotlinx.kover.api.VerificationTarget.CLASS
|
|
||||||
overrideClassFilter {
|
|
||||||
includes += "*ViewKt"
|
|
||||||
}
|
|
||||||
bound {
|
|
||||||
// TODO Update this value, for now there are too many missing tests.
|
|
||||||
minValue = 0
|
|
||||||
counter = kotlinx.kover.api.CounterType.INSTRUCTION
|
|
||||||
valueType = kotlinx.kover.api.VerificationValueType.COVERED_PERCENTAGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When running on the CI, run only debug test variants
|
|
||||||
val ciBuildProperty = "ci-build"
|
|
||||||
val isCiBuild = if (project.hasProperty(ciBuildProperty)) {
|
|
||||||
val raw = project.property(ciBuildProperty) as? String
|
|
||||||
raw?.toBooleanLenient() == true || raw?.toIntOrNull() == 1
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
if (isCiBuild) {
|
|
||||||
allprojects {
|
|
||||||
afterEvaluate {
|
|
||||||
tasks.withType<Test>().configureEach {
|
|
||||||
extensions.configure<KoverTaskExtension> {
|
|
||||||
val enabled = name.contains("debug", ignoreCase = true)
|
|
||||||
isDisabled.set(!enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register quality check tasks.
|
// Register quality check tasks.
|
||||||
|
|
|
||||||
1
changelog.d/1782.misc
Normal file
1
changelog.d/1782.misc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Migrate to Kover 0.7.X
|
||||||
|
|
@ -344,26 +344,26 @@ implementation of our interfaces. Mocking can be used to mock Android framework
|
||||||
[kover](https://github.com/Kotlin/kotlinx-kover) is used to compute code coverage. Only have unit tests can produce code coverage result. Running Maestro does
|
[kover](https://github.com/Kotlin/kotlinx-kover) is used to compute code coverage. Only have unit tests can produce code coverage result. Running Maestro does
|
||||||
not participate to the code coverage results.
|
not participate to the code coverage results.
|
||||||
|
|
||||||
Kover configuration is defined in the main [build.gradle.kts](../build.gradle.kts) file.
|
Kover configuration is defined in the app [build.gradle.kts](../app/build.gradle.kts) file.
|
||||||
|
|
||||||
To compute the code coverage, run:
|
To compute the code coverage, run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew koverMergedReport
|
./gradlew :app:koverHtmlReport
|
||||||
```
|
```
|
||||||
|
|
||||||
and open the Html report: [../build/reports/kover/merged/html/index.html](../build/reports/kover/merged/html/index.html)
|
and open the Html report: [../app/build/reports/kover/html/index.html](../app/build/reports/kover/html/index.html)
|
||||||
|
|
||||||
To ensure that the code coverage threshold are OK, you can run
|
To ensure that the code coverage threshold are OK, you can run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./gradlew koverMergedVerify
|
./gradlew :app:koverVerify
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the CI performs this check on every pull requests.
|
Note that the CI performs this check on every pull requests.
|
||||||
|
|
||||||
Also, if the rule `Global minimum code coverage.` is in error because code coverage is `> maxValue`, `minValue` and `maxValue` can be updated for this rule in
|
Also, if the rule `Global minimum code coverage.` is in error because code coverage is `> maxValue`, `minValue` and `maxValue` can be updated for this rule in
|
||||||
the file [build.gradle.kts](../build.gradle.kts) (you will see further instructions there).
|
the file [build.gradle.kts](../app/build.gradle.kts) (you will see further instructions there).
|
||||||
|
|
||||||
### Other points
|
### Other points
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,6 @@ dependencies {
|
||||||
testImplementation(projects.libraries.mediapickers.test)
|
testImplementation(projects.libraries.mediapickers.test)
|
||||||
testImplementation(projects.libraries.permissions.test)
|
testImplementation(projects.libraries.permissions.test)
|
||||||
testImplementation(projects.libraries.preferences.test)
|
testImplementation(projects.libraries.preferences.test)
|
||||||
testImplementation(projects.libraries.textcomposer.test)
|
|
||||||
testImplementation(projects.libraries.voicerecorder.test)
|
testImplementation(projects.libraries.voicerecorder.test)
|
||||||
testImplementation(projects.libraries.mediaplayer.test)
|
testImplementation(projects.libraries.mediaplayer.test)
|
||||||
testImplementation(projects.libraries.mediaviewer.test)
|
testImplementation(projects.libraries.mediaviewer.test)
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12"
|
||||||
dependencycheck = "org.owasp.dependencycheck:9.0.8"
|
dependencycheck = "org.owasp.dependencycheck:9.0.8"
|
||||||
dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" }
|
dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" }
|
||||||
paparazzi = "app.cash.paparazzi:1.3.1"
|
paparazzi = "app.cash.paparazzi:1.3.1"
|
||||||
kover = "org.jetbrains.kotlinx.kover:0.6.1"
|
kover = "org.jetbrains.kotlinx.kover:0.7.5"
|
||||||
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
|
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
|
||||||
firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" }
|
firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" }
|
||||||
knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" }
|
knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" }
|
||||||
|
|
|
||||||
1
libraries/coroutines/.gitignore
vendored
1
libraries/coroutines/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
||||||
/build
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
plugins {
|
|
||||||
id("java-library")
|
|
||||||
alias(libs.plugins.kotlin.jvm)
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(libs.coroutines.core)
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("io.element.android-compose-library")
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "io.element.android.libraries.textcomposer.test"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
api(projects.libraries.textcomposer.impl)
|
|
||||||
implementation(projects.tests.testutils)
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue