blob: e75bcf8715dca2a05bcfd957c11d1336bd24cfe9 [file] [log] [blame]
// 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.
// XCTest is weakly linked.
#if __has_include(<XCTest/XCTest.h>)
#import "FLTIntegrationTestCase.h"
#import "FLTIntegrationTestRunner.h"
#import "IntegrationTestPlugin.h"
@import ObjectiveC.runtime;
@import XCTest;
@implementation FLTIntegrationTestCase
+ (NSArray<NSInvocation *> *)testInvocations {
if (self == [FLTIntegrationTestCase class]) {
// Do not add any tests for this base class.
return @[];
}
FLTIntegrationTestRunner *integrationTestRunner = [FLTIntegrationTestRunner new];
NSMutableArray<NSInvocation *> *testInvocations = [NSMutableArray new];
[integrationTestRunner testIntegrationTestWithResults:^(NSString *testName, BOOL success, NSString *failureMessage) {
// 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.
IMP assertImplementation = imp_implementationWithBlock(^(id _self) {
XCTAssertTrue(success, @"%@", failureMessage);
});
// Create an appropriate XCTest method name based on the dart test name.
// Example: dart test "verify widget" becomes "testVerifyWidget"
NSString *upperCamelTestName = [testName.localizedCapitalizedString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSString *testSelectorName = [NSString stringWithFormat:@"test%@", upperCamelTestName];
SEL testSelector = NSSelectorFromString(testSelectorName);
class_addMethod(self, testSelector, assertImplementation, "v@:");
// Add the new class method as a test invocation to the XCTestCase.
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) {
// If the Flutter dart tests have captured screenshots, add them to the XCTest bundle.
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
#endif