gen_keycodes_test.dart 6.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// 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:convert';
import 'dart:io';

import 'package:gen_keycodes/android_code_gen.dart';
import 'package:gen_keycodes/base_code_gen.dart';
import 'package:gen_keycodes/gtk_code_gen.dart';
import 'package:gen_keycodes/ios_code_gen.dart';
import 'package:gen_keycodes/logical_key_data.dart';
import 'package:gen_keycodes/macos_code_gen.dart';
import 'package:gen_keycodes/physical_key_data.dart';
import 'package:gen_keycodes/utils.dart';
import 'package:gen_keycodes/web_code_gen.dart';
import 'package:gen_keycodes/windows_code_gen.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;

String readDataFile(String fileName) {
  return File(path.join(dataRoot, fileName)).readAsStringSync();
}

25
final PhysicalKeyData physicalData = PhysicalKeyData.fromJson(
26
    json.decode(readDataFile('physical_key_data.g.json')) as Map<String, dynamic>);
27
final LogicalKeyData logicalData = LogicalKeyData.fromJson(
28
    json.decode(readDataFile('logical_key_data.g.json')) as Map<String, dynamic>);
29 30
final Map<String, bool> keyGoals = parseMapOfBool(
    readDataFile('layout_goals.json'));
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

void main() {
  setUp(() {
    testDataRoot = path.canonicalize(path.join(Directory.current.absolute.path, 'data'));
  });

  tearDown((){
    testDataRoot = null;
  });

  void checkCommonOutput(String output) {
    expect(output, contains(RegExp('Copyright 201[34]')));
    expect(output, contains('DO NOT EDIT'));
    expect(output, contains(RegExp(r'\b[kK]eyA\b')));
    expect(output, contains(RegExp(r'\b[Dd]igit1\b')));
    expect(output, contains(RegExp(r'\b[Ff]1\b')));
    expect(output, contains(RegExp(r'\b[Nn]umpad1\b')));
    expect(output, contains(RegExp(r'\b[Ss]hiftLeft\b')));
  }

  test('Generate Keycodes for Android', () {
    const String platform = 'android';
    final PlatformCodeGenerator codeGenerator = AndroidCodeGenerator(
      physicalData,
      logicalData,
    );
    final String output = codeGenerator.generate();

    expect(codeGenerator.outputPath(platform), endsWith('KeyboardMap.java'));
    expect(output, contains('class KeyboardMap'));
    expect(output, contains('scanCodeToPhysical'));
    expect(output, contains('keyCodeToLogical'));
    checkCommonOutput(output);
  });
  test('Generate Keycodes for macOS', () {
    const String platform = 'macos';
    final PlatformCodeGenerator codeGenerator = MacOSCodeGenerator(
      physicalData,
      logicalData,
70
      keyGoals,
71 72 73
    );
    final String output = codeGenerator.generate();

74
    expect(codeGenerator.outputPath(platform), endsWith('KeyCodeMap.g.mm'));
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
    expect(output, contains('kValueMask'));
    expect(output, contains('keyCodeToPhysicalKey'));
    expect(output, contains('keyCodeToLogicalKey'));
    expect(output, contains('keyCodeToModifierFlag'));
    expect(output, contains('modifierFlagToKeyCode'));
    expect(output, contains('kCapsLockPhysicalKey'));
    expect(output, contains('kCapsLockLogicalKey'));
    checkCommonOutput(output);
  });
  test('Generate Keycodes for iOS', () {
    const String platform = 'ios';
    final PlatformCodeGenerator codeGenerator = IOSCodeGenerator(
      physicalData,
      logicalData,
    );
    final String output = codeGenerator.generate();

92
    expect(codeGenerator.outputPath(platform), endsWith('KeyCodeMap.g.mm'));
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    expect(output, contains('kValueMask'));
    expect(output, contains('keyCodeToPhysicalKey'));
    expect(output, contains('keyCodeToLogicalKey'));
    expect(output, contains('keyCodeToModifierFlag'));
    expect(output, contains('modifierFlagToKeyCode'));
    expect(output, contains('functionKeyCodes'));
    expect(output, contains('kCapsLockPhysicalKey'));
    expect(output, contains('kCapsLockLogicalKey'));
    checkCommonOutput(output);
  });
  test('Generate Keycodes for Windows', () {
    const String platform = 'windows';
    final PlatformCodeGenerator codeGenerator = WindowsCodeGenerator(
      physicalData,
      logicalData,
      readDataFile(path.join(dataRoot, 'windows_scancode_logical_map.json')),
    );
    final String output = codeGenerator.generate();

112
    expect(codeGenerator.outputPath(platform), endsWith('flutter_key_map.g.cc'));
113 114 115 116 117 118 119 120 121 122 123 124
    expect(output, contains('KeyboardKeyEmbedderHandler::windowsToPhysicalMap_'));
    expect(output, contains('KeyboardKeyEmbedderHandler::windowsToLogicalMap_'));
    expect(output, contains('KeyboardKeyEmbedderHandler::scanCodeToLogicalMap_'));
    checkCommonOutput(output);
  });
  test('Generate Keycodes for Linux', () {
    const String platform = 'gtk';
    final PlatformCodeGenerator codeGenerator = GtkCodeGenerator(
      physicalData,
      logicalData,
      readDataFile(path.join(dataRoot, 'gtk_modifier_bit_mapping.json')),
      readDataFile(path.join(dataRoot, 'gtk_lock_bit_mapping.json')),
125
      keyGoals,
126 127 128
    );
    final String output = codeGenerator.generate();

129
    expect(codeGenerator.outputPath(platform), endsWith('key_mapping.g.cc'));
130 131 132 133 134 135 136 137 138 139 140 141 142
    expect(output, contains('initialize_modifier_bit_to_checked_keys'));
    expect(output, contains('initialize_lock_bit_to_checked_keys'));
    checkCommonOutput(output);
  });
  test('Generate Keycodes for Web', () {
    const String platform = 'web';
    final PlatformCodeGenerator codeGenerator = WebCodeGenerator(
      physicalData,
      logicalData,
      readDataFile(path.join(dataRoot, 'web_logical_location_mapping.json')),
    );
    final String output = codeGenerator.generate();

143
    expect(codeGenerator.outputPath(platform), endsWith('key_map.g.dart'));
144 145 146 147 148
    expect(output, contains('kWebToLogicalKey'));
    expect(output, contains('kWebToPhysicalKey'));
    expect(output, contains('kWebLogicalLocationMap'));
    checkCommonOutput(output);
  });
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
  test('LogicalKeyData', () async {
    final List<LogicalKeyEntry> entries = logicalData.entries.toList();

    // Regression tests for https://github.com/flutter/flutter/pull/87098

    expect(
      entries.indexWhere((LogicalKeyEntry entry) => entry.name == 'ShiftLeft'),
      isNot(-1));
    expect(
      entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('ShiftLeft')),
      -1);
    // 'Shift' maps to both 'ShiftLeft' and 'ShiftRight', and should be resolved
    // by other ways.
    expect(
      entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('Shift')),
      -1);
    // Printable keys must not be added with Web key of their names.
    expect(
      entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('Slash')),
      -1);
  });
170
}