static void SwizzleXCTestMethodsIfAvailable()

in Shims/Shimulator/TestReporterShim/XCTestReporterShim.m [520:621]


static void SwizzleXCTestMethodsIfAvailable()
{
  if ([[[NSBundle mainBundle] bundleIdentifier] hasPrefix:@"com.apple.dt.xctest"]) {
    // Start from Xcode 11.1, XCTest will try to connect to testmanagerd service
    // when reporting test failures (for capture screenshots automatically), and crash
    // if it cannot make a connection.
    // We don't really boot the simulator for running logic tests, so just force
    // it to return nil.
    static dispatch_once_t token;
    dispatch_once(&token, ^{
      XTSwizzleClassSelectorForFunction(
        NSClassFromString(@"XCTRunnerDaemonSession"),
        @selector(sharedSession),
        (IMP)XCTRunnerDaemonSession_sharedSession
      );
    });
  }

  Class testLogClass = objc_getClass("XCTestLog");

  if (testLogClass == nil) {
    // Looks like the XCTest framework has not been loaded yet.
    return;
  }

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    if ([testLogClass instancesRespondToSelector:@selector(testSuiteWillStart:)]) {
      // Swizzle methods for Xcode 8.
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testSuiteWillStart:),
        (IMP)XCTestLog_testSuiteWillStart
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testSuiteDidFinish:),
        (IMP)XCTestLog_testSuiteDidFinish
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCaseWillStart:),
        (IMP)XCTestLog_testCaseWillStart
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCaseDidFinish:),
        (IMP)XCTestLog_testCaseDidFinish
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCase:didFailWithDescription:inFile:atLine:),
        (IMP)XCTestLog_testCaseDidFailWithDescription
      );
    } else {
      // Swizzle methods for Xcode 7 and earlier.
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testSuiteDidStart:),
        (IMP)XCTestLog_testSuiteDidStart
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testSuiteDidStop:),
        (IMP)XCTestLog_testSuiteDidStop
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCaseDidStart:),
        (IMP)XCTestLog_testCaseDidStart
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCaseDidStop:),
        (IMP)XCTestLog_testCaseDidStop
      );
      XTSwizzleSelectorForFunction(
        testLogClass,
        @selector(testCaseDidFail:withDescription:inFile:atLine:),
        (IMP)XCTestLog_testCaseDidFail
      );
      XTSwizzleSelectorForFunction(
        objc_getClass("XCTestCaseSuite"),
        @selector(performTest:),
        (IMP)XCTestCaseSuite_performTest
      );
    }
    XTSwizzleSelectorForFunction(
      objc_getClass("XCTestCase"),
      @selector(performTest:),
      (IMP)XCTestCase_performTest
    );
    if ([objc_getClass("XCTestCase") respondsToSelector:@selector(_enableSymbolication)]) {
      // Disable symbolication thing on xctest 7 because it sometimes takes forever.
      XTSwizzleClassSelectorForFunction(
        objc_getClass("XCTestCase"),
        @selector(_enableSymbolication),
        (IMP)XCTestCase__enableSymbolication
      );
    }
  });
}