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
parent.children.whereType<Multiball>().forEach((multiball) { void onNewState(GameState state) {
multiball.bloc.onAnimate(); parent.children.whereType<Multiball>().forEach((multiball) {
}); 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()), test(
]; 'is false when the bonusHistory has changed '
'with a bonus different than GameBonus.dashNest', () {
await parent.addAll(multiballs); final previous = GameState.initial();
await game.ensureAdd(parent); final state = previous.copyWith(
await parent.ensureAdd(behavior); bonusHistory: [GameBonus.androidSpaceship],
streamController.add(
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]),
); );
await tester.pump();
for (final multiball in multiballs) {
verify(multiball.bloc.onAnimate).called(1);
}
},
);
flameBlocTester.testGameWidget( expect(
"don't animate multiballs when now new GameBonus.dashNest received", MultiballsBehavior().listenWhen(previous, state),
setUp: (game, tester) async { isFalse,
final streamController = StreamController<GameState>(); );
whenListen( });
gameBloc,
streamController.stream, test('is false when the bonusHistory state is the same', () {
initialState: const GameState.initial(), final state = GameState(
score: 10,
multiplier: 1,
rounds: 0,
bonusHistory: const [],
); );
final behavior = MultiballsBehavior(); final previous = GameState.initial();
final parent = Multiballs.test(); expect(
final multiballs = [ MultiballsBehavior().listenWhen(previous, state),
Multiball.test(bloc: MockMultiballCubit()), isFalse,
Multiball.test(bloc: MockMultiballCubit()),
Multiball.test(bloc: MockMultiballCubit()),
Multiball.test(bloc: MockMultiballCubit()),
];
await parent.addAll(multiballs);
await game.ensureAdd(parent);
await parent.ensureAdd(behavior);
streamController.add(
GameState.initial().copyWith(
bonusHistory: [GameBonus.sparkyTurboCharge],
),
); );
await tester.pump(); });
});
for (final multiball in multiballs) { group('onNewState', () {
verifyNever(multiball.bloc.onAnimate); flameBlocTester.testGameWidget(
} "calls 'onAnimate' once per each multiball when GameBloc emit state",
}, setUp: (game, tester) async {
); final behavior = MultiballsBehavior();
final parent = Multiballs.test();
final multiballCubit = MockMultiballCubit();
final otherMultiballCubit = MockMultiballCubit();
final multiballs = [
Multiball.test(
bloc: multiballCubit,
),
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 game.ensureAdd(parent);
await parent.ensureAdd(behavior);
await tester.pump();
behavior.onNewState(
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]),
);
for (final multiball in multiballs) {
verify(
multiball.bloc.onAnimate,
).called(1);
}
},
);
});
}); });
} }

Loading…
Cancel
Save