screen-locker/stronglift_replacement/workout_app
Krzysztof kuhy Rudnicki ac7a7afa08 Extract WorkoutSyncSession from workout_sync_service.dart (322 -> 218)
The one file on the list that could not be fixed by moving code, so the
approach was agreed with the user first: extract a real collaborator rather
than change the public surface.

`push`, `pushManual` and `syncNow` were three near-identical bodies — same
configured-or-bail guard, same GitHubClient/Firebase/MirrorStore construction,
same getFileText/mergeLogs/syncLog round-trip, same catch-everything-and-report
handler, same close-both finally. They differed in the record they merged in
(one, one, none) and two strings. That shared body is now
WorkoutSyncSession.run(), and the three methods are thin wrappers holding only
their own guard and their own wording.

Why a collaborator and not a `part` extension: extension methods dispatch
statically. Four fakes in _home_test_fixtures.dart override `syncNow`, and
manual_workout_screen_test.dart overrides `pushManual` and
`readMergedManualPayloads` — with those in an extension the real
implementations would run while the fakes sat unused, which is how four tests
hung on pumpAndSettle in an earlier attempt. All four remain ordinary methods
on WorkoutSyncService, so every override still binds.

`successReason` and `failurePrefix` are passed in rather than derived from one
another, so the exact strings the tests assert on ('pushed' / 'push failed',
'synced' / 'sync failed') stay under the callers' control.

Unlike the part files, this is a real library with its own lcov SF: entry, so
it has to carry its own coverage — it does. The total drops 2751 -> 2728
covered lines, which is the duplication the extraction removed.

402 tests pass; dart analyze clean; coverage 100%.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EveB813BQ8abAP68VSqZ5Y
2026-08-15 22:28:02 +02:00
..
android Build and publish a signed APK on every push to main 2026-08-04 20:55:04 +02:00
assets Fix on-fill text contrast on filled buttons, bump gatelock pin 2026-07-21 21:17:14 +02:00
lib Extract WorkoutSyncSession from workout_sync_service.dart (322 -> 218) 2026-08-15 22:28:02 +02:00
test Split workout_screen_test.dart (362) into three 2026-08-15 22:20:56 +02:00
.gitignore feat: add Flutter workout app (StrongLifts replacement) 2026-05-31 16:23:46 +02:00
.metadata feat: add Flutter workout app (StrongLifts replacement) 2026-05-31 16:23:46 +02:00
analysis_options.yaml Persist the CI-mirror's analyzer excludes and dependency upgrades 2026-08-14 16:13:46 +02:00
CONTEXT.md feat: add Flutter workout app (StrongLifts replacement) 2026-05-31 16:23:46 +02:00
pubspec.lock Persist the CI-mirror's analyzer excludes and dependency upgrades 2026-08-14 16:13:46 +02:00
pubspec.yaml workout_app: migrate Sync settings to the shared sync_settings_ui package 2026-08-14 11:21:16 +02:00
README.md feat: add Flutter workout app (StrongLifts replacement) 2026-05-31 16:23:46 +02:00

workout_app

A new Flutter project.

Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter development, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.