feat: tests

pull/377/head
Erick Zanardo 3 years ago
parent 4f4f1cdd87
commit f88dbb7fb8

@ -9,6 +9,7 @@ import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:pinball_theme/pinball_theme.dart' hide Assets; import 'package:pinball_theme/pinball_theme.dart' hide Assets;
import 'package:platform_helper/platform_helper.dart';
/// {@template backbox} /// {@template backbox}
/// The [Backbox] of the pinball machine. /// The [Backbox] of the pinball machine.
@ -17,16 +18,20 @@ class Backbox extends PositionComponent with ZIndex, HasGameRef {
/// {@macro backbox} /// {@macro backbox}
Backbox({ Backbox({
required LeaderboardRepository leaderboardRepository, required LeaderboardRepository leaderboardRepository,
}) : _bloc = BackboxBloc(leaderboardRepository: leaderboardRepository); }) : _bloc = BackboxBloc(leaderboardRepository: leaderboardRepository),
_platformHelper = PlatformHelper();
/// {@macro backbox} /// {@macro backbox}
@visibleForTesting @visibleForTesting
Backbox.test({ Backbox.test({
required BackboxBloc bloc, required BackboxBloc bloc,
}) : _bloc = bloc; required PlatformHelper platformHelper,
}) : _bloc = bloc,
_platformHelper = platformHelper;
late final Component _display; late final Component _display;
final BackboxBloc _bloc; final BackboxBloc _bloc;
final PlatformHelper _platformHelper;
late StreamSubscription<BackboxState> _subscription; late StreamSubscription<BackboxState> _subscription;
@override @override
@ -59,8 +64,9 @@ class Backbox extends PositionComponent with ZIndex, HasGameRef {
} else if (state is LeaderboardSuccessState) { } else if (state is LeaderboardSuccessState) {
_display.add(LeaderboardDisplay(entries: state.entries)); _display.add(LeaderboardDisplay(entries: state.entries));
} else if (state is InitialsFormState) { } else if (state is InitialsFormState) {
// TODO check if (_platformHelper.isMobile) {
gameRef.overlays.add(PinballGame.mobileControlsOverlay); gameRef.overlays.add(PinballGame.mobileControlsOverlay);
}
_display.add( _display.add(
InitialsInputDisplay( InitialsInputDisplay(
score: state.score, score: state.score,

@ -8,7 +8,6 @@ import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
@ -117,16 +116,6 @@ class PinballGame extends PinballForge2DGame
final focusedBoardSide = <int, BoardSide>{}; final focusedBoardSide = <int, BoardSide>{};
void triggerVirtualKeyUp(LogicalKeyboardKey key) {
final keyControllers = descendants().whereType<KeyboardInputController>();
for (final controller in keyControllers) {
if (!controller.onVirtualKeyUp(key)) {
break;
}
}
}
@override @override
void onTapDown(int pointerId, TapDownInfo info) { void onTapDown(int pointerId, TapDownInfo info) {
if (info.raw.kind == PointerDeviceKind.touch) { if (info.raw.kind == PointerDeviceKind.touch) {

@ -12,6 +12,7 @@ import 'package:pinball/l10n/l10n.dart';
import 'package:pinball/select_character/select_character.dart'; import 'package:pinball/select_character/select_character.dart';
import 'package:pinball/start_game/start_game.dart'; import 'package:pinball/start_game/start_game.dart';
import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_flame/pinball_flame.dart';
import 'package:pinball_ui/pinball_ui.dart'; import 'package:pinball_ui/pinball_ui.dart';
class PinballGamePage extends StatelessWidget { class PinballGamePage extends StatelessWidget {
@ -143,29 +144,7 @@ class PinballGameLoadedView extends StatelessWidget {
bottom: 0, bottom: 0,
left: 0, left: 0,
right: 0, right: 0,
child: MobileControls( child: MobileControls(game: game),
onTapUp: () {
game.triggerVirtualKeyUp(LogicalKeyboardKey.arrowUp);
},
onTapDown: () {
game.triggerVirtualKeyUp(
LogicalKeyboardKey.arrowDown,
);
},
onTapLeft: () {
game.triggerVirtualKeyUp(
LogicalKeyboardKey.arrowLeft,
);
},
onTapRight: () {
game.triggerVirtualKeyUp(
LogicalKeyboardKey.arrowRight,
);
},
onTapEnter: () {
game.triggerVirtualKeyUp(LogicalKeyboardKey.enter);
},
),
); );
}, },
}, },

@ -1,5 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_flame/pinball_flame.dart';
import 'package:pinball_ui/pinball_ui.dart'; import 'package:pinball_ui/pinball_ui.dart';
/// {@template mobile_controls} /// {@template mobile_controls}
@ -7,43 +10,35 @@ import 'package:pinball_ui/pinball_ui.dart';
/// {@endtemplate} /// {@endtemplate}
class MobileControls extends StatelessWidget { class MobileControls extends StatelessWidget {
/// {@macro mobile_controls} /// {@macro mobile_controls}
const MobileControls({Key? key, const MobileControls({
required this.onTapUp, Key? key,
required this.onTapDown, required this.game,
required this.onTapLeft,
required this.onTapRight,
required this.onTapEnter,
}) : super(key: key); }) : super(key: key);
/// Called when dpad up is pressed /// Game instance
final VoidCallback onTapUp; final PinballGame game;
/// Called when dpad down is pressed
final VoidCallback onTapDown;
/// Called when dpad left is pressed
final VoidCallback onTapLeft;
/// Called when dpad right is pressed
final VoidCallback onTapRight;
/// Called when enter is pressed
final VoidCallback onTapEnter;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
MobileDpad( MobileDpad(
onTapUp: onTapUp, onTapUp: () => game.triggerVirtualKeyUp(LogicalKeyboardKey.arrowUp),
onTapDown: onTapUp, onTapDown: () => game.triggerVirtualKeyUp(
onTapLeft: onTapLeft, LogicalKeyboardKey.arrowDown,
onTapRight: onTapRight, ),
onTapLeft: () => game.triggerVirtualKeyUp(
LogicalKeyboardKey.arrowLeft,
),
onTapRight: () => game.triggerVirtualKeyUp(
LogicalKeyboardKey.arrowRight,
),
), ),
PinballButton( PinballButton(
text: 'Enter', // TODO l10n text: l10n.enter,
onTap: onTapEnter, onTap: () => game.triggerVirtualKeyUp(LogicalKeyboardKey.enter),
), ),
], ],
); );

@ -167,5 +167,9 @@
"ioPinball": "I/O Pinball", "ioPinball": "I/O Pinball",
"@ioPinball": { "@ioPinball": {
"description": "I/O Pinball - Name of the game" "description": "I/O Pinball - Name of the game"
},
"enter": "Enter",
"@enter": {
"description": "Enter show on the mobile controls button"
} }
} }

@ -1,4 +1,5 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
/// The signature for a key handle function /// The signature for a key handle function
@ -44,3 +45,18 @@ class KeyboardInputController extends Component with KeyboardHandler {
return true; return true;
} }
} }
/// Add the ability to virtually trigger key events to a [FlameGame]'s
/// [KeyboardInputController].
extension VirtualKeyEvents on FlameGame {
/// Trigger a key up
void triggerVirtualKeyUp(LogicalKeyboardKey key) {
final keyControllers = descendants().whereType<KeyboardInputController>();
for (final controller in keyControllers) {
if (!controller.onVirtualKeyUp(key)) {
break;
}
}
}
}

@ -1,11 +1,36 @@
// ignore_for_file: cascade_invocations, one_member_abstracts // ignore_for_file: cascade_invocations, one_member_abstracts
import 'package:flame/game.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
class _TestGame extends FlameGame {
bool pressed = false;
@override
Future<void>? onLoad() async {
await super.onLoad();
await add(
KeyboardInputController(
keyUp: {
LogicalKeyboardKey.enter: () {
pressed = true;
return true;
},
LogicalKeyboardKey.escape: () {
return false;
},
},
),
);
}
}
abstract class _KeyCall { abstract class _KeyCall {
bool onCall(); bool onCall();
} }
@ -75,4 +100,15 @@ void main() {
}, },
); );
}); });
group('VirtualKeyEvents', () {
final flameTester = FlameTester(_TestGame.new);
group('onVirtualKeyUp', () {
flameTester.test('triggers the event', (game) async {
await game.ready();
game.triggerVirtualKeyUp(LogicalKeyboardKey.enter);
expect(game.pressed, isTrue);
});
});
});
} }

@ -49,17 +49,17 @@ class _VoidCallbackStub extends Mock implements _VoidCallbackStubBase {}
void main() { void main() {
group('PinballDpadButton', () { group('PinballDpadButton', () {
testWidgets('can be tapped', (tester) async { testWidgets('can be tapped', (tester) async {
final stub = _VoidCallbackStub(); final stub = _VoidCallbackStub();
await tester.pumpButton( await tester.pumpButton(
direction: PinballDpadDirection.up, direction: PinballDpadDirection.up,
onTap: stub.onCall, onTap: stub.onCall,
); );
await tester.tap(find.byType(Image)); await tester.tap(find.byType(Image));
verify(stub.onCall).called(1); verify(stub.onCall).called(1);
}); });
group('when it is up', () { group('when it is up', () {
testWidgets('renders the correct image', (tester) async { testWidgets('renders the correct image', (tester) async {

@ -6,8 +6,7 @@ import 'package:flutter/foundation.dart';
class PlatformHelper { class PlatformHelper {
/// {@macro platform_helper} /// {@macro platform_helper}
bool get isMobile { bool get isMobile {
return true; return defaultTargetPlatform == TargetPlatform.iOS ||
//return defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.android;
// defaultTargetPlatform == TargetPlatform.android;
} }
} }

@ -19,6 +19,7 @@ import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
import 'package:pinball_theme/pinball_theme.dart' as theme; import 'package:pinball_theme/pinball_theme.dart' as theme;
import 'package:platform_helper/platform_helper.dart';
class _TestGame extends Forge2DGame with HasKeyboardHandlerComponents { class _TestGame extends Forge2DGame with HasKeyboardHandlerComponents {
final character = theme.DashTheme(); final character = theme.DashTheme();
@ -64,6 +65,8 @@ RawKeyUpEvent _mockKeyUp(LogicalKeyboardKey key) {
return event; return event;
} }
class _MockPlatformHelper extends Mock implements PlatformHelper {}
class _MockBackboxBloc extends Mock implements BackboxBloc {} class _MockBackboxBloc extends Mock implements BackboxBloc {}
class _MockLeaderboardRepository extends Mock implements LeaderboardRepository { class _MockLeaderboardRepository extends Mock implements LeaderboardRepository {
@ -104,21 +107,27 @@ void main() {
final flameTester = FlameTester(_TestGame.new); final flameTester = FlameTester(_TestGame.new);
late BackboxBloc bloc; late BackboxBloc bloc;
late PlatformHelper platformHelper;
setUp(() { setUp(() {
bloc = _MockBackboxBloc(); bloc = _MockBackboxBloc();
platformHelper = _MockPlatformHelper();
whenListen( whenListen(
bloc, bloc,
Stream<BackboxState>.empty(), Stream<BackboxState>.empty(),
initialState: LoadingState(), initialState: LoadingState(),
); );
when(() => platformHelper.isMobile).thenReturn(false);
}); });
group('Backbox', () { group('Backbox', () {
flameTester.test( flameTester.test(
'loads correctly', 'loads correctly',
(game) async { (game) async {
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
expect(game.descendants(), contains(backbox)); expect(game.descendants(), contains(backbox));
}, },
@ -127,7 +136,10 @@ void main() {
flameTester.test( flameTester.test(
'adds LeaderboardRequested when loaded', 'adds LeaderboardRequested when loaded',
(game) async { (game) async {
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
verify(() => bloc.add(LeaderboardRequested())).called(1); verify(() => bloc.add(LeaderboardRequested())).called(1);
@ -142,7 +154,10 @@ void main() {
..followVector2(Vector2(0, -130)) ..followVector2(Vector2(0, -130))
..zoom = 6; ..zoom = 6;
await game.pump( await game.pump(
Backbox.test(bloc: bloc), Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
),
); );
await tester.pump(); await tester.pump();
}, },
@ -161,6 +176,7 @@ void main() {
bloc: BackboxBloc( bloc: BackboxBloc(
leaderboardRepository: _MockLeaderboardRepository(), leaderboardRepository: _MockLeaderboardRepository(),
), ),
platformHelper: platformHelper,
); );
await game.pump(backbox); await game.pump(backbox);
backbox.requestInitials( backbox.requestInitials(
@ -189,7 +205,10 @@ void main() {
Stream<BackboxState>.empty(), Stream<BackboxState>.empty(),
initialState: state, initialState: state,
); );
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
game.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.enter), {}); game.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.enter), {});
@ -205,6 +224,34 @@ void main() {
}, },
); );
flameTester.test(
'adds the mobile controls overlay when it is mobile',
(game) async {
final bloc = _MockBackboxBloc();
final platformHelper = _MockPlatformHelper();
final state = InitialsFormState(
score: 10,
character: game.character,
);
whenListen(
bloc,
Stream<BackboxState>.empty(),
initialState: state,
);
when(() => platformHelper.isMobile).thenReturn(true);
final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox);
expect(
game.overlays.value,
contains(PinballGame.mobileControlsOverlay),
);
},
);
flameTester.test( flameTester.test(
'adds InitialsSubmissionSuccessDisplay on InitialsSuccessState', 'adds InitialsSubmissionSuccessDisplay on InitialsSuccessState',
(game) async { (game) async {
@ -213,7 +260,10 @@ void main() {
Stream<BackboxState>.empty(), Stream<BackboxState>.empty(),
initialState: InitialsSuccessState(), initialState: InitialsSuccessState(),
); );
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
expect( expect(
@ -234,7 +284,10 @@ void main() {
Stream<BackboxState>.empty(), Stream<BackboxState>.empty(),
initialState: InitialsFailureState(), initialState: InitialsFailureState(),
); );
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
expect( expect(
@ -256,7 +309,10 @@ void main() {
initialState: LeaderboardSuccessState(entries: const []), initialState: LeaderboardSuccessState(entries: const []),
); );
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
expect( expect(
@ -276,7 +332,10 @@ void main() {
initialState: LoadingState(), initialState: LoadingState(),
); );
final backbox = Backbox.test(bloc: bloc); final backbox = Backbox.test(
bloc: bloc,
platformHelper: platformHelper,
);
await game.pump(backbox); await game.pump(backbox);
backbox.removeFromParent(); backbox.removeFromParent();

@ -331,5 +331,19 @@ void main() {
expect(game.focusNode.hasFocus, isTrue); expect(game.focusNode.hasFocus, isTrue);
}); });
testWidgets('mobile controls when the overlay is added', (tester) async {
await tester.pumpApp(
PinballGameView(game: game),
gameBloc: gameBloc,
startGameBloc: startGameBloc,
);
game.overlays.add(PinballGame.mobileControlsOverlay);
await tester.pump();
expect(find.byType(MobileControls), findsOneWidget);
});
}); });
} }

@ -0,0 +1,131 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_flame/pinball_flame.dart';
import 'package:pinball_ui/pinball_ui.dart';
class _MockPinballGame extends Mock implements PinballGame {}
extension _WidgetTesterX on WidgetTester {
Future<void> pumpMobileControls(PinballGame game) async {
await pumpWidget(
MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
],
home: Scaffold(
body: MobileControls(game: game),
),
),
);
}
}
extension _CommonFindersX on CommonFinders {
Finder byPinballDpadDirection(PinballDpadDirection direction) {
return byWidgetPredicate((widget) {
return widget is PinballDpadButton && widget.direction == direction;
});
}
}
void main() {
group('MobileControls', () {
testWidgets('renders', (tester) async {
await tester.pumpMobileControls(_MockPinballGame());
expect(find.byType(PinballButton), findsOneWidget);
expect(find.byType(MobileDpad), findsOneWidget);
});
testWidgets('correctly triggers the arrow up', (tester) async {
var pressed = false;
final component = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowUp: () => pressed = true,
},
);
final game = _MockPinballGame();
when(game.descendants).thenReturn([component]);
await tester.pumpMobileControls(game);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.up));
await tester.pump();
expect(pressed, isTrue);
});
testWidgets('correctly triggers the arrow down', (tester) async {
var pressed = false;
final component = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowDown: () => pressed = true,
},
);
final game = _MockPinballGame();
when(game.descendants).thenReturn([component]);
await tester.pumpMobileControls(game);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.down));
await tester.pump();
expect(pressed, isTrue);
});
testWidgets('correctly triggers the arrow right', (tester) async {
var pressed = false;
final component = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowRight: () => pressed = true,
},
);
final game = _MockPinballGame();
when(game.descendants).thenReturn([component]);
await tester.pumpMobileControls(game);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.right));
await tester.pump();
expect(pressed, isTrue);
});
testWidgets('correctly triggers the arrow left', (tester) async {
var pressed = false;
final component = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowLeft: () => pressed = true,
},
);
final game = _MockPinballGame();
when(game.descendants).thenReturn([component]);
await tester.pumpMobileControls(game);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.left));
await tester.pump();
expect(pressed, isTrue);
});
testWidgets('correctly triggers the enter', (tester) async {
var pressed = false;
final component = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.enter: () => pressed = true,
},
);
final game = _MockPinballGame();
when(game.descendants).thenReturn([component]);
await tester.pumpMobileControls(game);
await tester.tap(find.byType(PinballButton));
await tester.pump();
expect(pressed, isTrue);
});
});
}

@ -0,0 +1,111 @@
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_ui/pinball_ui.dart';
extension _WidgetTesterX on WidgetTester {
Future<void> pumpDpad({
required VoidCallback onTapUp,
required VoidCallback onTapDown,
required VoidCallback onTapLeft,
required VoidCallback onTapRight,
}) async {
await pumpWidget(
MaterialApp(
home: Scaffold(
body: MobileDpad(
onTapUp: onTapUp,
onTapDown: onTapDown,
onTapLeft: onTapLeft,
onTapRight: onTapRight,
),
),
),
);
}
}
extension _CommonFindersX on CommonFinders {
Finder byPinballDpadDirection(PinballDpadDirection direction) {
return byWidgetPredicate((widget) {
return widget is PinballDpadButton && widget.direction == direction;
});
}
}
abstract class _VoidCallbackStubBase {
void onCall();
}
class _VoidCallbackStub extends Mock implements _VoidCallbackStubBase {}
void main() {
group('MobileDpad', () {
testWidgets('renders correctly', (tester) async {
await tester.pumpDpad(
onTapUp: () {},
onTapDown: () {},
onTapLeft: () {},
onTapRight: () {},
);
expect(
find.byType(PinballDpadButton),
findsNWidgets(4),
);
});
testWidgets('can tap up', (tester) async {
final stub = _VoidCallbackStub();
await tester.pumpDpad(
onTapUp: stub.onCall,
onTapDown: () {},
onTapLeft: () {},
onTapRight: () {},
);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.up));
verify(stub.onCall).called(1);
});
testWidgets('can tap down', (tester) async {
final stub = _VoidCallbackStub();
await tester.pumpDpad(
onTapUp: () {},
onTapDown: stub.onCall,
onTapLeft: () {},
onTapRight: () {},
);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.down));
verify(stub.onCall).called(1);
});
testWidgets('can tap left', (tester) async {
final stub = _VoidCallbackStub();
await tester.pumpDpad(
onTapUp: () {},
onTapDown: () {},
onTapLeft: stub.onCall,
onTapRight: () {},
);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.left));
verify(stub.onCall).called(1);
});
testWidgets('can tap left', (tester) async {
final stub = _VoidCallbackStub();
await tester.pumpDpad(
onTapUp: () {},
onTapDown: () {},
onTapLeft: () {},
onTapRight: stub.onCall,
);
await tester.tap(find.byPinballDpadDirection(PinballDpadDirection.right));
verify(stub.onCall).called(1);
});
});
}
Loading…
Cancel
Save