89 lines
3.3 KiB
Dart
89 lines
3.3 KiB
Dart
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:plezy/services/gamepad_service.dart';
|
|
|
|
void main() {
|
|
group('GamepadDuplicateInputGuard', () {
|
|
late DateTime now;
|
|
late GamepadDuplicateInputGuard guard;
|
|
|
|
setUp(() {
|
|
now = DateTime(2026, 4, 26, 12);
|
|
guard = GamepadDuplicateInputGuard(now: () => now, suppressionWindow: const Duration(milliseconds: 100));
|
|
});
|
|
|
|
test('suppresses a matching D-pad event after a native arrow key', () {
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.arrowRight));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.arrowRight), isTrue);
|
|
});
|
|
|
|
test('does not suppress D-pad input when no native key was seen', () {
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.arrowRight), isFalse);
|
|
});
|
|
|
|
test('suppresses gamepad A while native enter is down and just after release', () {
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.enter));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.enter), isTrue);
|
|
|
|
guard.handleNativeKeyEvent(_keyUp(LogicalKeyboardKey.enter));
|
|
now = now.add(const Duration(milliseconds: 50));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.enter), isTrue);
|
|
});
|
|
|
|
test('suppression expires after the debounce window', () {
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.arrowRight));
|
|
guard.handleNativeKeyEvent(_keyUp(LogicalKeyboardKey.arrowRight));
|
|
|
|
now = now.add(const Duration(milliseconds: 101));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.arrowRight), isFalse);
|
|
});
|
|
|
|
test('unrelated native keys do not suppress controller input', () {
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.space));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.arrowRight), isFalse);
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.enter), isFalse);
|
|
});
|
|
|
|
test('uses aliases for Steam Input mapped context menu and back keys', () {
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.contextMenu));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.gameButtonX), isTrue);
|
|
|
|
guard.clear();
|
|
guard.handleNativeKeyEvent(_keyDown(LogicalKeyboardKey.browserBack));
|
|
|
|
expect(guard.shouldSuppressSyntheticKey(LogicalKeyboardKey.gameButtonB), isTrue);
|
|
});
|
|
});
|
|
}
|
|
|
|
KeyDownEvent _keyDown(LogicalKeyboardKey logicalKey) {
|
|
return KeyDownEvent(
|
|
physicalKey: _physicalKeyFor(logicalKey),
|
|
logicalKey: logicalKey,
|
|
timeStamp: const Duration(milliseconds: 1),
|
|
);
|
|
}
|
|
|
|
KeyUpEvent _keyUp(LogicalKeyboardKey logicalKey) {
|
|
return KeyUpEvent(
|
|
physicalKey: _physicalKeyFor(logicalKey),
|
|
logicalKey: logicalKey,
|
|
timeStamp: const Duration(milliseconds: 1),
|
|
);
|
|
}
|
|
|
|
PhysicalKeyboardKey _physicalKeyFor(LogicalKeyboardKey logicalKey) {
|
|
if (logicalKey == LogicalKeyboardKey.arrowRight) return PhysicalKeyboardKey.arrowRight;
|
|
if (logicalKey == LogicalKeyboardKey.enter) return PhysicalKeyboardKey.enter;
|
|
if (logicalKey == LogicalKeyboardKey.space) return PhysicalKeyboardKey.space;
|
|
if (logicalKey == LogicalKeyboardKey.contextMenu) return PhysicalKeyboardKey.contextMenu;
|
|
if (logicalKey == LogicalKeyboardKey.browserBack) return PhysicalKeyboardKey.browserBack;
|
|
return PhysicalKeyboardKey.enter;
|
|
}
|