import 'package:flutter_test/flutter_test.dart'; import 'package:Grounded/Grounded/about/external/data/RoutineChain.dart'; import 'package:Grounded/Grounded/about/external/data/RoutineStep.dart'; import 'package:Grounded/Grounded/about/internal/application/RoutineRun.dart'; import 'package:Grounded/Grounded/about/internal/application/StepMode.dart'; RoutineChain _chain() { return RoutineChain(title: "Test", steps: [ RoutineStep(title: "Squat", mode: StepMode.Reps, sets: 2, reps: 5, restSeconds: 30), RoutineStep(title: "Plank", mode: StepMode.Timed, sets: 1, timerSeconds: 45, restSeconds: 15), ]); } void main() { test('phases interleave rest, with none after the final set', () { final RoutineRun run = RoutineRun(_chain()); final List shape = run.phases .map((p) => p.rest ? "rest" : "${p.step.title}${p.set}") .toList(); expect(shape, ["Squat1", "rest", "Squat2", "rest", "Plank1"]); }); test('clock is wall-clock derived and pauses cleanly', () { final RoutineRun run = RoutineRun(_chain()); final DateTime t0 = DateTime(2026, 1, 1, 7); run.resume(now: t0); run.pause(now: t0.add(const Duration(seconds: 20))); expect(run.elapsedSeconds(), 20); expect(run.phaseElapsed(), 20); run.resume(now: t0.add(const Duration(seconds: 100))); expect(run.elapsedSeconds(now: t0.add(const Duration(seconds: 105))), 25); }); test('step completes on its last set; skips are counted and break the chain', () { final RoutineRun run = RoutineRun(_chain()); run.advance(); // Squat1 -> rest run.advance(); // rest -> Squat2 expect(run.chain.steps[0].completed, false); run.advance(); // Squat2 done -> rest expect(run.chain.steps[0].completed, true); run.advance(); // rest -> Plank1 expect(run.advance(skipped: true), false); // end of run expect(run.skippedCount, 1); expect(run.chain.complete, false); expect(run.breakIndex, 1); }); test('back skips over rest to the previous work phase', () { final RoutineRun run = RoutineRun(_chain()); run.advance(); run.advance(); // Squat2 run.back(); expect(run.phase.set, 1); expect(run.phase.rest, false); }); test('planned time includes rest after every set', () { final RoutineChain chain = RoutineChain(steps: [ RoutineStep(mode: StepMode.Timed, sets: 3, timerSeconds: 40, restSeconds: 20), ]); expect(chain.totalSeconds, 180); expect(RoutineChain.fromJson(chain.toJson()).steps.first.restSeconds, 20); }); }