From ac524426242049db2844576cc4f6d4f8776e71d5 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 18 Jan 2025 20:18:28 -0800 Subject: [PATCH] feat: visionOS unit tests (#257) --- NativeScript/NativeScript-Prefix.pch | 2 +- README.md | 3 + TestFixtures/Api/TNSVersions.h | 111 +++++++++--------- TestFixtures/exported-symbols.txt | 9 ++ .../app/tests/Infrastructure/simulator.js | 6 + TestRunner/app/tests/MetadataTests.js | 8 +- TestRunner/app/tests/VersionDiffTests.js | 16 ++- v8ios.xcodeproj/project.pbxproj | 26 +++- 8 files changed, 119 insertions(+), 62 deletions(-) diff --git a/NativeScript/NativeScript-Prefix.pch b/NativeScript/NativeScript-Prefix.pch index b070729c..12e1daf3 100644 --- a/NativeScript/NativeScript-Prefix.pch +++ b/NativeScript/NativeScript-Prefix.pch @@ -1,7 +1,7 @@ #ifndef NativeScript_Prefix_pch #define NativeScript_Prefix_pch -#define NATIVESCRIPT_VERSION "8.7.2" +#define NATIVESCRIPT_VERSION "8.8.1" #ifdef DEBUG #define SIZEOF_OFF_T 8 diff --git a/README.md b/README.md index 60a25cd4..79d1303a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ To start diving into the v8 iOS runtime make sure you have Xcode and [Homebrew]( # Install CMake brew install cmake +# Install jq (for scripting json replacements) +brew install jq + # (Optional) Install clang-format to format the code brew install clang-format diff --git a/TestFixtures/Api/TNSVersions.h b/TestFixtures/Api/TNSVersions.h index e00d1784..04c2ce2a 100644 --- a/TestFixtures/Api/TNSVersions.h +++ b/TestFixtures/Api/TNSVersions.h @@ -1,61 +1,59 @@ -#define generateVersionDeclarations(V1, V2) \ - __attribute__((availability(ios, introduced = V1))) \ - @interface TNSInterface \ - ##V2##Plus : NSObject \ - @end \ - \ - @interface TNSInterfaceMembers \ - ##V2 : NSObject \ - @property int property \ - __attribute__((availability(ios, introduced = V1))); \ - \ - +(void)staticMethod \ - __attribute__((availability(ios, introduced = V1))); \ - \ - -(void)instanceMethod \ - __attribute__((availability(ios, introduced = V1))); \ - @end \ - \ - __attribute__((availability(ios, introduced = V1))) void TNSFunction##V2##Plus(); \ - \ - __attribute__((availability(ios, introduced = V1))) extern const int TNSConstant##V2##Plus; \ - \ - enum TNSEnum##V2##Plus { \ - TNSEnum##V2##Member \ - } \ - __attribute__((availability(ios, introduced = V1))) +#define generateVersionDeclarations(V1, V2) \ + __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))) @interface TNSInterface \ + ##V2##Plus : NSObject @end \ + \ + @interface TNSInterfaceMembers \ + ##V2 : NSObject @property int property __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))); \ + \ + +(void)staticMethod __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))); \ + \ + -(void)instanceMethod __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))); \ + @end \ + \ + __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))) void TNSFunction##V2##Plus(); \ + \ + __attribute__((availability(ios, introduced = V1))) __attribute__( \ + (availability(visionos, introduced = V1))) extern const int TNSConstant##V2##Plus; \ + \ + enum TNSEnum##V2##Plus { TNSEnum##V2##Member } \ + __attribute__((availability(ios, introduced = V1))) \ + __attribute__((availability(visionos, introduced = V1))) #ifndef generateVersionImpl -#define generateVersion(V1, V2) \ - generateVersionDeclarations(V1, V2) +#define generateVersion(V1, V2) generateVersionDeclarations(V1, V2) #else -#define generateVersion(V1, V2) \ - generateVersionDeclarations(V1, V2); \ - \ - @implementation TNSInterface \ - ##V2##Plus \ - @end \ - \ - @implementation TNSInterfaceMembers \ - ##V2 \ - + (void)staticMethod{} \ - \ - - (void)instanceMethod {} \ - @end \ - \ - void TNSFunction##V2##Plus() {} \ - \ - const int TNSConstant##V2##Plus = 0 +#define generateVersion(V1, V2) \ + generateVersionDeclarations(V1, V2); \ + \ + @implementation TNSInterface \ + ##V2##Plus @end \ + \ + @implementation TNSInterfaceMembers \ + ##V2 + (void)staticMethod{} \ + \ + - (void)instanceMethod {} \ + @end \ + \ + void TNSFunction##V2##Plus() {} \ + \ + const int TNSConstant##V2##Plus = 0 #endif -#define generateMinors(MAJOR) \ - generateVersion(MAJOR##.0, MAJOR##_0); \ - generateVersion(MAJOR##.1, MAJOR##_1); \ - generateVersion(MAJOR##.2, MAJOR##_2); \ - generateVersion(MAJOR##.3, MAJOR##_3); \ - generateVersion(MAJOR##.4, MAJOR##_4); \ - generateVersion(MAJOR##.5, MAJOR##_5); +#define generateMinors(MAJOR) \ + generateVersion(MAJOR##.0, MAJOR##_0); \ + generateVersion(MAJOR##.1, MAJOR##_1); \ + generateVersion(MAJOR##.2, MAJOR##_2); \ + generateVersion(MAJOR##.3, MAJOR##_3); \ + generateVersion(MAJOR##.4, MAJOR##_4); \ + generateVersion(MAJOR##.5, MAJOR##_5); +generateMinors(1); +generateMinors(2); generateMinors(9); generateMinors(10); generateMinors(11); @@ -64,10 +62,12 @@ generateMinors(13); generateMinors(14); generateMinors(15); -// max availability version that can be currently represented in the binary metadata is 31.7 (major << 3 | minor) -> uint8_t +// max availability version that can be currently represented in the binary metadata is 31.7 (major +// << 3 | minor) -> uint8_t #define MAX_AVAILABILITY 31.7 __attribute__((availability(ios, introduced = MAX_AVAILABILITY))) +__attribute__((availability(visionos, introduced = MAX_AVAILABILITY))) @protocol TNSProtocolNeverAvailable @property(class, readonly) int staticPropertyFromProtocolNeverAvailable; @@ -85,6 +85,7 @@ __attribute__((availability(ios, introduced = MAX_AVAILABILITY))) @end __attribute__((availability(ios, introduced = 1.0))) +__attribute__((availability(visionos, introduced = 1.0))) @protocol TNSProtocolAlwaysAvailable @property(class, readonly) int staticPropertyFromProtocolAlwaysAvailable; @@ -97,10 +98,12 @@ __attribute__((availability(ios, introduced = 1.0))) @end -@interface TNSInterfaceAlwaysAvailable : NSObject +@interface TNSInterfaceAlwaysAvailable + : NSObject @end __attribute__((availability(ios, introduced = MAX_AVAILABILITY))) +__attribute__((availability(visionos, introduced = MAX_AVAILABILITY))) @interface TNSInterfaceNeverAvailable : TNSInterfaceAlwaysAvailable @end diff --git a/TestFixtures/exported-symbols.txt b/TestFixtures/exported-symbols.txt index fb47d646..c506cba1 100644 --- a/TestFixtures/exported-symbols.txt +++ b/TestFixtures/exported-symbols.txt @@ -58,6 +58,9 @@ _functionWithUShortPtr _TNSIsConfigurationDebug _TNSClearOutput _TNSConstant +_TNSConstant1_0Plus +_TNSConstant1_1Plus +_TNSConstant1_2Plus _TNSConstant10_0Plus _TNSConstant10_1Plus _TNSConstant10_2Plus @@ -94,12 +97,18 @@ _TNSConstant15_2Plus _TNSConstant15_3Plus _TNSConstant15_4Plus _TNSConstant15_5Plus +_TNSConstant1_0Plus +_TNSConstant1_1Plus +_TNSConstant1_2Plus _TNSConstant9_0Plus _TNSConstant9_1Plus _TNSConstant9_2Plus _TNSConstant9_3Plus _TNSConstant9_4Plus _TNSConstant9_5Plus +_TNSFunction1_0Plus +_TNSFunction1_1Plus +_TNSFunction1_2Plus _TNSFunction9_0Plus _TNSFunction9_1Plus _TNSFunction9_2Plus diff --git a/TestRunner/app/tests/Infrastructure/simulator.js b/TestRunner/app/tests/Infrastructure/simulator.js index 061877f8..bf3f297c 100644 --- a/TestRunner/app/tests/Infrastructure/simulator.js +++ b/TestRunner/app/tests/Infrastructure/simulator.js @@ -7,3 +7,9 @@ function isSimulator() { } global.isSimulator = isSimulator(); + +function isVision() { + return UIDevice.currentDevice.model.toLowerCase().includes('vision'); +} + +global.isVision = isVision(); diff --git a/TestRunner/app/tests/MetadataTests.js b/TestRunner/app/tests/MetadataTests.js index d49c937e..7d61eb12 100644 --- a/TestRunner/app/tests/MetadataTests.js +++ b/TestRunner/app/tests/MetadataTests.js @@ -10,7 +10,13 @@ describe("Metadata", function () { const swiftLikeObj = TNSSwiftLikeFactory.create(); expect(swiftLikeObj.constructor).toBe(global.TNSSwiftLike); expect(swiftLikeObj.constructor.name).toBe("_TtC17NativeScriptTests12TNSSwiftLike"); - var expectedName = NSProcessInfo.processInfo.isOperatingSystemAtLeastVersion({ majorVersion: 13, minorVersion: 4, patchVersion: 0 }) + let majorVersion = 13; + let minorVersion = 4; + if (isVision) { + majorVersion = 1; + minorVersion = 0; + } + var expectedName = NSProcessInfo.processInfo.isOperatingSystemAtLeastVersion({ majorVersion: majorVersion, minorVersion: minorVersion, patchVersion: 0 }) ? "_TtC17NativeScriptTests12TNSSwiftLike" : "NativeScriptTests.TNSSwiftLike"; expect(NSString.stringWithUTF8String(class_getName(swiftLikeObj.constructor)).toString()).toBe(expectedName); diff --git a/TestRunner/app/tests/VersionDiffTests.js b/TestRunner/app/tests/VersionDiffTests.js index 7ef9aec1..2bb0dd0d 100644 --- a/TestRunner/app/tests/VersionDiffTests.js +++ b/TestRunner/app/tests/VersionDiffTests.js @@ -17,8 +17,16 @@ describe(module.id, function() { } function forEachVersion(action) { - for (var major = 9; major <= 15; major++) { - for (var minor = 0; minor <= 5; minor++) { + let majorMinVersion = 9; + let majorMaxVersion = 15; + let minorMaxVersion = 5; + if (isVision) { + majorMinVersion = 1; + majorMaxVersion = 1; + minorMaxVersion = 2; + } + for (var major = majorMinVersion; major <= majorMaxVersion; major++) { + for (var minor = 0; minor <= minorMaxVersion; minor++) { action(major, minor); } } @@ -74,6 +82,10 @@ describe(module.id, function() { }); it("Base class which is unavailable should be skipped", function() { + if (isVision) { + pending(); + return; + } // Test case inspired from MTLArrayType(8.0) : MTLType(11.0) : NSObject // TNSInterfaceNeverAvailableDescendant : TNSInterfaceNeverAvailable(API31.7 - skipped) : TNSInterfaceAlwaysAvailable expect(Object.getPrototypeOf(TNSInterfaceNeverAvailableDescendant).toString()).toBe(TNSInterfaceAlwaysAvailable.toString(), "TNSInterfaceNeverAvailable base class should be skipped as it is unavailable"); diff --git a/v8ios.xcodeproj/project.pbxproj b/v8ios.xcodeproj/project.pbxproj index 3b15a19b..0e7ae090 100644 --- a/v8ios.xcodeproj/project.pbxproj +++ b/v8ios.xcodeproj/project.pbxproj @@ -7,9 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 2B5088A62BBEB92300F6EB68 /* metadata-arm64.bin in Resources */ = {isa = PBXBuildFile; fileRef = 2BFE21ED2AC1AC3100307752 /* metadata-arm64.bin */; }; 2B5088A72BBEC1BC00F6EB68 /* TNSWidgets.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C20525A72577D86600C12A5C /* TNSWidgets.xcframework */; }; - 2B5088A82BBEC1BC00F6EB68 /* TNSWidgets.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C20525A72577D86600C12A5C /* TNSWidgets.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 2B7EA6AF2353477000E5184E /* NativeScriptException.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2B7EA6AD2353476F00E5184E /* NativeScriptException.mm */; }; 2B7EA6B02353477000E5184E /* NativeScriptException.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B7EA6AE2353477000E5184E /* NativeScriptException.h */; }; 2BFE22062AC1C93100307752 /* metadata-arm64.bin in Resources */ = {isa = PBXBuildFile; fileRef = 2BFE22052AC1C93100307752 /* metadata-arm64.bin */; }; @@ -1843,7 +1841,6 @@ files = ( C27E5DB522F3206B00498ED0 /* app in Resources */, C27E5DBA22F324C200498ED0 /* Default-568h@2x.png in Resources */, - 2B5088A62BBEB92300F6EB68 /* metadata-arm64.bin in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2282,7 +2279,6 @@ }; C293752B229FC4740075CB16 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - platformFilter = ios; target = C29374E1229FC0F60075CB16 /* TestFixtures */; targetProxy = C293752A229FC4740075CB16 /* PBXContainerItemProxy */; }; @@ -2376,6 +2372,7 @@ C23992CE236C2D6E00D2F720 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = NO; CODE_SIGN_STYLE = Automatic; @@ -2391,6 +2388,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.TestRunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -2402,6 +2401,7 @@ C23992CF236C2D6E00D2F720 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = NO; CODE_SIGN_STYLE = Automatic; @@ -2417,6 +2417,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.TestRunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; @@ -2549,6 +2551,7 @@ C27E5D9F22F31CCC00498ED0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; CLANG_CXX_LIBRARY = "compiler-default"; @@ -2580,6 +2583,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.AppWithModules; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; @@ -2587,6 +2592,7 @@ C27E5DA022F31CCC00498ED0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "compiler-default"; CLANG_CXX_LIBRARY = "compiler-default"; @@ -2618,6 +2624,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.AppWithModules; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = 1; }; name = Release; @@ -2625,6 +2633,7 @@ C29374E9229FC0F60075CB16 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; CLANG_ENABLE_MODULES = NO; CLANG_WARN_STRICT_PROTOTYPES = NO; DEFINES_MODULE = YES; @@ -2633,7 +2642,10 @@ IPHONEOS_DEPLOYMENT_TARGET = 13.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; SYMROOT = build; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -2642,6 +2654,7 @@ C29374EA229FC0F60075CB16 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; CLANG_ENABLE_MODULES = NO; CLANG_WARN_STRICT_PROTOTYPES = NO; DEFINES_MODULE = YES; @@ -2651,7 +2664,10 @@ IPHONEOS_DEPLOYMENT_TARGET = 13.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "xrsimulator xros iphonesimulator iphoneos"; + SUPPORTS_MACCATALYST = YES; SYMROOT = build; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -2839,6 +2855,7 @@ __DATA, __TNSMetadata, "\"$(SRCROOT)/NativeScript/metadata-arm64.bin\"", + "-w", ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.NativeScript; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; @@ -2931,6 +2948,7 @@ __DATA, __TNSMetadata, "\"$(SRCROOT)/NativeScript/metadata-arm64.bin\"", + "-w", ); PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.NativeScript; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";