1 //===- unittests/Basic/DarwinSDKInfoTest.cpp -- SDKSettings.json test -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/Basic/DarwinSDKInfo.h" 10 #include "llvm/Support/JSON.h" 11 #include "gtest/gtest.h" 12 #include <optional> 13 14 using namespace llvm; 15 using namespace clang; 16 17 // Check the version mapping logic in DarwinSDKInfo. 18 TEST(DarwinSDKInfo, VersionMapping) { 19 llvm::json::Object Obj({{"3.0", "1.0"}, {"3.1", "1.2"}}); 20 Optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping = 21 DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, 22 VersionTuple()); 23 EXPECT_TRUE(Mapping); 24 EXPECT_EQ(Mapping->getMinimumValue(), VersionTuple(1)); 25 26 // Exact mapping. 27 EXPECT_EQ(Mapping->map(VersionTuple(3), VersionTuple(0, 1), std::nullopt), 28 VersionTuple(1)); 29 EXPECT_EQ(Mapping->map(VersionTuple(3, 0), VersionTuple(0, 1), std::nullopt), 30 VersionTuple(1)); 31 EXPECT_EQ( 32 Mapping->map(VersionTuple(3, 0, 0), VersionTuple(0, 1), std::nullopt), 33 VersionTuple(1)); 34 EXPECT_EQ(Mapping->map(VersionTuple(3, 1), VersionTuple(0, 1), std::nullopt), 35 VersionTuple(1, 2)); 36 EXPECT_EQ( 37 Mapping->map(VersionTuple(3, 1, 0), VersionTuple(0, 1), std::nullopt), 38 VersionTuple(1, 2)); 39 40 // Missing mapping - fallback to major. 41 EXPECT_EQ( 42 Mapping->map(VersionTuple(3, 0, 1), VersionTuple(0, 1), std::nullopt), 43 VersionTuple(1)); 44 45 // Minimum 46 EXPECT_EQ(Mapping->map(VersionTuple(2), VersionTuple(0, 1), std::nullopt), 47 VersionTuple(0, 1)); 48 49 // Maximum 50 EXPECT_EQ( 51 Mapping->map(VersionTuple(4), VersionTuple(0, 1), VersionTuple(100)), 52 VersionTuple(100)); 53 } 54 55 // Check the version mapping logic in DarwinSDKInfo. 56 TEST(DarwinSDKInfo, VersionMappingMissingKey) { 57 llvm::json::Object Obj({{"3.0", "1.0"}, {"5.0", "1.2"}}); 58 Optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping = 59 DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, 60 VersionTuple()); 61 EXPECT_TRUE(Mapping); 62 EXPECT_EQ( 63 Mapping->map(VersionTuple(4), VersionTuple(0, 1), VersionTuple(100)), 64 std::nullopt); 65 } 66 67 TEST(DarwinSDKInfo, VersionMappingParseEmpty) { 68 llvm::json::Object Obj({}); 69 EXPECT_FALSE( 70 DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, VersionTuple()) 71 .has_value()); 72 } 73 74 TEST(DarwinSDKInfo, VersionMappingParseError) { 75 llvm::json::Object Obj({{"test", "1.2"}}); 76 EXPECT_FALSE( 77 DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, VersionTuple()) 78 .has_value()); 79 } 80 81 TEST(DarwinSDKInfoTest, ParseAndTestMappingMacCatalyst) { 82 llvm::json::Object Obj; 83 Obj["Version"] = "11.0"; 84 Obj["MaximumDeploymentTarget"] = "11.99"; 85 llvm::json::Object VersionMap; 86 VersionMap["10.15"] = "13.1"; 87 VersionMap["11.0"] = "14.0"; 88 VersionMap["11.2"] = "14.2"; 89 llvm::json::Object MacOS2iOSMac; 90 MacOS2iOSMac["macOS_iOSMac"] = std::move(VersionMap); 91 Obj["VersionMap"] = std::move(MacOS2iOSMac); 92 93 auto SDKInfo = DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj); 94 ASSERT_TRUE(SDKInfo); 95 EXPECT_EQ(SDKInfo->getVersion(), VersionTuple(11, 0)); 96 97 auto Mapping = SDKInfo->getVersionMapping( 98 DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair()); 99 ASSERT_TRUE(Mapping); 100 // Verify that the macOS versions that are present in the map are translated 101 // directly to their corresponding Mac Catalyst versions. 102 EXPECT_EQ(*Mapping->map(VersionTuple(10, 15), VersionTuple(), std::nullopt), 103 VersionTuple(13, 1)); 104 EXPECT_EQ(*Mapping->map(VersionTuple(11, 0), VersionTuple(), std::nullopt), 105 VersionTuple(14, 0)); 106 EXPECT_EQ(*Mapping->map(VersionTuple(11, 2), VersionTuple(), std::nullopt), 107 VersionTuple(14, 2)); 108 109 // Verify that a macOS version that's not present in the map is translated 110 // like the nearest major OS version. 111 EXPECT_EQ(*Mapping->map(VersionTuple(11, 1), VersionTuple(), std::nullopt), 112 VersionTuple(14, 0)); 113 114 // Verify that the macOS versions that are outside of the mapped version 115 // range map to the min/max values passed to the `map` call. 116 EXPECT_EQ( 117 *Mapping->map(VersionTuple(10, 14), VersionTuple(99, 99), std::nullopt), 118 VersionTuple(99, 99)); 119 EXPECT_EQ( 120 *Mapping->map(VersionTuple(11, 5), VersionTuple(), VersionTuple(99, 99)), 121 VersionTuple(99, 99)); 122 EXPECT_EQ(*Mapping->map(VersionTuple(11, 5), VersionTuple(99, 98), 123 VersionTuple(99, 99)), 124 VersionTuple(99, 99)); 125 } 126 127 TEST(DarwinSDKInfoTest, ParseAndTestMappingIOSDerived) { 128 llvm::json::Object Obj; 129 Obj["Version"] = "15.0"; 130 Obj["MaximumDeploymentTarget"] = "15.0.99"; 131 llvm::json::Object VersionMap; 132 VersionMap["10.0"] = "10.0"; 133 VersionMap["10.3.1"] = "10.2"; 134 VersionMap["11.0"] = "11.0"; 135 llvm::json::Object IOSToTvOS; 136 IOSToTvOS["iOS_tvOS"] = std::move(VersionMap); 137 Obj["VersionMap"] = std::move(IOSToTvOS); 138 139 auto SDKInfo = DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj); 140 ASSERT_TRUE(SDKInfo); 141 EXPECT_EQ(SDKInfo->getVersion(), VersionTuple(15, 0)); 142 143 // Verify that mapping is present for platforms that derive from iOS. 144 const auto *Mapping = SDKInfo->getVersionMapping(DarwinSDKInfo::OSEnvPair( 145 llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, llvm::Triple::TvOS, 146 llvm::Triple::UnknownEnvironment)); 147 ASSERT_TRUE(Mapping); 148 149 // Verify that the iOS versions that are present in the map are translated 150 // directly to their corresponding tvOS versions. 151 EXPECT_EQ(*Mapping->map(VersionTuple(10, 0), VersionTuple(), std::nullopt), 152 VersionTuple(10, 0)); 153 EXPECT_EQ(*Mapping->map(VersionTuple(10, 3, 1), VersionTuple(), std::nullopt), 154 VersionTuple(10, 2)); 155 EXPECT_EQ(*Mapping->map(VersionTuple(11, 0), VersionTuple(), std::nullopt), 156 VersionTuple(11, 0)); 157 158 // Verify that an iOS version that's not present in the map is translated 159 // like the nearest major OS version. 160 EXPECT_EQ(*Mapping->map(VersionTuple(10, 1), VersionTuple(), std::nullopt), 161 VersionTuple(10, 0)); 162 163 // Verify that the iOS versions that are outside of the mapped version 164 // range map to the min/max values passed to the `map` call. 165 EXPECT_EQ( 166 *Mapping->map(VersionTuple(9, 0), VersionTuple(99, 99), std::nullopt), 167 VersionTuple(99, 99)); 168 EXPECT_EQ( 169 *Mapping->map(VersionTuple(13, 0), VersionTuple(), VersionTuple(99, 99)), 170 VersionTuple(99, 99)); 171 } 172 173 TEST(DarwinSDKInfoTest, MissingKeys) { 174 llvm::json::Object Obj; 175 ASSERT_FALSE(DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj)); 176 Obj["Version"] = "11.0"; 177 ASSERT_FALSE(DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj)); 178 } 179