Skip to content

test#4

Merged
yet300 merged 5 commits into
mainfrom
test
May 13, 2026
Merged

test#4
yet300 merged 5 commits into
mainfrom
test

Conversation

@yet300
Copy link
Copy Markdown
Owner

@yet300 yet300 commented May 13, 2026

Summary

  • Audit + 165 unit tests across core:domain, core:data, core:common,
    feature:{home, settings, game, root} — every test green on
    iosSimulatorArm64Test.
  • Extracted Firebase telemetry into a new core:telemetry module so
    core:data no longer pulls Firebase into iOS test linking. TelemetryBindings
    is wired into both AndroidAppGraph and NativeAppGraph, so runtime DI
    is unchanged.
  • Moved the pure formatScore utility to core:common so it's reachable from
    shared test sources.
  • New CI workflow runs ./gradlew allTests on macOS PRs and a Linux
    assembleDebug smoke check; the existing release pipeline is untouched.

What's covered

Layer Module Tests
Pure logic core:common (FormatScore) 7
Pure logic core:domain (Score, Grid, ShapeGenerator, GameEngine) 62
Repositories core:data (GameSave, Settings, Audio, Vibration) 27
Stores feature:home HomeStoreFactory + Mappers 9
Stores feature:settings SettingsStoreFactory + Mappers 7
Stores feature:game GameStoreFactory 24
Components feature:home DefaultHomeComponent 5
Components feature:settings DefaultMainSettingsComponent 6
Components feature:game DefaultGameComponent + ReviewPrompt 9
Components feature:root DefaultRootComponent 8
Total 165

Edge cases covered include cross-clear scoring, combo multiplier chain,
game-over detection without false-positives on row/col completion,
revive caps, autosave debounce, save-restore JSON corruption,
monotonic best-score, concurrent review-counter increments,
audio music gating across requested && foreground && enabled,
review-prompt qualifier matrix (min score / delta / max / per-round),
game-over countdown edge-trigger, and lifecycle bg/fg → audio bridge.

Architecture changes

  • New module core:telemetryCrashlyticsRepositoryImpl,
    AnalyticRepositoryImpl, and their @Binds declarations moved out of
    core:data. composeApp depends on the new module directly; core:data
    no longer references Firebase.
  • formatScorecore:common — pure utility, easier to test, no logic
    change.

Both are surface-level moves with no behavioural impact; production iOS and
Android telemetry continues to work via the same AppScope DI graph.

CI

.github/workflows/ci.yml:

  • tests on macos-15 — needed for iosSimulatorArm64 test runner.
    Uploads HTML test reports as an artifact on failure (7-day retention).
  • android-build on ubuntu-latest:androidApp:assembleDebug smoke check.
  • Concurrency: in-flight PR runs cancel on new commits; main pushes do not.

Out of scope (flagged at audit, deferred)

  • Compose UI tests for the Game screen — needs a UI-test runner module
    or a JVM/desktop target; can be added separately if desired.
  • Three minor inline cleanups noticed during audit (separate PRs):
    • pieceIdCounter not reset in GameEngine.restore (potential id collision
      after revive on a restored save)
    • Loop of incrementReviewPromptCount() in
      DefaultGameComponent.onReviewPromptDontShowAgainClicked — could be a
      single set operation
    • Unused storeReview constructor parameter in GameStoreFactory

Test plan

  • ./gradlew allTests — 165 tests, 0 failures, locally on macOS
  • ./gradlew :composeApp:linkDebugFrameworkIosSimulatorArm64 — iOS prod
    framework links
  • ./gradlew :androidApp:assembleDebug — Android release-shell builds
  • CI green on this PR (will verify once opened)

yet3a and others added 5 commits May 13, 2026 18:55
Move CrashlyticsRepositoryImpl and AnalyticRepositoryImpl out of core:data
into a new core:telemetry module so core:data builds and links on iOS
without Firebase native frameworks at link time. TelemetryBindings is
contributed to AppScope and wired into both AndroidAppGraph and NativeAppGraph,
so runtime DI is unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brings total to 130 tests across core:domain, core:data, feature:home,
feature:settings, and feature:game — all green on iosSimulatorArm64Test.

- ScoreCalculator, Grid, ShapeGenerator: pure-logic edge cases
- GameEngine: placement, clearing, combo, cross-clear, feedback tiers,
  game-over detection, revive caps, restore semantics, autoSave debounce
- SettingsBackedGameSaveRepository: round-trip, corrupt-JSON handling, cache
- SettingsBackedSettingsRepository: defaults, monotonic best, concurrent
  increment safety via mutex
- DefaultAudioRepository: music gating across requested/foreground/sound flags
- DefaultVibrationRepository: live-flag gating
- HomeStoreFactory: hasSavedGame heuristic, best-score max, refresh logging
- SettingsStoreFactory: settings-flow propagation and write-intent logging
- GameStoreFactory: bootstrap branches, best-score persistence, SFX wiring,
  music start/stop, game-over countdown, review-prompt qualifier matrix,
  place/restart/revive intents

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The score formatter is a pure utility; moving it out of composeApp lets it
be exercised in unit tests (composeApp test-link still pulls Firebase via
core:telemetry). Updates AnimatedCounter and GameOverOverlay imports.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds component-level tests for the Decompose layer using LifecycleRegistry
plus light fakes for AudioRepository, SettingsRepository, AnalyticRepository,
StoreReviewRepository, and SettingsComponent.Factory. Brings total to
165 tests across the runnable iosSimulatorArm64Test targets.

- Home/Settings Mappers: state -> model translation
- DefaultHomeComponent: initial model, click callbacks with isNewGame flag,
  lifecycle.resume -> Refresh + home_shown analytics
- DefaultMainSettingsComponent: three toggles propagate to settings,
  more/back navigation callbacks
- DefaultRootComponent: initial Home child, settings flow mirroring,
  audio onAppForeground/onAppBackground on lifecycle start/stop,
  Home continue/newGame -> Game(isNewGame=false/true), back navigation
- DefaultGameComponent: settings sheet open/dismiss with analytics,
  exit callback, restart/revive intents, review prompt sheet on label,
  audio.stopMusic on lifecycle destroy

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Triggers on PRs to main and pushes to main. Two jobs:
- tests (macos-15): ./gradlew allTests — needs macOS for iosSimulatorArm64
  test runners. Uploads test reports as an artifact on failure.
- android-build (ubuntu-latest): :androidApp:assembleDebug as a smoke
  check on a cheaper runner.

Concurrency: cancels in-progress runs on the same PR when new commits land,
keeps main pushes running to completion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@yet300 yet300 merged commit b575b21 into main May 13, 2026
3 checks passed
@yet300 yet300 deleted the test branch May 13, 2026 15:35
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.

2 participants