Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 9e3fb80

Browse files
committed
Merge remote-tracking branch 'upstream/master' into bugfix/camera-threading
2 parents cd48ddd + 176cfb8 commit 9e3fb80

15 files changed

+106
-42
lines changed

packages/camera/camera/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
## 0.9.4+2
1+
## 0.9.4+3
22

33
* Fix registerTexture and result being called on background thread on iOS;
4+
5+
## 0.9.4+2
6+
47
* Updated package description.
8+
* Refactor unit test on iOS to make it compatible with new restrictions in Xcode 13 which only supports the use of the `XCUIDevice` in Xcode UI tests.
59

610
## 0.9.4+1
711

packages/camera/camera/example/ios/RunnerTests/CameraMethodChannelTests.m

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
// found in the LICENSE file.
44

55
@import camera;
6+
@import camera.Test;
67
@import XCTest;
78
@import AVFoundation;
89
#import <OCMock/OCMock.h>
910
#import "MockFLTThreadSafeFlutterResult.h"
1011

11-
@interface CameraPlugin (Test)
12-
- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FLTThreadSafeFlutterResult *)result;
13-
@end
14-
1512
@interface CameraMethodChannelTests : XCTestCase
1613
@property(readonly, nonatomic) CameraPlugin *camera;
1714
@property(readonly, nonatomic) MockFLTThreadSafeFlutterResult *resultObject;
@@ -20,7 +17,8 @@ @interface CameraMethodChannelTests : XCTestCase
2017
@implementation CameraMethodChannelTests
2118

2219
- (void)setUp {
23-
_camera = [[CameraPlugin alloc] init];
20+
_camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil];
21+
2422
XCTestExpectation *expectation =
2523
[[XCTestExpectation alloc] initWithDescription:@"Result finished"];
2624

packages/camera/camera/example/ios/RunnerTests/CameraOrientationTests.m

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,73 @@
33
// found in the LICENSE file.
44

55
@import camera;
6+
@import camera.Test;
67
@import XCTest;
8+
@import Flutter;
79

810
#import <OCMock/OCMock.h>
911

1012
@interface CameraOrientationTests : XCTestCase
11-
@property(strong, nonatomic) id mockRegistrar;
1213
@property(strong, nonatomic) id mockMessenger;
14+
@property(strong, nonatomic) CameraPlugin *cameraPlugin;
1315
@end
1416

1517
@implementation CameraOrientationTests
1618

1719
- (void)setUp {
1820
[super setUp];
19-
self.mockRegistrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar));
21+
2022
self.mockMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
21-
OCMStub([self.mockRegistrar messenger]).andReturn(self.mockMessenger);
23+
self.cameraPlugin = [[CameraPlugin alloc] initWithRegistry:nil messenger:self.mockMessenger];
2224
}
2325

2426
- (void)testOrientationNotifications {
2527
id mockMessenger = self.mockMessenger;
2628
[mockMessenger setExpectationOrderMatters:YES];
27-
XCUIDevice.sharedDevice.orientation = UIDeviceOrientationPortrait;
28-
29-
[CameraPlugin registerWithRegistrar:self.mockRegistrar];
3029

3130
[self rotate:UIDeviceOrientationPortraitUpsideDown expectedChannelOrientation:@"portraitDown"];
3231
[self rotate:UIDeviceOrientationPortrait expectedChannelOrientation:@"portraitUp"];
3332
[self rotate:UIDeviceOrientationLandscapeRight expectedChannelOrientation:@"landscapeLeft"];
3433
[self rotate:UIDeviceOrientationLandscapeLeft expectedChannelOrientation:@"landscapeRight"];
3534

3635
OCMReject([mockMessenger sendOnChannel:[OCMArg any] message:[OCMArg any]]);
37-
// No notification when orientation doesn't change.
38-
XCUIDevice.sharedDevice.orientation = UIDeviceOrientationLandscapeLeft;
36+
3937
// No notification when flat.
40-
XCUIDevice.sharedDevice.orientation = UIDeviceOrientationFaceUp;
38+
[self.cameraPlugin
39+
orientationChanged:[self createMockNotificationForOrientation:UIDeviceOrientationFaceUp]];
4140
// No notification when facedown.
42-
XCUIDevice.sharedDevice.orientation = UIDeviceOrientationFaceDown;
41+
[self.cameraPlugin
42+
orientationChanged:[self createMockNotificationForOrientation:UIDeviceOrientationFaceDown]];
4343

4444
OCMVerifyAll(mockMessenger);
4545
}
4646

4747
- (void)rotate:(UIDeviceOrientation)deviceOrientation
48-
expectedChannelOrientation:(NSString*)channelOrientation {
48+
expectedChannelOrientation:(NSString *)channelOrientation {
4949
id mockMessenger = self.mockMessenger;
50-
XCTestExpectation* orientationExpectation = [self expectationWithDescription:channelOrientation];
50+
XCTestExpectation *orientationExpectation = [self expectationWithDescription:channelOrientation];
5151

5252
OCMExpect([mockMessenger
5353
sendOnChannel:[OCMArg any]
54-
message:[OCMArg checkWithBlock:^BOOL(NSData* data) {
55-
NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance];
56-
FlutterMethodCall* methodCall = [codec decodeMethodCall:data];
54+
message:[OCMArg checkWithBlock:^BOOL(NSData *data) {
55+
NSObject<FlutterMethodCodec> *codec = [FlutterStandardMethodCodec sharedInstance];
56+
FlutterMethodCall *methodCall = [codec decodeMethodCall:data];
5757
[orientationExpectation fulfill];
5858
return
5959
[methodCall.method isEqualToString:@"orientation_changed"] &&
6060
[methodCall.arguments isEqualToDictionary:@{@"orientation" : channelOrientation}];
6161
}]]);
6262

63-
XCUIDevice.sharedDevice.orientation = deviceOrientation;
63+
[self.cameraPlugin
64+
orientationChanged:[self createMockNotificationForOrientation:deviceOrientation]];
6465
[self waitForExpectationsWithTimeout:30.0 handler:nil];
6566
}
6667

68+
- (NSNotification *)createMockNotificationForOrientation:(UIDeviceOrientation)deviceOrientation {
69+
UIDevice *mockDevice = OCMClassMock([UIDevice class]);
70+
OCMStub([mockDevice orientation]).andReturn(deviceOrientation);
71+
72+
return [NSNotification notificationWithName:@"orientation_test" object:mockDevice];
73+
}
74+
6775
@end

packages/camera/camera/example/ios/RunnerTests/CameraPreviewPauseTests.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ @implementation CameraPreviewPauseTests
2626
- (void)setUp {
2727
_camera = [[FLTCam alloc] init];
2828

29-
XCTestExpectation *expectation =
30-
[[XCTestExpectation alloc] initWithDescription:@"Result finished"];
31-
_resultObject = [[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];
29+
_resultObject = [[MockFLTThreadSafeFlutterResult alloc] init];
3230
}
3331

3432
- (void)testPausePreviewWithResult_shouldPausePreview {

packages/camera/camera/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
#ifndef MockFLTThreadSafeFlutterResult_h
66
#define MockFLTThreadSafeFlutterResult_h
77

8-
@interface FLTThreadSafeFlutterResult ()
9-
@property(readonly, nonatomic) FlutterResult _Nonnull flutterResult;
10-
@end
11-
128
/**
139
* Extends FLTThreadSafeFlutterResult to give tests the ability to wait on the result and
1410
* read the received result.
@@ -17,7 +13,7 @@
1713
@property(readonly, nonatomic) XCTestExpectation *_Nonnull expectation;
1814
@property(nonatomic, nullable) id receivedResult;
1915

20-
- (id _Nonnull)initWithExpectation:(XCTestExpectation *_Nonnull)expectation;
16+
- (instancetype _Nonnull)initWithExpectation:(XCTestExpectation *_Nonnull)expectation;
2117
@end
2218

2319
#endif /* MockFLTThreadSafeFlutterResult_h */

packages/camera/camera/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.m

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@
99

1010
@implementation MockFLTThreadSafeFlutterResult
1111
/**
12-
* Initializes with a notification center.
12+
* Initializes the MockFLTThreadSafeFlutterResult.
1313
*/
14-
- (id)initWithExpectation:(XCTestExpectation *)expectation {
14+
- (instancetype)init {
15+
self = [super init];
16+
return self;
17+
}
18+
19+
/**
20+
* Initializes the MockFLTThreadSafeFlutterResult with an expectation.
21+
*/
22+
- (instancetype)initWithExpectation:(XCTestExpectation *)expectation {
1523
self = [super init];
1624
_expectation = expectation;
1725
return self;

packages/camera/camera/ios/Classes/CameraPlugin.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// found in the LICENSE file.
44

55
#import "CameraPlugin.h"
6+
#import "CameraPlugin_Test.h"
7+
68
#import <AVFoundation/AVFoundation.h>
79
#import <Accelerate/Accelerate.h>
810
#import <CoreMotion/CoreMotion.h>
@@ -1292,6 +1294,7 @@ @interface CameraPlugin ()
12921294
@implementation CameraPlugin {
12931295
dispatch_queue_t _dispatchQueue;
12941296
}
1297+
12951298
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
12961299
FlutterMethodChannel *channel =
12971300
[FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/camera"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
framework module camera {
2+
umbrella header "camera-umbrella.h"
3+
4+
export *
5+
module * { export * }
6+
7+
explicit module Test {
8+
header "CameraPlugin_Test.h"
9+
}
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// This header is available in the Test module. Import via "@import camera.Test;"
6+
7+
#import <camera/CameraPlugin.h>
8+
#import <camera/FLTThreadSafeFlutterResult.h>
9+
10+
/// Methods exposed for unit testing.
11+
@interface CameraPlugin ()
12+
13+
- (instancetype)initWithRegistry:(NSObject<FlutterTextureRegistry> *)registry
14+
messenger:(NSObject<FlutterBinaryMessenger> *)messenger
15+
NS_DESIGNATED_INITIALIZER;
16+
- (instancetype)init NS_UNAVAILABLE;
17+
18+
- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FLTThreadSafeFlutterResult *)result;
19+
- (void)orientationChanged:(NSNotification *)notification;
20+
21+
@end

packages/camera/camera/ios/Classes/FLTThreadSafeFlutterResult.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
*/
1010
@interface FLTThreadSafeFlutterResult : NSObject
1111

12+
/**
13+
* Gets the original FlutterResult object wrapped by this FLTThreadSafeFlutterResult instance.
14+
*/
15+
@property(readonly, nonatomic) FlutterResult _Nonnull flutterResult;
16+
1217
/**
1318
* Initializes with a FlutterResult object.
1419
* @param result The FlutterResult object that the result will be given to.

0 commit comments

Comments
 (0)