mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 19:27:14 +01:00
Body: 2-column tiles, each opens its card in a sheet. Food bank: paged 3-column tiles, tap for macros. Pixel 6a widget test asserts no vertical scroll on log, calendar, food bank (250 foods) and body. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzxdWVUTaKFW8m7YrvWbzV
118 lines
3.8 KiB
Dart
118 lines
3.8 KiB
Dart
// Shared setup for the Body screen test files (split for the 250-line cap).
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:diet_guard_app/models/local_time.dart';
|
|
import 'package:diet_guard_app/screens/body_screen.dart';
|
|
import 'package:diet_guard_app/services/app_settings_service.dart';
|
|
import 'package:diet_guard_app/services/body_service.dart';
|
|
import 'package:diet_guard_app/services/log_storage_service.dart';
|
|
import 'package:diet_guard_app/widgets/body/body_tile_grid.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../services/body_test_support.dart';
|
|
|
|
export '../services/body_test_support.dart';
|
|
|
|
/// Points every service the screen reads at [store]; returns a teardown.
|
|
Future<void> setUpBodyServices(MemoryDocStore store) async {
|
|
LogStorageService.resetForTesting(store: store);
|
|
AppSettingsService.resetForTesting(store: store);
|
|
await BodyService.initForTesting(store);
|
|
}
|
|
|
|
/// Undoes [setUpBodyServices].
|
|
void tearDownBodyServices() {
|
|
BodyService.resetForTesting();
|
|
LogStorageService.resetForTesting();
|
|
AppSettingsService.resetForTesting();
|
|
}
|
|
|
|
/// Pumps the Body screen on a view tall enough to lay out every card.
|
|
Future<void> pumpBody(WidgetTester tester) async {
|
|
tester.view.physicalSize = const Size(1200, 12000);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.pumpWidget(const MaterialApp(home: BodyScreen()));
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
/// Yesterday's local date key.
|
|
String yesterdayKey() =>
|
|
localDateKey(DateTime.now().subtract(const Duration(days: 1)));
|
|
|
|
/// An 80 kg, 180 cm, 30-year-old man with a run, a lift and 9000 steps
|
|
/// yesterday; optionally a saved [goal].
|
|
Future<void> seedPerson(MemoryDocStore store, {Object? goal}) async {
|
|
final today = DateTime.now();
|
|
const t = '2026-09-01T10:00:00+02:00';
|
|
store.documents[BodyService.documentName] = jsonEncode({
|
|
'profile': {
|
|
'birth': {'v': localDateKey(DateTime(today.year - 30, 1, 1)), 't': t},
|
|
'height_cm': {'v': 180, 't': t},
|
|
'sex': {'v': 'm', 't': t},
|
|
if (goal != null) 'goal': {'v': goal, 't': t},
|
|
},
|
|
'weights': {
|
|
'2026-09-20': {'kg': 81, 'src': 'phone', 't': '2026-09-20T07:00:00Z'},
|
|
yesterdayKey(): {'kg': 80, 'src': 'manual', 't': '2026-09-20T07:00:00Z'},
|
|
},
|
|
'steps': {
|
|
yesterdayKey(): {'n': 9000, 't': t},
|
|
},
|
|
'activity': {
|
|
't': t,
|
|
'sessions': [
|
|
{
|
|
'day': yesterdayKey(),
|
|
'kind': 'run',
|
|
'min': 60,
|
|
'km': 10,
|
|
'label': 'Evening run',
|
|
'src': 'runnerup',
|
|
},
|
|
{
|
|
'day': yesterdayKey(),
|
|
'kind': 'strength',
|
|
'min': 80,
|
|
'label': 'StrongLifts A',
|
|
'src': 'screen-locker',
|
|
},
|
|
],
|
|
},
|
|
});
|
|
await BodyService.initForTesting(store);
|
|
}
|
|
|
|
/// The top edge of [finder]'s first match.
|
|
double topOf(WidgetTester tester, Finder finder) =>
|
|
tester.getTopLeft(finder.first).dy;
|
|
|
|
/// The overview tile titled [title].
|
|
Finder tile(String title) =>
|
|
find.descendant(of: find.byType(BodyTileGrid), matching: find.text(title));
|
|
|
|
/// Opens the sheet behind the tile titled [title].
|
|
Future<void> openTile(WidgetTester tester, String title) async {
|
|
await tester.tap(tile(title));
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
/// Dismisses the open sheet by tapping its scrim.
|
|
Future<void> closeSheet(WidgetTester tester) async {
|
|
await tester.tapAt(const Offset(5, 5));
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
/// [finder] restricted to the open sheet (the tiles stay mounted behind it).
|
|
Finder inSheet(Finder finder) =>
|
|
find.descendant(of: find.byType(BottomSheet), matching: finder);
|
|
|
|
/// Titles of the overview tiles, in display order.
|
|
List<String> tileTitles(WidgetTester tester) => tester
|
|
.widget<BodyTileGrid>(find.byType(BodyTileGrid))
|
|
.tiles
|
|
.map((t) => t.title)
|
|
.toList();
|