| // 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:html'; |
| import 'dart:js_util' as js_util; |
| // TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#106316) |
| // ignore: unnecessary_import |
| import 'dart:ui'; |
| |
| import 'package:camera_platform_interface/camera_platform_interface.dart'; |
| import 'package:camera_web/src/camera.dart'; |
| import 'package:camera_web/src/camera_service.dart'; |
| import 'package:camera_web/src/shims/dart_js_util.dart'; |
| import 'package:camera_web/src/types/types.dart'; |
| import 'package:flutter/services.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| import 'package:integration_test/integration_test.dart'; |
| import 'package:mocktail/mocktail.dart'; |
| |
| import 'helpers/helpers.dart'; |
| |
| void main() { |
| IntegrationTestWidgetsFlutterBinding.ensureInitialized(); |
| |
| group('CameraService', () { |
| const int cameraId = 1; |
| |
| late Window window; |
| late Navigator navigator; |
| late MediaDevices mediaDevices; |
| late CameraService cameraService; |
| late JsUtil jsUtil; |
| |
| setUp(() async { |
| window = MockWindow(); |
| navigator = MockNavigator(); |
| mediaDevices = MockMediaDevices(); |
| jsUtil = MockJsUtil(); |
| |
| when(() => window.navigator).thenReturn(navigator); |
| when(() => navigator.mediaDevices).thenReturn(mediaDevices); |
| |
| // Mock JsUtil to return the real getProperty from dart:js_util. |
| when<dynamic>(() => jsUtil.getProperty(any(), any())).thenAnswer( |
| (Invocation invocation) => js_util.getProperty<dynamic>( |
| invocation.positionalArguments[0] as Object, |
| invocation.positionalArguments[1] as Object, |
| ), |
| ); |
| |
| cameraService = CameraService()..window = window; |
| }); |
| |
| group('getMediaStreamForOptions', () { |
| testWidgets( |
| 'calls MediaDevices.getUserMedia ' |
| 'with provided options', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenAnswer((_) async => FakeMediaStream(<MediaStreamTrack>[])); |
| |
| final CameraOptions options = CameraOptions( |
| video: VideoConstraints( |
| facingMode: FacingModeConstraint.exact(CameraType.user), |
| width: const VideoSizeConstraint(ideal: 200), |
| ), |
| ); |
| |
| await cameraService.getMediaStreamForOptions(options); |
| |
| verify( |
| () => mediaDevices.getUserMedia(options.toJson()), |
| ).called(1); |
| }); |
| |
| testWidgets( |
| 'throws PlatformException ' |
| 'with notSupported error ' |
| 'when there are no media devices', (WidgetTester tester) async { |
| when(() => navigator.mediaDevices).thenReturn(null); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions(const CameraOptions()), |
| throwsA( |
| isA<PlatformException>().having( |
| (PlatformException e) => e.code, |
| 'code', |
| CameraErrorCode.notSupported.toString(), |
| ), |
| ), |
| ); |
| }); |
| |
| group('throws CameraWebException', () { |
| testWidgets( |
| 'with notFound error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with NotFoundError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('NotFoundError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.notFound), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with notFound error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with DevicesNotFoundError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('DevicesNotFoundError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.notFound), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with notReadable error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with NotReadableError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('NotReadableError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.notReadable), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with notReadable error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with TrackStartError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('TrackStartError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.notReadable), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with overconstrained error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with OverconstrainedError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('OverconstrainedError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.overconstrained), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with overconstrained error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with ConstraintNotSatisfiedError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('ConstraintNotSatisfiedError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.overconstrained), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with permissionDenied error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with NotAllowedError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('NotAllowedError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.permissionDenied), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with permissionDenied error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with PermissionDeniedError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('PermissionDeniedError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.permissionDenied), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with type error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with TypeError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('TypeError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.type), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with abort error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with AbortError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('AbortError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.abort), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with security error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with SecurityError', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('SecurityError')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.security), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with unknown error ' |
| 'when MediaDevices.getUserMedia throws DomException ' |
| 'with an unknown error', (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())) |
| .thenThrow(FakeDomException('Unknown')); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.unknown), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with unknown error ' |
| 'when MediaDevices.getUserMedia throws an unknown exception', |
| (WidgetTester tester) async { |
| when(() => mediaDevices.getUserMedia(any())).thenThrow(Exception()); |
| |
| expect( |
| () => cameraService.getMediaStreamForOptions( |
| const CameraOptions(), |
| cameraId: cameraId, |
| ), |
| throwsA( |
| isA<CameraWebException>() |
| .having((CameraWebException e) => e.cameraId, 'cameraId', |
| cameraId) |
| .having((CameraWebException e) => e.code, 'code', |
| CameraErrorCode.unknown), |
| ), |
| ); |
| }); |
| }); |
| }); |
| |
| group('getZoomLevelCapabilityForCamera', () { |
| late Camera camera; |
| late List<MediaStreamTrack> videoTracks; |
| |
| setUp(() { |
| camera = MockCamera(); |
| videoTracks = <MediaStreamTrack>[ |
| MockMediaStreamTrack(), |
| MockMediaStreamTrack() |
| ]; |
| |
| when(() => camera.textureId).thenReturn(0); |
| when(() => camera.stream).thenReturn(FakeMediaStream(videoTracks)); |
| |
| cameraService.jsUtil = jsUtil; |
| }); |
| |
| testWidgets( |
| 'returns the zoom level capability ' |
| 'based on the first video track', (WidgetTester tester) async { |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'zoom': true, |
| }); |
| |
| when(videoTracks.first.getCapabilities).thenReturn(<dynamic, dynamic>{ |
| 'zoom': js_util.jsify(<dynamic, dynamic>{ |
| 'min': 100, |
| 'max': 400, |
| 'step': 2, |
| }), |
| }); |
| |
| final ZoomLevelCapability zoomLevelCapability = |
| cameraService.getZoomLevelCapabilityForCamera(camera); |
| |
| expect(zoomLevelCapability.minimum, equals(100.0)); |
| expect(zoomLevelCapability.maximum, equals(400.0)); |
| expect(zoomLevelCapability.videoTrack, equals(videoTracks.first)); |
| }); |
| |
| group('throws CameraWebException', () { |
| testWidgets( |
| 'with zoomLevelNotSupported error ' |
| 'when there are no media devices', (WidgetTester tester) async { |
| when(() => navigator.mediaDevices).thenReturn(null); |
| |
| expect( |
| () => cameraService.getZoomLevelCapabilityForCamera(camera), |
| throwsA( |
| isA<CameraWebException>() |
| .having( |
| (CameraWebException e) => e.cameraId, |
| 'cameraId', |
| camera.textureId, |
| ) |
| .having( |
| (CameraWebException e) => e.code, |
| 'code', |
| CameraErrorCode.zoomLevelNotSupported, |
| ), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with zoomLevelNotSupported error ' |
| 'when the zoom level is not supported ' |
| 'in the browser', (WidgetTester tester) async { |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'zoom': false, |
| }); |
| |
| when(videoTracks.first.getCapabilities).thenReturn(<dynamic, dynamic>{ |
| 'zoom': <dynamic, dynamic>{ |
| 'min': 100, |
| 'max': 400, |
| 'step': 2, |
| }, |
| }); |
| |
| expect( |
| () => cameraService.getZoomLevelCapabilityForCamera(camera), |
| throwsA( |
| isA<CameraWebException>() |
| .having( |
| (CameraWebException e) => e.cameraId, |
| 'cameraId', |
| camera.textureId, |
| ) |
| .having( |
| (CameraWebException e) => e.code, |
| 'code', |
| CameraErrorCode.zoomLevelNotSupported, |
| ), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with zoomLevelNotSupported error ' |
| 'when the zoom level is not supported ' |
| 'by the camera', (WidgetTester tester) async { |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'zoom': true, |
| }); |
| |
| when(videoTracks.first.getCapabilities) |
| .thenReturn(<dynamic, dynamic>{}); |
| |
| expect( |
| () => cameraService.getZoomLevelCapabilityForCamera(camera), |
| throwsA( |
| isA<CameraWebException>() |
| .having( |
| (CameraWebException e) => e.cameraId, |
| 'cameraId', |
| camera.textureId, |
| ) |
| .having( |
| (CameraWebException e) => e.code, |
| 'code', |
| CameraErrorCode.zoomLevelNotSupported, |
| ), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'with notStarted error ' |
| 'when the camera stream has not been initialized', |
| (WidgetTester tester) async { |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'zoom': true, |
| }); |
| |
| // Create a camera stream with no video tracks. |
| when(() => camera.stream) |
| .thenReturn(FakeMediaStream(<MediaStreamTrack>[])); |
| |
| expect( |
| () => cameraService.getZoomLevelCapabilityForCamera(camera), |
| throwsA( |
| isA<CameraWebException>() |
| .having( |
| (CameraWebException e) => e.cameraId, |
| 'cameraId', |
| camera.textureId, |
| ) |
| .having( |
| (CameraWebException e) => e.code, |
| 'code', |
| CameraErrorCode.notStarted, |
| ), |
| ), |
| ); |
| }); |
| }); |
| }); |
| |
| group('getFacingModeForVideoTrack', () { |
| setUp(() { |
| cameraService.jsUtil = jsUtil; |
| }); |
| |
| testWidgets( |
| 'throws PlatformException ' |
| 'with notSupported error ' |
| 'when there are no media devices', (WidgetTester tester) async { |
| when(() => navigator.mediaDevices).thenReturn(null); |
| |
| expect( |
| () => |
| cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()), |
| throwsA( |
| isA<PlatformException>().having( |
| (PlatformException e) => e.code, |
| 'code', |
| CameraErrorCode.notSupported.toString(), |
| ), |
| ), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns null ' |
| 'when the facing mode is not supported', (WidgetTester tester) async { |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'facingMode': false, |
| }); |
| |
| final String? facingMode = |
| cameraService.getFacingModeForVideoTrack(MockMediaStreamTrack()); |
| |
| expect(facingMode, isNull); |
| }); |
| |
| group('when the facing mode is supported', () { |
| late MediaStreamTrack videoTrack; |
| |
| setUp(() { |
| videoTrack = MockMediaStreamTrack(); |
| |
| when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) |
| .thenReturn(true); |
| |
| when(mediaDevices.getSupportedConstraints) |
| .thenReturn(<dynamic, dynamic>{ |
| 'facingMode': true, |
| }); |
| }); |
| |
| testWidgets( |
| 'returns an appropriate facing mode ' |
| 'based on the video track settings', (WidgetTester tester) async { |
| when(videoTrack.getSettings) |
| .thenReturn(<dynamic, dynamic>{'facingMode': 'user'}); |
| |
| final String? facingMode = |
| cameraService.getFacingModeForVideoTrack(videoTrack); |
| |
| expect(facingMode, equals('user')); |
| }); |
| |
| testWidgets( |
| 'returns an appropriate facing mode ' |
| 'based on the video track capabilities ' |
| 'when the facing mode setting is empty', |
| (WidgetTester tester) async { |
| when(videoTrack.getSettings).thenReturn(<dynamic, dynamic>{}); |
| when(videoTrack.getCapabilities).thenReturn(<dynamic, dynamic>{ |
| 'facingMode': <dynamic>['environment', 'left'] |
| }); |
| |
| when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) |
| .thenReturn(true); |
| |
| final String? facingMode = |
| cameraService.getFacingModeForVideoTrack(videoTrack); |
| |
| expect(facingMode, equals('environment')); |
| }); |
| |
| testWidgets( |
| 'returns null ' |
| 'when the facing mode setting ' |
| 'and capabilities are empty', (WidgetTester tester) async { |
| when(videoTrack.getSettings).thenReturn(<dynamic, dynamic>{}); |
| when(videoTrack.getCapabilities) |
| .thenReturn(<dynamic, dynamic>{'facingMode': <dynamic>[]}); |
| |
| final String? facingMode = |
| cameraService.getFacingModeForVideoTrack(videoTrack); |
| |
| expect(facingMode, isNull); |
| }); |
| |
| testWidgets( |
| 'returns null ' |
| 'when the facing mode setting is empty and ' |
| 'the video track capabilities are not supported', |
| (WidgetTester tester) async { |
| when(videoTrack.getSettings).thenReturn(<dynamic, dynamic>{}); |
| |
| when(() => jsUtil.hasProperty(videoTrack, 'getCapabilities')) |
| .thenReturn(false); |
| |
| final String? facingMode = |
| cameraService.getFacingModeForVideoTrack(videoTrack); |
| |
| expect(facingMode, isNull); |
| }); |
| }); |
| }); |
| |
| group('mapFacingModeToLensDirection', () { |
| testWidgets( |
| 'returns front ' |
| 'when the facing mode is user', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToLensDirection('user'), |
| equals(CameraLensDirection.front), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns back ' |
| 'when the facing mode is environment', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToLensDirection('environment'), |
| equals(CameraLensDirection.back), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns external ' |
| 'when the facing mode is left', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToLensDirection('left'), |
| equals(CameraLensDirection.external), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns external ' |
| 'when the facing mode is right', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToLensDirection('right'), |
| equals(CameraLensDirection.external), |
| ); |
| }); |
| }); |
| |
| group('mapFacingModeToCameraType', () { |
| testWidgets( |
| 'returns user ' |
| 'when the facing mode is user', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToCameraType('user'), |
| equals(CameraType.user), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns environment ' |
| 'when the facing mode is environment', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToCameraType('environment'), |
| equals(CameraType.environment), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns user ' |
| 'when the facing mode is left', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToCameraType('left'), |
| equals(CameraType.user), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns user ' |
| 'when the facing mode is right', (WidgetTester tester) async { |
| expect( |
| cameraService.mapFacingModeToCameraType('right'), |
| equals(CameraType.user), |
| ); |
| }); |
| }); |
| |
| group('mapResolutionPresetToSize', () { |
| testWidgets( |
| 'returns 4096x2160 ' |
| 'when the resolution preset is max', (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.max), |
| equals(const Size(4096, 2160)), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns 4096x2160 ' |
| 'when the resolution preset is ultraHigh', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.ultraHigh), |
| equals(const Size(4096, 2160)), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns 1920x1080 ' |
| 'when the resolution preset is veryHigh', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.veryHigh), |
| equals(const Size(1920, 1080)), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns 1280x720 ' |
| 'when the resolution preset is high', (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.high), |
| equals(const Size(1280, 720)), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns 720x480 ' |
| 'when the resolution preset is medium', (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.medium), |
| equals(const Size(720, 480)), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns 320x240 ' |
| 'when the resolution preset is low', (WidgetTester tester) async { |
| expect( |
| cameraService.mapResolutionPresetToSize(ResolutionPreset.low), |
| equals(const Size(320, 240)), |
| ); |
| }); |
| }); |
| |
| group('mapDeviceOrientationToOrientationType', () { |
| testWidgets( |
| 'returns portraitPrimary ' |
| 'when the device orientation is portraitUp', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapDeviceOrientationToOrientationType( |
| DeviceOrientation.portraitUp, |
| ), |
| equals(OrientationType.portraitPrimary), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns landscapePrimary ' |
| 'when the device orientation is landscapeLeft', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapDeviceOrientationToOrientationType( |
| DeviceOrientation.landscapeLeft, |
| ), |
| equals(OrientationType.landscapePrimary), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns portraitSecondary ' |
| 'when the device orientation is portraitDown', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapDeviceOrientationToOrientationType( |
| DeviceOrientation.portraitDown, |
| ), |
| equals(OrientationType.portraitSecondary), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns landscapeSecondary ' |
| 'when the device orientation is landscapeRight', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapDeviceOrientationToOrientationType( |
| DeviceOrientation.landscapeRight, |
| ), |
| equals(OrientationType.landscapeSecondary), |
| ); |
| }); |
| }); |
| |
| group('mapOrientationTypeToDeviceOrientation', () { |
| testWidgets( |
| 'returns portraitUp ' |
| 'when the orientation type is portraitPrimary', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| OrientationType.portraitPrimary, |
| ), |
| equals(DeviceOrientation.portraitUp), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns landscapeLeft ' |
| 'when the orientation type is landscapePrimary', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| OrientationType.landscapePrimary, |
| ), |
| equals(DeviceOrientation.landscapeLeft), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns portraitDown ' |
| 'when the orientation type is portraitSecondary', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| OrientationType.portraitSecondary, |
| ), |
| equals(DeviceOrientation.portraitDown), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns portraitDown ' |
| 'when the orientation type is portraitSecondary', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| OrientationType.portraitSecondary, |
| ), |
| equals(DeviceOrientation.portraitDown), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns landscapeRight ' |
| 'when the orientation type is landscapeSecondary', |
| (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| OrientationType.landscapeSecondary, |
| ), |
| equals(DeviceOrientation.landscapeRight), |
| ); |
| }); |
| |
| testWidgets( |
| 'returns portraitUp ' |
| 'for an unknown orientation type', (WidgetTester tester) async { |
| expect( |
| cameraService.mapOrientationTypeToDeviceOrientation( |
| 'unknown', |
| ), |
| equals(DeviceOrientation.portraitUp), |
| ); |
| }); |
| }); |
| }); |
| } |
| |
| class JSNoSuchMethodError implements Exception {} |