Files
ZenXercise/test/support/test_app.dart
T
CedricandClaude Opus 5.5 bbdca95541 Stage 3: Plan editor with Steps, Supersets and reordering
- Plan model with immutable edits: add with Mode defaults, move, remove,
  Superset with next, take a member out, ungroup; Stretching length
  estimate from holds, sides, rounds and Transitions
- drift database (plans table, items as JSON, ADR 0005) and
  PlanRepository; Plans list per Mode with rename/duplicate/delete
- Editor: drag handles, step editor sheet (sets, reps or time, optional
  kg; hold, both sides, rounds; Superset sets and rest between),
  pause between holds for Stretching Plans
- Exercise picker reusing the Library browser; Add to plan from the
  Exercise detail page
- Theme: Mode-styled snackbar, FAB, menus, segmented buttons, switches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:48:07 +01:00

84 lines
2.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:zenxercise/src/app.dart';
import 'package:zenxercise/src/exercises/exercise.dart';
import 'package:zenxercise/src/exercises/exercise_library.dart';
import 'package:zenxercise/src/modes/mode.dart';
import 'package:zenxercise/src/plans/plan_repository.dart';
import 'package:zenxercise/src/settings/settings_controller.dart';
import 'test_database.dart';
Exercise exercise(
String id,
Mode mode, {
String? name,
List<String> primary = const ['hamstrings'],
List<String> secondary = const [],
String? equipment = 'body only',
String level = 'beginner',
List<String> instructions = const ['Breathe.'],
int imageCount = 0,
}) => Exercise(
id: id,
name: name ?? id.replaceAll('_', ' '),
mode: mode,
category: mode == Mode.stretching ? 'stretching' : 'strength',
level: level,
equipment: equipment,
primaryMuscles: primary,
secondaryMuscles: secondary,
instructions: instructions,
imageCount: imageCount,
);
/// Two stretches and a squat. The 90/90 Hamstring's images exist in the real assets.
final sampleLibrary = ExerciseLibrary([
exercise(
'90_90_Hamstring',
Mode.stretching,
name: '90/90 Hamstring',
secondary: const ['calves'],
instructions: const ['Lie on your back.', 'Straighten one leg.'],
imageCount: 2,
),
exercise('Calf_Stretch', Mode.stretching, primary: const ['calves'], equipment: 'other', level: 'intermediate'),
exercise('Barbell_Squat', Mode.workout, primary: const ['quadriceps'], equipment: 'barbell'),
]);
/// A Pixel-sized screen instead of the default 800×600, so the floating
/// navigation bar does not cover what a test taps.
void usePhoneScreen(WidgetTester tester) {
tester.view.physicalSize = const Size(1080, 2400);
tester.view.devicePixelRatio = 2.75;
addTearDown(tester.view.reset);
}
/// The whole app over [library], with preferences starting from [prefs].
Future<SettingsController> pumpApp(
WidgetTester tester, {
ExerciseLibrary? library,
Map<String, Object> prefs = const {},
PlanRepository? plans,
}) async {
SharedPreferences.setMockInitialValues(prefs);
final settings = SettingsController(SettingsService());
await settings.loadSettings();
final db = testDatabase();
addTearDown(db.close);
await tester.pumpWidget(
MultiProvider(
providers: [
ChangeNotifierProvider.value(value: settings),
Provider.value(value: library ?? sampleLibrary),
Provider.value(value: plans ?? PlanRepository(db)),
],
child: const ZenXerciseApp(),
),
);
await tester.pumpAndSettle();
return settings;
}