chore: create StartGameListener

pull/247/head
arturplaczek 3 years ago
parent dcc1951b47
commit c28c582424

@ -1 +1,2 @@
export 'bloc/start_game_bloc.dart';
export 'widgets/start_game_listener.dart';

@ -0,0 +1,90 @@
// ignore_for_file: public_member_api_docs
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/how_to_play/how_to_play.dart';
import 'package:pinball/select_character/select_character.dart';
import 'package:pinball/start_game/start_game.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_ui/pinball_ui.dart';
class StartGameListener extends StatelessWidget {
const StartGameListener({
Key? key,
required Widget child,
required PinballGame game,
}) : _child = child,
_game = game,
super(key: key);
final Widget _child;
final PinballGame _game;
@override
Widget build(BuildContext context) {
return BlocListener<StartGameBloc, StartGameState>(
listener: (context, state) {
switch (state.status) {
case StartGameStatus.initial:
break;
case StartGameStatus.selectCharacter:
_onSelectCharacter(context);
_game.gameFlowController.start();
break;
case StartGameStatus.howToPlay:
_onHowToPlay(context);
break;
case StartGameStatus.play:
break;
}
},
child: _child,
);
}
void _onSelectCharacter(BuildContext context) {
_showPinballDialog(
context: context,
child: const CharacterSelectionDialog(),
barrierDismissible: false,
);
}
void _onHowToPlay(BuildContext context) {
final audio = context.read<PinballAudio>();
_showPinballDialog(
context: context,
child: HowToPlayDialog(
onDismissCallback: () {
context.read<StartGameBloc>().add(const HowToPlayFinished());
audio.ioPinballVoiceOver();
},
),
);
}
void _showPinballDialog({
required BuildContext context,
required Widget child,
bool barrierDismissible = true,
}) {
final gameWidgetWidth = MediaQuery.of(context).size.height * 9 / 16;
showDialog<void>(
context: context,
barrierColor: PinballColors.transparent,
barrierDismissible: barrierDismissible,
builder: (_) {
return Center(
child: SizedBox(
height: gameWidgetWidth * 0.87,
width: gameWidgetWidth,
child: child,
),
);
},
);
}
}

@ -0,0 +1,275 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:flame/flame.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/how_to_play/how_to_play.dart';
import 'package:pinball/select_character/select_character.dart';
import 'package:pinball/start_game/start_game.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_theme/pinball_theme.dart';
import '../../helpers/helpers.dart';
class _MockStartGameBloc extends Mock implements StartGameBloc {}
class _MockCharacterThemeCubit extends Mock implements CharacterThemeCubit {}
class _MockPinballGame extends Mock implements PinballGame {}
class _MockGameFlowController extends Mock implements GameFlowController {}
class _MockPinballAudio extends Mock implements PinballAudio {}
void main() {
late StartGameBloc startGameBloc;
late PinballGame pinballGame;
late PinballAudio pinballAudio;
late CharacterThemeCubit characterThemeCubit;
group('StartGameListener', () {
setUp(() async {
Flame.images.prefix = '';
await Flame.images.load(const DashTheme().animation.keyName);
await Flame.images.load(const AndroidTheme().animation.keyName);
await Flame.images.load(const DinoTheme().animation.keyName);
await Flame.images.load(const SparkyTheme().animation.keyName);
startGameBloc = _MockStartGameBloc();
pinballGame = _MockPinballGame();
pinballAudio = _MockPinballAudio();
characterThemeCubit = _MockCharacterThemeCubit();
});
group('on selectCharacter status', () {
testWidgets(
'calls start on the game controller',
(tester) async {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.selectCharacter),
),
initialState: const StartGameState.initial(),
);
final gameController = _MockGameFlowController();
when(() => pinballGame.gameFlowController)
.thenAnswer((_) => gameController);
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
);
verify(gameController.start).called(1);
},
);
testWidgets(
'shows SelectCharacter dialog',
(tester) async {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.selectCharacter),
),
initialState: const StartGameState.initial(),
);
whenListen(
characterThemeCubit,
Stream.value(const CharacterThemeState.initial()),
initialState: const CharacterThemeState.initial(),
);
final gameController = _MockGameFlowController();
when(() => pinballGame.gameFlowController)
.thenAnswer((_) => gameController);
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
characterThemeCubit: characterThemeCubit,
);
await tester.pump(kThemeAnimationDuration);
expect(
find.byType(CharacterSelectionDialog),
findsOneWidget,
);
},
);
});
testWidgets(
'on howToPlay status shows HowToPlay dialog',
(tester) async {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.howToPlay),
),
initialState: const StartGameState.initial(),
);
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
);
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsOneWidget,
);
},
);
testWidgets(
'do nothing on play status',
(tester) async {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.play),
),
initialState: const StartGameState.initial(),
);
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
);
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsNothing,
);
expect(
find.byType(CharacterSelectionDialog),
findsNothing,
);
},
);
testWidgets(
'do nothing on initial status',
(tester) async {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.initial),
),
initialState: const StartGameState.initial(),
);
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
);
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsNothing,
);
expect(
find.byType(CharacterSelectionDialog),
findsNothing,
);
},
);
group('on dismiss HowToPlayDialog', () {
setUp(() {
whenListen(
startGameBloc,
Stream.value(
const StartGameState(status: StartGameStatus.howToPlay),
),
initialState: const StartGameState.initial(),
);
});
testWidgets(
'adds HowToPlayFinished event',
(tester) async {
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
);
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsOneWidget,
);
await tester.tapAt(const Offset(1, 1));
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsNothing,
);
await tester.pumpAndSettle();
verify(
() => startGameBloc.add(const HowToPlayFinished()),
).called(1);
},
);
testWidgets(
'plays the I/O Pinball voice over audio',
(tester) async {
await tester.pumpApp(
StartGameListener(
game: pinballGame,
child: const SizedBox.shrink(),
),
startGameBloc: startGameBloc,
pinballAudio: pinballAudio,
);
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsOneWidget,
);
await tester.tapAt(const Offset(1, 1));
await tester.pumpAndSettle();
expect(
find.byType(HowToPlayDialog),
findsNothing,
);
await tester.pumpAndSettle();
verify(pinballAudio.ioPinballVoiceOver).called(1);
},
);
});
});
}
Loading…
Cancel
Save