mirror of https://github.com/flutter/pinball.git
commit
570bc4773a
@ -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/select_character/select_character.dart';
|
||||
import 'package:pinball/start_game/start_game.dart';
|
||||
import 'package:pinball/theme/theme.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);
|
||||
break;
|
||||
case StartGameStatus.howToPlay:
|
||||
_onHowToPlay(context);
|
||||
break;
|
||||
case StartGameStatus.play:
|
||||
_game.gameFlowController.start();
|
||||
break;
|
||||
}
|
||||
},
|
||||
child: _child,
|
||||
);
|
||||
}
|
||||
|
||||
void _onSelectCharacter(BuildContext context) {
|
||||
_showPinballDialog(
|
||||
context: context,
|
||||
child: const CharacterSelectionDialog(),
|
||||
barrierDismissible: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onHowToPlay(BuildContext context) async {
|
||||
_showPinballDialog(
|
||||
context: context,
|
||||
child: HowToPlayDialog(
|
||||
onDismissCallback: () {
|
||||
// We need to add a delay between closing the dialog and starting the
|
||||
// game.
|
||||
Future.delayed(
|
||||
kThemeAnimationDuration,
|
||||
() => context.read<StartGameBloc>().add(const HowToPlayFinished()),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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: AppColors.transparent,
|
||||
barrierDismissible: barrierDismissible,
|
||||
builder: (_) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
height: gameWidgetWidth,
|
||||
width: gameWidgetWidth,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
@ -1 +1,2 @@
|
||||
export 'how_to_play_dialog.dart';
|
||||
export 'start_game_listener.dart';
|
||||
|
@ -1,46 +1,42 @@
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:pinball/game/game.dart';
|
||||
import 'package:pinball/select_character/select_character.dart';
|
||||
import 'package:pinball/start_game/bloc/start_game_bloc.dart';
|
||||
|
||||
import '../../../helpers/helpers.dart';
|
||||
|
||||
void main() {
|
||||
group('PlayButtonOverlay', () {
|
||||
late PinballGame game;
|
||||
late GameFlowController gameFlowController;
|
||||
late StartGameBloc startGameBloc;
|
||||
|
||||
setUp(() {
|
||||
game = MockPinballGame();
|
||||
gameFlowController = MockGameFlowController();
|
||||
startGameBloc = MockStartGameBloc();
|
||||
|
||||
when(() => game.gameFlowController).thenReturn(gameFlowController);
|
||||
when(gameFlowController.start).thenAnswer((_) {});
|
||||
whenListen(
|
||||
startGameBloc,
|
||||
Stream.value(const StartGameState.initial()),
|
||||
initialState: const StartGameState.initial(),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('renders correctly', (tester) async {
|
||||
await tester.pumpApp(PlayButtonOverlay(game: game));
|
||||
await tester.pumpApp(const PlayButtonOverlay());
|
||||
|
||||
expect(find.text('Play'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls gameFlowController.start when taped', (tester) async {
|
||||
await tester.pumpApp(PlayButtonOverlay(game: game));
|
||||
|
||||
await tester.tap(find.text('Play'));
|
||||
await tester.pump();
|
||||
|
||||
verify(gameFlowController.start).called(1);
|
||||
});
|
||||
|
||||
testWidgets('displays CharacterSelectionDialog when tapped',
|
||||
testWidgets('adds PlayTapped event to StartGameBloc when taped',
|
||||
(tester) async {
|
||||
await tester.pumpApp(PlayButtonOverlay(game: game));
|
||||
await tester.pumpApp(
|
||||
const PlayButtonOverlay(),
|
||||
startGameBloc: startGameBloc,
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Play'));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(CharacterSelectionDialog), findsOneWidget);
|
||||
verify(() => startGameBloc.add(const PlayTapped())).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,178 @@
|
||||
import 'package:bloc_test/bloc_test.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/select_character/select_character.dart';
|
||||
import 'package:pinball/start_game/start_game.dart';
|
||||
|
||||
import '../../helpers/helpers.dart';
|
||||
|
||||
void main() {
|
||||
late StartGameBloc startGameBloc;
|
||||
late PinballGame pinballGame;
|
||||
|
||||
group('StartGameListener', () {
|
||||
setUp(() {
|
||||
startGameBloc = MockStartGameBloc();
|
||||
pinballGame = MockPinballGame();
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'on selectCharacter status shows SelectCharacter dialog',
|
||||
(tester) async {
|
||||
whenListen(
|
||||
startGameBloc,
|
||||
Stream.value(
|
||||
const StartGameState(status: StartGameStatus.selectCharacter),
|
||||
),
|
||||
initialState: const StartGameState.initial(),
|
||||
);
|
||||
|
||||
await tester.pumpApp(
|
||||
StartGameListener(
|
||||
game: pinballGame,
|
||||
child: const SizedBox.shrink(),
|
||||
),
|
||||
startGameBloc: startGameBloc,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
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(
|
||||
'on play status call start on game controller',
|
||||
(tester) async {
|
||||
whenListen(
|
||||
startGameBloc,
|
||||
Stream.value(
|
||||
const StartGameState(status: StartGameStatus.play),
|
||||
),
|
||||
initialState: const StartGameState.initial(),
|
||||
);
|
||||
|
||||
final gameController = MockGameFlowController();
|
||||
when(() => pinballGame.gameFlowController)
|
||||
.thenAnswer((invocation) => gameController);
|
||||
|
||||
await tester.pumpApp(
|
||||
StartGameListener(
|
||||
game: pinballGame,
|
||||
child: const SizedBox.shrink(),
|
||||
),
|
||||
startGameBloc: startGameBloc,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle(kThemeAnimationDuration);
|
||||
await tester.pumpAndSettle(kThemeAnimationDuration);
|
||||
|
||||
verify(gameController.start).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
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,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'adds HowToPlayFinished event after closing HowToPlayDialog',
|
||||
(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,
|
||||
);
|
||||
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);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
Loading…
Reference in new issue