From 89a3f361f46ea4941b65bcef284c216a04dc3e10 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:36:28 -0400 Subject: [PATCH 1/8] Duplicate from platform interface --- .../lib/method_channel_image_picker.dart | 298 ++++ .../new_method_channel_image_picker_test.dart | 1261 +++++++++++++++++ 2 files changed, 1559 insertions(+) create mode 100644 packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart create mode 100644 packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart diff --git a/packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart b/packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart new file mode 100644 index 000000000000..ba5d60d7a677 --- /dev/null +++ b/packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart @@ -0,0 +1,298 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; + +const MethodChannel _channel = MethodChannel('plugins.flutter.io/image_picker'); + +/// An implementation of [ImagePickerPlatform] that uses method channels. +class MethodChannelImagePicker extends ImagePickerPlatform { + /// The MethodChannel that is being used by this implementation of the plugin. + @visibleForTesting + MethodChannel get channel => _channel; + + @override + Future pickImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + }) async { + final String? path = await _getImagePath( + source: source, + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + preferredCameraDevice: preferredCameraDevice, + ); + return path != null ? PickedFile(path) : null; + } + + @override + Future?> pickMultiImage({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + }) async { + final List? paths = await _getMultiImagePath( + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + ); + if (paths == null) { + return null; + } + + return paths.map((dynamic path) => PickedFile(path as String)).toList(); + } + + Future?> _getMultiImagePath({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + }) { + if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) { + throw ArgumentError.value( + imageQuality, 'imageQuality', 'must be between 0 and 100'); + } + + if (maxWidth != null && maxWidth < 0) { + throw ArgumentError.value(maxWidth, 'maxWidth', 'cannot be negative'); + } + + if (maxHeight != null && maxHeight < 0) { + throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative'); + } + + return _channel.invokeMethod?>( + 'pickMultiImage', + { + 'maxWidth': maxWidth, + 'maxHeight': maxHeight, + 'imageQuality': imageQuality, + }, + ); + } + + Future _getImagePath({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + bool requestFullMetadata = true, + }) { + if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) { + throw ArgumentError.value( + imageQuality, 'imageQuality', 'must be between 0 and 100'); + } + + if (maxWidth != null && maxWidth < 0) { + throw ArgumentError.value(maxWidth, 'maxWidth', 'cannot be negative'); + } + + if (maxHeight != null && maxHeight < 0) { + throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative'); + } + + return _channel.invokeMethod( + 'pickImage', + { + 'source': source.index, + 'maxWidth': maxWidth, + 'maxHeight': maxHeight, + 'imageQuality': imageQuality, + 'cameraDevice': preferredCameraDevice.index, + 'requestFullMetadata': requestFullMetadata, + }, + ); + } + + @override + Future pickVideo({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }) async { + final String? path = await _getVideoPath( + source: source, + maxDuration: maxDuration, + preferredCameraDevice: preferredCameraDevice, + ); + return path != null ? PickedFile(path) : null; + } + + Future _getVideoPath({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }) { + return _channel.invokeMethod( + 'pickVideo', + { + 'source': source.index, + 'maxDuration': maxDuration?.inSeconds, + 'cameraDevice': preferredCameraDevice.index + }, + ); + } + + @override + Future retrieveLostData() async { + final Map? result = + await _channel.invokeMapMethod('retrieve'); + + if (result == null) { + return LostData.empty(); + } + + assert(result.containsKey('path') != result.containsKey('errorCode')); + + final String? type = result['type'] as String?; + assert(type == kTypeImage || type == kTypeVideo); + + RetrieveType? retrieveType; + if (type == kTypeImage) { + retrieveType = RetrieveType.image; + } else if (type == kTypeVideo) { + retrieveType = RetrieveType.video; + } + + PlatformException? exception; + if (result.containsKey('errorCode')) { + exception = PlatformException( + code: result['errorCode']! as String, + message: result['errorMessage'] as String?); + } + + final String? path = result['path'] as String?; + + return LostData( + file: path != null ? PickedFile(path) : null, + exception: exception, + type: retrieveType, + ); + } + + @override + Future getImage({ + required ImageSource source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + CameraDevice preferredCameraDevice = CameraDevice.rear, + }) async { + final String? path = await _getImagePath( + source: source, + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + preferredCameraDevice: preferredCameraDevice, + ); + return path != null ? XFile(path) : null; + } + + @override + Future getImageFromSource({ + required ImageSource source, + ImagePickerOptions options = const ImagePickerOptions(), + }) async { + final String? path = await _getImagePath( + source: source, + maxHeight: options.maxHeight, + maxWidth: options.maxWidth, + imageQuality: options.imageQuality, + preferredCameraDevice: options.preferredCameraDevice, + requestFullMetadata: options.requestFullMetadata, + ); + return path != null ? XFile(path) : null; + } + + @override + Future?> getMultiImage({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + }) async { + final List? paths = await _getMultiImagePath( + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: imageQuality, + ); + if (paths == null) { + return null; + } + + return paths.map((dynamic path) => XFile(path as String)).toList(); + } + + @override + Future getVideo({ + required ImageSource source, + CameraDevice preferredCameraDevice = CameraDevice.rear, + Duration? maxDuration, + }) async { + final String? path = await _getVideoPath( + source: source, + maxDuration: maxDuration, + preferredCameraDevice: preferredCameraDevice, + ); + return path != null ? XFile(path) : null; + } + + @override + Future getLostData() async { + List? pickedFileList; + + final Map? result = + await _channel.invokeMapMethod('retrieve'); + + if (result == null) { + return LostDataResponse.empty(); + } + + assert(result.containsKey('path') != result.containsKey('errorCode')); + + final String? type = result['type'] as String?; + assert(type == kTypeImage || type == kTypeVideo); + + RetrieveType? retrieveType; + if (type == kTypeImage) { + retrieveType = RetrieveType.image; + } else if (type == kTypeVideo) { + retrieveType = RetrieveType.video; + } + + PlatformException? exception; + if (result.containsKey('errorCode')) { + exception = PlatformException( + code: result['errorCode']! as String, + message: result['errorMessage'] as String?); + } + + final String? path = result['path'] as String?; + + final List? pathList = + (result['pathList'] as List?)?.cast(); + if (pathList != null) { + pickedFileList = []; + for (final String path in pathList) { + pickedFileList.add(XFile(path)); + } + } + + return LostDataResponse( + file: path != null ? XFile(path) : null, + exception: exception, + type: retrieveType, + files: pickedFileList, + ); + } +} diff --git a/packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart b/packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart new file mode 100644 index 000000000000..72ed363ef7ae --- /dev/null +++ b/packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart @@ -0,0 +1,1261 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$MethodChannelImagePicker', () { + final MethodChannelImagePicker picker = MethodChannelImagePicker(); + + final List log = []; + dynamic returnValue = ''; + + setUp(() { + returnValue = ''; + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + return returnValue; + }); + + log.clear(); + }); + + group('#pickImage', () { + test('passes the image source argument correctly', () async { + await picker.pickImage(source: ImageSource.camera); + await picker.pickImage(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('passes the width and height arguments correctly', () async { + await picker.pickImage(source: ImageSource.camera); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxHeight: 10.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.pickImage( + source: ImageSource.camera, + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.pickImage(imageQuality: -1, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => + picker.pickImage(imageQuality: 101, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(imageQuality: -1, source: ImageSource.camera), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(imageQuality: 101, source: ImageSource.camera), + throwsArgumentError, + ); + }); + + test('does not accept a negative width or height argument', () { + expect( + () => picker.pickImage(source: ImageSource.camera, maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(source: ImageSource.camera, maxHeight: -1.0), + throwsArgumentError, + ); + }); + + test('handles a null image path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.pickImage(source: ImageSource.gallery), isNull); + expect(await picker.pickImage(source: ImageSource.camera), isNull); + }); + + test('camera position defaults to back', () async { + await picker.pickImage(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('camera position can set to front', () async { + await picker.pickImage( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); + }); + + group('#pickMultiImage', () { + test('calls the method correctly', () async { + returnValue = ['0', '1']; + await picker.pickMultiImage(); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + ], + ); + }); + + test('passes the width and height arguments correctly', () async { + returnValue = ['0', '1']; + await picker.pickMultiImage(); + await picker.pickMultiImage( + maxWidth: 10.0, + ); + await picker.pickMultiImage( + maxHeight: 10.0, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.pickMultiImage( + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + }), + ], + ); + }); + + test('does not accept a negative width or height argument', () { + returnValue = ['0', '1']; + expect( + () => picker.pickMultiImage(maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.pickMultiImage(maxHeight: -1.0), + throwsArgumentError, + ); + }); + + test('does not accept an invalid imageQuality argument', () { + returnValue = ['0', '1']; + expect( + () => picker.pickMultiImage(imageQuality: -1), + throwsArgumentError, + ); + + expect( + () => picker.pickMultiImage(imageQuality: 101), + throwsArgumentError, + ); + }); + + test('handles a null image path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.pickMultiImage(), isNull); + expect(await picker.pickMultiImage(), isNull); + }); + }); + + group('#pickVideo', () { + test('passes the image source argument correctly', () async { + await picker.pickVideo(source: ImageSource.camera); + await picker.pickVideo(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + isMethodCall('pickVideo', arguments: { + 'source': 1, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); + + test('passes the duration argument correctly', () async { + await picker.pickVideo(source: ImageSource.camera); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(seconds: 10), + ); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(minutes: 1), + ); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(hours: 1), + ); + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 10, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 60, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 3600, + 'cameraDevice': 0, + }), + ], + ); + }); + + test('handles a null video path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.pickVideo(source: ImageSource.gallery), isNull); + expect(await picker.pickVideo(source: ImageSource.camera), isNull); + }); + + test('camera position defaults to back', () async { + await picker.pickVideo(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); + + test('camera position can set to front', () async { + await picker.pickVideo( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front, + ); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 1, + }), + ], + ); + }); + }); + + group('#retrieveLostData', () { + test('retrieveLostData get success response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path', + }; + }); + final LostData response = await picker.retrieveLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path'); + }); + + test('retrieveLostData get error response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + }; + }); + final LostData response = await picker.retrieveLostData(); + expect(response.type, RetrieveType.video); + expect(response.exception, isNotNull); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); + }); + + test('retrieveLostData get null response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return null; + }); + expect((await picker.retrieveLostData()).isEmpty, true); + }); + + test('retrieveLostData get both path and error should throw', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + 'path': '/example/path', + }; + }); + expect(picker.retrieveLostData(), throwsAssertionError); + }); + }); + + group('#getImage', () { + test('passes the image source argument correctly', () async { + await picker.getImage(source: ImageSource.camera); + await picker.getImage(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('passes the width and height arguments correctly', () async { + await picker.getImage(source: ImageSource.camera); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxHeight: 10.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.getImage( + source: ImageSource.camera, + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.getImage(imageQuality: -1, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: 101, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: -1, source: ImageSource.camera), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: 101, source: ImageSource.camera), + throwsArgumentError, + ); + }); + + test('does not accept a negative width or height argument', () { + expect( + () => picker.getImage(source: ImageSource.camera, maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.getImage(source: ImageSource.camera, maxHeight: -1.0), + throwsArgumentError, + ); + }); + + test('handles a null image path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.getImage(source: ImageSource.gallery), isNull); + expect(await picker.getImage(source: ImageSource.camera), isNull); + }); + + test('camera position defaults to back', () async { + await picker.getImage(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('camera position can set to front', () async { + await picker.getImage( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); + }); + + group('#getMultiImage', () { + test('calls the method correctly', () async { + returnValue = ['0', '1']; + await picker.getMultiImage(); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + ], + ); + }); + + test('passes the width and height arguments correctly', () async { + returnValue = ['0', '1']; + await picker.getMultiImage(); + await picker.getMultiImage( + maxWidth: 10.0, + ); + await picker.getMultiImage( + maxHeight: 10.0, + ); + await picker.getMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.getMultiImage( + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.getMultiImage( + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.getMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + }), + ], + ); + }); + + test('does not accept a negative width or height argument', () { + returnValue = ['0', '1']; + expect( + () => picker.getMultiImage(maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.getMultiImage(maxHeight: -1.0), + throwsArgumentError, + ); + }); + + test('does not accept an invalid imageQuality argument', () { + returnValue = ['0', '1']; + expect( + () => picker.getMultiImage(imageQuality: -1), + throwsArgumentError, + ); + + expect( + () => picker.getMultiImage(imageQuality: 101), + throwsArgumentError, + ); + }); + + test('handles a null image path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.getMultiImage(), isNull); + expect(await picker.getMultiImage(), isNull); + }); + }); + + group('#getVideo', () { + test('passes the image source argument correctly', () async { + await picker.getVideo(source: ImageSource.camera); + await picker.getVideo(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + isMethodCall('pickVideo', arguments: { + 'source': 1, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); + + test('passes the duration argument correctly', () async { + await picker.getVideo(source: ImageSource.camera); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(seconds: 10), + ); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(minutes: 1), + ); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(hours: 1), + ); + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 10, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 60, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 3600, + 'cameraDevice': 0, + }), + ], + ); + }); + + test('handles a null video path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.getVideo(source: ImageSource.gallery), isNull); + expect(await picker.getVideo(source: ImageSource.camera), isNull); + }); + + test('camera position defaults to back', () async { + await picker.getVideo(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); + + test('camera position can set to front', () async { + await picker.getVideo( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front, + ); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 1, + }), + ], + ); + }); + }); + + group('#getLostData', () { + test('getLostData get success response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path', + }; + }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path'); + }); + + test('getLostData should successfully retrieve multiple files', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path1', + 'pathList': ['/example/path0', '/example/path1'], + }; + }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path1'); + expect(response.files!.first.path, '/example/path0'); + expect(response.files!.length, 2); + }); + + test('getLostData get error response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + }; + }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.video); + expect(response.exception, isNotNull); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); + }); + + test('getLostData get null response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return null; + }); + expect((await picker.getLostData()).isEmpty, true); + }); + + test('getLostData get both path and error should throw', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + 'path': '/example/path', + }; + }); + expect(picker.getLostData(), throwsAssertionError); + }); + }); + + group('#getImageFromSource', () { + test('passes the image source argument correctly', () async { + await picker.getImageFromSource(source: ImageSource.camera); + await picker.getImageFromSource(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('passes the width and height arguments correctly', () async { + await picker.getImageFromSource(source: ImageSource.camera); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxWidth: 10.0), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxHeight: 10.0), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + maxHeight: 20.0, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + imageQuality: 70, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxHeight: 10.0, + imageQuality: 70, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.getImageFromSource( + source: ImageSource.gallery, + options: const ImagePickerOptions(imageQuality: -1), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( + source: ImageSource.gallery, + options: const ImagePickerOptions(imageQuality: 101), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(imageQuality: -1), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(imageQuality: 101), + ), + throwsArgumentError, + ); + }); + + test('does not accept a negative width or height argument', () { + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxWidth: -1.0), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxHeight: -1.0), + ), + throwsArgumentError, + ); + }); + + test('handles a null image path response gracefully', () async { + picker.channel + .setMockMethodCallHandler((MethodCall methodCall) => null); + + expect(await picker.getImageFromSource(source: ImageSource.gallery), + isNull); + expect(await picker.getImageFromSource(source: ImageSource.camera), + isNull); + }); + + test('camera position defaults to back', () async { + await picker.getImageFromSource(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('camera position can set to front', () async { + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + preferredCameraDevice: CameraDevice.front, + ), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); + + test('passes the full metadata argument correctly', () async { + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(requestFullMetadata: false), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': false, + }), + ], + ); + }); + }); + }); +} From 696ee1f0e581cd0741397ce2edb19d9b66a252a9 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:38:17 -0400 Subject: [PATCH 2/8] Rename files, fix includes --- ..._channel_image_picker.dart => image_picker_android.dart} | 4 ++-- ...mage_picker_test.dart => image_picker_android_test.dart} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename packages/image_picker/image_picker_android/lib/{method_channel_image_picker.dart => image_picker_android.dart} (98%) rename packages/image_picker/image_picker_android/test/{new_method_channel_image_picker_test.dart => image_picker_android_test.dart} (99%) diff --git a/packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart b/packages/image_picker/image_picker_android/lib/image_picker_android.dart similarity index 98% rename from packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart rename to packages/image_picker/image_picker_android/lib/image_picker_android.dart index ba5d60d7a677..f4dea4246734 100644 --- a/packages/image_picker/image_picker_android/lib/method_channel_image_picker.dart +++ b/packages/image_picker/image_picker_android/lib/image_picker_android.dart @@ -11,8 +11,8 @@ import 'package:image_picker_platform_interface/image_picker_platform_interface. const MethodChannel _channel = MethodChannel('plugins.flutter.io/image_picker'); -/// An implementation of [ImagePickerPlatform] that uses method channels. -class MethodChannelImagePicker extends ImagePickerPlatform { +/// An Android implementation of [ImagePickerPlatform]. +class ImagePickerAndroid extends ImagePickerPlatform { /// The MethodChannel that is being used by this implementation of the plugin. @visibleForTesting MethodChannel get channel => _channel; diff --git a/packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart similarity index 99% rename from packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart rename to packages/image_picker/image_picker_android/test/image_picker_android_test.dart index 72ed363ef7ae..d3155714beb9 100644 --- a/packages/image_picker/image_picker_android/test/new_method_channel_image_picker_test.dart +++ b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart @@ -5,14 +5,14 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:image_picker_android/image_picker_android.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; -import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group('$MethodChannelImagePicker', () { - final MethodChannelImagePicker picker = MethodChannelImagePicker(); + group('ImagePickerAndroid', () { + final ImagePickerAndroid picker = ImagePickerAndroid(); final List log = []; dynamic returnValue = ''; From be0771aaadd2338f46198638406b7ff830d96a38 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:38:44 -0400 Subject: [PATCH 3/8] Remove unnecessary group from test --- .../test/image_picker_android_test.dart | 2314 ++++++++--------- 1 file changed, 1152 insertions(+), 1162 deletions(-) diff --git a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart index d3155714beb9..b01c3f8b8c87 100644 --- a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart +++ b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart @@ -11,1251 +11,1241 @@ import 'package:image_picker_platform_interface/image_picker_platform_interface. void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group('ImagePickerAndroid', () { - final ImagePickerAndroid picker = ImagePickerAndroid(); + final ImagePickerAndroid picker = ImagePickerAndroid(); - final List log = []; - dynamic returnValue = ''; + final List log = []; + dynamic returnValue = ''; - setUp(() { - returnValue = ''; - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - return returnValue; - }); + setUp(() { + returnValue = ''; + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + return returnValue; + }); - log.clear(); + log.clear(); + }); + + group('#pickImage', () { + test('passes the image source argument correctly', () async { + await picker.pickImage(source: ImageSource.camera); + await picker.pickImage(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); }); - group('#pickImage', () { - test('passes the image source argument correctly', () async { - await picker.pickImage(source: ImageSource.camera); - await picker.pickImage(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 1, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('passes the width and height arguments correctly', () async { + await picker.pickImage(source: ImageSource.camera); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxHeight: 10.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.pickImage( + source: ImageSource.camera, + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.pickImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('passes the width and height arguments correctly', () async { - await picker.pickImage(source: ImageSource.camera); - await picker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - ); - await picker.pickImage( - source: ImageSource.camera, - maxHeight: 10.0, - ); - await picker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - imageQuality: 70, - ); - await picker.pickImage( - source: ImageSource.camera, - maxHeight: 10.0, - imageQuality: 70, - ); - await picker.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.pickImage(imageQuality: -1, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(imageQuality: 101, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(imageQuality: -1, source: ImageSource.camera), + throwsArgumentError, + ); + + expect( + () => picker.pickImage(imageQuality: 101, source: ImageSource.camera), + throwsArgumentError, + ); + }); - test('does not accept an invalid imageQuality argument', () { - expect( - () => picker.pickImage(imageQuality: -1, source: ImageSource.gallery), - throwsArgumentError, - ); - - expect( - () => - picker.pickImage(imageQuality: 101, source: ImageSource.gallery), - throwsArgumentError, - ); - - expect( - () => picker.pickImage(imageQuality: -1, source: ImageSource.camera), - throwsArgumentError, - ); - - expect( - () => picker.pickImage(imageQuality: 101, source: ImageSource.camera), - throwsArgumentError, - ); - }); + test('does not accept a negative width or height argument', () { + expect( + () => picker.pickImage(source: ImageSource.camera, maxWidth: -1.0), + throwsArgumentError, + ); - test('does not accept a negative width or height argument', () { - expect( - () => picker.pickImage(source: ImageSource.camera, maxWidth: -1.0), - throwsArgumentError, - ); + expect( + () => picker.pickImage(source: ImageSource.camera, maxHeight: -1.0), + throwsArgumentError, + ); + }); - expect( - () => picker.pickImage(source: ImageSource.camera, maxHeight: -1.0), - throwsArgumentError, - ); - }); + test('handles a null image path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.pickImage(source: ImageSource.gallery), isNull); + expect(await picker.pickImage(source: ImageSource.camera), isNull); + }); - expect(await picker.pickImage(source: ImageSource.gallery), isNull); - expect(await picker.pickImage(source: ImageSource.camera), isNull); - }); + test('camera position defaults to back', () async { + await picker.pickImage(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('camera position defaults to back', () async { - await picker.pickImage(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('camera position can set to front', () async { + await picker.pickImage( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); + }); - test('camera position can set to front', () async { - await picker.pickImage( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 1, - 'requestFullMetadata': true, - }), - ], - ); - }); + group('#pickMultiImage', () { + test('calls the method correctly', () async { + returnValue = ['0', '1']; + await picker.pickMultiImage(); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + ], + ); }); - group('#pickMultiImage', () { - test('calls the method correctly', () async { - returnValue = ['0', '1']; - await picker.pickMultiImage(); - - expect( - log, - [ - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - }), - ], - ); - }); + test('passes the width and height arguments correctly', () async { + returnValue = ['0', '1']; + await picker.pickMultiImage(); + await picker.pickMultiImage( + maxWidth: 10.0, + ); + await picker.pickMultiImage( + maxHeight: 10.0, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.pickMultiImage( + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.pickMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + }), + ], + ); + }); - test('passes the width and height arguments correctly', () async { - returnValue = ['0', '1']; - await picker.pickMultiImage(); - await picker.pickMultiImage( - maxWidth: 10.0, - ); - await picker.pickMultiImage( - maxHeight: 10.0, - ); - await picker.pickMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.pickMultiImage( - maxWidth: 10.0, - imageQuality: 70, - ); - await picker.pickMultiImage( - maxHeight: 10.0, - imageQuality: 70, - ); - await picker.pickMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ); - - expect( - log, - [ - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - }), - ], - ); - }); + test('does not accept a negative width or height argument', () { + returnValue = ['0', '1']; + expect( + () => picker.pickMultiImage(maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.pickMultiImage(maxHeight: -1.0), + throwsArgumentError, + ); + }); - test('does not accept a negative width or height argument', () { - returnValue = ['0', '1']; - expect( - () => picker.pickMultiImage(maxWidth: -1.0), - throwsArgumentError, - ); - - expect( - () => picker.pickMultiImage(maxHeight: -1.0), - throwsArgumentError, - ); - }); + test('does not accept an invalid imageQuality argument', () { + returnValue = ['0', '1']; + expect( + () => picker.pickMultiImage(imageQuality: -1), + throwsArgumentError, + ); + + expect( + () => picker.pickMultiImage(imageQuality: 101), + throwsArgumentError, + ); + }); - test('does not accept an invalid imageQuality argument', () { - returnValue = ['0', '1']; - expect( - () => picker.pickMultiImage(imageQuality: -1), - throwsArgumentError, - ); - - expect( - () => picker.pickMultiImage(imageQuality: 101), - throwsArgumentError, - ); - }); + test('handles a null image path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.pickMultiImage(), isNull); + expect(await picker.pickMultiImage(), isNull); + }); + }); - expect(await picker.pickMultiImage(), isNull); - expect(await picker.pickMultiImage(), isNull); - }); + group('#pickVideo', () { + test('passes the image source argument correctly', () async { + await picker.pickVideo(source: ImageSource.camera); + await picker.pickVideo(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + isMethodCall('pickVideo', arguments: { + 'source': 1, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); }); - group('#pickVideo', () { - test('passes the image source argument correctly', () async { - await picker.pickVideo(source: ImageSource.camera); - await picker.pickVideo(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - isMethodCall('pickVideo', arguments: { - 'source': 1, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); + test('passes the duration argument correctly', () async { + await picker.pickVideo(source: ImageSource.camera); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(seconds: 10), + ); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(minutes: 1), + ); + await picker.pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(hours: 1), + ); + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 10, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 60, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 3600, + 'cameraDevice': 0, + }), + ], + ); + }); - test('passes the duration argument correctly', () async { - await picker.pickVideo(source: ImageSource.camera); - await picker.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10), - ); - await picker.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(minutes: 1), - ); - await picker.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(hours: 1), - ); - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 10, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 60, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 3600, - 'cameraDevice': 0, - }), - ], - ); - }); + test('handles a null video path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null video path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.pickVideo(source: ImageSource.gallery), isNull); + expect(await picker.pickVideo(source: ImageSource.camera), isNull); + }); - expect(await picker.pickVideo(source: ImageSource.gallery), isNull); - expect(await picker.pickVideo(source: ImageSource.camera), isNull); - }); + test('camera position defaults to back', () async { + await picker.pickVideo(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); - test('camera position defaults to back', () async { - await picker.pickVideo(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); + test('camera position can set to front', () async { + await picker.pickVideo( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front, + ); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 1, + }), + ], + ); + }); + }); - test('camera position can set to front', () async { - await picker.pickVideo( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front, - ); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 1, - }), - ], - ); + group('#retrieveLostData', () { + test('retrieveLostData get success response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path', + }; }); + final LostData response = await picker.retrieveLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path'); }); - group('#retrieveLostData', () { - test('retrieveLostData get success response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'image', - 'path': '/example/path', - }; - }); - final LostData response = await picker.retrieveLostData(); - expect(response.type, RetrieveType.image); - expect(response.file, isNotNull); - expect(response.file!.path, '/example/path'); + test('retrieveLostData get error response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + }; }); + final LostData response = await picker.retrieveLostData(); + expect(response.type, RetrieveType.video); + expect(response.exception, isNotNull); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); + }); - test('retrieveLostData get error response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - }; - }); - final LostData response = await picker.retrieveLostData(); - expect(response.type, RetrieveType.video); - expect(response.exception, isNotNull); - expect(response.exception!.code, 'test_error_code'); - expect(response.exception!.message, 'test_error_message'); + test('retrieveLostData get null response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return null; }); + expect((await picker.retrieveLostData()).isEmpty, true); + }); - test('retrieveLostData get null response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return null; - }); - expect((await picker.retrieveLostData()).isEmpty, true); + test('retrieveLostData get both path and error should throw', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + 'path': '/example/path', + }; }); + expect(picker.retrieveLostData(), throwsAssertionError); + }); + }); - test('retrieveLostData get both path and error should throw', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - 'path': '/example/path', - }; - }); - expect(picker.retrieveLostData(), throwsAssertionError); - }); + group('#getImage', () { + test('passes the image source argument correctly', () async { + await picker.getImage(source: ImageSource.camera); + await picker.getImage(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); }); - group('#getImage', () { - test('passes the image source argument correctly', () async { - await picker.getImage(source: ImageSource.camera); - await picker.getImage(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 1, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('passes the width and height arguments correctly', () async { + await picker.getImage(source: ImageSource.camera); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxHeight: 10.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.getImage( + source: ImageSource.camera, + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.getImage( + source: ImageSource.camera, + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('passes the width and height arguments correctly', () async { - await picker.getImage(source: ImageSource.camera); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - ); - await picker.getImage( - source: ImageSource.camera, - maxHeight: 10.0, - ); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - imageQuality: 70, - ); - await picker.getImage( - source: ImageSource.camera, - maxHeight: 10.0, - imageQuality: 70, - ); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.getImage(imageQuality: -1, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: 101, source: ImageSource.gallery), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: -1, source: ImageSource.camera), + throwsArgumentError, + ); + + expect( + () => picker.getImage(imageQuality: 101, source: ImageSource.camera), + throwsArgumentError, + ); + }); - test('does not accept an invalid imageQuality argument', () { - expect( - () => picker.getImage(imageQuality: -1, source: ImageSource.gallery), - throwsArgumentError, - ); - - expect( - () => picker.getImage(imageQuality: 101, source: ImageSource.gallery), - throwsArgumentError, - ); - - expect( - () => picker.getImage(imageQuality: -1, source: ImageSource.camera), - throwsArgumentError, - ); - - expect( - () => picker.getImage(imageQuality: 101, source: ImageSource.camera), - throwsArgumentError, - ); - }); + test('does not accept a negative width or height argument', () { + expect( + () => picker.getImage(source: ImageSource.camera, maxWidth: -1.0), + throwsArgumentError, + ); - test('does not accept a negative width or height argument', () { - expect( - () => picker.getImage(source: ImageSource.camera, maxWidth: -1.0), - throwsArgumentError, - ); + expect( + () => picker.getImage(source: ImageSource.camera, maxHeight: -1.0), + throwsArgumentError, + ); + }); - expect( - () => picker.getImage(source: ImageSource.camera, maxHeight: -1.0), - throwsArgumentError, - ); - }); + test('handles a null image path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.getImage(source: ImageSource.gallery), isNull); + expect(await picker.getImage(source: ImageSource.camera), isNull); + }); - expect(await picker.getImage(source: ImageSource.gallery), isNull); - expect(await picker.getImage(source: ImageSource.camera), isNull); - }); + test('camera position defaults to back', () async { + await picker.getImage(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('camera position defaults to back', () async { - await picker.getImage(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('camera position can set to front', () async { + await picker.getImage( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); + }); - test('camera position can set to front', () async { - await picker.getImage( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 1, - 'requestFullMetadata': true, - }), - ], - ); - }); + group('#getMultiImage', () { + test('calls the method correctly', () async { + returnValue = ['0', '1']; + await picker.getMultiImage(); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + ], + ); }); - group('#getMultiImage', () { - test('calls the method correctly', () async { - returnValue = ['0', '1']; - await picker.getMultiImage(); - - expect( - log, - [ - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - }), - ], - ); - }); + test('passes the width and height arguments correctly', () async { + returnValue = ['0', '1']; + await picker.getMultiImage(); + await picker.getMultiImage( + maxWidth: 10.0, + ); + await picker.getMultiImage( + maxHeight: 10.0, + ); + await picker.getMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + ); + await picker.getMultiImage( + maxWidth: 10.0, + imageQuality: 70, + ); + await picker.getMultiImage( + maxHeight: 10.0, + imageQuality: 70, + ); + await picker.getMultiImage( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ); + + expect( + log, + [ + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + }), + isMethodCall('pickMultiImage', arguments: { + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + }), + ], + ); + }); - test('passes the width and height arguments correctly', () async { - returnValue = ['0', '1']; - await picker.getMultiImage(); - await picker.getMultiImage( - maxWidth: 10.0, - ); - await picker.getMultiImage( - maxHeight: 10.0, - ); - await picker.getMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.getMultiImage( - maxWidth: 10.0, - imageQuality: 70, - ); - await picker.getMultiImage( - maxHeight: 10.0, - imageQuality: 70, - ); - await picker.getMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ); - - expect( - log, - [ - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - }), - isMethodCall('pickMultiImage', arguments: { - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - }), - ], - ); - }); + test('does not accept a negative width or height argument', () { + returnValue = ['0', '1']; + expect( + () => picker.getMultiImage(maxWidth: -1.0), + throwsArgumentError, + ); + + expect( + () => picker.getMultiImage(maxHeight: -1.0), + throwsArgumentError, + ); + }); - test('does not accept a negative width or height argument', () { - returnValue = ['0', '1']; - expect( - () => picker.getMultiImage(maxWidth: -1.0), - throwsArgumentError, - ); - - expect( - () => picker.getMultiImage(maxHeight: -1.0), - throwsArgumentError, - ); - }); + test('does not accept an invalid imageQuality argument', () { + returnValue = ['0', '1']; + expect( + () => picker.getMultiImage(imageQuality: -1), + throwsArgumentError, + ); + + expect( + () => picker.getMultiImage(imageQuality: 101), + throwsArgumentError, + ); + }); - test('does not accept an invalid imageQuality argument', () { - returnValue = ['0', '1']; - expect( - () => picker.getMultiImage(imageQuality: -1), - throwsArgumentError, - ); - - expect( - () => picker.getMultiImage(imageQuality: 101), - throwsArgumentError, - ); - }); + test('handles a null image path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.getMultiImage(), isNull); + expect(await picker.getMultiImage(), isNull); + }); + }); - expect(await picker.getMultiImage(), isNull); - expect(await picker.getMultiImage(), isNull); - }); + group('#getVideo', () { + test('passes the image source argument correctly', () async { + await picker.getVideo(source: ImageSource.camera); + await picker.getVideo(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + isMethodCall('pickVideo', arguments: { + 'source': 1, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); }); - group('#getVideo', () { - test('passes the image source argument correctly', () async { - await picker.getVideo(source: ImageSource.camera); - await picker.getVideo(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - isMethodCall('pickVideo', arguments: { - 'source': 1, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); + test('passes the duration argument correctly', () async { + await picker.getVideo(source: ImageSource.camera); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(seconds: 10), + ); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(minutes: 1), + ); + await picker.getVideo( + source: ImageSource.camera, + maxDuration: const Duration(hours: 1), + ); + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 10, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 60, + 'cameraDevice': 0, + }), + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': 3600, + 'cameraDevice': 0, + }), + ], + ); + }); - test('passes the duration argument correctly', () async { - await picker.getVideo(source: ImageSource.camera); - await picker.getVideo( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10), - ); - await picker.getVideo( - source: ImageSource.camera, - maxDuration: const Duration(minutes: 1), - ); - await picker.getVideo( - source: ImageSource.camera, - maxDuration: const Duration(hours: 1), - ); - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 10, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 60, - 'cameraDevice': 0, - }), - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': 3600, - 'cameraDevice': 0, - }), - ], - ); - }); + test('handles a null video path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - test('handles a null video path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + expect(await picker.getVideo(source: ImageSource.gallery), isNull); + expect(await picker.getVideo(source: ImageSource.camera), isNull); + }); - expect(await picker.getVideo(source: ImageSource.gallery), isNull); - expect(await picker.getVideo(source: ImageSource.camera), isNull); - }); + test('camera position defaults to back', () async { + await picker.getVideo(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'cameraDevice': 0, + 'maxDuration': null, + }), + ], + ); + }); - test('camera position defaults to back', () async { - await picker.getVideo(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'cameraDevice': 0, - 'maxDuration': null, - }), - ], - ); - }); + test('camera position can set to front', () async { + await picker.getVideo( + source: ImageSource.camera, + preferredCameraDevice: CameraDevice.front, + ); + + expect( + log, + [ + isMethodCall('pickVideo', arguments: { + 'source': 0, + 'maxDuration': null, + 'cameraDevice': 1, + }), + ], + ); + }); + }); - test('camera position can set to front', () async { - await picker.getVideo( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front, - ); - - expect( - log, - [ - isMethodCall('pickVideo', arguments: { - 'source': 0, - 'maxDuration': null, - 'cameraDevice': 1, - }), - ], - ); + group('#getLostData', () { + test('getLostData get success response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path', + }; }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path'); }); - group('#getLostData', () { - test('getLostData get success response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'image', - 'path': '/example/path', - }; - }); - final LostDataResponse response = await picker.getLostData(); - expect(response.type, RetrieveType.image); - expect(response.file, isNotNull); - expect(response.file!.path, '/example/path'); + test('getLostData should successfully retrieve multiple files', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'image', + 'path': '/example/path1', + 'pathList': ['/example/path0', '/example/path1'], + }; }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.image); + expect(response.file, isNotNull); + expect(response.file!.path, '/example/path1'); + expect(response.files!.first.path, '/example/path0'); + expect(response.files!.length, 2); + }); - test('getLostData should successfully retrieve multiple files', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'image', - 'path': '/example/path1', - 'pathList': ['/example/path0', '/example/path1'], - }; - }); - final LostDataResponse response = await picker.getLostData(); - expect(response.type, RetrieveType.image); - expect(response.file, isNotNull); - expect(response.file!.path, '/example/path1'); - expect(response.files!.first.path, '/example/path0'); - expect(response.files!.length, 2); + test('getLostData get error response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + }; }); + final LostDataResponse response = await picker.getLostData(); + expect(response.type, RetrieveType.video); + expect(response.exception, isNotNull); + expect(response.exception!.code, 'test_error_code'); + expect(response.exception!.message, 'test_error_message'); + }); - test('getLostData get error response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - }; - }); - final LostDataResponse response = await picker.getLostData(); - expect(response.type, RetrieveType.video); - expect(response.exception, isNotNull); - expect(response.exception!.code, 'test_error_code'); - expect(response.exception!.message, 'test_error_message'); + test('getLostData get null response', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return null; }); + expect((await picker.getLostData()).isEmpty, true); + }); - test('getLostData get null response', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return null; - }); - expect((await picker.getLostData()).isEmpty, true); + test('getLostData get both path and error should throw', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { + return { + 'type': 'video', + 'errorCode': 'test_error_code', + 'errorMessage': 'test_error_message', + 'path': '/example/path', + }; }); + expect(picker.getLostData(), throwsAssertionError); + }); + }); - test('getLostData get both path and error should throw', () async { - picker.channel.setMockMethodCallHandler((MethodCall methodCall) async { - return { - 'type': 'video', - 'errorCode': 'test_error_code', - 'errorMessage': 'test_error_message', - 'path': '/example/path', - }; - }); - expect(picker.getLostData(), throwsAssertionError); - }); + group('#getImageFromSource', () { + test('passes the image source argument correctly', () async { + await picker.getImageFromSource(source: ImageSource.camera); + await picker.getImageFromSource(source: ImageSource.gallery); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 1, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); }); - group('#getImageFromSource', () { - test('passes the image source argument correctly', () async { - await picker.getImageFromSource(source: ImageSource.camera); - await picker.getImageFromSource(source: ImageSource.gallery); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 1, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('passes the width and height arguments correctly', () async { + await picker.getImageFromSource(source: ImageSource.camera); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxWidth: 10.0), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxHeight: 10.0), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + maxHeight: 20.0, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + imageQuality: 70, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxHeight: 10.0, + imageQuality: 70, + ), + ); + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + maxWidth: 10.0, + maxHeight: 20.0, + imageQuality: 70, + ), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': null, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': 10.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': 10.0, + 'maxHeight': 20.0, + 'imageQuality': 70, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('passes the width and height arguments correctly', () async { - await picker.getImageFromSource(source: ImageSource.camera); - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(maxWidth: 10.0), - ); - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(maxHeight: 10.0), - ); - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions( - maxWidth: 10.0, - maxHeight: 20.0, - ), - ); - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions( - maxWidth: 10.0, - imageQuality: 70, - ), - ); - await picker.getImageFromSource( + test('does not accept an invalid imageQuality argument', () { + expect( + () => picker.getImageFromSource( + source: ImageSource.gallery, + options: const ImagePickerOptions(imageQuality: -1), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( + source: ImageSource.gallery, + options: const ImagePickerOptions(imageQuality: 101), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( source: ImageSource.camera, - options: const ImagePickerOptions( - maxHeight: 10.0, - imageQuality: 70, - ), - ); - await picker.getImageFromSource( + options: const ImagePickerOptions(imageQuality: -1), + ), + throwsArgumentError, + ); + + expect( + () => picker.getImageFromSource( source: ImageSource.camera, - options: const ImagePickerOptions( - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ), - ); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': null, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': 10.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': 10.0, - 'maxHeight': 20.0, - 'imageQuality': 70, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + options: const ImagePickerOptions(imageQuality: 101), + ), + throwsArgumentError, + ); + }); - test('does not accept an invalid imageQuality argument', () { - expect( - () => picker.getImageFromSource( - source: ImageSource.gallery, - options: const ImagePickerOptions(imageQuality: -1), - ), - throwsArgumentError, - ); - - expect( - () => picker.getImageFromSource( - source: ImageSource.gallery, - options: const ImagePickerOptions(imageQuality: 101), - ), - throwsArgumentError, - ); - - expect( - () => picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(imageQuality: -1), - ), - throwsArgumentError, - ); - - expect( - () => picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(imageQuality: 101), - ), - throwsArgumentError, - ); - }); + test('does not accept a negative width or height argument', () { + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxWidth: -1.0), + ), + throwsArgumentError, + ); - test('does not accept a negative width or height argument', () { - expect( - () => picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(maxWidth: -1.0), - ), - throwsArgumentError, - ); - - expect( - () => picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(maxHeight: -1.0), - ), - throwsArgumentError, - ); - }); + expect( + () => picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(maxHeight: -1.0), + ), + throwsArgumentError, + ); + }); - test('handles a null image path response gracefully', () async { - picker.channel - .setMockMethodCallHandler((MethodCall methodCall) => null); + test('handles a null image path response gracefully', () async { + picker.channel.setMockMethodCallHandler((MethodCall methodCall) => null); - expect(await picker.getImageFromSource(source: ImageSource.gallery), - isNull); - expect(await picker.getImageFromSource(source: ImageSource.camera), - isNull); - }); + expect( + await picker.getImageFromSource(source: ImageSource.gallery), isNull); + expect( + await picker.getImageFromSource(source: ImageSource.camera), isNull); + }); - test('camera position defaults to back', () async { - await picker.getImageFromSource(source: ImageSource.camera); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('camera position defaults to back', () async { + await picker.getImageFromSource(source: ImageSource.camera); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('camera position can set to front', () async { - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions( - preferredCameraDevice: CameraDevice.front, - ), - ); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 1, - 'requestFullMetadata': true, - }), - ], - ); - }); + test('camera position can set to front', () async { + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions( + preferredCameraDevice: CameraDevice.front, + ), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 1, + 'requestFullMetadata': true, + }), + ], + ); + }); - test('passes the full metadata argument correctly', () async { - await picker.getImageFromSource( - source: ImageSource.camera, - options: const ImagePickerOptions(requestFullMetadata: false), - ); - - expect( - log, - [ - isMethodCall('pickImage', arguments: { - 'source': 0, - 'maxWidth': null, - 'maxHeight': null, - 'imageQuality': null, - 'cameraDevice': 0, - 'requestFullMetadata': false, - }), - ], - ); - }); + test('passes the full metadata argument correctly', () async { + await picker.getImageFromSource( + source: ImageSource.camera, + options: const ImagePickerOptions(requestFullMetadata: false), + ); + + expect( + log, + [ + isMethodCall('pickImage', arguments: { + 'source': 0, + 'maxWidth': null, + 'maxHeight': null, + 'imageQuality': null, + 'cameraDevice': 0, + 'requestFullMetadata': false, + }), + ], + ); }); }); } From 9c95cbda398748c59e6f9497f611cff838a97d69 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:39:42 -0400 Subject: [PATCH 4/8] Dramatically simplify retrieveLostData --- .../lib/image_picker_android.dart | 52 ++++++------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/packages/image_picker/image_picker_android/lib/image_picker_android.dart b/packages/image_picker/image_picker_android/lib/image_picker_android.dart index f4dea4246734..cdf8ca596968 100644 --- a/packages/image_picker/image_picker_android/lib/image_picker_android.dart +++ b/packages/image_picker/image_picker_android/lib/image_picker_android.dart @@ -144,43 +144,6 @@ class ImagePickerAndroid extends ImagePickerPlatform { ); } - @override - Future retrieveLostData() async { - final Map? result = - await _channel.invokeMapMethod('retrieve'); - - if (result == null) { - return LostData.empty(); - } - - assert(result.containsKey('path') != result.containsKey('errorCode')); - - final String? type = result['type'] as String?; - assert(type == kTypeImage || type == kTypeVideo); - - RetrieveType? retrieveType; - if (type == kTypeImage) { - retrieveType = RetrieveType.image; - } else if (type == kTypeVideo) { - retrieveType = RetrieveType.video; - } - - PlatformException? exception; - if (result.containsKey('errorCode')) { - exception = PlatformException( - code: result['errorCode']! as String, - message: result['errorMessage'] as String?); - } - - final String? path = result['path'] as String?; - - return LostData( - file: path != null ? PickedFile(path) : null, - exception: exception, - type: retrieveType, - ); - } - @override Future getImage({ required ImageSource source, @@ -247,6 +210,21 @@ class ImagePickerAndroid extends ImagePickerPlatform { return path != null ? XFile(path) : null; } + @override + Future retrieveLostData() async { + final LostDataResponse result = await getLostData(); + + if (result.isEmpty) { + return LostData.empty(); + } + + return LostData( + file: result.file != null ? PickedFile(result.file!.path) : null, + exception: result.exception, + type: result.type, + ); + } + @override Future getLostData() async { List? pickedFileList; From 18c61759364e54549c89bef71e27e6fd2bd25695 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:44:26 -0400 Subject: [PATCH 5/8] Add Dart registration and test --- .../image_picker_android/lib/image_picker_android.dart | 5 +++++ packages/image_picker/image_picker_android/pubspec.yaml | 1 + .../image_picker_android/test/image_picker_android_test.dart | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/packages/image_picker/image_picker_android/lib/image_picker_android.dart b/packages/image_picker/image_picker_android/lib/image_picker_android.dart index cdf8ca596968..226d59aea012 100644 --- a/packages/image_picker/image_picker_android/lib/image_picker_android.dart +++ b/packages/image_picker/image_picker_android/lib/image_picker_android.dart @@ -17,6 +17,11 @@ class ImagePickerAndroid extends ImagePickerPlatform { @visibleForTesting MethodChannel get channel => _channel; + /// Registers this class as the default platform implementation. + static void registerWith() { + ImagePickerPlatform.instance = ImagePickerAndroid(); + } + @override Future pickImage({ required ImageSource source, diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index 3d17e8ae7745..c4ab408ba616 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -15,6 +15,7 @@ flutter: android: package: io.flutter.plugins.imagepicker pluginClass: ImagePickerPlugin + dartPLuginClass: ImagePickerAndroid dependencies: flutter: diff --git a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart index b01c3f8b8c87..ee1eb79f1045 100644 --- a/packages/image_picker/image_picker_android/test/image_picker_android_test.dart +++ b/packages/image_picker/image_picker_android/test/image_picker_android_test.dart @@ -26,6 +26,11 @@ void main() { log.clear(); }); + test('registers instance', () async { + ImagePickerAndroid.registerWith(); + expect(ImagePickerPlatform.instance, isA()); + }); + group('#pickImage', () { test('passes the image source argument correctly', () async { await picker.pickImage(source: ImageSource.camera); From 4104589d72ddf8dafc68d3a501a7849962bba704 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 10 Jun 2022 16:45:34 -0400 Subject: [PATCH 6/8] Rename method channel --- .../java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java | 2 +- .../image_picker_android/lib/image_picker_android.dart | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 311ef19103ac..8336a145e93a 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -183,7 +183,7 @@ ImagePickerDelegate getDelegate() { private static final String METHOD_CALL_RETRIEVE = "retrieve"; private static final int CAMERA_DEVICE_FRONT = 1; private static final int CAMERA_DEVICE_REAR = 0; - private static final String CHANNEL = "plugins.flutter.io/image_picker"; + private static final String CHANNEL = "plugins.flutter.io/image_picker_android"; private static final int SOURCE_CAMERA = 0; private static final int SOURCE_GALLERY = 1; diff --git a/packages/image_picker/image_picker_android/lib/image_picker_android.dart b/packages/image_picker/image_picker_android/lib/image_picker_android.dart index 226d59aea012..b6073c7a436a 100644 --- a/packages/image_picker/image_picker_android/lib/image_picker_android.dart +++ b/packages/image_picker/image_picker_android/lib/image_picker_android.dart @@ -9,7 +9,8 @@ import 'package:flutter/services.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; -const MethodChannel _channel = MethodChannel('plugins.flutter.io/image_picker'); +const MethodChannel _channel = + MethodChannel('plugins.flutter.io/image_picker_android'); /// An Android implementation of [ImagePickerPlatform]. class ImagePickerAndroid extends ImagePickerPlatform { From bcbcb68048c5b3e9d7b210652171cc9739a50df2 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 13 Jun 2022 13:18:22 -0400 Subject: [PATCH 7/8] Typo fix --- packages/image_picker/image_picker_android/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index c4ab408ba616..0f8aa4ac95ba 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -15,7 +15,7 @@ flutter: android: package: io.flutter.plugins.imagepicker pluginClass: ImagePickerPlugin - dartPLuginClass: ImagePickerAndroid + dartPluginClass: ImagePickerAndroid dependencies: flutter: From d7a76a3c56047b5abbe49c7b41a1e1384a106166 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 13 Jun 2022 13:28:24 -0400 Subject: [PATCH 8/8] Version bump --- packages/image_picker/image_picker_android/CHANGELOG.md | 4 ++++ packages/image_picker/image_picker_android/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index a5cc6139bf0f..664be36f880f 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.5+1 + +* Switches to an internal method channel implementation. + ## 0.8.5 * Updates gradle to 7.1.2. diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index 0f8aa4ac95ba..8cbaaac71daf 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.5 +version: 0.8.5+1 environment: sdk: ">=2.14.0 <3.0.0"