|
|
|
import 'dart:convert' show jsonDecode;
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter_quill/flutter_quill.dart';
|
|
|
|
import 'package:flutter_quill/flutter_quill_test.dart';
|
|
|
|
import 'package:flutter_quill/src/widgets/raw_editor.dart';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
late QuillController controller;
|
|
|
|
var didCopy = false;
|
|
|
|
|
|
|
|
setUp(() {
|
|
|
|
controller = QuillController.basic();
|
|
|
|
});
|
|
|
|
|
|
|
|
tearDown(() {
|
|
|
|
controller.dispose();
|
|
|
|
});
|
|
|
|
|
|
|
|
group('QuillEditor', () {
|
|
|
|
testWidgets('Keyboard entered text is stored in document', (tester) async {
|
|
|
|
await tester.pumpWidget(
|
|
|
|
MaterialApp(
|
|
|
|
home: QuillEditor.basic(controller: controller, readOnly: false),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
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(
|
|
|
|
home: QuillEditor(
|
|
|
|
controller: controller,
|
|
|
|
focusNode: FocusNode(),
|
|
|
|
scrollController: ScrollController(),
|
|
|
|
scrollable: true,
|
|
|
|
padding: const EdgeInsets.all(0),
|
|
|
|
autoFocus: true,
|
|
|
|
readOnly: false,
|
|
|
|
expands: true,
|
|
|
|
contentInsertionConfiguration: ContentInsertionConfiguration(
|
|
|
|
onContentInserted: (content) {
|
|
|
|
latestUri = content.uri;
|
|
|
|
},
|
|
|
|
allowedMimeTypes: const <String>['image/gif'],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
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));
|
|
|
|
});
|
|
|
|
|
|
|
|
Widget customBuilder(BuildContext context, RawEditorState state) {
|
|
|
|
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 {
|
|
|
|
await tester.pumpWidget(MaterialApp(
|
|
|
|
home: QuillEditor(
|
|
|
|
controller: controller,
|
|
|
|
focusNode: FocusNode(),
|
|
|
|
scrollController: ScrollController(),
|
|
|
|
scrollable: true,
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
autoFocus: true,
|
|
|
|
readOnly: false,
|
|
|
|
expands: true,
|
|
|
|
contextMenuBuilder: customBuilder,
|
|
|
|
),
|
|
|
|
));
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|