chore(sonar): wire JaCoCo coverage and clear actionable smells
All checks were successful
PR Checks / android-build (pull_request) Successful in 10m44s
All checks were successful
PR Checks / android-build (pull_request) Successful in 10m44s
Fix the SonarQube coverage gate (0% on new code) — a reporting gap, not a testing gap: the JVM unit suite already exists but the source-only scan never received a coverage report. - app/build.gradle.kts: apply jacoco, enable debug unit-test coverage, add a jacocoTestReport task (excludes generated/Hilt/Compose-singleton classes) - sonar-project.properties: consume the JaCoCo XML; exclude pure-@Composable UI from coverage (JVM unit tests can't execute composable bodies) - .gitea/workflows/sonarqube.yml: run JDK 17 + Android SDK + `testDebugUnitTest jacocoTestReport` before the scan Also clear the three actionable code smells: remove an unused import (AdminContentScreen), remove an unused parameter (AdminSupportScreen. RespondDialog), and decompose LoginViewModel.submit() (cognitive complexity 20 -> under 15). The remaining 12 smells (snake_case DTO fields that mirror the JSON wire contract; Compose/nav complexity) are marked Won't Fix in SonarQube with rationale. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
This commit is contained in:
@@ -10,6 +10,11 @@ plugins {
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.hilt)
|
||||
jacoco
|
||||
}
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.12"
|
||||
}
|
||||
|
||||
// Release signing material (PLAN.md §12) is never committed. It is read from, in
|
||||
@@ -78,6 +83,11 @@ android {
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
// Produce a JaCoCo .exec from JVM unit tests so SonarQube receives real
|
||||
// coverage (§12.1). Debug-only: the scan analyses the debug variant.
|
||||
enableUnitTestCoverage = true
|
||||
}
|
||||
release {
|
||||
// R8 full-mode minify + resource shrink (§7: no offline cache, so a lean
|
||||
// release APK). Keep rules live in proguard-rules.pro.
|
||||
@@ -170,3 +180,35 @@ dependencies {
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
}
|
||||
|
||||
// JaCoCo XML coverage from the JVM unit tests, consumed by SonarQube (§12.1). Generated,
|
||||
// DI (Hilt), and Compose-scaffold classes are excluded so they don't dilute the number;
|
||||
// pure-@Composable UI is excluded on the Sonar side (sonar.coverage.exclusions) because
|
||||
// JVM unit tests can't execute composable bodies without Robolectric.
|
||||
tasks.register<JacocoReport>("jacocoTestReport") {
|
||||
dependsOn("testDebugUnitTest")
|
||||
group = "verification"
|
||||
description = "Generates JaCoCo XML/HTML coverage for the debug unit tests."
|
||||
|
||||
reports {
|
||||
xml.required.set(true)
|
||||
html.required.set(true)
|
||||
}
|
||||
|
||||
val coverageExcludes = listOf(
|
||||
"**/R.class", "**/R$*.class", "**/BuildConfig.*", "**/Manifest*.*",
|
||||
"**/*_Hilt*.*", "**/Hilt_*.*", "**/*_Factory*.*", "**/*_MembersInjector*.*",
|
||||
"**/*_Impl*.*", "**/di/**", "**/*Module.*", "**/*Module$*.*",
|
||||
"**/*ComposableSingletons*.*", "**/ComposableSingletons$*.*",
|
||||
)
|
||||
val buildDirFile = layout.buildDirectory.get().asFile
|
||||
classDirectories.setFrom(
|
||||
fileTree("$buildDirFile/tmp/kotlin-classes/debug") { exclude(coverageExcludes) },
|
||||
)
|
||||
sourceDirectories.setFrom(files("src/main/java", "src/main/kotlin"))
|
||||
executionData.setFrom(
|
||||
fileTree(buildDirFile) {
|
||||
include("outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user