Rich text editor for Flutter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

190 lines
7.4 KiB

import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill/quill_delta.dart';
import 'package:test/test.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
group('copy', () {
const testDocumentContents = 'data';
late QuillController controller;
setUp(() {
controller = QuillController.basic()
..compose(Delta()..insert(testDocumentContents),
const TextSelection.collapsed(offset: 0), ChangeSource.local);
});
test('clipboardSelection empty', () {
expect(controller.clipboardSelection(true), false,
reason: 'No effect when no selection');
expect(controller.clipboardSelection(false), false);
});
test('clipboardSelection', () {
controller
..replaceText(0, 4, 'bold plain italic', null)
..formatText(0, 4, Attribute.bold)
..formatText(11, 17, Attribute.italic)
..updateSelection(const TextSelection(baseOffset: 2, extentOffset: 14),
ChangeSource.local);
//
expect(controller.clipboardSelection(true), true);
expect(controller.document.length, 18,
reason: 'Copy does not change the document');
expect(controller.clipboardSelection(false), true);
expect(controller.document.length, 6, reason: 'Cut changes the document');
//
controller
..readOnly = true
..updateSelection(const TextSelection(baseOffset: 2, extentOffset: 4),
ChangeSource.local);
expect(controller.selection.isCollapsed, false);
expect(controller.clipboardSelection(true), true);
expect(controller.document.length, 6);
expect(controller.clipboardSelection(false), false);
expect(controller.document.length, 6,
reason: 'Cut not permitted on readOnly document');
});
});
group('paste', () {
test('Plain', () async {
final controller = QuillController.basic()
..compose(Delta()..insert('[]'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(
const TextSelection.collapsed(offset: 1), ChangeSource.local);
//
expect(controller.document.toPlainText(), '[]\n');
expect(controller.pasteUsingPlainOrDelta('insert'), true);
expect(controller.document.toPlainText(), '[insert]\n');
});
test('Plain lines', () async {
final controller = QuillController.basic()
..compose(Delta()..insert('[]'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(
const TextSelection.collapsed(offset: 1), ChangeSource.local);
//
expect(controller.document.toPlainText(), '[]\n');
expect(controller.pasteUsingPlainOrDelta('1\n2\n3\n'), true);
expect(controller.document.toPlainText(), '[1\n2\n3\n]\n');
});
test('Paste from external', () async {
final source = QuillController.basic()
..compose(Delta()..insert('Plain text'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(const TextSelection(baseOffset: 4, extentOffset: 8),
ChangeSource.local);
assert(source.clipboardSelection(true));
expect(source.pastePlainText, 'n te');
//
final controller = QuillController.basic()
..compose(Delta()..insert('[]'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(
const TextSelection.collapsed(offset: 1), ChangeSource.local);
//
expect(controller.pasteUsingPlainOrDelta('insert'), true,
reason: 'External paste');
expect(controller.document.toPlainText(), '[insert]\n');
});
test('Delta simple', () async {
final source = QuillController.basic()
..compose(Delta()..insert('Plain text'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..formatText(6, 8, Attribute.bold)
..updateSelection(const TextSelection(baseOffset: 4, extentOffset: 8),
ChangeSource.local);
assert(source.clipboardSelection(true));
expect(source.pastePlainText, 'n te');
expect(
source.pasteDelta,
Delta()
..insert('n ')
..insert('te', {'bold': true}));
//
final controller = QuillController.basic()
..compose(Delta()..insert('[]'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(
const TextSelection.collapsed(offset: 1), ChangeSource.local);
//
expect(controller.pasteUsingPlainOrDelta('n te'), true,
reason: 'Internal paste');
expect(controller.document.toPlainText(), '[n te]\n');
expect(
controller.document.toDelta(),
Delta()
..insert('[n ')
..insert('te', {'bold': true})
..insert(']\n'));
expect(controller.selection, const TextSelection.collapsed(offset: 5));
});
test('Delta multi line', () async {
const blockAttribute = Attribute.ol;
const plainSelection = 'BC\nDEF\nGHI\nJK';
final source = QuillController.basic()
..compose(Delta()..insert('ABC\nDEF\nGHI\nJKL'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..formatText(1, 1, Attribute.underline) // ABC with B underlined
..formatText(4, 0, blockAttribute) // 1. DEF with E in italic
..formatText(5, 1, Attribute.italic)
..formatText(8, 0, blockAttribute) // 2. GHI with H as inline code
..formatText(9, 1, Attribute.inlineCode)
..formatText(13, 1, Attribute.strikeThrough) // JKL with K strikethrough
..updateSelection(const TextSelection(baseOffset: 1, extentOffset: 14),
ChangeSource.local);
//
assert(source.clipboardSelection(true));
expect(source.pastePlainText, plainSelection);
expect(
source.pasteDelta,
Delta()
..insert('B', {'underline': true})
..insert('C\nD')
..insert('E', {'italic': true})
..insert('F')
..insert('\n', {'list': 'ordered'})
..insert('G')
..insert('H', {'code': true})
..insert('I')
..insert('\n', {'list': 'ordered'})
..insert('J')
..insert('K', {'strike': true}));
//
final controller = QuillController.basic()
..compose(Delta()..insert('[]'),
const TextSelection.collapsed(offset: 0), ChangeSource.local)
..updateSelection(
const TextSelection.collapsed(offset: 1), ChangeSource.local);
//
expect(controller.pasteUsingPlainOrDelta(plainSelection), true,
reason: 'Internal paste');
expect(controller.document.toPlainText(), '[$plainSelection]\n');
expect(
controller.document.toDelta(),
Delta()
..insert('[')
..insert('B', {'underline': true})
..insert('C\nD')
..insert('E', {'italic': true})
..insert('F')
..insert('\n', {'list': 'ordered'})
..insert('G')
..insert('H', {'code': true})
..insert('I')
..insert('\n', {'list': 'ordered'})
..insert('J')
..insert('K', {'strike': true})
..insert(']\n'));
expect(controller.selection, const TextSelection.collapsed(offset: 14));
});
});
}