import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('html_document_test.dart', () {
// Foo Bar
test('sample 1', () {
const html = '
Foo Bar
';
final document = htmlToDocument(html);
expect(document.root.children.length, 1);
expect(document.nodeAtPath([0])!.type, ParagraphBlockKeys.type);
expect(document.nodeAtPath([0])!.delta!.toPlainText(), 'Foo Bar');
});
// * Foo
// * Bar
// * Baz
test('sample 2', () {
const html = '''''';
final document = htmlToDocument(html);
expect(document.root.children.length, 3);
expect(document.nodeAtPath([0])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([0])!.delta!.toPlainText(), 'Foo');
expect(document.nodeAtPath([1])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([1])!.delta!.toPlainText(), 'Bar');
expect(document.nodeAtPath([2])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([2])!.delta!.toPlainText(), 'Baz');
});
// Hello
// * Foo
// * Bar
// * Baz
test('sample 3', () {
const html = '''Hello
''';
final document = htmlToDocument(html);
expect(document.root.children.length, 4);
expect(document.nodeAtPath([0])!.type, ParagraphBlockKeys.type);
expect(document.nodeAtPath([0])!.delta!.toPlainText(), 'Hello');
expect(document.nodeAtPath([1])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([1])!.delta!.toPlainText(), 'Foo');
expect(document.nodeAtPath([2])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([2])!.delta!.toPlainText(), 'Bar');
expect(document.nodeAtPath([3])!.type, BulletedListBlockKeys.type);
expect(document.nodeAtPath([3])!.delta!.toPlainText(), 'Baz');
});
// * Foo
// * Bar
// * Baz
test('sample 4', () {
const html = '''''';
final document = htmlToDocument(html);
expect(document.root.children.length, 1);
final foo = document.nodeAtPath([0])!;
final bar = document.nodeAtPath([0, 0])!;
final baz = document.nodeAtPath([0, 0, 0])!;
expect(foo.type, BulletedListBlockKeys.type);
expect(foo.delta!.toPlainText(), 'Foo');
expect(bar.parent, foo);
expect(bar.type, BulletedListBlockKeys.type);
expect(bar.delta!.toPlainText(), 'Bar');
expect(baz.parent, bar);
expect(baz.type, BulletedListBlockKeys.type);
expect(baz.delta!.toPlainText(), 'Baz');
});
// copy from Notion
// There's a line with different formats, such as **bold**, __italic__, underline, ~~strikethrough~~, and `inline code`.
test('sample 5', () {
const html =
'''There's a line with different formats, such as bold, italic, underline, strikethrough, and inline code.''';
final document = htmlToDocument(html);
final delta = document.nodeAtPath([0])!.delta!;
expect(
delta.toJson(),
[
{"insert": "There's a line with different formats, such as "},
{
"insert": "bold",
"attributes": {"bold": true},
},
{"insert": ", "},
{
"insert": "italic",
"attributes": {"italic": true},
},
{"insert": ", underline, "},
{
"insert": "strikethrough",
"attributes": {"strikethrough": true},
},
{"insert": ", and "},
{
"insert": "inline code",
"attributes": {
"bg_color": "0x26878378",
"font_color": "0xffeb5757",
},
},
{"insert": "."},
],
);
});
// sample 6
// 1. Foo
// 2. Bar
// 3. Baz
test('sample 6', () {
const html = '''
- Foo
- Bar
- Baz
''';
final document = htmlToDocument(html);
expect(document.nodeAtPath([0])!.type, NumberedListBlockKeys.type);
expect(document.nodeAtPath([0])!.delta!.toPlainText(), 'Foo');
expect(document.nodeAtPath([1])!.type, NumberedListBlockKeys.type);
expect(document.nodeAtPath([1])!.delta!.toPlainText(), 'Bar');
expect(document.nodeAtPath([2])!.type, NumberedListBlockKeys.type);
expect(document.nodeAtPath([2])!.delta!.toPlainText(), 'Baz');
});
test('sample 7', () {
const html = '''
- Foo
- Bar
- Baz
''';
final document = htmlToDocument(html);
expect(document.root.children.length, 1);
final foo = document.nodeAtPath([0])!;
final bar = document.nodeAtPath([0, 0])!;
final baz = document.nodeAtPath([0, 0, 0])!;
expect(foo.type, NumberedListBlockKeys.type);
expect(foo.delta!.toPlainText(), 'Foo');
expect(bar.parent, foo);
expect(bar.type, NumberedListBlockKeys.type);
expect(bar.delta!.toPlainText(), 'Bar');
expect(baz.parent, bar);
expect(baz.type, NumberedListBlockKeys.type);
expect(baz.delta!.toPlainText(), 'Baz');
});
});
test('sample 8', () {
const html = '''
- Foo
- Bar
Baz
''';
final document = htmlToDocument(html);
expect(document.root.children.length, 6);
final foo1 = document.nodeAtPath([0])!;
final bar1 = document.nodeAtPath([1])!;
final baz1 = document.nodeAtPath([2])!;
final foo2 = document.nodeAtPath([3])!;
final bar2 = document.nodeAtPath([4])!;
final baz2 = document.nodeAtPath([5])!;
expect(foo1.type, NumberedListBlockKeys.type);
expect(foo1.delta!.toPlainText(), 'Foo');
expect(bar1.type, NumberedListBlockKeys.type);
expect(bar1.delta!.toPlainText(), 'Bar');
expect(baz1.type, NumberedListBlockKeys.type);
expect(baz1.delta!.toPlainText(), 'Baz');
expect(foo2.type, BulletedListBlockKeys.type);
expect(foo2.delta!.toPlainText(), 'Foo');
expect(bar2.type, BulletedListBlockKeys.type);
expect(bar2.delta!.toPlainText(), 'Bar');
expect(baz2.type, BulletedListBlockKeys.type);
expect(baz2.delta!.toPlainText(), 'Baz');
});
// copy from Notion
// There's a line with different formats, such as **bold**, __italic__, underline, ~~strikethrough~~, and `inline code`.
test('sample 9', () {
const html =
'''Hello
There's a line with different formats, such as bold, italic, underline, strikethrough, and inline code.
''';
final document = htmlToDocument(html);
expect(document.root.children.length, 2);
final delta = document.nodeAtPath([1])!.delta!;
expect(
delta.toJson(),
[
{"insert": "There's a line with different formats, such as "},
{
"insert": "bold",
"attributes": {"bold": true},
},
{"insert": ", "},
{
"insert": "italic",
"attributes": {"italic": true},
},
{"insert": ", underline, "},
{
"insert": "strikethrough",
"attributes": {"strikethrough": true},
},
{"insert": ", and "},
{
"insert": "inline code",
"attributes": {"code": true},
},
{"insert": "."},
],
);
});
test('sample 10', () {
const html =
'''DTrace is a dynamic tracing technology that can be used to locate system performance issues, obtain information about system function calls, or monitor system runtime information. And worth noting is that DTrace is non-intrusive to existing code. Also, there is no need to modify the existing code or use instrumentation technology to obtain more system information.''';
final document = htmlToDocument(html);
expect(document.root.children.length, 1);
final delta = document.nodeAtPath([0])!.delta!;
expect(
delta.toJson(),
[
{
"insert": "DTrace is a ",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
},
{
"insert": "dynamic tracing",
"attributes": {
"bg_color": "0xffbbdbba",
"bold": true,
"italic": true,
},
},
{
"insert": " technology",
"attributes": {"bg_color": "0xffbbdbba"},
},
{
"insert": " that can be used to locate ",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
},
{
"insert": "system performance issues",
"attributes": {"bg_color": "0xffe8f3e8"},
},
{
"insert": ", obtain information about ",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
},
{
"insert": "system function calls",
"attributes": {"bg_color": "0xffe8f3e8"},
},
{
"insert":
", or monitor system runtime information. And worth noting is that DTrace is ",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
},
{
"insert": "non-intrusive",
"attributes": {"bg_color": "0xffe8f3e8", "bold": true},
},
{
"insert":
" to existing code. Also, there is no need to modify the existing code or use ",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
},
{
"insert": "instrumentation technology",
"attributes": {"bg_color": "0xffe8f3e8"},
},
{
"insert": " to obtain more system information.",
"attributes": {"bg_color": "0xffffffff", "font_color": "0xff242424"},
}
],
);
});
test('sample 11', () {
const html = '''
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
''';
final document = htmlToDocument(html);
for (var i = 1; i <= 6; i++) {
final node = document.nodeAtPath([i - 1]);
expect(node!.type, HeadingBlockKeys.type);
expect(node.delta!.toPlainText(), 'Heading $i');
expect(node.attributes[HeadingBlockKeys.level], i);
}
});
test('sample 12', () {
// Checkout conversion is too low: only 18% of users who click on “Book” checkout.
// Comparable funnels for hotel booking sites achieve ~30% (source).
const html =
'''Checkout conversion is too low: only 18% of users who click on “Book” checkout.
Comparable funnels for hotel booking sites achieve ~30% (source).
''';
final document = htmlToDocument(html);
final node = document.nodeAtPath([0])!;
expect(node.type, ParagraphBlockKeys.type);
expect(
node.delta!.toPlainText(),
'Checkout conversion is too low: only 18% of users who click on “Book” checkout.',
);
final node2 = document.nodeAtPath([1])!;
expect(node2.type, ParagraphBlockKeys.type);
final jsonList = node2.delta!.toJson();
final cleanJson = jsonList.map((e) {
final map = e as Map;
map.removeWhere((k, v) => k != 'insert' && k != 'attributes');
return map;
}).toList();
expect(
cleanJson,
[
{
'insert': 'Comparable funnels for hotel booking sites achieve ~30% (',
'attributes': {'font_color': '0xff000000'},
},
{
'insert': 'source',
'attributes': {
'href':
'https://docs.google.com/document/d/147-eAtY305IGAghvmQzn0NXUFlh2zQs50GbmBNlgnaA/edit?tab=t.0',
'underline': true,
'font_color': '0xff1155cc',
},
},
{
'insert': ').',
'attributes': {'font_color': '0xff000000'},
}
],
);
});
}