import 'package:block_seasons/game/engine/game_engine.dart'; import 'package:block_seasons/game/models/grid.dart'; import 'package:block_seasons/game/models/stage.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { test('endless stage config has no objectives and the endless flag', () { final stage = StageConfig.endless(seed: 42); expect(stage.endless, isTrue); expect(stage.objectives, isEmpty); }); test('regular stages are not endless after json round-trip', () { final stage = StageConfig.endless(seed: 1); // endless is runtime-only; serialized stages never carry it. expect(StageConfig.fromJson(stage.toJson()).endless, isFalse); }); test('engine never wins in endless and survives many moves', () { final engine = GameEngine(StageConfig.endless(seed: 36)); var moves = 0; outer: while (engine.phase == GamePhase.playing && moves < 300) { for (var i = 0; i < engine.tray.length; i++) { for (var y = 0; y < GridState.size; y++) { for (var x = 0; x < GridState.size; x++) { if (engine.tryPlaceWouldSucceed(i, x, y)) { engine.tryPlace(i, x, y); moves++; continue outer; } } } } break; } expect(engine.phase, isNot(GamePhase.won)); expect(moves, greaterThan(30)); // above any generated stage move limit if (engine.phase == GamePhase.stuck) { expect(engine.stuckReason, StuckReason.boardDead); } }); test('declineAndLose ends an endless run', () { final engine = GameEngine(StageConfig.endless(seed: 36)); engine.declineAndLose(); expect(engine.phase, GamePhase.lost); }); }