| // 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 Foundation; |
| @import ObjectiveC.runtime; |
| |
| NS_ASSUME_NONNULL_BEGIN |
| |
| DEPRECATED_MSG_ATTRIBUTE("Use FLTIntegrationTestRunner instead.") |
| @interface IntegrationTestIosTest : NSObject |
| |
| /** |
| * Initiate dart tests and wait for results. @c testResult will be set to a string describing the results. |
| * |
| * @return @c YES if all tests succeeded. |
| */ |
| - (BOOL)testIntegrationTest:(NSString *_Nullable *_Nullable)testResult; |
| |
| @end |
| |
| // For every Flutter dart test, dynamically generate an Objective-C method mirroring the test results |
| // so it is reported as a native XCTest run result. |
| // If the Flutter dart tests have captured screenshots, add them to the XCTest bundle. |
| #define INTEGRATION_TEST_IOS_RUNNER(__test_class) \ |
| @interface __test_class : XCTestCase \ |
| @end \ |
| \ |
| @implementation __test_class \ |
| \ |
| + (NSArray<NSInvocation *> *)testInvocations { \ |
| FLTIntegrationTestRunner *integrationTestRunner = [[FLTIntegrationTestRunner alloc] init]; \ |
| NSMutableArray<NSInvocation *> *testInvocations = [[NSMutableArray alloc] init]; \ |
| [integrationTestRunner testIntegrationTestWithResults:^(SEL testSelector, BOOL success, NSString *failureMessage) { \ |
| IMP assertImplementation = imp_implementationWithBlock(^(id _self) { \ |
| XCTAssertTrue(success, @"%@", failureMessage); \ |
| }); \ |
| class_addMethod(self, testSelector, assertImplementation, "v@:"); \ |
| NSMethodSignature *signature = [self instanceMethodSignatureForSelector:testSelector]; \ |
| NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; \ |
| invocation.selector = testSelector; \ |
| [testInvocations addObject:invocation]; \ |
| }]; \ |
| NSDictionary<NSString *, UIImage *> *capturedScreenshotsByName = integrationTestRunner.capturedScreenshotsByName; \ |
| if (capturedScreenshotsByName.count > 0) { \ |
| IMP screenshotImplementation = imp_implementationWithBlock(^(id _self) { \ |
| [capturedScreenshotsByName enumerateKeysAndObjectsUsingBlock:^(NSString *name, UIImage *screenshot, BOOL *stop) { \ |
| XCTAttachment *attachment = [XCTAttachment attachmentWithImage:screenshot]; \ |
| attachment.lifetime = XCTAttachmentLifetimeKeepAlways; \ |
| if (name != nil) { \ |
| attachment.name = name; \ |
| } \ |
| [_self addAttachment:attachment]; \ |
| }]; \ |
| }); \ |
| SEL attachmentSelector = NSSelectorFromString(@"screenshotPlaceholder"); \ |
| class_addMethod(self, attachmentSelector, screenshotImplementation, "v@:"); \ |
| NSMethodSignature *attachmentSignature = [self instanceMethodSignatureForSelector:attachmentSelector]; \ |
| NSInvocation *attachmentInvocation = [NSInvocation invocationWithMethodSignature:attachmentSignature]; \ |
| attachmentInvocation.selector = attachmentSelector; \ |
| [testInvocations addObject:attachmentInvocation]; \ |
| } \ |
| return testInvocations; \ |
| } \ |
| \ |
| @end |
| |
| NS_ASSUME_NONNULL_END |