Unverified Commit 2868bc13 authored by derdilla's avatar derdilla Committed by GitHub

Fix leak in hardware_keyboard_test.dart (#134380)

parent 04854e8a
...@@ -8,9 +8,10 @@ import 'package:flutter/foundation.dart'; ...@@ -8,9 +8,10 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('HardwareKeyboard records pressed keys and enabled locks', (WidgetTester tester) async { testWidgetsWithLeakTracking('HardwareKeyboard records pressed keys and enabled locks', (WidgetTester tester) async {
await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows'); await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows');
expect(HardwareKeyboard.instance.physicalKeysPressed, expect(HardwareKeyboard.instance.physicalKeysPressed,
equals(<PhysicalKeyboardKey>{PhysicalKeyboardKey.numLock})); equals(<PhysicalKeyboardKey>{PhysicalKeyboardKey.numLock}));
...@@ -68,7 +69,7 @@ void main() { ...@@ -68,7 +69,7 @@ void main() {
equals(<KeyboardLockMode>{})); equals(<KeyboardLockMode>{}));
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData()); }, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
testWidgets('KeyboardManager synthesizes modifier keys in rawKeyData mode', (WidgetTester tester) async { testWidgetsWithLeakTracking('KeyboardManager synthesizes modifier keys in rawKeyData mode', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
HardwareKeyboard.instance.addHandler((KeyEvent event) { HardwareKeyboard.instance.addHandler((KeyEvent event) {
events.add(event); events.add(event);
...@@ -96,8 +97,9 @@ void main() { ...@@ -96,8 +97,9 @@ void main() {
expect(events[1].synthesized, false); expect(events[1].synthesized, false);
}); });
testWidgets('Dispatch events to all handlers', (WidgetTester tester) async { testWidgetsWithLeakTracking('Dispatch events to all handlers', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final List<int> logs = <int>[]; final List<int> logs = <int>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -201,8 +203,9 @@ void main() { ...@@ -201,8 +203,9 @@ void main() {
// _CastError on _hardwareKeyboard.lookUpLayout(key). The original scenario // _CastError on _hardwareKeyboard.lookUpLayout(key). The original scenario
// that this is triggered on Android is unknown. Here we make up a scenario // that this is triggered on Android is unknown. Here we make up a scenario
// where a ShiftLeft key down is dispatched but the modifier bit is not set. // where a ShiftLeft key down is dispatched but the modifier bit is not set.
testWidgets('Correctly convert down events that are synthesized released', (WidgetTester tester) async { testWidgetsWithLeakTracking('Correctly convert down events that are synthesized released', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -244,8 +247,9 @@ void main() { ...@@ -244,8 +247,9 @@ void main() {
KeyDataTransitMode.rawKeyData, KeyDataTransitMode.rawKeyData,
})); }));
testWidgets('Instantly dispatch synthesized key events when the queue is empty', (WidgetTester tester) async { testWidgetsWithLeakTracking('Instantly dispatch synthesized key events when the queue is empty', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final List<int> logs = <int>[]; final List<int> logs = <int>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -276,19 +280,22 @@ void main() { ...@@ -276,19 +280,22 @@ void main() {
logs.clear(); logs.clear();
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData()); }, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
testWidgets('Postpone synthesized key events when the queue is not empty', (WidgetTester tester) async { testWidgetsWithLeakTracking('Postpone synthesized key events when the queue is not empty', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode keyboardListenerFocusNode = FocusNode();
addTearDown(keyboardListenerFocusNode.dispose);
final FocusNode rawKeyboardListenerFocusNode = FocusNode();
addTearDown(rawKeyboardListenerFocusNode.dispose);
final List<String> logs = <String>[]; final List<String> logs = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
RawKeyboardListener( RawKeyboardListener(
focusNode: FocusNode(), focusNode: rawKeyboardListenerFocusNode,
onKey: (RawKeyEvent event) { onKey: (RawKeyEvent event) {
logs.add('${event.runtimeType}'); logs.add('${event.runtimeType}');
}, },
child: KeyboardListener( child: KeyboardListener(
autofocus: true, autofocus: true,
focusNode: focusNode, focusNode: keyboardListenerFocusNode,
child: Container(), child: Container(),
onKeyEvent: (KeyEvent event) { onKeyEvent: (KeyEvent event) {
logs.add('${event.runtimeType}'); logs.add('${event.runtimeType}');
...@@ -331,7 +338,7 @@ void main() { ...@@ -331,7 +338,7 @@ void main() {
// In that case, the key data should not be converted to any [KeyEvent]s, // In that case, the key data should not be converted to any [KeyEvent]s,
// but is only used so that *a* key data comes before the raw key message // but is only used so that *a* key data comes before the raw key message
// and makes [KeyEventManager] infer [KeyDataTransitMode.keyDataThenRawKeyData]. // and makes [KeyEventManager] infer [KeyDataTransitMode.keyDataThenRawKeyData].
testWidgets('Empty keyData yields no event but triggers inference', (WidgetTester tester) async { testWidgetsWithLeakTracking('Empty keyData yields no event but triggers inference', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
final List<RawKeyEvent> rawEvents = <RawKeyEvent>[]; final List<RawKeyEvent> rawEvents = <RawKeyEvent>[];
tester.binding.keyboard.addHandler((KeyEvent event) { tester.binding.keyboard.addHandler((KeyEvent event) {
...@@ -383,7 +390,7 @@ void main() { ...@@ -383,7 +390,7 @@ void main() {
expect(rawEvents.length, 2); expect(rawEvents.length, 2);
}); });
testWidgets('Exceptions from keyMessageHandler are caught and reported', (WidgetTester tester) async { testWidgetsWithLeakTracking('Exceptions from keyMessageHandler are caught and reported', (WidgetTester tester) async {
final KeyMessageHandler? oldKeyMessageHandler = tester.binding.keyEventManager.keyMessageHandler; final KeyMessageHandler? oldKeyMessageHandler = tester.binding.keyEventManager.keyMessageHandler;
addTearDown(() { addTearDown(() {
tester.binding.keyEventManager.keyMessageHandler = oldKeyMessageHandler; tester.binding.keyEventManager.keyMessageHandler = oldKeyMessageHandler;
...@@ -426,7 +433,7 @@ void main() { ...@@ -426,7 +433,7 @@ void main() {
expect(record, isNull); expect(record, isNull);
}); });
testWidgets('Exceptions from HardwareKeyboard handlers are caught and reported', (WidgetTester tester) async { testWidgetsWithLeakTracking('Exceptions from HardwareKeyboard handlers are caught and reported', (WidgetTester tester) async {
bool throwingCallback(KeyEvent event) { bool throwingCallback(KeyEvent event) {
throw 1; throw 1;
} }
...@@ -466,7 +473,7 @@ void main() { ...@@ -466,7 +473,7 @@ void main() {
expect(record, isNull); expect(record, isNull);
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('debugPrintKeyboardEvents causes logging of key events', (WidgetTester tester) async { testWidgetsWithLeakTracking('debugPrintKeyboardEvents causes logging of key events', (WidgetTester tester) async {
final bool oldDebugPrintKeyboardEvents = debugPrintKeyboardEvents; final bool oldDebugPrintKeyboardEvents = debugPrintKeyboardEvents;
final DebugPrintCallback oldDebugPrint = debugPrint; final DebugPrintCallback oldDebugPrint = debugPrint;
final StringBuffer messages = StringBuffer(); final StringBuffer messages = StringBuffer();
......
...@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart'; ...@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class _ModifierCheck { class _ModifierCheck {
const _ModifierCheck(this.key, this.side); const _ModifierCheck(this.key, this.side);
...@@ -17,7 +18,7 @@ class _ModifierCheck { ...@@ -17,7 +18,7 @@ class _ModifierCheck {
void main() { void main() {
group('RawKeyboard', () { group('RawKeyboard', () {
testWidgets('The correct character is produced', (WidgetTester tester) async { testWidgetsWithLeakTracking('The correct character is produced', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
String character = ''; String character = '';
void handleKey(RawKeyEvent event) { void handleKey(RawKeyEvent event) {
...@@ -32,7 +33,7 @@ void main() { ...@@ -32,7 +33,7 @@ void main() {
} }
}); });
testWidgets('No character is produced for non-printables', (WidgetTester tester) async { testWidgetsWithLeakTracking('No character is produced for non-printables', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
void handleKey(RawKeyEvent event) { void handleKey(RawKeyEvent event) {
expect(event.character, isNull, reason: 'on $platform'); expect(event.character, isNull, reason: 'on $platform');
...@@ -43,7 +44,7 @@ void main() { ...@@ -43,7 +44,7 @@ void main() {
} }
}); });
testWidgets('keysPressed is maintained', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed is maintained', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
RawKeyboard.instance.clearKeysPressed(); RawKeyboard.instance.clearKeysPressed();
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform'); expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
...@@ -149,7 +150,7 @@ void main() { ...@@ -149,7 +150,7 @@ void main() {
} }
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021
testWidgets('keysPressed is correct when modifier is released before key', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed is correct when modifier is released before key', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
RawKeyboard.instance.clearKeysPressed(); RawKeyboard.instance.clearKeysPressed();
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform'); expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
...@@ -200,7 +201,7 @@ void main() { ...@@ -200,7 +201,7 @@ void main() {
} }
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/76741 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/76741
testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -224,7 +225,7 @@ void main() { ...@@ -224,7 +225,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a macOS-specific test. }, skip: isBrowser); // [intended] This is a macOS-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -248,7 +249,7 @@ void main() { ...@@ -248,7 +249,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is an iOS-specific test. }, skip: isBrowser); // [intended] This is an iOS-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -272,7 +273,7 @@ void main() { ...@@ -272,7 +273,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a Windows-specific test. }, skip: isBrowser); // [intended] This is a Windows-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -296,7 +297,7 @@ void main() { ...@@ -296,7 +297,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is an Android-specific test. }, skip: isBrowser); // [intended] This is an Android-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -320,7 +321,7 @@ void main() { ...@@ -320,7 +321,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a Fuchsia-specific test. }, skip: isBrowser); // [intended] This is a Fuchsia-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -382,7 +383,7 @@ void main() { ...@@ -382,7 +383,7 @@ void main() {
// //
// GTK has some weird behavior where the tested key event sequence will // GTK has some weird behavior where the tested key event sequence will
// result in a AltRight down event without Alt bitmask. // result in a AltRight down event without Alt bitmask.
testWidgets('keysPressed modifiers are synchronized with key events on Linux GTK (down events)', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on Linux GTK (down events)', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
await simulateGTKKeyEvent(true, 0x6c/*AltRight*/, 0xffea/*AltRight*/, 0x2000000); await simulateGTKKeyEvent(true, 0x6c/*AltRight*/, 0xffea/*AltRight*/, 0x2000000);
...@@ -402,7 +403,7 @@ void main() { ...@@ -402,7 +403,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/114591 . // Regression test for https://github.com/flutter/flutter/issues/114591 .
// //
// On Linux, CapsLock can be remapped to a non-modifier key. // On Linux, CapsLock can be remapped to a non-modifier key.
testWidgets('CapsLock should not be release when remapped on Linux', (WidgetTester tester) async { testWidgetsWithLeakTracking('CapsLock should not be release when remapped on Linux', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
await simulateGTKKeyEvent(true, 0x42/*CapsLock*/, 0xff08/*Backspace*/, 0x2000000); await simulateGTKKeyEvent(true, 0x42/*CapsLock*/, 0xff08/*Backspace*/, 0x2000000);
...@@ -419,7 +420,7 @@ void main() { ...@@ -419,7 +420,7 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/114591 . // Regression test for https://github.com/flutter/flutter/issues/114591 .
// //
// On Web, CapsLock can be remapped to a non-modifier key. // On Web, CapsLock can be remapped to a non-modifier key.
testWidgets('CapsLock should not be release when remapped on Web', (WidgetTester _) async { testWidgetsWithLeakTracking('CapsLock should not be release when remapped on Web', (WidgetTester _) async {
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
RawKeyboard.instance.addListener(events.add); RawKeyboard.instance.addListener(events.add);
addTearDown(() { addTearDown(() {
...@@ -449,7 +450,7 @@ void main() { ...@@ -449,7 +450,7 @@ void main() {
); );
}, skip: !isBrowser); // [intended] This is a Browser-specific test. }, skip: !isBrowser); // [intended] This is a Browser-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async { testWidgetsWithLeakTracking('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. Change the modifiers so // Generate the data for a regular key down event. Change the modifiers so
// that they show the shift key as already down when this event is // that they show the shift key as already down when this event is
...@@ -537,7 +538,7 @@ void main() { ...@@ -537,7 +538,7 @@ void main() {
); );
}); });
testWidgets('sided modifiers without a side set return all sides on Android', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return all sides on Android', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -574,7 +575,7 @@ void main() { ...@@ -574,7 +575,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is an Android-specific test. }, skip: isBrowser); // [intended] This is an Android-specific test.
testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -611,7 +612,7 @@ void main() { ...@@ -611,7 +612,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a macOS-specific test. }, skip: isBrowser); // [intended] This is a macOS-specific test.
testWidgets('sided modifiers without a side set return all sides on iOS', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return all sides on iOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -648,7 +649,7 @@ void main() { ...@@ -648,7 +649,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is an iOS-specific test. }, skip: isBrowser); // [intended] This is an iOS-specific test.
testWidgets('repeat events', (WidgetTester tester) async { testWidgetsWithLeakTracking('repeat events', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
late RawKeyEvent receivedEvent; late RawKeyEvent receivedEvent;
RawKeyboard.instance.keyEventHandler = (RawKeyEvent event) { RawKeyboard.instance.keyEventHandler = (RawKeyEvent event) {
...@@ -691,7 +692,7 @@ void main() { ...@@ -691,7 +692,7 @@ void main() {
RawKeyboard.instance.keyEventHandler = null; RawKeyboard.instance.keyEventHandler = null;
}, skip: isBrowser); // [intended] This is a Windows-specific test. }, skip: isBrowser); // [intended] This is a Windows-specific test.
testWidgets('sided modifiers without a side set return all sides on Windows', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return all sides on Windows', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -726,7 +727,7 @@ void main() { ...@@ -726,7 +727,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a Windows-specific test. }, skip: isBrowser); // [intended] This is a Windows-specific test.
testWidgets('sided modifiers without a side set return all sides on Linux GLFW', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return all sides on Linux GLFW', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -764,7 +765,7 @@ void main() { ...@@ -764,7 +765,7 @@ void main() {
); );
}, skip: isBrowser); // [intended] This is a GLFW-specific test. }, skip: isBrowser); // [intended] This is a GLFW-specific test.
testWidgets('sided modifiers without a side set return left sides on web', (WidgetTester tester) async { testWidgetsWithLeakTracking('sided modifiers without a side set return left sides on web', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -797,7 +798,7 @@ void main() { ...@@ -797,7 +798,7 @@ void main() {
); );
}); });
testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async { testWidgetsWithLeakTracking('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
final Map<String, dynamic> keyEventMessage; final Map<String, dynamic> keyEventMessage;
if (kIsWeb) { if (kIsWeb) {
keyEventMessage = const <String, dynamic>{ keyEventMessage = const <String, dynamic>{
...@@ -833,7 +834,7 @@ void main() { ...@@ -833,7 +834,7 @@ void main() {
); );
}); });
testWidgets('Allows inconsistent modifier for iOS', (WidgetTester _) async { testWidgetsWithLeakTracking('Allows inconsistent modifier for iOS', (WidgetTester _) async {
// Use `testWidgets` for clean-ups. // Use `testWidgets` for clean-ups.
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
RawKeyboard.instance.addListener(events.add); RawKeyboard.instance.addListener(events.add);
...@@ -861,7 +862,7 @@ void main() { ...@@ -861,7 +862,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.capsLock)); expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.capsLock));
}, skip: isBrowser); // [intended] This is an iOS-specific group. }, skip: isBrowser); // [intended] This is an iOS-specific group.
testWidgets('Allows inconsistent modifier for Android', (WidgetTester _) async { testWidgetsWithLeakTracking('Allows inconsistent modifier for Android', (WidgetTester _) async {
// Use `testWidgets` for clean-ups. // Use `testWidgets` for clean-ups.
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
RawKeyboard.instance.addListener(events.add); RawKeyboard.instance.addListener(events.add);
...@@ -892,7 +893,7 @@ void main() { ...@@ -892,7 +893,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.capsLock)); expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.capsLock));
}, skip: isBrowser); // [intended] This is an Android-specific group. }, skip: isBrowser); // [intended] This is an Android-specific group.
testWidgets('Allows inconsistent modifier for Web - Alt graph', (WidgetTester _) async { testWidgetsWithLeakTracking('Allows inconsistent modifier for Web - Alt graph', (WidgetTester _) async {
// Regression test for https://github.com/flutter/flutter/issues/113836 // Regression test for https://github.com/flutter/flutter/issues/113836
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
RawKeyboard.instance.addListener(events.add); RawKeyboard.instance.addListener(events.add);
...@@ -921,7 +922,7 @@ void main() { ...@@ -921,7 +922,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.altGraph)); expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.altGraph));
}, skip: !isBrowser); // [intended] This is a Browser-specific test. }, skip: !isBrowser); // [intended] This is a Browser-specific test.
testWidgets('Allows inconsistent modifier for Web - Alt right', (WidgetTester _) async { testWidgetsWithLeakTracking('Allows inconsistent modifier for Web - Alt right', (WidgetTester _) async {
// Regression test for https://github.com/flutter/flutter/issues/113836 // Regression test for https://github.com/flutter/flutter/issues/113836
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
RawKeyboard.instance.addListener(events.add); RawKeyboard.instance.addListener(events.add);
...@@ -950,8 +951,9 @@ void main() { ...@@ -950,8 +951,9 @@ void main() {
expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.altRight)); expect(RawKeyboard.instance.keysPressed, contains(LogicalKeyboardKey.altRight));
}, skip: !isBrowser); // [intended] This is a Browser-specific test. }, skip: !isBrowser); // [intended] This is a Browser-specific test.
testWidgets('Dispatch events to all handlers', (WidgetTester tester) async { testWidgetsWithLeakTracking('Dispatch events to all handlers', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final List<int> logs = <int>[]; final List<int> logs = <int>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1014,7 +1016,7 @@ void main() { ...@@ -1014,7 +1016,7 @@ void main() {
logs.clear(); logs.clear();
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('Exceptions from RawKeyboard listeners are caught and reported', (WidgetTester tester) async { testWidgetsWithLeakTracking('Exceptions from RawKeyboard listeners are caught and reported', (WidgetTester tester) async {
void throwingListener(RawKeyEvent event) { void throwingListener(RawKeyEvent event) {
throw 1; throw 1;
} }
...@@ -1288,7 +1290,7 @@ void main() { ...@@ -1288,7 +1290,7 @@ void main() {
expect(data.repeatCount, equals(42)); expect(data.repeatCount, equals(42));
}); });
testWidgets('Key events are responded to correctly.', (WidgetTester tester) async { testWidgetsWithLeakTracking('Key events are responded to correctly.', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event. // Generate the data for a regular key down event.
final Map<String, dynamic> data = KeyEventSimulator.getKeyData( final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
...@@ -1308,6 +1310,7 @@ void main() { ...@@ -1308,6 +1310,7 @@ void main() {
// Set up a widget that will receive focused text events. // Set up a widget that will receive focused text events.
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Focus( Focus(
focusNode: focusNode, focusNode: focusNode,
...@@ -2098,7 +2101,7 @@ void main() { ...@@ -2098,7 +2101,7 @@ void main() {
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft)); expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
}); });
testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async { testWidgetsWithLeakTracking('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
const String platform = 'windows'; const String platform = 'windows';
bool lastHandled = true; bool lastHandled = true;
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
...@@ -2111,6 +2114,7 @@ void main() { ...@@ -2111,6 +2114,7 @@ void main() {
return KeyEventResult.ignored; return KeyEventResult.ignored;
}, },
); );
addTearDown(node.dispose);
await tester.pumpWidget(RawKeyboardListener( await tester.pumpWidget(RawKeyboardListener(
focusNode: node, focusNode: node,
child: Container(), child: Container(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment