diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index be8574eb30249..00a7c9ecda5bd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -252,8 +252,7 @@ } // If there were not enough existing clip views, add more. while (clipIndex < number_of_clips) { - ChildClippingView* clippingView = - [[ChildClippingView alloc] initWithFrame:flutter_view_.get().bounds]; + ChildClippingView* clippingView = [ChildClippingView new]; [clippingView addSubview:head]; head = clippingView; clipIndex++; diff --git a/testing/scenario_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/testing/scenario_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java deleted file mode 100644 index d007606a44d83..0000000000000 --- a/testing/scenario_app/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.flutter.plugins; - -import io.flutter.plugin.common.PluginRegistry; - -/** - * Generated file. Do not edit. - */ -public final class GeneratedPluginRegistrant { - public static void registerWith(PluginRegistry registry) { - if (alreadyRegisteredWith(registry)) { - return; - } - } - - private static boolean alreadyRegisteredWith(PluginRegistry registry) { - final String key = GeneratedPluginRegistrant.class.getCanonicalName(); - if (registry.hasPlugin(key)) { - return true; - } - registry.registrarFor(key); - return false; - } -} diff --git a/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.h b/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.h deleted file mode 100644 index 3b700eb481958..0000000000000 --- a/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// Generated file. Do not edit. -// - -#ifndef GeneratedPluginRegistrant_h -#define GeneratedPluginRegistrant_h - -#import - -@interface GeneratedPluginRegistrant : NSObject -+ (void)registerWithRegistry:(NSObject*)registry; -@end - -#endif /* GeneratedPluginRegistrant_h */ diff --git a/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.m b/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.m deleted file mode 100644 index 60dfa42b328db..0000000000000 --- a/testing/scenario_app/ios/Runner/GeneratedPluginRegistrant.m +++ /dev/null @@ -1,12 +0,0 @@ -// -// Generated file. Do not edit. -// - -#import "GeneratedPluginRegistrant.h" - -@implementation GeneratedPluginRegistrant - -+ (void)registerWithRegistry:(NSObject*)registry { -} - -@end diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index a95587c1a7fd0..b6c77bab8781d 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -30,14 +30,6 @@ 24D47D1B230C79840069DD5E /* golden_platform_view_D211AP.png in Resources */ = {isa = PBXBuildFile; fileRef = 24D47D1A230C79840069DD5E /* golden_platform_view_D211AP.png */; }; 24D47D1D230CA2700069DD5E /* golden_platform_view_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 24D47D1C230CA2700069DD5E /* golden_platform_view_iPhone SE_simulator.png */; }; 24F1FB89230B4579005ACE7C /* TextPlatformView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24F1FB87230B4579005ACE7C /* TextPlatformView.m */; }; - 6816DB9E231750ED00A51400 /* GoldenPlatformViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */; }; - 6816DBA12317573300A51400 /* GoldenImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA02317573300A51400 /* GoldenImage.m */; }; - 6816DBA42318358200A51400 /* PlatformViewGoldenTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA32318358200A51400 /* PlatformViewGoldenTestManager.m */; }; - 6816DBAA2318696600A51400 /* golden_platform_view_clippath_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA52318696600A51400 /* golden_platform_view_clippath_iPhone SE_simulator.png */; }; - 6816DBAB2318696600A51400 /* golden_platform_view_transform_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA62318696600A51400 /* golden_platform_view_transform_iPhone SE_simulator.png */; }; - 6816DBAC2318696600A51400 /* golden_platform_view_opacity_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA72318696600A51400 /* golden_platform_view_opacity_iPhone SE_simulator.png */; }; - 6816DBAD2318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */; }; - 6816DBAE2318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -121,17 +113,6 @@ 24D47D1E230CA4480069DD5E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 24F1FB87230B4579005ACE7C /* TextPlatformView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextPlatformView.m; sourceTree = ""; }; 24F1FB88230B4579005ACE7C /* TextPlatformView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextPlatformView.h; sourceTree = ""; }; - 6816DB9C231750ED00A51400 /* GoldenPlatformViewTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenPlatformViewTests.h; sourceTree = ""; }; - 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenPlatformViewTests.m; sourceTree = ""; }; - 6816DB9F2317573300A51400 /* GoldenImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenImage.h; sourceTree = ""; }; - 6816DBA02317573300A51400 /* GoldenImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenImage.m; sourceTree = ""; }; - 6816DBA22318358200A51400 /* PlatformViewGoldenTestManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformViewGoldenTestManager.h; sourceTree = ""; }; - 6816DBA32318358200A51400 /* PlatformViewGoldenTestManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGoldenTestManager.m; sourceTree = ""; }; - 6816DBA52318696600A51400 /* golden_platform_view_clippath_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_iPhone SE_simulator.png"; sourceTree = ""; }; - 6816DBA62318696600A51400 /* golden_platform_view_transform_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_transform_iPhone SE_simulator.png"; sourceTree = ""; }; - 6816DBA72318696600A51400 /* golden_platform_view_opacity_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_opacity_iPhone SE_simulator.png"; sourceTree = ""; }; - 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone SE_simulator.png"; sourceTree = ""; }; - 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_iPhone SE_simulator.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -219,20 +200,9 @@ 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */, 24D47D1C230CA2700069DD5E /* golden_platform_view_iPhone SE_simulator.png */, 24D47D1A230C79840069DD5E /* golden_platform_view_D211AP.png */, - 6816DBA52318696600A51400 /* golden_platform_view_clippath_iPhone SE_simulator.png */, - 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */, - 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */, - 6816DBA72318696600A51400 /* golden_platform_view_opacity_iPhone SE_simulator.png */, - 6816DBA62318696600A51400 /* golden_platform_view_transform_iPhone SE_simulator.png */, 248D76EE22E388380012F0C1 /* PlatformViewUITests.m */, 248D76F022E388380012F0C1 /* Info.plist */, 24D47D1E230CA4480069DD5E /* README.md */, - 6816DB9C231750ED00A51400 /* GoldenPlatformViewTests.h */, - 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */, - 6816DB9F2317573300A51400 /* GoldenImage.h */, - 6816DBA02317573300A51400 /* GoldenImage.m */, - 6816DBA22318358200A51400 /* PlatformViewGoldenTestManager.h */, - 6816DBA32318358200A51400 /* PlatformViewGoldenTestManager.m */, ); path = ScenariosUITests; sourceTree = ""; @@ -370,14 +340,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6816DBAE2318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png in Resources */, - 6816DBAB2318696600A51400 /* golden_platform_view_transform_iPhone SE_simulator.png in Resources */, - 6816DBAA2318696600A51400 /* golden_platform_view_clippath_iPhone SE_simulator.png in Resources */, - 6816DBAD2318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png in Resources */, 24D47D1B230C79840069DD5E /* golden_platform_view_D211AP.png in Resources */, 24D47D1D230CA2700069DD5E /* golden_platform_view_iPhone SE_simulator.png in Resources */, 244EA6D0230DBE8900B2D26E /* golden_platform_view_D21AP.png in Resources */, - 6816DBAC2318696600A51400 /* golden_platform_view_opacity_iPhone SE_simulator.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -410,9 +375,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6816DBA12317573300A51400 /* GoldenImage.m in Sources */, - 6816DB9E231750ED00A51400 /* GoldenPlatformViewTests.m in Sources */, - 6816DBA42318358200A51400 /* PlatformViewGoldenTestManager.m in Sources */, 248D76EF22E388380012F0C1 /* PlatformViewUITests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m index 205ce79384c9c..6a419e99a7bc3 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -25,55 +25,27 @@ - (BOOL)application:(UIApplication*)application // This argument is used by the XCUITest for Platform Views so that the app // under test will create platform views. - // The launchArgsMap should match the one in the `PlatformVieGoldenTestManager`. - NSDictionary* launchArgsMap = @{ - @"--platform-view" : @"platform_view", - @"--platform-view-cliprect" : @"platform_view_cliprect", - @"--platform-view-cliprrect" : @"platform_view_cliprrect", - @"--platform-view-clippath" : @"platform_view_clippath", - @"--platform-view-transform" : @"platform_view_transform", - @"--platform-view-opacity" : @"platform_view_opacity", - }; - __block NSString* goldenTestName = nil; - [launchArgsMap - enumerateKeysAndObjectsUsingBlock:^(NSString* argument, NSString* testName, BOOL* stop) { - if ([[[NSProcessInfo processInfo] arguments] containsObject:argument]) { - goldenTestName = testName; - *stop = YES; - } - }]; - - if (goldenTestName) { - [self readyContextForPlatformViewTests:goldenTestName]; + if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--platform-view"]) { + FlutterEngine* engine = [[FlutterEngine alloc] initWithScenario:@"text_platform_view" + withCompletion:nil]; + [engine runWithEntrypoint:nil]; + + FlutterViewController* flutterViewController = + [[NoStatusBarFlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; + TextPlatformViewFactory* textPlatformViewFactory = + [[TextPlatformViewFactory alloc] initWithMessenger:flutterViewController.binaryMessenger]; + NSObject* registrar = + [flutterViewController.engine registrarForPlugin:@"scenarios/TextPlatformViewPlugin"]; + [registrar registerViewFactory:textPlatformViewFactory withId:@"scenarios/textPlatformView"]; + self.window.rootViewController = flutterViewController; } else if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--screen-before-flutter"]) { self.window.rootViewController = [[ScreenBeforeFlutter alloc] initWithEngineRunCompletion:nil]; } else { self.window.rootViewController = [[UIViewController alloc] init]; } - [self.window makeKeyAndVisible]; - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -- (void)readyContextForPlatformViewTests:(NSString*)scenarioIdentifier { - FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"PlatformViewTest" project:nil]; - [engine runWithEntrypoint:nil]; - FlutterViewController* flutterViewController = - [[NoStatusBarFlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; - [engine.binaryMessenger - setMessageHandlerOnChannel:@"scenario_status" - binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply) { - [engine.binaryMessenger - sendOnChannel:@"set_scenario" - message:[scenarioIdentifier dataUsingEncoding:NSUTF8StringEncoding]]; - }]; - TextPlatformViewFactory* textPlatformViewFactory = - [[TextPlatformViewFactory alloc] initWithMessenger:flutterViewController.binaryMessenger]; - NSObject* registrar = - [flutterViewController.engine registrarForPlugin:@"scenarios/TextPlatformViewPlugin"]; - [registrar registerViewFactory:textPlatformViewFactory withId:@"scenarios/textPlatformView"]; - self.window.rootViewController = flutterViewController; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.h deleted file mode 100644 index dead0c530e126..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.h +++ /dev/null @@ -1,26 +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 - -NS_ASSUME_NONNULL_BEGIN - -@interface GoldenImage : NSObject - -@property(readonly, copy, nonatomic) NSString* goldenName; -@property(readonly, strong, nonatomic) UIImage* image; - -// Initilize with the golden file's prefix. -// -// Create an image from a golden file named prefix+devicemodel. -- (instancetype)initWithGoldenNamePrefix:(NSString*)prefix; - -// Compare this GoldenImage to `image`. -// -// Return YES if the `image` of this GoldenImage have the same pixels of provided `image`. -- (BOOL)compareGoldenToImage:(UIImage*)image; - -@end - -NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.m deleted file mode 100644 index 6dbcd8e73e72a..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenImage.m +++ /dev/null @@ -1,94 +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 "GoldenImage.h" -#import -#include - -@interface GoldenImage () - -@end - -@implementation GoldenImage - -- (instancetype)initWithGoldenNamePrefix:(NSString*)prefix { - self = [super init]; - if (self) { - _goldenName = [prefix stringByAppendingString:_platformName()]; - NSBundle* bundle = [NSBundle bundleForClass:[self class]]; - NSURL* goldenURL = [bundle URLForResource:_goldenName withExtension:@"png"]; - NSData* data = [NSData dataWithContentsOfURL:goldenURL]; - _image = [[UIImage alloc] initWithData:data]; - } - return self; -} - -- (BOOL)compareGoldenToImage:(UIImage*)image { - if (!self.image || !image) { - return NO; - } - CGImageRef imageRefA = [self.image CGImage]; - CGImageRef imageRefB = [image CGImage]; - - NSUInteger widthA = CGImageGetWidth(imageRefA); - NSUInteger heightA = CGImageGetHeight(imageRefA); - NSUInteger widthB = CGImageGetWidth(imageRefB); - NSUInteger heightB = CGImageGetHeight(imageRefB); - - if (widthA != widthB || heightA != heightB) { - return NO; - } - NSUInteger bytesPerPixel = 4; - NSUInteger size = widthA * heightA * bytesPerPixel; - NSMutableData* rawA = [NSMutableData dataWithLength:size]; - NSMutableData* rawB = [NSMutableData dataWithLength:size]; - - if (!rawA || !rawB) { - return NO; - } - - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - NSUInteger bytesPerRow = bytesPerPixel * widthA; - NSUInteger bitsPerComponent = 8; - CGContextRef contextA = - CGBitmapContextCreate(rawA.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow, - colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - - CGContextDrawImage(contextA, CGRectMake(0, 0, widthA, heightA), imageRefA); - CGContextRelease(contextA); - - CGContextRef contextB = - CGBitmapContextCreate(rawB.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow, - colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - CGColorSpaceRelease(colorSpace); - - CGContextDrawImage(contextB, CGRectMake(0, 0, widthA, heightA), imageRefB); - CGContextRelease(contextB); - - if (memcmp(rawA.mutableBytes, rawB.mutableBytes, size)) { - return NO; - } - - return YES; -} - -NS_INLINE NSString* _platformName() { - NSString* simulatorName = - [[NSProcessInfo processInfo].environment objectForKey:@"SIMULATOR_DEVICE_NAME"]; - if (simulatorName) { - return [NSString stringWithFormat:@"%@_simulator", simulatorName]; - } - - size_t size; - sysctlbyname("hw.model", NULL, &size, NULL, 0); - char* answer = malloc(size); - sysctlbyname("hw.model", answer, &size, NULL, 0); - - NSString* results = [NSString stringWithCString:answer encoding:NSUTF8StringEncoding]; - free(answer); - return results; -} - -@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.h deleted file mode 100644 index de2b175368261..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.h +++ /dev/null @@ -1,30 +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 -#import "PlatformViewGoldenTestManager.h" - -NS_ASSUME_NONNULL_BEGIN - -// The base class of all the PlatformView golden tests. -// -// A new PlatformView golden tests can subclass this and override the `-initiWithInvocation:` -// method, which then retun the `-initWithManager:invocation:` -// -// Then in any test method, call `checkGolden` to perform the golden test. -// -// This base class doesn't run any test case on its own. -@interface GoldenPlatformViewTests : XCTestCase - -// Initialize with a `PlatformViewGoldenTestManager`. -- (instancetype)initWithManager:(PlatformViewGoldenTestManager*)manager - invocation:(NSInvocation*)invocation; - -// Take a sceenshot of the test app and check it has the same pixels with goldenImage inside the -// `PlatformViewGoldenTestManager`. -- (void)checkGolden; - -@end - -NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.m deleted file mode 100644 index 80e2af25e3bff..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenPlatformViewTests.m +++ /dev/null @@ -1,68 +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 "GoldenPlatformViewTests.h" -#include -#import "PlatformViewGoldenTestManager.h" - -static const NSInteger kSecondsToWaitForPlatformView = 30; - -@interface GoldenPlatformViewTests () - -@property(nonatomic, copy) NSString* goldenName; -@property(nonatomic, strong) XCUIApplication* application; - -@property(nonatomic, strong) PlatformViewGoldenTestManager* manager; - -@end - -@implementation GoldenPlatformViewTests - -- (instancetype)initWithManager:(PlatformViewGoldenTestManager*)manager - invocation:(NSInvocation*)invocation { - self = [super initWithInvocation:invocation]; - _manager = manager; - return self; -} - -- (void)setUp { - [super setUp]; - self.continueAfterFailure = NO; - - self.application = [[XCUIApplication alloc] init]; - self.application.launchArguments = @[ self.manager.launchArg ]; - [self.application launch]; -} - -// Note: don't prefix with "test" or GoldenPlatformViewTests will run instead of the subclasses. -- (void)checkGolden { - XCUIElement* element = self.application.textViews.firstMatch; - BOOL exists = [element waitForExistenceWithTimeout:kSecondsToWaitForPlatformView]; - if (!exists) { - XCTFail(@"It took longer than %@ second to find the platform view." - @"There might be issues with the platform view's construction," - @"or with how the scenario is built.", - @(kSecondsToWaitForPlatformView)); - } - - GoldenImage* golden = self.manager.goldenImage; - - XCUIScreenshot* screenshot = [[XCUIScreen mainScreen] screenshot]; - XCTAttachment* attachment = [XCTAttachment attachmentWithScreenshot:screenshot]; - attachment.lifetime = XCTAttachmentLifetimeKeepAlways; - [self addAttachment:attachment]; - - if (golden.image) { - XCTAttachment* goldenAttachment = [XCTAttachment attachmentWithImage:golden.image]; - goldenAttachment.lifetime = XCTAttachmentLifetimeKeepAlways; - [self addAttachment:goldenAttachment]; - } else { - XCTFail(@"This test will fail - no golden named %@ found. Follow the steps in the " - @"README to add a new golden.", - golden.goldenName); - } - - XCTAssertTrue([golden compareGoldenToImage:screenshot.image]); -} -@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.h b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.h deleted file mode 100644 index f138aea88da3f..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.h +++ /dev/null @@ -1,29 +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 -#import "GoldenImage.h" - -NS_ASSUME_NONNULL_BEGIN - -extern NSDictionary* launchArgsMap; - -// Manages a `GoldenPlatformViewTests`. -// -// It creates the correct `identifer` based on the `launchArg`. -// It also generates the correct GoldenImage based on the `identifier`. -@interface PlatformViewGoldenTestManager : NSObject - -@property(readonly, strong, nonatomic) GoldenImage* goldenImage; -@property(readonly, copy, nonatomic) NSString* identifier; -@property(readonly, copy, nonatomic) NSString* launchArg; - -// Initilize with launchArg. -// -// Crahes if the launchArg is not mapped in `Appdelegate.launchArgsMap`. -- (instancetype)initWithLaunchArg:(NSString*)launchArg; - -@end - -NS_ASSUME_NONNULL_END diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.m deleted file mode 100644 index 9e512d5234889..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewGoldenTestManager.m +++ /dev/null @@ -1,41 +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 "PlatformViewGoldenTestManager.h" - -@interface PlatformViewGoldenTestManager () - -@property(readwrite, strong, nonatomic) GoldenImage* goldenImage; - -@end - -@implementation PlatformViewGoldenTestManager - -NSDictionary* launchArgsMap; - -- (instancetype)initWithLaunchArg:(NSString*)launchArg { - self = [super init]; - if (self) { - // The launchArgsMap should match the one in the `PlatformVieGoldenTestManager`. - static NSDictionary* launchArgsMap; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - launchArgsMap = @{ - @"--platform-view" : @"platform_view", - @"--platform-view-cliprect" : @"platform_view_cliprect", - @"--platform-view-cliprrect" : @"platform_view_cliprrect", - @"--platform-view-clippath" : @"platform_view_clippath", - @"--platform-view-transform" : @"platform_view_transform", - @"--platform-view-opacity" : @"platform_view_opacity", - }; - }); - _identifier = launchArgsMap[launchArg]; - NSString* prefix = [NSString stringWithFormat:@"golden_%@_", _identifier]; - _goldenImage = [[GoldenImage alloc] initWithGoldenNamePrefix:prefix]; - _launchArg = launchArg; - } - return self; -} - -@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m index 00708ecc282f4..e0a929572b81e 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m @@ -2,113 +2,114 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "GoldenPlatformViewTests.h" +#import +#import +#include -@interface PlatformViewUITests : GoldenPlatformViewTests +#import "../Scenarios/TextPlatformView.h" +@interface PlatformViewUITests : XCTestCase +@property(nonatomic, strong) XCUIApplication* application; @end @implementation PlatformViewUITests -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view"]; - return [super initWithManager:manager invocation:invocation]; -} - -- (void)testPlatformView { - [self checkGolden]; -} - -@end - -// Clip Rect Tests -@interface PlatformViewMutationClipRectTests : GoldenPlatformViewTests - -@end - -@implementation PlatformViewMutationClipRectTests - -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprect"]; - return [super initWithManager:manager invocation:invocation]; -} - -- (void)testPlatformView { - [self checkGolden]; -} - -@end - -@interface PlatformViewMutationClipRRectTests : GoldenPlatformViewTests - -@end +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; -@implementation PlatformViewMutationClipRRectTests - -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprrect"]; - return [super initWithManager:manager invocation:invocation]; + self.application = [[XCUIApplication alloc] init]; + self.application.launchArguments = @[ @"--platform-view" ]; + [self.application launch]; } - (void)testPlatformView { - [self checkGolden]; -} - -@end - -@interface PlatformViewMutationClipPathTests : GoldenPlatformViewTests - -@end - -@implementation PlatformViewMutationClipPathTests - -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view-clippath"]; - return [super initWithManager:manager invocation:invocation]; + NSBundle* bundle = [NSBundle bundleForClass:[self class]]; + NSString* goldenName = + [NSString stringWithFormat:@"golden_platform_view_%@", [self platformName]]; + NSString* path = [bundle pathForResource:goldenName ofType:@"png"]; + UIImage* golden = [[UIImage alloc] initWithContentsOfFile:path]; + + XCUIScreenshot* screenshot = [[XCUIScreen mainScreen] screenshot]; + XCTAttachment* attachment = [XCTAttachment attachmentWithScreenshot:screenshot]; + attachment.lifetime = XCTAttachmentLifetimeKeepAlways; + [self addAttachment:attachment]; + + if (golden) { + XCTAttachment* goldenAttachment = [XCTAttachment attachmentWithImage:golden]; + goldenAttachment.lifetime = XCTAttachmentLifetimeKeepAlways; + [self addAttachment:goldenAttachment]; + } else { + XCTFail(@"This test will fail - no golden named %@ found. Follow the steps in the " + @"README to add a new golden.", + goldenName); + } + + XCTAssertTrue([self compareImage:golden toOther:screenshot.image]); } -- (void)testPlatformView { - [self checkGolden]; +- (NSString*)platformName { + NSString* simulatorName = + [[NSProcessInfo processInfo].environment objectForKey:@"SIMULATOR_DEVICE_NAME"]; + if (simulatorName) { + return [NSString stringWithFormat:@"%@_simulator", simulatorName]; + } + + size_t size; + sysctlbyname("hw.model", NULL, &size, NULL, 0); + char* answer = malloc(size); + sysctlbyname("hw.model", answer, &size, NULL, 0); + + NSString* results = [NSString stringWithCString:answer encoding:NSUTF8StringEncoding]; + free(answer); + return results; } -@end +- (BOOL)compareImage:(UIImage*)a toOther:(UIImage*)b { + CGImageRef imageRefA = [a CGImage]; + CGImageRef imageRefB = [b CGImage]; -@interface PlatformViewMutationTransformTests : GoldenPlatformViewTests + NSUInteger widthA = CGImageGetWidth(imageRefA); + NSUInteger heightA = CGImageGetHeight(imageRefA); + NSUInteger widthB = CGImageGetWidth(imageRefB); + NSUInteger heightB = CGImageGetHeight(imageRefB); -@end + if (widthA != widthB || heightA != heightB) { + return NO; + } + NSUInteger bytesPerPixel = 4; + NSUInteger size = widthA * heightA * bytesPerPixel; + NSMutableData* rawA = [NSMutableData dataWithLength:size]; + NSMutableData* rawB = [NSMutableData dataWithLength:size]; -@implementation PlatformViewMutationTransformTests + if (!rawA || !rawB) { + return NO; + } -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view-transform"]; - return [super initWithManager:manager invocation:invocation]; -} - -- (void)testPlatformView { - [self checkGolden]; -} + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); -@end + NSUInteger bytesPerRow = bytesPerPixel * widthA; + NSUInteger bitsPerComponent = 8; + CGContextRef contextA = + CGBitmapContextCreate(rawA.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow, + colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); -@interface PlatformViewMutationOpacityTests : GoldenPlatformViewTests + CGContextDrawImage(contextA, CGRectMake(0, 0, widthA, heightA), imageRefA); + CGContextRelease(contextA); -@end + CGContextRef contextB = + CGBitmapContextCreate(rawB.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow, + colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); + CGColorSpaceRelease(colorSpace); -@implementation PlatformViewMutationOpacityTests + CGContextDrawImage(contextB, CGRectMake(0, 0, widthA, heightA), imageRefB); + CGContextRelease(contextB); -- (instancetype)initWithInvocation:(NSInvocation*)invocation { - PlatformViewGoldenTestManager* manager = - [[PlatformViewGoldenTestManager alloc] initWithLaunchArg:@"--platform-view-opacity"]; - return [super initWithManager:manager invocation:invocation]; -} + if (memcmp(rawA.mutableBytes, rawB.mutableBytes, size)) { + return NO; + } -- (void)testPlatformView { - [self checkGolden]; + return YES; } @end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone SE_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone SE_simulator.png deleted file mode 100644 index 8e776f220e849..0000000000000 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone SE_simulator.png and /dev/null differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_iPhone SE_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_iPhone SE_simulator.png deleted file mode 100644 index 9049412903215..0000000000000 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_iPhone SE_simulator.png and /dev/null differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_iPhone SE_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_iPhone SE_simulator.png deleted file mode 100644 index 94667b9a8254d..0000000000000 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_iPhone SE_simulator.png and /dev/null differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_opacity_iPhone SE_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_opacity_iPhone SE_simulator.png deleted file mode 100644 index 32e0a179a5c6c..0000000000000 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_opacity_iPhone SE_simulator.png and /dev/null differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone SE_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone SE_simulator.png deleted file mode 100644 index 678c7fd6bc7bb..0000000000000 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone SE_simulator.png and /dev/null differ diff --git a/testing/scenario_app/lib/main.dart b/testing/scenario_app/lib/main.dart index bbc16454470aa..11126afe69427 100644 --- a/testing/scenario_app/lib/main.dart +++ b/testing/scenario_app/lib/main.dart @@ -16,12 +16,7 @@ import 'src/scenario.dart'; Map _scenarios = { 'animated_color_square': AnimatedColorSquareScenario(window), - 'platform_view': PlatformViewScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_cliprect': PlatformViewClipRectScenario(window, 'PlatformViewClipRect', id: 1), - 'platform_view_cliprrect': PlatformViewClipRRectScenario(window, 'PlatformViewClipRRect', id: 2), - 'platform_view_clippath': PlatformViewClipPathScenario(window, 'PlatformViewClipPath', id: 3), - 'platform_view_transform': PlatformViewTransformScenario(window, 'PlatformViewTransform', id: 4), - 'platform_view_opacity': PlatformViewOpacityScenario(window, 'PlatformViewOpacity', id: 5), + 'text_platform_view': PlatformViewScenario(window, 'Hello from Scenarios (Platform View)'), 'poppable_screen': PoppableScreenScenario(window), }; diff --git a/testing/scenario_app/lib/src/platform_view.dart b/testing/scenario_app/lib/src/platform_view.dart index 354a2dcabf14d..4286469ce2937 100644 --- a/testing/scenario_app/lib/src/platform_view.dart +++ b/testing/scenario_app/lib/src/platform_view.dart @@ -4,10 +4,8 @@ import 'dart:convert'; import 'dart:io'; -import 'dart:math'; import 'dart:typed_data'; import 'dart:ui'; -import 'package:vector_math/vector_math_64.dart'; import 'scenario.dart'; @@ -28,147 +26,13 @@ List _to64(num value) { } /// A simple platform view. -class PlatformViewScenario extends Scenario - with _BasePlatformViewScenarioMixin { +class PlatformViewScenario extends Scenario { /// Creates the PlatformView scenario. /// /// The [window] parameter must not be null. PlatformViewScenario(Window window, String text, {int id = 0}) : assert(window != null), super(window) { - constructScenario(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - finishBuilderByAddingPlatformViewAndPicture(builder, 0); - } -} - -/// Platform view with clip rect. -class PlatformViewClipRectScenario extends Scenario - with _BasePlatformViewScenarioMixin { - /// Constructs a platform view with clip rect scenario. - PlatformViewClipRectScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - constructScenario(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - builder.pushOffset(0, 0); - builder.pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)); - finishBuilderByAddingPlatformViewAndPicture(builder, 1); - } -} - -/// Platform view with clip rrect. -class PlatformViewClipRRectScenario extends PlatformViewScenario { - /// Constructs a platform view with clip rrect scenario. - PlatformViewClipRRectScenario(Window window, String text, {int id = 0}) - : super(window, text, id: id); - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - builder.pushClipRRect( - RRect.fromLTRBAndCorners( - 100, - 100, - 400, - 400, - topLeft: const Radius.circular(15), - topRight: const Radius.circular(50), - bottomLeft: const Radius.circular(50), - ), - ); - finishBuilderByAddingPlatformViewAndPicture(builder, 2); - } -} - -/// Platform view with clip path. -class PlatformViewClipPathScenario extends PlatformViewScenario { - /// Constructs a platform view with clip rrect scenario. - PlatformViewClipPathScenario(Window window, String text, {int id = 0}) - : super(window, text, id: id); - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - // Create a path of rectangle with width of 200 and height of 300, starting from (100, 100). - // - // Refer to "../../ios/Scenarios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone SE_simulator.png" for the exact path after clipping. - Path path = Path(); - path.moveTo(100, 100); - path.quadraticBezierTo(50, 250, 100, 400); - path.lineTo(350, 400); - path.cubicTo(400, 300, 300, 200, 350, 100); - path.close(); - builder.pushClipPath(path); - - finishBuilderByAddingPlatformViewAndPicture(builder, 3); - } -} - -/// Platform view with transform. -class PlatformViewTransformScenario extends PlatformViewScenario { - /// Constructs a platform view with transform scenario. - PlatformViewTransformScenario(Window window, String text, {int id = 0}) - : super(window, text, id: id); - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - final Matrix4 matrix4 = Matrix4.identity() - ..rotateZ(1) - ..scale(0.5, 0.5, 1.0) - ..translate(1000.0, 100.0, 0.0); - - builder.pushTransform(matrix4.storage); - - finishBuilderByAddingPlatformViewAndPicture(builder, 4); - } -} - -/// Platform view with opacity. -class PlatformViewOpacityScenario extends PlatformViewScenario { - /// Constructs a platform view with transform scenario. - PlatformViewOpacityScenario(Window window, String text, {int id = 0}) - : super(window, text, id: id); - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - builder.pushOpacity(150); - - finishBuilderByAddingPlatformViewAndPicture(builder, 5); - } -} - -mixin _BasePlatformViewScenarioMixin on Scenario { - int _textureId; - - /// Construct the platform view related scenario - /// - /// It prepare a TextPlatformView so it can be added to the SceneBuilder in `onBeginFrame`. - /// Call this method in the constructor of the platform view related scenarios - /// to perform necessary set up. - void constructScenario(Window window, String text, int id) { const int _valueInt32 = 3; const int _valueFloat64 = 6; const int _valueString = 7; @@ -176,7 +40,7 @@ mixin _BasePlatformViewScenarioMixin on Scenario { const int _valueMap = 13; final Uint8List message = Uint8List.fromList([ _valueString, - 'create'.length, // this won't work if we use multi-byte characters. + 'create'.length, // this is safe as long as these are all single byte characters. ...utf8.encode('create'), _valueMap, if (Platform.isIOS) @@ -230,27 +94,29 @@ mixin _BasePlatformViewScenarioMixin on Scenario { ); } - // Add a platform view and a picture to the scene, then finish the `sceneBuilder`. - void finishBuilderByAddingPlatformViewAndPicture(SceneBuilder sceneBuilder, int viewId) { + int _textureId; + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + + builder.pushOffset(0, 0); + if (Platform.isIOS) { - sceneBuilder.addPlatformView(viewId, width: 500, height: 500); + builder.addPlatformView(0, width: 500, height: 500); } else if (Platform.isAndroid && _textureId != null) { - sceneBuilder.addTexture(_textureId, - offset: const Offset(150, 300), width: 500, height: 500); + builder.addTexture(_textureId, offset: const Offset(150, 300), width: 500, height: 500); } else { - throw UnsupportedError( - 'Platform ${Platform.operatingSystem} is not supported'); + throw UnsupportedError('Platform ${Platform.operatingSystem} is not supported'); } + final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); - canvas.drawCircle( - const Offset(50, 50), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); + canvas.drawCircle(const Offset(50, 50), 50, Paint()..color = const Color(0xFFABCDEF)); final Picture picture = recorder.endRecording(); - sceneBuilder.addPicture(const Offset(300, 300), picture); - final Scene scene = sceneBuilder.build(); + builder.addPicture(const Offset(300, 300), picture); + + final Scene scene = builder.build(); window.render(scene); scene.dispose(); } diff --git a/testing/scenario_app/pubspec.yaml b/testing/scenario_app/pubspec.yaml index f17ddb080a7dc..8748b51653ac9 100644 --- a/testing/scenario_app/pubspec.yaml +++ b/testing/scenario_app/pubspec.yaml @@ -8,4 +8,3 @@ dependencies: path: ../../../out/host_debug_unopt/gen/dart-pkg/sky_engine sky_services: path: ../../../out/host_debug_unopt/gen/dart-pkg/sky_services - vector_math: ^2.0.8