diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 1fa99b8c..3c99fbca 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -22,8 +22,6 @@ class PinballGame extends Forge2DGame final PinballAudio audio; - late final Plunger plunger; - @override void onAttach() { super.onAttach(); @@ -73,7 +71,7 @@ class PinballGame extends Forge2DGame } Future _addPlunger() async { - plunger = Plunger(compressionDistance: 29) + final plunger = Plunger(compressionDistance: 29) ..initialPosition = BoardDimensions.bounds.center.toVector2() + Vector2(41.5, -49); await add(plunger); @@ -90,14 +88,20 @@ class PinballGame extends Forge2DGame ); } - void spawnBall() { + Future spawnBall() async { + // TODO(alestiago): Remove once this logic is moved to controller. + var plunger = firstChild(); + if (plunger == null) { + await add(plunger = Plunger(compressionDistance: 1)); + } + final ball = ControlledBall.launch( theme: theme, )..initialPosition = Vector2( plunger.body.position.x, plunger.body.position.y + Ball.size.y, ); - add(ball); + await add(ball); } } diff --git a/test/game/components/board_test.dart b/test/game/components/board_test.dart index 2f51b2b1..9f2a5260 100644 --- a/test/game/components/board_test.dart +++ b/test/game/components/board_test.dart @@ -9,7 +9,7 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); group('Board', () { flameTester.test( @@ -78,7 +78,6 @@ void main() { flameTester.test( 'one FlutterForest', (game) async { - // TODO(alestiago): change to [NestBumpers] once provided. final board = Board(); await game.ready(); await game.ensureAdd(board); diff --git a/test/game/components/bonus_word_test.dart b/test/game/components/bonus_word_test.dart index 6b1af085..f01fced9 100644 --- a/test/game/components/bonus_word_test.dart +++ b/test/game/components/bonus_word_test.dart @@ -14,16 +14,18 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); group('BonusWord', () { flameTester.test( 'loads the letters correctly', (game) async { - await game.ready(); + final bonusWord = BonusWord( + position: Vector2.zero(), + ); + await game.ensureAdd(bonusWord); - final bonusWord = game.children.whereType().first; - final letters = bonusWord.children.whereType(); + final letters = bonusWord.descendants().whereType(); expect(letters.length, equals(GameBloc.bonusWord.length)); }, ); @@ -135,7 +137,7 @@ void main() { }); group('BonusLetter', () { - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); flameTester.test( 'loads correctly', @@ -215,8 +217,7 @@ void main() { late PinballAudio pinballAudio; final flameBlocTester = FlameBlocTester( - // TODO(alestiago): Use TestGame once BonusLetter has controller. - gameBuilder: PinballGameTest.create, + gameBuilder: EmptyPinballGameTest.new, blocBuilder: () => gameBloc, repositories: () => [ RepositoryProvider.value(value: pinballAudio), @@ -238,14 +239,20 @@ void main() { flameBlocTester.testGameWidget( 'adds BonusLetterActivated to GameBloc when not activated', setUp: (game, tester) async { - await game.ready(); - final bonusLetter = game.descendants().whereType().first; + final bonusWord = BonusWord( + position: Vector2.zero(), + ); + await game.ensureAdd(bonusWord); - bonusLetter.activate(); - await game.ready(); - }, - verify: (game, tester) async { - verify(() => gameBloc.add(const BonusLetterActivated(0))).called(1); + final bonusLetters = + game.descendants().whereType().toList(); + for (var index = 0; index < bonusLetters.length; index++) { + final bonusLetter = bonusLetters[index]; + bonusLetter.activate(); + await game.ready(); + + verify(() => gameBloc.add(BonusLetterActivated(index))).called(1); + } }, ); @@ -309,25 +316,33 @@ void main() { ); flameBlocTester.testGameWidget( - 'only listens when there is a change on the letter status', + 'listens when there is a change on the letter status', setUp: (game, tester) async { - await game.ready(); - final bonusLetter = game.descendants().whereType().first; - bonusLetter.activate(); - }, - verify: (game, tester) async { - const state = GameState( - score: 0, - balls: 2, - activatedBonusLetters: [0], - activatedDashNests: {}, - bonusHistory: [], - ); - final bonusLetter = game.descendants().whereType().first; - expect( - bonusLetter.listenWhen(const GameState.initial(), state), - isTrue, + final bonusWord = BonusWord( + position: Vector2.zero(), ); + await game.ensureAdd(bonusWord); + + final bonusLetters = + game.descendants().whereType().toList(); + for (var index = 0; index < bonusLetters.length; index++) { + final bonusLetter = bonusLetters[index]; + bonusLetter.activate(); + await game.ready(); + + final state = GameState( + score: 0, + balls: 2, + activatedBonusLetters: [index], + activatedDashNests: const {}, + bonusHistory: const [], + ); + + expect( + bonusLetter.listenWhen(const GameState.initial(), state), + isTrue, + ); + } }, ); }); diff --git a/test/game/components/controlled_ball_test.dart b/test/game/components/controlled_ball_test.dart index f9494543..05056484 100644 --- a/test/game/components/controlled_ball_test.dart +++ b/test/game/components/controlled_ball_test.dart @@ -13,7 +13,7 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); group('BonusBallController', () { late Ball ball; @@ -67,7 +67,7 @@ void main() { }); final flameBlocTester = FlameBlocTester( - gameBuilder: PinballGameTest.create, + gameBuilder: EmptyPinballGameTest.new, blocBuilder: () => gameBloc, ); @@ -155,13 +155,13 @@ void main() { await game.ensureAdd(ball); final state = MockGameState(); - when(() => state.balls).thenReturn(2); + when(() => state.balls).thenReturn(1); final previousBalls = game.descendants().whereType().toList(); controller.onNewState(state); await game.ready(); - final currentBalls = game.descendants().whereType(); + final currentBalls = game.descendants().whereType().toList(); expect(currentBalls.contains(ball), isFalse); expect(currentBalls.length, equals(previousBalls.length)); diff --git a/test/game/components/controlled_flipper_test.dart b/test/game/components/controlled_flipper_test.dart index eabeca5e..03c51830 100644 --- a/test/game/components/controlled_flipper_test.dart +++ b/test/game/components/controlled_flipper_test.dart @@ -10,7 +10,7 @@ import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); group('FlipperController', () { group('onKeyEvent', () { diff --git a/test/game/components/flutter_forest_test.dart b/test/game/components/flutter_forest_test.dart index 33dbb991..60c55be9 100644 --- a/test/game/components/flutter_forest_test.dart +++ b/test/game/components/flutter_forest_test.dart @@ -25,7 +25,7 @@ void beginContact(Forge2DGame game, BodyComponent bodyA, BodyComponent bodyB) { void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); + final flameTester = FlameTester(EmptyPinballGameTest.new); group('FlutterForest', () { flameTester.test( @@ -146,16 +146,15 @@ void main() { }); final flameBlocTester = FlameBlocTester( - gameBuilder: PinballGameTest.create, + gameBuilder: EmptyPinballGameTest.new, blocBuilder: () => gameBloc, ); flameBlocTester.testGameWidget( 'add DashNestActivated event', setUp: (game, tester) async { - await game.ready(); - final flutterForest = - game.descendants().whereType().first; + final flutterForest = FlutterForest(); + await game.ensureAdd(flutterForest); await game.ensureAdd(ball); final bumpers = @@ -177,15 +176,16 @@ void main() { final flutterForest = FlutterForest(); await game.ensureAdd(flutterForest); await game.ensureAdd(ball); + game.addContactCallback(BallScorePointsCallback(game)); - final bumpers = - flutterForest.descendants().whereType(); + final bumpers = flutterForest.descendants().whereType(); for (final bumper in bumpers) { beginContact(game, bumper, ball); - final points = (bumper as ScorePoints).points; verify( - () => gameBloc.add(Scored(points: points)), + () => gameBloc.add( + Scored(points: bumper.points), + ), ).called(1); } }, diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index 52008074..f418bad0 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -12,8 +12,8 @@ import '../helpers/helpers.dart'; void main() { group('PinballGame', () { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.create); - final debugModeFlameTester = FlameTester(DebugPinballGameTest.create); + final flameTester = FlameTester(PinballGameTest.new); + final debugModeFlameTester = FlameTester(DebugPinballGameTest.new); // TODO(alestiago): test if [PinballGame] registers // [BallScorePointsCallback] once the following issue is resolved: diff --git a/test/helpers/extensions.dart b/test/helpers/extensions.dart index a5039381..4731eec4 100644 --- a/test/helpers/extensions.dart +++ b/test/helpers/extensions.dart @@ -3,24 +3,27 @@ import 'package:pinball_theme/pinball_theme.dart'; import 'helpers.dart'; -/// [PinballGame] extension to reduce boilerplate in tests. -extension PinballGameTest on PinballGame { - /// Create [PinballGame] with default [PinballTheme]. - static PinballGame create() => PinballGame( - theme: const PinballTheme( - characterTheme: DashTheme(), - ), - audio: MockPinballAudio(), - )..images.prefix = ''; +class PinballGameTest extends PinballGame { + PinballGameTest() + : super( + audio: MockPinballAudio(), + theme: const PinballTheme( + characterTheme: DashTheme(), + ), + ); } -/// [DebugPinballGame] extension to reduce boilerplate in tests. -extension DebugPinballGameTest on DebugPinballGame { - /// Create [PinballGame] with default [PinballTheme]. - static DebugPinballGame create() => DebugPinballGame( - theme: const PinballTheme( - characterTheme: DashTheme(), - ), - audio: MockPinballAudio(), - ); +class DebugPinballGameTest extends DebugPinballGame { + DebugPinballGameTest() + : super( + audio: MockPinballAudio(), + theme: const PinballTheme( + characterTheme: DashTheme(), + ), + ); +} + +class EmptyPinballGameTest extends PinballGameTest { + @override + Future onLoad() async {} }