diff --git a/lib/game/behaviors/ball_spawning_behavior.dart b/lib/game/behaviors/ball_spawning_behavior.dart index 8995c16b..8fc56905 100644 --- a/lib/game/behaviors/ball_spawning_behavior.dart +++ b/lib/game/behaviors/ball_spawning_behavior.dart @@ -13,7 +13,8 @@ class BallSpawningBehavior extends Component bool listenWhen(GameState? previousState, GameState newState) { if (!newState.status.isPlaying) return false; - final startedGame = previousState?.status.isWaiting ?? true; + final startedGame = (previousState?.status.isWaiting ?? true) || + (previousState?.status.isGameOver ?? true); final lostRound = (previousState?.rounds ?? newState.rounds + 1) > newState.rounds; return startedGame || lostRound; diff --git a/lib/game/bloc/game_bloc.dart b/lib/game/bloc/game_bloc.dart index c63bf514..feea7304 100644 --- a/lib/game/bloc/game_bloc.dart +++ b/lib/game/bloc/game_bloc.dart @@ -19,7 +19,7 @@ class GameBloc extends Bloc { static const _maxScore = 9999999999; void _onGameStarted(GameStarted _, Emitter emit) { - emit(state.copyWith(status: GameStatus.playing)); + emit(const GameState.initial().copyWith(status: GameStatus.playing)); } void _onGameOver(GameOver _, Emitter emit) { diff --git a/lib/game/components/backbox/displays/game_over_info_display.dart b/lib/game/components/backbox/displays/game_over_info_display.dart index 52939345..2db7e20b 100644 --- a/lib/game/components/backbox/displays/game_over_info_display.dart +++ b/lib/game/components/backbox/displays/game_over_info_display.dart @@ -66,7 +66,7 @@ class GameOverInfoDisplay extends Component with HasGameRef { @override Future onLoad() async { await super.onLoad(); - gameRef.overlays.add(PinballGame.playButtonOverlay); + gameRef.overlays.add(PinballGame.replayButtonOverlay); } } @@ -290,7 +290,7 @@ class OpenSourceTextComponent extends TextComponent with HasGameRef, Tappable { ); @override - bool onTapDown(TapDownInfo info) { + bool onTapUp(TapUpInfo info) { openLink(ShareRepository.openSourceCode); return true; } diff --git a/lib/game/components/game_bloc_status_listener.dart b/lib/game/components/game_bloc_status_listener.dart index 560e5aa7..efd085a5 100644 --- a/lib/game/components/game_bloc_status_listener.dart +++ b/lib/game/components/game_bloc_status_listener.dart @@ -22,6 +22,7 @@ class GameBlocStatusListener extends Component break; case GameStatus.playing: readProvider().play(PinballAudio.backgroundMusic); + _resetBonuses(); gameRef .descendants() .whereType() @@ -31,6 +32,7 @@ class GameBlocStatusListener extends Component .whereType() .forEach(_addPlungerBehaviors); gameRef.overlays.remove(PinballGame.playButtonOverlay); + gameRef.overlays.remove(PinballGame.replayButtonOverlay); break; case GameStatus.gameOver: readProvider().play(PinballAudio.gameOverVoiceOver); @@ -52,6 +54,15 @@ class GameBlocStatusListener extends Component } } + void _resetBonuses() { + gameRef + .descendants() + .whereType>() + .single + .bloc + .onReset(); + } + void _addPlungerBehaviors(Plunger plunger) { final platformHelper = readProvider(); const pullingStrength = 7.0; diff --git a/lib/game/components/google_gallery/behaviors/google_word_bonus_behavior.dart b/lib/game/components/google_gallery/behaviors/google_word_bonus_behavior.dart index ed19f495..2313e921 100644 --- a/lib/game/components/google_gallery/behaviors/google_word_bonus_behavior.dart +++ b/lib/game/components/google_gallery/behaviors/google_word_bonus_behavior.dart @@ -17,7 +17,7 @@ class GoogleWordBonusBehavior extends Component { onNewState: (state) { readBloc() .add(const BonusActivated(GameBonus.googleWord)); - readBloc().onBonusAwarded(); + readBloc().onReset(); add(BonusBallSpawningBehavior()); add(GoogleWordAnimatingBehavior()); }, diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 84d2a6ae..ad81425f 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -38,10 +38,13 @@ class PinballGame extends PinballForge2DGame images.prefix = ''; } - /// Identifier of the play button overlay + /// Identifier of the play button overlay. static const playButtonOverlay = 'play_button'; - /// Identifier of the mobile controls overlay + /// Identifier of the replay button overlay. + static const replayButtonOverlay = 'replay_button'; + + /// Identifier of the mobile controls overlay. static const mobileControlsOverlay = 'mobile_controls'; @override diff --git a/lib/game/view/pinball_game_page.dart b/lib/game/view/pinball_game_page.dart index efc11996..06fde72d 100644 --- a/lib/game/view/pinball_game_page.dart +++ b/lib/game/view/pinball_game_page.dart @@ -100,22 +100,25 @@ class PinballGameLoadedView extends StatelessWidget { focusNode: game.focusNode, initialActiveOverlays: const [PinballGame.playButtonOverlay], overlayBuilderMap: { - PinballGame.playButtonOverlay: (context, game) { - return const Positioned( - bottom: 20, - right: 0, - left: 0, - child: PlayButtonOverlay(), - ); - }, - PinballGame.mobileControlsOverlay: (context, game) { - return Positioned( - bottom: 0, - left: 0, - right: 0, - child: MobileControls(game: game), - ); - }, + PinballGame.playButtonOverlay: (_, game) => const Positioned( + bottom: 20, + right: 0, + left: 0, + child: PlayButtonOverlay(), + ), + PinballGame.mobileControlsOverlay: (_, game) => Positioned( + bottom: 0, + left: 0, + right: 0, + child: MobileControls(game: game), + ), + PinballGame.replayButtonOverlay: (context, game) => + const Positioned( + bottom: 20, + right: 0, + left: 0, + child: ReplayButtonOverlay(), + ) }, ), ), diff --git a/lib/game/view/widgets/replay_button_overlay.dart b/lib/game/view/widgets/replay_button_overlay.dart index c0b2a67d..806f6ed7 100644 --- a/lib/game/view/widgets/replay_button_overlay.dart +++ b/lib/game/view/widgets/replay_button_overlay.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:pinball/game/game.dart'; import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/start_game/start_game.dart'; import 'package:pinball_ui/pinball_ui.dart'; @@ -18,6 +19,7 @@ class ReplayButtonOverlay extends StatelessWidget { return PinballButton( text: l10n.replay, onTap: () { + context.read().add(const GameStarted()); context.read().add(const ReplayTapped()); }, ); diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 64093ac6..6b6e55aa 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -213,7 +213,7 @@ "@socialMediaAccount": { "description": "Text displayed on share screen for description" }, - "iGotScoreAtPinball": "I got {score} at the #IOPinball machine, can you beat my score? See you at #GoogleIO!", + "iGotScoreAtPinball": "I got {score} points in #IOPinball, can you beat my score? \nSee you at #GoogleIO!", "@iGotScoreAtPinball": { "description": "Text to share score on Social Network", "placeholders": { diff --git a/packages/pinball_components/lib/src/components/android_animatronic.dart b/packages/pinball_components/lib/src/components/android_animatronic/android_animatronic.dart similarity index 83% rename from packages/pinball_components/lib/src/components/android_animatronic.dart rename to packages/pinball_components/lib/src/components/android_animatronic/android_animatronic.dart index 772d88c4..c78b387c 100644 --- a/packages/pinball_components/lib/src/components/android_animatronic.dart +++ b/packages/pinball_components/lib/src/components/android_animatronic/android_animatronic.dart @@ -1,6 +1,8 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flutter/material.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_components/src/components/android_animatronic/behaviors/behaviors.dart'; import 'package:pinball_flame/pinball_flame.dart'; /// {@template android_animatronic} @@ -13,6 +15,7 @@ class AndroidAnimatronic extends BodyComponent : super( children: [ _AndroidAnimatronicSpriteAnimationComponent(), + AndroidAnimatronicBallContactBehavior(), ...?children, ], renderBody: false, @@ -21,6 +24,13 @@ class AndroidAnimatronic extends BodyComponent zIndex = ZIndexes.androidHead; } + /// Creates an [AndroidAnimatronic] without any children. + /// + /// This can be used for testing [AndroidAnimatronic]'s behaviors in + /// isolation. + @visibleForTesting + AndroidAnimatronic.test(); + @override Body createBody() { final shape = EllipseShape( diff --git a/packages/pinball_components/lib/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior.dart.dart b/packages/pinball_components/lib/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior.dart.dart similarity index 58% rename from packages/pinball_components/lib/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior.dart.dart rename to packages/pinball_components/lib/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior.dart.dart index b577b7b3..6c74e21a 100644 --- a/packages/pinball_components/lib/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior.dart.dart +++ b/packages/pinball_components/lib/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior.dart.dart @@ -1,18 +1,15 @@ // ignore_for_file: public_member_api_docs -import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; -class AndroidSpaceshipEntranceBallContactBehavior - extends ContactBehavior - with FlameBlocReader { +class AndroidAnimatronicBallContactBehavior + extends ContactBehavior { @override void beginContact(Object other, Contact contact) { super.beginContact(other, contact); if (other is! Ball) return; - - bloc.onBallEntered(); + readBloc().onBallContacted(); } } diff --git a/packages/pinball_components/lib/src/components/android_animatronic/behaviors/behaviors.dart b/packages/pinball_components/lib/src/components/android_animatronic/behaviors/behaviors.dart new file mode 100644 index 00000000..e85e749f --- /dev/null +++ b/packages/pinball_components/lib/src/components/android_animatronic/behaviors/behaviors.dart @@ -0,0 +1 @@ +export 'android_animatronic_ball_contact_behavior.dart.dart'; diff --git a/packages/pinball_components/lib/src/components/android_spaceship/android_spaceship.dart b/packages/pinball_components/lib/src/components/android_spaceship/android_spaceship.dart index 0fd4628d..d09ff1e4 100644 --- a/packages/pinball_components/lib/src/components/android_spaceship/android_spaceship.dart +++ b/packages/pinball_components/lib/src/components/android_spaceship/android_spaceship.dart @@ -5,7 +5,6 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; import 'package:pinball_components/pinball_components.dart'; -import 'package:pinball_components/src/components/android_spaceship/behaviors/behaviors.dart'; import 'package:pinball_flame/pinball_flame.dart'; export 'cubit/android_spaceship_cubit.dart'; @@ -17,9 +16,6 @@ class AndroidSpaceship extends Component { _SpaceshipSaucer()..initialPosition = position, _SpaceshipSaucerSpriteAnimationComponent()..position = position, _LightBeamSpriteComponent()..position = position + Vector2(2.5, 5), - AndroidSpaceshipEntrance( - children: [AndroidSpaceshipEntranceBallContactBehavior()], - ), _SpaceshipHole( outsideLayer: Layer.spaceshipExitRail, outsidePriority: ZIndexes.ballOnSpaceshipRail, @@ -134,35 +130,6 @@ class _LightBeamSpriteComponent extends SpriteComponent } } -class AndroidSpaceshipEntrance extends BodyComponent - with ParentIsA, Layered { - AndroidSpaceshipEntrance({Iterable? children}) - : super( - children: children, - renderBody: false, - ) { - layer = Layer.spaceship; - } - - @override - Body createBody() { - final shape = PolygonShape() - ..setAsBox( - 2, - 0.1, - Vector2(-27.4, -37.2), - -0.12, - ); - final fixtureDef = FixtureDef( - shape, - isSensor: true, - ); - final bodyDef = BodyDef(); - - return world.createBody(bodyDef)..createFixture(fixtureDef); - } -} - class _SpaceshipHole extends LayerSensor { _SpaceshipHole({required Layer outsideLayer, required int outsidePriority}) : super( diff --git a/packages/pinball_components/lib/src/components/android_spaceship/behaviors/behaviors.dart b/packages/pinball_components/lib/src/components/android_spaceship/behaviors/behaviors.dart deleted file mode 100644 index cbf54e5d..00000000 --- a/packages/pinball_components/lib/src/components/android_spaceship/behaviors/behaviors.dart +++ /dev/null @@ -1 +0,0 @@ -export 'android_spaceship_entrance_ball_contact_behavior.dart.dart'; diff --git a/packages/pinball_components/lib/src/components/android_spaceship/cubit/android_spaceship_cubit.dart b/packages/pinball_components/lib/src/components/android_spaceship/cubit/android_spaceship_cubit.dart index 334c9cc3..5057d742 100644 --- a/packages/pinball_components/lib/src/components/android_spaceship/cubit/android_spaceship_cubit.dart +++ b/packages/pinball_components/lib/src/components/android_spaceship/cubit/android_spaceship_cubit.dart @@ -5,7 +5,7 @@ part 'android_spaceship_state.dart'; class AndroidSpaceshipCubit extends Cubit { AndroidSpaceshipCubit() : super(AndroidSpaceshipState.withoutBonus); - void onBallEntered() => emit(AndroidSpaceshipState.withBonus); + void onBallContacted() => emit(AndroidSpaceshipState.withBonus); void onBonusAwarded() => emit(AndroidSpaceshipState.withoutBonus); } diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 8fd74268..63684921 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -1,4 +1,4 @@ -export 'android_animatronic.dart'; +export 'android_animatronic/android_animatronic.dart'; export 'android_bumper/android_bumper.dart'; export 'android_spaceship/android_spaceship.dart'; export 'arcade_background/arcade_background.dart'; diff --git a/packages/pinball_components/lib/src/components/google_word/behaviors/google_word_animating_behavior.dart b/packages/pinball_components/lib/src/components/google_word/behaviors/google_word_animating_behavior.dart index c16d4a2e..2119c2f8 100644 --- a/packages/pinball_components/lib/src/components/google_word/behaviors/google_word_animating_behavior.dart +++ b/packages/pinball_components/lib/src/components/google_word/behaviors/google_word_animating_behavior.dart @@ -17,7 +17,7 @@ class GoogleWordAnimatingBehavior extends TimerComponent _blinks++; } else { timer.stop(); - bloc.onAnimationFinished(); + bloc.onReset(); shouldRemove = true; } } diff --git a/packages/pinball_components/lib/src/components/google_word/cubit/google_word_cubit.dart b/packages/pinball_components/lib/src/components/google_word/cubit/google_word_cubit.dart index 8a8b976d..cd69fc9d 100644 --- a/packages/pinball_components/lib/src/components/google_word/cubit/google_word_cubit.dart +++ b/packages/pinball_components/lib/src/components/google_word/cubit/google_word_cubit.dart @@ -68,7 +68,7 @@ class GoogleWordCubit extends Cubit { ); } - void onAnimationFinished() { + void onReset() { emit(GoogleWordState.initial()); _lastLitLetter = 0; } diff --git a/packages/pinball_components/test/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior_test.dart b/packages/pinball_components/test/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior_test.dart similarity index 69% rename from packages/pinball_components/test/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior_test.dart rename to packages/pinball_components/test/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior_test.dart index 4b0f16ea..4d8bb675 100644 --- a/packages/pinball_components/test/src/components/android_spaceship/behaviors/android_spaceship_entrance_ball_contact_behavior_test.dart +++ b/packages/pinball_components/test/src/components/android_animatronic/behaviors/android_animatronic_ball_contact_behavior_test.dart @@ -7,7 +7,7 @@ import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:pinball_components/pinball_components.dart'; -import 'package:pinball_components/src/components/android_spaceship/behaviors/behaviors.dart'; +import 'package:pinball_components/src/components/android_animatronic/behaviors/behaviors.dart'; import '../../../../helpers/helpers.dart'; @@ -23,19 +23,19 @@ void main() { final flameTester = FlameTester(TestGame.new); group( - 'AndroidSpaceshipEntranceBallContactBehavior', + 'AndroidAnimatronicBallContactBehavior', () { test('can be instantiated', () { expect( - AndroidSpaceshipEntranceBallContactBehavior(), - isA(), + AndroidAnimatronicBallContactBehavior(), + isA(), ); }); flameTester.test( - 'beginContact calls onBallEntered when entrance contacts with a ball', + 'beginContact calls onBallContacted when in contact with a ball', (game) async { - final behavior = AndroidSpaceshipEntranceBallContactBehavior(); + final behavior = AndroidAnimatronicBallContactBehavior(); final bloc = _MockAndroidSpaceshipCubit(); whenListen( bloc, @@ -43,20 +43,20 @@ void main() { initialState: AndroidSpaceshipState.withoutBonus, ); - final entrance = AndroidSpaceshipEntrance(); + final animatronic = AndroidAnimatronic.test(); final androidSpaceship = FlameBlocProvider.value( value: bloc, children: [ - AndroidSpaceship.test(children: [entrance]) + AndroidSpaceship.test(children: [animatronic]) ], ); - await entrance.add(behavior); + await animatronic.add(behavior); await game.ensureAdd(androidSpaceship); behavior.beginContact(_MockBall(), _MockContact()); - verify(bloc.onBallEntered).called(1); + verify(bloc.onBallContacted).called(1); }, ); }, diff --git a/packages/pinball_components/test/src/components/android_animatronic_test.dart b/packages/pinball_components/test/src/components/android_animatronic_test.dart index 65114778..55b564fe 100644 --- a/packages/pinball_components/test/src/components/android_animatronic_test.dart +++ b/packages/pinball_components/test/src/components/android_animatronic_test.dart @@ -4,6 +4,7 @@ import 'package:flame/components.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_components/src/components/android_animatronic/behaviors/behaviors.dart'; import '../../helpers/helpers.dart'; @@ -58,13 +59,26 @@ void main() { }, ); - flameTester.test('adds new children', (game) async { - final component = Component(); - final androidAnimatronic = AndroidAnimatronic( - children: [component], - ); - await game.ensureAdd(androidAnimatronic); - expect(androidAnimatronic.children, contains(component)); + group('adds', () { + flameTester.test('new children', (game) async { + final component = Component(); + final androidAnimatronic = AndroidAnimatronic( + children: [component], + ); + await game.ensureAdd(androidAnimatronic); + expect(androidAnimatronic.children, contains(component)); + }); + + flameTester.test('a AndroidAnimatronicBallContactBehavior', (game) async { + final androidAnimatronic = AndroidAnimatronic(); + await game.ensureAdd(androidAnimatronic); + expect( + androidAnimatronic.children + .whereType() + .single, + isNotNull, + ); + }); }); }); } diff --git a/packages/pinball_components/test/src/components/android_spaceship/android_spaceship_test.dart b/packages/pinball_components/test/src/components/android_spaceship/android_spaceship_test.dart index 70edd32e..a282865c 100644 --- a/packages/pinball_components/test/src/components/android_spaceship/android_spaceship_test.dart +++ b/packages/pinball_components/test/src/components/android_spaceship/android_spaceship_test.dart @@ -6,7 +6,6 @@ import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:pinball_components/pinball_components.dart'; -import 'package:pinball_components/src/components/android_spaceship/behaviors/behaviors.dart'; import 'package:pinball_flame/pinball_flame.dart'; import '../../../helpers/helpers.dart'; @@ -84,26 +83,5 @@ void main() { ); }, ); - - flameTester.test( - 'AndroidSpaceshipEntrance has an ' - 'AndroidSpaceshipEntranceBallContactBehavior', (game) async { - final androidSpaceship = AndroidSpaceship(position: Vector2.zero()); - final provider = - FlameBlocProvider.value( - value: bloc, - children: [androidSpaceship], - ); - await game.ensureAdd(provider); - - final androidSpaceshipEntrance = - androidSpaceship.firstChild(); - expect( - androidSpaceshipEntrance!.children - .whereType() - .single, - isNotNull, - ); - }); }); } diff --git a/packages/pinball_components/test/src/components/android_spaceship/cubit/android_spaceship_cubit_test.dart b/packages/pinball_components/test/src/components/android_spaceship/cubit/android_spaceship_cubit_test.dart index 47b763af..f7de3674 100644 --- a/packages/pinball_components/test/src/components/android_spaceship/cubit/android_spaceship_cubit_test.dart +++ b/packages/pinball_components/test/src/components/android_spaceship/cubit/android_spaceship_cubit_test.dart @@ -9,7 +9,7 @@ void main() { blocTest( 'onBallEntered emits withBonus', build: AndroidSpaceshipCubit.new, - act: (bloc) => bloc.onBallEntered(), + act: (bloc) => bloc.onBallContacted(), expect: () => [AndroidSpaceshipState.withBonus], ); diff --git a/packages/pinball_components/test/src/components/google_word/behaviors/google_word_animating_behavior_test.dart b/packages/pinball_components/test/src/components/google_word/behaviors/google_word_animating_behavior_test.dart index 7224aeed..6275678c 100644 --- a/packages/pinball_components/test/src/components/google_word/behaviors/google_word_animating_behavior_test.dart +++ b/packages/pinball_components/test/src/components/google_word/behaviors/google_word_animating_behavior_test.dart @@ -41,7 +41,7 @@ void main() { ); flameTester.testGameWidget( - 'calls onAnimationFinished and removes itself ' + 'calls onReset and removes itself ' 'after all blinks complete', setUp: (game, tester) async { final behavior = GoogleWordAnimatingBehavior(); @@ -53,7 +53,7 @@ void main() { } await game.ready(); - verify(bloc.onAnimationFinished).called(1); + verify(bloc.onReset).called(1); expect( game.descendants().whereType().isEmpty, isTrue, diff --git a/packages/pinball_components/test/src/components/google_word/cubit/google_word_cubit_test.dart b/packages/pinball_components/test/src/components/google_word/cubit/google_word_cubit_test.dart index b5000387..152b5f96 100644 --- a/packages/pinball_components/test/src/components/google_word/cubit/google_word_cubit_test.dart +++ b/packages/pinball_components/test/src/components/google_word/cubit/google_word_cubit_test.dart @@ -62,9 +62,9 @@ void main() { ); blocTest( - 'onAnimationFinished emits initial state', + 'onReset emits initial state', build: GoogleWordCubit.new, - act: (bloc) => bloc.onAnimationFinished(), + act: (bloc) => bloc.onReset(), expect: () => [GoogleWordState.initial()], ); }, diff --git a/test/game/components/backbox/displays/game_over_info_display_test.dart b/test/game/components/backbox/displays/game_over_info_display_test.dart index 2bee4005..bb092347 100644 --- a/test/game/components/backbox/displays/game_over_info_display_test.dart +++ b/test/game/components/backbox/displays/game_over_info_display_test.dart @@ -176,7 +176,7 @@ void main() { final openSourceLink = component.descendants().whereType().first; - openSourceLink.onTapDown(_MockTapDownInfo()); + openSourceLink.onTapUp(_MockTapUpInfo()); await game.ready(); diff --git a/test/game/components/game_bloc_status_listener_test.dart b/test/game/components/game_bloc_status_listener_test.dart index 3519dbbd..874f901c 100644 --- a/test/game/components/game_bloc_status_listener_test.dart +++ b/test/game/components/game_bloc_status_listener_test.dart @@ -37,6 +37,7 @@ class _TestGame extends Forge2DGame with HasTappables { Iterable children, { PinballAudioPlayer? pinballAudioPlayer, PlatformHelper? platformHelper, + GoogleWordCubit? googleWordBloc, }) async { return ensureAdd( FlameMultiBlocProvider( @@ -47,6 +48,9 @@ class _TestGame extends Forge2DGame with HasTappables { FlameBlocProvider.value( value: CharacterThemeCubit(), ), + FlameBlocProvider.value( + value: googleWordBloc ?? GoogleWordCubit(), + ), ], children: [ MultiFlameProvider( @@ -80,6 +84,8 @@ class _MockPlatformHelper extends Mock implements PlatformHelper {} class _MockPlungerCubit extends Mock implements PlungerCubit {} +class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {} + class _MockAppLocalizations extends Mock implements AppLocalizations { @override String get score => ''; @@ -332,6 +338,20 @@ void main() { }, ); + flameTester.test( + 'resets the GoogleWordCubit', + (game) async { + final googleWordBloc = _MockGoogleWordCubit(); + final component = GameBlocStatusListener(); + await game.pump([component], googleWordBloc: googleWordBloc); + + expect(state.status, equals(GameStatus.playing)); + component.onNewState(state); + + verify(googleWordBloc.onReset).called(1); + }, + ); + flameTester.test( 'adds FlipperKeyControllingBehavior to Flippers', (game) async { diff --git a/test/game/components/google_gallery/behaviors/google_word_bonus_behavior_test.dart b/test/game/components/google_gallery/behaviors/google_word_bonus_behavior_test.dart index acabe4c7..17726156 100644 --- a/test/game/components/google_gallery/behaviors/google_word_bonus_behavior_test.dart +++ b/test/game/components/google_gallery/behaviors/google_word_bonus_behavior_test.dart @@ -75,7 +75,7 @@ void main() { flameTester.testGameWidget( 'adds GameBonus.googleWord to the game when all letters ' - 'in google word are activated and calls onBonusAwarded', + 'in google word are activated and calls onReset', setUp: (game, tester) async { final behavior = GoogleWordBonusBehavior(); final parent = GoogleGallery.test(); @@ -114,7 +114,7 @@ void main() { verify( () => gameBloc.add(const BonusActivated(GameBonus.googleWord)), ).called(1); - verify(googleWordBloc.onBonusAwarded).called(1); + verify(googleWordBloc.onReset).called(1); }, ); diff --git a/test/game/view/pinball_game_page_test.dart b/test/game/view/pinball_game_page_test.dart index a0a0f22c..669117ed 100644 --- a/test/game/view/pinball_game_page_test.dart +++ b/test/game/view/pinball_game_page_test.dart @@ -307,6 +307,23 @@ void main() { expect(find.byType(MobileControls), findsOneWidget); }); + testWidgets( + 'ReplayButtonOverlay when the overlay is added', + (tester) async { + await tester.pumpApp( + PinballGameView(game), + gameBloc: gameBloc, + startGameBloc: startGameBloc, + ); + + game.overlays.add(PinballGame.replayButtonOverlay); + + await tester.pump(); + + expect(find.byType(ReplayButtonOverlay), findsOneWidget); + }, + ); + group('info icon', () { testWidgets('renders on game over', (tester) async { final gameState = GameState.initial().copyWith( diff --git a/test/game/view/widgets/replay_button_overlay_test.dart b/test/game/view/widgets/replay_button_overlay_test.dart index 1497031a..5c3e4884 100644 --- a/test/game/view/widgets/replay_button_overlay_test.dart +++ b/test/game/view/widgets/replay_button_overlay_test.dart @@ -8,24 +8,32 @@ import '../../../helpers/helpers.dart'; class _MockStartGameBloc extends Mock implements StartGameBloc {} +class _MockGameBloc extends Mock implements GameBloc {} + void main() { group('ReplayButtonOverlay', () { late StartGameBloc startGameBloc; + late _MockGameBloc gameBloc; setUp(() async { await mockFlameImages(); startGameBloc = _MockStartGameBloc(); + gameBloc = _MockGameBloc(); whenListen( startGameBloc, Stream.value(const StartGameState.initial()), initialState: const StartGameState.initial(), ); + whenListen( + gameBloc, + Stream.value(const GameState.initial()), + initialState: const GameState.initial(), + ); }); testWidgets('renders correctly', (tester) async { await tester.pumpApp(const ReplayButtonOverlay()); - expect(find.text('Replay'), findsOneWidget); }); @@ -33,6 +41,7 @@ void main() { (tester) async { await tester.pumpApp( const ReplayButtonOverlay(), + gameBloc: gameBloc, startGameBloc: startGameBloc, ); @@ -41,5 +50,19 @@ void main() { verify(() => startGameBloc.add(const ReplayTapped())).called(1); }); + + testWidgets('adds GameStarted event to GameBloc when tapped', + (tester) async { + await tester.pumpApp( + const ReplayButtonOverlay(), + gameBloc: gameBloc, + startGameBloc: startGameBloc, + ); + + await tester.tap(find.text('Replay')); + await tester.pump(); + + verify(() => gameBloc.add(const GameStarted())).called(1); + }); }); }