test: implement enter key test for styled text

This commit is contained in:
Lucas.Xu
2022-08-13 22:37:46 +08:00
parent e508d7414c
commit d6f1593a20
4 changed files with 108 additions and 18 deletions

View File

@ -77,7 +77,8 @@ class FlowyRenderPlugin extends FlowyRenderPluginService {
node.key = key; node.key = key;
return _autoUpdateNodeWidget(builder, context); return _autoUpdateNodeWidget(builder, context);
} else { } else {
assert(false, 'Could not query the builder with this $name'); assert(false,
'Could not query the builder with this $name, or nodeValidator return false.');
// TODO: return a placeholder widget with tips. // TODO: return a placeholder widget with tips.
return Container(); return Container();
} }

View File

@ -187,11 +187,11 @@ class _FlowySelectionState extends State<FlowySelection>
if (selection != null) { if (selection != null) {
if (selection.isCollapsed) { if (selection.isCollapsed) {
/// updates cursor area. /// updates cursor area.
debugPrint('updating cursor'); debugPrint('updating cursor, $selection');
_updateCursorAreas(selection.start); _updateCursorAreas(selection.start);
} else { } else {
// updates selection area. // updates selection area.
debugPrint('updating selection'); debugPrint('updating selection, $selection');
_updateSelectionAreas(selection); _updateSelectionAreas(selection);
} }
} }

View File

@ -1,4 +1,5 @@
import 'package:flowy_editor/flowy_editor.dart'; 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/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../../infra/test_editor.dart'; import '../../infra/test_editor.dart';
@ -8,11 +9,9 @@ void main() async {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
}); });
group('Enter key without shift handler', () { group('enter_without_shift_in_text_node_handler.dart', () {
testWidgets('Pressing enter key in empty document', (tester) async { testWidgets('Presses enter key in empty document', (tester) async {
final editor = tester.editor final editor = tester.editor..insertEmptyTextNode();
..initialize()
..insertEmptyTextNode();
await editor.startTesting(); await editor.startTesting();
await editor.updateSelection( await editor.updateSelection(
Selection.collapsed( Selection.collapsed(
@ -30,19 +29,32 @@ void main() async {
} }
}); });
testWidgets('Pressing enter key in non-empty document', (tester) async { testWidgets('Presses enter key in non-empty document', (tester) async {
// Before
//
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
//
// After
//
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// [Empty Line]
// Welcome to Appflowy 😁
//
const text = 'Welcome to Appflowy 😁'; const text = 'Welcome to Appflowy 😁';
var lines = 5; var lines = 3;
final editor = tester.editor..initialize(); final editor = tester.editor;
for (var i = 1; i <= lines; i++) { for (var i = 1; i <= lines; i++) {
editor.insertTextNode(text: text); editor.insertTextNode(text);
} }
await editor.startTesting(); await editor.startTesting();
expect(editor.documentLength, lines); expect(editor.documentLength, lines);
// Pressing the enter key in last line. // Presses the enter key in last line.
await editor.updateSelection( await editor.updateSelection(
Selection.collapsed( Selection.collapsed(
Position(path: [lines - 1], offset: 0), Position(path: [lines - 1], offset: 0),
@ -52,7 +64,6 @@ void main() async {
LogicalKeyboardKey.enter, LogicalKeyboardKey.enter,
); );
lines += 1; lines += 1;
await tester.pumpAndSettle(const Duration(microseconds: 500));
expect(editor.documentLength, lines); expect(editor.documentLength, lines);
expect(editor.documentSelection, expect(editor.documentSelection,
Selection.collapsed(Position(path: [lines - 1], offset: 0))); Selection.collapsed(Position(path: [lines - 1], offset: 0)));
@ -60,10 +71,87 @@ void main() async {
expect(lastNode != null, true); expect(lastNode != null, true);
expect(lastNode is TextNode, true); expect(lastNode is TextNode, true);
lastNode = lastNode as TextNode; lastNode = lastNode as TextNode;
for (final node in editor.root.children) {
print(
'path = ${node.path}, text = ${(node as TextNode).toRawString()}');
}
expect(lastNode.delta.toRawString(), text); expect(lastNode.delta.toRawString(), text);
expect((lastNode.previous as TextNode).delta.toRawString(), ''); expect((lastNode.previous as TextNode).delta.toRawString(), '');
expect( expect(
(lastNode.previous!.previous as TextNode).delta.toRawString(), text); (lastNode.previous!.previous as TextNode).delta.toRawString(), text);
}); });
// Before
//
// Welcome to Appflowy 😁
// [Style] Welcome to Appflowy 😁
// [Style] Welcome to Appflowy 😁
//
// After
//
// Welcome to Appflowy 😁
// [Empty Line]
// [Style] Welcome to Appflowy 😁
// [Style] Welcome to Appflowy 😁
// [Style]
testWidgets('Presses enter key in bulleted list', (tester) async {
await _testStyleNeedToBeCopy(tester, StyleKey.bulletedList);
});
testWidgets('Presses enter key in numbered list', (tester) async {
await _testStyleNeedToBeCopy(tester, StyleKey.numberList);
});
testWidgets('Presses enter key in checkbox styled text', (tester) async {
await _testStyleNeedToBeCopy(tester, StyleKey.checkbox);
});
testWidgets('Presses enter key in quoted text', (tester) async {
await _testStyleNeedToBeCopy(tester, StyleKey.quote);
});
}); });
} }
Future<void> _testStyleNeedToBeCopy(WidgetTester tester, String style) async {
const text = 'Welcome to Appflowy 😁';
Attributes attributes = {
StyleKey.subtype: style,
};
if (style == StyleKey.checkbox) {
attributes[StyleKey.checkbox] = false;
} 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.collapsed(
Position(path: [1], offset: 0),
),
);
await editor.pressLogicKey(
LogicalKeyboardKey.enter,
);
expect(editor.documentSelection,
Selection.collapsed(Position(path: [2], offset: 0)));
await editor.updateSelection(
Selection.collapsed(
Position(path: [3], offset: text.length),
),
);
await editor.pressLogicKey(
LogicalKeyboardKey.enter,
);
expect(editor.documentSelection,
Selection.collapsed(Position(path: [4], offset: 0)));
expect(editor.nodeAtPath([4])?.subtype, style);
await editor.pressLogicKey(
LogicalKeyboardKey.enter,
);
expect(editor.documentSelection,
Selection.collapsed(Position(path: [4], offset: 0)));
expect(editor.nodeAtPath([4])?.subtype, null);
}

View File

@ -39,15 +39,15 @@ class EditorWidgetTester {
_editorState = _createEmptyDocument(); _editorState = _createEmptyDocument();
} }
insert<T extends Node>(T node) { void insert<T extends Node>(T node) {
_editorState.document.root.insert(node); _editorState.document.root.insert(node);
} }
insertEmptyTextNode() { void insertEmptyTextNode() {
insert(TextNode.empty()); insert(TextNode.empty());
} }
insertTextNode({String? text, Attributes? attributes}) { void insertTextNode(String? text, {Attributes? attributes}) {
insert( insert(
TextNode( TextNode(
type: 'text', type: 'text',
@ -102,6 +102,7 @@ class EditorWidgetTester {
} }
extension TestEditorExtension on WidgetTester { extension TestEditorExtension on WidgetTester {
EditorWidgetTester get editor => EditorWidgetTester(tester: this); EditorWidgetTester get editor =>
EditorWidgetTester(tester: this)..initialize();
EditorState get editorState => editor.editorState; EditorState get editorState => editor.editorState;
} }