Add tests for PreserveInlineStylesRule and fix link editing. Other minor fixes. (#2058)
* Value setting Stateful toolbar buttons derive from base class * Removed deprecated functions * Move clipboard actions to QuillController * Add: Clipboard toolbar buttons * Translation Justify * Translation alignJustify * Fix: Translation en-US * Misc fixes --------- Co-authored-by: Douglas Ward <dward@scied.com>pull/2060/head v10.0.5
parent
faf8f558a8
commit
42d830f037
5 changed files with 366 additions and 72 deletions
@ -0,0 +1,289 @@ |
||||
import 'package:flutter/services.dart'; |
||||
import 'package:flutter_quill/flutter_quill.dart'; |
||||
import 'package:flutter_quill/quill_delta.dart'; |
||||
import 'package:flutter_quill/src/rules/insert.dart'; |
||||
import 'package:test/test.dart'; |
||||
|
||||
void main() { |
||||
group('PreserveInlineStylesRule', () { |
||||
const rule = PreserveInlineStylesRule(); |
||||
|
||||
test('Data does not apply', () { |
||||
final delta = Delta() |
||||
..insert('data\n') |
||||
..insert('second\n', <String, dynamic>{'bold': true}) |
||||
..insert('\n\nplain\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 1), null); |
||||
expect(rule.apply(document, 0, data: '\n'), null); |
||||
}); |
||||
|
||||
test('Insert in text', () { |
||||
final delta = Delta() |
||||
..insert('data\n') |
||||
..insert('second\n', <String, dynamic>{'bold': true}) |
||||
..insert('\n\nplain\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 1, data: 'X', len: 0), null); |
||||
expect( |
||||
rule.apply(document, 6, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(6) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
expect(rule.apply(document, 16, data: 'X', len: 0), null, |
||||
reason: 'insertion with no attributes'); |
||||
}); |
||||
|
||||
test('Insert at start of line', () { |
||||
final delta = Delta() |
||||
..insert('data\n') |
||||
..insert('second\n', <String, dynamic>{'bold': true}) |
||||
..insert('\n\nplain\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'a', len: 0), null); |
||||
expect( |
||||
rule.apply(document, 5, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(5) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
expect( |
||||
rule.apply(document, 12, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(12) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
expect( |
||||
rule.apply(document, 13, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(13) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
expect(rule.apply(document, 14, data: 'X', len: 0), null, |
||||
reason: 'insertion before "plain" has no attributes'); |
||||
}); |
||||
|
||||
test('Insert on first line of document with bold text', () { |
||||
final delta = Delta()..insert('data\n', <String, dynamic>{'bold': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), |
||||
Delta()..insert('X', <String, dynamic>{'bold': true}), |
||||
reason: 'Insert at document start must pickup style for the line'); |
||||
expect( |
||||
rule.apply(document, 1, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(1) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
}); |
||||
|
||||
test('Insert around image', () { |
||||
final delta = Delta() |
||||
..insert(<String, String>{'image': 'url'}) |
||||
..insert('data\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), null); |
||||
expect(rule.apply(document, 1, data: 'X', len: 0), null); |
||||
}); |
||||
|
||||
test('Insert around image with bold text', () { |
||||
final delta = Delta() |
||||
..insert(<String, String>{'image': 'url'}) |
||||
..insert('data\n', <String, dynamic>{'bold': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), null, |
||||
reason: |
||||
'Insert before image must pickup inline attribute for the image'); |
||||
expect( |
||||
rule.apply(document, 1, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(1) |
||||
..insert('X', <String, dynamic>{'bold': true}), |
||||
reason: |
||||
'Insert after image must pickup style for text following the image'); |
||||
}); |
||||
|
||||
test('Insert around image with inline attribute', () { |
||||
final delta = Delta() |
||||
..insert( |
||||
<String, String>{'image': 'url'}, <String, dynamic>{'bold': true}) |
||||
..insert('data\n', <String, dynamic>{'bold': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), |
||||
Delta()..insert('X', <String, dynamic>{'bold': true}), |
||||
reason: 'Insert before image must pickup style for the image'); |
||||
expect( |
||||
rule.apply(document, 1, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(1) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
}); |
||||
|
||||
test('Replace in text', () { |
||||
final delta = Delta() |
||||
..insert('data\n') |
||||
..insert('second\n', <String, dynamic>{'bold': true}) |
||||
..insert('\n\nplain\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 1), null); |
||||
expect( |
||||
rule.apply(document, 5, data: 'X', len: 1), |
||||
Delta() |
||||
..retain(6) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
}); |
||||
|
||||
test('Insert around multiple images', () { |
||||
final delta = Delta() |
||||
..insert( |
||||
<String, String>{'image': 'url'}, <String, dynamic>{'bold': true}) |
||||
..insert(<String, String>{'image': 'url2'}, |
||||
<String, dynamic>{'italic': true}) |
||||
..insert('data\n', <String, dynamic>{'underline': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), |
||||
Delta()..insert('X', <String, dynamic>{'bold': true})); |
||||
expect( |
||||
rule.apply(document, 1, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(1) |
||||
..insert('X', <String, dynamic>{'italic': true})); |
||||
expect( |
||||
rule.apply(document, 2, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(2) |
||||
..insert('X', <String, dynamic>{'underline': true})); |
||||
}); |
||||
|
||||
test('Insert around mix of text and images', () { |
||||
final delta = Delta() |
||||
..insert( |
||||
<String, String>{'image': 'url'}, <String, dynamic>{'bold': true}) |
||||
..insert('p\n') |
||||
..insert(<String, String>{'image': 'url2'}, |
||||
<String, dynamic>{'italic': true}) |
||||
..insert('data\n', <String, dynamic>{'underline': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect( |
||||
rule.apply(document, 3, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(3) |
||||
..insert('X', <String, dynamic>{'italic': true})); |
||||
}); |
||||
|
||||
test('Insert around images with NL', () { |
||||
final delta = Delta() |
||||
..insert('\n\n\n', <String, dynamic>{'strike': true}) |
||||
..insert( |
||||
<String, String>{'image': 'url'}, <String, dynamic>{'bold': true}) |
||||
..insert('\n\n\n', <String, dynamic>{'strike': true}) |
||||
..insert(<String, String>{'image': 'url2'}, |
||||
<String, dynamic>{'italic': true}) |
||||
..insert('data\n', <String, dynamic>{'underline': true}); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect( |
||||
rule.apply(document, 2, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(2) |
||||
..insert('X', <String, dynamic>{'strike': true})); |
||||
expect( |
||||
rule.apply(document, 6, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(6) |
||||
..insert('X', <String, dynamic>{'strike': true})); |
||||
expect( |
||||
rule.apply(document, 7, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(7) |
||||
..insert('X', <String, dynamic>{'italic': true})); |
||||
}); |
||||
|
||||
test('Exclude non-inline styles', () { |
||||
final delta = Delta()..insert('\n', <String, dynamic>{'list': 'ordered'}); |
||||
final document = Document.fromDelta(delta); |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), null); |
||||
}); |
||||
|
||||
test('Insert around non-inline styles', () { |
||||
final delta = Delta() |
||||
..insert('data\n') |
||||
..insert('first') |
||||
..insert('\n', <String, dynamic>{'list': 'ordered'}) |
||||
..insert('A', <String, dynamic>{'bold': true}) |
||||
..insert('B') |
||||
..insert('C', <String, dynamic>{'italic': true}) |
||||
..insert('\n\n', <String, dynamic>{'list': 'ordered'}) |
||||
..insert('D', <String, dynamic>{'strike': true}) |
||||
..insert('\n', <String, dynamic>{'list': 'ordered'}) |
||||
..insert( |
||||
<String, String>{'image': 'url'}, <String, dynamic>{'bold': true}) |
||||
..insert('\n', <String, dynamic>{'list': 'ordered'}) |
||||
..insert(' plain\n'); |
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), null); |
||||
expect(rule.apply(document, 5, data: 'X', len: 0), null, |
||||
reason: '1. plain text'); |
||||
expect( |
||||
rule.apply(document, 11, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(11) |
||||
..insert('X', <String, dynamic>{'bold': true}), |
||||
reason: '2. bold text at start'); |
||||
expect( |
||||
rule.apply(document, 15, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(15) |
||||
..insert('X', <String, dynamic>{'italic': true}), |
||||
reason: '3. blank entry gets style from end of previous line'); |
||||
expect( |
||||
rule.apply(document, 16, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(16) |
||||
..insert('X', <String, dynamic>{'strike': true}), |
||||
reason: '4. strike text'); |
||||
expect( |
||||
rule.apply(document, 18, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(18) |
||||
..insert('X', <String, dynamic>{'bold': true}), |
||||
reason: '5. bold image'); |
||||
expect(rule.apply(document, 20, data: 'X', len: 0), null); |
||||
// |
||||
expect(rule.apply(document, 16, data: LogicalKeyboardKey.enter, len: 0), |
||||
null); |
||||
}); |
||||
|
||||
test('Insert around link, insert within link label', () { |
||||
final delta = Delta() |
||||
..insert(<String, String>{'image': 'imageUrl'}, |
||||
<String, dynamic>{'link': 'linkURL'}) |
||||
..insert('data\n') |
||||
..insert('link', <String, dynamic>{'link': 'linkURL', 'bold': true}) |
||||
..insert('\n'); |
||||
|
||||
final document = Document.fromDelta(delta); |
||||
// |
||||
expect(rule.apply(document, 0, data: 'X', len: 0), Delta()..insert('X')); |
||||
expect(rule.apply(document, 1, data: 'X', len: 0), null); |
||||
expect( |
||||
rule.apply(document, 6, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(6) |
||||
..insert('X', <String, dynamic>{'bold': true})); |
||||
expect( |
||||
rule.apply(document, 7, data: 'X', len: 0), |
||||
Delta() |
||||
..retain(7) |
||||
..insert('X', <String, dynamic>{'link': 'linkURL', 'bold': true}), |
||||
reason: 'Insertion within link label updates label'); |
||||
}); |
||||
}); |
||||
} |
Loading…
Reference in new issue