Skip to content

1.7.1: build modernization, Kover coverage gate, Job-returning async API#8

Merged
projectdelta6 merged 3 commits into
masterfrom
release/1.7.1
Jun 4, 2026
Merged

1.7.1: build modernization, Kover coverage gate, Job-returning async API#8
projectdelta6 merged 3 commits into
masterfrom
release/1.7.1

Conversation

@projectdelta6

Copy link
Copy Markdown
Owner

Release prep for 1.7.1. Three commits — build/tooling modernization, a real CI coverage gate, and a small library API addition. Validated locally: 174 tests pass, koverVerifyDebug green at 82.6% line coverage (floor 70).

Build & tooling

  • libs.versions.toml now uses version.ref consistently (all versions declared at the top)
  • Migrate to AGP 9 new DSL: configure<ApplicationExtension> / <LibraryExtension>, kotlin {} moved to top level
  • Drop deprecated gradle.properties flags now defaulted in AGP 9 (newDsl, resvalues, enableAppCompileTimeRClass, usesSdkInManifest.disallowed, r8.optimizedResourceShrinking, sdk.defaultTargetSdkToCompileSdkIfUnset)
  • Gradle wrapper 9.4.1 → 9.5.0

Library

  • BaseDataStoreHelper.writeXxxAsync (+ removeKeyAsync / writeValueAsync) now return the Job so callers can .join() to await fire-and-forget writes. Delegate setters still discard it (property setters return Unit).
  • Use the kotlin.time Duration API for withTimeoutOrNull

Tests & coverage

  • Add Kover, scoped to com.duck.prefshelper.*, aggregated into :app (where the tests live), with a koverVerify floor of minBound(70)
  • Migrate BaseDataStoreHelperTest to the JVM under Robolectric (androidTest → test). Kover can't instrument on-device tests, so this is what makes the coverage gate meaningful — and it drops the emulator requirement entirely. Robolectric SDK pinned to 36 (targetSdk 37 has no image yet).
  • Backfill property-delegate coverage on both helpers (long/boolean/double/date/temporal/nullable variants + enum) and *WithDefault read coverage
  • Replace racy fixed delays with deterministic awaits (.join() for direct async writes; awaitValue polling for delegate writes)

CI / merge gate

  • .github/workflows/ci.ymlTests & coverage gate job runs :app:testDebugUnitTest :app:koverXmlReportDebug :app:koverVerifyDebug on a plain ubuntu-latest runner (no emulator), on PRs to master and pushes to master
  • master branch protection now requires this check to pass before merge

Docs

  • CLAUDE.md: corrected test/coverage commands (all JVM now), added a gotcha explaining the Robolectric/Kover rationale
  • README.md reviewed — still accurate (delegate-first), no changes needed

🤖 Generated with Claude Code

projectdelta6 and others added 3 commits June 4, 2026 12:13
…est coverage

Build & tooling
- Make gradle/libs.versions.toml use version.ref consistently (all versions
  declared at the top)
- Migrate to AGP 9 new DSL: configure<ApplicationExtension>/<LibraryExtension>
  and move the kotlin {} block to top level
- Drop deprecated gradle.properties flags now defaulted in AGP 9
  (newDsl, resvalues, enableAppCompileTimeRClass, usesSdkInManifest.disallowed,
  r8.optimizedResourceShrinking, sdk.defaultTargetSdkToCompileSdkIfUnset)
- Bump Gradle wrapper 9.4.1 -> 9.5.0

Coverage
- Add Kover, aggregating :PrefsHelper into :app (where the tests live), with a
  report filter focusing the metric on the library

Library
- BaseDataStoreHelper.writeXxxAsync (+ removeKeyAsync / writeValueAsync) now
  return the Job so callers can join() to await fire-and-forget writes
- Use the kotlin.time Duration API for withTimeoutOrNull

Tests
- Backfill property-delegate coverage on both helpers (long/boolean/double/date/
  temporal/nullable string + enum) and *WithDefault read coverage on DataStore
- Replace racy fixed delays with deterministic awaits (join() for direct async
  writes, value/flow polling for delegate writes)
- Duration API for delay/withTimeout, joinAll() for concurrent writes

Docs
- Fix CLAUDE.md test commands to target :app and document the Kover report

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…overage gate

Kover can't instrument on-device tests, so the instrumented BaseDataStoreHelperTest
contributed ~0% to coverage — making an aggregate koverVerify floor impossible.
Move it to the JVM under Robolectric so Kover measures both helpers.

- Move BaseDataStoreHelperTest androidTest -> test; it runs under Robolectric via
  the AndroidJUnit4 delegating runner (no test changes needed). No emulator now.
- Pin Robolectric SDK to 36 (targetSdk 37 has no image yet) via robolectric.properties
- app: enable unitTests.isIncludeAndroidResources, add Robolectric + ext-junit as
  testImplementation, drop the now-dead androidTest/compose-test deps, and revert the
  pointless enableAndroidTestCoverage flag
- Add Kover coverage floor: reports.verify minBound(70), scoped to com.duck.prefshelper.*
  (the sample app's consumer prefs aren't the code under test)
- Make the flow-emits tests deterministic: confirm the write landed via awaitValue,
  then assert the flow's emission, instead of a racy withTimeout(flow.first{})
- Remove orphaned compose-ui-test-* catalog entries
- CI: .github/workflows/ci.yml runs :app:testDebugUnitTest + koverVerifyDebug on a
  plain ubuntu runner (no emulator) on PRs to master and pushes to master
- Docs: update CLAUDE.md test/coverage commands and add a gotcha explaining the
  Robolectric/Kover rationale

Verified locally: 166/166 tests pass, koverVerifyDebug green at 76.5% line coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cover the nullable longPref/doublePref/booleanPref/enumPref delegate overloads on
BaseDataStoreHelper, which had no test exercising them (the harness only declared the
non-null variants). Each: round-trip + null-removal, asserted via awaitValue.

Library line coverage 76.5% -> 82.6% (koverVerifyDebug floor remains 70).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@projectdelta6 projectdelta6 merged commit 7b7673f into master Jun 4, 2026
1 check passed
@projectdelta6 projectdelta6 deleted the release/1.7.1 branch June 4, 2026 12:51
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