diff --git a/test/game/components/crossing_ramp_test.dart b/test/game/components/crossing_ramp_test.dart new file mode 100644 index 00000000..88cc1118 --- /dev/null +++ b/test/game/components/crossing_ramp_test.dart @@ -0,0 +1,158 @@ +// 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 FakeRampArea extends RampArea { + FakeRampArea({ + required Vector2 position, + required int categoryBits, + }) : super(position: position, categoryBits: categoryBits); + + @override + RampOrientation get orientation => RampOrientation.down; + + @override + Shape get shape => PolygonShape() + ..set([ + Vector2(0, 0), + Vector2(0, 1), + Vector2(1, 1), + Vector2(1, 0), + ]); +} + +class FakeRampAreaCallback extends RampAreaCallback { + FakeRampAreaCallback() : super(); + + final _ballsInside = {}; + + @override + Set get ballsInside => _ballsInside; +} + +void main() { + group('RampType', () { + test('has three values', () { + expect(RampType.values.length, equals(3)); + }); + }); + + group('RampTypeX', () { + test('all type has default maskBits', () { + expect(RampType.all.maskBits, equals(Filter().maskBits)); + }); + + test('jetpack type has 0x010 maskBits', () { + expect(RampType.jetpack.maskBits, equals(0x010)); + }); + + test('sparky type has 0x0100 maskBits', () { + expect(RampType.sparky.maskBits, equals(0x0100)); + }); + }); + + group('RampArea', () { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(PinballGame.new); + + flameTester.test( + 'loads correctly', + (game) async { + final ramp = FakeRampArea( + position: Vector2.zero(), + categoryBits: RampType.all.maskBits, + ); + await game.ensureAdd(ramp); + + expect(game.contains(ramp), isTrue); + }, + ); + + group('body', () { + flameTester.test( + 'positions correctly', + (game) async { + final position = Vector2.all(10); + final ramp = FakeRampArea( + position: position, + categoryBits: RampType.all.maskBits, + ); + await game.ensureAdd(ramp); + + game.contains(ramp); + expect(ramp.body.position, position); + }, + ); + + flameTester.test( + 'is static', + (game) async { + final ramp = FakeRampArea( + position: Vector2.zero(), + categoryBits: RampType.all.maskBits, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.bodyType, equals(BodyType.static)); + }, + ); + + group('fixtures', () { + flameTester.test( + 'has only one shape', + (game) async { + final ramp = FakeRampArea( + position: Vector2.zero(), + categoryBits: RampType.all.maskBits, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.fixtures.length, 1); + + for (final fixture in ramp.body.fixtures) { + expect(fixture, isA()); + expect(fixture.shape, isA()); + } + }, + ); + flameTester.test( + 'is sensor', + (game) async { + final ramp = FakeRampArea( + position: Vector2.zero(), + categoryBits: RampType.all.maskBits, + ); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect(fixture.isSensor, isTrue); + }, + ); + + flameTester.test( + 'sets correctly filter categoryBits ', + (game) async { + const maskBits = 1234; + final ramp = FakeRampArea( + position: Vector2.zero(), + categoryBits: maskBits, + ); + await game.ready(); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect( + fixture.filterData.categoryBits, + equals(maskBits), + ); + }, + ); + }); + }); + }); + + group('RampAreaCallback', () {}); +} diff --git a/test/game/components/jetpack_ramp_test.dart b/test/game/components/jetpack_ramp_test.dart new file mode 100644 index 00000000..7df9fab1 --- /dev/null +++ b/test/game/components/jetpack_ramp_test.dart @@ -0,0 +1,175 @@ +// 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:mocktail/mocktail.dart'; +import 'package:pinball/game/game.dart'; + +import '../../helpers/helpers.dart'; + +class MockJetpackRampArea extends Mock implements JetpackRampArea {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(PinballGame.new); + + group('JetpackRamp', () { + group('body', () { + flameTester.test( + 'has a Pathway.arc at position', + (game) async { + final jetpackRamp = JetpackRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(jetpackRamp); + game.contains(jetpackRamp); + }, + ); + + flameTester.test( + 'has a two sensors for the ramp', + (game) async { + final jetpackRamp = JetpackRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(jetpackRamp); + + game.contains(jetpackRamp); + }, + ); + + flameTester.test( + 'sensors and ramp are static', + (game) async { + final jetpackRamp = JetpackRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(jetpackRamp); + + game.contains(jetpackRamp); + }, + ); + }); + }); + + group('JetpackRampArea', () { + flameTester.test( + 'loads correctly', + (game) async { + final ramp = JetpackRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(game.contains(ramp), isTrue); + }, + ); + + flameTester.test( + 'orientation correctly', + (game) async { + final position = Vector2.all(10); + final ramp = JetpackRampArea( + position: position, + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + game.contains(ramp); + expect(ramp.orientation, RampOrientation.down); + }, + ); + + group('body', () { + flameTester.test( + 'positions correctly', + (game) async { + final position = Vector2.all(10); + final ramp = JetpackRampArea( + position: position, + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + game.contains(ramp); + expect(ramp.body.position, position); + }, + ); + + flameTester.test( + 'is static', + (game) async { + final ramp = JetpackRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.bodyType, equals(BodyType.static)); + }, + ); + + group('fixtures', () { + flameTester.test( + 'has only one shape', + (game) async { + final ramp = JetpackRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.fixtures.length, 1); + + for (final fixture in ramp.body.fixtures) { + expect(fixture, isA()); + expect(fixture.shape, isA()); + } + }, + ); + flameTester.test( + 'is sensor', + (game) async { + final ramp = JetpackRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect(fixture.isSensor, isTrue); + }, + ); + + flameTester.test( + 'sets correctly filter categoryBits to RampType.jetpack', + (game) async { + final ramp = JetpackRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ready(); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect( + fixture.filterData.categoryBits, + equals(RampType.jetpack.maskBits), + ); + }, + ); + }); + }); + }); + + group('JetpackRampAreaCallback', () { + test('has no ball inside on creation', () { + expect(JetpackRampAreaCallback().ballsInside, equals({})); + }); + }); +} diff --git a/test/game/components/pathway_test.dart b/test/game/components/pathway_test.dart index d3b82e96..b54d2bce 100644 --- a/test/game/components/pathway_test.dart +++ b/test/game/components/pathway_test.dart @@ -143,6 +143,52 @@ void main() { } }, ); + + flameTester.test( + 'has default filter categoryBits when no modified', + (game) async { + final pathway = Pathway.straight( + position: Vector2.zero(), + start: Vector2(10, 10), + end: Vector2(20, 20), + width: width, + ); + await game.ready(); + await game.ensureAdd(pathway); + + for (final fixture in pathway.body.fixtures) { + expect(fixture, isA()); + expect( + fixture.filterData.categoryBits, + equals(Filter().categoryBits), + ); + } + }, + ); + + flameTester.test( + 'sets correctly filter categoryBits ', + (game) async { + const maskBits = 1234; + final pathway = Pathway.straight( + position: Vector2.zero(), + start: Vector2(10, 10), + end: Vector2(20, 20), + width: width, + categoryBits: maskBits, + ); + await game.ready(); + await game.ensureAdd(pathway); + + for (final fixture in pathway.body.fixtures) { + expect(fixture, isA()); + expect( + fixture.filterData.categoryBits, + equals(maskBits), + ); + } + }, + ); }); }); diff --git a/test/game/components/sparky_ramp_test.dart b/test/game/components/sparky_ramp_test.dart new file mode 100644 index 00000000..3f94ec10 --- /dev/null +++ b/test/game/components/sparky_ramp_test.dart @@ -0,0 +1,175 @@ +// 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:mocktail/mocktail.dart'; +import 'package:pinball/game/game.dart'; + +import '../../helpers/helpers.dart'; + +class MockSparkyRampArea extends Mock implements SparkyRampArea {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(PinballGame.new); + + group('SparkyRamp', () { + group('body', () { + flameTester.test( + 'has a Pathway.arc at position', + (game) async { + final sparkyRamp = SparkyRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(sparkyRamp); + game.contains(sparkyRamp); + }, + ); + + flameTester.test( + 'has a two sensors for the ramp', + (game) async { + final sparkyRamp = SparkyRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(sparkyRamp); + + game.contains(sparkyRamp); + }, + ); + + flameTester.test( + 'sensors and ramp are static', + (game) async { + final sparkyRamp = SparkyRamp( + position: Vector2.zero(), + ); + await game.ready(); + await game.ensureAdd(sparkyRamp); + + game.contains(sparkyRamp); + }, + ); + }); + }); + + group('SparkyRampArea', () { + flameTester.test( + 'loads correctly', + (game) async { + final ramp = SparkyRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(game.contains(ramp), isTrue); + }, + ); + + flameTester.test( + 'orientation correctly', + (game) async { + final position = Vector2.all(10); + final ramp = SparkyRampArea( + position: position, + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + game.contains(ramp); + expect(ramp.orientation, RampOrientation.down); + }, + ); + + group('body', () { + flameTester.test( + 'positions correctly', + (game) async { + final position = Vector2.all(10); + final ramp = SparkyRampArea( + position: position, + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + game.contains(ramp); + expect(ramp.body.position, position); + }, + ); + + flameTester.test( + 'is static', + (game) async { + final ramp = SparkyRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.bodyType, equals(BodyType.static)); + }, + ); + + group('fixtures', () { + flameTester.test( + 'has only one shape', + (game) async { + final ramp = SparkyRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + expect(ramp.body.fixtures.length, 1); + + for (final fixture in ramp.body.fixtures) { + expect(fixture, isA()); + expect(fixture.shape, isA()); + } + }, + ); + flameTester.test( + 'is sensor', + (game) async { + final ramp = SparkyRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect(fixture.isSensor, isTrue); + }, + ); + + flameTester.test( + 'sets correctly filter categoryBits to RampType.sparky', + (game) async { + final ramp = SparkyRampArea( + position: Vector2.zero(), + orientation: RampOrientation.down, + ); + await game.ready(); + await game.ensureAdd(ramp); + + final fixture = ramp.body.fixtures.first; + expect( + fixture.filterData.categoryBits, + equals(RampType.sparky.maskBits), + ); + }, + ); + }); + }); + }); + + group('SparkyRampAreaCallback', () { + test('has no ball inside on creation', () { + expect(SparkyRampAreaCallback().ballsInside, equals({})); + }); + }); +}