// ignore_for_file: cascade_invocations import 'package:bloc_test/bloc_test.dart'; import 'package:flame/components.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/behaviors/behaviors.dart'; import 'package:pinball/select_character/select_character.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_theme/pinball_theme.dart' as theme; import 'package:platform_helper/platform_helper.dart'; class _TestGame extends Forge2DGame { @override Future onLoad() async { images.prefix = ''; await images.loadAll([ theme.Assets.images.dash.ball.keyName, theme.Assets.images.dino.ball.keyName, theme.Assets.images.dash.background.keyName, theme.Assets.images.dino.background.keyName, ]); } Future pump( List children, { CharacterThemeCubit? characterThemeBloc, PlatformHelper? platformHelper, }) async { await ensureAdd( FlameBlocProvider.value( value: characterThemeBloc ?? CharacterThemeCubit(), children: [ FlameProvider.value( platformHelper ?? _MockPlatformHelper(), children: children, ), ], ), ); } } class _MockBallCubit extends Mock implements BallCubit {} class _MockArcadeBackgroundCubit extends Mock implements ArcadeBackgroundCubit { } class _MockPlatformHelper extends Mock implements PlatformHelper {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); group( 'CharacterSelectionBehavior', () { final flameTester = FlameTester(_TestGame.new); test('can be instantiated', () { expect( CharacterSelectionBehavior(), isA(), ); }); flameTester.test( 'loads', (game) async { final behavior = CharacterSelectionBehavior(); await game.pump([behavior]); expect(game.descendants(), contains(behavior)); }, ); flameTester.test( 'onNewState does not call onCharacterSelected on the arcade background ' 'bloc when platform is mobile', (game) async { final platformHelper = _MockPlatformHelper(); when(() => platformHelper.isMobile).thenAnswer((_) => true); final arcadeBackgroundBloc = _MockArcadeBackgroundCubit(); whenListen( arcadeBackgroundBloc, const Stream.empty(), initialState: const ArcadeBackgroundState.initial(), ); final behavior = CharacterSelectionBehavior(); await game.pump( [ behavior, ZCanvasComponent(), Plunger.test(), Ball.test(), ], platformHelper: platformHelper, ); const dinoThemeState = CharacterThemeState(theme.DinoTheme()); behavior.onNewState(dinoThemeState); await game.ready(); verifyNever( () => arcadeBackgroundBloc .onCharacterSelected(dinoThemeState.characterTheme), ); }, ); flameTester.test( 'onNewState calls onCharacterSelected on the arcade background ' 'bloc when platform is not mobile', (game) async { final platformHelper = _MockPlatformHelper(); when(() => platformHelper.isMobile).thenAnswer((_) => false); final arcadeBackgroundBloc = _MockArcadeBackgroundCubit(); whenListen( arcadeBackgroundBloc, const Stream.empty(), initialState: const ArcadeBackgroundState.initial(), ); final arcadeBackground = ArcadeBackground.test(bloc: arcadeBackgroundBloc); final behavior = CharacterSelectionBehavior(); await game.pump( [ arcadeBackground, behavior, ZCanvasComponent(), Plunger.test(), Ball.test(), ], platformHelper: platformHelper, ); const dinoThemeState = CharacterThemeState(theme.DinoTheme()); behavior.onNewState(dinoThemeState); await game.ready(); verify( () => arcadeBackgroundBloc .onCharacterSelected(dinoThemeState.characterTheme), ).called(1); }, ); flameTester.test( 'onNewState calls onCharacterSelected on the ball bloc', (game) async { final platformHelper = _MockPlatformHelper(); when(() => platformHelper.isMobile).thenAnswer((_) => false); final ballBloc = _MockBallCubit(); whenListen( ballBloc, const Stream.empty(), initialState: const BallState.initial(), ); final ball = Ball.test(bloc: ballBloc); final behavior = CharacterSelectionBehavior(); await game.pump( [ ball, behavior, ZCanvasComponent(), Plunger.test(), ArcadeBackground.test(), ], platformHelper: platformHelper, ); const dinoThemeState = CharacterThemeState(theme.DinoTheme()); behavior.onNewState(dinoThemeState); await game.ready(); verify( () => ballBloc.onCharacterSelected(dinoThemeState.characterTheme), ).called(1); }, ); }, ); }