Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
core:domain,core:data,core:common,feature:{home, settings, game, root}— every test green oniosSimulatorArm64Test.core:telemetrymodule socore:datano longer pulls Firebase into iOS test linking.TelemetryBindingsis wired into both
AndroidAppGraphandNativeAppGraph, so runtime DIis unchanged.
formatScoreutility tocore:commonso it's reachable fromshared test sources.
./gradlew allTestson macOS PRs and a LinuxassembleDebugsmoke check; the existing release pipeline is untouched.What's covered
core:common(FormatScore)core:domain(Score, Grid, ShapeGenerator, GameEngine)core:data(GameSave, Settings, Audio, Vibration)feature:homeHomeStoreFactory + Mappersfeature:settingsSettingsStoreFactory + Mappersfeature:gameGameStoreFactoryfeature:homeDefaultHomeComponentfeature:settingsDefaultMainSettingsComponentfeature:gameDefaultGameComponent + ReviewPromptfeature:rootDefaultRootComponentEdge 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
core:telemetry—CrashlyticsRepositoryImpl,AnalyticRepositoryImpl, and their@Bindsdeclarations moved out ofcore:data.composeAppdepends on the new module directly;core:datano longer references Firebase.
formatScore→core:common— pure utility, easier to test, no logicchange.
Both are surface-level moves with no behavioural impact; production iOS and
Android telemetry continues to work via the same
AppScopeDI graph.CI
.github/workflows/ci.yml:testsonmacos-15— needed foriosSimulatorArm64test runner.Uploads HTML test reports as an artifact on failure (7-day retention).
android-buildonubuntu-latest—:androidApp:assembleDebugsmoke check.Out of scope (flagged at audit, deferred)
or a JVM/desktop target; can be added separately if desired.
pieceIdCounternot reset inGameEngine.restore(potential id collisionafter revive on a restored save)
incrementReviewPromptCount()inDefaultGameComponent.onReviewPromptDontShowAgainClicked— could be asingle
setoperationstoreReviewconstructor parameter inGameStoreFactoryTest plan
./gradlew allTests— 165 tests, 0 failures, locally on macOS./gradlew :composeApp:linkDebugFrameworkIosSimulatorArm64— iOS prodframework links
./gradlew :androidApp:assembleDebug— Android release-shell builds