diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 4e350433bab..f7dc03558d4 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.9.18+12 + +* Migrates test utils and mocks to Swift. +* Renames the methods of Objective-C type `FLTCaptureSession` when exported to Swift. + ## 0.9.18+11 * Backfills unit tests for the `FLTCam` class. 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 d12a1bcc2d9..e3d9a2a2323 100644 --- a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 54D650172516862D30686934 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ECAF63F924EFA2D68883BA85 /* libPods-Runner.a */; }; 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; 7F29EB292D26A59000740257 /* MockCameraDeviceDiscoverer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F29EB282D26A59000740257 /* MockCameraDeviceDiscoverer.m */; }; - 7F29EB412D281C7E00740257 /* MockCaptureSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F29EB402D281C7E00740257 /* MockCaptureSession.m */; }; 7F8FD2292D4BFABF001AF2C1 /* MockGlobalEventApi.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F8FD2282D4BFABF001AF2C1 /* MockGlobalEventApi.m */; }; 7F8FD22C2D4D07DD001AF2C1 /* MockFlutterTextureRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F8FD22B2D4D07DD001AF2C1 /* MockFlutterTextureRegistry.m */; }; 7F8FD22F2D4D0B88001AF2C1 /* MockFlutterBinaryMessenger.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F8FD22E2D4D0B88001AF2C1 /* MockFlutterBinaryMessenger.m */; }; @@ -47,14 +46,15 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 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 */; }; - E11D6A912D82C7740031E6C5 /* FLTCamExposureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11D6A902D82C7740031E6C5 /* FLTCamExposureTests.swift */; }; + E0CDBAC227CD9729002561D9 /* QueueTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* QueueTestUtils.m */; }; E11D6A8F2D81B81D0031E6C5 /* MockCaptureVideoDataOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11D6A8E2D81B81D0031E6C5 /* MockCaptureVideoDataOutput.swift */; }; + E11D6A912D82C7740031E6C5 /* FLTCamExposureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E11D6A902D82C7740031E6C5 /* FLTCamExposureTests.swift */; }; E12C4FF62D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E12C4FF52D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift */; }; E12C4FF82D68E85500515E70 /* MockFLTCameraPermissionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E12C4FF72D68E85500515E70 /* MockFLTCameraPermissionManager.swift */; }; - E16602952D8471C0003CFE12 /* FLTCamZoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E16602942D8471C0003CFE12 /* FLTCamZoomTests.swift */; }; - E1A5F4E32D80259C0005BA64 /* FLTCamSetFlashModeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A5F4E22D80259C0005BA64 /* FLTCamSetFlashModeTests.swift */; }; + E142681D2D8483FD0046CBBC /* MockCaptureSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = E142681C2D8483FD0046CBBC /* MockCaptureSession.swift */; }; + E142681F2D8566230046CBBC /* CameraTestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E142681E2D8566230046CBBC /* CameraTestUtils.swift */; }; E15139182D80980900FEE47B /* FLTCamSetDeviceOrientationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15139172D80980900FEE47B /* FLTCamSetDeviceOrientationTests.swift */; }; + E16602952D8471C0003CFE12 /* FLTCamZoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E16602942D8471C0003CFE12 /* FLTCamZoomTests.swift */; }; E1A5F4E32D80259C0005BA64 /* FLTCamSetFlashModeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A5F4E22D80259C0005BA64 /* FLTCamSetFlashModeTests.swift */; }; E1FFEAAD2D6C8DD700B14107 /* MockFLTCam.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FFEAAC2D6C8DD700B14107 /* MockFLTCam.swift */; }; E1FFEAAF2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FFEAAE2D6CDA8C00B14107 /* CameraPluginCreateCameraTests.swift */; }; @@ -96,8 +96,6 @@ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 7F29EB272D26A55300740257 /* MockCameraDeviceDiscoverer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockCameraDeviceDiscoverer.h; sourceTree = ""; }; 7F29EB282D26A59000740257 /* MockCameraDeviceDiscoverer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockCameraDeviceDiscoverer.m; sourceTree = ""; }; - 7F29EB3E2D281C5800740257 /* MockCaptureSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockCaptureSession.h; sourceTree = ""; }; - 7F29EB402D281C7E00740257 /* MockCaptureSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockCaptureSession.m; sourceTree = ""; }; 7F8FD2272D4BFA8D001AF2C1 /* MockGlobalEventApi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockGlobalEventApi.h; sourceTree = ""; }; 7F8FD2282D4BFABF001AF2C1 /* MockGlobalEventApi.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockGlobalEventApi.m; sourceTree = ""; }; 7F8FD22A2D4D07A6001AF2C1 /* MockFlutterTextureRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockFlutterTextureRegistry.h; sourceTree = ""; }; @@ -148,15 +146,16 @@ 9DDC4CE84A8B378AE4A8CD9C /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A8F314CD1C64E9257EBC811D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 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 = ""; }; - E11D6A902D82C7740031E6C5 /* FLTCamExposureTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamExposureTests.swift; sourceTree = ""; }; + E0CDBAC027CD9729002561D9 /* QueueTestUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QueueTestUtils.h; sourceTree = ""; }; + E0CDBAC127CD9729002561D9 /* QueueTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QueueTestUtils.m; sourceTree = ""; }; E11D6A8E2D81B81D0031E6C5 /* MockCaptureVideoDataOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCaptureVideoDataOutput.swift; sourceTree = ""; }; + E11D6A902D82C7740031E6C5 /* FLTCamExposureTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamExposureTests.swift; 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 = ""; }; - E16602942D8471C0003CFE12 /* FLTCamZoomTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamZoomTests.swift; sourceTree = ""; }; - E1A5F4E22D80259C0005BA64 /* FLTCamSetFlashModeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamSetFlashModeTests.swift; sourceTree = ""; }; + E142681C2D8483FD0046CBBC /* MockCaptureSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCaptureSession.swift; sourceTree = ""; }; + E142681E2D8566230046CBBC /* CameraTestUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraTestUtils.swift; sourceTree = ""; }; E15139172D80980900FEE47B /* FLTCamSetDeviceOrientationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamSetDeviceOrientationTests.swift; sourceTree = ""; }; + E16602942D8471C0003CFE12 /* FLTCamZoomTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamZoomTests.swift; sourceTree = ""; }; E1A5F4E22D80259C0005BA64 /* FLTCamSetFlashModeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FLTCamSetFlashModeTests.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 = ""; }; @@ -191,8 +190,9 @@ children = ( 7F29EB3F2D281C6D00740257 /* Mocks */, 03BB766C2665316900CE5A93 /* Info.plist */, - E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */, - E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */, + E0CDBAC027CD9729002561D9 /* QueueTestUtils.h */, + E0CDBAC127CD9729002561D9 /* QueueTestUtils.m */, + E142681E2D8566230046CBBC /* CameraTestUtils.swift */, 979B3DF92D5B6BA2009BDE1A /* ExceptionCatcher.h */, 979B3DFA2D5B6BC7009BDE1A /* ExceptionCatcher.m */, 979B3DFC2D5B985B009BDE1A /* RunnerTests-Bridging-Header.h */, @@ -255,13 +255,12 @@ 7FCEDD342D43C2B900EA1CA8 /* MockDeviceOrientationProvider.m */, 7F29EB272D26A55300740257 /* MockCameraDeviceDiscoverer.h */, 7F29EB282D26A59000740257 /* MockCameraDeviceDiscoverer.m */, - 7F29EB3E2D281C5800740257 /* MockCaptureSession.h */, - 7F29EB402D281C7E00740257 /* MockCaptureSession.m */, E1FFEAAC2D6C8DD700B14107 /* MockFLTCam.swift */, 970ADABF2D6764CC00EFDCD9 /* MockEventChannel.swift */, E12C4FF72D68E85500515E70 /* MockFLTCameraPermissionManager.swift */, 970ADABD2D6740A900EFDCD9 /* MockWritableData.swift */, E11D6A8E2D81B81D0031E6C5 /* MockCaptureVideoDataOutput.swift */, + E142681C2D8483FD0046CBBC /* MockCaptureSession.swift */, ); path = Mocks; sourceTree = ""; @@ -565,9 +564,10 @@ 7F8FD22F2D4D0B88001AF2C1 /* MockFlutterBinaryMessenger.m in Sources */, E12C4FF82D68E85500515E70 /* MockFLTCameraPermissionManager.swift in Sources */, 97922B0D2D6380C300A9B4CF /* SampleBufferTests.swift in Sources */, + E142681D2D8483FD0046CBBC /* MockCaptureSession.swift in Sources */, E15139182D80980900FEE47B /* FLTCamSetDeviceOrientationTests.swift in Sources */, 972CA92B2D5A1D8C004B846F /* CameraPropertiesTests.swift in Sources */, - E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */, + E0CDBAC227CD9729002561D9 /* QueueTestUtils.m in Sources */, 978296CF2D5F744B0009BDD3 /* PhotoCaptureTests.swift in Sources */, 7FD582202D579ECC003B1200 /* MockCapturePhotoOutput.m in Sources */, 979B3E002D5B9E6C009BDE1A /* CameraMethodChannelTests.swift in Sources */, @@ -575,6 +575,7 @@ 97DB234D2D566D0700CEFE66 /* CameraPreviewPauseTests.swift in Sources */, 970ADAC02D6764CC00EFDCD9 /* MockEventChannel.swift in Sources */, 977A25202D5A439300931E34 /* AvailableCamerasTests.swift in Sources */, + E142681F2D8566230046CBBC /* CameraTestUtils.swift in Sources */, E1FFEAAD2D6C8DD700B14107 /* MockFLTCam.swift in Sources */, 7F29EB292D26A59000740257 /* MockCameraDeviceDiscoverer.m in Sources */, E16602952D8471C0003CFE12 /* FLTCamZoomTests.swift in Sources */, @@ -584,7 +585,6 @@ E12C4FF62D68C69000515E70 /* CameraPluginDelegatingMethodTests.swift in Sources */, 977A25222D5A49EC00931E34 /* FLTCamFocusTests.swift in Sources */, 978D90B42D5F630300CD817E /* StreamingTests.swift in Sources */, - 7F29EB412D281C7E00740257 /* MockCaptureSession.m in Sources */, 7FCEDD352D43C2B900EA1CA8 /* MockDeviceOrientationProvider.m in Sources */, E11D6A8F2D81B81D0031E6C5 /* MockCaptureVideoDataOutput.swift in Sources */, 977CAC9F2D5E5180001E5DC3 /* ThreadSafeEventChannelTests.swift in Sources */, diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.swift index 9befe9865de..a9787b91fcf 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.swift @@ -23,7 +23,7 @@ final class CameraMethodChannelTests: XCTestCase { func testCreate_ShouldCallResultOnMainThread() { let avCaptureSessionMock = MockCaptureSession() - avCaptureSessionMock.canSetSessionPreset = true + avCaptureSessionMock.canSetSessionPresetStub = { _ in true } let camera = createCameraPlugin(with: avCaptureSessionMock) let expectation = self.expectation(description: "Result finished") @@ -48,7 +48,7 @@ final class CameraMethodChannelTests: XCTestCase { func testDisposeShouldDeallocCamera() { let avCaptureSessionMock = MockCaptureSession() - avCaptureSessionMock.canSetSessionPreset = true + avCaptureSessionMock.canSetSessionPresetStub = { _ in true } let camera = createCameraPlugin(with: avCaptureSessionMock) let createExpectation = self.expectation(description: "create's result block must be called") diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginCreateCameraTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginCreateCameraTests.swift index de38b7507d2..dd044b96909 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginCreateCameraTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPluginCreateCameraTests.swift @@ -109,7 +109,7 @@ final class CameraPluginCreateCameraTests: XCTestCase { // Permission is granted completion?(nil) } - mockCaptureSession.canSetSessionPreset = true + mockCaptureSession.canSetSessionPresetStub = { _ in true } cameraPlugin.createCamera( withName: "camera_name", diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.swift index 4be4db51554..a89f2cb4c02 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSessionPresetsTests.swift @@ -30,15 +30,16 @@ final class CameraSessionPresetsTests: XCTestCase { return true } - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureDeviceFactory = { captureDeviceMock } configuration.videoDimensionsForFormat = { format in return CMVideoDimensions(width: 1, height: 1) } configuration.videoCaptureSession = videoSessionMock - configuration.mediaSettings = FCPGetDefaultMediaSettings(FCPPlatformResolutionPreset.max) + configuration.mediaSettings = CameraTestUtils.createDefaultMediaSettings( + resolutionPreset: FCPPlatformResolutionPreset.max) - FLTCreateCamWithConfiguration(configuration) + let _ = FLTCam(configuration: configuration, error: nil) waitForExpectations(timeout: 30, handler: nil) } @@ -49,19 +50,20 @@ final class CameraSessionPresetsTests: XCTestCase { let videoSessionMock = MockCaptureSession() // Make sure that setting resolution preset for session always succeeds. - videoSessionMock.canSetSessionPreset = true + videoSessionMock.canSetSessionPresetStub = { _ in true } videoSessionMock.setSessionPresetStub = { preset in if preset == expectedPreset { expectation.fulfill() } } - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.videoCaptureSession = videoSessionMock - configuration.mediaSettings = FCPGetDefaultMediaSettings(FCPPlatformResolutionPreset.max) + configuration.mediaSettings = CameraTestUtils.createDefaultMediaSettings( + resolutionPreset: FCPPlatformResolutionPreset.max) configuration.captureDeviceFactory = { MockCaptureDevice() } - FLTCreateCamWithConfiguration(configuration) + let _ = FLTCam(configuration: configuration, error: nil) waitForExpectations(timeout: 30, handler: nil) } @@ -72,7 +74,7 @@ final class CameraSessionPresetsTests: XCTestCase { let videoSessionMock = MockCaptureSession() // Make sure that setting resolution preset for session always succeeds. - videoSessionMock.canSetSessionPreset = true + videoSessionMock.canSetSessionPresetStub = { _ in true } // Expect that setting "ultraHigh" resolutionPreset correctly updates videoCaptureSession. videoSessionMock.setSessionPresetStub = { preset in if preset == expectedPreset { @@ -80,11 +82,12 @@ final class CameraSessionPresetsTests: XCTestCase { } } - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.videoCaptureSession = videoSessionMock - configuration.mediaSettings = FCPGetDefaultMediaSettings(FCPPlatformResolutionPreset.ultraHigh) + configuration.mediaSettings = CameraTestUtils.createDefaultMediaSettings( + resolutionPreset: FCPPlatformResolutionPreset.ultraHigh) - FLTCreateCamWithConfiguration(configuration) + let _ = FLTCam(configuration: configuration, error: nil) waitForExpectations(timeout: 30, handler: nil) } diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift index c0e966a6d1f..c9fa64288be 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift @@ -118,10 +118,10 @@ final class CameraSettingsTests: XCTestCase { ) let injectedWrapper = TestMediaSettingsAVWrapper(test: self) - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.mediaSettingsWrapper = injectedWrapper configuration.mediaSettings = settings - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) // Expect FPS configuration is passed to camera device. wait( @@ -149,7 +149,7 @@ final class CameraSettingsTests: XCTestCase { func testSettings_ShouldBeSupportedByMethodCall() { let mockDevice = MockCaptureDevice() let mockSession = MockCaptureSession() - mockSession.canSetSessionPreset = true + mockSession.canSetSessionPresetStub = { _ in true } let camera = CameraPlugin( registry: MockFlutterTextureRegistry(), messenger: MockFlutterBinaryMessenger(), @@ -192,9 +192,9 @@ final class CameraSettingsTests: XCTestCase { enableAudio: testEnableAudio ) - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.mediaSettings = settings - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) let range = camera.captureDevice.activeFormat.videoSupportedFrameRateRanges[0] XCTAssertLessThanOrEqual(range.minFrameRate, 60) diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h deleted file mode 100644 index aae88cfa738..00000000000 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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 camera_avfoundation; -#if __has_include() -@import camera_avfoundation.Test; -#endif - -NS_ASSUME_NONNULL_BEGIN - -/// This method provides a convenient way to create media settings with minimal configuration. -/// Audio is enabled by default, while other parameters use platform-specific defaults. -extern FCPPlatformMediaSettings *FCPGetDefaultMediaSettings( - FCPPlatformResolutionPreset resolutionPreset); - -/// Creates a test `FLTCamConfiguration` with a default mock setup. -extern FLTCamConfiguration *FLTCreateTestCameraConfiguration(void); - -extern FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue); - -/// Creates an `FLTCam` with a test configuration. -extern FLTCam *FLTCreateCamWithConfiguration(FLTCamConfiguration *configuration); - -/// Creates a test sample buffer. -/// @return a test sample buffer. -extern CMSampleBufferRef FLTCreateTestSampleBuffer(void); - -/// Creates a test audio sample buffer. -/// @return a test audio sample buffer. -extern CMSampleBufferRef FLTCreateTestAudioSampleBuffer(void); - -/// Calls `dispatch_queue_set_specific` with a key that is used to identify the queue. -/// This method is needed for comaptibility of Swift tests with Objective-C code. -/// In Swift, the API for settinng key-value pairs on a queue is different, so Swift tests -/// need to call this method to set the key-value pair on the queue in a way that's -/// compatible withn the existing Objective-C code. -extern void FLTdispatchQueueSetSpecific(dispatch_queue_t queue, const void *key); - -NS_ASSUME_NONNULL_END diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m deleted file mode 100644 index 1e2f5f6bde0..00000000000 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.m +++ /dev/null @@ -1,133 +0,0 @@ -// 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 "CameraTestUtils.h" - -@import AVFoundation; -@import camera_avfoundation; - -#import "MockAssetWriter.h" -#import "MockCaptureDevice.h" -#import "MockCaptureDeviceFormat.h" -#import "MockCaptureSession.h" -#import "MockDeviceOrientationProvider.h" - -FCPPlatformMediaSettings *FCPGetDefaultMediaSettings(FCPPlatformResolutionPreset resolutionPreset) { - return [FCPPlatformMediaSettings makeWithResolutionPreset:resolutionPreset - framesPerSecond:nil - videoBitrate:nil - audioBitrate:nil - enableAudio:YES]; -} - -FLTCamConfiguration *FLTCreateTestCameraConfiguration(void) { - dispatch_queue_t captureSessionQueue = dispatch_queue_create("capture_session_queue", NULL); - - MockCaptureSession *videoSessionMock = [[MockCaptureSession alloc] init]; - videoSessionMock.canSetSessionPreset = YES; - - MockCaptureSession *audioSessionMock = [[MockCaptureSession alloc] init]; - audioSessionMock.canSetSessionPreset = YES; - - MockFrameRateRange *frameRateRangeMock1 = [[MockFrameRateRange alloc] initWithMinFrameRate:3 - maxFrameRate:30]; - MockCaptureDeviceFormat *captureDeviceFormatMock1 = [[MockCaptureDeviceFormat alloc] init]; - captureDeviceFormatMock1.videoSupportedFrameRateRanges = @[ frameRateRangeMock1 ]; - - MockFrameRateRange *frameRateRangeMock2 = [[MockFrameRateRange alloc] initWithMinFrameRate:3 - maxFrameRate:60]; - MockCaptureDeviceFormat *captureDeviceFormatMock2 = [[MockCaptureDeviceFormat alloc] init]; - captureDeviceFormatMock2.videoSupportedFrameRateRanges = @[ frameRateRangeMock2 ]; - - MockCaptureDevice *captureDeviceMock = [[MockCaptureDevice alloc] init]; - captureDeviceMock.lockForConfigurationStub = ^BOOL(NSError **error) { - return YES; - }; - captureDeviceMock.formats = @[ captureDeviceFormatMock1, captureDeviceFormatMock2 ]; - - __block NSObject *currentFormat = captureDeviceFormatMock1; - captureDeviceMock.activeFormatStub = ^NSObject * { - return currentFormat; - }; - captureDeviceMock.setActiveFormatStub = ^(NSObject *format) { - currentFormat = format; - }; - - FLTCamConfiguration *configuration = [[FLTCamConfiguration alloc] - initWithMediaSettings:FCPGetDefaultMediaSettings(FCPPlatformResolutionPresetMedium) - mediaSettingsWrapper:[[FLTCamMediaSettingsAVWrapper alloc] init] - captureDeviceFactory:^NSObject *(void) { - return captureDeviceMock; - } - captureSessionFactory:^NSObject *_Nonnull { - return videoSessionMock; - } - captureSessionQueue:captureSessionQueue - captureDeviceInputFactory:[[MockCaptureDeviceInputFactory alloc] init]]; - configuration.videoCaptureSession = videoSessionMock; - configuration.audioCaptureSession = audioSessionMock; - configuration.orientation = UIDeviceOrientationPortrait; - configuration.assetWriterFactory = - ^NSObject *(NSURL *url, AVFileType fileType, NSError **error) { - return [[MockAssetWriter alloc] init]; - }; - configuration.inputPixelBufferAdaptorFactory = ^NSObject *( - NSObject *input, NSDictionary *settings) { - return [[MockAssetWriterInputPixelBufferAdaptor alloc] init]; - }; - - return configuration; -} - -FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue) { - FLTCamConfiguration *configuration = FLTCreateTestCameraConfiguration(); - configuration.captureSessionQueue = captureSessionQueue; - return FLTCreateCamWithConfiguration(configuration); -} - -FLTCam *FLTCreateCamWithConfiguration(FLTCamConfiguration *configuration) { - return [[FLTCam alloc] initWithConfiguration:configuration error:nil]; -} - -CMSampleBufferRef FLTCreateTestSampleBuffer(void) { - CVPixelBufferRef pixelBuffer; - CVPixelBufferCreate(kCFAllocatorDefault, 100, 100, kCVPixelFormatType_32BGRA, NULL, &pixelBuffer); - - CMFormatDescriptionRef formatDescription; - CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, - &formatDescription); - - CMSampleTimingInfo timingInfo = {CMTimeMake(1, 44100), kCMTimeZero, kCMTimeInvalid}; - - CMSampleBufferRef sampleBuffer; - CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer, formatDescription, - &timingInfo, &sampleBuffer); - - CFRelease(pixelBuffer); - CFRelease(formatDescription); - return sampleBuffer; -} - -CMSampleBufferRef FLTCreateTestAudioSampleBuffer(void) { - CMBlockBufferRef blockBuffer; - CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, 100, kCFAllocatorDefault, NULL, 0, - 100, kCMBlockBufferAssureMemoryNowFlag, &blockBuffer); - - CMFormatDescriptionRef formatDescription; - AudioStreamBasicDescription basicDescription = {44100, kAudioFormatLinearPCM, 0, 1, 1, 1, 1, 8}; - CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &basicDescription, 0, NULL, 0, NULL, NULL, - &formatDescription); - - CMSampleBufferRef sampleBuffer; - CMAudioSampleBufferCreateReadyWithPacketDescriptions( - kCFAllocatorDefault, blockBuffer, formatDescription, 1, kCMTimeZero, NULL, &sampleBuffer); - - CFRelease(blockBuffer); - CFRelease(formatDescription); - return sampleBuffer; -} - -void FLTdispatchQueueSetSpecific(dispatch_queue_t queue, const void *key) { - dispatch_queue_set_specific(queue, key, (void *)key, NULL); -} diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.swift new file mode 100644 index 00000000000..e320beb9411 --- /dev/null +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.swift @@ -0,0 +1,161 @@ +// 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 Foundation + +/// Utils for creating default class instances used in tests +enum CameraTestUtils { + /// This method provides a convenient way to create media settings with minimal configuration. + /// Audio is enabled by default, while other parameters use platform-specific defaults. + static func createDefaultMediaSettings(resolutionPreset: FCPPlatformResolutionPreset) + -> FCPPlatformMediaSettings + { + return FCPPlatformMediaSettings.make( + with: resolutionPreset, + framesPerSecond: nil, + videoBitrate: nil, + audioBitrate: nil, + enableAudio: true) + } + + /// Creates a test `FLTCamConfiguration` with a default mock setup. + static func createTestCameraConfiguration() -> FLTCamConfiguration { + let captureSessionQueue = DispatchQueue(label: "capture_session_queue") + + let videoSessionMock = MockCaptureSession() + videoSessionMock.canSetSessionPresetStub = { _ in true } + + let audioSessionMock = MockCaptureSession() + audioSessionMock.canSetSessionPresetStub = { _ in true } + + let frameRateRangeMock1 = MockFrameRateRange.init(minFrameRate: 3, maxFrameRate: 30) + + let captureDeviceFormatMock1 = MockCaptureDeviceFormat() + captureDeviceFormatMock1.videoSupportedFrameRateRanges = [frameRateRangeMock1] + + let frameRateRangeMock2 = MockFrameRateRange.init(minFrameRate: 3, maxFrameRate: 60) + + let captureDeviceFormatMock2 = MockCaptureDeviceFormat() + captureDeviceFormatMock2.videoSupportedFrameRateRanges = [frameRateRangeMock2] + + let captureDeviceMock = MockCaptureDevice() + captureDeviceMock.lockForConfigurationStub = { _ in true } + captureDeviceMock.formats = [captureDeviceFormatMock1, captureDeviceFormatMock2] + + var currentFormat: FLTCaptureDeviceFormat = captureDeviceFormatMock1 + + captureDeviceMock.activeFormatStub = { currentFormat } + captureDeviceMock.setActiveFormatStub = { format in + currentFormat = format + } + + let configuration = FLTCamConfiguration( + mediaSettings: createDefaultMediaSettings( + resolutionPreset: FCPPlatformResolutionPreset.medium), + mediaSettingsWrapper: FLTCamMediaSettingsAVWrapper(), + captureDeviceFactory: { captureDeviceMock }, + captureSessionFactory: { videoSessionMock }, + captureSessionQueue: captureSessionQueue, + captureDeviceInputFactory: MockCaptureDeviceInputFactory() + ) + + configuration.videoCaptureSession = videoSessionMock + configuration.audioCaptureSession = audioSessionMock + configuration.orientation = .portrait + + configuration.assetWriterFactory = { _, _, _ in MockAssetWriter() } + + configuration.inputPixelBufferAdaptorFactory = { _, _ in + MockAssetWriterInputPixelBufferAdaptor() + } + + return configuration + } + + static func createCameraWithCaptureSessionQueue(_ captureSessionQueue: DispatchQueue) -> FLTCam { + let configuration = createTestCameraConfiguration() + configuration.captureSessionQueue = captureSessionQueue + return FLTCam(configuration: configuration, error: nil) + } + + /// Creates a test sample buffer. + /// @return a test sample buffer. + static func createTestSampleBuffer() -> CMSampleBuffer { + var pixelBuffer: CVPixelBuffer? + CVPixelBufferCreate(kCFAllocatorDefault, 100, 100, kCVPixelFormatType_32BGRA, nil, &pixelBuffer) + + var formatDescription: CMFormatDescription? + CMVideoFormatDescriptionCreateForImageBuffer( + allocator: kCFAllocatorDefault, + imageBuffer: pixelBuffer!, + formatDescriptionOut: &formatDescription) + + var timingInfo = CMSampleTimingInfo( + duration: CMTimeMake(value: 1, timescale: 44100), + presentationTimeStamp: CMTime.zero, + decodeTimeStamp: CMTime.invalid) + + var sampleBuffer: CMSampleBuffer? + CMSampleBufferCreateReadyWithImageBuffer( + allocator: kCFAllocatorDefault, + imageBuffer: pixelBuffer!, + formatDescription: formatDescription!, + sampleTiming: &timingInfo, + sampleBufferOut: &sampleBuffer) + + return sampleBuffer! + } + + /// Creates a test audio sample buffer. + /// @return a test audio sample buffer. + static func createTestAudioSampleBuffer() -> CMSampleBuffer? { + var blockBuffer: CMBlockBuffer? + CMBlockBufferCreateWithMemoryBlock( + allocator: kCFAllocatorDefault, + memoryBlock: nil, + blockLength: 100, + blockAllocator: kCFAllocatorDefault, + customBlockSource: nil, + offsetToData: 0, + dataLength: 100, + flags: kCMBlockBufferAssureMemoryNowFlag, + blockBufferOut: &blockBuffer) + + guard let blockBuffer = blockBuffer else { return nil } + + var formatDescription: CMFormatDescription? + var basicDescription = AudioStreamBasicDescription( + mSampleRate: 44100, + mFormatID: kAudioFormatLinearPCM, + mFormatFlags: 0, + mBytesPerPacket: 1, + mFramesPerPacket: 1, + mBytesPerFrame: 1, + mChannelsPerFrame: 1, + mBitsPerChannel: 8, + mReserved: 0) + + CMAudioFormatDescriptionCreate( + allocator: kCFAllocatorDefault, + asbd: &basicDescription, + layoutSize: 0, + layout: nil, + magicCookieSize: 0, + magicCookie: nil, + extensions: nil, + formatDescriptionOut: &formatDescription) + + var sampleBuffer: CMSampleBuffer? + CMAudioSampleBufferCreateReadyWithPacketDescriptions( + allocator: kCFAllocatorDefault, + dataBuffer: blockBuffer, + formatDescription: formatDescription!, + sampleCount: 1, + presentationTimeStamp: .zero, + packetDescriptions: nil, + sampleBufferOut: &sampleBuffer) + + return sampleBuffer + } +} diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamExposureTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamExposureTests.swift index faa61949da0..d6f0845c4bd 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamExposureTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamExposureTests.swift @@ -11,10 +11,10 @@ final class FLTCamExposureTests: XCTestCase { let mockDevice = MockCaptureDevice() let mockDeviceOrientationProvider = MockDeviceOrientationProvider() - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureDeviceFactory = { mockDevice } configuration.deviceOrientationProvider = mockDeviceOrientationProvider - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) return (camera, mockDevice, mockDeviceOrientationProvider) } diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamFocusTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamFocusTests.swift index 3d46e91c3fa..9bb3c2afbbf 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamFocusTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamFocusTests.swift @@ -12,10 +12,10 @@ final class FLTCamSetFocusModeTests: XCTestCase { let mockDevice = MockCaptureDevice() let mockDeviceOrientationProvider = MockDeviceOrientationProvider() - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureDeviceFactory = { mockDevice } configuration.deviceOrientationProvider = mockDeviceOrientationProvider - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) return (camera, mockDevice, mockDeviceOrientationProvider) } diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift index 5829d54313f..68bad3a1c2f 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetDeviceOrientationTests.swift @@ -9,8 +9,8 @@ import XCTest final class FLTCamSetDeviceOrientationTests: XCTestCase { private func createCamera() -> (FLTCam, MockCaptureConnection, MockCaptureConnection) { - let configuration = FLTCreateTestCameraConfiguration() - let camera = FLTCreateCamWithConfiguration(configuration) + let configuration = CameraTestUtils.createTestCameraConfiguration() + let camera = FLTCam(configuration: configuration, error: nil) let mockCapturePhotoOutput = MockCapturePhotoOutput() let mockPhotoCaptureConnection = MockCaptureConnection() diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetFlashModeTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetFlashModeTests.swift index 91fe75b0bc2..f70ce530c6b 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetFlashModeTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSetFlashModeTests.swift @@ -12,9 +12,9 @@ final class FLTCamSetFlashModeTests: XCTestCase { let mockDevice = MockCaptureDevice() let mockCapturePhotoOutput = MockCapturePhotoOutput() - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureDeviceFactory = { mockDevice } - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) camera.capturePhotoOutput = mockCapturePhotoOutput return (camera, mockDevice, mockCapturePhotoOutput) diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamZoomTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamZoomTests.swift index 09906dc794f..57c340afcfc 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamZoomTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamZoomTests.swift @@ -11,9 +11,9 @@ final class FLTCamZoomTests: XCTestCase { private func createCamera() -> (FLTCam, MockCaptureDevice) { let mockDevice = MockCaptureDevice() - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureDeviceFactory = { mockDevice } - let camera = FLTCreateCamWithConfiguration(configuration) + let camera = FLTCam(configuration: configuration, error: nil) return (camera, mockDevice) } diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.h deleted file mode 100644 index beb3054b776..00000000000 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.h +++ /dev/null @@ -1,33 +0,0 @@ -// 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 camera_avfoundation; -#if __has_include() -@import camera_avfoundation.Test; -#endif -@import AVFoundation; - -NS_ASSUME_NONNULL_BEGIN - -/// Mock implementation of `FLTCaptureSession` protocol which allows injecting a custom -/// implementation. -@interface MockCaptureSession : NSObject - -// Stubs that are called when the corresponding public method is called. -@property(nonatomic, copy) void (^beginConfigurationStub)(void); -@property(nonatomic, copy) void (^commitConfigurationStub)(void); -@property(nonatomic, copy) void (^startRunningStub)(void); -@property(nonatomic, copy) void (^stopRunningStub)(void); -@property(nonatomic, copy) void (^setSessionPresetStub)(AVCaptureSessionPreset preset); - -// Properties re-declared as read/write so a mocked value can be set during testing. -@property(nonatomic, strong) NSMutableArray *inputs; -@property(nonatomic, strong) NSMutableArray *outputs; -@property(nonatomic, assign) BOOL canSetSessionPreset; -@property(nonatomic, copy) AVCaptureSessionPreset sessionPreset; -@property(nonatomic, assign) BOOL automaticallyConfiguresApplicationAudioSession; - -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.m deleted file mode 100644 index eb1dee86495..00000000000 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.m +++ /dev/null @@ -1,85 +0,0 @@ -// 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 "MockCaptureSession.h" - -@implementation MockCaptureSession - -- (instancetype)init { - self = [super init]; - if (self) { - _inputs = [NSMutableArray array]; - _outputs = [NSMutableArray array]; - } - return self; -} - -- (void)beginConfiguration { - if (self.beginConfigurationStub) { - self.beginConfigurationStub(); - } -} - -- (void)commitConfiguration { - if (self.commitConfigurationStub) { - self.commitConfigurationStub(); - } -} - -- (void)startRunning { - if (self.startRunningStub) { - self.startRunningStub(); - } -} - -- (void)stopRunning { - if (self.stopRunningStub) { - self.stopRunningStub(); - } -} - -- (BOOL)canSetSessionPreset:(AVCaptureSessionPreset)preset { - return self.canSetSessionPreset; -} - -- (void)addConnection:(nonnull AVCaptureConnection *)connection { -} - -- (void)addInput:(nonnull NSObject *)input { -} - -- (void)addInputWithNoConnections:(nonnull NSObject *)input { -} - -- (void)addOutput:(nonnull AVCaptureOutput *)output { -} - -- (void)addOutputWithNoConnections:(nonnull AVCaptureOutput *)output { -} - -- (BOOL)canAddConnection:(nonnull AVCaptureConnection *)connection { - return YES; -} - -- (BOOL)canAddInput:(nonnull NSObject *)input { - return YES; -} - -- (BOOL)canAddOutput:(nonnull AVCaptureOutput *)output { - return YES; -} - -- (void)removeInput:(nonnull NSObject *)input { -} - -- (void)removeOutput:(nonnull AVCaptureOutput *)output { -} - -- (void)setSessionPreset:(AVCaptureSessionPreset)sessionPreset { - if (self.setSessionPresetStub) { - self.setSessionPresetStub(sessionPreset); - } -} - -@end diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.swift new file mode 100644 index 00000000000..b249f08ea12 --- /dev/null +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockCaptureSession.swift @@ -0,0 +1,74 @@ +// 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. + +/// Mock implementation of `FLTCaptureSession` protocol which allows injecting a custom +/// implementation. +final class MockCaptureSession: NSObject, FLTCaptureSession { + var setSessionPresetStub: ((AVCaptureSession.Preset) -> Void)? + var beginConfigurationStub: (() -> Void)? + var commitConfigurationStub: (() -> Void)? + var startRunningStub: (() -> Void)? + var stopRunningStub: (() -> Void)? + var canSetSessionPresetStub: ((AVCaptureSession.Preset) -> Bool)? + + var _sessionPreset = AVCaptureSession.Preset.high + var inputs = [AVCaptureInput]() + var outputs = [AVCaptureOutput]() + var automaticallyConfiguresApplicationAudioSession = false + + var sessionPreset: AVCaptureSession.Preset { + get { + return _sessionPreset + } + set { + setSessionPresetStub?(newValue) + } + } + + func beginConfiguration() { + beginConfigurationStub?() + } + + func commitConfiguration() { + commitConfigurationStub?() + } + + func startRunning() { + startRunningStub?() + } + + func stopRunning() { + stopRunningStub?() + } + + func canSetSessionPreset(_ preset: AVCaptureSession.Preset) -> Bool { + return canSetSessionPresetStub?(preset) ?? true + } + + func addInputWithNoConnections(_ input: FLTCaptureInput) {} + + func addOutputWithNoConnections(_ output: AVCaptureOutput) {} + + func addConnection(_: AVCaptureConnection) {} + + func addInput(_: FLTCaptureInput) {} + + func addOutput(_: AVCaptureOutput) {} + + func removeInput(_: FLTCaptureInput) {} + + func removeOutput(_: AVCaptureOutput) {} + + func canAddInput(_: FLTCaptureInput) -> Bool { + return true + } + + func canAddOutput(_: AVCaptureOutput) -> Bool { + return true + } + + func canAddConnection(_: AVCaptureConnection) -> Bool { + return true + } +} diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/PhotoCaptureTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/PhotoCaptureTests.swift index 5ff4dc0c69a..58ccc013131 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/PhotoCaptureTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/PhotoCaptureTests.swift @@ -10,16 +10,16 @@ import XCTest /// Includes test cases related to photo capture operations for FLTCam class. final class PhotoCaptureTests: XCTestCase { private func createCam(with captureSessionQueue: DispatchQueue) -> FLTCam { - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureSessionQueue = captureSessionQueue - return FLTCreateCamWithConfiguration(configuration) + return FLTCam(configuration: configuration, error: nil) } func testCaptureToFile_mustReportErrorToResultIfSavePhotoDelegateCompletionsWithError() { let errorExpectation = expectation( description: "Must send error to result if save photo delegate completes with error.") let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - FLTdispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) + FLTDispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) let cam = createCam(with: captureSessionQueue) let error = NSError(domain: "test", code: 0, userInfo: nil) @@ -52,7 +52,7 @@ final class PhotoCaptureTests: XCTestCase { let pathExpectation = expectation( description: "Must send file path to result if save photo delegate completes with file path.") let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - FLTdispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) + FLTDispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) let cam = createCam(with: captureSessionQueue) let filePath = "test" @@ -85,7 +85,7 @@ final class PhotoCaptureTests: XCTestCase { description: "Test must set extension to heif if availablePhotoCodecTypes contains HEVC.") let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - FLTdispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) + FLTDispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) let cam = createCam(with: captureSessionQueue) cam.setImageFileFormat(FCPPlatformImageFileFormat.heif) @@ -120,7 +120,7 @@ final class PhotoCaptureTests: XCTestCase { "Test must set extension to jpg if availablePhotoCodecTypes does not contain HEVC.") let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - FLTdispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) + FLTDispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) let cam = createCam(with: captureSessionQueue) cam.setImageFileFormat(FCPPlatformImageFileFormat.heif) @@ -165,11 +165,11 @@ final class PhotoCaptureTests: XCTestCase { } let captureSessionQueue = DispatchQueue(label: "capture_session_queue") - FLTdispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) - let configuration = FLTCreateTestCameraConfiguration() + FLTDispatchQueueSetSpecific(captureSessionQueue, FLTCaptureSessionQueueSpecific) + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureSessionQueue = captureSessionQueue configuration.captureDeviceFactory = { captureDeviceMock } - let cam = FLTCreateCamWithConfiguration(configuration) + let cam = FLTCam(configuration: configuration, error: nil) let filePath = "test" let mockOutput = MockCapturePhotoOutput() diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.h new file mode 100644 index 00000000000..ea8e90e821e --- /dev/null +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.h @@ -0,0 +1,19 @@ +// 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 camera_avfoundation; +#if __has_include() +@import camera_avfoundation.Test; +#endif + +NS_ASSUME_NONNULL_BEGIN + +/// Calls `dispatch_queue_set_specific` with a key that is used to identify the queue. +/// This method is needed for comaptibility of Swift tests with Objective-C code. +/// In Swift, the API for settinng key-value pairs on a queue is different, so Swift tests +/// need to call this method to set the key-value pair on the queue in a way that's +/// compatible with the existing Objective-C code. +extern void FLTDispatchQueueSetSpecific(dispatch_queue_t queue, const void *key); + +NS_ASSUME_NONNULL_END diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.m new file mode 100644 index 00000000000..32198b7f461 --- /dev/null +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueTestUtils.m @@ -0,0 +1,11 @@ +// 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 "QueueTestUtils.h" + +@import camera_avfoundation; + +void FLTDispatchQueueSetSpecific(dispatch_queue_t queue, const void *key) { + dispatch_queue_set_specific(queue, key, (void *)key, NULL); +} diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/RunnerTests-Bridging-Header.h index bf3b2bd9e3c..8316eb929cd 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/RunnerTests-Bridging-Header.h +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/RunnerTests-Bridging-Header.h @@ -17,12 +17,11 @@ #import "MockCaptureDevice.h" #import "MockCaptureDeviceFormat.h" #import "MockCapturePhotoOutput.h" -#import "MockCaptureSession.h" #import "MockDeviceOrientationProvider.h" #import "MockFlutterBinaryMessenger.h" #import "MockFlutterTextureRegistry.h" #import "MockGlobalEventApi.h" // Utils. -#import "CameraTestUtils.h" #import "ExceptionCatcher.h" +#import "QueueTestUtils.h" diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift index 6ea6773c870..bb8e18ed827 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift @@ -74,7 +74,7 @@ final class CameraSampleBufferTests: XCTestCase { let adaptor = MockAssetWriterInputPixelBufferAdaptor() let input = MockAssetWriterInput() - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.mediaSettings = FCPPlatformMediaSettings.make( with: .medium, framesPerSecond: nil, @@ -91,14 +91,14 @@ final class CameraSampleBufferTests: XCTestCase { } return ( - FLTCreateCamWithConfiguration(configuration), assetWriter, adaptor, input, + FLTCam(configuration: configuration, error: nil), assetWriter, adaptor, input, MockCaptureConnection() ) } func testSampleBufferCallbackQueueMustBeCaptureSessionQueue() { let captureSessionQueue = DispatchQueue(label: "testing") - let camera = FLTCreateCamWithCaptureSessionQueue(captureSessionQueue) + let camera = CameraTestUtils.createCameraWithCaptureSessionQueue(captureSessionQueue) XCTAssertEqual( captureSessionQueue, camera.captureVideoOutput.avOutput.sampleBufferCallbackQueue, "Sample buffer callback queue must be the capture session queue.") @@ -106,7 +106,7 @@ final class CameraSampleBufferTests: XCTestCase { func testCopyPixelBuffer() { let (camera, _, _, _, connectionMock) = createCamera() - let capturedSampleBuffer = FLTCreateTestSampleBuffer().takeRetainedValue() + let capturedSampleBuffer = CameraTestUtils.createTestSampleBuffer() let capturedPixelBuffer = CMSampleBufferGetImageBuffer(capturedSampleBuffer)! // Mimic sample buffer callback when captured a new video sample. camera.captureOutput( @@ -120,7 +120,7 @@ final class CameraSampleBufferTests: XCTestCase { func testDidOutputSampleBuffer_mustNotChangeSampleBufferRetainCountAfterPauseResumeRecording() { let (camera, _, _, _, connectionMock) = createCamera() - let sampleBuffer = FLTCreateTestSampleBuffer().takeRetainedValue() + let sampleBuffer = CameraTestUtils.createTestSampleBuffer() let initialRetainCount = CFGetRetainCount(sampleBuffer) @@ -149,8 +149,8 @@ final class CameraSampleBufferTests: XCTestCase { return status } - let videoSample = FLTCreateTestSampleBuffer().takeRetainedValue() - let audioSample = FLTCreateTestAudioSampleBuffer().takeRetainedValue() + let videoSample = CameraTestUtils.createTestSampleBuffer() + let audioSample = CameraTestUtils.createTestAudioSampleBuffer() var writtenSamples: [String] = [] adaptorMock.appendPixelBufferStub = { buffer, time in @@ -177,8 +177,8 @@ final class CameraSampleBufferTests: XCTestCase { func testDidOutputSampleBufferSampleTimesMustBeNumericAfterPauseResume() { let (camera, writerMock, adaptorMock, inputMock, connectionMock) = createCamera() - let videoSample = FLTCreateTestSampleBuffer().takeRetainedValue() - let audioSample = FLTCreateTestAudioSampleBuffer().takeRetainedValue() + let videoSample = CameraTestUtils.createTestSampleBuffer() + let audioSample = CameraTestUtils.createTestAudioSampleBuffer() var status = AVAssetWriter.Status.unknown writerMock.startWritingStub = { @@ -220,7 +220,7 @@ final class CameraSampleBufferTests: XCTestCase { func testDidOutputSampleBufferMustNotAppendSampleWhenReadyForMoreMediaDataIsFalse() { let (camera, _, adaptorMock, inputMock, connectionMock) = createCamera() - let videoSample = FLTCreateTestSampleBuffer().takeRetainedValue() + let videoSample = CameraTestUtils.createTestSampleBuffer() var sampleAppended = false adaptorMock.appendPixelBufferStub = { buffer, time in @@ -273,7 +273,7 @@ final class CameraSampleBufferTests: XCTestCase { func testStartWritingShouldNotBeCalledBetweenSampleCreationAndAppending() { let (camera, writerMock, adaptorMock, inputMock, connectionMock) = createCamera() - let videoSample = FLTCreateTestSampleBuffer().takeRetainedValue() + let videoSample = CameraTestUtils.createTestSampleBuffer() var startWritingCalled = false writerMock.startWritingStub = { @@ -303,7 +303,7 @@ final class CameraSampleBufferTests: XCTestCase { } func testStartVideoRecordingWithCompletionShouldNotDisableMixWithOthers() { - let cam = FLTCreateCamWithCaptureSessionQueue(DispatchQueue(label: "testing")) + let cam = CameraTestUtils.createCameraWithCaptureSessionQueue(DispatchQueue(label: "testing")) try? AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers) cam.startVideoRecording(completion: { error in }, messengerForStreaming: nil) diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTests.swift index 2acae46f983..f164bb6e9a2 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTests.swift @@ -29,11 +29,11 @@ private class MockImageStreamHandler: FLTImageStreamHandler { final class StreamingTests: XCTestCase { private func createCamera() -> (FLTCam, CMSampleBuffer) { let captureSessionQueue = DispatchQueue(label: "testing") - let configuration = FLTCreateTestCameraConfiguration() + let configuration = CameraTestUtils.createTestCameraConfiguration() configuration.captureSessionQueue = captureSessionQueue - let camera = FLTCreateCamWithConfiguration(configuration) - let sampleBuffer = FLTCreateTestSampleBuffer().takeRetainedValue() + let camera = FLTCam(configuration: configuration, error: nil) + let sampleBuffer = CameraTestUtils.createTestSampleBuffer() return (camera, sampleBuffer) } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCaptureSession.h b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCaptureSession.h index 8d8aa21816e..473f1a2ef0a 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCaptureSession.h +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/include/camera_avfoundation/FLTCaptureSession.h @@ -24,14 +24,15 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)canSetSessionPreset:(AVCaptureSessionPreset)preset; - (void)addInputWithNoConnections:(NSObject *)input; - (void)addOutputWithNoConnections:(AVCaptureOutput *)output; -- (void)addConnection:(AVCaptureConnection *)connection; -- (void)addOutput:(AVCaptureOutput *)output; -- (void)removeInput:(NSObject *)input; -- (void)removeOutput:(AVCaptureOutput *)output; -- (BOOL)canAddInput:(NSObject *)input; -- (BOOL)canAddOutput:(AVCaptureOutput *)output; -- (BOOL)canAddConnection:(AVCaptureConnection *)connection; -- (void)addInput:(NSObject *)input; +// Methods renamed in Swift for consistency with AVCaptureSession Swift interface. +- (void)addConnection:(AVCaptureConnection *)connection NS_SWIFT_NAME(addConnection(_:)); +- (void)addInput:(NSObject *)input NS_SWIFT_NAME(addInput(_:)); +- (void)addOutput:(AVCaptureOutput *)output NS_SWIFT_NAME(addOutput(_:)); +- (void)removeInput:(NSObject *)input NS_SWIFT_NAME(removeInput(_:)); +- (void)removeOutput:(AVCaptureOutput *)output NS_SWIFT_NAME(removeOutput(_:)); +- (BOOL)canAddInput:(NSObject *)input NS_SWIFT_NAME(canAddInput(_:)); +- (BOOL)canAddOutput:(AVCaptureOutput *)output NS_SWIFT_NAME(canAddOutput(_:)); +- (BOOL)canAddConnection:(AVCaptureConnection *)connection NS_SWIFT_NAME(canAddConnection(_:)); @end diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index 4b9e4d459f9..7605730d9ce 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.18+11 +version: 0.9.18+12 environment: sdk: ^3.4.0