mirror of https://github.com/flutter/pinball.git
feat: `GameOverInfoDisplay` on game over `Backbox` (#359)
* feat: info screen ui * feat: info screen ui * feat: replay button * feat: added replay button and game flow * feat: game over info display flow at backbox * test: fixed tests and coverage * test: fix tests and coverage * chore: info display doc" * refactor: text component name * Update lib/game/components/backbox/bloc/backbox_state.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/bloc/backbox_state.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/bloc/backbox_state.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/game/components/backbox/displays/info_display_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/start_game/widgets/start_game_listener_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/start_game/widgets/start_game_listener_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/game/view/widgets/replay_button_overlay_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/game/components/backbox/displays/info_display_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/displays/info_display.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/displays/info_display.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/displays/info_display.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/components/backbox/displays/info_display.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/game/view/widgets/replay_button_overlay.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/l10n/arb/app_en.arb Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/game/components/backbox/backbox_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update test/game/components/backbox/bloc/backbox_bloc_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * Update lib/l10n/arb/app_en.arb Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * refactor: changed names and removed replaying * refactor: removed restart logic changes for another pr * feat: link underscore * chore: test fixed, names changed * chore: unused import * feat: add replayButtonOverlay at GameOverInfoDisplay * feat: added open source url url launcher * feat: launch url and test * chore: removed comments * fix: remove overlay for Replay to merge info screen * chore: unused import * test: load images bug fix * Update lib/game/components/backbox/displays/game_over_info_display.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * refactor: removed props from state for sharing only score * feat: moved open links to info display and added link to OS * test: fixed merge tests * chore: unused imports and annotation missed * Update lib/game/components/backbox/bloc/backbox_state.dart * chore: tappables added to cspell Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Co-authored-by: Tom Arra <tarra3@gmail.com>refactor/blinking-behavior
parent
5ebddd37c2
commit
fdb9075738
@ -0,0 +1,311 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pinball/game/game.dart';
|
||||
import 'package:pinball/l10n/l10n.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:pinball_flame/pinball_flame.dart';
|
||||
import 'package:pinball_ui/pinball_ui.dart';
|
||||
import 'package:share_repository/share_repository.dart';
|
||||
|
||||
/// Signature for the callback called when the user tries to share their score
|
||||
/// from the [GameOverInfoDisplay].
|
||||
typedef OnShareTap = void Function();
|
||||
|
||||
final _titleTextPaint = TextPaint(
|
||||
style: const TextStyle(
|
||||
fontSize: 1.6,
|
||||
color: PinballColors.white,
|
||||
fontFamily: PinballFonts.pixeloidSans,
|
||||
),
|
||||
);
|
||||
|
||||
final _titleBoldTextPaint = TextPaint(
|
||||
style: const TextStyle(
|
||||
fontSize: 1.4,
|
||||
color: PinballColors.white,
|
||||
fontFamily: PinballFonts.pixeloidSans,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
);
|
||||
|
||||
final _linkTextPaint = TextPaint(
|
||||
style: const TextStyle(
|
||||
fontSize: 1.7,
|
||||
color: PinballColors.orange,
|
||||
fontFamily: PinballFonts.pixeloidSans,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
);
|
||||
|
||||
final _descriptionTextPaint = TextPaint(
|
||||
style: const TextStyle(
|
||||
fontSize: 1.6,
|
||||
color: PinballColors.white,
|
||||
fontFamily: PinballFonts.pixeloidSans,
|
||||
),
|
||||
);
|
||||
|
||||
/// {@template game_over_info_display}
|
||||
/// Display with links to share your score or go to the IO webpage.
|
||||
/// {@endtemplate}
|
||||
class GameOverInfoDisplay extends Component with HasGameRef {
|
||||
/// {@macro game_over_info_display}
|
||||
GameOverInfoDisplay({
|
||||
OnShareTap? onShare,
|
||||
}) : super(
|
||||
children: [
|
||||
_InstructionsComponent(
|
||||
onShare: onShare,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
gameRef.overlays.add(PinballGame.playButtonOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
class _InstructionsComponent extends PositionComponent with HasGameRef {
|
||||
_InstructionsComponent({
|
||||
OnShareTap? onShare,
|
||||
}) : super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, -25),
|
||||
children: [
|
||||
_TitleComponent(),
|
||||
_LinksComponent(
|
||||
onShare: onShare,
|
||||
),
|
||||
_DescriptionComponent(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _TitleComponent extends PositionComponent with HasGameRef {
|
||||
_TitleComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, 3),
|
||||
children: [
|
||||
_TitleBackgroundSpriteComponent(),
|
||||
_ShareScoreTextComponent(),
|
||||
_ChallengeFriendsTextComponent(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _ShareScoreTextComponent extends TextComponent with HasGameRef {
|
||||
_ShareScoreTextComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, -1.5),
|
||||
textRenderer: _titleTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
text = readProvider<AppLocalizations>().shareYourScore;
|
||||
}
|
||||
}
|
||||
|
||||
class _ChallengeFriendsTextComponent extends TextComponent with HasGameRef {
|
||||
_ChallengeFriendsTextComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, 1.5),
|
||||
textRenderer: _titleBoldTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
text = readProvider<AppLocalizations>().andChallengeYourFriends;
|
||||
}
|
||||
}
|
||||
|
||||
class _TitleBackgroundSpriteComponent extends SpriteComponent with HasGameRef {
|
||||
_TitleBackgroundSpriteComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2.zero(),
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
final sprite = Sprite(
|
||||
gameRef.images
|
||||
.fromCache(Assets.images.backbox.displayTitleDecoration.keyName),
|
||||
);
|
||||
this.sprite = sprite;
|
||||
size = sprite.originalSize / 22;
|
||||
}
|
||||
}
|
||||
|
||||
class _LinksComponent extends PositionComponent with HasGameRef {
|
||||
_LinksComponent({
|
||||
OnShareTap? onShare,
|
||||
}) : super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, 9.2),
|
||||
children: [
|
||||
ShareLinkComponent(onTap: onShare),
|
||||
GoogleIOLinkComponent(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// {@template share_link_component}
|
||||
/// Link button to navigate to sharing score display.
|
||||
/// {@endtemplate}
|
||||
class ShareLinkComponent extends TextComponent with HasGameRef, Tappable {
|
||||
/// {@macro share_link_component}
|
||||
ShareLinkComponent({
|
||||
OnShareTap? onTap,
|
||||
}) : _onTap = onTap,
|
||||
super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(-7, 0),
|
||||
textRenderer: _linkTextPaint,
|
||||
);
|
||||
|
||||
final OnShareTap? _onTap;
|
||||
|
||||
@override
|
||||
bool onTapDown(TapDownInfo info) {
|
||||
_onTap?.call();
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
await add(
|
||||
RectangleComponent(
|
||||
size: Vector2(6.4, 0.2),
|
||||
paint: Paint()..color = PinballColors.orange,
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(3.2, 2.3),
|
||||
),
|
||||
);
|
||||
|
||||
text = readProvider<AppLocalizations>().share;
|
||||
}
|
||||
}
|
||||
|
||||
/// {@template google_io_link_component}
|
||||
/// Link button to navigate to Google I/O site.
|
||||
/// {@endtemplate}
|
||||
class GoogleIOLinkComponent extends TextComponent with HasGameRef, Tappable {
|
||||
/// {@macro google_io_link_component}
|
||||
GoogleIOLinkComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(6, 0),
|
||||
textRenderer: _linkTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
bool onTapDown(TapDownInfo info) {
|
||||
openLink(ShareRepository.googleIOEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
await add(
|
||||
RectangleComponent(
|
||||
size: Vector2(10.2, 0.2),
|
||||
paint: Paint()..color = PinballColors.orange,
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(5.1, 2.3),
|
||||
),
|
||||
);
|
||||
|
||||
text = readProvider<AppLocalizations>().gotoIO;
|
||||
}
|
||||
}
|
||||
|
||||
class _DescriptionComponent extends PositionComponent with HasGameRef {
|
||||
_DescriptionComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(0, 13),
|
||||
children: [
|
||||
_LearnMoreTextComponent(),
|
||||
_FirebaseTextComponent(),
|
||||
OpenSourceTextComponent(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _LearnMoreTextComponent extends TextComponent with HasGameRef {
|
||||
_LearnMoreTextComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2.zero(),
|
||||
textRenderer: _descriptionTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
text = readProvider<AppLocalizations>().learnMore;
|
||||
}
|
||||
}
|
||||
|
||||
class _FirebaseTextComponent extends TextComponent with HasGameRef {
|
||||
_FirebaseTextComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(-8.5, 2.5),
|
||||
textRenderer: _descriptionTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
text = readProvider<AppLocalizations>().firebaseOr;
|
||||
}
|
||||
}
|
||||
|
||||
/// {@template open_source_link_component}
|
||||
/// Link text to navigate to Open Source site.
|
||||
/// {@endtemplate}
|
||||
@visibleForTesting
|
||||
class OpenSourceTextComponent extends TextComponent with HasGameRef, Tappable {
|
||||
/// {@macro open_source_link_component}
|
||||
OpenSourceTextComponent()
|
||||
: super(
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(13.5, 2.5),
|
||||
textRenderer: _descriptionTextPaint,
|
||||
);
|
||||
|
||||
@override
|
||||
bool onTapDown(TapDownInfo info) {
|
||||
openLink(ShareRepository.openSourceCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
await add(
|
||||
RectangleComponent(
|
||||
size: Vector2(16, 0.2),
|
||||
paint: Paint()..color = PinballColors.white,
|
||||
anchor: Anchor.center,
|
||||
position: Vector2(8, 2.3),
|
||||
),
|
||||
);
|
||||
text = readProvider<AppLocalizations>().openSourceCode;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:pinball/l10n/l10n.dart';
|
||||
import 'package:pinball/start_game/start_game.dart';
|
||||
import 'package:pinball_ui/pinball_ui.dart';
|
||||
|
||||
/// {@template replay_button_overlay}
|
||||
/// [Widget] that renders the button responsible for restarting the game.
|
||||
/// {@endtemplate}
|
||||
class ReplayButtonOverlay extends StatelessWidget {
|
||||
/// {@macro replay_button_overlay}
|
||||
const ReplayButtonOverlay({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = context.l10n;
|
||||
|
||||
return PinballButton(
|
||||
text: l10n.replay,
|
||||
onTap: () {
|
||||
context.read<StartGameBloc>().add(const ReplayTapped());
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.0 KiB |
@ -0,0 +1,195 @@
|
||||
// ignore_for_file: cascade_invocations
|
||||
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/input.dart';
|
||||
import 'package:flame_bloc/flame_bloc.dart';
|
||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||
import 'package:flame_test/flame_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:pinball/game/bloc/game_bloc.dart';
|
||||
import 'package:pinball/game/components/backbox/displays/game_over_info_display.dart';
|
||||
import 'package:pinball/l10n/l10n.dart';
|
||||
import 'package:pinball_components/pinball_components.dart';
|
||||
import 'package:pinball_flame/pinball_flame.dart';
|
||||
import 'package:pinball_ui/pinball_ui.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
import 'package:share_repository/share_repository.dart';
|
||||
|
||||
class _TestGame extends Forge2DGame with HasTappables {
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
await super.onLoad();
|
||||
images.prefix = '';
|
||||
await images.loadAll(
|
||||
[
|
||||
Assets.images.backbox.displayTitleDecoration.keyName,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> pump(GameOverInfoDisplay component) {
|
||||
return ensureAdd(
|
||||
FlameBlocProvider<GameBloc, GameState>.value(
|
||||
value: GameBloc(),
|
||||
children: [
|
||||
FlameProvider.value(
|
||||
_MockAppLocalizations(),
|
||||
children: [component],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MockAppLocalizations extends Mock implements AppLocalizations {
|
||||
@override
|
||||
String get shareYourScore => '';
|
||||
|
||||
@override
|
||||
String get andChallengeYourFriends => '';
|
||||
|
||||
@override
|
||||
String get share => '';
|
||||
|
||||
@override
|
||||
String get gotoIO => '';
|
||||
|
||||
@override
|
||||
String get learnMore => '';
|
||||
|
||||
@override
|
||||
String get firebaseOr => '';
|
||||
|
||||
@override
|
||||
String get openSourceCode => '';
|
||||
}
|
||||
|
||||
class _MockTapDownInfo extends Mock implements TapDownInfo {}
|
||||
|
||||
class _MockUrlLauncher extends Mock
|
||||
with MockPlatformInterfaceMixin
|
||||
implements UrlLauncherPlatform {}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
final flameTester = FlameTester(_TestGame.new);
|
||||
|
||||
late UrlLauncherPlatform urlLauncher;
|
||||
|
||||
setUp(() async {
|
||||
urlLauncher = _MockUrlLauncher();
|
||||
UrlLauncherPlatform.instance = urlLauncher;
|
||||
});
|
||||
|
||||
group('InfoDisplay', () {
|
||||
flameTester.test(
|
||||
'loads correctly',
|
||||
(game) async {
|
||||
final component = GameOverInfoDisplay();
|
||||
await game.pump(component);
|
||||
expect(game.descendants(), contains(component));
|
||||
},
|
||||
);
|
||||
|
||||
flameTester.test(
|
||||
'calls onShare when Share link is tapped',
|
||||
(game) async {
|
||||
var tapped = false;
|
||||
|
||||
final tapDownInfo = _MockTapDownInfo();
|
||||
final component = GameOverInfoDisplay(
|
||||
onShare: () => tapped = true,
|
||||
);
|
||||
await game.pump(component);
|
||||
|
||||
final shareLink =
|
||||
component.descendants().whereType<ShareLinkComponent>().first;
|
||||
|
||||
shareLink.onTapDown(tapDownInfo);
|
||||
|
||||
expect(tapped, isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
flameTester.test(
|
||||
'open Google IO Event url when navigating',
|
||||
(game) async {
|
||||
when(() => urlLauncher.canLaunch(any())).thenAnswer((_) async => true);
|
||||
when(
|
||||
() => urlLauncher.launch(
|
||||
any(),
|
||||
useSafariVC: any(named: 'useSafariVC'),
|
||||
useWebView: any(named: 'useWebView'),
|
||||
enableJavaScript: any(named: 'enableJavaScript'),
|
||||
enableDomStorage: any(named: 'enableDomStorage'),
|
||||
universalLinksOnly: any(named: 'universalLinksOnly'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => true);
|
||||
|
||||
final component = GameOverInfoDisplay();
|
||||
await game.pump(component);
|
||||
|
||||
final googleLink =
|
||||
component.descendants().whereType<GoogleIOLinkComponent>().first;
|
||||
googleLink.onTapDown(_MockTapDownInfo());
|
||||
|
||||
await game.ready();
|
||||
|
||||
verify(
|
||||
() => urlLauncher.launch(
|
||||
ShareRepository.googleIOEvent,
|
||||
useSafariVC: any(named: 'useSafariVC'),
|
||||
useWebView: any(named: 'useWebView'),
|
||||
enableJavaScript: any(named: 'enableJavaScript'),
|
||||
enableDomStorage: any(named: 'enableDomStorage'),
|
||||
universalLinksOnly: any(named: 'universalLinksOnly'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
flameTester.test(
|
||||
'open OpenSource url when navigating',
|
||||
(game) async {
|
||||
when(() => urlLauncher.canLaunch(any())).thenAnswer((_) async => true);
|
||||
when(
|
||||
() => urlLauncher.launch(
|
||||
any(),
|
||||
useSafariVC: any(named: 'useSafariVC'),
|
||||
useWebView: any(named: 'useWebView'),
|
||||
enableJavaScript: any(named: 'enableJavaScript'),
|
||||
enableDomStorage: any(named: 'enableDomStorage'),
|
||||
universalLinksOnly: any(named: 'universalLinksOnly'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
).thenAnswer((_) async => true);
|
||||
|
||||
final component = GameOverInfoDisplay();
|
||||
await game.pump(component);
|
||||
|
||||
final openSourceLink =
|
||||
component.descendants().whereType<OpenSourceTextComponent>().first;
|
||||
openSourceLink.onTapDown(_MockTapDownInfo());
|
||||
|
||||
await game.ready();
|
||||
|
||||
verify(
|
||||
() => urlLauncher.launch(
|
||||
ShareRepository.openSourceCode,
|
||||
useSafariVC: any(named: 'useSafariVC'),
|
||||
useWebView: any(named: 'useWebView'),
|
||||
enableJavaScript: any(named: 'enableJavaScript'),
|
||||
enableDomStorage: any(named: 'enableDomStorage'),
|
||||
universalLinksOnly: any(named: 'universalLinksOnly'),
|
||||
headers: any(named: 'headers'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
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/start_game/bloc/start_game_bloc.dart';
|
||||
|
||||
import '../../../helpers/helpers.dart';
|
||||
|
||||
class _MockStartGameBloc extends Mock implements StartGameBloc {}
|
||||
|
||||
void main() {
|
||||
group('ReplayButtonOverlay', () {
|
||||
late StartGameBloc startGameBloc;
|
||||
|
||||
setUp(() async {
|
||||
await mockFlameImages();
|
||||
startGameBloc = _MockStartGameBloc();
|
||||
|
||||
whenListen(
|
||||
startGameBloc,
|
||||
Stream.value(const StartGameState.initial()),
|
||||
initialState: const StartGameState.initial(),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('renders correctly', (tester) async {
|
||||
await tester.pumpApp(const ReplayButtonOverlay());
|
||||
|
||||
expect(find.text('Replay'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('adds ReplayTapped event to StartGameBloc when tapped',
|
||||
(tester) async {
|
||||
await tester.pumpApp(
|
||||
const ReplayButtonOverlay(),
|
||||
startGameBloc: startGameBloc,
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Replay'));
|
||||
await tester.pump();
|
||||
|
||||
verify(() => startGameBloc.add(const ReplayTapped())).called(1);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in new issue