Quellcode durchsuchen

Add tests for InputBehaviorDesktop

xuty vor 4 Jahren
Ursprung
Commit
0a6cf1540b
2 geänderte Dateien mit 379 neuen und 0 gelöschten Zeilen
  1. 140 0
      test/frontend/input_test.dart
  2. 239 0
      test/frontend/input_test.mocks.dart

+ 140 - 0
test/frontend/input_test.dart

@@ -0,0 +1,140 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+import 'package:xterm/frontend/input_behavior_desktop.dart';
+import 'package:xterm/xterm.dart';
+
+import 'input_test.mocks.dart';
+
+@GenerateMocks([
+  TerminalUiInteraction,
+])
+void main() {
+  group('InputBehaviorDesktop', () {
+    test('can handle fast typing', () {
+      final mockTerminal = MockTerminalUiInteraction();
+      final inputBehavior = InputBehaviorDesktop();
+
+      inputBehavior.onTextEdit(composing('l', -1, -1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('l'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(composing('ls', -1, -1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('s'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      verifyNever(mockTerminal.raiseOnInput(any));
+      verifyNever(mockTerminal.updateComposingString(any));
+    });
+
+    test('can handle English', () {
+      final mockTerminal = MockTerminalUiInteraction();
+      final inputBehavior = InputBehaviorDesktop();
+
+      // typing 'hello'
+
+      inputBehavior.onTextEdit(composing('h', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('h'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      inputBehavior.onTextEdit(composing('e', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('e'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      inputBehavior.onTextEdit(composing('l', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('l'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      inputBehavior.onTextEdit(composing('l', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('l'));
+      verifyNever(mockTerminal.updateComposingString(any));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      inputBehavior.onTextEdit(composing('o', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('o'));
+      verifyNever(mockTerminal.updateComposingString(any));
+    });
+
+    test('can handle Chinese', () {
+      final mockTerminal = MockTerminalUiInteraction();
+      final inputBehavior = InputBehaviorDesktop();
+
+      // typing '你好'
+
+      inputBehavior.onTextEdit(composing('n', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('ni', 0, 2), mockTerminal);
+      inputBehavior.onTextEdit(composing('ni h', 0, 4), mockTerminal);
+      inputBehavior.onTextEdit(composing('ni ha', 0, 5), mockTerminal);
+      inputBehavior.onTextEdit(composing('ni hao', 0, 6), mockTerminal);
+      inputBehavior.onTextEdit(composing('你好', 0, 2), mockTerminal);
+      verify(mockTerminal.updateComposingString(any)).called(6);
+      verifyNever(mockTerminal.raiseOnInput(any));
+
+      inputBehavior.onTextEdit(composing('你好', -1, -1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('你好'));
+      verify(mockTerminal.updateComposingString(''));
+    });
+
+    test('can handle Japanese', () {
+      final mockTerminal = MockTerminalUiInteraction();
+      final inputBehavior = InputBehaviorDesktop();
+
+      // typing 'どうも'
+
+      inputBehavior.onTextEdit(composing('d', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('ど', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('どう', 0, 2), mockTerminal);
+      inputBehavior.onTextEdit(composing('どうm', 0, 3), mockTerminal);
+      inputBehavior.onTextEdit(composing('どうも', 0, 3), mockTerminal);
+      verify(mockTerminal.updateComposingString(any)).called(5);
+      verifyNever(mockTerminal.raiseOnInput(any));
+
+      inputBehavior.onTextEdit(composing('どうも', -1, -1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('どうも'));
+      verify(mockTerminal.updateComposingString(''));
+    });
+
+    test('can handle Korean', () {
+      final mockTerminal = MockTerminalUiInteraction();
+      final inputBehavior = InputBehaviorDesktop();
+
+      // typing '안녕'
+
+      inputBehavior.onTextEdit(composing('ㅇ', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('아', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('안', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('안', 0, 1), mockTerminal);
+      verify(mockTerminal.updateComposingString(any)).called(4);
+      verifyNever(mockTerminal.raiseOnInput(any));
+
+      inputBehavior.onTextEdit(composing('안', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('안'));
+      verify(mockTerminal.updateComposingString(''));
+
+      inputBehavior.onTextEdit(TextEditingValue.empty, mockTerminal);
+      inputBehavior.onTextEdit(composing('ㄴ', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('녀', 0, 1), mockTerminal);
+      inputBehavior.onTextEdit(composing('녕', 0, 1), mockTerminal);
+      verify(mockTerminal.updateComposingString(any)).called(3);
+      verifyNever(mockTerminal.raiseOnInput(any));
+
+      inputBehavior.onTextEdit(composing('녕', 1, 1), mockTerminal);
+      verify(mockTerminal.raiseOnInput('녕'));
+      verify(mockTerminal.updateComposingString(''));
+    });
+  });
+}
+
+TextEditingValue composing(String text, int start, int end) {
+  return TextEditingValue(
+    text: text,
+    selection: TextSelection.collapsed(offset: text.length),
+    composing: TextRange(start: start, end: end),
+  );
+}

+ 239 - 0
test/frontend/input_test.mocks.dart

@@ -0,0 +1,239 @@
+// Mocks generated by Mockito 5.0.15 from annotations
+// in xterm/test/frontend/input_test.dart.
+// Do not manually edit this file.
+
+import 'dart:async' as _i6;
+
+import 'package:mockito/mockito.dart' as _i1;
+import 'package:xterm/buffer/line/line.dart' as _i7;
+import 'package:xterm/input/keys.dart' as _i9;
+import 'package:xterm/mouse/position.dart' as _i8;
+import 'package:xterm/terminal/platform.dart' as _i3;
+import 'package:xterm/terminal/terminal_search.dart' as _i4;
+import 'package:xterm/terminal/terminal_ui_interaction.dart' as _i5;
+import 'package:xterm/theme/terminal_theme.dart' as _i2;
+
+// ignore_for_file: avoid_redundant_argument_values
+// ignore_for_file: avoid_setters_without_getters
+// ignore_for_file: comment_references
+// ignore_for_file: implementation_imports
+// ignore_for_file: invalid_use_of_visible_for_testing_member
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: unnecessary_parenthesis
+
+class _FakeTerminalTheme_0 extends _i1.Fake implements _i2.TerminalTheme {}
+
+class _FakePlatformBehavior_1 extends _i1.Fake implements _i3.PlatformBehavior {
+}
+
+class _FakeTerminalSearchResult_2 extends _i1.Fake
+    implements _i4.TerminalSearchResult {}
+
+class _FakeTerminalSearchOptions_3 extends _i1.Fake
+    implements _i4.TerminalSearchOptions {}
+
+/// A class which mocks [TerminalUiInteraction].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockTerminalUiInteraction extends _i1.Mock
+    implements _i5.TerminalUiInteraction {
+  MockTerminalUiInteraction() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i2.TerminalTheme get theme => (super.noSuchMethod(Invocation.getter(#theme),
+      returnValue: _FakeTerminalTheme_0()) as _i2.TerminalTheme);
+  @override
+  int get scrollOffsetFromBottom =>
+      (super.noSuchMethod(Invocation.getter(#scrollOffsetFromBottom),
+          returnValue: 0) as int);
+  @override
+  int get scrollOffsetFromTop => (super
+          .noSuchMethod(Invocation.getter(#scrollOffsetFromTop), returnValue: 0)
+      as int);
+  @override
+  int get bufferHeight =>
+      (super.noSuchMethod(Invocation.getter(#bufferHeight), returnValue: 0)
+          as int);
+  @override
+  int get terminalHeight =>
+      (super.noSuchMethod(Invocation.getter(#terminalHeight), returnValue: 0)
+          as int);
+  @override
+  int get terminalWidth =>
+      (super.noSuchMethod(Invocation.getter(#terminalWidth), returnValue: 0)
+          as int);
+  @override
+  int get invisibleHeight =>
+      (super.noSuchMethod(Invocation.getter(#invisibleHeight), returnValue: 0)
+          as int);
+  @override
+  bool get showCursor =>
+      (super.noSuchMethod(Invocation.getter(#showCursor), returnValue: false)
+          as bool);
+  @override
+  int get cursorY =>
+      (super.noSuchMethod(Invocation.getter(#cursorY), returnValue: 0) as int);
+  @override
+  int get cursorX =>
+      (super.noSuchMethod(Invocation.getter(#cursorX), returnValue: 0) as int);
+  @override
+  int get cursorColor =>
+      (super.noSuchMethod(Invocation.getter(#cursorColor), returnValue: 0)
+          as int);
+  @override
+  int get backgroundColor =>
+      (super.noSuchMethod(Invocation.getter(#backgroundColor), returnValue: 0)
+          as int);
+  @override
+  bool get dirty =>
+      (super.noSuchMethod(Invocation.getter(#dirty), returnValue: false)
+          as bool);
+  @override
+  _i3.PlatformBehavior get platform =>
+      (super.noSuchMethod(Invocation.getter(#platform),
+          returnValue: _FakePlatformBehavior_1()) as _i3.PlatformBehavior);
+  @override
+  bool get isReady =>
+      (super.noSuchMethod(Invocation.getter(#isReady), returnValue: false)
+          as bool);
+  @override
+  _i6.Future<int> get backendExited =>
+      (super.noSuchMethod(Invocation.getter(#backendExited),
+          returnValue: Future<int>.value(0)) as _i6.Future<int>);
+  @override
+  bool get isTerminated =>
+      (super.noSuchMethod(Invocation.getter(#isTerminated), returnValue: false)
+          as bool);
+  @override
+  String get composingString =>
+      (super.noSuchMethod(Invocation.getter(#composingString), returnValue: '')
+          as String);
+  @override
+  _i4.TerminalSearchResult get userSearchResult => (super.noSuchMethod(
+      Invocation.getter(#userSearchResult),
+      returnValue: _FakeTerminalSearchResult_2()) as _i4.TerminalSearchResult);
+  @override
+  int get numberOfSearchHits => (super
+          .noSuchMethod(Invocation.getter(#numberOfSearchHits), returnValue: 0)
+      as int);
+  @override
+  set currentSearchHit(int? currentSearchHit) =>
+      super.noSuchMethod(Invocation.setter(#currentSearchHit, currentSearchHit),
+          returnValueForMissingStub: null);
+  @override
+  _i4.TerminalSearchOptions get userSearchOptions =>
+      (super.noSuchMethod(Invocation.getter(#userSearchOptions),
+              returnValue: _FakeTerminalSearchOptions_3())
+          as _i4.TerminalSearchOptions);
+  @override
+  set userSearchOptions(_i4.TerminalSearchOptions? options) =>
+      super.noSuchMethod(Invocation.setter(#userSearchOptions, options),
+          returnValueForMissingStub: null);
+  @override
+  set userSearchPattern(String? pattern) =>
+      super.noSuchMethod(Invocation.setter(#userSearchPattern, pattern),
+          returnValueForMissingStub: null);
+  @override
+  bool get isUserSearchActive =>
+      (super.noSuchMethod(Invocation.getter(#isUserSearchActive),
+          returnValue: false) as bool);
+  @override
+  set isUserSearchActive(bool? isUserSearchActive) => super.noSuchMethod(
+      Invocation.setter(#isUserSearchActive, isUserSearchActive),
+      returnValueForMissingStub: null);
+  @override
+  Set<void Function()> get listeners =>
+      (super.noSuchMethod(Invocation.getter(#listeners),
+          returnValue: <void Function()>{}) as Set<void Function()>);
+  @override
+  List<_i7.BufferLine> getVisibleLines() =>
+      (super.noSuchMethod(Invocation.method(#getVisibleLines, []),
+          returnValue: <_i7.BufferLine>[]) as List<_i7.BufferLine>);
+  @override
+  void refresh() => super.noSuchMethod(Invocation.method(#refresh, []),
+      returnValueForMissingStub: null);
+  @override
+  void clearSelection() =>
+      super.noSuchMethod(Invocation.method(#clearSelection, []),
+          returnValueForMissingStub: null);
+  @override
+  void selectAll() => super.noSuchMethod(Invocation.method(#selectAll, []),
+      returnValueForMissingStub: null);
+  @override
+  void onMouseTap(_i8.Position? position) =>
+      super.noSuchMethod(Invocation.method(#onMouseTap, [position]),
+          returnValueForMissingStub: null);
+  @override
+  void onMouseDoubleTap(_i8.Position? position) =>
+      super.noSuchMethod(Invocation.method(#onMouseDoubleTap, [position]),
+          returnValueForMissingStub: null);
+  @override
+  void onPanStart(_i8.Position? position) =>
+      super.noSuchMethod(Invocation.method(#onPanStart, [position]),
+          returnValueForMissingStub: null);
+  @override
+  void onPanUpdate(_i8.Position? position) =>
+      super.noSuchMethod(Invocation.method(#onPanUpdate, [position]),
+          returnValueForMissingStub: null);
+  @override
+  void setScrollOffsetFromBottom(int? offset) => super.noSuchMethod(
+      Invocation.method(#setScrollOffsetFromBottom, [offset]),
+      returnValueForMissingStub: null);
+  @override
+  int convertViewLineToRawLine(int? viewLine) => (super.noSuchMethod(
+      Invocation.method(#convertViewLineToRawLine, [viewLine]),
+      returnValue: 0) as int);
+  @override
+  void raiseOnInput(String? input) =>
+      super.noSuchMethod(Invocation.method(#raiseOnInput, [input]),
+          returnValueForMissingStub: null);
+  @override
+  void write(String? text) =>
+      super.noSuchMethod(Invocation.method(#write, [text]),
+          returnValueForMissingStub: null);
+  @override
+  void paste(String? data) =>
+      super.noSuchMethod(Invocation.method(#paste, [data]),
+          returnValueForMissingStub: null);
+  @override
+  void resize(int? newWidth, int? newHeight, int? newPixelWidth,
+          int? newPixelHeight) =>
+      super.noSuchMethod(
+          Invocation.method(
+              #resize, [newWidth, newHeight, newPixelWidth, newPixelHeight]),
+          returnValueForMissingStub: null);
+  @override
+  void keyInput(_i9.TerminalKey? key,
+          {bool? ctrl = false,
+          bool? alt = false,
+          bool? shift = false,
+          bool? mac = false}) =>
+      super.noSuchMethod(
+          Invocation.method(#keyInput, [key],
+              {#ctrl: ctrl, #alt: alt, #shift: shift, #mac: mac}),
+          returnValueForMissingStub: null);
+  @override
+  void terminateBackend() =>
+      super.noSuchMethod(Invocation.method(#terminateBackend, []),
+          returnValueForMissingStub: null);
+  @override
+  void updateComposingString(String? value) =>
+      super.noSuchMethod(Invocation.method(#updateComposingString, [value]),
+          returnValueForMissingStub: null);
+  @override
+  String toString() => super.toString();
+  @override
+  void addListener(void Function()? listener) =>
+      super.noSuchMethod(Invocation.method(#addListener, [listener]),
+          returnValueForMissingStub: null);
+  @override
+  void removeListener(void Function()? listener) =>
+      super.noSuchMethod(Invocation.method(#removeListener, [listener]),
+          returnValueForMissingStub: null);
+  @override
+  void notifyListeners() =>
+      super.noSuchMethod(Invocation.method(#notifyListeners, []),
+          returnValueForMissingStub: null);
+}