mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
test: invert
This commit is contained in:
parent
3cbac6f3f9
commit
def03273b8
@ -1,6 +1,7 @@
|
|||||||
import 'package:flowy_editor/flowy_editor.dart';
|
import 'package:flowy_editor/flowy_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:flowy_editor/document/attributes.dart';
|
||||||
|
|
||||||
class ImageNodeBuilder extends NodeWidgetBuilder {
|
class ImageNodeBuilder extends NodeWidgetBuilder {
|
||||||
ImageNodeBuilder.create({
|
ImageNodeBuilder.create({
|
||||||
|
@ -21,3 +21,22 @@ Attributes invertAttributes(Attributes? attr, Attributes? base) {
|
|||||||
return memo;
|
return memo;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Attributes? composeAttributes(Attributes? a, Attributes? b) {
|
||||||
|
a ??= {};
|
||||||
|
b ??= {};
|
||||||
|
final Attributes attributes = {};
|
||||||
|
attributes.addAll(b);
|
||||||
|
|
||||||
|
for (final entry in a.entries) {
|
||||||
|
if (!b.containsKey(entry.key)) {
|
||||||
|
attributes[entry.key] = entry.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
@ -336,7 +336,8 @@ class Delta {
|
|||||||
final length = min(thisIter.peekLength(), otherIter.peekLength());
|
final length = min(thisIter.peekLength(), otherIter.peekLength());
|
||||||
final thisOp = thisIter.next(length);
|
final thisOp = thisIter.next(length);
|
||||||
final otherOp = otherIter.next(length);
|
final otherOp = otherIter.next(length);
|
||||||
final attributes = _composeMap(thisOp.attributes, otherOp.attributes);
|
final attributes =
|
||||||
|
composeAttributes(thisOp.attributes, otherOp.attributes);
|
||||||
if (otherOp is TextRetain && otherOp.length > 0) {
|
if (otherOp is TextRetain && otherOp.length > 0) {
|
||||||
TextOperation? newOp;
|
TextOperation? newOp;
|
||||||
if (thisOp is TextRetain) {
|
if (thisOp is TextRetain) {
|
||||||
@ -423,22 +424,3 @@ class Delta {
|
|||||||
return inverted.chop();
|
return inverted.chop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Attributes? _composeMap(Attributes? a, Attributes? b) {
|
|
||||||
a ??= {};
|
|
||||||
b ??= {};
|
|
||||||
final Attributes attributes = {};
|
|
||||||
attributes.addAll(b);
|
|
||||||
|
|
||||||
for (final entry in a.entries) {
|
|
||||||
if (!b.containsKey(entry.key)) {
|
|
||||||
attributes[entry.key] = entry.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attributes.isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flowy_editor/document/node.dart';
|
import 'package:flowy_editor/document/node.dart';
|
||||||
import 'package:flowy_editor/operation/operation.dart';
|
import 'package:flowy_editor/operation/operation.dart';
|
||||||
|
import 'package:flowy_editor/document/attributes.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import './document/state_tree.dart';
|
import './document/state_tree.dart';
|
||||||
|
@ -2,172 +2,199 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:flowy_editor/document/text_delta.dart';
|
import 'package:flowy_editor/document/text_delta.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
group('compose', () {
|
||||||
test('test delta', () {
|
test('test delta', () {
|
||||||
final delta = Delta(<TextOperation>[
|
final delta = Delta(<TextOperation>[
|
||||||
TextInsert('Gandalf', {
|
TextInsert('Gandalf', {
|
||||||
|
'bold': true,
|
||||||
|
}),
|
||||||
|
TextInsert(' the '),
|
||||||
|
TextInsert('Grey', {
|
||||||
|
'color': '#ccc',
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
final death = Delta().retain(12).insert("White", {
|
||||||
|
'color': '#fff',
|
||||||
|
}).delete(4);
|
||||||
|
|
||||||
|
final restores = delta.compose(death);
|
||||||
|
expect(restores.operations, <TextOperation>[
|
||||||
|
TextInsert('Gandalf', {'bold': true}),
|
||||||
|
TextInsert(' the '),
|
||||||
|
TextInsert('White', {'color': '#fff'}),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
test('compose()', () {
|
||||||
|
final a = Delta().insert('A');
|
||||||
|
final b = Delta().insert('B');
|
||||||
|
final expected = Delta().insert('B').insert('A');
|
||||||
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('insert + retain', () {
|
||||||
|
final a = Delta().insert('A');
|
||||||
|
final b = Delta().retain(1, {
|
||||||
'bold': true,
|
'bold': true,
|
||||||
}),
|
'color': 'red',
|
||||||
TextInsert(' the '),
|
});
|
||||||
TextInsert('Grey', {
|
final expected = Delta().insert('A', {
|
||||||
'color': '#ccc',
|
'bold': true,
|
||||||
})
|
'color': 'red',
|
||||||
]);
|
});
|
||||||
|
expect(a.compose(b), expected);
|
||||||
final death = Delta().retain(12).insert("White", {
|
|
||||||
'color': '#fff',
|
|
||||||
}).delete(4);
|
|
||||||
|
|
||||||
final restores = delta.compose(death);
|
|
||||||
expect(restores.operations, <TextOperation>[
|
|
||||||
TextInsert('Gandalf', {'bold': true}),
|
|
||||||
TextInsert(' the '),
|
|
||||||
TextInsert('White', {'color': '#fff'}),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
test('compose()', () {
|
|
||||||
final a = Delta().insert('A');
|
|
||||||
final b = Delta().insert('B');
|
|
||||||
final expected = Delta().insert('B').insert('A');
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('insert + retain', () {
|
|
||||||
final a = Delta().insert('A');
|
|
||||||
final b = Delta().retain(1, {
|
|
||||||
'bold': true,
|
|
||||||
'color': 'red',
|
|
||||||
});
|
});
|
||||||
final expected = Delta().insert('A', {
|
test('insert + delete', () {
|
||||||
'bold': true,
|
final a = Delta().insert('A');
|
||||||
'color': 'red',
|
final b = Delta().delete(1);
|
||||||
|
final expected = Delta();
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
expect(a.compose(b), expected);
|
test('delete + insert', () {
|
||||||
});
|
final a = Delta().delete(1);
|
||||||
test('insert + delete', () {
|
final b = Delta().insert('B');
|
||||||
final a = Delta().insert('A');
|
final expected = Delta().insert('B').delete(1);
|
||||||
final b = Delta().delete(1);
|
expect(a.compose(b), expected);
|
||||||
final expected = Delta();
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('delete + insert', () {
|
|
||||||
final a = Delta().delete(1);
|
|
||||||
final b = Delta().insert('B');
|
|
||||||
final expected = Delta().insert('B').delete(1);
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('delete + retain', () {
|
|
||||||
final a = Delta().delete(1);
|
|
||||||
final b = Delta().retain(1, {
|
|
||||||
'bold': true,
|
|
||||||
'color': 'red',
|
|
||||||
});
|
});
|
||||||
final expected = Delta().delete(1).retain(1, {
|
test('delete + retain', () {
|
||||||
'bold': true,
|
final a = Delta().delete(1);
|
||||||
'color': 'red',
|
final b = Delta().retain(1, {
|
||||||
|
'bold': true,
|
||||||
|
'color': 'red',
|
||||||
|
});
|
||||||
|
final expected = Delta().delete(1).retain(1, {
|
||||||
|
'bold': true,
|
||||||
|
'color': 'red',
|
||||||
|
});
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
expect(a.compose(b), expected);
|
test('delete + delete', () {
|
||||||
});
|
final a = Delta().delete(1);
|
||||||
test('delete + delete', () {
|
final b = Delta().delete(1);
|
||||||
final a = Delta().delete(1);
|
final expected = Delta().delete(2);
|
||||||
final b = Delta().delete(1);
|
expect(a.compose(b), expected);
|
||||||
final expected = Delta().delete(2);
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('retain + insert', () {
|
|
||||||
final a = Delta().retain(1, {'color': 'blue'});
|
|
||||||
final b = Delta().insert('B');
|
|
||||||
final expected = Delta().insert('B').retain(1, {
|
|
||||||
'color': 'blue',
|
|
||||||
});
|
});
|
||||||
expect(a.compose(b), expected);
|
test('retain + insert', () {
|
||||||
});
|
final a = Delta().retain(1, {'color': 'blue'});
|
||||||
test('retain + retain', () {
|
final b = Delta().insert('B');
|
||||||
final a = Delta().retain(1, {
|
final expected = Delta().insert('B').retain(1, {
|
||||||
'color': 'blue',
|
'color': 'blue',
|
||||||
|
});
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
final b = Delta().retain(1, {
|
test('retain + retain', () {
|
||||||
'bold': true,
|
final a = Delta().retain(1, {
|
||||||
'color': 'red',
|
'color': 'blue',
|
||||||
|
});
|
||||||
|
final b = Delta().retain(1, {
|
||||||
|
'bold': true,
|
||||||
|
'color': 'red',
|
||||||
|
});
|
||||||
|
final expected = Delta().retain(1, {
|
||||||
|
'bold': true,
|
||||||
|
'color': 'red',
|
||||||
|
});
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
final expected = Delta().retain(1, {
|
test('retain + delete', () {
|
||||||
'bold': true,
|
final a = Delta().retain(1, {
|
||||||
'color': 'red',
|
'color': 'blue',
|
||||||
|
});
|
||||||
|
final b = Delta().delete(1);
|
||||||
|
final expected = Delta().delete(1);
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
expect(a.compose(b), expected);
|
test('insert in middle of text', () {
|
||||||
});
|
final a = Delta().insert('Hello');
|
||||||
test('retain + delete', () {
|
final b = Delta().retain(3).insert('X');
|
||||||
final a = Delta().retain(1, {
|
final expected = Delta().insert('HelXlo');
|
||||||
'color': 'blue',
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('insert and delete ordering', () {
|
||||||
|
final a = Delta().insert('Hello');
|
||||||
|
final b = Delta().insert('Hello');
|
||||||
|
final insertFirst = Delta().retain(3).insert('X').delete(1);
|
||||||
|
final deleteFirst = Delta().retain(3).delete(1).insert('X');
|
||||||
|
final expected = Delta().insert('HelXo');
|
||||||
|
expect(a.compose(insertFirst), expected);
|
||||||
|
expect(b.compose(deleteFirst), expected);
|
||||||
|
});
|
||||||
|
test('delete entire text', () {
|
||||||
|
final a = Delta().retain(4).insert('Hello');
|
||||||
|
final b = Delta().delete(9);
|
||||||
|
final expected = Delta().delete(4);
|
||||||
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('retain more than length of text', () {
|
||||||
|
final a = Delta().insert('Hello');
|
||||||
|
final b = Delta().retain(10);
|
||||||
|
final expected = Delta().insert('Hello');
|
||||||
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('retain start optimization', () {
|
||||||
|
final a = Delta()
|
||||||
|
.insert('A', {'bold': true})
|
||||||
|
.insert('B')
|
||||||
|
.insert('C', {'bold': true})
|
||||||
|
.delete(1);
|
||||||
|
final b = Delta().retain(3).insert('D');
|
||||||
|
final expected = Delta()
|
||||||
|
.insert('A', {'bold': true})
|
||||||
|
.insert('B')
|
||||||
|
.insert('C', {'bold': true})
|
||||||
|
.insert('D')
|
||||||
|
.delete(1);
|
||||||
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('retain end optimization', () {
|
||||||
|
final a = Delta()
|
||||||
|
.insert('A', {'bold': true})
|
||||||
|
.insert('B')
|
||||||
|
.insert('C', {'bold': true});
|
||||||
|
final b = Delta().delete(1);
|
||||||
|
final expected = Delta().insert('B').insert('C', {'bold': true});
|
||||||
|
expect(a.compose(b), expected);
|
||||||
|
});
|
||||||
|
test('retain end optimization join', () {
|
||||||
|
final a = Delta()
|
||||||
|
.insert('A', {'bold': true})
|
||||||
|
.insert('B')
|
||||||
|
.insert('C', {'bold': true})
|
||||||
|
.insert('D')
|
||||||
|
.insert('E', {'bold': true})
|
||||||
|
.insert('F');
|
||||||
|
final b = Delta().retain(1).delete(1);
|
||||||
|
final expected = Delta()
|
||||||
|
.insert('AC', {'bold': true})
|
||||||
|
.insert('D')
|
||||||
|
.insert('E', {'bold': true})
|
||||||
|
.insert('F');
|
||||||
|
expect(a.compose(b), expected);
|
||||||
});
|
});
|
||||||
final b = Delta().delete(1);
|
|
||||||
final expected = Delta().delete(1);
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
});
|
||||||
test('insert in middle of text', () {
|
group('invert', () {
|
||||||
final a = Delta().insert('Hello');
|
test('insert', () {
|
||||||
final b = Delta().retain(3).insert('X');
|
final delta = Delta().retain(2).insert('A');
|
||||||
final expected = Delta().insert('HelXlo');
|
final base = Delta().insert('12346');
|
||||||
expect(a.compose(b), expected);
|
final expected = Delta().retain(2).delete(1);
|
||||||
});
|
final inverted = delta.invert(base);
|
||||||
test('insert and delete ordering', () {
|
expect(expected, inverted);
|
||||||
final a = Delta().insert('Hello');
|
expect(base.compose(delta).compose(inverted), base);
|
||||||
final b = Delta().insert('Hello');
|
});
|
||||||
final insertFirst = Delta().retain(3).insert('X').delete(1);
|
test('delete', () {
|
||||||
final deleteFirst = Delta().retain(3).delete(1).insert('X');
|
final delta = Delta().retain(2).delete(3);
|
||||||
final expected = Delta().insert('HelXo');
|
final base = Delta().insert('123456');
|
||||||
expect(a.compose(insertFirst), expected);
|
final expected = Delta().retain(2).insert('345');
|
||||||
expect(b.compose(deleteFirst), expected);
|
final inverted = delta.invert(base);
|
||||||
});
|
expect(expected, inverted);
|
||||||
test('delete entire text', () {
|
expect(base.compose(delta).compose(inverted), base);
|
||||||
final a = Delta().retain(4).insert('Hello');
|
});
|
||||||
final b = Delta().delete(9);
|
// test('retain', () {
|
||||||
final expected = Delta().delete(4);
|
// final delta = Delta().retain(2).retain(3, {'bold': true});
|
||||||
expect(a.compose(b), expected);
|
// final base = Delta().insert('123456');
|
||||||
});
|
// final expected = Delta().retain(2).retain(3, {'bold': null});
|
||||||
test('retain more than length of text', () {
|
// final inverted = delta.invert(base);
|
||||||
final a = Delta().insert('Hello');
|
// expect(expected, inverted);
|
||||||
final b = Delta().retain(10);
|
// expect(base.compose(delta).compose(inverted), base);
|
||||||
final expected = Delta().insert('Hello');
|
// });
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('retain start optimization', () {
|
|
||||||
final a = Delta()
|
|
||||||
.insert('A', {'bold': true})
|
|
||||||
.insert('B')
|
|
||||||
.insert('C', {'bold': true})
|
|
||||||
.delete(1);
|
|
||||||
final b = Delta().retain(3).insert('D');
|
|
||||||
final expected = Delta()
|
|
||||||
.insert('A', {'bold': true})
|
|
||||||
.insert('B')
|
|
||||||
.insert('C', {'bold': true})
|
|
||||||
.insert('D')
|
|
||||||
.delete(1);
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('retain end optimization', () {
|
|
||||||
final a = Delta()
|
|
||||||
.insert('A', {'bold': true})
|
|
||||||
.insert('B')
|
|
||||||
.insert('C', {'bold': true});
|
|
||||||
final b = Delta().delete(1);
|
|
||||||
final expected = Delta().insert('B').insert('C', {'bold': true});
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
|
||||||
test('retain end optimization join', () {
|
|
||||||
final a = Delta()
|
|
||||||
.insert('A', {'bold': true})
|
|
||||||
.insert('B')
|
|
||||||
.insert('C', {'bold': true})
|
|
||||||
.insert('D')
|
|
||||||
.insert('E', {'bold': true})
|
|
||||||
.insert('F');
|
|
||||||
final b = Delta().retain(1).delete(1);
|
|
||||||
final expected = Delta()
|
|
||||||
.insert('AC', {'bold': true})
|
|
||||||
.insert('D')
|
|
||||||
.insert('E', {'bold': true})
|
|
||||||
.insert('F');
|
|
||||||
expect(a.compose(b), expected);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user