Explorar o código

test: implement backspace key test for styled text

Lucas.Xu %!s(int64=2) %!d(string=hai) anos
pai
achega
c008f3369c

+ 1 - 23
frontend/app_flowy/packages/flowy_editor/example/test/widget_test.dart

@@ -5,26 +5,4 @@
 // gestures. You can also use WidgetTester to find child widgets in the widget
 // gestures. You can also use WidgetTester to find child widgets in the widget
 // tree, read text, and verify that the values of widget properties are correct.
 // tree, read text, and verify that the values of widget properties are correct.
 
 
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:example/main.dart';
-
-void main() {
-  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
-    // Build our app and trigger a frame.
-    await tester.pumpWidget(const MyApp());
-
-    // Verify that our counter starts at 0.
-    expect(find.text('0'), findsOneWidget);
-    expect(find.text('1'), findsNothing);
-
-    // Tap the '+' icon and trigger a frame.
-    await tester.tap(find.byIcon(Icons.add));
-    await tester.pump();
-
-    // Verify that our counter has incremented.
-    expect(find.text('0'), findsNothing);
-    expect(find.text('1'), findsOneWidget);
-  });
-}
+void main() {}

+ 3 - 1
frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart

@@ -72,7 +72,9 @@ KeyEventResult _handleBackspace(EditorState editorState, RawKeyEvent event) {
     _deleteNodes(transactionBuilder, textNodes, selection);
     _deleteNodes(transactionBuilder, textNodes, selection);
   }
   }
 
 
-  transactionBuilder.commit();
+  if (transactionBuilder.operations.isNotEmpty) {
+    transactionBuilder.commit();
+  }
 
 
   return KeyEventResult.handled;
   return KeyEventResult.handled;
 }
 }

+ 1 - 7
frontend/app_flowy/packages/flowy_editor/test/infra/test_editor.dart

@@ -73,13 +73,7 @@ class EditorWidgetTester {
   }
   }
 
 
   Future<void> pressLogicKey(LogicalKeyboardKey key) async {
   Future<void> pressLogicKey(LogicalKeyboardKey key) async {
-    late RawKeyEvent testRawKeyEventData;
-    if (key == LogicalKeyboardKey.enter) {
-      testRawKeyEventData = const TestRawKeyEventData(
-        logicalKey: LogicalKeyboardKey.enter,
-        physicalKey: PhysicalKeyboardKey.enter,
-      ).toKeyEvent;
-    }
+    final testRawKeyEventData = TestRawKeyEventData(logicalKey: key).toKeyEvent;
     _editorState.service.keyboardService!.onKey(testRawKeyEventData);
     _editorState.service.keyboardService!.onKey(testRawKeyEventData);
     await tester.pumpAndSettle();
     await tester.pumpAndSettle();
   }
   }

+ 13 - 2
frontend/app_flowy/packages/flowy_editor/test/infra/test_raw_key_event.dart

@@ -7,7 +7,6 @@ class TestRawKeyEvent extends RawKeyDownEvent {
 class TestRawKeyEventData extends RawKeyEventData {
 class TestRawKeyEventData extends RawKeyEventData {
   const TestRawKeyEventData({
   const TestRawKeyEventData({
     required this.logicalKey,
     required this.logicalKey,
-    required this.physicalKey,
     this.isControlPressed = false,
     this.isControlPressed = false,
     this.isShiftPressed = false,
     this.isShiftPressed = false,
     this.isAltPressed = false,
     this.isAltPressed = false,
@@ -30,7 +29,7 @@ class TestRawKeyEventData extends RawKeyEventData {
   final LogicalKeyboardKey logicalKey;
   final LogicalKeyboardKey logicalKey;
 
 
   @override
   @override
-  final PhysicalKeyboardKey physicalKey;
+  PhysicalKeyboardKey get physicalKey => logicalKey.toPhysicalKey;
 
 
   @override
   @override
   KeyboardSide? getModifierSide(ModifierKey key) {
   KeyboardSide? getModifierSide(ModifierKey key) {
@@ -50,3 +49,15 @@ class TestRawKeyEventData extends RawKeyEventData {
     return TestRawKeyEvent(data: this);
     return TestRawKeyEvent(data: this);
   }
   }
 }
 }
+
+extension on LogicalKeyboardKey {
+  PhysicalKeyboardKey get toPhysicalKey {
+    if (this == LogicalKeyboardKey.enter) {
+      return PhysicalKeyboardKey.enter;
+    }
+    if (this == LogicalKeyboardKey.backspace) {
+      return PhysicalKeyboardKey.backspace;
+    }
+    throw UnimplementedError();
+  }
+}

+ 97 - 0
frontend/app_flowy/packages/flowy_editor/test/service/internal_key_event_handlers/delete_text_handler_test.dart

@@ -0,0 +1,97 @@
+import 'package:flowy_editor/flowy_editor.dart';
+import 'package:flowy_editor/src/render/rich_text/rich_text_style.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import '../../infra/test_editor.dart';
+
+void main() async {
+  setUpAll(() {
+    TestWidgetsFlutterBinding.ensureInitialized();
+  });
+
+  group('delete_text_handler.dart', () {
+    testWidgets('Presses backspace key in empty document', (tester) async {
+      // Before
+      //
+      // [Empty Line]
+      //
+      // After
+      //
+      // [Empty Line]
+      //
+      final editor = tester.editor..insertEmptyTextNode();
+      await editor.startTesting();
+      await editor.updateSelection(
+        Selection.single(path: [0], startOffset: 0),
+      );
+      // Pressing the backspace key continuously.
+      for (int i = 1; i <= 1; i++) {
+        await editor.pressLogicKey(
+          LogicalKeyboardKey.backspace,
+        );
+        expect(editor.documentLength, 1);
+        expect(editor.documentSelection,
+            Selection.single(path: [0], startOffset: 0));
+      }
+    });
+  });
+
+  // Before
+  //
+  // Welcome to Appflowy 😁
+  // [Style] Welcome to Appflowy 😁
+  // [Style] Welcome to Appflowy 😁
+  //
+  // After
+  //
+  // Welcome to Appflowy 😁
+  // [Style] Welcome to Appflowy 😁Welcome to Appflowy 😁
+  //
+  testWidgets('Presses backspace key in styled text', (tester) async {
+    await _deleteStyledText(tester, StyleKey.checkbox);
+  });
+}
+
+Future<void> _deleteStyledText(WidgetTester tester, String style) async {
+  const text = 'Welcome to Appflowy 😁';
+  Attributes attributes = {
+    StyleKey.subtype: style,
+  };
+  if (style == StyleKey.checkbox) {
+    attributes[StyleKey.checkbox] = true;
+  } else if (style == StyleKey.numberList) {
+    attributes[StyleKey.number] = 1;
+  }
+  final editor = tester.editor
+    ..insertTextNode(text)
+    ..insertTextNode(text, attributes: attributes)
+    ..insertTextNode(text, attributes: attributes);
+
+  await editor.startTesting();
+  await editor.updateSelection(
+    Selection.single(path: [2], startOffset: 0),
+  );
+  await editor.pressLogicKey(
+    LogicalKeyboardKey.backspace,
+  );
+  expect(editor.documentSelection, Selection.single(path: [2], startOffset: 0));
+
+  await editor.pressLogicKey(
+    LogicalKeyboardKey.backspace,
+  );
+  expect(editor.documentLength, 2);
+  expect(editor.documentSelection,
+      Selection.single(path: [1], startOffset: text.length));
+  expect(editor.nodeAtPath([1])?.subtype, style);
+  expect((editor.nodeAtPath([1]) as TextNode).toRawString(), text * 2);
+
+  await editor.updateSelection(
+    Selection.single(path: [1], startOffset: 0),
+  );
+  await editor.pressLogicKey(
+    LogicalKeyboardKey.backspace,
+  );
+  expect(editor.documentLength, 2);
+  expect(editor.documentSelection, Selection.single(path: [1], startOffset: 0));
+  expect(editor.nodeAtPath([1])?.subtype, null);
+}