test: improve coverage of operations.dart
This commit is contained in:
parent
a564c10e87
commit
639ebf1415
3 changed files with 99 additions and 9 deletions
|
|
@ -2,8 +2,8 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
/// [Operation] represents a change to a [Document].
|
/// [Operation] represents a change to a [Document].
|
||||||
abstract class Operation {
|
sealed class Operation {
|
||||||
Operation(
|
const Operation(
|
||||||
this.path,
|
this.path,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ abstract class Operation {
|
||||||
|
|
||||||
/// [InsertOperation] represents an insert operation.
|
/// [InsertOperation] represents an insert operation.
|
||||||
class InsertOperation extends Operation {
|
class InsertOperation extends Operation {
|
||||||
InsertOperation(
|
const InsertOperation(
|
||||||
super.path,
|
super.path,
|
||||||
this.nodes,
|
this.nodes,
|
||||||
);
|
);
|
||||||
|
|
@ -71,7 +71,7 @@ class InsertOperation extends Operation {
|
||||||
|
|
||||||
/// [DeleteOperation] represents a delete operation.
|
/// [DeleteOperation] represents a delete operation.
|
||||||
class DeleteOperation extends Operation {
|
class DeleteOperation extends Operation {
|
||||||
DeleteOperation(
|
const DeleteOperation(
|
||||||
super.path,
|
super.path,
|
||||||
this.nodes,
|
this.nodes,
|
||||||
);
|
);
|
||||||
|
|
@ -118,7 +118,7 @@ class DeleteOperation extends Operation {
|
||||||
|
|
||||||
/// [UpdateOperation] represents an attributes update operation.
|
/// [UpdateOperation] represents an attributes update operation.
|
||||||
class UpdateOperation extends Operation {
|
class UpdateOperation extends Operation {
|
||||||
UpdateOperation(
|
const UpdateOperation(
|
||||||
super.path,
|
super.path,
|
||||||
this.attributes,
|
this.attributes,
|
||||||
this.oldAttributes,
|
this.oldAttributes,
|
||||||
|
|
@ -181,7 +181,7 @@ class UpdateOperation extends Operation {
|
||||||
|
|
||||||
/// [UpdateTextOperation] represents a text update operation.
|
/// [UpdateTextOperation] represents a text update operation.
|
||||||
class UpdateTextOperation extends Operation {
|
class UpdateTextOperation extends Operation {
|
||||||
UpdateTextOperation(
|
const UpdateTextOperation(
|
||||||
super.path,
|
super.path,
|
||||||
this.delta,
|
this.delta,
|
||||||
this.inverted,
|
this.inverted,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,43 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
group('operation.dart', () {
|
group('operation.dart', () {
|
||||||
|
test('Operation.fromJson throws', () {
|
||||||
|
expect(() => Operation.fromJson(), throwsA(isA<UnimplementedError>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('InsertOperation.hashCode', () {
|
||||||
|
const ip1 = InsertOperation([0], []);
|
||||||
|
const ip2 = InsertOperation([0], []);
|
||||||
|
|
||||||
|
expect(ip1 == ip2, true);
|
||||||
|
expect(ip1.hashCode == ip2.hashCode, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('DeleteOperation.hashCode', () {
|
||||||
|
const dp1 = DeleteOperation([0], []);
|
||||||
|
const dp2 = DeleteOperation([0], []);
|
||||||
|
|
||||||
|
expect(dp1 == dp2, true);
|
||||||
|
expect(dp1.hashCode == dp2.hashCode, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('UpdateOperation.hashCode', () {
|
||||||
|
const attr = {'a': 1};
|
||||||
|
const up1 = UpdateOperation([0], attr, {});
|
||||||
|
const up2 = UpdateOperation([0], attr, {});
|
||||||
|
|
||||||
|
expect(up1 == up2, true);
|
||||||
|
expect(up1.hashCode == up2.hashCode, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('UpdateTextOperation.hashCode', () {
|
||||||
|
final up1 = UpdateTextOperation([0], Delta(), Delta());
|
||||||
|
final up2 = UpdateTextOperation([0], Delta(), Delta());
|
||||||
|
|
||||||
|
expect(up1 == up2, true);
|
||||||
|
expect(up1.hashCode == up2.hashCode, true);
|
||||||
|
});
|
||||||
|
|
||||||
test('test insert operation', () {
|
test('test insert operation', () {
|
||||||
final node = Node(type: 'example');
|
final node = Node(type: 'example');
|
||||||
final op = InsertOperation([0], [node]);
|
final op = InsertOperation([0], [node]);
|
||||||
|
|
@ -22,7 +59,7 @@ void main() async {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('test update operation', () {
|
test('test update operation', () {
|
||||||
final op = UpdateOperation([0], {'a': 1}, {'a': 0});
|
const op = UpdateOperation([0], {'a': 1}, {'a': 0});
|
||||||
final json = op.toJson();
|
final json = op.toJson();
|
||||||
expect(json, {
|
expect(json, {
|
||||||
'op': 'update',
|
'op': 'update',
|
||||||
|
|
@ -75,5 +112,57 @@ void main() async {
|
||||||
expect(op.invert().invert(), op);
|
expect(op.invert().invert(), op);
|
||||||
expect(op.copyWith(), op);
|
expect(op.copyWith(), op);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('transformOperation() a is InsertOperation', () {
|
||||||
|
final n1 = Node(type: 'paragraph');
|
||||||
|
final n2 = Node(type: 'example');
|
||||||
|
|
||||||
|
final ip = InsertOperation([0], [n1, n2]);
|
||||||
|
final dp = DeleteOperation([0], [n2]);
|
||||||
|
|
||||||
|
final operation = transformOperation(ip, dp) as DeleteOperation;
|
||||||
|
|
||||||
|
expect(operation.nodes.length, 1);
|
||||||
|
expect(operation.nodes.first.delta, null);
|
||||||
|
expect(operation.nodes.first.type, 'example');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('transformOperation() a is DeleteOperation', () {
|
||||||
|
final n1 = Node(type: 'paragraph');
|
||||||
|
final n2 = Node(type: 'example');
|
||||||
|
|
||||||
|
final ip = InsertOperation([0], [n1, n2]);
|
||||||
|
final dp = DeleteOperation([0], [n2]);
|
||||||
|
|
||||||
|
final operation = transformOperation(dp, ip) as InsertOperation;
|
||||||
|
|
||||||
|
expect(operation.nodes.length, 2);
|
||||||
|
expect(operation.nodes.first.type, 'paragraph');
|
||||||
|
expect(operation.nodes.last.type, 'example');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('transformOperation() a is UpdateOperation', () {
|
||||||
|
final n1 = Node(type: 'paragraph');
|
||||||
|
|
||||||
|
const up = UpdateOperation([0], {'a': 1}, {});
|
||||||
|
final dp = DeleteOperation([0], [n1]);
|
||||||
|
|
||||||
|
final operation = transformOperation(up, dp) as DeleteOperation;
|
||||||
|
|
||||||
|
expect(operation.nodes.length, 1);
|
||||||
|
expect(operation.nodes.first.type, 'paragraph');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('transformOperation() a and b is DeleteOperation', () {
|
||||||
|
final n1 = Node(type: 'paragraph');
|
||||||
|
|
||||||
|
final dp1 = DeleteOperation([1, 0, 1], [n1]);
|
||||||
|
final dp2 = DeleteOperation([1, 0], [n1]);
|
||||||
|
|
||||||
|
final operation = transformOperation(dp1, dp2) as DeleteOperation;
|
||||||
|
|
||||||
|
expect(operation.nodes.length, 1);
|
||||||
|
expect(operation.nodes.first.type, 'paragraph');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,9 @@ void main() async {
|
||||||
|
|
||||||
final historyItem = HistoryItem();
|
final historyItem = HistoryItem();
|
||||||
historyItem.add(DeleteOperation([0], [paragraphNode(text: '0')]));
|
historyItem.add(DeleteOperation([0], [paragraphNode(text: '0')]));
|
||||||
historyItem
|
historyItem.add(
|
||||||
.add(UpdateOperation([0], {'subType': 'number'}, {'subType': null}));
|
const UpdateOperation([0], {'subType': 'number'}, {'subType': null}),
|
||||||
|
);
|
||||||
historyItem.add(DeleteOperation([0], [paragraphNode(), paragraphNode()]));
|
historyItem.add(DeleteOperation([0], [paragraphNode(), paragraphNode()]));
|
||||||
historyItem.add(DeleteOperation([0], [paragraphNode()]));
|
historyItem.add(DeleteOperation([0], [paragraphNode()]));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue