adding missing tests

pull/187/head
Erick Zanardo 3 years ago
parent e596cac6c1
commit 6664cc6a86

@ -37,8 +37,7 @@ class Backboard extends PositionComponent with HasGameRef {
factory Backboard.waiting({
required Vector2 position,
}) {
return Backboard(position: position)
..waitingMode();
return Backboard(position: position)..waitingMode();
}
/// {@macro backboard}
@ -47,9 +46,13 @@ class Backboard extends PositionComponent with HasGameRef {
factory Backboard.gameOver({
required Vector2 position,
required int score,
required BackboardOnSubmit onSubmit,
}) {
return Backboard(position: position)
..gameOverMode(score: score);
..gameOverMode(
score: score,
onSubmit: onSubmit,
);
}
/// Puts the Backboard in waiting mode, where the scoreboard is shown.
@ -59,8 +62,14 @@ class Backboard extends PositionComponent with HasGameRef {
}
/// Puts the Backboard in game over mode, where the score input is shown.
Future<void> gameOverMode({ required int score}) async {
Future<void> gameOverMode({
required int score,
required BackboardOnSubmit onSubmit,
}) async {
children.removeWhere((element) => true);
await add(BackboardGameOver(score: score));
await add(BackboardGameOver(
score: score,
onSubmit: onSubmit,
));
}
}

@ -2,11 +2,14 @@ import 'dart:async';
import 'dart:math';
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:pinball_components/pinball_components.dart';
/// Signature for the callback called when the used has
/// submettied their initials on the [BackboardGameOver]
typedef BackboardOnSubmit = void Function(String);
/// {@template backboard_game_over}
/// [PositionComponent] that handles the user input on the
/// game over display view.
@ -15,9 +18,12 @@ class BackboardGameOver extends PositionComponent with HasGameRef {
/// {@macro backboard_game_over}
BackboardGameOver({
required int score,
}) : _score = score;
required BackboardOnSubmit onSubmit,
}) : _score = score,
_onSubmit = onSubmit;
final int _score;
final BackboardOnSubmit _onSubmit;
final _numberFormat = NumberFormat('#,###,###');
@ -83,12 +89,24 @@ class BackboardGameOver extends PositionComponent with HasGameRef {
keyUp: {
LogicalKeyboardKey.arrowLeft: () => _movePrompt(true),
LogicalKeyboardKey.arrowRight: () => _movePrompt(false),
LogicalKeyboardKey.enter: _submit,
},
),
),
);
}
/// Returns the current inputed initials
String get initials => children
.whereType<BackboardLetterPrompt>()
.map((prompt) => prompt.char)
.join();
bool _submit() {
_onSubmit(initials);
return true;
}
bool _movePrompt(bool left) {
final prompts = children.whereType<BackboardLetterPrompt>().toList();

@ -75,6 +75,9 @@ class BackboardLetterPrompt extends PositionComponent {
);
}
/// Returns the current selected character
String get char => String.fromCharCode(_alphabetCode + _charIndex);
bool _cycle(bool up) {
if (_hasFocus) {
final newCharCode =

@ -1,5 +1,4 @@
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/// The signature for a key handle function
@ -9,13 +8,12 @@ typedef KeyHandlerCallback = bool Function();
/// A that receives keyboard input and execute registered methods
/// {@endtemplate}
class KeyboardInputController extends Component with KeyboardHandler {
/// {@macro keyboard_input_controller}
KeyboardInputController({
Map<LogicalKeyboardKey, KeyHandlerCallback> keyUp = const {},
Map<LogicalKeyboardKey, KeyHandlerCallback> keyDown = const {},
}) : _keyUp = keyUp,
_keyDown = keyDown;
}) : _keyUp = keyUp,
_keyDown = keyDown;
final Map<LogicalKeyboardKey, KeyHandlerCallback> _keyUp;
final Map<LogicalKeyboardKey, KeyHandlerCallback> _keyDown;

@ -1,4 +1,5 @@
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:pinball_components/pinball_components.dart';
import 'package:sandbox/common/common.dart';
@ -21,6 +22,15 @@ class BackboardGameOverGame extends BasicKeyboardGame {
Backboard.gameOver(
position: Vector2(0, 20),
score: score,
onSubmit: (initials) {
add(
ScoreText(
text: 'User $initials made $score',
position: Vector2(0, 50),
color: Colors.pink,
),
);
},
),
);
}

@ -18,7 +18,7 @@ void addBackboardStories(Dashbook dashbook) {
'Game over',
(context) => GameWidget(
game: BackboardGameOverGame(
context.numberProperty('score', 9000000000).toInt(),
context.numberProperty('score', 9000000000).toInt(),
),
),
codeLink: buildSourceLink('backboard/game_over.dart'),

@ -1,3 +1,4 @@
import 'package:flame/input.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
class TestGame extends Forge2DGame {
@ -5,3 +6,5 @@ class TestGame extends Forge2DGame {
images.prefix = '';
}
}
class KeyboardTestGame extends TestGame with HasKeyboardHandlerComponents {}

@ -1,7 +1,9 @@
// ignore_for_file: unawaited_futures
// ignore_for_file: unawaited_futures, cascade_invocations
import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinball_components/pinball_components.dart';
@ -9,7 +11,7 @@ import '../../helpers/helpers.dart';
void main() {
group('Backboard', () {
final tester = FlameTester(TestGame.new);
final tester = FlameTester(KeyboardTestGame.new);
group('on waitingMode', () {
tester.testGameWidget(
@ -17,7 +19,7 @@ void main() {
setUp: (game, tester) async {
game.camera.zoom = 2;
game.camera.followVector2(Vector2.zero());
await game.ensureAdd(Backboard(position: Vector2(0, 15)));
await game.ensureAdd(Backboard.waiting(position: Vector2(0, 15)));
},
verify: (game, tester) async {
await expectLater(
@ -34,20 +36,145 @@ void main() {
setUp: (game, tester) async {
game.camera.zoom = 2;
game.camera.followVector2(Vector2.zero());
final backboard = Backboard(position: Vector2(0, 15));
final backboard = Backboard.gameOver(
position: Vector2(0, 15),
score: 1000,
onSubmit: (_) {},
);
await game.ensureAdd(backboard);
},
verify: (game, tester) async {
final prompts =
game.descendants().whereType<BackboardLetterPrompt>().length;
expect(prompts, equals(3));
final score = game.descendants().firstWhere(
(component) =>
component is TextComponent && component.text == '1,000',
);
expect(score, isNotNull);
},
);
tester.testGameWidget(
'can change the initials',
setUp: (game, tester) async {
final backboard = Backboard.gameOver(
position: Vector2(0, 15),
score: 1000,
onSubmit: (_) {},
);
await game.ensureAdd(backboard);
await backboard.gameOverMode();
await game.ready();
// Focus is already on the first letter
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
// Move to the next an press up again
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
// One more time
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
// Back to the previous and increase one more
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
},
verify: (game, tester) async {
await expectLater(
find.byGame<TestGame>(),
matchesGoldenFile('golden/backboard/game_over.png'),
final backboard = game
.descendants()
.firstWhere((component) => component is BackboardGameOver)
as BackboardGameOver;
expect(backboard.initials, equals('BCB'));
},
);
String? submitedInitials;
tester.testGameWidget(
'submits the initial',
setUp: (game, tester) async {
final backboard = Backboard.gameOver(
position: Vector2(0, 15),
score: 1000,
onSubmit: (value) {
submitedInitials = value;
},
);
await game.ensureAdd(backboard);
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
await tester.pump();
},
verify: (game, tester) async {
expect(submitedInitials, equals('AAA'));
},
);
});
});
group('BackboardLetterPrompt', () {
final tester = FlameTester(KeyboardTestGame.new);
tester.testGameWidget(
'cycles the char up and down when it has focus',
setUp: (game, tester) async {
await game.ensureAdd(
BackboardLetterPrompt(hasFocus: true, position: Vector2.zero()),
);
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pump();
},
verify: (game, tester) async {
final prompt = game.firstChild<BackboardLetterPrompt>();
expect(prompt?.char, equals('C'));
},
);
tester.testGameWidget(
"does nothing when don't have focus",
setUp: (game, tester) async {
await game.ensureAdd(
BackboardLetterPrompt(position: Vector2.zero()),
);
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump();
},
verify: (game, tester) async {
final prompt = game.firstChild<BackboardLetterPrompt>();
expect(prompt?.char, equals('A'));
},
);
tester.testGameWidget(
'blinks the promp when have focus',
setUp: (game, tester) async {
await game.ensureAdd(
BackboardLetterPrompt(position: Vector2.zero(), hasFocus: true),
);
},
verify: (game, tester) async {
final underscore = game.descendants().whereType<ShapeComponent>().first;
expect(underscore.paint.color, Colors.white);
game.update(2);
expect(underscore.paint.color, Colors.transparent);
},
);
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 KiB

@ -0,0 +1,78 @@
// ignore_for_file: cascade_invocations, one_member_abstracts
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:pinball_components/pinball_components.dart';
abstract class _KeyCallStub {
bool onCall();
}
class KeyCallStub extends Mock implements _KeyCallStub {}
class MockRawKeyUpEvent extends Mock implements RawKeyUpEvent {
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return super.toString();
}
}
RawKeyUpEvent _mockKeyUp(LogicalKeyboardKey key) {
final event = MockRawKeyUpEvent();
when(() => event.logicalKey).thenReturn(key);
return event;
}
void main() {
group('KeyboardInputController', () {
test('calls registered handlers', () {
final stub = KeyCallStub();
when(stub.onCall).thenReturn(true);
final input = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowUp: stub.onCall,
},
);
input.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.arrowUp), {});
verify(stub.onCall).called(1);
});
test(
'returns false the handler return value',
() {
final stub = KeyCallStub();
when(stub.onCall).thenReturn(false);
final input = KeyboardInputController(
keyUp: {
LogicalKeyboardKey.arrowUp: stub.onCall,
},
);
expect(
input.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.arrowUp), {}),
isFalse,
);
},
);
test(
'returns true (allowing event to bubble) when no handler is registered',
() {
final stub = KeyCallStub();
when(stub.onCall).thenReturn(true);
final input = KeyboardInputController();
expect(
input.onKeyEvent(_mockKeyUp(LogicalKeyboardKey.arrowUp), {}),
isTrue,
);
},
);
});
}
Loading…
Cancel
Save