dartlangeditorflutterflutter-appsflutter-examplesflutter-packageflutter-widgetquillquill-deltaquilljsreactquillrich-textrich-text-editorwysiwygwysiwyg-editor
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.
220 lines
6.3 KiB
220 lines
6.3 KiB
2 years ago
|
import 'dart:convert' show jsonDecode;
|
||
|
|
||
|
import 'package:flutter/material.dart';
|
||
|
import 'package:flutter/services.dart';
|
||
|
import 'package:flutter_quill/flutter_quill.dart';
|
||
10 months ago
|
import 'package:flutter_quill/translations.dart';
|
||
1 year ago
|
import 'package:flutter_quill_test/flutter_quill_test.dart';
|
||
2 years ago
|
import 'package:flutter_test/flutter_test.dart';
|
||
|
|
||
|
void main() {
|
||
|
late QuillController controller;
|
||
2 years ago
|
var didCopy = false;
|
||
2 years ago
|
|
||
|
setUp(() {
|
||
|
controller = QuillController.basic();
|
||
|
});
|
||
|
|
||
|
tearDown(() {
|
||
|
controller.dispose();
|
||
|
});
|
||
|
|
||
|
group('QuillEditor', () {
|
||
|
testWidgets('Keyboard entered text is stored in document', (tester) async {
|
||
|
await tester.pumpWidget(
|
||
1 year ago
|
MaterialApp(
|
||
|
home: QuillEditor.basic(
|
||
|
// ignore: avoid_redundant_argument_values
|
||
|
configurations: QuillEditorConfigurations(
|
||
|
controller: controller,
|
||
2 years ago
|
// ignore: avoid_redundant_argument_values
|
||
|
),
|
||
2 years ago
|
),
|
||
2 years ago
|
),
|
||
|
);
|
||
|
await tester.quillEnterText(find.byType(QuillEditor), 'test\n');
|
||
|
|
||
|
expect(controller.document.toPlainText(), 'test\n');
|
||
|
});
|
||
|
|
||
|
testWidgets('insertContent is handled correctly', (tester) async {
|
||
|
String? latestUri;
|
||
|
await tester.pumpWidget(
|
||
|
MaterialApp(
|
||
1 year ago
|
home: QuillEditor(
|
||
|
focusNode: FocusNode(),
|
||
|
scrollController: ScrollController(),
|
||
|
configurations: QuillEditorConfigurations(
|
||
2 years ago
|
controller: controller,
|
||
1 year ago
|
// ignore: avoid_redundant_argument_values
|
||
|
autoFocus: true,
|
||
|
expands: true,
|
||
|
contentInsertionConfiguration: ContentInsertionConfiguration(
|
||
|
onContentInserted: (content) {
|
||
|
latestUri = content.uri;
|
||
|
},
|
||
|
allowedMimeTypes: <String>['image/gif'],
|
||
2 years ago
|
),
|
||
2 years ago
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
await tester.tap(find.byType(QuillEditor));
|
||
|
await tester.quillEnterText(find.byType(QuillEditor), 'test\n');
|
||
|
await tester.idle();
|
||
|
|
||
|
const uri =
|
||
|
'content://com.google.android.inputmethod.latin.fileprovider/test.gif';
|
||
|
final messageBytes =
|
||
|
const JSONMessageCodec().encodeMessage(<String, dynamic>{
|
||
|
'args': <dynamic>[
|
||
|
-1,
|
||
|
'TextInputAction.commitContent',
|
||
|
jsonDecode(
|
||
|
'{"mimeType": "image/gif", "data": [0,1,0,1,0,1,0,0,0], "uri": "$uri"}'),
|
||
|
],
|
||
|
'method': 'TextInputClient.performAction',
|
||
|
});
|
||
|
|
||
|
Object? error;
|
||
|
try {
|
||
|
await tester.binding.defaultBinaryMessenger
|
||
|
.handlePlatformMessage('flutter/textinput', messageBytes, (_) {});
|
||
|
} catch (e) {
|
||
|
error = e;
|
||
|
}
|
||
|
expect(error, isNull);
|
||
|
expect(latestUri, equals(uri));
|
||
|
});
|
||
2 years ago
|
|
||
1 year ago
|
Widget customBuilder(BuildContext context, QuillRawEditorState state) {
|
||
2 years ago
|
return AdaptiveTextSelectionToolbar(
|
||
|
anchors: state.contextMenuAnchors,
|
||
|
children: [
|
||
|
Container(
|
||
|
height: 50,
|
||
|
color: Colors.white,
|
||
|
child: Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
|
children: [
|
||
|
IconButton(
|
||
|
onPressed: () {
|
||
|
didCopy = true;
|
||
|
},
|
||
|
icon: const Icon(Icons.copy),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
}
|
||
|
|
||
|
testWidgets('custom context menu builder', (tester) async {
|
||
2 years ago
|
await tester.pumpWidget(
|
||
|
MaterialApp(
|
||
1 year ago
|
home: QuillEditor(
|
||
|
focusNode: FocusNode(),
|
||
|
scrollController: ScrollController(),
|
||
|
// ignore: avoid_redundant_argument_values
|
||
|
configurations: QuillEditorConfigurations(
|
||
2 years ago
|
controller: controller,
|
||
2 years ago
|
// ignore: avoid_redundant_argument_values
|
||
1 year ago
|
autoFocus: true,
|
||
|
expands: true,
|
||
|
contextMenuBuilder: customBuilder,
|
||
2 years ago
|
),
|
||
|
),
|
||
2 years ago
|
),
|
||
2 years ago
|
);
|
||
2 years ago
|
|
||
|
// Long press to show menu
|
||
|
await tester.longPress(find.byType(QuillEditor));
|
||
|
await tester.pumpAndSettle();
|
||
|
|
||
|
// Verify custom widget shows
|
||
|
expect(find.byIcon(Icons.copy), findsOneWidget);
|
||
|
|
||
|
await tester.tap(find.byIcon(Icons.copy));
|
||
|
expect(didCopy, isTrue);
|
||
|
});
|
||
10 months ago
|
|
||
|
testWidgets(
|
||
|
'make sure QuillEditorOpenSearchAction does not throw an exception',
|
||
|
(tester) async {
|
||
|
final editorFocusNode = FocusNode();
|
||
|
await tester.pumpWidget(
|
||
|
MaterialApp(
|
||
|
home: QuillEditor.basic(
|
||
|
configurations: QuillEditorConfigurations(controller: controller),
|
||
|
focusNode: editorFocusNode,
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
// Required, otherwise the action shortcuts won't be invoked.
|
||
|
editorFocusNode.requestFocus();
|
||
|
|
||
|
await tester.sendKeyDownEvent(LogicalKeyboardKey.control);
|
||
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyF);
|
||
|
await tester.sendKeyUpEvent(LogicalKeyboardKey.control);
|
||
|
|
||
|
await tester.pump();
|
||
|
|
||
|
final exception = tester.takeException();
|
||
|
expect(
|
||
|
exception,
|
||
|
isNot(
|
||
|
isInstanceOf<MissingFlutterQuillLocalizationException>(),
|
||
|
),
|
||
|
);
|
||
|
|
||
|
expect(exception, isNull);
|
||
|
},
|
||
|
);
|
||
|
|
||
|
testWidgets(
|
||
10 months ago
|
'should throw MissingFlutterQuillLocalizationException if the delegate not provided',
|
||
10 months ago
|
(tester) async {
|
||
|
await tester.pumpWidget(
|
||
|
MaterialApp(
|
||
|
home: Builder(
|
||
|
builder: (context) => Text(context.loc.font),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
|
||
|
final exception = tester.takeException();
|
||
|
|
||
|
expect(exception, isNotNull);
|
||
|
expect(
|
||
|
exception,
|
||
|
isA<MissingFlutterQuillLocalizationException>(),
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
|
||
|
testWidgets(
|
||
10 months ago
|
'should not throw MissingFlutterQuillLocalizationException if the delegate is provided',
|
||
10 months ago
|
(tester) async {
|
||
|
await tester.pumpWidget(
|
||
|
MaterialApp(
|
||
|
home: FlutterQuillLocalizationsWidget(
|
||
|
child: Builder(
|
||
|
builder: (context) => Text(context.loc.font),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
|
||
|
final exception = tester.takeException();
|
||
|
|
||
|
expect(exception, isNull);
|
||
|
expect(
|
||
|
exception,
|
||
|
isNot(isA<MissingFlutterQuillLocalizationException>()),
|
||
|
);
|
||
|
},
|
||
|
);
|
||
2 years ago
|
});
|
||
|
}
|