Tests for toolbar (#1006)

* fix: fix linux build

* Merge pull request #599 from AppFlowy-IO/refactor/grid_decode_cell_data

Refactor/grid decode cell data

* test: 🧪 tests for toolbar widget

* fix: removed multiText & replaced with single line

* refactor: cleaned up code & removed unused imports

* fix: fix some tests about the toolbar service

Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
Sean Riley Hawkins 2022-09-12 14:11:23 +02:00 committed by GitHub
parent f4cf5d0808
commit 1f9686dc66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 347 additions and 3 deletions

View File

@ -49,6 +49,7 @@ class StyleKey {
StyleKey.strikethrough,
StyleKey.backgroundColor,
StyleKey.href,
StyleKey.code,
];
static List<String> globalStyleKeys = [
@ -58,7 +59,6 @@ class StyleKey {
StyleKey.bulletedList,
StyleKey.numberList,
StyleKey.quote,
StyleKey.code,
];
}

View File

@ -28,6 +28,9 @@ class EditorWidgetTester {
home: Scaffold(
body: AppFlowyEditor(
editorState: _editorState,
editorStyle: const EditorStyle(
padding: EdgeInsets.symmetric(vertical: 30),
),
),
),
),

View File

@ -0,0 +1,331 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
import 'package:appflowy_editor/src/render/rich_text/rich_text_style.dart';
import 'package:appflowy_editor/src/render/toolbar/toolbar_item_widget.dart';
import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../infra/test_editor.dart';
void main() async {
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
});
const singleLineText = "One Line Of Text";
group('toolbar, heading', (() {
testWidgets('Select Text, Click toolbar and set style for h1 heading',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final h1 = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(h1);
expect(find.byType(ToolbarWidget), findsOneWidget);
final h1Button = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.h1';
}
return false;
});
expect(h1Button, findsOneWidget);
await tester.tap(h1Button);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.attributes.heading, 'h1');
});
testWidgets('Select Text, Click toolbar and set style for h2 heading',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final h2 = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(h2);
expect(find.byType(ToolbarWidget), findsOneWidget);
final h2Button = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.h2';
}
return false;
});
expect(h2Button, findsOneWidget);
await tester.tap(h2Button);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.attributes.heading, 'h2');
});
testWidgets('Select Text, Click toolbar and set style for h3 heading',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final h3 = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(h3);
expect(find.byType(ToolbarWidget), findsOneWidget);
final h3Button = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.h3';
}
return false;
});
expect(h3Button, findsOneWidget);
await tester.tap(h3Button);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.attributes.heading, 'h3');
});
}));
group('toolbar, underline', (() {
testWidgets('Select text, click toolbar and set style for underline',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final underline = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(underline);
expect(find.byType(ToolbarWidget), findsOneWidget);
final underlineButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.underline';
}
return false;
});
expect(underlineButton, findsOneWidget);
await tester.tap(underlineButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
// expect(node.attributes.underline, true);
expect(node.allSatisfyUnderlineInSelection(underline), true);
});
}));
group('toolbar, bold', (() {
testWidgets('Select Text, Click Toolbar and set style for bold',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final bold = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(bold);
expect(find.byType(ToolbarWidget), findsOneWidget);
final boldButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.bold';
}
return false;
});
expect(boldButton, findsOneWidget);
await tester.tap(boldButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.allSatisfyBoldInSelection(bold), true);
});
}));
group('toolbar, italic', (() {
testWidgets('Select Text, Click Toolbar and set style for italic',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final italic = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(italic);
expect(find.byType(ToolbarWidget), findsOneWidget);
final italicButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.italic';
}
return false;
});
expect(italicButton, findsOneWidget);
await tester.tap(italicButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.allSatisfyItalicInSelection(italic), true);
});
}));
group('toolbar, strikethrough', (() {
testWidgets('Select Text, Click Toolbar and set style for strikethrough',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final strikeThrough = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(strikeThrough);
expect(find.byType(ToolbarWidget), findsOneWidget);
final strikeThroughButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.strikethrough';
}
return false;
});
expect(strikeThroughButton, findsOneWidget);
await tester.tap(strikeThroughButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.allSatisfyStrikethroughInSelection(strikeThrough), true);
});
}));
group('toolbar, code', (() {
testWidgets('Select Text, Click Toolbar and set style for code',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final code = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(code);
expect(find.byType(ToolbarWidget), findsOneWidget);
final codeButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.code';
}
return false;
});
expect(codeButton, findsOneWidget);
await tester.tap(codeButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(
node.allSatisfyInSelection(
code,
StyleKey.code,
(value) {
return value == true;
},
),
true,
);
});
}));
group('toolbar, quote', (() {
testWidgets('Select Text, Click Toolbar and set style for quote',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final quote = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(quote);
expect(find.byType(ToolbarWidget), findsOneWidget);
final quoteButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.quote';
}
return false;
});
expect(quoteButton, findsOneWidget);
await tester.tap(quoteButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.subtype, 'quote');
});
}));
group('toolbar, bullet list', (() {
testWidgets('Select Text, Click Toolbar and set style for bullet',
(tester) async {
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final bulletList = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(bulletList);
expect(find.byType(ToolbarWidget), findsOneWidget);
final bulletListButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.bulleted_list';
}
return false;
});
expect(bulletListButton, findsOneWidget);
await tester.tap(bulletListButton);
await tester.pumpAndSettle();
final node = editor.nodeAtPath([0]) as TextNode;
expect(node.subtype, 'bulleted-list');
});
}));
group('toolbar, highlight', (() {
testWidgets('Select Text, Click Toolbar and set style for highlighted text',
(tester) async {
// FIXME: Use a const value instead of the magic string.
const blue = '0x6000BCF0';
final editor = tester.editor..insertTextNode(singleLineText);
await editor.startTesting();
final node = editor.nodeAtPath([0]) as TextNode;
final selection = Selection(
start: Position(path: [0], offset: 0),
end: Position(path: [0], offset: singleLineText.length));
await editor.updateSelection(selection);
expect(find.byType(ToolbarWidget), findsOneWidget);
final highlightButton = find.byWidgetPredicate((widget) {
if (widget is ToolbarItemWidget) {
return widget.item.id == 'appflowy.toolbar.highlight';
}
return false;
});
expect(highlightButton, findsOneWidget);
await tester.tap(highlightButton);
await tester.pumpAndSettle();
expect(
node.allSatisfyInSelection(
selection,
StyleKey.backgroundColor,
(value) {
return value == blue;
},
),
true,
);
});
}));
}

View File

@ -40,7 +40,11 @@ void main() async {
await editor.pressLogicKey(
LogicalKeyboardKey.pageDown,
);
currentOffsetY += onePageHeight!;
if (i == page) {
currentOffsetY = scrollService.maxScrollExtent;
} else {
currentOffsetY += onePageHeight!;
}
final dy = scrollService.dy;
expect(dy, currentOffsetY);
}
@ -58,7 +62,11 @@ void main() async {
await editor.pressLogicKey(
LogicalKeyboardKey.pageUp,
);
currentOffsetY -= onePageHeight!;
if (i == 1) {
currentOffsetY = scrollService.minScrollExtent;
} else {
currentOffsetY -= onePageHeight!;
}
final dy = editor.editorState.service.scrollService?.dy;
expect(dy, currentOffsetY);
}

View File

@ -83,6 +83,8 @@ void main() async {
key = 'highlight';
} else if (styleKey == StyleKey.href) {
key = 'link';
} else {
continue;
}
final itemWidget = _itemWidgetForId(tester, 'appflowy.toolbar.$key');
expect(itemWidget.isHighlight, expectedValue);