From 742d47b5728a785b455991c2b568f116e5f9dd37 Mon Sep 17 00:00:00 2001 From: Ty Rauber Date: Wed, 9 Sep 2026 19:46:07 -0700 Subject: [PATCH 1/3] fix(macos): use RCTPlatformImage in RCTImageLoaderTests RCTImageLoaderTests.m is compiled into both RNTesterUnitTests (iOS) and RNTester-macOSUnitTests, but referenced UIImage directly, so the macOS unit test target failed to compile: RCTImageLoaderTests.m:38:3: error: unknown type name 'UIImage'; did you mean 'CIImage'? Use RCTPlatformImage, the existing per-platform alias (UIImage on iOS, NSImage on macOS) that RCTImageLoaderCompletionBlock and RCTImageLoaderPartialLoadBlock already use. Co-Authored-By: Claude Opus 5 (1M context) --- .../RNTesterUnitTests/RCTImageLoaderTests.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/rn-tester/RNTesterUnitTests/RCTImageLoaderTests.m b/packages/rn-tester/RNTesterUnitTests/RCTImageLoaderTests.m index 6c58e9cb26d0..baedbf966369 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTImageLoaderTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTImageLoaderTests.m @@ -7,6 +7,8 @@ #import +#import // [macOS] + #import #import @@ -35,7 +37,7 @@ - (void)setUp - (void)testImageLoading { - UIImage *image = [UIImage new]; + RCTPlatformImage *image = [RCTPlatformImage new]; // [macOS] id loader = [[RCTImageLoaderTestsURLLoader1 alloc] initWithPriority:1.0 canLoadImageURLHandler:^BOOL(__unused NSURL *requestURL) { @@ -70,7 +72,7 @@ - (void)testImageLoading XCTAssertEqual(progress, 1); XCTAssertEqual(total, 1); } - partialLoadBlock:^(UIImage *loadedImage) { + partialLoadBlock:^(RCTPlatformImage *loadedImage) { // [macOS] } completionBlock:^(NSError *loadError, id loadedImage) { XCTAssertEqualObjects(loadedImage, image); @@ -80,7 +82,7 @@ - (void)testImageLoading - (void)testImageLoaderUsesImageURLLoaderWithHighestPriority { - UIImage *image = [UIImage new]; + RCTPlatformImage *image = [RCTPlatformImage new]; // [macOS] id loader1 = [[RCTImageLoaderTestsURLLoader1 alloc] initWithPriority:1.0 canLoadImageURLHandler:^BOOL(__unused NSURL *requestURL) { @@ -130,7 +132,7 @@ - (void)testImageLoaderUsesImageURLLoaderWithHighestPriority XCTAssertEqual(progress, 1); XCTAssertEqual(total, 1); } - partialLoadBlock:^(UIImage *loadedImage) { + partialLoadBlock:^(RCTPlatformImage *loadedImage) { // [macOS] } completionBlock:^(NSError *loadError, id loadedImage) { XCTAssertEqualObjects(loadedImage, image); @@ -141,7 +143,7 @@ - (void)testImageLoaderUsesImageURLLoaderWithHighestPriority - (void)testImageDecoding { NSData *data = [NSData dataWithBytesNoCopy:blackGIF length:sizeof(blackGIF) freeWhenDone:NO]; - UIImage *image = [[UIImage alloc] initWithData:data]; + RCTPlatformImage *image = [[RCTPlatformImage alloc] initWithData:data]; // [macOS] id decoder = [[RCTImageLoaderTestsDecoder1 alloc] initWithPriority:1.0 canDecodeImageDataHandler:^BOOL(__unused NSData *imageData) { @@ -180,7 +182,7 @@ - (void)testImageDecoding - (void)testImageLoaderUsesImageDecoderWithHighestPriority { NSData *data = [NSData dataWithBytesNoCopy:blackGIF length:sizeof(blackGIF) freeWhenDone:NO]; - UIImage *image = [[UIImage alloc] initWithData:data]; + RCTPlatformImage *image = [[RCTPlatformImage alloc] initWithData:data]; // [macOS] id decoder1 = [[RCTImageLoaderTestsDecoder1 alloc] initWithPriority:1.0 canDecodeImageDataHandler:^BOOL(__unused NSData *imageData) { From 60f09c46099b0f34c854427ba5d748b783b78fb1 Mon Sep 17 00:00:00 2001 From: Ty Rauber Date: Wed, 9 Sep 2026 19:46:15 -0700 Subject: [PATCH 2/3] fix: give RCTIsGzippedData C linkage so RCTGzipTests links RCTGzipTests.m is a plain .m file that forward-declared `extern BOOL RCTIsGzippedData(NSData *data);` and calls it. RCTUtils was converted to Objective-C++ in a74649d285c, which gave the definition C++ mangling, so the test bundle no longer links: Undefined symbols for architecture arm64: "_RCTIsGzippedData", referenced from: -[RCTGzipTests testGzip] in RCTGzipTests.o -[RCTGzipTests testRequestBodyEncoding] in RCTGzipTests.o Declare it in RCTUtils.h with RCT_EXTERN, like every other RCTUtils function, which restores C linkage. Drop the now-redundant forward declaration in RCTUtils.mm and the local extern in the test. No behavior change. Co-Authored-By: Claude Opus 5 (1M context) --- packages/react-native/React/Base/RCTUtils.h | 4 ++++ packages/react-native/React/Base/RCTUtils.mm | 1 - packages/rn-tester/RNTesterUnitTests/RCTGzipTests.m | 2 -- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-native/React/Base/RCTUtils.h b/packages/react-native/React/Base/RCTUtils.h index a26b1a7a5fc6..b06b279593fe 100644 --- a/packages/react-native/React/Base/RCTUtils.h +++ b/packages/react-native/React/Base/RCTUtils.h @@ -141,6 +141,10 @@ RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data); // Gzip functionality - compression level in range 0 - 1 (-1 for default) RCT_EXTERN NSData *__nullable RCTGzipData(NSData *__nullable data, float level); +// Determines whether data is already gzipped. Declared here (rather than only in +// RCTUtils.mm) so it keeps C linkage and can be called from .m unit tests. +RCT_EXTERN BOOL RCTIsGzippedData(NSData *__nullable data); + // Returns the relative path within the main bundle for an absolute URL // (or nil, if the URL does not specify a path within the main bundle) RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL); diff --git a/packages/react-native/React/Base/RCTUtils.mm b/packages/react-native/React/Base/RCTUtils.mm index a378d0001e7a..7ea31c9702e2 100644 --- a/packages/react-native/React/Base/RCTUtils.mm +++ b/packages/react-native/React/Base/RCTUtils.mm @@ -761,7 +761,6 @@ BOOL RCTForceTouchAvailable(void) [data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]]; } -BOOL RCTIsGzippedData(NSData *__nullable /*data*/); // exposed for unit testing purposes BOOL RCTIsGzippedData(NSData *__nullable data) { UInt8 *bytes = (UInt8 *)data.bytes; diff --git a/packages/rn-tester/RNTesterUnitTests/RCTGzipTests.m b/packages/rn-tester/RNTesterUnitTests/RCTGzipTests.m index a24d9972be77..de848ba8be3a 100644 --- a/packages/rn-tester/RNTesterUnitTests/RCTGzipTests.m +++ b/packages/rn-tester/RNTesterUnitTests/RCTGzipTests.m @@ -11,8 +11,6 @@ #import #import -extern BOOL RCTIsGzippedData(NSData *data); - @interface RCTNetworking (Private) - (void)buildRequest:(NSDictionary *)query completionBlock:(void (^)(NSURLRequest *request))block; From b334a7a837e01364e1c892b89f2d90346d1f53a2 Mon Sep 17 00:00:00 2001 From: Ty Rauber Date: Wed, 9 Sep 2026 20:46:14 -0700 Subject: [PATCH 3/3] fix(macos): drop sanitizers from the macOS test plan so tests can launch With any sanitizer enabled in RNTester-macOS.xctestplan, macOS unit tests cannot be run at all on Xcode 26.0.1 / macOS 26.6.2. Two separate toolchain failures, both reproduced: 1. Launch. A sanitizer makes Xcode build into Build/Products/Variant-/Debug, but the scheme-driven test launcher does not follow it: xctest encountered an error (Failed to install or launch the test runner. (Underlying Error: Launch error. There is a problem launching using posix_spawn (error code: 2).)) Reproduced with ASan+UBSan and with UBSan alone. The same build runs fine when driven from the generated .xctestrun, which carries absolute paths, so the products are good and only the launcher is confused. 2. Address Sanitizer deadlock. Past the launcher, an ASan-instrumented xctest bundle never starts: xctest encountered an error (The test runner hung before establishing connection.) sample(1) shows the ASan runtime spinning in its own initializer: __asan::AsanInitInternal() __asan::InitializeShadowMemory() __sanitizer::MemoryRangeIsAvailable() __sanitizer::get_dyld_hdr() dyld_shared_cache_iterate_text_swift _Block_copy -> malloc __sanitizer_mz_malloc __asan::AsanInitFromRtl() <- re-entrant __sanitizer::StaticSpinMutex::LockSlow() internal_sched_yield() <- forever This is not a React Native bug. A three-line Swift package with one trivial test fails identically with -enableAddressSanitizer YES, and passes without it and with -enableUndefinedBehaviorSanitizer YES. The iOS plan (RNTester/RNTester.xctestplan) is left alone; only the macOS plan is changed. Restore the sanitizer configuration once the toolchain is fixed. With this change `xcodebuild test -scheme RNTester-macOS -only-testing:RNTester-macOSUnitTests` launches and runs all 192 tests. Co-Authored-By: Claude Opus 5 (1M context) --- .../rn-tester/RNTester-macOS/RNTester-macOS.xctestplan | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/rn-tester/RNTester-macOS/RNTester-macOS.xctestplan b/packages/rn-tester/RNTester-macOS/RNTester-macOS.xctestplan index b4aa08079c2e..91420d67276a 100644 --- a/packages/rn-tester/RNTester-macOS/RNTester-macOS.xctestplan +++ b/packages/rn-tester/RNTester-macOS/RNTester-macOS.xctestplan @@ -2,12 +2,9 @@ "configurations" : [ { "id" : "59C4DFC4-597F-41C6-99FD-32D94C5488D4", - "name" : "Address Sanitizer", + "name" : "Default", "options" : { - "addressSanitizer" : { - "detectStackUseAfterReturn" : true, - "enabled" : true - } + } } ], @@ -24,8 +21,7 @@ "identifier" : "ACC52F3D299ECB7A002A2B0B", "name" : "RNTester-macOS" }, - "testRepetitionMode" : "retryOnFailure", - "undefinedBehaviorSanitizerEnabled" : true + "testRepetitionMode" : "retryOnFailure" }, "testTargets" : [ {