test: implement white_space_handler test

This commit is contained in:
Lucas.Xu 2022-08-16 00:14:40 +08:00
parent 88ae437379
commit a7681f86e5
5 changed files with 221 additions and 4 deletions

View File

@ -9,6 +9,13 @@ import 'package:flowy_editor/src/operation/transaction_builder.dart';
import 'package:flowy_editor/src/render/rich_text/rich_text_style.dart';
import 'package:flowy_editor/src/service/keyboard_service.dart';
@visibleForTesting
List<String> get checkboxListSymbols => _checkboxListSymbols;
@visibleForTesting
List<String> get unCheckboxListSymbols => _unCheckboxListSymbols;
@visibleForTesting
List<String> get bulletedListSymbols => _bulletedListSymbols;
const _bulletedListSymbols = ['*', '-'];
const _checkboxListSymbols = ['[x]', '-[x]'];
const _unCheckboxListSymbols = ['[]', '-[]'];

View File

@ -1,7 +1,4 @@
import 'package:flowy_editor/src/service/keyboard_service.dart';
import 'package:flowy_editor/src/service/render_plugin_service.dart';
import 'package:flowy_editor/src/service/scroll_service.dart';
import 'package:flowy_editor/src/service/selection_service.dart';
import 'package:flowy_editor/flowy_editor.dart';
import 'package:flowy_editor/src/service/toolbar_service.dart';
import 'package:flutter/material.dart';
@ -26,6 +23,13 @@ class FlowyService {
// input service
final inputServiceKey = GlobalKey(debugLabel: 'flowy_input_service');
FlowyInputService? get inputService {
if (inputServiceKey.currentState != null &&
inputServiceKey.currentState is FlowyInputService) {
return inputServiceKey.currentState! as FlowyInputService;
}
return null;
}
// render plugin service
late FlowyRenderPlugin renderPluginService;

View File

@ -70,6 +70,31 @@ class EditorWidgetTester {
_editorState.service.selectionService.updateSelection(selection);
}
await tester.pumpAndSettle();
expect(_editorState.service.selectionService.currentSelection.value,
selection);
}
Future<void> insertText(TextNode textNode, String text, int offset,
{Selection? selection}) async {
await apply([
TextEditingDeltaInsertion(
oldText: textNode.toRawString(),
textInserted: text,
insertionOffset: offset,
selection: selection != null
? TextSelection(
baseOffset: selection.start.offset,
extentOffset: selection.end.offset)
: TextSelection.collapsed(offset: offset),
composing: TextRange.empty,
)
]);
}
Future<void> apply(List<TextEditingDelta> deltas) async {
_editorState.service.inputService?.apply(deltas);
await tester.pumpAndSettle();
}
Future<void> pressLogicKey(

View File

@ -79,6 +79,9 @@ extension on LogicalKeyboardKey {
if (this == LogicalKeyboardKey.enter) {
return PhysicalKeyboardKey.enter;
}
if (this == LogicalKeyboardKey.space) {
return PhysicalKeyboardKey.space;
}
if (this == LogicalKeyboardKey.backspace) {
return PhysicalKeyboardKey.backspace;
}

View File

@ -0,0 +1,178 @@
import 'package:flowy_editor/flowy_editor.dart';
import 'package:flowy_editor/src/render/rich_text/rich_text_style.dart';
import 'package:flowy_editor/src/service/internal_key_event_handlers/whitespace_handler.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('white_space_handler.dart', () {
// Before
//
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
//
// After
// [h1]Welcome to Appflowy 😁
// [h2]Welcome to Appflowy 😁
// [h3]Welcome to Appflowy 😁
// [h4]Welcome to Appflowy 😁
// [h5]Welcome to Appflowy 😁
// [h6]Welcome to Appflowy 😁
//
testWidgets('Presses whitespace key after #*', (tester) async {
const maxSignCount = 6;
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor;
for (var i = 1; i <= maxSignCount; i++) {
editor.insertTextNode('${'#' * i}$text');
}
await editor.startTesting();
for (var i = 1; i <= maxSignCount; i++) {
await editor.updateSelection(
Selection.single(path: [i - 1], startOffset: i),
);
await editor.pressLogicKey(LogicalKeyboardKey.space);
final textNode = (editor.nodeAtPath([i - 1]) as TextNode);
expect(textNode.subtype, StyleKey.heading);
// StyleKey.h1 ~ StyleKey.h6
expect(textNode.attributes.heading, 'h$i');
}
});
// Before
//
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
// Welcome to Appflowy 😁
//
// After
// [h1]##Welcome to Appflowy 😁
// [h2]##Welcome to Appflowy 😁
// [h3]##Welcome to Appflowy 😁
// [h4]##Welcome to Appflowy 😁
// [h5]##Welcome to Appflowy 😁
// [h6]##Welcome to Appflowy 😁
//
testWidgets('Presses whitespace key inside #*', (tester) async {
const maxSignCount = 6;
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor;
for (var i = 1; i <= maxSignCount; i++) {
editor.insertTextNode('${'###' * i}$text');
}
await editor.startTesting();
for (var i = 1; i <= maxSignCount; i++) {
await editor.updateSelection(
Selection.single(path: [i - 1], startOffset: i),
);
await editor.pressLogicKey(LogicalKeyboardKey.space);
final textNode = (editor.nodeAtPath([i - 1]) as TextNode);
expect(textNode.subtype, StyleKey.heading);
// StyleKey.h1 ~ StyleKey.h6
expect(textNode.attributes.heading, 'h$i');
expect(textNode.toRawString().startsWith('##'), true);
}
});
// Before
//
// Welcome to Appflowy 😁
//
// After
// [h1 ~ h6]##Welcome to Appflowy 😁
//
testWidgets('Presses whitespace key in heading styled text',
(tester) async {
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor..insertTextNode(text);
await editor.startTesting();
const maxSignCount = 6;
for (var i = 1; i <= maxSignCount; i++) {
await editor.updateSelection(
Selection.single(path: [0], startOffset: 0),
);
final textNode = (editor.nodeAtPath([0]) as TextNode);
await editor.insertText(textNode, '#' * i, 0);
await editor.pressLogicKey(LogicalKeyboardKey.space);
expect(textNode.subtype, StyleKey.heading);
// StyleKey.h2 ~ StyleKey.h6
expect(textNode.attributes.heading, 'h$i');
}
});
testWidgets('Presses whitespace key after (un)checkbox symbols',
(tester) async {
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor..insertTextNode(text);
await editor.startTesting();
final textNode = editor.nodeAtPath([0]) as TextNode;
for (final symbol in unCheckboxListSymbols) {
await editor.updateSelection(
Selection.single(path: [0], startOffset: 0),
);
await editor.insertText(textNode, symbol, 0);
await editor.pressLogicKey(LogicalKeyboardKey.space);
expect(textNode.subtype, StyleKey.checkbox);
expect(textNode.attributes.check, false);
}
});
testWidgets('Presses whitespace key after checkbox symbols',
(tester) async {
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor..insertTextNode(text);
await editor.startTesting();
final textNode = editor.nodeAtPath([0]) as TextNode;
for (final symbol in checkboxListSymbols) {
await editor.updateSelection(
Selection.single(path: [0], startOffset: 0),
);
await editor.insertText(textNode, symbol, 0);
await editor.pressLogicKey(LogicalKeyboardKey.space);
expect(textNode.subtype, StyleKey.checkbox);
expect(textNode.attributes.check, true);
}
});
testWidgets('Presses whitespace key after bulleted list', (tester) async {
const text = 'Welcome to Appflowy 😁';
final editor = tester.editor..insertTextNode(text);
await editor.startTesting();
final textNode = editor.nodeAtPath([0]) as TextNode;
for (final symbol in bulletedListSymbols) {
await editor.updateSelection(
Selection.single(path: [0], startOffset: 0),
);
await editor.insertText(textNode, symbol, 0);
await editor.pressLogicKey(LogicalKeyboardKey.space);
expect(textNode.subtype, StyleKey.bulletedList);
}
});
});
}