xref: /llvm-project/clang/unittests/Basic/DarwinSDKInfoTest.cpp (revision 9cf9cb271bf86bda4996be9a31fa413381f2f5e3)
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.
TEST(DarwinSDKInfo,VersionMapping)18 TEST(DarwinSDKInfo, VersionMapping) {
19   llvm::json::Object Obj({{"3.0", "1.0"}, {"3.1", "1.2"}});
20   std::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.
TEST(DarwinSDKInfo,VersionMappingMissingKey)56 TEST(DarwinSDKInfo, VersionMappingMissingKey) {
57   llvm::json::Object Obj({{"3.0", "1.0"}, {"5.0", "1.2"}});
58   std::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 
TEST(DarwinSDKInfo,VersionMappingParseEmpty)67 TEST(DarwinSDKInfo, VersionMappingParseEmpty) {
68   llvm::json::Object Obj({});
69   EXPECT_FALSE(
70       DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(Obj, VersionTuple())
71           .has_value());
72 }
73 
TEST(DarwinSDKInfo,VersionMappingParseError)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 
TEST(DarwinSDKInfoTest,ParseAndTestMappingMacCatalyst)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 
TEST(DarwinSDKInfoTest,ParseAndTestMappingIOSDerived)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   // 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 
TEST(DarwinSDKInfoTest,MissingKeys)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