feat: tests

pull/341/head
Erick Zanardo 3 years ago
parent a3e0e35b9c
commit f32985d0bc

@ -1,10 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart'; import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball/game/components/backbox/displays/displays.dart'; import 'package:pinball/game/components/backbox/displays/displays.dart';
import 'package:pinball/game/pinball_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;
@ -12,11 +11,11 @@ import 'package:pinball_theme/pinball_theme.dart' hide Assets;
/// {@template backbox} /// {@template backbox}
/// The [Backbox] of the pinball machine. /// The [Backbox] of the pinball machine.
/// {@endtemplate} /// {@endtemplate}
class Backbox extends PositionComponent with HasGameRef, ZIndex { class Backbox extends PositionComponent with HasGameRef<PinballGame>, ZIndex {
/// {@macro backbox} /// {@macro backbox}
Backbox({ Backbox({
LeaderboardRepository? leaderboardRepository, required BackboxBloc bloc,
}) : _leaderboardRepository = leaderboardRepository, }) : _bloc = bloc,
super( super(
position: Vector2(0, -87), position: Vector2(0, -87),
anchor: Anchor.bottomCenter, anchor: Anchor.bottomCenter,
@ -29,16 +28,12 @@ class Backbox extends PositionComponent with HasGameRef, ZIndex {
} }
late final Component _display; late final Component _display;
late final LeaderboardRepository? _leaderboardRepository; final BackboxBloc _bloc;
late BackboxBloc _bloc;
late StreamSubscription<BackboxState> _subscription; late StreamSubscription<BackboxState> _subscription;
@override @override
Future<void> onLoad() async { Future<void> onLoad() async {
final repository = _leaderboardRepository ?? _subscription = _bloc.stream.listen((state) {
gameRef.buildContext!.read<LeaderboardRepository>();
_bloc = BackboxBloc(leaderboardRepository: repository);
_bloc.stream.listen((state) {
_display.children.removeWhere((_) => true); _display.children.removeWhere((_) => true);
_build(state); _build(state);
}); });

@ -24,7 +24,7 @@ class PlayerInitialsRequested extends BackboxEvent {
final CharacterTheme character; final CharacterTheme character;
@override @override
List<Object?> get props => [props, character]; List<Object?> get props => [score, character];
} }
/// {@template player_initials_submited} /// {@template player_initials_submited}
@ -46,5 +46,5 @@ class PlayerInitialsSubmited extends BackboxEvent {
final CharacterTheme character; final CharacterTheme character;
@override @override
List<Object?> get props => [props, initials, character]; List<Object?> get props => [score, initials, character];
} }

@ -1,6 +1,7 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_ui/pinball_ui.dart'; import 'package:pinball_ui/pinball_ui.dart';
@ -13,9 +14,14 @@ final _bodyTextPaint = TextPaint(
); );
/// {@template loading_display} /// {@template loading_display}
/// /// Display used to show the loading animation
/// {@endtemplate} /// {@endtemplate}
class LoadingDisplay extends TextComponent with HasGameRef<PinballGame> { class LoadingDisplay extends TextComponent with HasGameRef<PinballGame> {
/// {@template loading_display
LoadingDisplay({ AppLocalizations? l10n }) : _l10n = l10n;
final AppLocalizations? _l10n;
late final String _label; late final String _label;
@override @override
@ -24,7 +30,7 @@ class LoadingDisplay extends TextComponent with HasGameRef<PinballGame> {
position = Vector2(0, -10); position = Vector2(0, -10);
anchor = Anchor.center; anchor = Anchor.center;
text = _label = gameRef.l10n.loading; text = _label = (_l10n ?? gameRef.l10n).loading;
textRenderer = _bodyTextPaint; textRenderer = _bodyTextPaint;
await add( await add(

@ -7,8 +7,9 @@ import 'package:flame/input.dart';
import 'package:flame_bloc/flame_bloc.dart'; 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:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/behaviors/behaviors.dart';
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_audio/pinball_audio.dart';
@ -24,6 +25,7 @@ class PinballGame extends PinballForge2DGame
MultiTouchTapDetector { MultiTouchTapDetector {
PinballGame({ PinballGame({
required this.characterTheme, required this.characterTheme,
required this.leaderboardRepository,
required this.l10n, required this.l10n,
required this.player, required this.player,
}) : super(gravity: Vector2(0, 30)) { }) : super(gravity: Vector2(0, 30)) {
@ -41,6 +43,8 @@ class PinballGame extends PinballForge2DGame
final PinballPlayer player; final PinballPlayer player;
final LeaderboardRepository leaderboardRepository;
final AppLocalizations l10n; final AppLocalizations l10n;
@override @override
@ -50,7 +54,7 @@ class PinballGame extends PinballForge2DGame
final machine = [ final machine = [
BoardBackgroundSpriteComponent(), BoardBackgroundSpriteComponent(),
Boundaries(), Boundaries(),
Backbox(), Backbox(bloc: BackboxBloc(leaderboardRepository: leaderboardRepository)),
]; ];
final decals = [ final decals = [
GoogleWord(position: Vector2(-4.25, 1.8)), GoogleWord(position: Vector2(-4.25, 1.8)),
@ -185,11 +189,13 @@ class _GameBallsController extends ComponentController<PinballGame>
class DebugPinballGame extends PinballGame with FPSCounter, PanDetector { class DebugPinballGame extends PinballGame with FPSCounter, PanDetector {
DebugPinballGame({ DebugPinballGame({
required CharacterTheme characterTheme, required CharacterTheme characterTheme,
required LeaderboardRepository leaderboardRepository,
required AppLocalizations l10n, required AppLocalizations l10n,
required PinballPlayer player, required PinballPlayer player,
}) : super( }) : super(
characterTheme: characterTheme, characterTheme: characterTheme,
player: player, player: player,
leaderboardRepository: leaderboardRepository,
l10n: l10n, l10n: l10n,
) { ) {
controller = _GameBallsController(this); controller = _GameBallsController(this);
@ -204,18 +210,6 @@ class DebugPinballGame extends PinballGame with FPSCounter, PanDetector {
await add(PreviewLine()); await add(PreviewLine());
await add(_DebugInformation()); await add(_DebugInformation());
await add(
KeyboardInputController(
keyUp: {
LogicalKeyboardKey.escape: () {
read<GameBloc>().add(const RoundLost());
read<GameBloc>().add(const RoundLost());
read<GameBloc>().add(const RoundLost());
return true;
},
},
),
);
} }
@override @override

@ -4,6 +4,7 @@ import 'package:flame/game.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/assets_manager/assets_manager.dart'; import 'package:pinball/assets_manager/assets_manager.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/l10n/l10n.dart';
@ -37,23 +38,25 @@ class PinballGamePage extends StatelessWidget {
final characterTheme = final characterTheme =
context.read<CharacterThemeCubit>().state.characterTheme; context.read<CharacterThemeCubit>().state.characterTheme;
final player = context.read<PinballPlayer>(); final player = context.read<PinballPlayer>();
final pinballAudio = context.read<PinballPlayer>(); final leaderboardRepository = context.read<LeaderboardRepository>();
final game = isDebugMode final game = isDebugMode
? DebugPinballGame( ? DebugPinballGame(
characterTheme: characterTheme, characterTheme: characterTheme,
player: player, player: player,
leaderboardRepository: leaderboardRepository,
l10n: context.l10n, l10n: context.l10n,
) )
: PinballGame( : PinballGame(
characterTheme: characterTheme, characterTheme: characterTheme,
player: player, player: player,
leaderboardRepository: leaderboardRepository,
l10n: context.l10n, l10n: context.l10n,
); );
final loadables = [ final loadables = [
...game.preLoadAssets(), ...game.preLoadAssets(),
...pinballAudio.load(), ...player.load(),
...BonusAnimation.loadAssets(), ...BonusAnimation.loadAssets(),
...SelectedCharacter.loadAssets(), ...SelectedCharacter.loadAssets(),
]; ];

@ -1,3 +1,4 @@
import 'package:equatable/equatable.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball_theme/pinball_theme.dart'; import 'package:pinball_theme/pinball_theme.dart';
@ -6,9 +7,9 @@ import 'package:pinball_theme/pinball_theme.dart';
/// player's initials, score, and chosen character. /// player's initials, score, and chosen character.
/// ///
/// {@endtemplate} /// {@endtemplate}
class LeaderboardEntry { class LeaderboardEntry extends Equatable {
/// {@macro leaderboard_entry} /// {@macro leaderboard_entry}
LeaderboardEntry({ const LeaderboardEntry({
required this.rank, required this.rank,
required this.playerInitials, required this.playerInitials,
required this.score, required this.score,
@ -26,6 +27,9 @@ class LeaderboardEntry {
/// [CharacterTheme] for [LeaderboardEntry]. /// [CharacterTheme] for [LeaderboardEntry].
final AssetGenImage character; final AssetGenImage character;
@override
List<Object?> get props => [rank, playerInitials, score, character];
} }
/// Converts [LeaderboardEntryData] from repository to [LeaderboardEntry]. /// Converts [LeaderboardEntryData] from repository to [LeaderboardEntry].

@ -1,10 +1,15 @@
// ignore_for_file: cascade_invocations // ignore_for_file: cascade_invocations, prefer_const_constructors
import 'package:bloc_test/bloc_test.dart';
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/backbox/displays/initials_input_display.dart'; import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball/game/components/backbox/displays/displays.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/l10n/l10n.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
@ -12,6 +17,24 @@ import 'package:pinball_theme/pinball_theme.dart' as theme;
import '../../../helpers/helpers.dart'; import '../../../helpers/helpers.dart';
class _MockRawKeyUpEvent extends Mock implements RawKeyUpEvent {
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return super.toString();
}
}
RawKeyUpEvent _mockKeyUp(LogicalKeyboardKey key) {
final event = _MockRawKeyUpEvent();
when(() => event.logicalKey).thenReturn(key);
return event;
}
class _MockBackboxBloc extends Mock implements BackboxBloc {}
class _MockLeaderboardRepository extends Mock implements LeaderboardRepository {
}
class _MockAppLocalizations extends Mock implements AppLocalizations { class _MockAppLocalizations extends Mock implements AppLocalizations {
@override @override
String get score => ''; String get score => '';
@ -33,13 +56,16 @@ class _MockAppLocalizations extends Mock implements AppLocalizations {
@override @override
String get toSubmit => ''; String get toSubmit => '';
@override
String get loading => '';
} }
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
final characterIconPath = theme.Assets.images.dash.leaderboardIcon.keyName; const character = theme.AndroidTheme();
final assets = [ final assets = [
characterIconPath, character.leaderboardIcon.keyName,
Assets.images.backbox.marquee.keyName, Assets.images.backbox.marquee.keyName,
Assets.images.backbox.displayDivider.keyName, Assets.images.backbox.displayDivider.keyName,
]; ];
@ -50,11 +76,22 @@ void main() {
), ),
); );
late BackboxBloc bloc;
setUp(() {
bloc = _MockBackboxBloc();
whenListen(
bloc,
Stream.value(LoadingState()),
initialState: LoadingState(),
);
});
group('Backbox', () { group('Backbox', () {
flameTester.test( flameTester.test(
'loads correctly', 'loads correctly',
(game) async { (game) async {
final backbox = Backbox(); final backbox = Backbox(bloc: bloc);
await game.ensureAdd(backbox); await game.ensureAdd(backbox);
expect(game.children, contains(backbox)); expect(game.children, contains(backbox));
@ -68,7 +105,9 @@ void main() {
game.camera game.camera
..followVector2(Vector2(0, -130)) ..followVector2(Vector2(0, -130))
..zoom = 6; ..zoom = 6;
await game.ensureAdd(Backbox()); await game.ensureAdd(
Backbox(bloc: bloc),
);
await tester.pump(); await tester.pump();
}, },
verify: (game, tester) async { verify: (game, tester) async {
@ -80,18 +119,120 @@ void main() {
); );
flameTester.test( flameTester.test(
'initialsInput adds InitialsInputDisplay', 'requestInitials adds InitialsInputDisplay',
(game) async { (game) async {
final backbox = Backbox(); final backbox = Backbox(
bloc: BackboxBloc(
leaderboardRepository: _MockLeaderboardRepository(),
),
);
await game.ensureAdd(backbox); await game.ensureAdd(backbox);
await backbox.initialsInput( backbox.requestInitials(
score: 0, score: 0,
characterIconPath: characterIconPath, character: character,
onSubmit: (_) {}, );
await game.ready();
expect(
backbox.descendants().whereType<InitialsInputDisplay>().length,
equals(1),
);
},
);
flameTester.test(
'adds PlayerInitialsSubmited when initials are submitted',
(game) async {
final bloc = _MockBackboxBloc();
final state = InitialsFormState(
score: 10,
character: theme.AndroidTheme(),
);
whenListen(
bloc,
Stream.value(state),
initialState: state,
);
final backbox = Backbox(bloc: bloc);
await game.ensureAdd(backbox);
game.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.enter), {});
verify(
() => bloc.add(
PlayerInitialsSubmited(
score: 10,
initials: 'AAA',
character: theme.AndroidTheme(),
),
),
).called(1);
},
);
flameTester.test(
'adds InitialsSubmissionSuccessDisplay on InitialsSuccessState',
(game) async {
whenListen(
bloc,
Stream.value(InitialsSuccessState()),
initialState: InitialsSuccessState(),
);
final backbox = Backbox(bloc: bloc);
await game.ensureAdd(backbox);
expect(
game
.descendants()
.whereType<InitialsSubmissionSuccessDisplay>()
.length,
equals(1),
);
},
);
flameTester.test(
'adds InitialsSubmissionFailureDisplay on InitialsFailureState',
(game) async {
whenListen(
bloc,
Stream.value(InitialsFailureState()),
initialState: InitialsFailureState(),
);
final backbox = Backbox(bloc: bloc);
await game.ensureAdd(backbox);
expect(
game
.descendants()
.whereType<InitialsSubmissionFailureDisplay>()
.length,
equals(1),
); );
},
);
flameTester.test(
'closes the subscription when it is removed',
(game) async {
final backbox = Backbox(bloc: bloc);
await game.ensureAdd(backbox);
backbox.removeFromParent();
await game.ready(); await game.ready();
expect(backbox.firstChild<InitialsInputDisplay>(), isNotNull); whenListen(
bloc,
Stream.value(InitialsFailureState()),
initialState: InitialsFailureState(),
);
expect(
backbox
.descendants()
.whereType<InitialsSubmissionFailureDisplay>()
.isEmpty,
isTrue,
);
}, },
); );
}); });

@ -0,0 +1,92 @@
// ignore_for_file: prefer_const_constructors
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball_theme/pinball_theme.dart';
class _MockLeaderboardRepository extends Mock implements LeaderboardRepository {
}
void main() {
late LeaderboardRepository leaderboardRepository;
group('BackboxBloc', () {
blocTest<BackboxBloc, BackboxState>(
'adds InitialsFormState on PlayerInitialsRequested',
setUp: () {
leaderboardRepository = _MockLeaderboardRepository();
},
build: () => BackboxBloc(leaderboardRepository: leaderboardRepository),
act: (bloc) => bloc.add(
PlayerInitialsRequested(
score: 100,
character: AndroidTheme(),
),
),
expect: () => [
InitialsFormState(score: 100, character: AndroidTheme()),
],
);
group('PlayerInitialsSubmited', () {
blocTest<BackboxBloc, BackboxState>(
'adds [LoadingState, InitialsSuccessState] when submission works',
setUp: () {
leaderboardRepository = _MockLeaderboardRepository();
when(
() => leaderboardRepository.addLeaderboardEntry(
LeaderboardEntryData(
playerInitials: 'AAA',
score: 10,
character: CharacterType.dash,
),
),
).thenAnswer((_) async {});
},
build: () => BackboxBloc(leaderboardRepository: leaderboardRepository),
act: (bloc) => bloc.add(
PlayerInitialsSubmited(
score: 10,
initials: 'AAA',
character: DashTheme(),
),
),
expect: () => [
LoadingState(),
InitialsSuccessState(),
],
);
blocTest<BackboxBloc, BackboxState>(
'adds [LoadingState, InitialsSuccessState] when submission works',
setUp: () {
leaderboardRepository = _MockLeaderboardRepository();
when(
() => leaderboardRepository.addLeaderboardEntry(
LeaderboardEntryData(
playerInitials: 'AAA',
score: 10,
character: CharacterType.dash,
),
),
).thenThrow(Exception('Error'));
},
build: () => BackboxBloc(leaderboardRepository: leaderboardRepository),
act: (bloc) => bloc.add(
PlayerInitialsSubmited(
score: 10,
initials: 'AAA',
character: DashTheme(),
),
),
expect: () => [
LoadingState(),
InitialsFailureState(),
],
);
});
});
}

@ -0,0 +1,126 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('BackboxEvent', () {
group('PlayerInitialsRequested', () {
test('can be instantiated', () {
expect(
PlayerInitialsRequested(score: 0, character: AndroidTheme()),
isNotNull,
);
});
test('supports value comparison', () {
expect(
PlayerInitialsRequested(score: 0, character: AndroidTheme()),
equals(
PlayerInitialsRequested(score: 0, character: AndroidTheme()),
),
);
expect(
PlayerInitialsRequested(score: 0, character: AndroidTheme()),
isNot(
equals(
PlayerInitialsRequested(score: 1, character: AndroidTheme()),
),
),
);
expect(
PlayerInitialsRequested(score: 0, character: AndroidTheme()),
isNot(
equals(
PlayerInitialsRequested(score: 0, character: SparkyTheme()),
),
),
);
});
});
group('PlayerInitialsSubmited', () {
test('can be instantiated', () {
expect(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
isNotNull,
);
});
test('supports value comparison', () {
expect(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
equals(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
),
);
expect(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
isNot(
equals(
PlayerInitialsSubmited(
score: 1,
initials: 'AAA',
character: AndroidTheme(),
),
),
),
);
expect(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
isNot(
equals(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: SparkyTheme(),
),
),
),
);
expect(
PlayerInitialsSubmited(
score: 0,
initials: 'AAA',
character: AndroidTheme(),
),
isNot(
equals(
PlayerInitialsSubmited(
score: 0,
initials: 'BBB',
character: AndroidTheme(),
),
),
),
);
});
});
});
}

@ -0,0 +1,126 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/components/backbox/bloc/backbox_bloc.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('BackboxState', () {
group('LoadingState', () {
test('can be instantiated', () {
expect(LoadingState(), isNotNull);
});
test('supports value comparison', () {
expect(LoadingState(), equals(LoadingState()));
});
});
group('FailureState', () {
test('can be instantiated', () {
expect(FailureState(), isNotNull);
});
test('supports value comparison', () {
expect(FailureState(), equals(FailureState()));
});
});
group('LeaderboardSuccessState', () {
test('can be instantiated', () {
expect(LeaderboardSuccessState(), isNotNull);
});
test('supports value comparison', () {
expect(LeaderboardSuccessState(), equals(LeaderboardSuccessState()));
});
});
group('LeaderboardFailureState', () {
test('can be instantiated', () {
expect(LeaderboardFailureState(), isNotNull);
});
test('supports value comparison', () {
expect(LeaderboardFailureState(), equals(LeaderboardFailureState()));
});
});
group('InitialsFormState', () {
test('can be InitialsFormState', () {
expect(
InitialsFormState(
score: 0,
character: AndroidTheme(),
),
isNotNull,
);
});
test('supports value comparison', () {
expect(
InitialsFormState(
score: 0,
character: AndroidTheme(),
),
equals(
InitialsFormState(
score: 0,
character: AndroidTheme(),
),
),
);
expect(
InitialsFormState(
score: 0,
character: AndroidTheme(),
),
isNot(
equals(
InitialsFormState(
score: 1,
character: AndroidTheme(),
),
),
),
);
expect(
InitialsFormState(
score: 0,
character: AndroidTheme(),
),
isNot(
equals(
InitialsFormState(
score: 0,
character: SparkyTheme(),
),
),
),
);
});
});
group('InitialsSuccessState', () {
test('can be instantiated', () {
expect(InitialsSuccessState(), isNotNull);
});
test('supports value comparison', () {
expect(InitialsSuccessState(), equals(InitialsSuccessState()));
});
group('InitialsFailureState', () {
test('can be instantiated', () {
expect(InitialsFailureState(), isNotNull);
});
test('supports value comparison', () {
expect(InitialsFailureState(), equals(InitialsFailureState()));
});
});
});
});
}

@ -0,0 +1,22 @@
// ignore_for_file: cascade_invocations
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/components/backbox/displays/initials_submission_failure_display.dart';
import '../../../../helpers/helpers.dart';
void main() {
group('InitialsSubmissionFailureDisplay', () {
final flameTester = FlameTester(EmptyKeyboardPinballTestGame.new);
flameTester.test('renders correctly', (game) async {
await game.ensureAdd(InitialsSubmissionFailureDisplay());
final component = game.firstChild<TextComponent>();
expect(component, isNotNull);
expect(component?.text, equals('Failure!'));
});
});
}

@ -0,0 +1,22 @@
// ignore_for_file: cascade_invocations
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/components/backbox/displays/initials_submission_success_display.dart';
import '../../../../helpers/helpers.dart';
void main() {
group('InitialsSubmissionSuccessDisplay', () {
final flameTester = FlameTester(EmptyKeyboardPinballTestGame.new);
flameTester.test('renders correctly', (game) async {
await game.ensureAdd(InitialsSubmissionSuccessDisplay());
final component = game.firstChild<TextComponent>();
expect(component, isNotNull);
expect(component?.text, equals('Success!'));
});
});
}

@ -0,0 +1,50 @@
// ignore_for_file: cascade_invocations
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/components/backbox/displays/loading_display.dart';
import 'package:pinball/l10n/l10n.dart';
import '../../../../helpers/helpers.dart';
class _MockAppLocalizations extends Mock implements AppLocalizations {
@override
String get loading => 'Loading';
}
void main() {
group('LoadingDisplay', () {
final flameTester = FlameTester(EmptyKeyboardPinballTestGame.new);
flameTester.test('renders correctly', (game) async {
await game.ensureAdd(LoadingDisplay(l10n: _MockAppLocalizations()));
final component = game.firstChild<TextComponent>();
expect(component, isNotNull);
expect(component?.text, equals('Loading'));
});
flameTester.test('use ellipses as animation', (game) async {
await game.ensureAdd(LoadingDisplay(l10n: _MockAppLocalizations()));
final component = game.firstChild<TextComponent>();
expect(component?.text, equals('Loading'));
final timer = component?.firstChild<TimerComponent>();
timer?.update(1.1);
expect(component?.text, equals('Loading.'));
timer?.update(1.1);
expect(component?.text, equals('Loading..'));
timer?.update(1.1);
expect(component?.text, equals('Loading...'));
timer?.update(1.1);
expect(component?.text, equals('Loading'));
});
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -20,6 +20,11 @@ class _MockPinballPlayer extends Mock implements PinballPlayer {}
void main() { void main() {
group('GameBlocStatusListener', () { group('GameBlocStatusListener', () {
setUpAll(() {
registerFallbackValue(AndroidTheme());
});
group('listenWhen', () { group('listenWhen', () {
test('is true when the game over state has changed', () { test('is true when the game over state has changed', () {
final state = GameState( final state = GameState(
@ -58,10 +63,9 @@ void main() {
gameFlowController.mockGameRef(game); gameFlowController.mockGameRef(game);
when( when(
() => backbox.initialsInput( () => backbox.requestInitials(
score: any(named: 'score'), score: any(named: 'score'),
characterIconPath: any(named: 'characterIconPath'), character: any(named: 'character'),
onSubmit: any(named: 'onSubmit'),
), ),
).thenAnswer((_) async {}); ).thenAnswer((_) async {});
when(cameraController.focusOnWaitingBackbox).thenAnswer((_) async {}); when(cameraController.focusOnWaitingBackbox).thenAnswer((_) async {});
@ -92,10 +96,9 @@ void main() {
gameFlowController.onNewState(state); gameFlowController.onNewState(state);
verify( verify(
() => backbox.initialsInput( () => backbox.requestInitials(
score: state.displayScore, score: any(named: 'score'),
characterIconPath: any(named: 'characterIconPath'), character: any(named: 'character'),
onSubmit: any(named: 'onSubmit'),
), ),
).called(1); ).called(1);
verify(cameraController.focusOnGameOverBackbox).called(1); verify(cameraController.focusOnGameOverBackbox).called(1);

@ -5,6 +5,7 @@ import 'dart:async';
import 'package:flame/input.dart'; import 'package:flame/input.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/l10n/l10n.dart';
@ -15,6 +16,9 @@ class _MockPinballPlayer extends Mock implements PinballPlayer {}
class _MockAppLocalizations extends Mock implements AppLocalizations {} class _MockAppLocalizations extends Mock implements AppLocalizations {}
class _MockLeaderboardRepository extends Mock implements LeaderboardRepository {
}
class TestGame extends Forge2DGame with FlameBloc { class TestGame extends Forge2DGame with FlameBloc {
TestGame() { TestGame() {
images.prefix = ''; images.prefix = '';
@ -25,11 +29,14 @@ class PinballTestGame extends PinballGame {
PinballTestGame({ PinballTestGame({
List<String>? assets, List<String>? assets,
PinballPlayer? player, PinballPlayer? player,
LeaderboardRepository? leaderboardRepository,
CharacterTheme? theme, CharacterTheme? theme,
AppLocalizations? l10n, AppLocalizations? l10n,
}) : _assets = assets, }) : _assets = assets,
super( super(
player: player ?? _MockPinballPlayer(), player: player ?? _MockPinballPlayer(),
leaderboardRepository:
leaderboardRepository ?? _MockLeaderboardRepository(),
characterTheme: theme ?? const DashTheme(), characterTheme: theme ?? const DashTheme(),
l10n: l10n ?? _MockAppLocalizations(), l10n: l10n ?? _MockAppLocalizations(),
); );
@ -48,11 +55,14 @@ class DebugPinballTestGame extends DebugPinballGame {
DebugPinballTestGame({ DebugPinballTestGame({
List<String>? assets, List<String>? assets,
PinballPlayer? player, PinballPlayer? player,
LeaderboardRepository? leaderboardRepository,
CharacterTheme? theme, CharacterTheme? theme,
AppLocalizations? l10n, AppLocalizations? l10n,
}) : _assets = assets, }) : _assets = assets,
super( super(
player: player ?? _MockPinballPlayer(), player: player ?? _MockPinballPlayer(),
leaderboardRepository:
leaderboardRepository ?? _MockLeaderboardRepository(),
characterTheme: theme ?? const DashTheme(), characterTheme: theme ?? const DashTheme(),
l10n: l10n ?? _MockAppLocalizations(), l10n: l10n ?? _MockAppLocalizations(),
); );

@ -0,0 +1,42 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:leaderboard_repository/leaderboard_repository.dart';
import 'package:pinball/leaderboard/models/leader_board_entry.dart';
import 'package:pinball_theme/pinball_theme.dart';
void main() {
group('LeaderboardEntry', () {
group('toEntry', () {
test('returns the correct from a to entry data', () {
expect(
LeaderboardEntryData.empty.toEntry(1),
LeaderboardEntry(
rank: '1',
playerInitials: '',
score: 0,
character: CharacterType.dash.toTheme.leaderboardIcon,
),
);
});
});
group('CharacterType', () {
test('toTheme returns the correct theme', () {
expect(CharacterType.dash.toTheme, equals(DashTheme()));
expect(CharacterType.sparky.toTheme, equals(SparkyTheme()));
expect(CharacterType.android.toTheme, equals(AndroidTheme()));
expect(CharacterType.dino.toTheme, equals(DinoTheme()));
});
});
group('CharacterTheme', () {
test('toType returns the correct type', () {
expect(DashTheme().toType, equals(CharacterType.dash));
expect(SparkyTheme().toType, equals(CharacterType.sparky));
expect(AndroidTheme().toType, equals(CharacterType.android));
expect(DinoTheme().toType, equals(CharacterType.dino));
});
});
});
}
Loading…
Cancel
Save