// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

class _ModifierCheck {
  const _ModifierCheck(this.key, this.side);
  final ModifierKey key;
  final KeyboardSide side;
}

void main() {
  group('RawKeyboard', () {
    testWidgets('The correct character is produced', (WidgetTester tester) async {
      for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
        String character = '';
        void handleKey(RawKeyEvent event) {
          expect(event.character, equals(character), reason: 'on $platform');
        }
        RawKeyboard.instance.addListener(handleKey);
        character = 'a';
        await simulateKeyDownEvent(LogicalKeyboardKey.keyA, platform: platform);
        character = '`';
        await simulateKeyDownEvent(LogicalKeyboardKey.backquote, platform: platform);
        RawKeyboard.instance.removeListener(handleKey);
      }
    });

    testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
      for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
        void handleKey(RawKeyEvent event) {
          expect(event.character, isNull, reason: 'on $platform');
        }
        RawKeyboard.instance.addListener(handleKey);
        await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
        RawKeyboard.instance.removeListener(handleKey);
      }
    });

    testWidgets('keysPressed is maintained', (WidgetTester tester) async {
      for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
        RawKeyboard.instance.clearKeysPressed();
        expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
        await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{ LogicalKeyboardKey.shiftLeft,
            // Linux doesn't have a concept of left/right keys, so they're all
            // shown as down when either is pressed.
            if (platform == 'linux') LogicalKeyboardKey.shiftRight,
          },
        ),
          reason: 'on $platform',
        );
        await simulateKeyDownEvent(LogicalKeyboardKey.controlLeft, platform: platform);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
              LogicalKeyboardKey.controlLeft,
              if (platform == 'linux') LogicalKeyboardKey.controlRight,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyDownEvent(LogicalKeyboardKey.keyA, platform: platform);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
              LogicalKeyboardKey.controlLeft,
              if (platform == 'linux') LogicalKeyboardKey.controlRight,
              LogicalKeyboardKey.keyA,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
              LogicalKeyboardKey.controlLeft,
              if (platform == 'linux') LogicalKeyboardKey.controlRight,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyUpEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
        expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
        // The Fn key isn't mapped on linux or Windows.
        if (platform != 'linux' && platform != 'windows' && platform != 'ios') {
          await simulateKeyDownEvent(LogicalKeyboardKey.fn, platform: platform);
          expect(
            RawKeyboard.instance.keysPressed,
            equals(
              <LogicalKeyboardKey>{
                if (platform != 'macos') LogicalKeyboardKey.fn,
              },
            ),
            reason: 'on $platform',
          );
          await simulateKeyDownEvent(LogicalKeyboardKey.f12, platform: platform);
          expect(
            RawKeyboard.instance.keysPressed,
            equals(
              <LogicalKeyboardKey>{
                if (platform != 'macos') LogicalKeyboardKey.fn,
                LogicalKeyboardKey.f12,
              },
            ),
            reason: 'on $platform',
          );
          await simulateKeyUpEvent(LogicalKeyboardKey.fn, platform: platform);
          expect(
            RawKeyboard.instance.keysPressed,
            equals(
              <LogicalKeyboardKey>{ LogicalKeyboardKey.f12 },
            ),
            reason: 'on $platform',
          );
          await simulateKeyUpEvent(LogicalKeyboardKey.f12, platform: platform);
          expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
        }
      }
    }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021

    testWidgets('keysPressed is correct when modifier is released before key', (WidgetTester tester) async {
      for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
        RawKeyboard.instance.clearKeysPressed();
        expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
        await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform, physicalKey: PhysicalKeyboardKey.shiftLeft);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              // Linux doesn't have a concept of left/right keys, so they're all
              // shown as down when either is pressed.
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
            },
          ),
          reason: 'on $platform',
        );
        // TODO(gspencergoog): Switch to capital A when the new key event code
        // is finished that can simulate real keys.
        // https://github.com/flutter/flutter/issues/33521
        // This should really be done with a simulated capital A, but the event
        // simulation code doesn't really support that, since it only can
        // simulate events that appear in the key maps (and capital letters
        // don't appear there).
        await simulateKeyDownEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.shiftLeft,
              if (platform == 'linux') LogicalKeyboardKey.shiftRight,
              LogicalKeyboardKey.keyA,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyUpEvent(LogicalKeyboardKey.shiftLeft, platform: platform, physicalKey: PhysicalKeyboardKey.shiftLeft);
        expect(
          RawKeyboard.instance.keysPressed,
          equals(
            <LogicalKeyboardKey>{
              LogicalKeyboardKey.keyA,
            },
          ),
          reason: 'on $platform',
        );
        await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
        expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
      }
    }, skip: isBrowser); // https://github.com/flutter/flutter/issues/76741

    testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'macos',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['modifiers'] = (data['modifiers'] as int) | RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
        ),
      );
    }, skip: isBrowser); // [intended] This is a macOS-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'ios',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['modifiers'] = (data['modifiers'] as int) | RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
        ),
      );
    }, skip: isBrowser); // [intended] This is an iOS-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'windows',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['modifiers'] = (data['modifiers'] as int) | RawKeyEventDataWindows.modifierLeftShift | RawKeyEventDataWindows.modifierShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
        ),
      );
    }, skip: isBrowser); // [intended] This is a Windows-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'android',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['metaState'] = (data['metaState'] as int) | RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
        ),
      );
    }, skip: isBrowser); // [intended] This is an Android-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'fuchsia',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['modifiers'] = (data['modifiers'] as int) | RawKeyEventDataFuchsia.modifierLeftShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
        ),
      );
    }, skip: isBrowser); // [intended] This is a Fuchsia-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'linux',
      );
      // Change the modifiers so that they show the shift key as already down
      // when this event is received, but it's not in keysPressed yet.
      data['modifiers'] = (data['modifiers'] as int) | GLFWKeyHelper.modifierShift;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            // Linux doesn't have a concept of left/right keys, so they're all
            // shown as down when either is pressed.
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is a GLFW-specific test.


    // Regression test for https://github.com/flutter/flutter/issues/93278 .
    //
    // GTK has some weird behavior where the tested key event sequence will
    // 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 {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      Future<void> simulate(bool keyDown, int scancode, int keycode, int modifiers) async {
        final Map<String, dynamic> data = <String, dynamic>{
            'type': keyDown ? 'keydown' : 'keyup',
            'keymap': 'linux',
            'toolkit': 'gtk',
            'scanCode': scancode,
            'keyCode': keycode,
            'modifiers': modifiers,
          };
        // Dispatch an empty key data to disable HardwareKeyboard sanity check,
        // since we're only testing if the raw keyboard can handle the message.
        // In real application the embedder responder will send correct key data
        // (which is tested in the engine.)
        TestDefaultBinaryMessengerBinding.instance!.keyEventManager.handleKeyData(const ui.KeyData(
          type: ui.KeyEventType.down,
          timeStamp: Duration.zero,
          logical: 0,
          physical: 0,
          character: null,
          synthesized: false,
        ));
        await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
          SystemChannels.keyEvent.name,
          SystemChannels.keyEvent.codec.encodeMessage(data),
          (ByteData? data) {},
        );
      }

      await simulate(true,  0x6c/*AltRight*/,  0xffea/*AltRight*/,  0x2000000);
      await simulate(true,  0x32/*ShiftLeft*/, 0xfe08/*NextGroup*/, 0x2000008/*MOD3*/);
      await simulate(false, 0x6c/*AltRight*/,  0xfe03/*AltRight*/,  0x2002008/*MOD3|Reserve14*/);
      await simulate(true,  0x6c/*AltRight*/,  0xfe03/*AltRight*/,  0x2002000/*Reserve14*/);
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.altRight,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is a GTK-specific test.

    testWidgets('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // 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
      // received, but it's not in keysPressed yet.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'web',
      );
      data['metaState'] = (data['metaState'] as int) | RawKeyEventDataWeb.modifierShift;
      // Dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.keyA,
          },
        ),
      );

      // Generate the data for a regular key up event. Don't set the modifiers
      // for shift so that they show the shift key as already up when this event
      // is received, and it's in keysPressed.
      final Map<String, dynamic> data2 = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'web',
        isDown: false,
      )..['metaState'] = 0;
      // Dispatch the modified data.
      await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data2),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{},
        ),
      );

      // Press right modifier key
      final Map<String, dynamic> data3 = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.shiftRight,
        platform: 'web',
      );
      data['metaState'] = (data['metaState'] as int) | RawKeyEventDataWeb.modifierShift;
      // Dispatch the modified data.
      await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data3),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftRight,
          },
        ),
      );

      // Release the key
      final Map<String, dynamic> data4 = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.shiftRight,
        platform: 'web',
        isDown: false,
      )..['metaState'] = 0;
      // Dispatch the modified data.
      await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data4),
        (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{},
        ),
      );
    });

    testWidgets('sided modifiers without a side set return all sides on Android', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'android',
      );
      // Set only the generic "down" modifier, without setting a side.
      data['metaState'] = (data['metaState'] as int) |
        RawKeyEventDataAndroid.modifierShift |
        RawKeyEventDataAndroid.modifierAlt |
        RawKeyEventDataAndroid.modifierControl |
        RawKeyEventDataAndroid.modifierMeta;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.altRight,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.controlRight,
            LogicalKeyboardKey.metaLeft,
            LogicalKeyboardKey.metaRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is an Android-specific test.

    testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'macos',
      );
      // Set only the generic "shift down" modifier, without setting a side.
      data['modifiers'] = (data['modifiers'] as int) |
          RawKeyEventDataMacOs.modifierShift |
          RawKeyEventDataMacOs.modifierOption |
          RawKeyEventDataMacOs.modifierCommand |
          RawKeyEventDataMacOs.modifierControl;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.altRight,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.controlRight,
            LogicalKeyboardKey.metaLeft,
            LogicalKeyboardKey.metaRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is a macOS-specific test.

    testWidgets('sided modifiers without a side set return all sides on iOS', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'ios',
      );
      // Set only the generic "shift down" modifier, without setting a side.
      data['modifiers'] = (data['modifiers'] as int) |
          RawKeyEventDataIos.modifierShift |
          RawKeyEventDataIos.modifierOption |
          RawKeyEventDataIos.modifierCommand |
          RawKeyEventDataIos.modifierControl;
      // dispatch the modified data.
      await ServicesBinding.instance?.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.altRight,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.controlRight,
            LogicalKeyboardKey.metaLeft,
            LogicalKeyboardKey.metaRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is an iOS-specific test.

    testWidgets('repeat events', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      late RawKeyEvent receivedEvent;
      RawKeyboard.instance.keyEventHandler = (RawKeyEvent event) {
        receivedEvent = event;
        return true;
      };

      // Dispatch a down event.
      final Map<String, dynamic> downData = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'windows',
      );
      await ServicesBinding.instance?.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(downData),
        (ByteData? data) {},
      );
      expect(receivedEvent.repeat, false);

      // Dispatch another down event, which should be recognized as a repeat.
      await ServicesBinding.instance?.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(downData),
        (ByteData? data) {},
      );
      expect(receivedEvent.repeat, true);

      // Dispatch an up event.
      await ServicesBinding.instance?.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(KeyEventSimulator.getKeyData(
          LogicalKeyboardKey.keyA,
          isDown: false,
          platform: 'windows',
        )),
        (ByteData? data) {},
      );
      expect(receivedEvent.repeat, false);

      RawKeyboard.instance.keyEventHandler = null;
    }, skip: isBrowser); // [intended] This is a Windows-specific test.

    testWidgets('sided modifiers without a side set return all sides on Windows', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'windows',
      );
      // Set only the generic "shift down" modifier, without setting a side.
      // Windows doesn't have a concept of "either" for the Windows (meta) key.
      data['modifiers'] = (data['modifiers'] as int) |
          RawKeyEventDataWindows.modifierShift |
          RawKeyEventDataWindows.modifierAlt |
          RawKeyEventDataWindows.modifierControl;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.altRight,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.controlRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, 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 {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'linux',
      );
      // Set only the generic "shift down" modifier, without setting a side.
      // Windows doesn't have a concept of "either" for the Windows (meta) key.
      data['modifiers'] = (data['modifiers'] as int) |
        GLFWKeyHelper.modifierShift |
        GLFWKeyHelper.modifierAlt |
        GLFWKeyHelper.modifierControl |
        GLFWKeyHelper.modifierMeta;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.shiftRight,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.altRight,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.controlRight,
            LogicalKeyboardKey.metaLeft,
            LogicalKeyboardKey.metaRight,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    }, skip: isBrowser); // [intended] This is a GLFW-specific test.

    testWidgets('sided modifiers without a side set return left sides on web', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'web',
      );
      // Set only the generic "shift down" modifier, without setting a side.
      data['metaState'] = (data['metaState'] as int) |
        RawKeyEventDataWeb.modifierShift |
        RawKeyEventDataWeb.modifierAlt |
        RawKeyEventDataWeb.modifierControl |
        RawKeyEventDataWeb.modifierMeta;
      // dispatch the modified data.
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
            (ByteData? data) {},
      );
      expect(
        RawKeyboard.instance.keysPressed,
        equals(
          <LogicalKeyboardKey>{
            LogicalKeyboardKey.shiftLeft,
            LogicalKeyboardKey.altLeft,
            LogicalKeyboardKey.controlLeft,
            LogicalKeyboardKey.metaLeft,
            LogicalKeyboardKey.keyA,
          },
        ),
      );
    });

    testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
      final Map<String, dynamic> keyEventMessage;
      if (kIsWeb) {
        keyEventMessage = const <String, dynamic>{
          'type': 'keydown',
          'keymap': 'web',
          'code': 'ShiftLeft', // Left shift code
          'metaState': 0x0, // No shift key metaState set!
        };
      } else {
        keyEventMessage = const <String, dynamic>{
          'type': 'keydown',
          'keymap': 'android',
          'keyCode': 0x3b, // Left shift key keyCode
          'scanCode': 0x2a,
          'metaState': 0x0, // No shift key metaState set!
          'source': 0x101,
          'deviceId': 1,
        };
      }

      expect(
        () async {
          await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
            SystemChannels.keyEvent.name,
            SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
            (ByteData? data) { },
          );
        },
        throwsA(isA<AssertionError>().having(
          (AssertionError error) => error.toString(),
          '.toString()',
          contains('Attempted to send a key down event when no keys are in keysPressed'),
        )),
      );
    });

    testWidgets('Dispatch events to all handlers', (WidgetTester tester) async {
      final FocusNode focusNode = FocusNode();
      final List<int> logs = <int>[];

      await tester.pumpWidget(
        RawKeyboardListener(
          autofocus: true,
          focusNode: focusNode,
          child: Container(),
          onKey: (RawKeyEvent event) {
            logs.add(1);
          },
        ),
      );

      // Only the Service binding handler.

      expect(await simulateKeyDownEvent(LogicalKeyboardKey.keyA),
        false);
      expect(logs, <int>[1]);
      logs.clear();

      // Add a handler.

      void handler2(RawKeyEvent event) {
        logs.add(2);
      }
      RawKeyboard.instance.addListener(handler2);

      expect(await simulateKeyUpEvent(LogicalKeyboardKey.keyA),
        false);
      expect(logs, <int>[1, 2]);
      logs.clear();

      // Add another handler.

      void handler3(RawKeyEvent event) {
        logs.add(3);
      }
      RawKeyboard.instance.addListener(handler3);

      expect(await simulateKeyDownEvent(LogicalKeyboardKey.keyA),
        false);
      expect(logs, <int>[1, 2, 3]);
      logs.clear();

      // Add handler2 again.

      RawKeyboard.instance.addListener(handler2);

      expect(await simulateKeyUpEvent(LogicalKeyboardKey.keyA),
        false);
      expect(logs, <int>[1, 2, 3, 2]);
      logs.clear();

      // Remove handler2 once.

      RawKeyboard.instance.removeListener(handler2);
      expect(await simulateKeyDownEvent(LogicalKeyboardKey.keyA),
        false);
      expect(logs, <int>[1, 3, 2]);
      logs.clear();
    }, variant: KeySimulatorTransitModeVariant.all());

    testWidgets('Exceptions from RawKeyboard listeners are caught and reported', (WidgetTester tester) async {
      void throwingListener(RawKeyEvent event) {
        throw 1;
      }

      // When the listener throws an error...
      RawKeyboard.instance.addListener(throwingListener);

      // Simulate a key down event.
      FlutterErrorDetails? record;
      await _runWhileOverridingOnError(
        () => simulateKeyDownEvent(LogicalKeyboardKey.keyA),
        onError: (FlutterErrorDetails details) {
          record = details;
        }
      );

      // ... the error should be caught.
      expect(record, isNotNull);
      expect(record!.exception, 1);
      final Map<String, DiagnosticsNode> infos = _groupDiagnosticsByName(record!.informationCollector!());
      expect(infos['Event'], isA<DiagnosticsProperty<RawKeyEvent>>());

      // But the exception should not interrupt recording the state.
      // Now the key handler no longer throws an error.
      RawKeyboard.instance.removeListener(throwingListener);
      record = null;

      // Simulate a key up event.
      await _runWhileOverridingOnError(
        () => simulateKeyUpEvent(LogicalKeyboardKey.keyA),
        onError: (FlutterErrorDetails details) {
          record = details;
        }
      );
      // If the previous state (key down) wasn't recorded, this key up event will
      // trigger assertions.
      expect(record, isNull);
    });
  });

  group('RawKeyEventDataAndroid', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      RawKeyEventDataAndroid.modifierAlt | RawKeyEventDataAndroid.modifierLeftAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.left),
      RawKeyEventDataAndroid.modifierAlt | RawKeyEventDataAndroid.modifierRightAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.right),
      RawKeyEventDataAndroid.modifierShift | RawKeyEventDataAndroid.modifierLeftShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.left),
      RawKeyEventDataAndroid.modifierShift | RawKeyEventDataAndroid.modifierRightShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.right),
      RawKeyEventDataAndroid.modifierSym: _ModifierCheck(ModifierKey.symbolModifier, KeyboardSide.all),
      RawKeyEventDataAndroid.modifierFunction: _ModifierCheck(ModifierKey.functionModifier, KeyboardSide.all),
      RawKeyEventDataAndroid.modifierControl | RawKeyEventDataAndroid.modifierLeftControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.left),
      RawKeyEventDataAndroid.modifierControl | RawKeyEventDataAndroid.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
      RawKeyEventDataAndroid.modifierMeta | RawKeyEventDataAndroid.modifierLeftMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
      RawKeyEventDataAndroid.modifierMeta | RawKeyEventDataAndroid.modifierRightMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
      RawKeyEventDataAndroid.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
      RawKeyEventDataAndroid.modifierNumLock: _ModifierCheck(ModifierKey.numLockModifier, KeyboardSide.all),
      RawKeyEventDataAndroid.modifierScrollLock: _ModifierCheck(ModifierKey.scrollLockModifier, KeyboardSide.all),
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'android',
          'keyCode': 0x04,
          'plainCodePoint': 0x64,
          'codePoint': 0x44,
          'scanCode': 0x20,
          'metaState': modifier,
          'source': 0x101, // Keyboard source.
          'deviceId': 1,
        });
        final RawKeyEventDataAndroid data = event.data as RawKeyEventDataAndroid;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: "$key should be pressed with metaState $modifier, but isn't.",
            );
            expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataAndroid.modifierFunction) {
          // No need to combine function key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'android',
          'keyCode': 0x04,
          'plainCodePoint': 0x64,
          'codePoint': 0x44,
          'scanCode': 0x20,
          'metaState': modifier | RawKeyEventDataAndroid.modifierFunction,
          'source': 0x101, // Keyboard source.
          'deviceId': 1,
        });
        final RawKeyEventDataAndroid data = event.data as RawKeyEventDataAndroid;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.functionModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataAndroid.modifierFunction}, but isn't.",
            );
            if (key != ModifierKey.functionModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataAndroid.modifierFunction}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 29,
        'plainCodePoint': 'a'.codeUnitAt(0),
        'codePoint': 'A'.codeUnitAt(0),
        'character': 'A',
        'scanCode': 30,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'deviceId': 1,
      });
      final RawKeyEventDataAndroid data = keyAEvent.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 111,
        'codePoint': 0,
        'scanCode': 1,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'deviceId': 1,
      });
      final RawKeyEventDataAndroid data = escapeKeyEvent.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 59,
        'plainCodePoint': 0,
        'codePoint': 0,
        'scanCode': 42,
        'metaState': RawKeyEventDataAndroid.modifierLeftShift,
        'source': 0x101, // Keyboard source.
        'deviceId': 1,
      });
      final RawKeyEventDataAndroid data = shiftLeftKeyEvent.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('DPAD keys from a joystick give physical key mappings', () {
      final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 20,
        'plainCodePoint': 0,
        'codePoint': 0,
        'scanCode': 0,
        'metaState': 0,
        'source': 0x1000010, // Joystick source.
        'deviceId': 1,
      });
      final RawKeyEventDataAndroid data = joystickDpadDown.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
      expect(data.keyLabel, isEmpty);
    });

    test('Arrow keys from a keyboard give correct physical key mappings', () {
      final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 20,
        'plainCodePoint': 0,
        'codePoint': 0,
        'scanCode': 108,
        'metaState': 0,
        'source': 0x101, // Keyboard source.
      });
      final RawKeyEventDataAndroid data = joystickDpadDown.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
      expect(data.keyLabel, isEmpty);
    });

    test('DPAD center from a game pad gives physical key mappings', () {
      final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 23, // DPAD_CENTER code.
        'plainCodePoint': 0,
        'codePoint': 0,
        'scanCode': 317, // Left side thumb joystick center click button.
        'metaState': 0,
        'source': 0x501, // Gamepad and keyboard source.
        'deviceId': 1,
      });
      final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.gameButtonThumbLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.select));
      expect(data.keyLabel, isEmpty);
    });

    test('Device id is read from message', () {
      final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 23, // DPAD_CENTER code.
        'plainCodePoint': 0,
        'codePoint': 0,
        'scanCode': 317, // Left side thumb joystick center click button.
        'metaState': 0,
        'source': 0x501, // Gamepad and keyboard source.
        'deviceId': 10,
      });
      final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
      expect(data.deviceId, equals(10));
    });

    test('Repeat count is passed correctly', () {
      final RawKeyEvent repeatCountEvent = RawKeyEvent.fromMessage(<String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 29,
        'plainCodePoint': 'a'.codeUnitAt(0),
        'codePoint': 'A'.codeUnitAt(0),
        'character': 'A',
        'scanCode': 30,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'repeatCount': 42,
      });
      final RawKeyEventDataAndroid data = repeatCountEvent.data as RawKeyEventDataAndroid;
      expect(data.repeatCount, equals(42));
    });

    testWidgets('Key events are responded to correctly.', (WidgetTester tester) async {
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      // Generate the data for a regular key down event.
      final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
        LogicalKeyboardKey.keyA,
        platform: 'android',
      );
      Map<String, Object?>? message;
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {
          message = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, Object?>?;
        },
      );
      expect(message, equals(<String, Object?>{ 'handled': false }));
      message = null;

      // Set up a widget that will receive focused text events.
      final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
      await tester.pumpWidget(
        Focus(
          focusNode: focusNode,
          onKey: (FocusNode node, RawKeyEvent event) {
            return KeyEventResult.handled; // handle all events.
          },
          child: const SizedBox(),
        ),
      );
      focusNode.requestFocus();
      await tester.pump();

      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(data),
        (ByteData? data) {
          message = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, Object?>?;
        },
      );
      expect(message, equals(<String, Object?>{ 'handled': true }));
      tester.binding.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 29,
        'plainCodePoint': 97,
        'codePoint': 65,
        'character': 'A',
        'scanCode': 30,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'repeatCount': 42,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataAndroid#00000('
        'flags: 0, codePoint: 65, plainCodePoint: 97, keyCode: 29, '
        'scanCode: 30, metaState: 0)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 29,
        'plainCodePoint': 97,
        'codePoint': 65,
        'character': 'A',
        'scanCode': 30,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'repeatCount': 42,
      }).data, const RawKeyEventDataAndroid(
        codePoint: 65,
        plainCodePoint: 97,
        keyCode: 29,
        scanCode: 30,
      ));

      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'android',
        'keyCode': 29,
        'plainCodePoint': 97,
        'codePoint': 65,
        'character': 'A',
        'scanCode': 30,
        'metaState': 0x0,
        'source': 0x101, // Keyboard source.
        'repeatCount': 42,
      }).data, isNot(equals(const RawKeyEventDataAndroid())));
    });
  }, skip: isBrowser); // [intended] This is an Android-specific group.

  group('RawKeyEventDataFuchsia', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      RawKeyEventDataFuchsia.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.any),
      RawKeyEventDataFuchsia.modifierLeftAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.left),
      RawKeyEventDataFuchsia.modifierRightAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.right),
      RawKeyEventDataFuchsia.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.any),
      RawKeyEventDataFuchsia.modifierLeftShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.left),
      RawKeyEventDataFuchsia.modifierRightShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.right),
      RawKeyEventDataFuchsia.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.any),
      RawKeyEventDataFuchsia.modifierLeftControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.left),
      RawKeyEventDataFuchsia.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
      RawKeyEventDataFuchsia.modifierMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.any),
      RawKeyEventDataFuchsia.modifierLeftMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
      RawKeyEventDataFuchsia.modifierRightMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
      RawKeyEventDataFuchsia.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.any),
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'fuchsia',
          'hidUsage': 0x04,
          'codePoint': 0x64,
          'modifiers': modifier,
        });
        final RawKeyEventDataFuchsia data = event.data as RawKeyEventDataFuchsia;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: "$key should be pressed with metaState $modifier, but isn't.",
            );
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataFuchsia.modifierCapsLock) {
          // No need to combine caps lock key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'fuchsia',
          'hidUsage': 0x04,
          'codePoint': 0x64,
          'modifiers': modifier | RawKeyEventDataFuchsia.modifierCapsLock,
        });
        final RawKeyEventDataFuchsia data = event.data as RawKeyEventDataFuchsia;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataFuchsia.modifierCapsLock}, but isn't.",
            );
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataFuchsia.modifierCapsLock}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x00070004,
        'codePoint': 'a'.codeUnitAt(0),
        'character': 'a',
      });
      final RawKeyEventDataFuchsia data = keyAEvent.data as RawKeyEventDataFuchsia;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x00070029,
      });
      final RawKeyEventDataFuchsia data = escapeKeyEvent.data as RawKeyEventDataFuchsia;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x000700e1,
      });
      final RawKeyEventDataFuchsia data = shiftLeftKeyEvent.data as RawKeyEventDataFuchsia;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x00070004,
        'codePoint': 97,
        'character': 'a',
        'modifiers': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataFuchsia#00000(hidUsage: 458756, codePoint: 97, modifiers: 16)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x00070004,
        'codePoint': 97,
        'character': 'a',
        'modifiers': 0x10,
      }).data, const RawKeyEventDataFuchsia(
        hidUsage: 0x00070004,
        codePoint: 97,
        modifiers: 0x10,
      ));

      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'fuchsia',
        'hidUsage': 0x00070004,
        'codePoint': 97,
        'character': 'a',
        'modifiers': 0x10,
      }).data, isNot(equals(const RawKeyEventDataFuchsia())));
    });
  }, skip: isBrowser); // [intended] This is a Fuchsia-specific group.

  group('RawKeyEventDataMacOs', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      RawKeyEventDataMacOs.modifierOption | RawKeyEventDataMacOs.modifierLeftOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.left),
      RawKeyEventDataMacOs.modifierOption | RawKeyEventDataMacOs.modifierRightOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.right),
      RawKeyEventDataMacOs.modifierShift | RawKeyEventDataMacOs.modifierLeftShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.left),
      RawKeyEventDataMacOs.modifierShift | RawKeyEventDataMacOs.modifierRightShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.right),
      RawKeyEventDataMacOs.modifierControl | RawKeyEventDataMacOs.modifierLeftControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.left),
      RawKeyEventDataMacOs.modifierControl | RawKeyEventDataMacOs.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
      RawKeyEventDataMacOs.modifierCommand | RawKeyEventDataMacOs.modifierLeftCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
      RawKeyEventDataMacOs.modifierCommand | RawKeyEventDataMacOs.modifierRightCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
      RawKeyEventDataMacOs.modifierOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
      RawKeyEventDataMacOs.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
      RawKeyEventDataMacOs.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
      RawKeyEventDataMacOs.modifierCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.all),
      RawKeyEventDataMacOs.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'macos',
          'keyCode': 0x04,
          'characters': 'a',
          'charactersIgnoringModifiers': 'a',
          'modifiers': modifier,
        });
        final RawKeyEventDataMacOs data = event.data as RawKeyEventDataMacOs;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: "$key should be pressed with metaState $modifier, but isn't.",
            );
            expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataMacOs.modifierCapsLock) {
          // No need to combine caps lock key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'macos',
          'keyCode': 0x04,
          'characters': 'a',
          'charactersIgnoringModifiers': 'a',
          'modifiers': modifier | RawKeyEventDataMacOs.modifierCapsLock,
        });
        final RawKeyEventDataMacOs data = event.data as RawKeyEventDataMacOs;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataMacOs.modifierCapsLock}, but isn't.",
            );
            if (key != ModifierKey.capsLockModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataMacOs.modifierCapsLock}.',
            );
          }
        }
      }
    });

    test('Lower letter keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000000,
        'characters': 'a',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x0,
      });
      final RawKeyEventDataMacOs data = keyAEvent.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Upper letter keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000000,
        'characters': 'A',
        'charactersIgnoringModifiers': 'A',
        'modifiers': 0x20002,
      });
      final RawKeyEventDataMacOs data = keyAEvent.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('A'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000035,
        'characters': '',
        'charactersIgnoringModifiers': '',
        'modifiers': 0x0,
      });
      final RawKeyEventDataMacOs data = escapeKeyEvent.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000038,
        'characters': '',
        'charactersIgnoringModifiers': '',
        'modifiers': RawKeyEventDataMacOs.modifierLeftShift,
      });
      final RawKeyEventDataMacOs data = shiftLeftKeyEvent.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('Unprintable keyboard keys are correctly translated', () {
      final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x0000007B,
        'characters': '',
        'charactersIgnoringModifiers': '', // NSLeftArrowFunctionKey = 0xF702
        'modifiers': RawKeyEventDataMacOs.modifierFunction,
      });
      final RawKeyEventDataMacOs data = leftArrowKey.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
    });

    test('Multi-char keyboard keys are correctly translated', () {
      final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000000,
        'characters': 'án',
        'charactersIgnoringModifiers': 'án',
        'modifiers': 0,
      });
      final RawKeyEventDataMacOs data = leftArrowKey.data as RawKeyEventDataMacOs;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(const LogicalKeyboardKey(0x1400000000)));
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000060,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataMacOs#00000(characters: A, charactersIgnoringModifiers: a, keyCode: 96, modifiers: 16)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000060,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data, const RawKeyEventDataMacOs(
        keyCode: 0x00000060,
        characters: 'A',
        charactersIgnoringModifiers: 'a',
        modifiers: 0x10,
      ));

      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'macos',
        'keyCode': 0x00000060,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data, isNot(equals(const RawKeyEventDataMacOs())));
    });
  }, skip: isBrowser); // [intended] This is a macOS-specific group.

  group('RawKeyEventDataIos', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      RawKeyEventDataIos.modifierOption | RawKeyEventDataIos.modifierLeftOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.left),
      RawKeyEventDataIos.modifierOption | RawKeyEventDataIos.modifierRightOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.right),
      RawKeyEventDataIos.modifierShift | RawKeyEventDataIos.modifierLeftShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.left),
      RawKeyEventDataIos.modifierShift | RawKeyEventDataIos.modifierRightShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.right),
      RawKeyEventDataIos.modifierControl | RawKeyEventDataIos.modifierLeftControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.left),
      RawKeyEventDataIos.modifierControl | RawKeyEventDataIos.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
      RawKeyEventDataIos.modifierCommand | RawKeyEventDataIos.modifierLeftCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
      RawKeyEventDataIos.modifierCommand | RawKeyEventDataIos.modifierRightCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
      RawKeyEventDataIos.modifierOption: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
      RawKeyEventDataIos.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
      RawKeyEventDataIos.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
      RawKeyEventDataIos.modifierCommand: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.all),
      RawKeyEventDataIos.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'ios',
          'keyCode': 0x04,
          'characters': 'a',
          'charactersIgnoringModifiers': 'a',
          'modifiers': modifier,
        });
        final RawKeyEventDataIos data = event.data as RawKeyEventDataIos;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: "$key should be pressed with metaState $modifier, but isn't.",
            );
            expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataIos.modifierCapsLock) {
          // No need to combine caps lock key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'ios',
          'keyCode': 0x04,
          'characters': 'a',
          'charactersIgnoringModifiers': 'a',
          'modifiers': modifier | RawKeyEventDataIos.modifierCapsLock,
        });
        final RawKeyEventDataIos data = event.data as RawKeyEventDataIos;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataIos.modifierCapsLock}, but isn't.",
            );
            if (key != ModifierKey.capsLockModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataIos.modifierCapsLock}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      const String unmodifiedCharacter = 'a';
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000004,
        'characters': 'a',
        'charactersIgnoringModifiers': unmodifiedCharacter,
        'modifiers': 0x0,
      });
      final RawKeyEventDataIos data = keyAEvent.data as RawKeyEventDataIos;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000029,
        'characters': '',
        'charactersIgnoringModifiers': '',
        'modifiers': 0x0,
      });
      final RawKeyEventDataIos data = escapeKeyEvent.data as RawKeyEventDataIos;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x000000e1,
        'characters': '',
        'charactersIgnoringModifiers': '',
        'modifiers': RawKeyEventDataIos.modifierLeftShift,
      });
      final RawKeyEventDataIos data = shiftLeftKeyEvent.data as RawKeyEventDataIos;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('Unprintable keyboard keys are correctly translated', () {
      final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000050,
        'characters': '',
        'charactersIgnoringModifiers': 'UIKeyInputLeftArrow',
        'modifiers': RawKeyEventDataIos.modifierFunction,
      });
      final RawKeyEventDataIos data = leftArrowKey.data as RawKeyEventDataIos;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000004,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataIos#00000(characters: A, charactersIgnoringModifiers: a, keyCode: 4, modifiers: 16)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000004,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data, const RawKeyEventDataIos(
        keyCode: 0x00000004,
        characters: 'A',
        charactersIgnoringModifiers: 'a',
        modifiers: 0x10,
      ));

      expect(RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'ios',
        'keyCode': 0x00000004,
        'characters': 'A',
        'charactersIgnoringModifiers': 'a',
        'modifiers': 0x10,
      }).data, isNot(equals(const RawKeyEventDataIos())));
    });
  }, skip: isBrowser); // [intended] This is an iOS-specific group.

  group('RawKeyEventDataWindows', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      RawKeyEventDataWindows.modifierLeftAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.left),
      RawKeyEventDataWindows.modifierRightAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.right),
      RawKeyEventDataWindows.modifierLeftShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.left),
      RawKeyEventDataWindows.modifierRightShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.right),
      RawKeyEventDataWindows.modifierLeftControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.left),
      RawKeyEventDataWindows.modifierRightControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.right),
      RawKeyEventDataWindows.modifierLeftMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.left),
      RawKeyEventDataWindows.modifierRightMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.right),
      RawKeyEventDataWindows.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
      RawKeyEventDataWindows.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
      RawKeyEventDataWindows.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
      RawKeyEventDataWindows.modifierCaps: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
      RawKeyEventDataWindows.modifierNumLock: _ModifierCheck(ModifierKey.numLockModifier, KeyboardSide.all),
      RawKeyEventDataWindows.modifierScrollLock: _ModifierCheck(ModifierKey.scrollLockModifier, KeyboardSide.all),
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'windows',
          'keyCode': 0x04,
          'characterCodePoint': 0,
          'scanCode': 0x04,
          'modifiers': modifier,
        });
        final RawKeyEventDataWindows data = event.data as RawKeyEventDataWindows;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: "$key should be pressed with modifier $modifier, but isn't.",
            );
            expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataWindows.modifierCaps) {
          // No need to combine caps lock key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, dynamic>{
          'type': 'keydown',
          'keymap': 'windows',
          'keyCode': 0x04,
          'characterCodePoint': 0,
          'scanCode': 0x04,
          'modifiers': modifier | RawKeyEventDataWindows.modifierCaps,
        });
        final RawKeyEventDataWindows data = event.data as RawKeyEventDataWindows;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataWindows.modifierCaps}, but isn't.",
            );
            if (key != ModifierKey.capsLockModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataWindows.modifierCaps}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      const int unmodifiedCharacter = 97; // ASCII value for 'a'.
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 0x00000000,
        'characterCodePoint': unmodifiedCharacter,
        'scanCode': 0x0000001e,
        'modifiers': 0x0,
      });
      final RawKeyEventDataWindows data = keyAEvent.data as RawKeyEventDataWindows;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 27, // keycode for escape key
        'scanCode': 0x00000001, // scanCode for escape key
        'characterCodePoint': 0,
        'modifiers': 0x0,
      });
      final RawKeyEventDataWindows data = escapeKeyEvent.data as RawKeyEventDataWindows;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 160, // keyCode for left shift.
        'scanCode': 0x0000002a,  // scanCode for left shift.
        'characterCodePoint': 0,
        'modifiers': RawKeyEventDataWindows.modifierLeftShift,
      });
      final RawKeyEventDataWindows data = shiftLeftKeyEvent.data as RawKeyEventDataWindows;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('Unprintable keyboard keys are correctly translated', () {
      final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 37, // keyCode for left arrow.
        'scanCode': 0x0000e04b, // scanCode for left arrow.
        'characterCodePoint': 0,
        'modifiers': 0,
      });
      final RawKeyEventDataWindows data = leftArrowKey.data as RawKeyEventDataWindows;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
    });

    testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
      const  String platform = 'windows';
      bool lastHandled = true;
      final List<RawKeyEvent> events = <RawKeyEvent>[];
      // Simulate raw events because VK_PROCESSKEY does not exist in the key mapping.
      Future<void> simulateKeyEventMessage(String type, int keyCode, int scanCode) {
        return ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
          SystemChannels.keyEvent.name,
          SystemChannels.keyEvent.codec.encodeMessage(<String, Object?>{
            'type': type,
            'keymap': platform,
            'keyCode': keyCode,
            'scanCode': scanCode,
            'modifiers': 0,
          }),
          (ByteData? data) {
            final Map<String, Object?> decoded = SystemChannels.keyEvent.codec.decodeMessage(data)! as Map<String, Object?>;
            lastHandled = decoded['handled']! as bool;
          },
        );
      }
      RawKeyboard.instance.addListener(events.add);
      await simulateKeyEventMessage('keydown', 229, 30);
      expect(events, isEmpty);
      expect(lastHandled, true);
      expect(RawKeyboard.instance.keysPressed, isEmpty);
      await simulateKeyEventMessage('keyup', 65, 30);
      expect(events, isEmpty);
      expect(lastHandled, true);
      expect(RawKeyboard.instance.keysPressed, isEmpty);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 0x00000010,
        'characterCodePoint': 10,
        'scanCode': 0x0000001e,
        'modifiers': 0x20,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataWindows#00000(keyCode: 16, scanCode: 30, characterCodePoint: 10, modifiers: 32)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 0x00000010,
        'characterCodePoint': 10,
        'scanCode': 0x0000001e,
        'modifiers': 0x20,
      }).data, const RawKeyEventDataWindows(
        keyCode: 0x00000010,
        scanCode: 0x1e,
        modifiers: 0x20,
        characterCodePoint: 10,
      ));

      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'windows',
        'keyCode': 0x00000010,
        'characterCodePoint': 10,
        'scanCode': 0x0000001e,
        'modifiers': 0x20,
      }).data, isNot(equals(const RawKeyEventDataWindows())));
    });
  }, skip: isBrowser); // [intended] This is a Windows-specific group.

  group('RawKeyEventDataLinux-GLFW', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      GLFWKeyHelper.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
      GLFWKeyHelper.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
      GLFWKeyHelper.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
      GLFWKeyHelper.modifierMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.all),
      GLFWKeyHelper.modifierNumericPad: _ModifierCheck(ModifierKey.numLockModifier, KeyboardSide.all),
      GLFWKeyHelper.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
    };

    // How modifiers are interpreted depends upon the keyCode for GLFW.
    int keyCodeForModifier(int modifier, {required bool isLeft}) {
      switch (modifier) {
        case GLFWKeyHelper.modifierAlt:
          return isLeft ? 342 : 346;
        case GLFWKeyHelper.modifierShift:
          return isLeft ? 340 : 344;
        case GLFWKeyHelper.modifierControl:
          return isLeft ? 341 : 345;
        case GLFWKeyHelper.modifierMeta:
          return isLeft ? 343 : 347;
        case GLFWKeyHelper.modifierNumericPad:
          return 282;
        case GLFWKeyHelper.modifierCapsLock:
          return 280;
        default:
          return 65; // keyA
      }
    }

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        for (final bool isDown in <bool>[true, false]) {
          for (final bool isLeft in <bool>[true, false]) {
            final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
              'type': isDown ? 'keydown' : 'keyup',
              'keymap': 'linux',
              'toolkit': 'glfw',
              'keyCode': keyCodeForModifier(modifier, isLeft: isLeft),
              'scanCode': 0x00000026,
              'unicodeScalarValues': 97,
              // GLFW modifiers don't include the current key event.
              'modifiers': isDown ? 0 : modifier,
            });
            final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
            for (final ModifierKey key in ModifierKey.values) {
              if (modifierTests[modifier]!.key == key) {
                expect(
                  data.isModifierPressed(key, side: modifierTests[modifier]!.side),
                  isDown ? isTrue : isFalse,
                  reason: "${isLeft ? 'left' : 'right'} $key ${isDown ? 'should' : 'should not'} be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but isn't.",
                );
                expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
              } else {
                expect(
                  data.isModifierPressed(key, side: modifierTests[modifier]!.side),
                  isFalse,
                  reason: "${isLeft ? 'left' : 'right'} $key should not be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but is.",
                );
              }
            }
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == GLFWKeyHelper.modifierControl) {
          // No need to combine CTRL key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
          'type': 'keydown',
          'keymap': 'linux',
          'toolkit': 'glfw',
          'keyCode': 65,
          'scanCode': 0x00000026,
          'unicodeScalarValues': 97,
          'modifiers': modifier | GLFWKeyHelper.modifierControl,
        });
        final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.controlModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${GLFWKeyHelper.modifierControl}, but isn't.",
            );
            if (key != ModifierKey.controlModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${GLFWKeyHelper.modifierControl}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = keyAEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
      expect(data.keyLabel, equals('q'));
    });

    test('Code points with two Unicode scalar values are allowed', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 0x10FFFF,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = keyAEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey.keyId, equals(0x10FFFF));
      expect(data.keyLabel, equals('􏿿'));
    });

    test('Code points with more than three Unicode scalar values are not allowed', () {
      // |keyCode| and |scanCode| are arbitrary values. This test should fail due to an invalid |unicodeScalarValues|.
      void _createFailingKey() {
        RawKeyEvent.fromMessage(const <String, Object?>{
          'type': 'keydown',
          'keymap': 'linux',
          'toolkit': 'glfw',
          'keyCode': 65,
          'scanCode': 0x00000026,
          'unicodeScalarValues': 0x1F00000000,
          'modifiers': 0x0,
        });
      }

      expect(() => _createFailingKey(), throwsAssertionError);
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 256,
        'scanCode': 0x00000009,
        'unicodeScalarValues': 0,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = escapeKeyEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 340,
        'scanCode': 0x00000032,
        'unicodeScalarValues': 0,
      });
      final RawKeyEventDataLinux data = shiftLeftKeyEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 0x10FFFF,
        'modifiers': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
       'RawKeyEventDataLinux#00000(toolkit: GLFW, unicodeScalarValues: 1114111, scanCode: 38, keyCode: 65, modifiers: 16, isDown: true)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 0x10FFFF,
        'modifiers': 0x10,
      }).data, RawKeyEventDataLinux(
        keyHelper: KeyHelper('glfw'),
        unicodeScalarValues: 0x10FFFF,
        keyCode: 65,
        scanCode: 0x26,
        modifiers: 0x10,
        isDown: true,
      ));

      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'glfw',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 0x10FFFF,
        'modifiers': 0x10,
      }).data, isNot(equals(RawKeyEventDataLinux(
        keyHelper: KeyHelper('glfw'), isDown: true)),
      ));
    });
  }, skip: isBrowser); // [intended] This is a GLFW-specific group.

  group('RawKeyEventDataLinux-GTK', () {
    const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
      GtkKeyHelper.modifierMod1: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.all),
      GtkKeyHelper.modifierShift: _ModifierCheck(ModifierKey.shiftModifier, KeyboardSide.all),
      GtkKeyHelper.modifierControl: _ModifierCheck(ModifierKey.controlModifier, KeyboardSide.all),
      GtkKeyHelper.modifierMeta: _ModifierCheck(ModifierKey.metaModifier, KeyboardSide.all),
      GtkKeyHelper.modifierMod2: _ModifierCheck(ModifierKey.numLockModifier, KeyboardSide.all),
      GtkKeyHelper.modifierCapsLock: _ModifierCheck(ModifierKey.capsLockModifier, KeyboardSide.all),
    };

    // How modifiers are interpreted depends upon the keyCode for GTK.
    int keyCodeForModifier(int modifier, {required bool isLeft}) {
      switch (modifier) {
        case GtkKeyHelper.modifierMod1:
          return 65513;
        case GtkKeyHelper.modifierShift:
          return isLeft ? 65505 : 65506;
        case GtkKeyHelper.modifierControl:
          return isLeft ? 65507 : 65508;
        case GtkKeyHelper.modifierMeta:
          return isLeft ? 65515 : 65516;
        case GtkKeyHelper.modifierMod2:
          return 65407;
        case GtkKeyHelper.modifierCapsLock:
          return 65509;
        default:
          return 65; // keyA
      }
    }

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        for (final bool isDown in <bool>[true, false]) {
          for (final bool isLeft in <bool>[true, false]) {
            final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
              'type': isDown ? 'keydown' : 'keyup',
              'keymap': 'linux',
              'toolkit': 'gtk',
              'keyCode': keyCodeForModifier(modifier, isLeft: isLeft),
              'scanCode': 0x00000026,
              'unicodeScalarValues': 97,
              // GTK modifiers don't include the current key event.
              'modifiers': isDown ? 0 : modifier,
            });
            final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
            for (final ModifierKey key in ModifierKey.values) {
              if (modifierTests[modifier]!.key == key) {
                expect(
                  data.isModifierPressed(key, side: modifierTests[modifier]!.side),
                  isDown ? isTrue : isFalse,
                  reason: "${isLeft ? 'left' : 'right'} $key ${isDown ? 'should' : 'should not'} be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but isn't.",
                );
                expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
              } else {
                expect(
                  data.isModifierPressed(key, side: modifierTests[modifier]!.side),
                  isFalse,
                  reason: "${isLeft ? 'left' : 'right'} $key should not be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but is.",
                );
              }
            }
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == GtkKeyHelper.modifierControl) {
          // No need to combine CTRL key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
          'type': 'keydown',
          'keymap': 'linux',
          'toolkit': 'gtk',
          'keyCode': 65,
          'scanCode': 0x00000026,
          'unicodeScalarValues': 97,
          'modifiers': modifier | GtkKeyHelper.modifierControl,
        });
        final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier]!.key == key || key == ModifierKey.controlModifier) {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${GtkKeyHelper.modifierControl}, but isn't.",
            );
            if (key != ModifierKey.controlModifier) {
              expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
            } else {
              expect(data.getModifierSide(key), equals(KeyboardSide.all));
            }
          } else {
            expect(
              data.isModifierPressed(key, side: modifierTests[modifier]!.side),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${GtkKeyHelper.modifierControl}.',
            );
          }
        }
      }
    });

    test('Printable keyboard keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = keyAEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
      expect(data.keyLabel, equals('q'));
    });

    test('Code points with two Unicode scalar values are allowed', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 0x10FFFF,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = keyAEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey.keyId, equals(0x10FFFF));
      expect(data.keyLabel, equals('􏿿'));
    });

    test('Code points with more than three Unicode scalar values are not allowed', () {
      // |keyCode| and |scanCode| are arbitrary values. This test should fail due to an invalid |unicodeScalarValues|.
      void _createFailingKey() {
        RawKeyEvent.fromMessage(const <String, Object?>{
          'type': 'keydown',
          'keymap': 'linux',
          'toolkit': 'gtk',
          'keyCode': 65,
          'scanCode': 0x00000026,
          'unicodeScalarValues': 0x1F00000000,
          'modifiers': 0x0,
        });
      }

      expect(() => _createFailingKey(), throwsAssertionError);
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65307,
        'scanCode': 0x00000009,
        'unicodeScalarValues': 0,
        'modifiers': 0x0,
      });
      final RawKeyEventDataLinux data = escapeKeyEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65505,
        'scanCode': 0x00000032,
        'unicodeScalarValues': 0,
      });
      final RawKeyEventDataLinux data = shiftLeftKeyEvent.data as RawKeyEventDataLinux;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataLinux#00000(toolkit: GTK, unicodeScalarValues: 113, scanCode: 38, keyCode: 65, modifiers: 16, isDown: true)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x10,
      }).data, RawKeyEventDataLinux(
        keyHelper: KeyHelper('gtk'),
        unicodeScalarValues: 113,
        keyCode: 65,
        scanCode: 0x26,
        modifiers: 0x10,
        isDown: true,
      ));

      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x10,
      }).data, isNot(equals(RawKeyEventDataLinux(
        keyHelper: KeyHelper('glfw'),
        unicodeScalarValues: 113,
        keyCode: 65,
        scanCode: 0x26,
        modifiers: 0x10,
        isDown: true,
      ))));

      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'linux',
        'toolkit': 'gtk',
        'keyCode': 65,
        'scanCode': 0x00000026,
        'unicodeScalarValues': 113,
        'modifiers': 0x10,
      }).data, isNot(equals(RawKeyEventDataLinux(
        keyHelper: KeyHelper('gtk'), isDown: true)),
      ));
    });
  }, skip: isBrowser); // [intended] This is a GTK-specific group.

  group('RawKeyEventDataWeb', () {
    const Map<int, ModifierKey> modifierTests = <int, ModifierKey>{
      RawKeyEventDataWeb.modifierAlt: ModifierKey.altModifier,
      RawKeyEventDataWeb.modifierShift: ModifierKey.shiftModifier,
      RawKeyEventDataWeb.modifierControl: ModifierKey.controlModifier,
      RawKeyEventDataWeb.modifierMeta: ModifierKey.metaModifier,
      RawKeyEventDataWeb.modifierCapsLock: ModifierKey.capsLockModifier,
      RawKeyEventDataWeb.modifierNumLock: ModifierKey.numLockModifier,
      RawKeyEventDataWeb.modifierScrollLock: ModifierKey.scrollLockModifier,
    };

    test('modifier keys are recognized individually', () {
      for (final int modifier in modifierTests.keys) {
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
          'type': 'keydown',
          'keymap': 'web',
          'code': 'RandomCode',
          'metaState': modifier,
        });
        final RawKeyEventDataWeb data = event.data as RawKeyEventDataWeb;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier] == key) {
            expect(
              data.isModifierPressed(key),
              isTrue,
              reason: "$key should be pressed with metaState $modifier, but isn't.",
            );
          } else {
            expect(
              data.isModifierPressed(key),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier.',
            );
          }
        }
      }
    });

    test('modifier keys are recognized when combined', () {
      for (final int modifier in modifierTests.keys) {
        if (modifier == RawKeyEventDataWeb.modifierMeta) {
          // No need to combine meta key with itself.
          continue;
        }
        final RawKeyEvent event = RawKeyEvent.fromMessage(<String, Object?>{
          'type': 'keydown',
          'keymap': 'web',
          'code': 'RandomCode',
          'metaState': modifier | RawKeyEventDataWeb.modifierMeta,
        });
        final RawKeyEventDataWeb data = event.data as RawKeyEventDataWeb;
        for (final ModifierKey key in ModifierKey.values) {
          if (modifierTests[modifier] == key || key == ModifierKey.metaModifier) {
            expect(
              data.isModifierPressed(key),
              isTrue,
              reason: '$key should be pressed with metaState $modifier '
                  "and additional key ${RawKeyEventDataWeb.modifierMeta}, but isn't.",
            );
          } else {
            expect(
              data.isModifierPressed(key),
              isFalse,
              reason: '$key should not be pressed with metaState $modifier '
                  'and additional key ${RawKeyEventDataWeb.modifierMeta}.',
            );
          }
        }
      }
    });

    test('Lower letter keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'a',
        'location': 0,
        'metaState': 0x0,
      });
      final RawKeyEventDataWeb data = keyAEvent.data as RawKeyEventDataWeb;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('a'));
    });

    test('Upper letter keys are correctly translated', () {
      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'A',
        'location': 0,
        'metaState': 0x1, // Shift
      });
      final RawKeyEventDataWeb data = keyAEvent.data as RawKeyEventDataWeb;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
      expect(data.keyLabel, equals('A'));
    });

    test('Control keyboard keys are correctly translated', () {
      final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'Escape',
        'key': 'Escape',
        'location': 0,
        'metaState': 0x0,
      });
      final RawKeyEventDataWeb data = escapeKeyEvent.data as RawKeyEventDataWeb;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
      expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
      expect(data.keyLabel, isEmpty);
    });

    test('Modifier keyboard keys are correctly translated', () {
      final RawKeyEvent shiftKeyEvent = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'ShiftLeft',
        'key': 'Shift',
        'location': 1,
        'metaState': RawKeyEventDataWeb.modifierShift,
      });
      final RawKeyEventDataWeb data = shiftKeyEvent.data as RawKeyEventDataWeb;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
      expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
      expect(data.keyLabel, isEmpty);
    });

    test('Arrow keys from a keyboard give correct physical key mappings', () {
      final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'ArrowDown',
        'key': 'ArrowDown',
        'location': 0,
        'metaState': 0x0,
      });
      final RawKeyEventDataWeb data = arrowKeyDown.data as RawKeyEventDataWeb;
      expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
      expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
      expect(data.keyLabel, isEmpty);
    });

    test('Unrecognized keys are mapped to Web plane', () {
      final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'Unrecog1',
        'key': 'Unrecog2',
        'location': 0,
        'metaState': 0x0,
      });
      final RawKeyEventDataWeb data = arrowKeyDown.data as RawKeyEventDataWeb;
      // This might be easily broken on Web if the code fails to acknowledge
      // that JavaScript doesn't handle 64-bit bit-wise operation.
      expect(data.physicalKey.usbHidUsage, greaterThan(0x01700000000));
      expect(data.physicalKey.usbHidUsage, lessThan(0x01800000000));
      expect(data.logicalKey.keyId, greaterThan(0x01700000000));
      expect(data.logicalKey.keyId, lessThan(0x01800000000));
      expect(data.keyLabel, isEmpty);
    });

    test('data.toString', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'a',
        'location': 2,
        'metaState': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataWeb#00000(code: KeyA, key: a, location: 2, metaState: 16)'));

      // Without location
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'a',
        'metaState': 0x10,
      }).data.toString(), equalsIgnoringHashCodes(
        'RawKeyEventDataWeb#00000(code: KeyA, key: a, location: 0, metaState: 16)'));
    });

    test('data.equality', () {
      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'a',
        'location': 2,
        'metaState': 0x10,
      }).data, const RawKeyEventDataWeb(
        key: 'a',
        code: 'KeyA',
        location: 2,
        metaState: 0x10,
      ));

      expect(RawKeyEvent.fromMessage(const <String, Object?>{
        'type': 'keydown',
        'keymap': 'web',
        'code': 'KeyA',
        'key': 'a',
        'location': 2,
        'metaState': 0x10,
      }).data, isNot(equals(const RawKeyEventDataWeb(code: 'KeyA', key: 'a'))));
    });
  });
}

Future<void> _runWhileOverridingOnError(AsyncCallback body, {required FlutterExceptionHandler onError}) async {
  final FlutterExceptionHandler? oldFlutterErrorOnError = FlutterError.onError;
  FlutterError.onError = onError;

  try {
    await body();
  } finally {
    FlutterError.onError = oldFlutterErrorOnError;
  }
}

Map<String, DiagnosticsNode> _groupDiagnosticsByName(Iterable<DiagnosticsNode> infos) {
  return Map<String, DiagnosticsNode>.fromIterable(
    infos,
    key: (Object? node) => (node! as DiagnosticsNode).name ?? '',
  );
}
