Skip to content

Commit

Permalink
Merge pull request #21 from Xazin/tests/improve-coverage-for-commands
Browse files Browse the repository at this point in the history
tests: improve test coverage for commands
  • Loading branch information
LucasXu0 authored Mar 20, 2023
2 parents 2c4a007 + 63fedd3 commit 4e8b8bc
Show file tree
Hide file tree
Showing 7 changed files with 373 additions and 47 deletions.
15 changes: 12 additions & 3 deletions lib/src/commands/command_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extension CommandExtension on EditorState {
} else if (path != null) {
return document.nodeAtPath(path)!;
}

throw Exception('path and node cannot be null at the same time');
}

Expand All @@ -37,26 +38,33 @@ extension CommandExtension on EditorState {
} else if (path != null) {
return document.nodeAtPath(path)! as TextNode;
}

throw Exception('path and node cannot be null at the same time');
}

Selection getSelection(
Selection? selection,
) {
final currentSelection = service.selectionService.currentSelection.value;
if (selection != null) {
return selection;
} else if (currentSelection != null) {
}

final currentSelection = service.selectionService.currentSelection.value;
if (currentSelection != null) {
return currentSelection;
}
throw Exception('path and textNode cannot be null at the same time');

throw Exception(
'selection and selectionService.currentSelection cannot be null at the same time',
);
}

String getTextInSelection(
List<TextNode> textNodes,
Selection selection,
) {
List<String> res = [];

if (selection.isSingle) {
final plainText = textNodes.first.toPlainText();
res.add(plainText.substring(selection.startIndex, selection.endIndex));
Expand All @@ -77,6 +85,7 @@ extension CommandExtension on EditorState {
}
}
}

return res.join('\n');
}
}
6 changes: 0 additions & 6 deletions lib/src/commands/text/text_commands.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ extension TextCommands on EditorState {
}

Future<void> formatText(
EditorState editorState,
Selection? selection,
Attributes attributes, {
Path? path,
Expand All @@ -43,7 +42,6 @@ extension TextCommands on EditorState {
}

Future<void> formatTextWithBuiltInAttribute(
EditorState editorState,
String key,
Attributes attributes, {
Selection? selection,
Expand Down Expand Up @@ -71,13 +69,11 @@ extension TextCommands on EditorState {
}

Future<void> formatTextToCheckbox(
EditorState editorState,
bool check, {
Path? path,
TextNode? textNode,
}) async {
return formatTextWithBuiltInAttribute(
editorState,
BuiltInAttributeKey.checkbox,
{BuiltInAttributeKey.checkbox: check},
path: path,
Expand All @@ -86,13 +82,11 @@ extension TextCommands on EditorState {
}

Future<void> formatLinkInText(
EditorState editorState,
String? link, {
Path? path,
TextNode? textNode,
}) async {
return formatTextWithBuiltInAttribute(
editorState,
BuiltInAttributeKey.href,
{BuiltInAttributeKey.href: link},
path: path,
Expand Down
1 change: 0 additions & 1 deletion lib/src/render/rich_text/checkbox_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
behavior: HitTestBehavior.opaque,
onTap: () async {
await widget.editorState.formatTextToCheckbox(
widget.editorState,
!check,
textNode: widget.textNode,
);
Expand Down
1 change: 0 additions & 1 deletion lib/src/render/toolbar/toolbar_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ void showLinkMenu(
},
onSubmitted: (text) async {
await editorState.formatLinkInText(
editorState,
text,
textNode: textNode,
);
Expand Down
36 changes: 0 additions & 36 deletions test/command/command_extension_test.dart

This file was deleted.

142 changes: 142 additions & 0 deletions test/commands/command_extension_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter_test/flutter_test.dart';
import '../infra/test_editor.dart';

void main() {
group('command_extension.dart', () {
testWidgets('getTextInSelection w/ multiple nodes', (tester) async {
final editor = tester.editor
..insertTextNode(
'Welcome',
)
..insertTextNode(
'to',
)
..insertTextNode(
'Appflowy 😁',
);

await editor.startTesting();

final selection = Selection(
start: Position(path: [2], offset: 5),
end: Position(path: [0], offset: 5),
);

await editor.updateSelection(selection);

final textNodes = editor
.editorState.service.selectionService.currentSelectedNodes
.whereType<TextNode>()
.toList(growable: false);

final text = editor.editorState.getTextInSelection(
textNodes.normalized,
selection.normalized,
);

expect(text, 'me\nto\nAppfl');
});

testWidgets('getTextInSelection where selection.isSingle', (tester) async {
final editor = tester.editor
..insertTextNode(
'Welcome',
)
..insertTextNode(
'to',
)
..insertTextNode(
'Appflowy 😁',
);

await editor.startTesting();

final selection = Selection(
start: Position(path: [0], offset: 3),
end: Position(path: [0]),
);

await editor.updateSelection(selection);

final textNodes = editor
.editorState.service.selectionService.currentSelectedNodes
.whereType<TextNode>()
.toList(growable: false);

final text = editor.editorState.getTextInSelection(
textNodes.normalized,
selection.normalized,
);

expect(text, 'Wel');
});

testWidgets('getNode throws if node and path are null', (tester) async {
final editor = tester.editor;
await editor.startTesting();

expect(() => editor.editorState.getNode(), throwsA(isA<Exception>()));
});

testWidgets('getNode by path', (tester) async {
final editor = tester.editor
..insertTextNode(
'Welcome',
)
..insertTextNode(
'to',
)
..insertTextNode(
'Appflowy 😁',
);

await editor.startTesting();

final node = editor.editorState.getNode(path: [0]) as TextNode;

expect(node.type, 'text');
expect((node.delta.first as TextInsert).text, 'Welcome');
});

testWidgets('getTextNode throws if textNode and path are null',
(tester) async {
final editor = tester.editor;
await editor.startTesting();

expect(() => editor.editorState.getTextNode(), throwsA(isA<Exception>()));
});

testWidgets('getTextNode by path', (tester) async {
final editor = tester.editor
..insertTextNode(
'Welcome',
)
..insertTextNode(
'to',
)
..insertTextNode(
'Appflowy 😁',
);

await editor.startTesting();

final node = editor.editorState.getTextNode(path: [1]);

expect(node.type, 'text');
expect((node.delta.first as TextInsert).text, 'to');
});

testWidgets(
'getSelection throws if selection and selectionService.currentSelection are null',
(tester) async {
final editor = tester.editor;
await editor.startTesting();

expect(
() => editor.editorState.getSelection(null),
throwsA(isA<Exception>()),
);
});
});
}
Loading

0 comments on commit 4e8b8bc

Please sign in to comment.