chore: StartGameBloc for control flow before launch the game (#184)

pull/186/head
arturplaczek 3 years ago committed by GitHub
parent e1bdb0e14b
commit 034c3719bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,58 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:pinball/game/game.dart';
part 'start_game_event.dart';
part 'start_game_state.dart';
/// {@template start_game_bloc}
/// Bloc that manages the app flow before the game starts.
/// {@endtemplate}
class StartGameBloc extends Bloc<StartGameEvent, StartGameState> {
/// {@macro start_game_bloc}
StartGameBloc({
required PinballGame game,
}) : _game = game,
super(const StartGameState.initial()) {
on<PlayTapped>(_onPlayTapped);
on<CharacterSelected>(_onCharacterSelected);
on<HowToPlayFinished>(_onHowToPlayFinished);
}
final PinballGame _game;
void _onPlayTapped(
PlayTapped event,
Emitter<StartGameState> emit,
) {
_game.gameFlowController.start();
emit(
state.copyWith(
status: StartGameStatus.selectCharacter,
),
);
}
void _onCharacterSelected(
CharacterSelected event,
Emitter<StartGameState> emit,
) {
emit(
state.copyWith(
status: StartGameStatus.howToPlay,
),
);
}
void _onHowToPlayFinished(
HowToPlayFinished event,
Emitter<StartGameState> emit,
) {
emit(
state.copyWith(
status: StartGameStatus.play,
),
);
}
}

@ -0,0 +1,42 @@
part of 'start_game_bloc.dart';
/// {@template start_game_event}
/// Event added during the start game flow.
/// {@endtemplate}
abstract class StartGameEvent extends Equatable {
/// {@macro start_game_event}
const StartGameEvent();
}
/// {@template play_tapped}
/// Play tapped event.
/// {@endtemplate}
class PlayTapped extends StartGameEvent {
/// {@macro play_tapped}
const PlayTapped();
@override
List<Object> get props => [];
}
/// {@template character_selected}
/// Character selected event.
/// {@endtemplate}
class CharacterSelected extends StartGameEvent {
/// {@macro character_selected}
const CharacterSelected();
@override
List<Object> get props => [];
}
/// {@template how_to_play_finished}
/// How to play finished event.
/// {@endtemplate}
class HowToPlayFinished extends StartGameEvent {
/// {@macro how_to_play_finished}
const HowToPlayFinished();
@override
List<Object> get props => [];
}

@ -0,0 +1,44 @@
part of 'start_game_bloc.dart';
/// Defines status of start game flow.
enum StartGameStatus {
/// Initial status.
initial,
/// Selection characters status.
selectCharacter,
/// How to play status.
howToPlay,
/// Play status.
play,
}
/// {@template start_game_state}
/// Represents the state of flow before the game starts.
/// {@endtemplate}
class StartGameState extends Equatable {
/// {@macro start_game_state}
const StartGameState({
required this.status,
});
/// Initial [StartGameState].
const StartGameState.initial() : this(status: StartGameStatus.initial);
/// Status of [StartGameState].
final StartGameStatus status;
/// Creates a copy of [StartGameState].
StartGameState copyWith({
StartGameStatus? status,
}) {
return StartGameState(
status: status ?? this.status,
);
}
@override
List<Object> get props => [status];
}

@ -0,0 +1 @@
export 'bloc/start_game_bloc.dart';

@ -0,0 +1,62 @@
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';
void main() {
late PinballGame pinballGame;
setUp(() {
pinballGame = MockPinballGame();
when(
() => pinballGame.gameFlowController,
).thenReturn(
MockGameFlowController(),
);
});
group('StartGameBloc', () {
blocTest<StartGameBloc, StartGameState>(
'on PlayTapped changes status to selectCharacter',
build: () => StartGameBloc(
game: pinballGame,
),
act: (bloc) => bloc.add(const PlayTapped()),
expect: () => [
const StartGameState(
status: StartGameStatus.selectCharacter,
)
],
);
blocTest<StartGameBloc, StartGameState>(
'on CharacterSelected changes status to howToPlay',
build: () => StartGameBloc(
game: pinballGame,
),
act: (bloc) => bloc.add(const CharacterSelected()),
expect: () => [
const StartGameState(
status: StartGameStatus.howToPlay,
)
],
);
blocTest<StartGameBloc, StartGameState>(
'on HowToPlayFinished changes status to play',
build: () => StartGameBloc(
game: pinballGame,
),
act: (bloc) => bloc.add(const HowToPlayFinished()),
expect: () => [
const StartGameState(
status: StartGameStatus.play,
)
],
);
});
}

@ -0,0 +1,29 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/start_game/bloc/start_game_bloc.dart';
void main() {
group('StartGameEvent', () {
test('PlayTapped supports value equality', () {
expect(
PlayTapped(),
equals(PlayTapped()),
);
});
test('CharacterSelected supports value equality', () {
expect(
CharacterSelected(),
equals(CharacterSelected()),
);
});
test('HowToPlayFinished supports value equality', () {
expect(
HowToPlayFinished(),
equals(HowToPlayFinished()),
);
});
});
}

@ -0,0 +1,43 @@
// ignore_for_file: prefer_const_constructors
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/start_game/bloc/start_game_bloc.dart';
void main() {
group('StartGameState', () {
final testState = StartGameState(
status: StartGameStatus.selectCharacter,
);
test('initial state has correct values', () {
final state = StartGameState(
status: StartGameStatus.initial,
);
expect(state, StartGameState.initial());
});
test('supports value equality', () {
final secondState = StartGameState(
status: StartGameStatus.selectCharacter,
);
expect(testState, secondState);
});
test('supports copyWith', () {
final secondState = testState.copyWith();
expect(testState, secondState);
});
test('has correct props', () {
expect(
testState.props,
equals([
StartGameStatus.selectCharacter,
]),
);
});
});
}
Loading…
Cancel
Save