From 75d34407c11f884a71c44bfaded664b80caf3aed Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Wed, 14 Jun 2023 17:14:02 -0700 Subject: [PATCH] test RCTInstance invalidation on RCTHost restart (#37899) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37899 Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D46547012 fbshipit-source-id: 9b157678c474120aeca3896942e368678cb5b8eb --- .../react/bridgeless/iostests/RCTHostTests.mm | 37 +++++++++++++++++++ .../bridgeless/platform/ios/Core/RCTHost.mm | 4 ++ .../test_utils/ios/Shims/ShimRCTInstance.h | 1 + .../test_utils/ios/Shims/ShimRCTInstance.mm | 8 ++++ 4 files changed, 50 insertions(+) diff --git a/packages/react-native/ReactCommon/react/bridgeless/iostests/RCTHostTests.mm b/packages/react-native/ReactCommon/react/bridgeless/iostests/RCTHostTests.mm index 58467be556b..be05d7a97ab 100644 --- a/packages/react-native/ReactCommon/react/bridgeless/iostests/RCTHostTests.mm +++ b/packages/react-native/ReactCommon/react/bridgeless/iostests/RCTHostTests.mm @@ -8,6 +8,8 @@ #import #import +#import +#import #import #import #import @@ -15,6 +17,22 @@ #import +RCT_MOCK_REF(RCTHost, _RCTLogNativeInternal); + +RCTLogLevel gLogLevel; +int gLogCalledTimes = 0; +NSString *gLogMessage = nil; +static void RCTLogNativeInternalMock(RCTLogLevel level, const char *fileName, int lineNumber, NSString *format, ...) +{ + gLogLevel = level; + gLogCalledTimes++; + + va_list args; + va_start(args, format); + gLogMessage = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); +} + @interface RCTHostTests : XCTestCase @end @@ -43,15 +61,34 @@ static ShimRCTInstance *shimmedRCTInstance; - (void)tearDown { [shimmedRCTInstance reset]; + gLogCalledTimes = 0; + gLogMessage = nil; [super tearDown]; } - (void)testStart { + RCT_MOCK_SET(RCTHost, _RCTLogNativeInternal, RCTLogNativeInternalMock); + + XCTAssertEqual(shimmedRCTInstance.initCount, 0); [_subject start]; OCMVerify(OCMTimes(1), [_mockHostDelegate hostDidStart:_subject]); XCTAssertEqual(shimmedRCTInstance.initCount, 1); + XCTAssertEqual(gLogCalledTimes, 0); + + XCTAssertEqual(shimmedRCTInstance.invalidateCount, 0); + [_subject start]; + XCTAssertEqual(shimmedRCTInstance.initCount, 2); + XCTAssertEqual(shimmedRCTInstance.invalidateCount, 1); + OCMVerify(OCMTimes(2), [_mockHostDelegate hostDidStart:_subject]); + XCTAssertEqual(gLogLevel, RCTLogLevelWarning); + XCTAssertEqual(gLogCalledTimes, 1); + XCTAssertEqualObjects( + gLogMessage, + @"RCTHost should not be creating a new instance if one already exists. This implies there is a bug with how/when this method is being called."); + + RCT_MOCK_RESET(RCTHost, _RCTLogNativeInternal); } @end diff --git a/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTHost.mm b/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTHost.mm index d7d8c274af1..2706a9e40ad 100644 --- a/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTHost.mm +++ b/packages/react-native/ReactCommon/react/bridgeless/platform/ios/Core/RCTHost.mm @@ -15,9 +15,13 @@ #import #import #import +#import #import #import +RCT_MOCK_DEF(RCTHost, _RCTLogNativeInternal); +#define _RCTLogNativeInternal RCT_MOCK_USE(RCTHost, _RCTLogNativeInternal) + using namespace facebook::react; @interface RCTHost () diff --git a/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.h b/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.h index a0aee07975b..42686392f2a 100644 --- a/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.h +++ b/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.h @@ -10,6 +10,7 @@ @interface ShimRCTInstance : NSObject @property (assign) int initCount; +@property (assign) int invalidateCount; - (void)reset; diff --git a/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.mm b/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.mm index 017b45ac212..0cfaff555d9 100644 --- a/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.mm +++ b/packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.mm @@ -24,6 +24,7 @@ static __weak ShimRCTInstance *weakShim = nil; [ShimRCTInstance class], @selector(initWithDelegate: jsEngineInstance:bundleManager:turboModuleManagerDelegate:onInitialBundleLoad:moduleRegistry:)); + RCTSwizzleInstanceSelector([RCTInstance class], [ShimRCTInstance class], @selector(invalidate)); weakShim = self; } return self; @@ -36,7 +37,9 @@ static __weak ShimRCTInstance *weakShim = nil; [ShimRCTInstance class], @selector(initWithDelegate: jsEngineInstance:bundleManager:turboModuleManagerDelegate:onInitialBundleLoad:moduleRegistry:)); + RCTSwizzleInstanceSelector([RCTInstance class], [ShimRCTInstance class], @selector(invalidate)); _initCount = 0; + _invalidateCount = 0; } - (instancetype)initWithDelegate:(id)delegate @@ -50,4 +53,9 @@ static __weak ShimRCTInstance *weakShim = nil; return self; } +- (void)invalidate +{ + weakShim.invalidateCount++; +} + @end