From 2439e764fe89832cf92889dd436ad4c195cdfffa Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Mon, 3 Mar 2025 09:27:55 +0100 Subject: [PATCH 1/2] Add CameraPlugin delegating method tests --- .../ios/Runner.xcodeproj/project.pbxproj | 4 + .../CameraPluginDelegatingMethodTests.swift | 391 ++++++++++++++++++ .../ios/RunnerTests/Mocks/MockFLTCam.swift | 176 ++++++++ 3 files changed, 571 insertions(+) create mode 100644 packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift diff --git a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj index 4fd11717f7de..780d65678100 100644 --- a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97DB234D2D566D0700CEFE66 /* CameraPreviewPauseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97DB234C2D566D0700CEFE66 /* CameraPreviewPauseTests.swift */; }; E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */; }; + E12C4FF62D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E12C4FF52D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift */; }; E12C4FF82D68E85500515E70 /* MockFLTCameraPermissionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E12C4FF72D68E85500515E70 /* MockFLTCameraPermissionManager.swift */; }; E1FFEAAD2D6C8DD700B14107 /* MockFLTCam.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FFEAAC2D6C8DD700B14107 /* MockFLTCam.swift */; }; E1FFEAAF2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FFEAAE2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift */; }; @@ -145,6 +146,7 @@ B61D98BBC8FB276D1C4A7BB2 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CameraTestUtils.h; sourceTree = ""; }; E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraTestUtils.m; sourceTree = ""; }; + E12C4FF52D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPluginDelegatingMethodTests.swift; sourceTree = ""; }; E12C4FF72D68E85500515E70 /* MockFLTCameraPermissionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFLTCameraPermissionManager.swift; sourceTree = ""; }; E1FFEAAC2D6C8DD700B14107 /* MockFLTCam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFLTCam.swift; sourceTree = ""; }; E1FFEAAE2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPluginCreateCameraTests.swift; sourceTree = ""; }; @@ -201,6 +203,7 @@ 978D90B32D5F630300CD817E /* StreamingTests.swift */, 97922B0C2D6380C300A9B4CF /* SampleBufferTests.swift */, 978296CE2D5F744B0009BDD3 /* PhotoCaptureTests.swift */, + E12C4FF52D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift */, E1FFEAAE2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift */, E1FFEAB02D6CDE5B00B14107 /* CameraPluginInitializeCameraTests.swift */, ); @@ -561,6 +564,7 @@ 97BD4A102D5CE13500F857D5 /* CameraSessionPresetsTests.swift in Sources */, 7FD582272D57C020003B1200 /* MockAssetWriter.m in Sources */, 979B3E022D5BA48F009BDE1A /* CameraOrientationTests.swift in Sources */, + E12C4FF62D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift in Sources */, 977A25222D5A49EC00931E34 /* CameraFocusTests.swift in Sources */, 978D90B42D5F630300CD817E /* StreamingTests.swift in Sources */, 7F29EB412D281C7E00740257 /* MockCaptureSession.m in Sources */, diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift new file mode 100644 index 000000000000..1ecad246716d --- /dev/null +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift @@ -0,0 +1,391 @@ +// 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 XCTest + +@testable import camera_avfoundation + +/// Tests of `CameraPlugin` methods delegating to `FLTCam` instance +final class CameraPluginDelegatingMethodTests: XCTestCase { + private func createCameraPlugin() -> (CameraPlugin, MockFLTCam) { + let mockCamera = MockFLTCam() + + let cameraPlugin = CameraPlugin( + registry: MockFlutterTextureRegistry(), + messenger: MockFlutterBinaryMessenger(), + globalAPI: MockGlobalEventApi(), + deviceDiscoverer: MockCameraDeviceDiscoverer(), + permissionManager: MockFLTCameraPermissionManager(), + deviceFactory: { _ in MockCaptureDevice() }, + captureSessionFactory: { MockCaptureSession() }, + captureDeviceInputFactory: MockCaptureDeviceInputFactory() + ) + cameraPlugin.camera = mockCamera + + return (cameraPlugin, mockCamera) + } + + // Universal function orchiestrating a test of a delegating method + private func testDelegatingMethod( + // Callback with MockFLTCam instance and a callback to call when the expected FLTCam method has + // been called + setUp: (MockFLTCam, @escaping () -> Void) -> Void, + // Callback with CameraPlugin instance and a complition to call when the tested method finishes + act: (CameraPlugin, @escaping (FlutterError?) -> Void) -> Void + ) { + let (cameraPlugin, mockCamera) = createCameraPlugin() + // Expectation fulfilled when complition passed to `act` callback is called + let expectation = expectation(description: "Call completed") + + var markCalled = false + + setUp( + mockCamera, + { + markCalled = true + } + ) + + act(cameraPlugin) { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(markCalled) + } + + func testLockCapture_callsDelegateMethod() { + let targetOrientation = FCPPlatformDeviceOrientation.landscapeLeft + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.lockCaptureStub = { orientation in + XCTAssertEqual(orientation, targetOrientation) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.lockCapture(targetOrientation, completion: complition) + } + } + + func testPausePreview_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.pausePreviewStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.pausePreview(completion: complition) + } + } + + func testPauseVideoRecording_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.pauseVideoRecordingStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.pauseVideoRecording(completion: complition) + } + } + + func testPrepareForVideoRecording_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setUpCaptureSessionForAudioIfNeededStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.prepareForVideoRecording(completion: complition) + } + } + + func testReceivedImageStreamData_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.receivedImageStreamDataStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.receivedImageStreamData(completion: complition) + } + } + + func testResumeVideoRecording_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.resumeVideoRecordingStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.resumeVideoRecording(completion: complition) + } + } + + func testResumePreview_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.resumePreviewStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.resumePreview(completion: complition) + } + } + + func testSetExposureMode_callsDelegateMethod() { + let targetExposureMode = FCPPlatformExposureMode.locked + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setExposureModeStub = { mode in + XCTAssertEqual(mode, targetExposureMode) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setExposureMode(targetExposureMode, completion: complition) + } + } + + func testSetExposureOffset_callsDelegateMethod() { + let targetExposureOffset = 1.0 + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setExposureOffsetStub = { offset in + XCTAssertEqual(offset, targetExposureOffset) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setExposureOffset(targetExposureOffset, completion: complition) + } + } + + func testSetFocusMode_callsDelegateMethod() { + let targetFocusMode = FCPPlatformFocusMode.locked + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setFocusModeStub = { mode in + XCTAssertEqual(mode, targetFocusMode) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setFocusMode(targetFocusMode, completion: complition) + } + } + + func testSetImageFileFormat_callsDelegateMethod() { + let targetFileFormat = FCPPlatformImageFileFormat.heif + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setImageFileFormatStub = { filerFormat in + XCTAssertEqual(filerFormat, targetFileFormat) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setImageFileFormat(targetFileFormat, completion: complition) + } + } + + func testStartImageStream_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.startImageStreamStub = { _ in markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.startImageStream(completion: complition) + } + } + + func testStopImageStream_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.stopImageStreamStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.stopImageStream(completion: complition) + } + } + + func testStartVideoRecording_withStreamingTrue_callsDelegateMethodWithMessanger() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.startVideoRecordingStub = { complition, messanger in + XCTAssertNotNil(messanger) + complition(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.startVideoRecording(withStreaming: true, completion: complition) + } + } + + func testStartVideoRecording_withStreamingFalse_callsDelegateMethodWithoutMessagner() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.startVideoRecordingStub = { complition, messanger in + XCTAssertNil(messanger) + complition(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.startVideoRecording(withStreaming: false, completion: complition) + } + } + + func testStopVideoRecording_callsDelegateMethod() { + let targetPath = "path" + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.stopVideoRecordingStub = { completion in + completion?(targetPath, nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.stopVideoRecording { path, error in + XCTAssertEqual(path, targetPath) + complition(error) + } + } + } + + func testUnlockCaptureOrientation_callsDelegateMethod() { + testDelegatingMethod { mockCamera, markCalled in + mockCamera.unlockCaptureOrientationStub = { markCalled() } + } act: { cameraPlugin, complition in + cameraPlugin.unlockCaptureOrientation(completion: complition) + } + } + + func testSetExposurePoint_callsDelegateMethod() { + let targetExposurePoint = FCPPlatformPoint.makeWith(x: 1.0, y: 1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setExposurePointStub = { point, complition in + XCTAssertEqual(point, targetExposurePoint) + complition?(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setExposurePoint(targetExposurePoint, completion: complition) + } + } + + func testSetFlashMode_callsDelegateMethod() { + let targetFlashMode = FCPPlatformFlashMode.auto + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setFlashModeStub = { mode, complition in + XCTAssertEqual(mode, targetFlashMode) + complition?(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setFlashMode(targetFlashMode, completion: complition) + } + } + + func testSetFocusPoint_callsDelegateMethod() { + let targetFocusPoint = FCPPlatformPoint.makeWith(x: 1.0, y: 1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setFocusPointStub = { point, complition in + XCTAssertEqual(point, targetFocusPoint) + complition?(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setFocus(targetFocusPoint, completion: complition) + } + } + + func testSetZoomLevel_callsDelegateMethod() { + let targetZoomLevel = 1.0 + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setZoomLevelStub = { zoom, complition in + XCTAssertEqual(zoom, targetZoomLevel) + complition?(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.setZoomLevel(targetZoomLevel, completion: complition) + } + } + + func testTakePicture_callsDelegateMethod() { + let targetPath = "path" + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.captureToFileStub = { completion in + completion?(targetPath, nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.takePicture { path, error in + XCTAssertEqual(path, targetPath) + complition(error) + } + } + } + + func testUpdateDescriptionWhileRecordingCameraName_callsDelegateMethod() { + let targetCameraName = "camera_name" + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.setDescriptionWhileRecordingStub = { cameraName, complition in + XCTAssertEqual(cameraName, targetCameraName) + complition?(nil) + markCalled() + } + } act: { cameraPlugin, complition in + cameraPlugin.updateDescriptionWhileRecordingCameraName( + targetCameraName, completion: complition) + } + } + + func testGetMaximumZoomLevel_returnsValueFromDelegateMethod() { + let targetMaximumZoomLevel = CGFloat(1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.getMaximumAvailableZoomFactorStub = { + markCalled() + return targetMaximumZoomLevel + } + } act: { cameraPlugin, complition in + cameraPlugin.getMaximumZoomLevel { zoom, error in + XCTAssertNil(error) + XCTAssertEqual(zoom?.doubleValue, targetMaximumZoomLevel) + complition(nil) + } + } + } + + func testGetMinimumZoomLevel_returnsValueFromDelegateMethod() { + let targetMinimumZoomLevel = CGFloat(1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.getMinimumAvailableZoomFactorStub = { + markCalled() + return targetMinimumZoomLevel + } + } act: { cameraPlugin, complition in + cameraPlugin.getMinimumZoomLevel { zoom, error in + XCTAssertNil(error) + XCTAssertEqual(zoom?.doubleValue, targetMinimumZoomLevel) + complition(nil) + } + } + } + + func testGetMaximumExposureOffset_returnsValueFromDelegateMethod() { + let targetMaximumExposureOffset = CGFloat(1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.getMaximumExposureOffsetStub = { + markCalled() + return targetMaximumExposureOffset + } + } act: { cameraPlugin, complition in + cameraPlugin.getMaximumExposureOffset { offset, error in + XCTAssertNil(error) + XCTAssertEqual(offset?.doubleValue, targetMaximumExposureOffset) + complition(nil) + } + } + } + + func testGetMinimumExposureOffset_returnsValueFromDelegateMethod() { + let targetMinimumExposureOffset = CGFloat(1.0) + + testDelegatingMethod { mockCamera, markCalled in + mockCamera.getMinimumExposureOffsetStub = { + markCalled() + return targetMinimumExposureOffset + } + } act: { cameraPlugin, complition in + cameraPlugin.getMinimumExposureOffset { offset, error in + XCTAssertNil(error) + XCTAssertEqual(offset?.doubleValue, targetMinimumExposureOffset) + complition(nil) + } + } + } +} diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockFLTCam.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockFLTCam.swift index ad1122f7ae35..a2740cebb322 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockFLTCam.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockFLTCam.swift @@ -5,9 +5,36 @@ final class MockFLTCam: FLTCam { var setOnFrameAvailableStub: ((() -> Void) -> Void)? var setDartApiStub: ((FCPCameraEventApi) -> Void)? + var setExposureModeStub: ((FCPPlatformExposureMode) -> Void)? + var setFocusModeStub: ((FCPPlatformFocusMode) -> Void)? + var getMinimumAvailableZoomFactorStub: (() -> CGFloat)? + var getMaximumAvailableZoomFactorStub: (() -> CGFloat)? + var getMinimumExposureOffsetStub: (() -> CGFloat)? + var getMaximumExposureOffsetStub: (() -> CGFloat)? var startStub: (() -> Void)? var setDeviceOrientationStub: ((UIDeviceOrientation) -> Void)? + var captureToFileStub: ((((String?, FlutterError?) -> Void)?) -> Void)? + var setImageFileFormatStub: ((FCPPlatformImageFileFormat) -> Void)? + var startVideoRecordingStub: + ((@escaping (FlutterError?) -> Void, FlutterBinaryMessenger?) -> Void)? + var stopVideoRecordingStub: ((((String?, FlutterError?) -> Void)?) -> Void)? + var pauseVideoRecordingStub: (() -> Void)? + var resumeVideoRecordingStub: (() -> Void)? + var lockCaptureStub: ((FCPPlatformDeviceOrientation) -> Void)? + var unlockCaptureOrientationStub: (() -> Void)? + var setFlashModeStub: ((FCPPlatformFlashMode, ((FlutterError?) -> Void)?) -> Void)? + var receivedImageStreamDataStub: (() -> Void)? + var pausePreviewStub: (() -> Void)? + var resumePreviewStub: (() -> Void)? + var setDescriptionWhileRecordingStub: ((String, ((FlutterError?) -> Void)?) -> Void)? + var setExposurePointStub: ((FCPPlatformPoint?, ((FlutterError?) -> Void)?) -> Void)? + var setFocusPointStub: ((FCPPlatformPoint?, ((FlutterError?) -> Void)?) -> Void)? + var setExposureOffsetStub: ((Double) -> Void)? + var startImageStreamStub: ((FlutterBinaryMessenger) -> Void)? + var stopImageStreamStub: (() -> Void)? + var setZoomLevelStub: ((CGFloat, ((FlutterError?) -> Void)?) -> Void)? + var setUpCaptureSessionForAudioIfNeededStub: (() -> Void)? override var onFrameAvailable: (() -> Void) { get { @@ -27,6 +54,62 @@ final class MockFLTCam: FLTCam { } } + /// The `setExposureMode` ObjC method is converted to property accessor in Swift translation + override var exposureMode: FCPPlatformExposureMode { + get { + return super.exposureMode + } + set { + setExposureModeStub?(newValue) + } + } + + /// The `setFocusMode` ObjC method is converted to property accessor in Swift translation + override var focusMode: FCPPlatformFocusMode { + get { + return super.focusMode + } + set { + setFocusModeStub?(newValue) + } + } + + override var minimumAvailableZoomFactor: CGFloat { + get { + return getMinimumAvailableZoomFactorStub?() ?? super.minimumAvailableZoomFactor + } + set { + super.minimumAvailableZoomFactor = newValue + } + } + + override var maximumAvailableZoomFactor: CGFloat { + get { + return getMaximumAvailableZoomFactorStub?() ?? super.maximumAvailableZoomFactor + } + set { + super.maximumAvailableZoomFactor = newValue + } + } + + override var minimumExposureOffset: CGFloat { + get { + return getMinimumExposureOffsetStub?() ?? super.minimumExposureOffset + } + set { + super.minimumExposureOffset = newValue + } + } + + override var maximumExposureOffset: CGFloat { + get { + return getMaximumExposureOffsetStub?() ?? super.maximumExposureOffset + } + set { + super.maximumExposureOffset = newValue + } + } + override func start() { startStub?() } @@ -34,4 +117,97 @@ final class MockFLTCam: FLTCam { override func setDeviceOrientation(_ orientation: UIDeviceOrientation) { setDeviceOrientationStub?(orientation) } + + override func captureToFile(completion: @escaping (String?, FlutterError?) -> Void) { + captureToFileStub?(completion) + } + + override func setImageFileFormat(_ fileFormat: FCPPlatformImageFileFormat) { + setImageFileFormatStub?(fileFormat) + } + + override func startVideoRecording( + completion: @escaping (FlutterError?) -> Void, + messengerForStreaming messenger: FlutterBinaryMessenger? + ) { + startVideoRecordingStub?(completion, messenger) + } + + override func stopVideoRecording(completion: ((String?, FlutterError?) -> Void)?) { + stopVideoRecordingStub?(completion) + } + + override func pauseVideoRecording() { + pauseVideoRecordingStub?() + } + + override func resumeVideoRecording() { + resumeVideoRecordingStub?() + } + + override func lockCapture(_ orientation: FCPPlatformDeviceOrientation) { + lockCaptureStub?(orientation) + } + + override func unlockCaptureOrientation() { + unlockCaptureOrientationStub?() + } + + override func setFlashMode( + _ mode: FCPPlatformFlashMode, withCompletion completion: @escaping (FlutterError?) -> Void + ) { + setFlashModeStub?(mode, completion) + } + + override func receivedImageStreamData() { + receivedImageStreamDataStub?() + } + + override func pausePreview() { + pausePreviewStub?() + } + + override func resumePreview() { + resumePreviewStub?() + } + + override func setDescriptionWhileRecording( + _ cameraName: String, withCompletion completion: @escaping (FlutterError?) -> Void + ) { + setDescriptionWhileRecordingStub?(cameraName, completion) + } + + override func setExposurePoint( + _ point: FCPPlatformPoint?, withCompletion completion: ((FlutterError?) -> Void)? + ) { + setExposurePointStub?(point, completion) + } + + override func setFocusPoint( + _ point: FCPPlatformPoint?, completion: @escaping (FlutterError?) -> Void + ) { + setFocusPointStub?(point, completion) + } + + override func setExposureOffset(_ offset: Double) { + setExposureOffsetStub?(offset) + } + + override func startImageStream(with messenger: FlutterBinaryMessenger) { + startImageStreamStub?(messenger) + } + + override func stopImageStream() { + stopImageStreamStub?() + } + + override func setZoomLevel( + _ zoom: CGFloat, withCompletion completion: @escaping (FlutterError?) -> Void + ) { + setZoomLevelStub?(zoom, completion) + } + + override func setUpCaptureSessionForAudioIfNeeded() { + setUpCaptureSessionForAudioIfNeededStub?() + } } From e4460bb13dfcee0d67bd7bb77e057a9f09777302 Mon Sep 17 00:00:00 2001 From: Robert Odrowaz Date: Fri, 7 Mar 2025 11:01:02 +0100 Subject: [PATCH 2/2] Remove testDelegatingMethod helper method --- .../CameraPluginDelegatingMethodTests.swift | 691 ++++++++++++------ 1 file changed, 452 insertions(+), 239 deletions(-) diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift index 1ecad246716d..b4237d8d638e 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginDelegatingMethodTests.swift @@ -26,366 +26,579 @@ final class CameraPluginDelegatingMethodTests: XCTestCase { return (cameraPlugin, mockCamera) } - // Universal function orchiestrating a test of a delegating method - private func testDelegatingMethod( - // Callback with MockFLTCam instance and a callback to call when the expected FLTCam method has - // been called - setUp: (MockFLTCam, @escaping () -> Void) -> Void, - // Callback with CameraPlugin instance and a complition to call when the tested method finishes - act: (CameraPlugin, @escaping (FlutterError?) -> Void) -> Void - ) { + func testLockCapture_callsCameraLockCapture() { let (cameraPlugin, mockCamera) = createCameraPlugin() - // Expectation fulfilled when complition passed to `act` callback is called let expectation = expectation(description: "Call completed") - var markCalled = false + let targetOrientation = FCPPlatformDeviceOrientation.landscapeLeft - setUp( - mockCamera, - { - markCalled = true - } - ) + var lockCaptureCalled = false + mockCamera.lockCaptureStub = { orientation in + XCTAssertEqual(orientation, targetOrientation) + lockCaptureCalled = true + } - act(cameraPlugin) { error in + cameraPlugin.lockCapture(targetOrientation) { error in XCTAssertNil(error) expectation.fulfill() } waitForExpectations(timeout: 30, handler: nil) - XCTAssertTrue(markCalled) + XCTAssertTrue(lockCaptureCalled) } - func testLockCapture_callsDelegateMethod() { - let targetOrientation = FCPPlatformDeviceOrientation.landscapeLeft + func testPausePreview_callsCameraPausePreview() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") - testDelegatingMethod { mockCamera, markCalled in - mockCamera.lockCaptureStub = { orientation in - XCTAssertEqual(orientation, targetOrientation) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.lockCapture(targetOrientation, completion: complition) + var pausePreviewCalled = false + mockCamera.pausePreviewStub = { + pausePreviewCalled = true } - } - func testPausePreview_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.pausePreviewStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.pausePreview(completion: complition) + cameraPlugin.pausePreview { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(pausePreviewCalled) } - func testPauseVideoRecording_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.pauseVideoRecordingStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.pauseVideoRecording(completion: complition) + func testPauseVideoRecording_callsCameraPauseVideoRecording() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var pauseVideoRecordingCalled = false + mockCamera.pauseVideoRecordingStub = { + pauseVideoRecordingCalled = true } + + cameraPlugin.pauseVideoRecording { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(pauseVideoRecordingCalled) } - func testPrepareForVideoRecording_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setUpCaptureSessionForAudioIfNeededStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.prepareForVideoRecording(completion: complition) + func testPrepareForVideoRecording_callsCameraSetUpCaptureSessionForAudioIfNeeded() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var setUpCaptureSessionForAudioIfNeededCalled = false + mockCamera.setUpCaptureSessionForAudioIfNeededStub = { + setUpCaptureSessionForAudioIfNeededCalled = true } + + cameraPlugin.prepareForVideoRecording { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setUpCaptureSessionForAudioIfNeededCalled) } - func testReceivedImageStreamData_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.receivedImageStreamDataStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.receivedImageStreamData(completion: complition) + func testReceivedImageStreamData_callsCameraReceivedImageStreamData() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var receivedImageStreamDataCalled = false + mockCamera.receivedImageStreamDataStub = { + receivedImageStreamDataCalled = true } + + cameraPlugin.receivedImageStreamData { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(receivedImageStreamDataCalled) } - func testResumeVideoRecording_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.resumeVideoRecordingStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.resumeVideoRecording(completion: complition) + func testResumeVideoRecording_callsCameraResumeVideoRecording() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var resumeVideoRecordingCalled = false + mockCamera.resumeVideoRecordingStub = { + resumeVideoRecordingCalled = true + } + + cameraPlugin.resumeVideoRecording { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(resumeVideoRecordingCalled) } - func testResumePreview_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.resumePreviewStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.resumePreview(completion: complition) + func testResumePreview_callsCameraResumePreview() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var resumePreviewCalled = false + mockCamera.resumePreviewStub = { + resumePreviewCalled = true + } + + cameraPlugin.resumePreview { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(resumePreviewCalled) } - func testSetExposureMode_callsDelegateMethod() { + func testSetExposureMode_callsCameraExposureMode() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetExposureMode = FCPPlatformExposureMode.locked - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setExposureModeStub = { mode in - XCTAssertEqual(mode, targetExposureMode) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setExposureMode(targetExposureMode, completion: complition) + var setExposureModeCalled = false + mockCamera.setExposureModeStub = { mode in + XCTAssertEqual(mode, targetExposureMode) + setExposureModeCalled = true } + + cameraPlugin.setExposureMode(targetExposureMode) { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setExposureModeCalled) } - func testSetExposureOffset_callsDelegateMethod() { + func testSetExposureOffset_callsCameraSetExposureOffset() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetExposureOffset = 1.0 - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setExposureOffsetStub = { offset in - XCTAssertEqual(offset, targetExposureOffset) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setExposureOffset(targetExposureOffset, completion: complition) + var setExposureOffsetCalled = false + mockCamera.setExposureOffsetStub = { offset in + XCTAssertEqual(offset, targetExposureOffset) + setExposureOffsetCalled = true } + + cameraPlugin.setExposureOffset(targetExposureOffset) { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setExposureOffsetCalled) } - func testSetFocusMode_callsDelegateMethod() { + func testSetFocusMode_callsCameraSetFocusMode() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetFocusMode = FCPPlatformFocusMode.locked - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setFocusModeStub = { mode in - XCTAssertEqual(mode, targetFocusMode) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setFocusMode(targetFocusMode, completion: complition) + var setFocusModeCalled = false + mockCamera.setFocusModeStub = { mode in + XCTAssertEqual(mode, targetFocusMode) + setFocusModeCalled = true + } + + cameraPlugin.setFocusMode(targetFocusMode) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setFocusModeCalled) } - func testSetImageFileFormat_callsDelegateMethod() { + func testSetImageFileFormat_callsCameraSetImageFileFormat() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetFileFormat = FCPPlatformImageFileFormat.heif - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setImageFileFormatStub = { filerFormat in - XCTAssertEqual(filerFormat, targetFileFormat) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setImageFileFormat(targetFileFormat, completion: complition) + var setImageFileFormatCalled = false + mockCamera.setImageFileFormatStub = { fileFormat in + XCTAssertEqual(fileFormat, targetFileFormat) + setImageFileFormatCalled = true + } + + cameraPlugin.setImageFileFormat(targetFileFormat) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setImageFileFormatCalled) } - func testStartImageStream_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.startImageStreamStub = { _ in markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.startImageStream(completion: complition) + func testStartImageStream_callsCameraStartImageStream() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var startImageStreamCalled = false + mockCamera.startImageStreamStub = { _ in + startImageStreamCalled = true + } + + cameraPlugin.startImageStream { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(startImageStreamCalled) } - func testStopImageStream_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.stopImageStreamStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.stopImageStream(completion: complition) + func testStopImageStream_callsCameraStopImageStream() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var stopImageStreamCalled = false + mockCamera.stopImageStreamStub = { + stopImageStreamCalled = true } + + cameraPlugin.stopImageStream { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(stopImageStreamCalled) } - func testStartVideoRecording_withStreamingTrue_callsDelegateMethodWithMessanger() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.startVideoRecordingStub = { complition, messanger in - XCTAssertNotNil(messanger) - complition(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.startVideoRecording(withStreaming: true, completion: complition) + func testStartVideoRecording_withStreamingTrue_callsCameraStartVideoRecordingWithMessenger() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var startVideoRecordingCalled = false + mockCamera.startVideoRecordingStub = { completion, messenger in + XCTAssertNotNil(messenger) + completion(nil) + startVideoRecordingCalled = true + } + + cameraPlugin.startVideoRecording(withStreaming: true) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(startVideoRecordingCalled) } - func testStartVideoRecording_withStreamingFalse_callsDelegateMethodWithoutMessagner() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.startVideoRecordingStub = { complition, messanger in - XCTAssertNil(messanger) - complition(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.startVideoRecording(withStreaming: false, completion: complition) + func testStartVideoRecording_withStreamingFalse_callsCameraStartVideoRecordingWithoutMessenger() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var startVideoRecordingCalled = false + mockCamera.startVideoRecordingStub = { completion, messenger in + XCTAssertNil(messenger) + completion(nil) + startVideoRecordingCalled = true } + + cameraPlugin.startVideoRecording(withStreaming: false) { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(startVideoRecordingCalled) } - func testStopVideoRecording_callsDelegateMethod() { + func testStopVideoRecording_callsCameraStopVideoRecording() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetPath = "path" - testDelegatingMethod { mockCamera, markCalled in - mockCamera.stopVideoRecordingStub = { completion in - completion?(targetPath, nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.stopVideoRecording { path, error in - XCTAssertEqual(path, targetPath) - complition(error) - } + var stopVideoRecordingCalled = false + mockCamera.stopVideoRecordingStub = { completion in + completion?(targetPath, nil) + stopVideoRecordingCalled = true } + + cameraPlugin.stopVideoRecording { path, error in + XCTAssertEqual(path, targetPath) + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(stopVideoRecordingCalled) } - func testUnlockCaptureOrientation_callsDelegateMethod() { - testDelegatingMethod { mockCamera, markCalled in - mockCamera.unlockCaptureOrientationStub = { markCalled() } - } act: { cameraPlugin, complition in - cameraPlugin.unlockCaptureOrientation(completion: complition) + func testUnlockCaptureOrientation_callsCameraUnlockCaptureOrientation() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + + var unlockCaptureOrientationCalled = false + mockCamera.unlockCaptureOrientationStub = { + unlockCaptureOrientationCalled = true + } + + cameraPlugin.unlockCaptureOrientation { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(unlockCaptureOrientationCalled) } - func testSetExposurePoint_callsDelegateMethod() { + func testSetExposurePoint_callsCameraSetExposurePoint() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetExposurePoint = FCPPlatformPoint.makeWith(x: 1.0, y: 1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setExposurePointStub = { point, complition in - XCTAssertEqual(point, targetExposurePoint) - complition?(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setExposurePoint(targetExposurePoint, completion: complition) + var setExposurePointCalled = false + mockCamera.setExposurePointStub = { point, completion in + XCTAssertEqual(point, targetExposurePoint) + completion?(nil) + setExposurePointCalled = true + } + + cameraPlugin.setExposurePoint(targetExposurePoint) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setExposurePointCalled) } - func testSetFlashMode_callsDelegateMethod() { + func testSetFlashMode_callsCameraSetFlashMode() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetFlashMode = FCPPlatformFlashMode.auto - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setFlashModeStub = { mode, complition in - XCTAssertEqual(mode, targetFlashMode) - complition?(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setFlashMode(targetFlashMode, completion: complition) + var setFlashModeCalled = false + mockCamera.setFlashModeStub = { mode, completion in + XCTAssertEqual(mode, targetFlashMode) + completion?(nil) + setFlashModeCalled = true + } + + cameraPlugin.setFlashMode(targetFlashMode) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setFlashModeCalled) } - func testSetFocusPoint_callsDelegateMethod() { + func testSetFocusPoint_callsCameraSetFocusPoint() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetFocusPoint = FCPPlatformPoint.makeWith(x: 1.0, y: 1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setFocusPointStub = { point, complition in - XCTAssertEqual(point, targetFocusPoint) - complition?(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setFocus(targetFocusPoint, completion: complition) + var setFocusPointCalled = false + mockCamera.setFocusPointStub = { point, completion in + XCTAssertEqual(point, targetFocusPoint) + completion?(nil) + setFocusPointCalled = true + } + + cameraPlugin.setFocus(targetFocusPoint) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setFocusPointCalled) } - func testSetZoomLevel_callsDelegateMethod() { + func testSetZoomLevel_callsCameraSetZoomLevel() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetZoomLevel = 1.0 - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setZoomLevelStub = { zoom, complition in - XCTAssertEqual(zoom, targetZoomLevel) - complition?(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.setZoomLevel(targetZoomLevel, completion: complition) + var setZoomLevelCalled = false + mockCamera.setZoomLevelStub = { zoom, completion in + XCTAssertEqual(zoom, targetZoomLevel) + completion?(nil) + setZoomLevelCalled = true } + + cameraPlugin.setZoomLevel(targetZoomLevel) { error in + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setZoomLevelCalled) } - func testTakePicture_callsDelegateMethod() { + func testTakePicture_callsCameraCaptureToFile() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetPath = "path" - testDelegatingMethod { mockCamera, markCalled in - mockCamera.captureToFileStub = { completion in - completion?(targetPath, nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.takePicture { path, error in - XCTAssertEqual(path, targetPath) - complition(error) - } + var captureToFileCalled = false + mockCamera.captureToFileStub = { completion in + completion?(targetPath, nil) + captureToFileCalled = true } + + cameraPlugin.takePicture { path, error in + XCTAssertEqual(path, targetPath) + XCTAssertNil(error) + expectation.fulfill() + } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(captureToFileCalled) } - func testUpdateDescriptionWhileRecordingCameraName_callsDelegateMethod() { + func testUpdateDescriptionWhileRecordingCameraName_callsCameraSetDescriptionWhileRecording() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetCameraName = "camera_name" - testDelegatingMethod { mockCamera, markCalled in - mockCamera.setDescriptionWhileRecordingStub = { cameraName, complition in - XCTAssertEqual(cameraName, targetCameraName) - complition?(nil) - markCalled() - } - } act: { cameraPlugin, complition in - cameraPlugin.updateDescriptionWhileRecordingCameraName( - targetCameraName, completion: complition) + var setDescriptionWhileRecordingCalled = false + mockCamera.setDescriptionWhileRecordingStub = { cameraName, completion in + XCTAssertEqual(cameraName, targetCameraName) + completion?(nil) + setDescriptionWhileRecordingCalled = true + } + + cameraPlugin.updateDescriptionWhileRecordingCameraName(targetCameraName) { error in + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(setDescriptionWhileRecordingCalled) } - func testGetMaximumZoomLevel_returnsValueFromDelegateMethod() { + func testGetMaximumZoomLevel_returnsValueFromCameraGetMaximumAvailableZoomFactor() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetMaximumZoomLevel = CGFloat(1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.getMaximumAvailableZoomFactorStub = { - markCalled() - return targetMaximumZoomLevel - } - } act: { cameraPlugin, complition in - cameraPlugin.getMaximumZoomLevel { zoom, error in - XCTAssertNil(error) - XCTAssertEqual(zoom?.doubleValue, targetMaximumZoomLevel) - complition(nil) - } + var getMaximumAvailableZoomFactorCalled = false + mockCamera.getMaximumAvailableZoomFactorStub = { + getMaximumAvailableZoomFactorCalled = true + return targetMaximumZoomLevel + } + + cameraPlugin.getMaximumZoomLevel { zoom, error in + XCTAssertEqual(zoom?.doubleValue, targetMaximumZoomLevel) + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(getMaximumAvailableZoomFactorCalled) } - func testGetMinimumZoomLevel_returnsValueFromDelegateMethod() { + func testGetMinimumZoomLevel_returnsValueFromCameraGetMinimumAvailableZoomFactor() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetMinimumZoomLevel = CGFloat(1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.getMinimumAvailableZoomFactorStub = { - markCalled() - return targetMinimumZoomLevel - } - } act: { cameraPlugin, complition in - cameraPlugin.getMinimumZoomLevel { zoom, error in - XCTAssertNil(error) - XCTAssertEqual(zoom?.doubleValue, targetMinimumZoomLevel) - complition(nil) - } + var getMinimumAvailableZoomFactorCalled = false + mockCamera.getMinimumAvailableZoomFactorStub = { + getMinimumAvailableZoomFactorCalled = true + return targetMinimumZoomLevel + } + + cameraPlugin.getMinimumZoomLevel { zoom, error in + XCTAssertEqual(zoom?.doubleValue, targetMinimumZoomLevel) + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(getMinimumAvailableZoomFactorCalled) } - func testGetMaximumExposureOffset_returnsValueFromDelegateMethod() { + func testGetMaximumExposureOffset_returnsValueFromCameraGetMaximumExposureOffset() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetMaximumExposureOffset = CGFloat(1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.getMaximumExposureOffsetStub = { - markCalled() - return targetMaximumExposureOffset - } - } act: { cameraPlugin, complition in - cameraPlugin.getMaximumExposureOffset { offset, error in - XCTAssertNil(error) - XCTAssertEqual(offset?.doubleValue, targetMaximumExposureOffset) - complition(nil) - } + var getMaximumExposureOffsetCalled = false + mockCamera.getMaximumExposureOffsetStub = { + getMaximumExposureOffsetCalled = true + return targetMaximumExposureOffset + } + + cameraPlugin.getMaximumExposureOffset { offset, error in + XCTAssertEqual(offset?.doubleValue, targetMaximumExposureOffset) + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(getMaximumExposureOffsetCalled) } - func testGetMinimumExposureOffset_returnsValueFromDelegateMethod() { + func testGetMinimumExposureOffset_returnsValueFromCameraGetMinimumExposureOffset() { + let (cameraPlugin, mockCamera) = createCameraPlugin() + let expectation = expectation(description: "Call completed") + let targetMinimumExposureOffset = CGFloat(1.0) - testDelegatingMethod { mockCamera, markCalled in - mockCamera.getMinimumExposureOffsetStub = { - markCalled() - return targetMinimumExposureOffset - } - } act: { cameraPlugin, complition in - cameraPlugin.getMinimumExposureOffset { offset, error in - XCTAssertNil(error) - XCTAssertEqual(offset?.doubleValue, targetMinimumExposureOffset) - complition(nil) - } + var getMinimumExposureOffsetCalled = false + mockCamera.getMinimumExposureOffsetStub = { + getMinimumExposureOffsetCalled = true + return targetMinimumExposureOffset + } + + cameraPlugin.getMinimumExposureOffset { offset, error in + XCTAssertEqual(offset?.doubleValue, targetMinimumExposureOffset) + XCTAssertNil(error) + expectation.fulfill() } + + waitForExpectations(timeout: 30, handler: nil) + + XCTAssertTrue(getMinimumExposureOffsetCalled) } }