Skip to content

fix: classify Gradle/KMP test source sets as test zone for Kotlin - #677

Open
tallclouds wants to merge 1 commit into
peteromallet:mainfrom
tallclouds:fix/kotlin-gradle-test-zones
Open

fix: classify Gradle/KMP test source sets as test zone for Kotlin#677
tallclouds wants to merge 1 commit into
peteromallet:mainfrom
tallclouds:fix/kotlin-gradle-test-zones

Conversation

@tallclouds

Copy link
Copy Markdown

Problem

The Kotlin plugin passes no zone_rules, so it falls back to COMMON_ZONE_RULES, whose test rule is:

ZoneRule(Zone.TEST, ["/tests/", "/test/", "/fixtures/"]),

Kotlin projects aren't laid out that way. Gradle organises by source set, and Kotlin Multiplatform names every test source set <target>Test:

shared/src/commonTest/kotlin/com/example/FormEngineTest.kt
sync/src/jvmTest/kotlin/com/example/SubmissionStoreTest.kt
composeApp/src/androidUnitTest/kotlin/com/example/RendererTest.kt

None of these contain a /test/ segment, so every test file is classified as production. On the KMP project I was scanning:

zone_distribution: {"production": 241}     # literally every file

Two concrete consequences:

  • 64 test files reported as orphaned — "zero importers, not an entry point". A test file has no importers by definition; the test runner is its entry point. This was 28% of the orphaned findings.
  • Hardcoded test credentials raised as production security findings — 6 of the 7 security findings were stub tokens in *Test.kt / live-validation harnesses.

Plain Gradle JVM/Android layouts (src/test/java) happen to work by accident, since they contain /test/. src/androidTest/ and src/testFixtures/ do not.

Fix

Adds desloppify/languages/kotlin/_zones.py and wires it in via zone_rules=KOTLIN_ZONE_RULES:

  • TEST: /src/test/, /src/androidTest/, /src/testFixtures/, and the KMP source-set suffixes Test/kotlin/, Test/java/, Test/resources/ — which cover commonTest, jvmTest, iosTest, androidUnitTest, nativeTest, and any other <target>Test.
  • CONFIG: build.gradle.kts, settings.gradle.kts, gradle.properties, gradle/libs.versions.toml.
  • Common rules still apply after these.

The suffix form (Test/kotlin/ rather than Test/) is deliberate: it requires the source-set directory shape, so a production package that merely ends in "Test" isn't swept up.

Verification

  • New tests in desloppify/tests/lang/common/test_kotlin_zones.py (18 cases: KMP + Gradle test source sets classify as TEST, *Main source sets stay PRODUCTION, build scripts classify as CONFIG).
  • Full suite: 5834 passed, 4 skipped.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PCWKUYMUFfgPFW9brzaPVn

The Kotlin plugin declared no zone_rules, so it fell back to the common rules,
which look for a '/test/' or '/tests/' path segment. Kotlin projects are laid out
by Gradle source set instead, and Kotlin Multiplatform names every test source set
'<target>Test':

  shared/src/commonTest/kotlin/...
  sync/src/jvmTest/kotlin/...
  composeApp/src/androidUnitTest/kotlin/...

None contain '/test/', so every test file was zoned production. On a KMP project
that put all 241 files in the production zone, with 64 test files reported as
orphaned (a test file has no importers by definition) and hardcoded test
credentials raised as production security findings.

Adds desloppify/languages/kotlin/_zones.py covering KMP and plain Gradle/Android
test source sets, marking Gradle build scripts as config, and wires it into the
plugin via zone_rules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant