99
1010#import < OCMock/OCMock.h>
1111
12+ @interface StubGlobalEventApi : FCPCameraGlobalEventApi
13+ @property (nonatomic ) BOOL called;
14+ @property (nonatomic ) FCPPlatformDeviceOrientation lastOrientation;
15+ @end
16+
17+ @implementation StubGlobalEventApi
18+ - (void )deviceOrientationChangedOrientation : (FCPPlatformDeviceOrientation)orientation
19+ completion : (void (^)(FlutterError *_Nullable))completion {
20+ self.called = YES ;
21+ self.lastOrientation = orientation;
22+ completion (nil );
23+ }
24+
25+ - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel : (nonnull NSString *)channel
26+ binaryMessageHandler :
27+ (nullable FlutterBinaryMessageHandler)handler {
28+ return 0 ;
29+ }
30+
31+ @end
32+
33+ #pragma mark -
34+
1235@interface CameraOrientationTests : XCTestCase
1336@end
1437
1538@implementation CameraOrientationTests
1639
40+ // Ensure that the given queue and then the main queue have both cycled, to wait for any pending
41+ // async events that may have been bounced between them.
42+ - (void )waitForRoundTripWithQueue : (dispatch_queue_t )queue {
43+ XCTestExpectation *expectation = [[XCTestExpectation alloc ] initWithDescription: @" Queue flush" ];
44+ dispatch_async (queue, ^{
45+ dispatch_async (dispatch_get_main_queue (), ^{
46+ [expectation fulfill ];
47+ });
48+ });
49+ [self waitForExpectations: @[ expectation ]];
50+ }
51+
52+ - (void )sendOrientation : (UIDeviceOrientation)orientation toCamera : (CameraPlugin *)cameraPlugin {
53+ [cameraPlugin orientationChanged: [self createMockNotificationForOrientation: orientation]];
54+ [self waitForRoundTripWithQueue: cameraPlugin.captureSessionQueue];
55+ }
56+
1757- (void )testOrientationNotifications {
18- id mockMessenger = OCMProtocolMock (@protocol (FlutterBinaryMessenger));
19- CameraPlugin *cameraPlugin = [[CameraPlugin alloc ] initWithRegistry: nil messenger: mockMessenger];
20-
21- [mockMessenger setExpectationOrderMatters: YES ];
22-
23- [self rotate: UIDeviceOrientationPortraitUpsideDown
24- expectedChannelOrientation: @" portraitDown"
25- cameraPlugin: cameraPlugin
26- messenger: mockMessenger];
27- [self rotate: UIDeviceOrientationPortrait
28- expectedChannelOrientation: @" portraitUp"
29- cameraPlugin: cameraPlugin
30- messenger: mockMessenger];
31- [self rotate: UIDeviceOrientationLandscapeLeft
32- expectedChannelOrientation: @" landscapeLeft"
33- cameraPlugin: cameraPlugin
34- messenger: mockMessenger];
35- [self rotate: UIDeviceOrientationLandscapeRight
36- expectedChannelOrientation: @" landscapeRight"
37- cameraPlugin: cameraPlugin
38- messenger: mockMessenger];
39-
40- OCMReject ([mockMessenger sendOnChannel: [OCMArg any ] message: [OCMArg any ]]);
41-
42- // No notification when flat.
43- [cameraPlugin
44- orientationChanged: [self createMockNotificationForOrientation: UIDeviceOrientationFaceUp]];
45- // No notification when facedown.
46- [cameraPlugin
47- orientationChanged: [self createMockNotificationForOrientation: UIDeviceOrientationFaceDown]];
48-
49- OCMVerifyAll (mockMessenger);
58+ StubGlobalEventApi *eventAPI = [[StubGlobalEventApi alloc ] init ];
59+ CameraPlugin *cameraPlugin = [[CameraPlugin alloc ] initWithRegistry: nil
60+ messenger: nil
61+ globalAPI: eventAPI];
62+
63+ [self sendOrientation: UIDeviceOrientationPortraitUpsideDown toCamera: cameraPlugin];
64+ XCTAssertEqual (eventAPI.lastOrientation , FCPPlatformDeviceOrientationPortraitDown);
65+ [self sendOrientation: UIDeviceOrientationPortrait toCamera: cameraPlugin];
66+ XCTAssertEqual (eventAPI.lastOrientation , FCPPlatformDeviceOrientationPortraitUp);
67+ [self sendOrientation: UIDeviceOrientationLandscapeLeft toCamera: cameraPlugin];
68+ XCTAssertEqual (eventAPI.lastOrientation , FCPPlatformDeviceOrientationLandscapeLeft);
69+ [self sendOrientation: UIDeviceOrientationLandscapeRight toCamera: cameraPlugin];
70+ XCTAssertEqual (eventAPI.lastOrientation , FCPPlatformDeviceOrientationLandscapeRight);
71+ }
72+
73+ - (void )testOrientationNotificationsNotCalledForFaceUp {
74+ StubGlobalEventApi *eventAPI = [[StubGlobalEventApi alloc ] init ];
75+ CameraPlugin *cameraPlugin = [[CameraPlugin alloc ] initWithRegistry: nil
76+ messenger: nil
77+ globalAPI: eventAPI];
78+
79+ [self sendOrientation: UIDeviceOrientationFaceUp toCamera: cameraPlugin];
80+
81+ XCTAssertFalse (eventAPI.called );
82+ }
83+
84+ - (void )testOrientationNotificationsNotCalledForFaceDown {
85+ StubGlobalEventApi *eventAPI = [[StubGlobalEventApi alloc ] init ];
86+ CameraPlugin *cameraPlugin = [[CameraPlugin alloc ] initWithRegistry: nil
87+ messenger: nil
88+ globalAPI: eventAPI];
89+
90+ [self sendOrientation: UIDeviceOrientationFaceDown toCamera: cameraPlugin];
91+
92+ XCTAssertFalse (eventAPI.called );
5093}
5194
5295- (void )testOrientationUpdateMustBeOnCaptureSessionQueue {
@@ -71,40 +114,20 @@ - (void)testOrientationUpdateMustBeOnCaptureSessionQueue {
71114 [self waitForExpectationsWithTimeout: 1 handler: nil ];
72115}
73116
74- - (void )rotate : (UIDeviceOrientation)deviceOrientation
75- expectedChannelOrientation : (NSString *)channelOrientation
76- cameraPlugin : (CameraPlugin *)cameraPlugin
77- messenger : (NSObject <FlutterBinaryMessenger> *)messenger {
78- XCTestExpectation *orientationExpectation = [self expectationWithDescription: channelOrientation];
79-
80- OCMExpect ([messenger
81- sendOnChannel: [OCMArg any ]
82- message: [OCMArg checkWithBlock: ^BOOL (NSData *data) {
83- NSObject <FlutterMethodCodec> *codec = [FlutterStandardMethodCodec sharedInstance ];
84- FlutterMethodCall *methodCall = [codec decodeMethodCall: data];
85- [orientationExpectation fulfill ];
86- return
87- [methodCall.method isEqualToString: @" orientation_changed" ] &&
88- [methodCall.arguments isEqualToDictionary: @{@" orientation" : channelOrientation}];
89- }]]);
90-
91- [cameraPlugin orientationChanged: [self createMockNotificationForOrientation: deviceOrientation]];
92- [self waitForExpectationsWithTimeout: 30.0 handler: nil ];
93- }
94-
95117- (void )testOrientationChanged_noRetainCycle {
96118 dispatch_queue_t captureSessionQueue = dispatch_queue_create (" capture_session_queue" , NULL );
97119 FLTCam *mockCam = OCMClassMock ([FLTCam class ]);
98- FLTThreadSafeMethodChannel *mockChannel = OCMClassMock ([FLTThreadSafeMethodChannel class ]) ;
120+ StubGlobalEventApi *stubAPI = [[StubGlobalEventApi alloc ] init ] ;
99121
100122 __weak CameraPlugin *weakCamera;
101123
102124 @autoreleasepool {
103- CameraPlugin *camera = [[CameraPlugin alloc ] initWithRegistry: nil messenger: nil ];
125+ CameraPlugin *camera = [[CameraPlugin alloc ] initWithRegistry: nil
126+ messenger: nil
127+ globalAPI: stubAPI];
104128 weakCamera = camera;
105129 camera.captureSessionQueue = captureSessionQueue;
106130 camera.camera = mockCam;
107- camera.deviceEventMethodChannel = mockChannel;
108131
109132 [camera orientationChanged:
110133 [self createMockNotificationForOrientation: UIDeviceOrientationLandscapeLeft]];
@@ -118,11 +141,11 @@ - (void)testOrientationChanged_noRetainCycle {
118141 [self expectationWithDescription: @" Dispatched to capture session queue" ];
119142 dispatch_async (captureSessionQueue, ^{
120143 OCMVerify (never (), [mockCam setDeviceOrientation: UIDeviceOrientationLandscapeLeft]);
121- OCMVerify ( never (), [mockChannel invokeMethod: @" orientation_changed " arguments: OCMOCK_ANY] );
144+ XCTAssertFalse (stubAPI. called );
122145 [expectation fulfill ];
123146 });
124147
125- [self waitForExpectationsWithTimeout: 1 handler: nil ];
148+ [self waitForExpectationsWithTimeout: 30 handler: nil ];
126149}
127150
128151- (NSNotification *)createMockNotificationForOrientation : (UIDeviceOrientation)deviceOrientation {
0 commit comments