5#import <OCMock/OCMock.h>
6#import <XCTest/XCTest.h>
17@interface FlutterView (Testing)
22@property(nonatomic)
BOOL callbackCalled;
27@synthesize platformViewsController = _platformViewsController;
35 asBase64Encoded:(
BOOL)base64Encode {
39- (void)flutterViewAccessibilityDidCall {
40 _callbackCalled = YES;
50- (void)testFlutterViewEnableSemanticsWhenIsAccessibilityElementIsCalled {
54 XCTAssertFalse(
view.isAccessibilityElement);
58- (void)testFlutterViewBackgroundColorIsNil {
61 XCTAssertNil(
view.backgroundColor);
64- (void)testLayerScalesMatchScreenAfterLayoutSubviews {
67 view.layer.contentsScale = CGFloat(-99.0);
68 view.layer.rasterizationScale = CGFloat(-99.0);
69 UIScreen* screen = [view
screen];
70 XCTAssertNotEqual(
view.layer.contentsScale, screen.scale);
71 XCTAssertNotEqual(
view.layer.rasterizationScale, screen.scale);
72 [view layoutSubviews];
73 XCTAssertEqual(
view.layer.contentsScale, screen.scale);
74 XCTAssertEqual(
view.layer.rasterizationScale, screen.scale);
77- (void)testViewWillMoveToWindow {
78 NSDictionary* mocks = [
self createWindowMocks];
80 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
83 id mockEngine = mocks[@"mockEngine"];
84 id mockWindow = mocks[@"mockWindow"];
86 [view willMoveToWindow:mockWindow];
87 OCMVerify(times(1), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine]);
91- (void)testViewWillMoveToSameWindow {
92 NSDictionary* mocks = [
self createWindowMocks];
94 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
97 id mockEngine = mocks[@"mockEngine"];
98 id mockWindow = mocks[@"mockWindow"];
100 [view willMoveToWindow:mockWindow];
101 [view willMoveToWindow:mockWindow];
103 OCMVerify(times(2), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine]);
107- (void)testMultipleViewsWillMoveToSameWindow {
108 NSDictionary* mocks = [
self createWindowMocks];
110 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
113 id mockEngine1 = mocks[@"mockEngine"];
114 id mockWindow1 = mocks[@"mockWindow"];
121 [view1 willMoveToWindow:mockWindow1];
122 [view2 willMoveToWindow:mockWindow1];
123 [view1 willMoveToWindow:mockWindow1];
124 OCMVerify(times(2), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine1]);
125 OCMVerify(times(1), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine2]);
129- (void)testMultipleViewsWillMoveToDifferentWindow {
130 NSDictionary* mocks = [
self createWindowMocks];
132 id mockLifecycleDelegate1 = mocks[@"mockLifecycleDelegate"];
135 id mockEngine1 = mocks[@"mockEngine"];
136 id mockWindow1 = mocks[@"mockWindow"];
138 NSDictionary* mocks2 = [
self createWindowMocks];
140 id mockLifecycleDelegate2 = mocks2[@"mockLifecycleDelegate"];
143 id mockEngine2 = mocks2[@"mockEngine"];
144 id mockWindow2 = mocks2[@"mockWindow"];
146 [view1 willMoveToWindow:mockWindow1];
147 [view2 willMoveToWindow:mockWindow2];
148 [view1 willMoveToWindow:mockWindow1];
149 OCMVerify(times(2), [mockLifecycleDelegate1 addFlutterManagedEngine:mockEngine1]);
150 OCMVerify(times(1), [mockLifecycleDelegate2 addFlutterManagedEngine:mockEngine2]);
155- (void)testViewRemovedFromWindowAndAddedToNewScene {
156 NSDictionary* mocks = [
self createWindowMocks];
158 id mockLifecycleDelegate = mocks[@"mockLifecycleDelegate"];
161 id mockEngine = mocks[@"mockEngine"];
162 id mockWindow = mocks[@"mockWindow"];
164 NSDictionary* mocks2 = [
self createWindowMocks];
165 id mockWindow2 = mocks2[@"mockWindow"];
166 id mockLifecycleDelegate2 = mocks2[@"mockLifecycleDelegate"];
170 id mockView = OCMPartialMock(
view);
172 [mockView willMoveToWindow:mockWindow];
173 OCMVerify(times(1), [mockLifecycleDelegate addFlutterManagedEngine:mockEngine]);
176 OCMStub([mockView
window]).andReturn(mockWindow);
177 [mockView willMoveToWindow:nil];
180 OCMStub([mockView
window]).andReturn(nil);
181 [mockView willMoveToWindow:mockWindow2];
182 OCMVerify(times(1), [mockLifecycleDelegate removeFlutterManagedEngine:mockEngine]);
184 OCMVerify(times(1), [mockLifecycleDelegate2 addFlutterManagedEngine:mockEngine]);
188- (NSDictionary*)createWindowMocks {
189 return [
self createWindowMocksWithWideGamut:NO];
192- (NSDictionary*)createWindowMocksWithWideGamut:(
BOOL)enableWideGamut {
196 enableWideGamut:enableWideGamut];
197 id mockWindow = OCMClassMock([UIWindow
class]);
198 id mockWindowScene = OCMClassMock([UIWindowScene
class]);
201 id mockSceneDelegate = OCMPartialMock(sceneDelegate);
205 id mockLifecycleDelegate = OCMPartialMock(lifecycleDelegate);
207 OCMStub([mockWindow windowScene]).andReturn(mockWindowScene);
208 OCMStub([mockWindowScene delegate]).andReturn(mockSceneDelegate);
209 OCMStub([mockSceneDelegate sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
213 @"mockLifecycleDelegate" : mockLifecycleDelegate,
214 @"lifecycleDelegate" : lifecycleDelegate,
215 @"mockEngine" : mockEngine,
216 @"mockWindow" : mockWindow,
220#pragma mark - Wide Gamut Tests
227 enableWideGamut:enableWideGamut];
229 UIWindow*
window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
230 [window addSubview:view];
232 [view layoutSubviews];
236- (void)testWideGamutViewSetsBGRA10XRPixelFormat {
240 if ([
view isWideGamutSupported]) {
241 XCTAssertEqual(
view.pixelFormat, MTLPixelFormatBGRA10_XR);
243 XCTAssertEqual(
view.pixelFormat, MTLPixelFormatBGRA8Unorm);
247- (void)testStandardGamutViewKeepsBGRA8Unorm {
249 XCTAssertEqual(
view.pixelFormat, MTLPixelFormatBGRA8Unorm);
252- (void)testWideGamutViewSetsExtendedSRGBColorSpace {
254 if ([
view isWideGamutSupported]) {
255 CAMetalLayer* layer = (CAMetalLayer*)
view.layer;
256 CGColorSpaceRef colorSpace = layer.colorspace;
257 XCTAssertNotNil((__bridge
id)colorSpace);
258 CGColorSpaceRef extendedSRGB = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
259 XCTAssertTrue(CFEqual(colorSpace, extendedSRGB));
260 CGColorSpaceRelease(extendedSRGB);
264- (void)testStandardGamutViewDoesNotSetExtendedColorSpace {
266 CAMetalLayer* layer = (CAMetalLayer*)
view.layer;
268 XCTAssertNil((__bridge
id)layer.colorspace);
271#pragma mark - FlutterOverlayView Wide Gamut Tests
273- (void)testOverlayViewWideGamutSetsBGRA10XR {
275 [[
FlutterOverlayView alloc] initWithContentsScale:2.0 pixelFormat:MTLPixelFormatBGRA10_XR];
276 CAMetalLayer* layer = (CAMetalLayer*)overlay.layer;
277 XCTAssertEqual(layer.pixelFormat, MTLPixelFormatBGRA10_XR);
280- (void)testOverlayViewWideGamutSetsExtendedSRGBColorSpace {
282 [[
FlutterOverlayView alloc] initWithContentsScale:2.0 pixelFormat:MTLPixelFormatBGRA10_XR];
283 CAMetalLayer* layer = (CAMetalLayer*)overlay.layer;
284 CGColorSpaceRef colorSpace = layer.colorspace;
285 XCTAssertNotNil((__bridge
id)colorSpace);
286 CGColorSpaceRef extendedSRGB = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
287 XCTAssertTrue(CFEqual(colorSpace, extendedSRGB));
288 CGColorSpaceRelease(extendedSRGB);
291- (void)testOverlayViewStandardGamutKeepsBGRA8Unorm {
293 [[
FlutterOverlayView alloc] initWithContentsScale:2.0 pixelFormat:MTLPixelFormatBGRA8Unorm];
294 CAMetalLayer* layer = (CAMetalLayer*)overlay.layer;
295 XCTAssertEqual(layer.pixelFormat, MTLPixelFormatBGRA8Unorm);
298- (void)testOverlayViewStandardGamutDoesNotSetExtendedColorSpace {
300 [[
FlutterOverlayView alloc] initWithContentsScale:2.0 pixelFormat:MTLPixelFormatBGRA8Unorm];
301 CAMetalLayer* layer = (CAMetalLayer*)overlay.layer;
302 XCTAssertNil((__bridge
id)layer.colorspace);
305- (void)testOverlayViewContentsScaleIsSet {
307 [[
FlutterOverlayView alloc] initWithContentsScale:3.0 pixelFormat:MTLPixelFormatBGRA10_XR];
308 XCTAssertEqual(overlay.layer.contentsScale, 3.0);
309 XCTAssertEqual(overlay.layer.rasterizationScale, 3.0);
BOOL isWideGamutSupported()
ScreenshotType
The type of the screenshot to obtain of the previously rendered layer tree.
NSPointerArray * flutterManagedEngines
A POD type used to return the screenshot data along with the size of the frame.