diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 89f60343..aa11ace3 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -2,6 +2,7 @@ export 'anchor.dart'; export 'ball.dart'; export 'board_side.dart'; export 'flipper.dart'; +export 'initial_position.dart'; export 'pathway.dart'; export 'plunger.dart'; export 'score_points.dart'; diff --git a/lib/game/components/initial_position.dart b/lib/game/components/initial_position.dart new file mode 100644 index 00000000..9716754d --- /dev/null +++ b/lib/game/components/initial_position.dart @@ -0,0 +1,14 @@ +import 'package:flame_forge2d/flame_forge2d.dart'; + +mixin InitialPosition on BodyComponent { + late final Vector2 initialPosition; + + @override + void onMount() { + super.onMount(); + assert( + body.position == initialPosition, + 'Body position is not equal to initial position.', + ); + } +} diff --git a/test/game/components/initial_position_test.dart b/test/game/components/initial_position_test.dart new file mode 100644 index 00000000..a1e27276 --- /dev/null +++ b/test/game/components/initial_position_test.dart @@ -0,0 +1,68 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/game/game.dart'; + +class EmptyGame extends Forge2DGame {} + +class TestBodyComponent extends BodyComponent with InitialPosition { + @override + Body createBody() { + return world.createBody(BodyDef()); + } +} + +class TestPositionBodyComponent extends BodyComponent with InitialPosition { + @override + Body createBody() { + return world.createBody(BodyDef()..position = initialPosition); + } +} + +void main() { + final flameTester = FlameTester(EmptyGame.new); + group('InitialPosition', () { + test('correctly sets and gets', () { + final component = TestBodyComponent()..initialPosition = Vector2(1, 2); + expect(component.initialPosition, Vector2(1, 2)); + }); + + test('can only be set once', () { + final component = TestBodyComponent()..initialPosition = Vector2(1, 2); + expect( + () => component.initialPosition = Vector2(3, 4), + throwsA(isA()), + ); + }); + + flameTester.test( + 'returns normally ' + 'when the body sets the position to initial position', + (game) async { + final component = TestPositionBodyComponent() + ..initialPosition = Vector2.zero(); + + await expectLater( + () async => game.ensureAdd(component), + returnsNormally, + ); + }, + ); + + flameTester.test( + 'throws AssertionError ' + 'when not setting initialPosition to body', + (game) async { + final component = TestBodyComponent()..initialPosition = Vector2.zero(); + await game.ensureAdd(component); + + await expectLater( + () async => game.ensureAdd(component), + throwsAssertionError, + ); + }, + ); + }); +}