From 96af0f7fa7069f3069236d2d92ea361a2fba5a0f Mon Sep 17 00:00:00 2001 From: Allison Ryan Date: Tue, 8 Mar 2022 16:35:13 -0600 Subject: [PATCH] refactor: decrease theme cubit scope --- lib/app/view/app.dart | 29 +++++++--------- lib/game/components/ball.dart | 9 +---- lib/game/pinball_game.dart | 12 +++++++ lib/game/view/pinball_game_page.dart | 17 +++++---- lib/theme/view/character_selection_page.dart | 11 ++++-- test/game/components/anchor_test.dart | 2 +- test/game/components/ball_test.dart | 36 +++++++------------- test/game/components/plunger_test.dart | 14 ++------ test/game/components/wall_test.dart | 2 +- test/game/pinball_game_test.dart | 23 +++++++++++++ test/game/view/pinball_game_page_test.dart | 18 +++++++--- test/helpers/builders.dart | 19 +++-------- 12 files changed, 102 insertions(+), 90 deletions(-) diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index 36e9e842..7e3fdf17 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -6,34 +6,29 @@ // https://opensource.org/licenses/MIT. import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/landing/landing.dart'; -import 'package:pinball/theme/theme.dart'; class App extends StatelessWidget { const App({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return BlocProvider( - create: (_) => ThemeCubit(), - child: MaterialApp( - title: 'I/O Pinball', - theme: ThemeData( - appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)), - colorScheme: ColorScheme.fromSwatch( - accentColor: const Color(0xFF13B9FF), - ), + return MaterialApp( + title: 'I/O Pinball', + theme: ThemeData( + appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)), + colorScheme: ColorScheme.fromSwatch( + accentColor: const Color(0xFF13B9FF), ), - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], - supportedLocales: AppLocalizations.supportedLocales, - home: const LandingPage(), ), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + home: const LandingPage(), ); } } diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 3143874d..52a31827 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -1,7 +1,6 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/game.dart'; -import 'package:pinball/theme/theme.dart'; class Ball extends PositionBodyComponent { Ball({ @@ -19,13 +18,7 @@ class Ball extends PositionBodyComponent { Future onLoad() async { await super.onLoad(); final sprite = await gameRef.loadSprite(spritePath); - final tint = gameRef - .read() - .state - .theme - .characterTheme - .ballColor - .withOpacity(0.5); + final tint = gameRef.theme.characterTheme.ballColor.withOpacity(0.5); positionComponent = SpriteComponent(sprite: sprite, size: ballSize) ..tint(tint); } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 7c701c09..036aa5b3 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -3,8 +3,20 @@ import 'dart:async'; import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball_theme/pinball_theme.dart'; class PinballGame extends Forge2DGame with FlameBloc { + PinballGame({required this.theme}); + + PinballGame.initial() + : this( + theme: const PinballTheme( + characterTheme: DashTheme(), + ), + ); + + final PinballTheme theme; + void spawnBall() { add( Ball(position: ballStartingPosition), diff --git a/lib/game/view/pinball_game_page.dart b/lib/game/view/pinball_game_page.dart index 02f5b34c..e954b591 100644 --- a/lib/game/view/pinball_game_page.dart +++ b/lib/game/view/pinball_game_page.dart @@ -2,16 +2,19 @@ import 'package:flame/game.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:pinball/game/game.dart'; +import 'package:pinball_theme/pinball_theme.dart'; class PinballGamePage extends StatelessWidget { - const PinballGamePage({Key? key}) : super(key: key); + const PinballGamePage({Key? key, required this.theme}) : super(key: key); - static Route route() { + final PinballTheme theme; + + static Route route({required PinballTheme theme}) { return MaterialPageRoute( builder: (_) { return BlocProvider( create: (_) => GameBloc(), - child: const PinballGamePage(), + child: PinballGamePage(theme: theme), ); }, ); @@ -19,12 +22,14 @@ class PinballGamePage extends StatelessWidget { @override Widget build(BuildContext context) { - return const PinballGameView(); + return PinballGameView(theme: theme); } } class PinballGameView extends StatefulWidget { - const PinballGameView({Key? key}) : super(key: key); + const PinballGameView({Key? key, required this.theme}) : super(key: key); + + final PinballTheme theme; @override State createState() => _PinballGameViewState(); @@ -40,7 +45,7 @@ class _PinballGameViewState extends State { // TODO(erickzanardo): Revisit this when we start to have more assets // this could expose a Stream (maybe even a cubit?) so we could show the // the loading progress with some fancy widgets. - _game = PinballGame()..preLoadAssets(); + _game = PinballGame(theme: widget.theme)..preLoadAssets(); } @override diff --git a/lib/theme/view/character_selection_page.dart b/lib/theme/view/character_selection_page.dart index 5f612b83..307244ef 100644 --- a/lib/theme/view/character_selection_page.dart +++ b/lib/theme/view/character_selection_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/theme/theme.dart'; import 'package:pinball_theme/pinball_theme.dart'; -import 'package:provider/provider.dart'; class CharacterSelectionPage extends StatelessWidget { const CharacterSelectionPage({Key? key}) : super(key: key); @@ -16,7 +16,10 @@ class CharacterSelectionPage extends StatelessWidget { @override Widget build(BuildContext context) { - return const CharacterSelectionView(); + return BlocProvider( + create: (_) => ThemeCubit(), + child: const CharacterSelectionView(), + ); } } @@ -42,7 +45,9 @@ class CharacterSelectionView extends StatelessWidget { const SizedBox(height: 20), TextButton( onPressed: () => Navigator.of(context).push( - PinballGamePage.route(), + PinballGamePage.route( + theme: context.read().state.theme, + ), ), child: Text(l10n.start), ), diff --git a/test/game/components/anchor_test.dart b/test/game/components/anchor_test.dart index 5cc37eca..f9548439 100644 --- a/test/game/components/anchor_test.dart +++ b/test/game/components/anchor_test.dart @@ -9,7 +9,7 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('Anchor', () { - final flameTester = FlameTester(PinballGame.new); + final flameTester = FlameTester(PinballGame.initial); flameTester.test( 'loads correctly', diff --git a/test/game/components/ball_test.dart b/test/game/components/ball_test.dart index c665dd52..38419320 100644 --- a/test/game/components/ball_test.dart +++ b/test/game/components/ball_test.dart @@ -6,7 +6,6 @@ import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:pinball/game/game.dart'; -import 'package:pinball/theme/cubit/theme_cubit.dart'; import '../../helpers/helpers.dart'; @@ -15,7 +14,6 @@ void main() { group('Ball', () { final gameBloc = MockGameBloc(); - final themeCubit = MockThemeCubit(); setUp(() { whenListen( @@ -23,21 +21,13 @@ void main() { const Stream.empty(), initialState: const GameState.initial(), ); - whenListen( - themeCubit, - const Stream.empty(), - initialState: const ThemeState.initial(), - ); }); - final tester = flameBlocTester( - gameBloc: gameBloc, - themeCubit: themeCubit, - ); + final tester = flameBlocTester(gameBloc: gameBloc); - tester.widgetTest( + tester.test( 'loads correctly', - (game, tester) async { + (game) async { final ball = Ball(position: Vector2.zero()); await game.ensureAdd(ball); @@ -46,9 +36,9 @@ void main() { ); group('body', () { - tester.widgetTest( + tester.test( 'positions correctly', - (game, tester) async { + (game) async { final position = Vector2.all(10); final ball = Ball(position: position); await game.ensureAdd(ball); @@ -58,9 +48,9 @@ void main() { }, ); - tester.widgetTest( + tester.test( 'is dynamic', - (game, tester) async { + (game) async { final ball = Ball(position: Vector2.zero()); await game.ensureAdd(ball); @@ -70,9 +60,9 @@ void main() { }); group('first fixture', () { - tester.widgetTest( + tester.test( 'exists', - (game, tester) async { + (game) async { final ball = Ball(position: Vector2.zero()); await game.ensureAdd(ball); @@ -80,9 +70,9 @@ void main() { }, ); - tester.widgetTest( + tester.test( 'is dense', - (game, tester) async { + (game) async { final ball = Ball(position: Vector2.zero()); await game.ensureAdd(ball); @@ -91,9 +81,9 @@ void main() { }, ); - tester.widgetTest( + tester.test( 'shape is circular', - (game, tester) async { + (game) async { final ball = Ball(position: Vector2.zero()); await game.ensureAdd(ball); diff --git a/test/game/components/plunger_test.dart b/test/game/components/plunger_test.dart index bf580f4e..f87f5adc 100644 --- a/test/game/components/plunger_test.dart +++ b/test/game/components/plunger_test.dart @@ -5,13 +5,12 @@ import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball/game/game.dart'; -import 'package:pinball/theme/theme.dart'; import '../../helpers/helpers.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGame.new); + final flameTester = FlameTester(PinballGame.initial); group('Plunger', () { flameTester.test( @@ -131,7 +130,6 @@ void main() { late Anchor anchor; final gameBloc = MockGameBloc(); - final themeCubit = MockThemeCubit(); setUp(() { plunger = Plunger(position: Vector2.zero()); @@ -141,17 +139,9 @@ void main() { const Stream.empty(), initialState: const GameState.initial(), ); - whenListen( - themeCubit, - const Stream.empty(), - initialState: const ThemeState.initial(), - ); }); - final flameTester = flameBlocTester( - gameBloc: gameBloc, - themeCubit: themeCubit, - ); + final flameTester = flameBlocTester(gameBloc: gameBloc); flameTester.test( 'throws AssertionError ' diff --git a/test/game/components/wall_test.dart b/test/game/components/wall_test.dart index 8151055e..d1e146bc 100644 --- a/test/game/components/wall_test.dart +++ b/test/game/components/wall_test.dart @@ -32,7 +32,7 @@ void main() { }, ); }); - final flameTester = FlameTester(PinballGame.new); + final flameTester = FlameTester(PinballGame.initial); flameTester.test( 'loads correctly', diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index 75a77aa9..5f559702 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -1,4 +1,8 @@ +import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/game/game.dart'; + +import '../helpers/helpers.dart'; void main() { group('PinballGame', () { @@ -6,4 +10,23 @@ void main() { // [BallScorePointsCallback] once the following issue is resolved: // https://github.com/flame-engine/flame/issues/1416 }); + + group('PinballGame.initial', () { + final gameBloc = MockGameBloc(); + + setUp(() { + whenListen( + gameBloc, + const Stream.empty(), + initialState: const GameState.initial(), + ); + }); + + flameBlocTester(gameBloc: gameBloc).test( + 'has initial theme', + (game) async { + expect(game.theme, PinballGame.initial().theme); + }, + ); + }); } diff --git a/test/game/view/pinball_game_page_test.dart b/test/game/view/pinball_game_page_test.dart index 2481a59e..d02bfa2b 100644 --- a/test/game/view/pinball_game_page_test.dart +++ b/test/game/view/pinball_game_page_test.dart @@ -4,10 +4,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball/theme/theme.dart'; +import 'package:pinball_theme/pinball_theme.dart'; import '../../helpers/helpers.dart'; void main() { + const theme = PinballTheme(characterTheme: DashTheme()); + group('PinballGamePage', () { testWidgets('renders PinballGameView', (tester) async { final gameBloc = MockGameBloc(); @@ -17,7 +20,10 @@ void main() { initialState: const GameState.initial(), ); - await tester.pumpApp(const PinballGamePage(), gameBloc: gameBloc); + await tester.pumpApp( + const PinballGamePage(theme: theme), + gameBloc: gameBloc, + ); expect(find.byType(PinballGameView), findsOneWidget); }); @@ -35,7 +41,8 @@ void main() { builder: (context) { return ElevatedButton( onPressed: () { - Navigator.of(context).push(PinballGamePage.route()); + Navigator.of(context) + .push(PinballGamePage.route(theme: theme)); }, child: const Text('Tap me'), ); @@ -65,7 +72,10 @@ void main() { initialState: const GameState.initial(), ); - await tester.pumpApp(const PinballGameView(), gameBloc: gameBloc); + await tester.pumpApp( + const PinballGameView(theme: theme), + gameBloc: gameBloc, + ); expect( find.byWidgetPredicate((w) => w is GameWidget), findsOneWidget, @@ -91,7 +101,7 @@ void main() { ); await tester.pumpApp( - const PinballGameView(), + const PinballGameView(theme: theme), gameBloc: gameBloc, themeCubit: themeCubit, ); diff --git a/test/helpers/builders.dart b/test/helpers/builders.dart index 27cdad0d..a211188a 100644 --- a/test/helpers/builders.dart +++ b/test/helpers/builders.dart @@ -1,27 +1,16 @@ import 'package:flame_test/flame_test.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:pinball/game/game.dart'; -import 'package:pinball/theme/theme.dart'; - -import 'mocks.dart'; FlameTester flameBlocTester({ - GameBloc? gameBloc, - ThemeCubit? themeCubit, + required GameBloc gameBloc, }) { return FlameTester( - PinballGame.new, + PinballGame.initial, pumpWidget: (gameWidget, tester) async { await tester.pumpWidget( - MultiBlocProvider( - providers: [ - BlocProvider.value( - value: gameBloc ?? MockGameBloc(), - ), - BlocProvider.value( - value: themeCubit ?? MockThemeCubit(), - ), - ], + BlocProvider.value( + value: gameBloc, child: gameWidget, ), );