From 094ff34f33a2d44aeaf3a307cc40a9e0f0633060 Mon Sep 17 00:00:00 2001 From: alestiago Date: Thu, 5 May 2022 15:31:39 +0100 Subject: [PATCH] test: coverage --- lib/game/bloc/game_state.dart | 1 - test/game/bloc/game_bloc_test.dart | 14 ++ test/game/bloc/game_event_test.dart | 26 ++++ .../components/game_bloc_status_listener.dart | 123 ---------------- .../game_bloc_status_listener_test.dart | 138 ++++++++++++++++++ test/game/view/widgets/score_view_test.dart | 4 +- 6 files changed, 179 insertions(+), 127 deletions(-) delete mode 100644 test/game/components/game_bloc_status_listener.dart create mode 100644 test/game/components/game_bloc_status_listener_test.dart diff --git a/lib/game/bloc/game_state.dart b/lib/game/bloc/game_state.dart index d0311442..a9e86720 100644 --- a/lib/game/bloc/game_state.dart +++ b/lib/game/bloc/game_state.dart @@ -27,7 +27,6 @@ enum GameStatus { } extension GameStatusX on GameStatus { - bool get isWaiting => this == GameStatus.waiting; bool get isPlaying => this == GameStatus.playing; bool get isGameOver => this == GameStatus.gameOver; } diff --git a/test/game/bloc/game_bloc_test.dart b/test/game/bloc/game_bloc_test.dart index cd578b17..3e5abb74 100644 --- a/test/game/bloc/game_bloc_test.dart +++ b/test/game/bloc/game_bloc_test.dart @@ -24,6 +24,20 @@ void main() { ], ); + blocTest( + 'GameOver finishes the game', + build: GameBloc.new, + act: (bloc) => bloc.add(const GameOver()), + expect: () => [ + isA() + ..having( + (state) => state.status, + 'status', + GameStatus.gameOver, + ), + ], + ); + group('RoundLost', () { blocTest( 'decreases number of rounds ' diff --git a/test/game/bloc/game_event_test.dart b/test/game/bloc/game_event_test.dart index 6a39bd67..c4de5792 100644 --- a/test/game/bloc/game_event_test.dart +++ b/test/game/bloc/game_event_test.dart @@ -72,6 +72,32 @@ void main() { }); }); + group('GameStarted', () { + test('can be instantiated', () { + expect(const GameStarted(), isNotNull); + }); + + test('supports value equality', () { + expect( + GameStarted(), + equals(const GameStarted()), + ); + }); + }); + + group('GameOver', () { + test('can be instantiated', () { + expect(const GameOver(), isNotNull); + }); + + test('supports value equality', () { + expect( + GameOver(), + equals(const GameOver()), + ); + }); + }); + group('SparkyTurboChargeActivated', () { test('can be instantiated', () { expect(const SparkyTurboChargeActivated(), isNotNull); diff --git a/test/game/components/game_bloc_status_listener.dart b/test/game/components/game_bloc_status_listener.dart deleted file mode 100644 index 57622200..00000000 --- a/test/game/components/game_bloc_status_listener.dart +++ /dev/null @@ -1,123 +0,0 @@ -// ignore_for_file: type_annotate_public_apis, prefer_const_constructors - -import 'package:flame/game.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:pinball/game/game.dart'; -import 'package:pinball_audio/pinball_audio.dart'; -import 'package:pinball_theme/pinball_theme.dart'; - -class _MockPinballGame extends Mock implements PinballGame {} - -class _MockBackbox extends Mock implements Backbox {} - -class _MockCameraController extends Mock implements CameraController {} - -class _MockActiveOverlaysNotifier extends Mock - implements ActiveOverlaysNotifier {} - -class _MockPinballAudio extends Mock implements PinballAudio {} - -void main() { - group('GameBlocStatusListener', () { - group('listenWhen', () { - test('is true when the game over state has changed', () { - final state = GameState( - totalScore: 0, - roundScore: 10, - multiplier: 1, - rounds: 0, - bonusHistory: const [], - status: GameStatus.playing, - ); - - final previous = GameState.initial(); - expect( - GameBlocStatusListener().listenWhen(previous, state), - isTrue, - ); - }); - }); - - group('onNewState', () { - late PinballGame game; - late Backbox backbox; - late CameraController cameraController; - late GameBlocStatusListener gameFlowController; - late PinballAudio pinballAudio; - late ActiveOverlaysNotifier overlays; - - setUp(() { - game = _MockPinballGame(); - backbox = _MockBackbox(); - cameraController = _MockCameraController(); - gameFlowController = GameBlocStatusListener(); - overlays = _MockActiveOverlaysNotifier(); - pinballAudio = _MockPinballAudio(); - - when( - () => backbox.initialsInput( - score: any(named: 'score'), - characterIconPath: any(named: 'characterIconPath'), - onSubmit: any(named: 'onSubmit'), - ), - ).thenAnswer((_) async {}); - when(cameraController.focusOnWaitingBackbox).thenAnswer((_) async {}); - when(cameraController.focusOnGame).thenAnswer((_) async {}); - - when(() => overlays.remove(any())).thenAnswer((_) => true); - - when(() => game.descendants().whereType()) - .thenReturn([backbox]); - when(game.firstChild).thenReturn(cameraController); - when(() => game.overlays).thenReturn(overlays); - when(() => game.characterTheme).thenReturn(DashTheme()); - when(() => game.audio).thenReturn(pinballAudio); - }); - - test( - 'changes the backbox display and camera correctly ' - 'when the game is over', - () { - gameFlowController.onNewState( - GameState( - totalScore: 0, - roundScore: 10, - multiplier: 1, - rounds: 0, - bonusHistory: const [], - status: GameStatus.gameOver, - ), - ); - - verify( - () => backbox.initialsInput( - score: 0, - characterIconPath: any(named: 'characterIconPath'), - onSubmit: any(named: 'onSubmit'), - ), - ).called(1); - verify(cameraController.focusOnGameOverBackbox).called(1); - }, - ); - - test( - 'changes the backbox and camera correctly when it is not a game over', - () { - gameFlowController.onNewState(GameState.initial()); - verify(cameraController.focusOnGame).called(1); - verify(() => overlays.remove(PinballGame.playButtonOverlay)) - .called(1); - }, - ); - - test( - 'plays the background music on start', - () { - gameFlowController.onNewState(GameState.initial()); - verify(pinballAudio.backgroundMusic).called(1); - }, - ); - }); - }); -} diff --git a/test/game/components/game_bloc_status_listener_test.dart b/test/game/components/game_bloc_status_listener_test.dart new file mode 100644 index 00000000..d6234f33 --- /dev/null +++ b/test/game/components/game_bloc_status_listener_test.dart @@ -0,0 +1,138 @@ +// ignore_for_file: type_annotate_public_apis, prefer_const_constructors + +import 'package:flame/game.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball/game/game.dart'; +import 'package:pinball_audio/pinball_audio.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +class _MockPinballGame extends Mock implements PinballGame {} + +class _MockBackbox extends Mock implements Backbox {} + +class _MockCameraController extends Mock implements CameraController {} + +class _MockActiveOverlaysNotifier extends Mock + implements ActiveOverlaysNotifier {} + +class _MockPinballAudio extends Mock implements PinballAudio {} + +void main() { + group('GameBlocStatusListener', () { + group('listenWhen', () { + test('is true when the game over state has changed', () { + final state = GameState( + totalScore: 0, + roundScore: 10, + multiplier: 1, + rounds: 0, + bonusHistory: const [], + status: GameStatus.playing, + ); + + final previous = GameState.initial(); + expect( + GameBlocStatusListener().listenWhen(previous, state), + isTrue, + ); + }); + }); + + group('onNewState', () { + late PinballGame game; + late Backbox backbox; + late CameraController cameraController; + late GameBlocStatusListener gameBlocStatusListener; + late PinballAudio pinballAudio; + late ActiveOverlaysNotifier overlays; + + group('onNewState', () { + late PinballGame game; + late Backbox backbox; + late CameraController cameraController; + late GameBlocStatusListener gameFlowController; + late PinballAudio pinballAudio; + late ActiveOverlaysNotifier overlays; + + setUp(() { + game = _MockPinballGame(); + backbox = _MockBackbox(); + cameraController = _MockCameraController(); + gameFlowController = GameBlocStatusListener(); + overlays = _MockActiveOverlaysNotifier(); + pinballAudio = _MockPinballAudio(); + + gameFlowController.mockGameRef(game); + when( + () => backbox.initialsInput( + score: any(named: 'score'), + characterIconPath: any(named: 'characterIconPath'), + onSubmit: any(named: 'onSubmit'), + ), + ).thenAnswer((_) async {}); + when(cameraController.focusOnWaitingBackbox).thenAnswer((_) async {}); + when(cameraController.focusOnGame).thenAnswer((_) async {}); + + when(() => overlays.remove(any())).thenAnswer((_) => true); + + when(() => game.descendants().whereType()) + .thenReturn([backbox]); + when(game.firstChild).thenReturn(cameraController); + when(() => game.overlays).thenReturn(overlays); + when(() => game.characterTheme).thenReturn(DashTheme()); + when(() => game.audio).thenReturn(pinballAudio); + }); + + test( + 'changes the backbox display and camera correctly ' + 'when the game is over', + () { + final state = GameState( + totalScore: 0, + roundScore: 10, + multiplier: 1, + rounds: 0, + bonusHistory: const [], + status: GameStatus.gameOver, + ); + gameFlowController.onNewState(state); + + verify( + () => backbox.initialsInput( + score: state.displayScore, + characterIconPath: any(named: 'characterIconPath'), + onSubmit: any(named: 'onSubmit'), + ), + ).called(1); + verify(cameraController.focusOnGameOverBackbox).called(1); + }, + ); + + test( + 'changes the backbox and camera correctly when it is not a game over', + () { + gameFlowController.onNewState( + GameState.initial().copyWith(status: GameStatus.playing), + ); + + verify(cameraController.focusOnGame).called(1); + verify(() => overlays.remove(PinballGame.playButtonOverlay)) + .called(1); + }, + ); + + test( + 'plays the background music on start', + () { + gameFlowController.onNewState( + GameState.initial().copyWith(status: GameStatus.playing), + ); + + verify(pinballAudio.backgroundMusic).called(1); + }, + ); + }); + }); + }); +} diff --git a/test/game/view/widgets/score_view_test.dart b/test/game/view/widgets/score_view_test.dart index 503ca1cb..18e94c09 100644 --- a/test/game/view/widgets/score_view_test.dart +++ b/test/game/view/widgets/score_view_test.dart @@ -55,9 +55,7 @@ void main() { final l10n = await AppLocalizations.delegate.load(const Locale('en')); stateController.add( - initialState.copyWith( - rounds: 0, - ), + initialState.copyWith(status: GameStatus.gameOver), ); await tester.pumpApp(