diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index e0a074e5f7..71ca5d8b8c 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -224,9 +224,14 @@ version. `quartz/` is protocol-only — no composables. # Build Quartz for all targets ./gradlew :quartz:build -# Run tests +# Run tests (every module, including the KMP ones) ./gradlew test +# One module. KMP modules (quartz, commons, commonsUI, quic, nestsClient, +# marmotQuic) have no `test` task of their own - the root build registers an +# alias onto jvmTest, which is the task to name directly: +./gradlew :quartz:jvmTest --tests "com.vitorpamplona.quartz.nip52Calendar.*" + # Format code ./gradlew spotlessApply ``` diff --git a/.git-hooks/pre-push b/.git-hooks/pre-push index 5821e1d1d0..7faea9d18a 100755 --- a/.git-hooks/pre-push +++ b/.git-hooks/pre-push @@ -16,11 +16,21 @@ echo "Running test... " # variants of :amethyst (play/fdroid × debug/release/benchmark) plus full # native-libs merging per variant — ~6× the work of one variant. CI runs the # multi-flavor matrix on push to main; pre-push only needs one happy path. +# +# Every KMP module's tests live under :jvmTest - the Kotlin Multiplatform +# plugin registers no plain `test` task - so a module missing from this list is a +# module nobody runs before pushing. Add new KMP modules here when they gain tests. +# +# `./gradlew test` now reaches the KMP modules too (see the `test` alias in the root +# build), but this hook stays explicit: a bare `test` would also pull in :desktopApp:test, +# which needs a display server and is deliberately skipped on CLAUDE_CODE_REMOTE below. TASKS=( :quartz:jvmTest :commons:jvmTest + :commonsUI:jvmTest :nestsClient:jvmTest :quic:jvmTest + :marmotQuic:jvmTest :amethyst:testPlayDebugUnitTest :cli:test ) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7665ea2bb6..bc5c96b109 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,15 +102,16 @@ jobs: - name: Test + Build Desktop (gradle) run: | - CMD="./gradlew :quartz:jvmTest :commons:jvmTest :commonsUI:jvmTest :nestsClient:jvmTest :cli:test :desktopApp:test :desktopApp:${{ matrix.desktop-task }}" + CMD="./gradlew :quartz:jvmTest :commons:jvmTest :commonsUI:jvmTest :quic:jvmTest :nestsClient:jvmTest :marmotQuic:jvmTest :cli:test :desktopApp:test :desktopApp:${{ matrix.desktop-task }}" if [ "${{ runner.os }}" = "Linux" ]; then xvfb-run --auto-servernum $CMD else $CMD fi - # This job runs five test suites (:quartz, :commons, :nestsClient, :cli, - # :desktopApp) but, unlike test-geode / test-quartz-ios / + # This job runs the JVM test suites (:quartz, :commons, :commonsUI, :quic, + # :nestsClient, :marmotQuic, :cli, :desktopApp) but, unlike test-geode / + # test-quartz-ios / # test-and-build-android, published nothing when one of them failed. The # console line names the failing test and the exception class and stops # there, so the message is lost with the runner. That is how the diff --git a/build.gradle.kts b/build.gradle.kts index d3ea321ee8..5e687e3fe4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -91,6 +91,31 @@ allprojects { subprojects { afterEvaluate { + // The Kotlin Multiplatform plugin never registers a plain `test` task: it creates one + // task per target (jvmTest, androidUnitTest, linuxX64Test, ...) plus the `allTests` + // aggregate. A root `./gradlew test` therefore runs `test` only in the Java/Android + // modules that own one and *silently* skips every KMP module - Gradle only errors when + // no project at all has the task, and four of them do, so it exits 0 looking healthy. + // That hid ~8k tests (quartz, commons, commonsUI, quic, nestsClient, marmotQuic), which + // is most of this repo's suite. Register the alias so the documented command means what + // it says. + // + // It maps to jvmTest, not allTests, on purpose: allTests also drags in androidUnitTest + // and the native targets, half of which cannot run on a given host (macosArm64Test on + // Linux) and all of which change what `test` costs. jvmTest is exactly what the + // pre-push hook and CI already run for these modules, so the alias matches the coverage + // they expect rather than inventing a third definition of "the tests". + if (plugins.hasPlugin("org.jetbrains.kotlin.multiplatform") && + tasks.findByName("test") == null && + tasks.findByName("jvmTest") != null + ) { + tasks.register("test") { + group = "verification" + description = "Runs the JVM unit tests for this Kotlin Multiplatform module." + dependsOn("jvmTest") + } + } + try { tasks.named("preBuild") { dependsOn("spotlessApply")