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({{.K: "3.0" , .V: "1.0" }, {.K: "3.1" , .V: "1.2" }}); |
20 | std::optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping = |
21 | DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, |
22 | MaximumDeploymentTarget: 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({{.K: "3.0" , .V: "1.0" }, {.K: "5.0" , .V: "1.2" }}); |
58 | std::optional<DarwinSDKInfo::RelatedTargetVersionMapping> Mapping = |
59 | DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, |
60 | MaximumDeploymentTarget: 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({{.K: "test" , .V: "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: &Obj); |
94 | ASSERT_TRUE(SDKInfo); |
95 | EXPECT_EQ(SDKInfo->getVersion(), VersionTuple(11, 0)); |
96 | |
97 | auto Mapping = SDKInfo->getVersionMapping( |
98 | Kind: 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: &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(Kind: 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 | // Verify introduced, deprecated, and obsoleted mappings. |
173 | EXPECT_EQ(Mapping->mapIntroducedAvailabilityVersion(VersionTuple(10, 1)), |
174 | VersionTuple(10.0)); |
175 | EXPECT_EQ(Mapping->mapDeprecatedObsoletedAvailabilityVersion( |
176 | VersionTuple(100000, 0)), |
177 | VersionTuple(100000)); |
178 | EXPECT_EQ( |
179 | Mapping->mapDeprecatedObsoletedAvailabilityVersion(VersionTuple(13.0)), |
180 | VersionTuple(15, 0, 99)); |
181 | } |
182 | |
183 | TEST(DarwinSDKInfoTest, MissingKeys) { |
184 | llvm::json::Object Obj; |
185 | ASSERT_FALSE(DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj)); |
186 | Obj["Version" ] = "11.0" ; |
187 | ASSERT_FALSE(DarwinSDKInfo::parseDarwinSDKSettingsJSON(&Obj)); |
188 | } |
189 | |