| // Copyright 2014 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 "FLTIntegrationTestRunner.h" |
| |
| #import "IntegrationTestPlugin.h" |
| |
| @import ObjectiveC.runtime; |
| @import UIKit; |
| |
| @interface FLTIntegrationTestRunner () |
| |
| @property IntegrationTestPlugin *integrationTestPlugin; |
| |
| @end |
| |
| @implementation FLTIntegrationTestRunner |
| |
| - (instancetype)init { |
| self = [super init]; |
| _integrationTestPlugin = [IntegrationTestPlugin instance]; |
| |
| return self; |
| } |
| |
| - (void)testIntegrationTestWithResults:(NS_NOESCAPE FLTIntegrationTestResults)testResult { |
| IntegrationTestPlugin *integrationTestPlugin = self.integrationTestPlugin; |
| UIViewController *rootViewController = UIApplication.sharedApplication.delegate.window.rootViewController; |
| if (![rootViewController isKindOfClass:[FlutterViewController class]]) { |
| testResult(NSSelectorFromString(@"testSetup"), NO, @"rootViewController was not expected FlutterViewController"); |
| } |
| FlutterViewController *flutterViewController = (FlutterViewController *)rootViewController; |
| [integrationTestPlugin setupChannels:flutterViewController.engine.binaryMessenger]; |
| |
| // Spin the runloop. |
| while (!integrationTestPlugin.testResults) { |
| [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; |
| } |
| |
| NSMutableSet<NSString *> *testCaseNames = [[NSMutableSet alloc] init]; |
| |
| [integrationTestPlugin.testResults enumerateKeysAndObjectsUsingBlock:^(NSString *test, NSString *result, BOOL *stop) { |
| NSString *testSelectorName = [[self class] testCaseNameFromDartTestName:test]; |
| |
| // Validate Objective-C test names are unique after sanitization. |
| if ([testCaseNames containsObject:testSelectorName]) { |
| NSString *reason = [NSString stringWithFormat:@"Cannot test \"%@\", duplicate XCTestCase tests named %@", test, testSelectorName]; |
| testResult(NSSelectorFromString(@"testDuplicateTestNames"), NO, reason); |
| *stop = YES; |
| return; |
| } |
| [testCaseNames addObject:testSelectorName]; |
| SEL testSelector = NSSelectorFromString(testSelectorName); |
| |
| if ([result isEqualToString:@"success"]) { |
| testResult(testSelector, YES, nil); |
| } else { |
| testResult(testSelector, NO, result); |
| } |
| }]; |
| } |
| |
| - (NSDictionary<NSString *,UIImage *> *)capturedScreenshotsByName { |
| return self.integrationTestPlugin.capturedScreenshotsByName; |
| } |
| |
| + (NSString *)testCaseNameFromDartTestName:(NSString *)dartTestName { |
| NSString *capitalizedString = dartTestName.localizedCapitalizedString; |
| // Objective-C method names must be alphanumeric. |
| NSCharacterSet *disallowedCharacters = NSCharacterSet.alphanumericCharacterSet.invertedSet; |
| // Remove disallowed characters. |
| NSString *upperCamelTestName = [[capitalizedString componentsSeparatedByCharactersInSet:disallowedCharacters] componentsJoinedByString:@""]; |
| return [NSString stringWithFormat:@"test%@", upperCamelTestName]; |
| } |
| |
| @end |