@ -15,20 +15,26 @@ void main() {
TestWidgetsFlutterBinding . ensureInitialized ( ) ;
final flameTester = FlameTester ( PinballGameTest . create ) ;
group ( ' B allController' , ( ) {
group ( ' B onusB allController' , ( ) {
late Ball ball ;
setUp ( ( ) {
ball = Ball ( baseColor: const Color ( 0xFF00FFFF ) ) ;
} ) ;
test ( ' can be instantiated ' , ( ) {
expect (
BonusBallController ( ball ) ,
isA < BonusBallController > ( ) ,
) ;
} ) ;
flameTester . test (
' lost removes ball ' ,
( game ) async {
await game . add ( ball ) ;
final controller = BallController ( ball ) ;
await ball . add ( controller ) ;
await game . ready ( ) ;
final controller = BonusBallController ( ball ) ;
await ball . ensureAdd ( controller ) ;
controller . lost ( ) ;
await game . ready ( ) ;
@ -39,13 +45,20 @@ void main() {
} ) ;
group ( ' LaunchedBallController ' , ( ) {
group ( ' lost ' , ( ) {
late GameBloc gameBloc ;
test ( ' can be instantiated ' , ( ) {
expect (
LaunchedBallController ( MockBall ( ) ) ,
isA < LaunchedBallController > ( ) ,
) ;
} ) ;
group ( ' description ' , ( ) {
late Ball ball ;
late GameBloc gameBloc ;
setUp ( ( ) {
gameBloc = MockGameBloc ( ) ;
ball = Ball ( baseColor: const Color ( 0xFF00FFFF ) ) ;
gameBloc = MockGameBloc ( ) ;
whenListen (
gameBloc ,
const Stream < GameState > . empty ( ) ,
@ -59,81 +72,126 @@ void main() {
) ;
tester . testGameWidget (
' removes ball ' ,
verify: ( game , tester ) async {
await game . add ( ball ) ;
' lost adds BallLost to GameBloc ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ready( ) ;
await game . ensureAdd( ball ) ;
controller . lost ( ) ;
await game . ready ( ) ;
expect ( game . contains ( ball ) , isFalse ) ;
} ,
) ;
tester . testGameWidget (
' adds BallLost to GameBloc ' ,
verify: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . add ( ball ) ;
await game . ready ( ) ;
controller . lost ( ) ;
verify ( ( ) = > gameBloc . add ( const BallLost ( ) ) ) . called ( 1 ) ;
} ,
) ;
tester . testGameWidget (
' adds a new ball if the game is not over ' ,
verify: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . add ( ball ) ;
await game . ready ( ) ;
group ( ' listenWhen ' , ( ) {
tester . testGameWidget (
' listens when a ball has been lost ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ensureAdd ( ball ) ;
} ,
verify: ( game , tester ) async {
final controller =
game . descendants ( ) . whereType < LaunchedBallController > ( ) . first ;
final previousState = MockGameState ( ) ;
final newState = MockGameState ( ) ;
when ( ( ) = > previousState . balls ) . thenReturn ( 3 ) ;
when ( ( ) = > newState . balls ) . thenReturn ( 2 ) ;
expect ( controller . listenWhen ( previousState , newState ) , isTrue ) ;
} ,
) ;
final previousBalls = game . descendants ( ) . whereType < Ball > ( ) . length ;
controller . lost ( ) ;
await game . ready ( ) ;
final currentBalls = game . descendants ( ) . whereType < Ball > ( ) . length ;
tester . testGameWidget (
' does not listen when a ball has not been lost ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ensureAdd ( ball ) ;
} ,
verify: ( game , tester ) async {
final controller =
game . descendants ( ) . whereType < LaunchedBallController > ( ) . first ;
final previousState = MockGameState ( ) ;
final newState = MockGameState ( ) ;
when ( ( ) = > previousState . balls ) . thenReturn ( 3 ) ;
when ( ( ) = > newState . balls ) . thenReturn ( 3 ) ;
expect ( controller . listenWhen ( previousState , newState ) , isFalse ) ;
} ,
) ;
} ) ;
expect ( previousBalls , equals ( currentBalls ) ) ;
} ,
) ;
group ( ' onNewState ' , ( ) {
tester . testGameWidget (
' removes ball ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ensureAdd ( ball ) ;
final state = MockGameState ( ) ;
when ( ( ) = > state . balls ) . thenReturn ( 1 ) ;
controller . onNewState ( state ) ;
await game . ready ( ) ;
} ,
verify: ( game , tester ) async {
expect ( game . contains ( ball ) , isFalse ) ;
} ,
) ;
tester . testGameWidget (
' no ball is added on game over ' ,
verify: ( game , tester ) async {
whenListen (
gameBloc ,
const Stream < GameState > . empty ( ) ,
initialState: const GameState (
score: 10 ,
balls: 1 ,
activatedBonusLetters: [ ] ,
activatedDashNests: { } ,
bonusHistory: [ ] ,
) ,
) ;
final controller = BallController ( ball ) ;
await ball . add ( controller ) ;
await game . add ( ball ) ;
await game . ready ( ) ;
tester . testGameWidget (
' spawns a new ball when the ball is not the last one ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ensureAdd ( ball ) ;
final previousBalls = game . descendants ( ) . whereType < Ball > ( ) . toList ( ) ;
controller . lost ( ) ;
await game . ready ( ) ;
final currentBalls = game . descendants ( ) . whereType < Ball > ( ) . length ;
final state = MockGameState ( ) ;
when ( ( ) = > state . balls ) . thenReturn ( 2 ) ;
expect (
currentBalls ,
equals ( ( previousBalls . . remove ( ball ) ) . length ) ,
) ;
} ,
) ;
final previousBalls = game . descendants ( ) . whereType < Ball > ( ) . toList ( ) ;
controller . onNewState ( state ) ;
await game . ready ( ) ;
final currentBalls = game . descendants ( ) . whereType < Ball > ( ) ;
expect ( currentBalls . contains ( ball ) , isFalse ) ;
expect ( currentBalls . length , equals ( previousBalls . length ) ) ;
} ,
) ;
tester . testGameWidget (
' does not spawn a new ball is the last one ' ,
setUp: ( game , tester ) async {
final controller = LaunchedBallController ( ball ) ;
await ball . add ( controller ) ;
await game . ensureAdd ( ball ) ;
final state = MockGameState ( ) ;
when ( ( ) = > state . balls ) . thenReturn ( 1 ) ;
final previousBalls = game . descendants ( ) . whereType < Ball > ( ) . toList ( ) ;
controller . onNewState ( state ) ;
await game . ready ( ) ;
final currentBalls = game . descendants ( ) . whereType < Ball > ( ) ;
expect ( currentBalls . contains ( ball ) , isFalse ) ;
expect (
currentBalls . length ,
equals ( ( previousBalls . . remove ( ball ) ) . length ) ,
) ;
} ,
) ;
} ) ;
} ) ;
} ) ;
}