fix: fixed bloc error on behavior with tests

pull/235/head
RuiAlonso 3 years ago
parent 40526bf0fe
commit ff909394ae

@ -1,40 +1,26 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/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';
/// Toggle each [Multiball] when there is a bonus ball. /// Toggle each [Multiball] when there is a bonus ball.
class MultiballsBehavior extends Component class MultiballsBehavior extends Component
with HasGameRef<PinballGame>, ParentIsA<Multiballs> { with
HasGameRef<PinballGame>,
ParentIsA<Multiballs>,
BlocComponent<GameBloc, GameState> {
@override @override
void onMount() { bool listenWhen(GameState? previousState, GameState newState) {
super.onMount(); final hasMultiball = newState.bonusHistory.contains(GameBonus.dashNest);
final hasChanged = previousState?.bonusHistory != newState.bonusHistory;
var _previousMultiballBonus = 0; return hasChanged && hasMultiball;
gameRef.read<GameBloc>().stream.listen((state) {
// TODO(ruimiguel): only when state.bonusHistory dashNest has changed
final multiballBonus = state.bonusHistory.fold<int>(
0,
(previousValue, bonus) {
if (bonus == GameBonus.dashNest) {
previousValue++;
} }
return previousValue;
},
);
if (_previousMultiballBonus != multiballBonus) {
_previousMultiballBonus = multiballBonus;
final hasMultiball = state.bonusHistory.contains(GameBonus.dashNest);
if (hasMultiball) { @override
void onNewState(GameState state) {
parent.children.whereType<Multiball>().forEach((multiball) { parent.children.whereType<Multiball>().forEach((multiball) {
multiball.bloc.onAnimate(); multiball.bloc.onAnimate();
}); });
} }
}
});
}
} }

@ -24,6 +24,11 @@ void main() {
setUp(() { setUp(() {
gameBloc = MockGameBloc(); gameBloc = MockGameBloc();
whenListen(
gameBloc,
const Stream<GameState>.empty(),
initialState: const GameState.initial(),
);
}); });
final flameBlocTester = FlameBlocTester<PinballGame, GameBloc>( final flameBlocTester = FlameBlocTester<PinballGame, GameBloc>(
@ -32,74 +37,99 @@ void main() {
assets: assets, assets: assets,
); );
flameBlocTester.testGameWidget( group('listenWhen', () {
'animate multiballs when new GameBonus.dashNest received', test(
setUp: (game, tester) async { 'is true when the bonusHistory has changed '
final streamController = StreamController<GameState>(); 'with a new GameBonus.dashNest', () {
whenListen( final previous = GameState.initial();
gameBloc, final state = previous.copyWith(
streamController.stream, bonusHistory: [GameBonus.dashNest],
initialState: const GameState.initial(),
); );
final behavior = MultiballsBehavior(); expect(
final parent = Multiballs.test(); MultiballsBehavior().listenWhen(previous, state),
final multiballs = [ isTrue,
Multiball.test(bloc: MockMultiballCubit()), );
Multiball.test(bloc: MockMultiballCubit()), });
Multiball.test(bloc: MockMultiballCubit()),
Multiball.test(bloc: MockMultiballCubit()),
];
await parent.addAll(multiballs); test(
await game.ensureAdd(parent); 'is false when the bonusHistory has changed '
await parent.ensureAdd(behavior); 'with a bonus different than GameBonus.dashNest', () {
final previous = GameState.initial();
final state = previous.copyWith(
bonusHistory: [GameBonus.androidSpaceship],
);
streamController.add( expect(
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]), MultiballsBehavior().listenWhen(previous, state),
isFalse,
); );
await tester.pump(); });
for (final multiball in multiballs) { test('is false when the bonusHistory state is the same', () {
verify(multiball.bloc.onAnimate).called(1); final state = GameState(
} score: 10,
}, multiplier: 1,
rounds: 0,
bonusHistory: const [],
); );
flameBlocTester.testGameWidget( final previous = GameState.initial();
"don't animate multiballs when now new GameBonus.dashNest received", expect(
setUp: (game, tester) async { MultiballsBehavior().listenWhen(previous, state),
final streamController = StreamController<GameState>(); isFalse,
whenListen(
gameBloc,
streamController.stream,
initialState: const GameState.initial(),
); );
});
});
group('onNewState', () {
flameBlocTester.testGameWidget(
"calls 'onAnimate' once per each multiball when GameBloc emit state",
setUp: (game, tester) async {
final behavior = MultiballsBehavior(); final behavior = MultiballsBehavior();
final parent = Multiballs.test(); final parent = Multiballs.test();
final multiballCubit = MockMultiballCubit();
final otherMultiballCubit = MockMultiballCubit();
final multiballs = [ final multiballs = [
Multiball.test(bloc: MockMultiballCubit()), Multiball.test(
Multiball.test(bloc: MockMultiballCubit()), bloc: multiballCubit,
Multiball.test(bloc: MockMultiballCubit()), ),
Multiball.test(bloc: MockMultiballCubit()), Multiball.test(
bloc: otherMultiballCubit,
),
]; ];
whenListen(
multiballCubit,
const Stream<MultiballState>.empty(),
initialState: MultiballState.initial(),
);
when(multiballCubit.onAnimate).thenAnswer((_) async {});
whenListen(
otherMultiballCubit,
const Stream<MultiballState>.empty(),
initialState: MultiballState.initial(),
);
when(otherMultiballCubit.onAnimate).thenAnswer((_) async {});
await parent.addAll(multiballs); await parent.addAll(multiballs);
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);
streamController.add(
GameState.initial().copyWith(
bonusHistory: [GameBonus.sparkyTurboCharge],
),
);
await tester.pump(); await tester.pump();
behavior.onNewState(
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]),
);
for (final multiball in multiballs) { for (final multiball in multiballs) {
verifyNever(multiball.bloc.onAnimate); verify(
multiball.bloc.onAnimate,
).called(1);
} }
}, },
); );
}); });
});
} }

Loading…
Cancel
Save