mirror of
https://github.com/kuhyx/screen-locker.git
synced 2026-11-12 08:30:54 +01:00
The rest banner used to be inserted into the column only while a break ran, so its arrival took height from the exercise list, shifted every tile down and pushed the last one into scroll range. The strip is now a permanently reserved 64 dp slot (muted "Rest / 00:00" while idle, Skip keeps its space), the list is a non-scrolling column that scales down as a whole if it would not fit (0.96 on the Pixel 6a with four tiles, pinned by a widget test at the phone's logical size with the status bar simulated), and the activity is locked to portrait. Verified on the real phone: only the tapped circle's pixels change when a rest starts. Verifying that needed a workout screen that today's already-logged workout did not offer, so the app gained a `sandbox` product flavor beside `daily`: com.kuhy.workout_app.sandbox installs side by side with its own data, refuses every network connection at the socket layer, starts no LAN server for the PC to pull from, keeps its /sdcard files beside the daily build's, wears a red SANDBOX ribbon, and offers a SANDBOX section in Settings (wipe, mark today not done, rest length in seconds). MainActivity answers the flavor and carries a `WorkoutSandbox` logcat trace of every tap, break, save and navigation. On Linux the same mode is WORKOUT_SANDBOX=1, driven under Xvfb by scripts/run_sandbox_xvfb.sh. CI builds --flavor daily; .phone-deploy-flavor tells phone_deploy.sh the same. Set circles and the home icon buttons carry semantics labels so they can be addressed by element (and by screen readers). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YbBZqUaNWyhHYfzz6zGC7q
72 lines
2.2 KiB
Dart
72 lines
2.2 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:workout_app/sandbox/sandbox.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
void answer(Object? Function(MethodCall call)? handler) {
|
|
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
|
.setMockMethodCallHandler(
|
|
Sandbox.channel,
|
|
handler == null ? null : (call) async => handler(call),
|
|
);
|
|
}
|
|
|
|
final printed = <String>[];
|
|
setUp(() {
|
|
printed.clear();
|
|
debugPrint = (String? message, {int? wrapWidth}) => printed.add(message ?? '');
|
|
Sandbox.enabled = false;
|
|
Sandbox.restSecs = Sandbox.defaultRestSecs;
|
|
});
|
|
tearDown(() {
|
|
debugPrint = debugPrintThrottled;
|
|
answer(null);
|
|
Sandbox.enabled = false;
|
|
});
|
|
|
|
test('init takes the flavor from MainActivity', () async {
|
|
answer((call) => call.method == 'isSandbox');
|
|
await Sandbox.init();
|
|
expect(Sandbox.enabled, isTrue);
|
|
});
|
|
|
|
test('init treats a null answer as the daily build', () async {
|
|
answer((_) => null);
|
|
await Sandbox.init();
|
|
expect(Sandbox.enabled, isFalse);
|
|
});
|
|
|
|
test('init falls back to the environment where there is no channel', () async {
|
|
answer(null);
|
|
await Sandbox.init({Sandbox.envVar: '1'});
|
|
expect(Sandbox.enabled, isTrue);
|
|
expect(printed.single, contains('WORKOUT_SANDBOX=1: sandbox'));
|
|
|
|
await Sandbox.init({});
|
|
expect(Sandbox.enabled, isFalse);
|
|
expect(printed.last, contains('unset: daily build'));
|
|
});
|
|
|
|
test('init reads the real environment by default', () async {
|
|
answer(null);
|
|
await Sandbox.init();
|
|
// Whatever the host env says, it must not throw and must report it.
|
|
expect(printed.single, contains('no sandbox channel'));
|
|
});
|
|
|
|
test('rest and label pass through for the daily build', () {
|
|
expect(Sandbox.rest(180), 180);
|
|
expect(Sandbox.restLabel('Rest (3 min — well done!)'), 'Rest (3 min — well done!)');
|
|
});
|
|
|
|
test('rest and label are overridden in the sandbox', () {
|
|
Sandbox.enabled = true;
|
|
Sandbox.restSecs = 9;
|
|
expect(Sandbox.rest(180), 9);
|
|
expect(Sandbox.restLabel('Rest (3 min — well done!)'), 'Rest (9 s — sandbox)');
|
|
});
|
|
}
|