refactor: changed ramp behaviors

pull/296/head
RuiAlonso 3 years ago
parent db3150b39e
commit fb0d08ffff

@ -19,7 +19,7 @@ class AppBlocObserver extends BlocObserver {
@override @override
void onChange(BlocBase bloc, Change change) { void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change); super.onChange(bloc, change);
log('onChange(${bloc.runtimeType}, $change)'); //log('onChange(${bloc.runtimeType}, $change)');
} }
@override @override

@ -19,11 +19,9 @@ class AndroidAcres extends Component {
children: [ children: [
RampShotBehavior( RampShotBehavior(
points: Points.fiveThousand, points: Points.fiveThousand,
scorePosition: Vector2(0, -45),
), ),
RampBonusBehavior( RampBonusBehavior(
points: Points.oneMillion, points: Points.oneMillion,
scorePosition: Vector2(0, -60),
), ),
], ],
), ),

@ -4,32 +4,33 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
/// {@template ramp_bonus_behavior} /// {@template ramp_bonus_behavior}
/// When a [Ball] shot inside the [SpaceshipRamp] 10 times increases score. /// Increases the score when a [Ball] is shot 10 times into the [SpaceshipRamp].
/// {@endtemplate} /// {@endtemplate}
class RampBonusBehavior extends Component class RampBonusBehavior extends Component
with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> { with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> {
/// {@macro ramp_bonus_behavior} /// {@macro ramp_bonus_behavior}
RampBonusBehavior({ RampBonusBehavior({
required Points points, required Points points,
required Vector2 scorePosition,
}) : _points = points, }) : _points = points,
_scorePosition = scorePosition,
super(); super();
final Points _points; final Points _points;
final Vector2 _scorePosition;
@override @override
void onMount() { void onMount() {
super.onMount(); super.onMount();
parent.bloc.stream.listen((state) { parent.bloc.stream.listen((state) {
if (state.status == SpaceshipRampStatus.withBonus) { print("state.hits ${state.hits}");
final achievedOneMillionPoints = state.hits % 10 == 0;
if (achievedOneMillionPoints) {
print("achievedOneMillionPoints");
gameRef.read<GameBloc>().add(Scored(points: _points.value)); gameRef.read<GameBloc>().add(Scored(points: _points.value));
gameRef.add( gameRef.add(
ScoreComponent( ScoreComponent(
points: _points, points: _points,
position: _scorePosition, position: Vector2(0, -60),
), ),
); );
} }

@ -4,37 +4,35 @@ import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
/// {@template ramp_shot_behavior} /// {@template ramp_shot_behavior}
/// When a [Ball] shot inside the [SpaceshipRamp] it achieve improvements for /// Increases the score when a [Ball] is shot into the [SpaceshipRamp].
/// the current game, like multipliers or score.
/// {@endtemplate} /// {@endtemplate}
class RampShotBehavior extends Component class RampShotBehavior extends Component
with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> { with ParentIsA<SpaceshipRamp>, HasGameRef<PinballGame> {
/// {@macro ramp_shot_behavior} /// {@macro ramp_shot_behavior}
RampShotBehavior({ RampShotBehavior({
required Points points, required Points points,
required Vector2 scorePosition,
}) : _points = points, }) : _points = points,
_scorePosition = scorePosition,
super(); super();
final Points _points; final Points _points;
final Vector2 _scorePosition;
@override @override
void onMount() { void onMount() {
super.onMount(); super.onMount();
parent.bloc.stream.listen((state) { parent.bloc.stream.listen((state) {
if (state.shot) { parent.progress();
parent.progress();
final achievedOneMillionPoints = state.hits % 10 == 0;
if (!achievedOneMillionPoints) {
gameRef.read<GameBloc>() gameRef.read<GameBloc>()
..add(const MultiplierIncreased()) ..add(const MultiplierIncreased())
..add(Scored(points: _points.value)); ..add(Scored(points: _points.value));
gameRef.add( gameRef.add(
ScoreComponent( ScoreComponent(
points: _points, points: _points,
position: _scorePosition, position: Vector2(0, -45),
), ),
); );
} }

@ -7,22 +7,18 @@ import 'package:pinball_flame/pinball_flame.dart';
/// {@template ramp_contact_behavior} /// {@template ramp_contact_behavior}
/// Detects a [Ball]that enters in the [SpaceshipRamp]. /// Detects a [Ball]that enters in the [SpaceshipRamp].
/// ///
/// The [Ball] can hit with sensor at door or sensor inside, just to recognize /// The [Ball] can hit with sensor to recognize if [Ball] goes in or out the
/// when if [Ball] comes from out. /// [SpaceshipRamp].
/// {@endtemplate} /// {@endtemplate}
class RampContactBehavior extends ContactBehavior<RampSensor> { class RampContactBehavior extends ContactBehavior<RampScoringSensor> {
@override @override
void beginContact(Object other, Contact contact) { void beginContact(Object other, Contact contact) {
super.beginContact(other, contact); super.beginContact(other, contact);
if (other is! Ball) return; if (other is! Ball) return;
switch (parent.type) {
case RampSensorType.door: if (other.body.linearVelocity.y < 0) {
parent.parent.bloc.onDoor(other); parent.parent.bloc.onInside();
break;
case RampSensorType.inside:
parent.parent.bloc.onInside(other);
break;
} }
} }
} }

@ -1,43 +1,18 @@
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:collection';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:pinball_components/pinball_components.dart';
part 'spaceship_ramp_state.dart'; part 'spaceship_ramp_state.dart';
class SpaceshipRampCubit extends Cubit<SpaceshipRampState> { class SpaceshipRampCubit extends Cubit<SpaceshipRampState> {
SpaceshipRampCubit() : super(SpaceshipRampState.initial()); SpaceshipRampCubit() : super(SpaceshipRampState.initial());
void onDoor(Ball ball) { void onInside() {
if (!state.balls.contains(ball)) { emit(
emit( state.copyWith(
state.copyWith( hits: state.hits + 1,
balls: state.balls..add(ball), ),
status: SpaceshipRampStatus.withoutBonus, );
),
);
}
}
void onInside(Ball ball) {
if (state.balls.contains(ball)) {
final hits = state.hits + 1;
final bonus = (hits % 10 == 0)
? SpaceshipRampStatus.withBonus
: SpaceshipRampStatus.withoutBonus;
final shot = hits % 10 != 0;
emit(
state.copyWith(
hits: hits,
balls: state.balls..remove(ball),
shot: shot,
status: bonus,
),
);
}
} }
} }

@ -2,56 +2,23 @@
part of 'spaceship_ramp_cubit.dart'; part of 'spaceship_ramp_cubit.dart';
/// Used to know when a [Ball] gets into the [SpaceshipRamp] against every ball
/// that crosses the opening.
enum RampSensorType {
/// Sensor at the entrance of the opening.
door,
/// Sensor inside the [SpaceshipRamp].
inside,
}
enum SpaceshipRampStatus {
withoutBonus,
withBonus,
}
class SpaceshipRampState extends Equatable { class SpaceshipRampState extends Equatable {
const SpaceshipRampState({ const SpaceshipRampState({
required this.hits, required this.hits,
required this.balls,
required this.shot,
required this.status,
}) : assert(hits >= 0, "Hits can't be negative"); }) : assert(hits >= 0, "Hits can't be negative");
SpaceshipRampState.initial() SpaceshipRampState.initial() : this(hits: 0);
: this(
hits: 0,
balls: HashSet(),
shot: false,
status: SpaceshipRampStatus.withoutBonus,
);
final int hits; final int hits;
final Set<Ball> balls;
final bool shot;
final SpaceshipRampStatus status;
SpaceshipRampState copyWith({ SpaceshipRampState copyWith({
int? hits, int? hits,
Set<Ball>? balls,
bool? shot,
SpaceshipRampStatus? status,
}) { }) {
return SpaceshipRampState( return SpaceshipRampState(
hits: hits ?? this.hits, hits: hits ?? this.hits,
balls: balls ?? this.balls,
shot: shot ?? this.shot,
status: status ?? this.status,
); );
} }
@override @override
List<Object?> get props => [hits, balls, shot, status]; List<Object?> get props => [hits];
} }

@ -22,18 +22,11 @@ class SpaceshipRamp extends Component {
children: [ children: [
// TODO(ruimiguel): refactor RampSensor and RampOpening to be in // TODO(ruimiguel): refactor RampSensor and RampOpening to be in
// only one sensor. // only one sensor.
RampSensor( RampScoringSensor(
type: RampSensorType.door,
children: [ children: [
RampContactBehavior(), RampContactBehavior(),
], ],
)..initialPosition = Vector2(1.7, -20.4), )..initialPosition = Vector2(1.7, -20.4),
RampSensor(
type: RampSensorType.inside,
children: [
RampContactBehavior(),
],
)..initialPosition = Vector2(1.7, -22),
_SpaceshipRampOpening( _SpaceshipRampOpening(
outsidePriority: ZIndexes.ballOnBoard, outsidePriority: ZIndexes.ballOnBoard,
rotation: math.pi, rotation: math.pi,
@ -414,15 +407,14 @@ class _SpaceshipRampOpening extends LayerSensor {
} }
} }
/// {@template ramp_sensor} /// {@template ramp_scoring_sensor}
/// Small sensor body used to detect when a ball has entered the /// Small sensor body used to detect when a ball has entered the
/// [SpaceshipRamp]. /// [SpaceshipRamp].
/// {@endtemplate} /// {@endtemplate}
class RampSensor extends BodyComponent class RampScoringSensor extends BodyComponent
with ParentIsA<SpaceshipRamp>, InitialPosition, Layered { with ParentIsA<SpaceshipRamp>, InitialPosition, Layered {
/// {@macro ramp_sensor} /// {@macro ramp_scoring_sensor}
RampSensor({ RampScoringSensor({
required this.type,
Iterable<Component>? children, Iterable<Component>? children,
}) : super( }) : super(
children: children, children: children,
@ -431,15 +423,10 @@ class RampSensor extends BodyComponent
layer = Layer.spaceshipEntranceRamp; layer = Layer.spaceshipEntranceRamp;
} }
/// Creates a [RampSensor] without any children. /// Creates a [RampScoringSensor] without any children.
/// ///
@visibleForTesting @visibleForTesting
RampSensor.test({ RampScoringSensor.test();
required this.type,
});
/// Type for the sensor, to know if it's the one at the door or inside ramp.
final RampSensorType type;
@override @override
Body createBody() { Body createBody() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

@ -3,7 +3,6 @@
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.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_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
@ -13,6 +12,10 @@ import '../../../../helpers/helpers.dart';
class _MockSpaceshipRampCubit extends Mock implements SpaceshipRampCubit {} class _MockSpaceshipRampCubit extends Mock implements SpaceshipRampCubit {}
class _MockBall extends Mock implements Ball {}
class _MockBody extends Mock implements Body {}
class _MockContact extends Mock implements Contact {} class _MockContact extends Mock implements Contact {}
void main() { void main() {
@ -42,63 +45,73 @@ void main() {
); );
}); });
flameTester.test( group('beginContact', () {
"beginContact with door sensor calls bloc 'onDoor'", late Ball ball;
(game) async { late Body body;
final ball = Ball(baseColor: Colors.red);
final behavior = RampContactBehavior(); setUp(() {
final bloc = _MockSpaceshipRampCubit(); ball = _MockBall();
whenListen( body = _MockBody();
bloc,
const Stream<SpaceshipRampState>.empty(), when(() => ball.body).thenReturn(body);
initialState: SpaceshipRampState.initial(), });
);
flameTester.test(
final rampSensor = RampSensor.test( "calls 'onInside' when a ball enters into the ramp",
type: RampSensorType.door, (game) async {
); final behavior = RampContactBehavior();
final spaceshipRamp = SpaceshipRamp.test( final bloc = _MockSpaceshipRampCubit();
bloc: bloc, whenListen(
); bloc,
const Stream<SpaceshipRampState>.empty(),
await spaceshipRamp.add(rampSensor); initialState: SpaceshipRampState.initial(),
await game.ensureAddAll([spaceshipRamp, ball]); );
await rampSensor.add(behavior);
final rampSensor = RampScoringSensor.test();
behavior.beginContact(ball, _MockContact()); final spaceshipRamp = SpaceshipRamp.test(
bloc: bloc,
verify(() => bloc.onDoor(ball)).called(1); );
},
); when(() => body.linearVelocity).thenReturn(Vector2(0, 1));
flameTester.test( await spaceshipRamp.add(rampSensor);
"beginContact with inside sensor calls bloc 'onInside'", await game.ensureAddAll([spaceshipRamp, ball]);
(game) async { await rampSensor.add(behavior);
final ball = Ball(baseColor: Colors.red);
final behavior = RampContactBehavior(); behavior.beginContact(ball, _MockContact());
final bloc = _MockSpaceshipRampCubit();
whenListen( verify(bloc.onInside).called(1);
bloc, },
const Stream<SpaceshipRampState>.empty(), );
initialState: SpaceshipRampState.initial(),
); flameTester.test(
"doesn't call 'onInside' when a ball goes out the ramp",
final rampSensor = RampSensor.test( (game) async {
type: RampSensorType.inside, final behavior = RampContactBehavior();
); final bloc = _MockSpaceshipRampCubit();
final spaceshipRamp = SpaceshipRamp.test( whenListen(
bloc: bloc, bloc,
); const Stream<SpaceshipRampState>.empty(),
initialState: SpaceshipRampState.initial(),
await spaceshipRamp.add(rampSensor); );
await game.ensureAddAll([spaceshipRamp, ball]);
await rampSensor.add(behavior); final rampSensor = RampScoringSensor.test();
final spaceshipRamp = SpaceshipRamp.test(
behavior.beginContact(ball, _MockContact()); bloc: bloc,
);
verify(() => bloc.onInside(ball)).called(1);
}, when(() => body.linearVelocity).thenReturn(Vector2(0, -1));
);
await spaceshipRamp.add(rampSensor);
await game.ensureAddAll([spaceshipRamp, ball]);
await rampSensor.add(behavior);
behavior.beginContact(ball, _MockContact());
verifyNever(bloc.onInside);
},
);
});
}, },
); );
} }

@ -1,96 +1,23 @@
// ignore_for_file: prefer_const_constructors // ignore_for_file: prefer_const_constructors
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
void main() { void main() {
group('SpaceshipRampCubit', () { group('SpaceshipRampCubit', () {
final ball = Ball(baseColor: Colors.red);
group('onDoor', () {
blocTest<SpaceshipRampCubit, SpaceshipRampState>(
'emits nothing if contains ball',
build: SpaceshipRampCubit.new,
seed: () => SpaceshipRampState.initial().copyWith(
balls: {ball},
),
act: (bloc) => bloc.onDoor(ball),
expect: () => <SpaceshipRampState>[],
);
blocTest<SpaceshipRampCubit, SpaceshipRampState>(
'emits [{ball}, withoutBonus] if not contains ball',
build: SpaceshipRampCubit.new,
act: (bloc) => bloc.onDoor(ball),
expect: () => [
isA<SpaceshipRampState>()
..having(
(state) => state.balls,
'balls',
contains(ball),
)
..having(
(state) => state.status,
'status',
SpaceshipRampStatus.withoutBonus,
),
],
);
});
group('onInside', () { group('onInside', () {
blocTest<SpaceshipRampCubit, SpaceshipRampState>( blocTest<SpaceshipRampCubit, SpaceshipRampState>(
'emits nothing if not contains ball', 'emits hits incremented',
build: SpaceshipRampCubit.new,
seed: () => SpaceshipRampState.initial().copyWith(
balls: {},
),
act: (bloc) => bloc.onInside(ball),
expect: () => <SpaceshipRampState>[],
);
blocTest<SpaceshipRampCubit, SpaceshipRampState>(
'emits withoutBonus if contains ball '
'and hits less than 10 times',
build: SpaceshipRampCubit.new,
seed: () => SpaceshipRampState.initial().copyWith(
hits: 5,
balls: {ball},
),
act: (bloc) => bloc.onInside(ball),
expect: () => [
isA<SpaceshipRampState>()
..having((state) => state.hits, 'hits', 6)
..having((state) => state.balls, 'balls', isNot(contains(ball)))
..having((state) => state.shot, 'shot', true)
..having(
(state) => state.status,
'status',
SpaceshipRampStatus.withoutBonus,
),
],
);
blocTest<SpaceshipRampCubit, SpaceshipRampState>(
'emits withBonus if contains ball and hits 10 times',
build: SpaceshipRampCubit.new, build: SpaceshipRampCubit.new,
seed: () => SpaceshipRampState.initial().copyWith( act: (bloc) => bloc
hits: 9, ..onInside()
balls: {ball}, ..onInside()
), ..onInside(),
act: (bloc) => bloc.onInside(ball),
expect: () => [ expect: () => [
isA<SpaceshipRampState>() SpaceshipRampState(hits: 1),
..having((state) => state.hits, 'hits', 10) SpaceshipRampState(hits: 2),
..having((state) => state.balls, 'balls', contains(ball)) SpaceshipRampState(hits: 3),
..having((state) => state.shot, 'shot', false)
..having(
(state) => state.status,
'status',
SpaceshipRampStatus.withBonus,
),
], ],
); );
}); });

@ -10,16 +10,10 @@ void main() {
expect( expect(
SpaceshipRampState( SpaceshipRampState(
hits: 0, hits: 0,
balls: const {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
), ),
equals( equals(
SpaceshipRampState( SpaceshipRampState(
hits: 0, hits: 0,
balls: const {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
), ),
), ),
); );
@ -30,9 +24,6 @@ void main() {
expect( expect(
SpaceshipRampState( SpaceshipRampState(
hits: 0, hits: 0,
balls: const {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
), ),
isNotNull, isNotNull,
); );
@ -46,9 +37,6 @@ void main() {
expect( expect(
() => SpaceshipRampState( () => SpaceshipRampState(
hits: -1, hits: -1,
balls: const {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
), ),
throwsAssertionError, throwsAssertionError,
); );
@ -62,9 +50,6 @@ void main() {
() { () {
const rampState = SpaceshipRampState( const rampState = SpaceshipRampState(
hits: 0, hits: 0,
balls: {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
); );
expect( expect(
() => rampState.copyWith(hits: rampState.hits - 1), () => rampState.copyWith(hits: rampState.hits - 1),
@ -79,9 +64,6 @@ void main() {
() { () {
const rampState = SpaceshipRampState( const rampState = SpaceshipRampState(
hits: 0, hits: 0,
balls: {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
); );
expect( expect(
rampState.copyWith(), rampState.copyWith(),
@ -98,24 +80,15 @@ void main() {
const rampState = SpaceshipRampState( const rampState = SpaceshipRampState(
hits: 0, hits: 0,
balls: {},
shot: false,
status: SpaceshipRampStatus.withoutBonus,
); );
final otherRampState = SpaceshipRampState( final otherRampState = SpaceshipRampState(
hits: rampState.hits + 1, hits: rampState.hits + 1,
balls: {ball},
shot: true,
status: SpaceshipRampStatus.withBonus,
); );
expect(rampState, isNot(equals(otherRampState))); expect(rampState, isNot(equals(otherRampState)));
expect( expect(
rampState.copyWith( rampState.copyWith(
hits: rampState.hits + 1, hits: rampState.hits + 1,
balls: {ball},
shot: true,
status: SpaceshipRampStatus.withBonus,
), ),
equals(otherRampState), equals(otherRampState),
); );

@ -1,13 +1,17 @@
// ignore_for_file: cascade_invocations // ignore_for_file: cascade_invocations
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_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.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 '../../helpers/helpers.dart'; import '../../helpers/helpers.dart';
class _MockSpaceshipRampCubit extends Mock implements SpaceshipRampCubit {}
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
final assets = [ final assets = [
@ -204,5 +208,37 @@ void main() {
}, },
); );
}); });
flameTester.test('closes bloc when removed', (game) async {
final bloc = _MockSpaceshipRampCubit();
whenListen(
bloc,
const Stream<SpaceshipRampState>.empty(),
initialState: SpaceshipRampState.initial(),
);
when(bloc.close).thenAnswer((_) async {});
final ramp = SpaceshipRamp.test(
bloc: bloc,
);
await game.ensureAdd(ramp);
game.remove(ramp);
await game.ready();
verify(bloc.close).called(1);
});
group('adds', () {
flameTester.test('new children', (game) async {
final component = Component();
final ramp = SpaceshipRamp.test(
bloc: _MockSpaceshipRampCubit(),
children: [component],
);
await game.ensureAdd(ramp);
expect(ramp.children, contains(component));
});
});
}); });
} }

@ -3,7 +3,6 @@
import 'dart:async'; import 'dart:async';
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.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';
@ -32,7 +31,7 @@ void main() {
Assets.images.android.ramp.arrow.active5.keyName, Assets.images.android.ramp.arrow.active5.keyName,
Assets.images.android.rail.main.keyName, Assets.images.android.rail.main.keyName,
Assets.images.android.rail.exit.keyName, Assets.images.android.rail.exit.keyName,
Assets.images.score.fiveThousand.keyName, Assets.images.score.oneMillion.keyName,
]; ];
group('RampBonusBehavior', () { group('RampBonusBehavior', () {
@ -56,17 +55,18 @@ void main() {
); );
flameBlocTester.testGameWidget( flameBlocTester.testGameWidget(
"when withoutBonus doesn't add any score or show any score points", 'when hits are multiples of 10 times '
'add score and show score points',
setUp: (game, tester) async { setUp: (game, tester) async {
final bloc = _MockSpaceshipRampCubit(); final bloc = _MockSpaceshipRampCubit();
final streamController = StreamController<SpaceshipRampState>();
whenListen( whenListen(
bloc, bloc,
const Stream<SpaceshipRampState>.empty(), streamController.stream,
initialState: SpaceshipRampState.initial(), initialState: SpaceshipRampState(hits: 9),
); );
final behavior = RampShotBehavior( final behavior = RampBonusBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(),
); );
final parent = SpaceshipRamp.test( final parent = SpaceshipRamp.test(
bloc: bloc, bloc: bloc,
@ -75,30 +75,29 @@ void main() {
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
await tester.pump(); streamController.add(SpaceshipRampState(hits: 10));
final scores = game.descendants().whereType<ScoreComponent>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(Scored(points: shotPoints.value))); verify(() => gameBloc.add(Scored(points: shotPoints.value))).called(1);
expect(scores.length, 0); expect(scores.length, 1);
}, },
); );
flameBlocTester.testGameWidget( flameBlocTester.testGameWidget(
'when withBonus add score and show score points', 'when hits are not multiple of 10 times '
"doesn't add score neither show score points",
setUp: (game, tester) async { setUp: (game, tester) async {
final bloc = _MockSpaceshipRampCubit(); final bloc = _MockSpaceshipRampCubit();
final streamController = StreamController<SpaceshipRampState>();
whenListen( whenListen(
bloc, bloc,
const Stream<SpaceshipRampState>.empty(), streamController.stream,
initialState: SpaceshipRampState.initial().copyWith( initialState: SpaceshipRampState.initial(),
status: SpaceshipRampStatus.withBonus,
),
); );
final behavior = RampShotBehavior( final behavior = RampBonusBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(),
); );
final parent = SpaceshipRamp.test( final parent = SpaceshipRamp.test(
bloc: bloc, bloc: bloc,
@ -107,12 +106,11 @@ void main() {
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
await tester.pump(); streamController.add(SpaceshipRampState(hits: 1));
final scores = game.descendants().whereType<ScoreComponent>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(MultiplierIncreased()));
verifyNever(() => gameBloc.add(Scored(points: shotPoints.value))); verifyNever(() => gameBloc.add(Scored(points: shotPoints.value)));
expect(scores.length, 0); expect(scores.length, 0);
}, },

@ -3,7 +3,6 @@
import 'dart:async'; import 'dart:async';
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.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';
@ -56,18 +55,18 @@ void main() {
); );
flameBlocTester.testGameWidget( flameBlocTester.testGameWidget(
"when not shot doesn't increase multiplier " 'when hits are not multiple of 10 times '
'neither add any score or show any score points', 'increase multiplier, add score and show score points',
setUp: (game, tester) async { setUp: (game, tester) async {
final bloc = _MockSpaceshipRampCubit(); final bloc = _MockSpaceshipRampCubit();
final streamController = StreamController<SpaceshipRampState>();
whenListen( whenListen(
bloc, bloc,
const Stream<SpaceshipRampState>.empty(), streamController.stream,
initialState: SpaceshipRampState.initial(), initialState: SpaceshipRampState.initial(),
); );
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(),
); );
final parent = SpaceshipRamp.test( final parent = SpaceshipRamp.test(
bloc: bloc, bloc: bloc,
@ -76,31 +75,30 @@ void main() {
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
await tester.pump(); streamController.add(SpaceshipRampState(hits: 1));
final scores = game.descendants().whereType<ScoreComponent>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();
verifyNever(() => gameBloc.add(MultiplierIncreased())); verify(() => gameBloc.add(MultiplierIncreased())).called(1);
verifyNever(() => gameBloc.add(Scored(points: shotPoints.value))); verify(() => gameBloc.add(Scored(points: shotPoints.value))).called(1);
expect(scores.length, 0); expect(scores.length, 1);
}, },
); );
flameBlocTester.testGameWidget( flameBlocTester.testGameWidget(
'when shot increase multiplier add score and show score points', 'when hits multiple of 10 times '
"doesn't increase multiplier, neither add score or show score points",
setUp: (game, tester) async { setUp: (game, tester) async {
final bloc = _MockSpaceshipRampCubit(); final bloc = _MockSpaceshipRampCubit();
final streamController = StreamController<SpaceshipRampState>();
whenListen( whenListen(
bloc, bloc,
const Stream<SpaceshipRampState>.empty(), streamController.stream,
initialState: SpaceshipRampState.initial().copyWith( initialState: SpaceshipRampState(hits: 9),
shot: false,
),
); );
final behavior = RampShotBehavior( final behavior = RampShotBehavior(
points: shotPoints, points: shotPoints,
scorePosition: Vector2.zero(),
); );
final parent = SpaceshipRamp.test( final parent = SpaceshipRamp.test(
bloc: bloc, bloc: bloc,
@ -109,7 +107,7 @@ void main() {
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
await tester.pump(); streamController.add(SpaceshipRampState(hits: 10));
final scores = game.descendants().whereType<ScoreComponent>(); final scores = game.descendants().whereType<ScoreComponent>();
await game.ready(); await game.ready();

Loading…
Cancel
Save