import 'package:flutter_test/flutter_test.dart'; import 'package:zenxercise/src/modes/mode.dart'; import 'package:zenxercise/src/plans/models/plan.dart'; import 'package:zenxercise/src/player/segments.dart'; Plan _plan(Mode mode, List items, {int transition = 5}) => Plan( id: 'p', mode: mode, name: 'P', items: items, transitionSeconds: transition, createdAt: DateTime(2026), updatedAt: DateTime(2026), ); String _describe(Segment s) => switch (s) { HoldSegment(:final exerciseId, :final side, :final round) => 'hold $exerciseId${side == null ? '' : ' ${side.name}'} r$round', TransitionSegment(:final kind, :final seconds) => '${kind.name} ${seconds}s', SetSegment(:final exerciseId, :final set) => 'set $exerciseId $set', RestSegment() => 'rest', }; void main() { group('Stretching', () { test('holds every side and round with Transitions between, after a get-ready', () { final segments = buildSegments( _plan(Mode.stretching, const [ StretchingStep(exerciseId: 'A', holdSeconds: 30, bothSides: true, rounds: 2), StretchingStep(exerciseId: 'B', holdSeconds: 20, bothSides: false, rounds: 1), ]), ); expect(segments.map(_describe), [ 'getReady 5s', 'hold A left r1', 'switchSides 5s', 'hold A right r1', 'nextRound 5s', 'hold A left r2', 'switchSides 5s', 'hold A right r2', 'nextExercise 5s', 'hold B r1', ]); }); test('a pause of 0 s means no Transitions at all', () { final segments = buildSegments( _plan(Mode.stretching, const [ StretchingStep(exerciseId: 'A', holdSeconds: 30, bothSides: true, rounds: 1), ], transition: 0), ); expect(segments.map(_describe), ['hold A left r1', 'hold A right r1']); }); }); group('Workout', () { test('each set is followed by a Rest, except the very last', () { final segments = buildSegments( _plan(Mode.workout, const [ WorkoutStep(exerciseId: 'A', sets: 2, target: WorkoutTarget.reps(10)), WorkoutStep(exerciseId: 'B', sets: 1, target: WorkoutTarget.seconds(30)), ]), ); expect(segments.map(_describe), ['set A 1', 'rest', 'set A 2', 'rest', 'set B 1']); }); test('a Superset alternates its members and rests after each round only', () { final segments = buildSegments( _plan(Mode.workout, const [ Superset( sets: 2, restBetween: false, members: [ SupersetMember(exerciseId: 'A', target: WorkoutTarget.reps(10)), SupersetMember(exerciseId: 'B', target: WorkoutTarget.reps(12)), ], ), ]), ); expect(segments.map(_describe), ['set A 1', 'set B 1', 'rest', 'set A 2', 'set B 2']); }); test('with rest between, a Superset also rests between its members', () { final segments = buildSegments( _plan(Mode.workout, const [ Superset( sets: 1, restBetween: true, members: [ SupersetMember(exerciseId: 'A', target: WorkoutTarget.reps(10)), SupersetMember(exerciseId: 'B', target: WorkoutTarget.reps(12)), ], ), ]), ); expect(segments.map(_describe), ['set A 1', 'rest', 'set B 1']); }); test('a set carries its target, weight and position in the Step', () { final set = buildSegments( _plan(Mode.workout, const [ WorkoutStep(exerciseId: 'A', sets: 3, target: WorkoutTarget.reps(8), weightKg: 40), ]), )[2] as SetSegment; expect(set.target, const WorkoutTarget.reps(8)); expect(set.weightKg, 40); expect((set.set, set.sets), (2, 3)); }); }); }