Skip to content

Commit

Permalink
Use DI for mocking dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
mchudy committed Dec 30, 2024
1 parent c21efc0 commit c597ad3
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 31 deletions.
3 changes: 2 additions & 1 deletion packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT
## 0.9.17+6

* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
* Introduces new protocols `FLTCaptureDeviceControlling` and `FLTDeviceOrientationProviding`

## 0.9.17+5

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
7F56D0382D1EDDCE005676A5 /* CameraPermissionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0B0D2BA27DFF2AF00E71E4B /* CameraPermissionTests.m */; };
7F87E8022D01FD6F00A3549C /* MockCaptureDeviceController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F87E8012D01FD5600A3549C /* MockCaptureDeviceController.m */; };
7F87E80C2D0325D900A3549C /* MockDeviceOrientationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F87E80B2D0325D700A3549C /* MockDeviceOrientationProvider.m */; };
7FA99E592D22C75300582559 /* CameraExposureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FA99E582D22C75300582559 /* CameraExposureTests.m */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
Expand Down Expand Up @@ -82,6 +83,7 @@
7F87E8032D02FF8C00A3549C /* MockCaptureDeviceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockCaptureDeviceController.h; sourceTree = "<group>"; };
7F87E80A2D0325B200A3549C /* MockDeviceOrientationProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockDeviceOrientationProvider.h; sourceTree = "<group>"; };
7F87E80B2D0325D700A3549C /* MockDeviceOrientationProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockDeviceOrientationProvider.m; sourceTree = "<group>"; };
7FA99E582D22C75300582559 /* CameraExposureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraExposureTests.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -140,6 +142,7 @@
7F87E8012D01FD5600A3549C /* MockCaptureDeviceController.m */,
7D5FCCD32AEF9D0200FB7108 /* CameraSettingsTests.m */,
03BB766A2665316900CE5A93 /* CameraFocusTests.m */,
7FA99E582D22C75300582559 /* CameraExposureTests.m */,
03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */,
03BB766C2665316900CE5A93 /* Info.plist */,
033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */,
Expand Down Expand Up @@ -462,6 +465,7 @@
03BB766B2665316900CE5A93 /* CameraFocusTests.m in Sources */,
7F87E8022D01FD6F00A3549C /* MockCaptureDeviceController.m in Sources */,
7D5FCCD42AEF9D0200FB7108 /* CameraSettingsTests.m in Sources */,
7FA99E592D22C75300582559 /* CameraExposureTests.m in Sources */,
E487C86026D686A10034AC92 /* CameraPreviewPauseTests.m in Sources */,
7F87E80C2D0325D900A3549C /* MockDeviceOrientationProvider.m in Sources */,
E071CF7427B31DE4006EF3BA /* FLTCamSampleBufferTests.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import XCTest;
@import AVFoundation;

#import "CameraTestUtils.h"
#import "MockCaptureDeviceController.h"
#import "MockDeviceOrientationProvider.h"

Expand All @@ -18,12 +19,16 @@ @interface CameraExposureTests : XCTestCase
@implementation CameraExposureTests

- (void)setUp {
_camera = [[FLTCam alloc] init];
_mockDevice = [[MockCaptureDeviceController alloc] init];
MockCaptureDeviceController *mockDevice = [[MockCaptureDeviceController alloc] init];
_mockDeviceOrientationProvider = [[MockDeviceOrientationProvider alloc] init];
_mockDevice = mockDevice;

[_camera setValue:_mockDevice forKey:@"captureDevice"];
[_camera setValue:_mockDeviceOrientationProvider forKey:@"deviceOrientationProvider"];
_camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
nil, nil, nil,
^id<FLTCaptureDeviceControlling>(void) {
return mockDevice;
},
_mockDeviceOrientationProvider);
}

- (void)testSetExposurePointWithResult_SetsExposurePointOfInterest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@import XCTest;
@import AVFoundation;

#import "CameraTestUtils.h"
#import "MockCaptureDeviceController.h"
#import "MockDeviceOrientationProvider.h"

Expand All @@ -21,12 +22,16 @@ @interface CameraFocusTests : XCTestCase
@implementation CameraFocusTests

- (void)setUp {
_camera = [[FLTCam alloc] init];
_mockDevice = [[MockCaptureDeviceController alloc] init];
MockCaptureDeviceController *mockDevice = [[MockCaptureDeviceController alloc] init];
_mockDevice = mockDevice;
_mockDeviceOrientationProvider = [[MockDeviceOrientationProvider alloc] init];

[_camera setValue:_mockDevice forKey:@"captureDevice"];
[_camera setValue:_mockDeviceOrientationProvider forKey:@"deviceOrientationProvider"];
_camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
nil, nil, nil,
^id<FLTCaptureDeviceControlling>(void) {
return mockDevice;
},
_mockDeviceOrientationProvider);
}

- (void)testAutoFocusWithContinuousModeSupported_ShouldSetContinuousAutoFocus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ - (void)testSettings_shouldPassConfigurationToCameraDeviceAndWriter {
[[TestMediaSettingsAVWrapper alloc] initWithTestCase:self];

FLTCam *camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
dispatch_queue_create("test", NULL), settings, injectedWrapper, nil);
dispatch_queue_create("test", NULL), settings, injectedWrapper, nil, nil);

// Expect FPS configuration is passed to camera device.
[self waitForExpectations:@[
Expand Down Expand Up @@ -211,7 +211,7 @@ - (void)testSettings_ShouldSelectFormatWhichSupports60FPS {
enableAudio:gTestEnableAudio];

FLTCam *camera = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
dispatch_queue_create("test", NULL), settings, nil, nil);
dispatch_queue_create("test", NULL), settings, nil, nil, nil);

AVFrameRateRange *range = camera.captureDevice.activeFormat.videoSupportedFrameRateRanges[0];
XCTAssertLessThanOrEqual(range.minFrameRate, 60);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ extern FLTCam *_Nullable FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
dispatch_queue_t _Nullable captureSessionQueue,
FCPPlatformMediaSettings *_Nullable mediaSettings,
FLTCamMediaSettingsAVWrapper *_Nullable mediaSettingsAVWrapper,
CaptureDeviceFactory _Nullable captureDeviceFactory);
CaptureDeviceFactory _Nullable captureDeviceFactory,
id<FLTDeviceOrientationProviding> _Nullable deviceOrientationProvider);

extern FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
@import AVFoundation;
@import camera_avfoundation;

#import "MockDeviceOrientationProvider.h"

static FCPPlatformMediaSettings *FCPGetDefaultMediaSettings(
FCPPlatformResolutionPreset resolutionPreset) {
return [FCPPlatformMediaSettings makeWithResolutionPreset:resolutionPreset
Expand All @@ -18,13 +20,14 @@
}

FLTCam *FLTCreateCamWithCaptureSessionQueue(dispatch_queue_t captureSessionQueue) {
return FLTCreateCamWithCaptureSessionQueueAndMediaSettings(captureSessionQueue, nil, nil, nil);
return FLTCreateCamWithCaptureSessionQueueAndMediaSettings(captureSessionQueue, nil, nil, nil,
nil);
}

FLTCam *FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
dispatch_queue_t captureSessionQueue, FCPPlatformMediaSettings *mediaSettings,
FLTCamMediaSettingsAVWrapper *mediaSettingsAVWrapper,
CaptureDeviceFactory captureDeviceFactory) {
FLTCamMediaSettingsAVWrapper *mediaSettingsAVWrapper, CaptureDeviceFactory captureDeviceFactory,
id<FLTDeviceOrientationProviding> deviceOrientationProvider) {
if (!mediaSettings) {
mediaSettings = FCPGetDefaultMediaSettings(FCPPlatformResolutionPresetMedium);
}
Expand All @@ -33,6 +36,10 @@
mediaSettingsAVWrapper = [[FLTCamMediaSettingsAVWrapper alloc] init];
}

if (!deviceOrientationProvider) {
deviceOrientationProvider = [[MockDeviceOrientationProvider alloc] init];
}

id inputMock = OCMClassMock([AVCaptureDeviceInput class]);
OCMStub([inputMock deviceInputWithDevice:[OCMArg any] error:[OCMArg setTo:nil]])
.andReturn(inputMock);
Expand Down Expand Up @@ -94,6 +101,7 @@
videoDimensionsForFormat:^CMVideoDimensions(AVCaptureDeviceFormat *format) {
return CMVideoFormatDescriptionGetDimensions(format.formatDescription);
}
deviceOrientationProvider:deviceOrientationProvider
error:nil];

id captureVideoDataOutputMock = [OCMockObject niceMockForClass:[AVCaptureVideoDataOutput class]];
Expand Down Expand Up @@ -156,17 +164,18 @@
OCMStub([audioSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);

return [[FLTCam alloc]
initWithMediaSettings:FCPGetDefaultMediaSettings(resolutionPreset)
mediaSettingsAVWrapper:[[FLTCamMediaSettingsAVWrapper alloc] init]
orientation:UIDeviceOrientationPortrait
videoCaptureSession:captureSession
audioCaptureSession:audioSessionMock
captureSessionQueue:dispatch_queue_create("capture_session_queue", NULL)
captureDeviceFactory:^id<FLTCaptureDeviceControlling>(void) {
return [[FLTDefaultCaptureDeviceController alloc] initWithDevice:captureDevice];
}
videoDimensionsForFormat:videoDimensionsForFormat
error:nil];
initWithMediaSettings:FCPGetDefaultMediaSettings(resolutionPreset)
mediaSettingsAVWrapper:[[FLTCamMediaSettingsAVWrapper alloc] init]
orientation:UIDeviceOrientationPortrait
videoCaptureSession:captureSession
audioCaptureSession:audioSessionMock
captureSessionQueue:dispatch_queue_create("capture_session_queue", NULL)
captureDeviceFactory:^id<FLTCaptureDeviceControlling>(void) {
return [[FLTDefaultCaptureDeviceController alloc] initWithDevice:captureDevice];
}
videoDimensionsForFormat:videoDimensionsForFormat
deviceOrientationProvider:[[MockDeviceOrientationProvider alloc] init]
error:nil];
}

CMSampleBufferRef FLTCreateTestSampleBuffer(void) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,11 @@ - (void)testCaptureToFile_handlesTorchMode {
(void *)FLTCaptureSessionQueueSpecific, NULL);

FLTCam *cam = FLTCreateCamWithCaptureSessionQueueAndMediaSettings(
captureSessionQueue, nil, nil, ^id<FLTCaptureDeviceControlling>(void) {
captureSessionQueue, nil, nil,
^id<FLTCaptureDeviceControlling>(void) {
return [[FLTDefaultCaptureDeviceController alloc] initWithDevice:captureDeviceMock];
});
},
nil);

AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
id mockSettings = OCMClassMock([AVCapturePhotoSettings class]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
videoDimensionsForFormat:^CMVideoDimensions(AVCaptureDeviceFormat *format) {
return CMVideoFormatDescriptionGetDimensions(format.formatDescription);
}
deviceOrientationProvider:[[FLTDefaultDeviceOrientationProvider alloc] init]
error:error];
}

Expand Down Expand Up @@ -217,6 +218,7 @@ - (instancetype)initWithMediaSettings:(FCPPlatformMediaSettings *)mediaSettings
captureSessionQueue:(dispatch_queue_t)captureSessionQueue
captureDeviceFactory:(CaptureDeviceFactory)captureDeviceFactory
videoDimensionsForFormat:(VideoDimensionsForFormat)videoDimensionsForFormat
deviceOrientationProvider:(id<FLTDeviceOrientationProviding>)deviceOrientationProvider
error:(NSError **)error {
self = [super init];
NSAssert(self, @"super init cannot be nil");
Expand Down Expand Up @@ -266,7 +268,7 @@ - (instancetype)initWithMediaSettings:(FCPPlatformMediaSettings *)mediaSettings
_motionManager = [[CMMotionManager alloc] init];
[_motionManager startAccelerometerUpdates];

_deviceOrientationProvider = [[FLTDefaultDeviceOrientationProvider alloc] init];
_deviceOrientationProvider = deviceOrientationProvider;

if (_mediaSettings.framesPerSecond) {
// The frame rate can be changed only on a locked for configuration device.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#import "FLTCam.h"
#import "FLTCaptureDeviceControlling.h"
#import "FLTDeviceOrientationProviding.h"
#import "FLTSavePhotoDelegate.h"

/// Determines the video dimensions (width and height) for a given capture device format.
Expand Down Expand Up @@ -75,6 +76,7 @@ typedef id<FLTCaptureDeviceControlling> (^CaptureDeviceFactory)(void);
captureSessionQueue:(dispatch_queue_t)captureSessionQueue
captureDeviceFactory:(CaptureDeviceFactory)captureDeviceFactory
videoDimensionsForFormat:(VideoDimensionsForFormat)videoDimensionsForFormat
deviceOrientationProvider:(id<FLTDeviceOrientationProviding>)deviceOrientationProvider
error:(NSError **)error;

/// Start streaming images.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
NS_ASSUME_NONNULL_BEGIN

/// Queue-specific context data to be associated with the capture session queue.
extern const char *FLTCaptureSessionQueueSpecific;
extern const char* FLTCaptureSessionQueueSpecific;

/// Ensures the given block to be run on the main queue.
/// If caller site is already on the main queue, the block will be run
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera_avfoundation/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.17+5
version: 0.9.17+6

environment:
sdk: ^3.4.0
Expand Down

0 comments on commit c597ad3

Please sign in to comment.