1 | //===-- TextStubV4Tests.cpp - TBD V4 File 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 "TextStubHelpers.h" |
10 | #include "llvm/TextAPI/InterfaceFile.h" |
11 | #include "llvm/TextAPI/TextAPIReader.h" |
12 | #include "llvm/TextAPI/TextAPIWriter.h" |
13 | #include "gtest/gtest.h" |
14 | #include <string> |
15 | #include <vector> |
16 | |
17 | using namespace llvm; |
18 | using namespace llvm::MachO; |
19 | |
20 | |
21 | namespace TBDv4 { |
22 | |
23 | TEST(TBDv4, ReadFile) { |
24 | static const char TBDv4File[] = |
25 | "--- !tapi-tbd\n" |
26 | "tbd-version: 4\n" |
27 | "targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" |
28 | "uuids:\n" |
29 | " - target: i386-macos\n" |
30 | " value: 00000000-0000-0000-0000-000000000000\n" |
31 | " - target: x86_64-macos\n" |
32 | " value: 11111111-1111-1111-1111-111111111111\n" |
33 | " - target: x86_64-ios\n" |
34 | " value: 11111111-1111-1111-1111-111111111111\n" |
35 | "flags: [ flat_namespace, installapi ]\n" |
36 | "install-name: Umbrella.framework/Umbrella\n" |
37 | "current-version: 1.2.3\n" |
38 | "compatibility-version: 1.2\n" |
39 | "swift-abi-version: 5\n" |
40 | "parent-umbrella:\n" |
41 | " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" |
42 | " umbrella: System\n" |
43 | "allowable-clients:\n" |
44 | " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" |
45 | " clients: [ ClientA ]\n" |
46 | "reexported-libraries:\n" |
47 | " - targets: [ i386-macos ]\n" |
48 | " libraries: [ /System/Library/Frameworks/A.framework/A ]\n" |
49 | "exports:\n" |
50 | " - targets: [ i386-macos ]\n" |
51 | " symbols: [ _symA ]\n" |
52 | " objc-classes: []\n" |
53 | " objc-eh-types: []\n" |
54 | " objc-ivars: []\n" |
55 | " weak-symbols: []\n" |
56 | " thread-local-symbols: []\n" |
57 | " - targets: [ x86_64-ios ]\n" |
58 | " symbols: [_symB]\n" |
59 | " - targets: [ x86_64-macos, x86_64-ios ]\n" |
60 | " symbols: [_symAB]\n" |
61 | "reexports:\n" |
62 | " - targets: [ i386-macos ]\n" |
63 | " symbols: [_symC]\n" |
64 | " objc-classes: []\n" |
65 | " objc-eh-types: []\n" |
66 | " objc-ivars: []\n" |
67 | " weak-symbols: [weakReexport]\n" |
68 | " thread-local-symbols: []\n" |
69 | "undefineds:\n" |
70 | " - targets: [ i386-macos ]\n" |
71 | " symbols: [ _symD ]\n" |
72 | " objc-classes: []\n" |
73 | " objc-eh-types: []\n" |
74 | " objc-ivars: []\n" |
75 | " weak-symbols: [weakReference]\n" |
76 | " thread-local-symbols: []\n" |
77 | "...\n" ; |
78 | |
79 | Expected<TBDFile> Result = |
80 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "Test.tbd" )); |
81 | EXPECT_TRUE(!!Result); |
82 | TBDFile File = std::move(Result.get()); |
83 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
84 | PlatformSet Platforms; |
85 | Platforms.insert(V: getPlatformFromName(Name: "macos" )); |
86 | Platforms.insert(V: getPlatformFromName(Name: "ios" )); |
87 | auto Archs = AK_i386 | AK_x86_64; |
88 | TargetList Targets = { |
89 | Target(AK_i386, PLATFORM_MACOS), |
90 | Target(AK_x86_64, PLATFORM_MACOS), |
91 | Target(AK_x86_64, PLATFORM_IOS), |
92 | }; |
93 | EXPECT_EQ(Archs, File->getArchitectures()); |
94 | EXPECT_EQ(Platforms.size(), File->getPlatforms().size()); |
95 | for (auto Platform : File->getPlatforms()) |
96 | EXPECT_EQ(Platforms.count(Platform), 1U); |
97 | EXPECT_EQ(std::string("Umbrella.framework/Umbrella" ), File->getInstallName()); |
98 | EXPECT_EQ(PackedVersion(1, 2, 3), File->getCurrentVersion()); |
99 | EXPECT_EQ(PackedVersion(1, 2, 0), File->getCompatibilityVersion()); |
100 | EXPECT_EQ(5U, File->getSwiftABIVersion()); |
101 | EXPECT_FALSE(File->isTwoLevelNamespace()); |
102 | EXPECT_TRUE(File->isApplicationExtensionSafe()); |
103 | EXPECT_FALSE(File->isOSLibNotForSharedCache()); |
104 | InterfaceFileRef client("ClientA" , Targets); |
105 | InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A" , |
106 | {Targets[0]}); |
107 | EXPECT_EQ(1U, File->allowableClients().size()); |
108 | EXPECT_EQ(client, File->allowableClients().front()); |
109 | EXPECT_EQ(1U, File->reexportedLibraries().size()); |
110 | EXPECT_EQ(reexport, File->reexportedLibraries().front()); |
111 | |
112 | ExportedSymbolSeq Exports, Reexports, Undefineds; |
113 | for (const auto *Sym : File->symbols()) { |
114 | ExportedSymbol Temp = |
115 | ExportedSymbol{.Kind: Sym->getKind(), .Name: std::string(Sym->getName()), |
116 | .Weak: Sym->isWeakDefined() || Sym->isWeakReferenced(), |
117 | .ThreadLocalValue: Sym->isThreadLocalValue()}; |
118 | if (Sym->isUndefined()) { |
119 | EXPECT_FALSE(Sym->isWeakDefined()); |
120 | Undefineds.emplace_back(args: std::move(Temp)); |
121 | } |
122 | // Check that defined symbols cannot be set as weak referenced. |
123 | else if (Sym->isReexported()) { |
124 | EXPECT_FALSE(Sym->isWeakReferenced()); |
125 | Reexports.emplace_back(args: std::move(Temp)); |
126 | } else { |
127 | EXPECT_FALSE(Sym->isWeakReferenced()); |
128 | Exports.emplace_back(args: std::move(Temp)); |
129 | } |
130 | } |
131 | llvm::sort(C&: Exports); |
132 | llvm::sort(C&: Reexports); |
133 | llvm::sort(C&: Undefineds); |
134 | |
135 | static ExportedSymbol ExpectedExportedSymbols[] = { |
136 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symA" , .Weak: false, .ThreadLocalValue: false}, |
137 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symAB" , .Weak: false, .ThreadLocalValue: false}, |
138 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symB" , .Weak: false, .ThreadLocalValue: false}, |
139 | }; |
140 | |
141 | static ExportedSymbol ExpectedReexportedSymbols[] = { |
142 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symC" , .Weak: false, .ThreadLocalValue: false}, |
143 | {.Kind: EncodeKind::GlobalSymbol, .Name: "weakReexport" , .Weak: true, .ThreadLocalValue: false}, |
144 | }; |
145 | |
146 | static ExportedSymbol ExpectedUndefinedSymbols[] = { |
147 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symD" , .Weak: false, .ThreadLocalValue: false}, |
148 | {.Kind: EncodeKind::GlobalSymbol, .Name: "weakReference" , .Weak: true, .ThreadLocalValue: false}, |
149 | }; |
150 | |
151 | EXPECT_EQ(std::size(ExpectedExportedSymbols), Exports.size()); |
152 | EXPECT_EQ(std::size(ExpectedReexportedSymbols), Reexports.size()); |
153 | EXPECT_EQ(std::size(ExpectedUndefinedSymbols), Undefineds.size()); |
154 | EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(), |
155 | std::begin(ExpectedExportedSymbols))); |
156 | EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(), |
157 | std::begin(ExpectedReexportedSymbols))); |
158 | EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(), |
159 | std::begin(ExpectedUndefinedSymbols))); |
160 | } |
161 | |
162 | TEST(TBDv4, ReadMultipleDocuments) { |
163 | static const char TBDv4Inlines[] = |
164 | "--- !tapi-tbd\n" |
165 | "tbd-version: 4\n" |
166 | "targets: [ i386-macos, i386-maccatalyst, x86_64-macos, " |
167 | "x86_64-maccatalyst ]\n" |
168 | "install-name: /System/Library/Frameworks/Umbrella.framework/Umbrella\n" |
169 | "parent-umbrella:\n" |
170 | " - targets: [ i386-macos, x86_64-macos ]\n" |
171 | " umbrella: System\n" |
172 | "reexported-libraries:\n" |
173 | " - targets: [ i386-macos, x86_64-macos ]\n" |
174 | " libraries: [ /System/Library/Frameworks/A.framework/A ]\n" |
175 | "--- !tapi-tbd\n" |
176 | "tbd-version: 4\n" |
177 | "targets: [ i386-macos, x86_64-macos ]\n" |
178 | "uuids:\n" |
179 | " - target: i386-macos\n" |
180 | " value: 20000000-0000-0000-0000-000000000000\n" |
181 | " - target: x86_64-macos\n" |
182 | " value: 21111111-1111-1111-1111-111111111111\n" |
183 | "flags: [ flat_namespace ]\n" |
184 | "install-name: /System/Library/Frameworks/A.framework/A\n" |
185 | "current-version: 1.2.3\n" |
186 | "compatibility-version: 1.2\n" |
187 | "swift-abi-version: 5\n" |
188 | "exports:\n" |
189 | " - targets: [ i386-macos ]\n" |
190 | " symbols: [ _symA ]\n" |
191 | " objc-classes: []\n" |
192 | " objc-eh-types: []\n" |
193 | " objc-ivars: []\n" |
194 | " weak-symbols: []\n" |
195 | " thread-local-symbols: []\n" |
196 | " - targets: [ x86_64-macos ]\n" |
197 | " symbols: [_symAB]\n" |
198 | "reexports:\n" |
199 | " - targets: [ i386-macos ]\n" |
200 | " symbols: [_symC]\n" |
201 | " objc-classes: []\n" |
202 | " objc-eh-types: []\n" |
203 | " objc-ivars: []\n" |
204 | " weak-symbols: []\n" |
205 | " thread-local-symbols: []\n" |
206 | "undefineds:\n" |
207 | " - targets: [ i386-macos ]\n" |
208 | " symbols: [ _symD ]\n" |
209 | " objc-classes: []\n" |
210 | " objc-eh-types: []\n" |
211 | " objc-ivars: []\n" |
212 | " weak-symbols: []\n" |
213 | " thread-local-symbols: []\n" |
214 | "...\n" ; |
215 | |
216 | PlatformSet Platforms; |
217 | Platforms.insert(V: PLATFORM_MACOS); |
218 | Platforms.insert(V: PLATFORM_MACCATALYST); |
219 | ArchitectureSet Archs = AK_i386 | AK_x86_64; |
220 | TargetList Targets; |
221 | for (auto &&Arch : Archs) |
222 | for (auto &&Platform : Platforms) |
223 | Targets.emplace_back(Args: Target(Arch, Platform)); |
224 | TargetToAttr Uuids = { |
225 | {Targets[0], "00000000-0000-0000-0000-000000000000" }, |
226 | {Targets[1], "00000000-0000-0000-0000-000000000002" }, |
227 | {Targets[2], "11111111-1111-1111-1111-111111111111" }, |
228 | {Targets[3], "11111111-1111-1111-1111-111111111112" }, |
229 | }; |
230 | |
231 | Expected<TBDFile> Result = |
232 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4Inlines, "Test.tbd" )); |
233 | EXPECT_TRUE(!!Result); |
234 | TBDFile File = std::move(Result.get()); |
235 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
236 | EXPECT_EQ(Archs, File->getArchitectures()); |
237 | EXPECT_EQ(Platforms, File->getPlatforms()); |
238 | EXPECT_EQ( |
239 | std::string("/System/Library/Frameworks/Umbrella.framework/Umbrella" ), |
240 | File->getInstallName()); |
241 | EXPECT_TRUE(File->isTwoLevelNamespace()); |
242 | EXPECT_TRUE(File->isApplicationExtensionSafe()); |
243 | EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion()); |
244 | EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion()); |
245 | InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A" , |
246 | {Targets[0], Targets[2]}); |
247 | EXPECT_EQ(1U, File->reexportedLibraries().size()); |
248 | EXPECT_EQ(reexport, File->reexportedLibraries().front()); |
249 | EXPECT_TRUE(File->symbols().empty()); |
250 | |
251 | // Check Inlined Document |
252 | Targets.clear(); |
253 | Uuids.clear(); |
254 | PlatformType Platform = PLATFORM_MACOS; |
255 | for (auto &&Arch : Archs) |
256 | Targets.emplace_back(Args: Target(Arch, Platform)); |
257 | Uuids = { |
258 | {Targets[0], "20000000-0000-0000-0000-000000000000" }, |
259 | {Targets[1], "21111111-1111-1111-1111-111111111111" }, |
260 | }; |
261 | |
262 | TBDReexportFile Document = File->documents().front(); |
263 | EXPECT_EQ(FileType::TBD_V4, Document->getFileType()); |
264 | EXPECT_EQ(Archs, Document->getArchitectures()); |
265 | EXPECT_EQ(1U, Document->getPlatforms().size()); |
266 | EXPECT_EQ(Platform, *(Document->getPlatforms().begin())); |
267 | EXPECT_EQ(std::string("/System/Library/Frameworks/A.framework/A" ), |
268 | Document->getInstallName()); |
269 | EXPECT_EQ(PackedVersion(1, 2, 3), Document->getCurrentVersion()); |
270 | EXPECT_EQ(PackedVersion(1, 2, 0), Document->getCompatibilityVersion()); |
271 | EXPECT_EQ(5U, Document->getSwiftABIVersion()); |
272 | EXPECT_FALSE(Document->isTwoLevelNamespace()); |
273 | EXPECT_TRUE(Document->isApplicationExtensionSafe()); |
274 | |
275 | ExportedSymbolSeq Exports; |
276 | ExportedSymbolSeq Reexports, Undefineds; |
277 | for (const auto *Sym : Document->symbols()) { |
278 | ExportedSymbol Temp = |
279 | ExportedSymbol{.Kind: Sym->getKind(), .Name: std::string(Sym->getName()), |
280 | .Weak: Sym->isWeakDefined(), .ThreadLocalValue: Sym->isThreadLocalValue()}; |
281 | EXPECT_FALSE(Sym->isWeakReferenced()); |
282 | if (Sym->isUndefined()) |
283 | Undefineds.emplace_back(args: std::move(Temp)); |
284 | else |
285 | Sym->isReexported() ? Reexports.emplace_back(args: std::move(Temp)) |
286 | : Exports.emplace_back(args: std::move(Temp)); |
287 | } |
288 | llvm::sort(C&: Exports); |
289 | llvm::sort(C&: Reexports); |
290 | llvm::sort(C&: Undefineds); |
291 | |
292 | static ExportedSymbol ExpectedExportedSymbols[] = { |
293 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symA" , .Weak: false, .ThreadLocalValue: false}, |
294 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symAB" , .Weak: false, .ThreadLocalValue: false}, |
295 | }; |
296 | |
297 | static ExportedSymbol ExpectedReexportedSymbols[] = { |
298 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symC" , .Weak: false, .ThreadLocalValue: false}, |
299 | }; |
300 | |
301 | static ExportedSymbol ExpectedUndefinedSymbols[] = { |
302 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_symD" , .Weak: false, .ThreadLocalValue: false}, |
303 | }; |
304 | |
305 | EXPECT_EQ(std::size(ExpectedExportedSymbols), Exports.size()); |
306 | EXPECT_EQ(std::size(ExpectedReexportedSymbols), Reexports.size()); |
307 | EXPECT_EQ(std::size(ExpectedUndefinedSymbols), Undefineds.size()); |
308 | EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(), |
309 | std::begin(ExpectedExportedSymbols))); |
310 | EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(), |
311 | std::begin(ExpectedReexportedSymbols))); |
312 | EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(), |
313 | std::begin(ExpectedUndefinedSymbols))); |
314 | } |
315 | |
316 | TEST(TBDv4, WriteFile) { |
317 | static const char TBDv4File[] = |
318 | "--- !tapi-tbd\n" |
319 | "tbd-version: 4\n" |
320 | "targets: [ i386-macos, x86_64-ios-simulator ]\n" |
321 | "install-name: 'Umbrella.framework/Umbrella'\n" |
322 | "current-version: 1.2.3\n" |
323 | "compatibility-version: 0\n" |
324 | "swift-abi-version: 5\n" |
325 | "parent-umbrella:\n" |
326 | " - targets: [ i386-macos, x86_64-ios-simulator ]\n" |
327 | " umbrella: System\n" |
328 | "allowable-clients:\n" |
329 | " - targets: [ i386-macos ]\n" |
330 | " clients: [ ClientA ]\n" |
331 | "exports:\n" |
332 | " - targets: [ i386-macos ]\n" |
333 | " symbols: [ _symA ]\n" |
334 | " objc-classes: [ Class1 ]\n" |
335 | " weak-symbols: [ _symC ]\n" |
336 | " - targets: [ x86_64-ios-simulator ]\n" |
337 | " symbols: [ _symB ]\n" |
338 | "...\n" ; |
339 | |
340 | InterfaceFile File; |
341 | TargetList Targets = { |
342 | Target(AK_i386, PLATFORM_MACOS), |
343 | Target(AK_x86_64, PLATFORM_IOSSIMULATOR), |
344 | }; |
345 | File.setInstallName("Umbrella.framework/Umbrella" ); |
346 | File.setFileType(FileType::TBD_V4); |
347 | File.addTargets(Targets); |
348 | File.setCurrentVersion(PackedVersion(1, 2, 3)); |
349 | File.setTwoLevelNamespace(); |
350 | File.setApplicationExtensionSafe(true); |
351 | File.setSwiftABIVersion(5); |
352 | File.addAllowableClient(InstallName: "ClientA" , Target: Targets[0]); |
353 | File.addParentUmbrella(Target_: Targets[0], Parent: "System" ); |
354 | File.addParentUmbrella(Target_: Targets[1], Parent: "System" ); |
355 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symA" , Target&: {Targets[0]}); |
356 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symB" , Target&: {Targets[1]}); |
357 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symC" , Target&: {Targets[0]}, |
358 | Flags: SymbolFlags::WeakDefined); |
359 | File.addSymbol(Kind: EncodeKind::ObjectiveCClass, Name: "Class1" , Target&: {Targets[0]}); |
360 | |
361 | SmallString<4096> Buffer; |
362 | raw_svector_ostream OS(Buffer); |
363 | Error Result = TextAPIWriter::writeToStream(OS, File); |
364 | EXPECT_FALSE(Result); |
365 | EXPECT_STREQ(TBDv4File, Buffer.c_str()); |
366 | } |
367 | |
368 | TEST(TBDv4, WriteMultipleDocuments) { |
369 | static const char TBDv4Inlines[] = |
370 | "--- !tapi-tbd\n" |
371 | "tbd-version: 4\n" |
372 | "targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n" |
373 | "install-name: " |
374 | "'/System/Library/Frameworks/Umbrella.framework/Umbrella'\n" |
375 | "reexported-libraries:\n" |
376 | " - targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n" |
377 | " libraries: [ '/System/Library/Frameworks/A.framework/A' ]\n" |
378 | "--- !tapi-tbd\n" |
379 | "tbd-version: 4\n" |
380 | "targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n" |
381 | "install-name: '/System/Library/Frameworks/A.framework/A'\n" |
382 | "exports:\n" |
383 | " - targets: [ i386-maccatalyst ]\n" |
384 | " weak-symbols: [ _symC ]\n" |
385 | " - targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n" |
386 | " symbols: [ _symA ]\n" |
387 | " objc-classes: [ Class1 ]\n" |
388 | " - targets: [ x86_64-maccatalyst ]\n" |
389 | " symbols: [ _symAB ]\n" |
390 | "...\n" ; |
391 | |
392 | InterfaceFile File; |
393 | PlatformType Platform = PLATFORM_MACCATALYST; |
394 | TargetList Targets = { |
395 | Target(AK_i386, Platform), |
396 | Target(AK_x86_64, Platform), |
397 | }; |
398 | TargetToAttr Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000002" }, |
399 | {Targets[1], "11111111-1111-1111-1111-111111111112" }}; |
400 | File.setInstallName("/System/Library/Frameworks/Umbrella.framework/Umbrella" ); |
401 | File.setFileType(FileType::TBD_V4); |
402 | File.addTargets(Targets); |
403 | File.setCompatibilityVersion(PackedVersion(1, 0, 0)); |
404 | File.setCurrentVersion(PackedVersion(1, 0, 0)); |
405 | File.setTwoLevelNamespace(); |
406 | File.setApplicationExtensionSafe(true); |
407 | File.addReexportedLibrary(InstallName: "/System/Library/Frameworks/A.framework/A" , |
408 | Target: Targets[0]); |
409 | File.addReexportedLibrary(InstallName: "/System/Library/Frameworks/A.framework/A" , |
410 | Target: Targets[1]); |
411 | |
412 | // Write Second Document |
413 | Uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000" }, |
414 | {Targets[1], "11111111-1111-1111-1111-111111111111" }}; |
415 | InterfaceFile Document; |
416 | Document.setInstallName("/System/Library/Frameworks/A.framework/A" ); |
417 | Document.setFileType(FileType::TBD_V4); |
418 | Document.addTargets(Targets); |
419 | Document.setCompatibilityVersion(PackedVersion(1, 0, 0)); |
420 | Document.setCurrentVersion(PackedVersion(1, 0, 0)); |
421 | Document.setTwoLevelNamespace(); |
422 | Document.setApplicationExtensionSafe(true); |
423 | Document.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symA" , Targets); |
424 | Document.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symAB" , Target&: {Targets[1]}); |
425 | Document.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symC" , Target&: {Targets[0]}, |
426 | Flags: SymbolFlags::WeakDefined); |
427 | Document.addSymbol(Kind: EncodeKind::ObjectiveCClass, Name: "Class1" , Targets); |
428 | File.addDocument(Document: std::make_shared<InterfaceFile>(args: std::move(Document))); |
429 | |
430 | SmallString<4096> Buffer; |
431 | raw_svector_ostream OS(Buffer); |
432 | Error Result = TextAPIWriter::writeToStream(OS, File); |
433 | EXPECT_FALSE(Result); |
434 | EXPECT_STREQ(TBDv4Inlines, Buffer.c_str()); |
435 | } |
436 | |
437 | TEST(TBDv4, MultipleTargets) { |
438 | static const char TBDv4MultipleTargets[] = |
439 | "--- !tapi-tbd\n" |
440 | "tbd-version: 4\n" |
441 | "targets: [ i386-maccatalyst, x86_64-tvos, arm64-ios ]\n" |
442 | "install-name: Test.dylib\n" |
443 | "...\n" ; |
444 | |
445 | Expected<TBDFile> Result = |
446 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4MultipleTargets, "Test.tbd" )); |
447 | EXPECT_TRUE(!!Result); |
448 | PlatformSet Platforms; |
449 | Platforms.insert(V: PLATFORM_MACCATALYST); |
450 | Platforms.insert(V: PLATFORM_TVOS); |
451 | Platforms.insert(V: PLATFORM_IOS); |
452 | TBDFile File = std::move(Result.get()); |
453 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
454 | EXPECT_EQ(AK_x86_64 | AK_arm64 | AK_i386, File->getArchitectures()); |
455 | EXPECT_EQ(Platforms.size(), File->getPlatforms().size()); |
456 | for (auto Platform : File->getPlatforms()) |
457 | EXPECT_EQ(Platforms.count(Platform), 1U); |
458 | |
459 | SmallString<4096> Buffer; |
460 | raw_svector_ostream OS(Buffer); |
461 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
462 | EXPECT_TRUE(!WriteResult); |
463 | EXPECT_EQ(stripWhitespace(TBDv4MultipleTargets), |
464 | stripWhitespace(Buffer.c_str())); |
465 | } |
466 | |
467 | TEST(TBDv4, MultipleTargetsSameArch) { |
468 | static const char TBDv4TargetsSameArch[] = |
469 | "--- !tapi-tbd\n" |
470 | "tbd-version: 4\n" |
471 | "targets: [ x86_64-tvos , x86_64-maccatalyst ]\n" |
472 | "install-name: Test.dylib\n" |
473 | "...\n" ; |
474 | |
475 | Expected<TBDFile> Result = |
476 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4TargetsSameArch, "Test.tbd" )); |
477 | EXPECT_TRUE(!!Result); |
478 | PlatformSet Platforms; |
479 | Platforms.insert(V: PLATFORM_TVOS); |
480 | Platforms.insert(V: PLATFORM_MACCATALYST); |
481 | TBDFile File = std::move(Result.get()); |
482 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
483 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
484 | EXPECT_EQ(Platforms.size(), File->getPlatforms().size()); |
485 | for (auto Platform : File->getPlatforms()) |
486 | EXPECT_EQ(Platforms.count(Platform), 1U); |
487 | |
488 | SmallString<4096> Buffer; |
489 | raw_svector_ostream OS(Buffer); |
490 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
491 | EXPECT_TRUE(!WriteResult); |
492 | EXPECT_EQ(stripWhitespace(TBDv4TargetsSameArch), |
493 | stripWhitespace(Buffer.c_str())); |
494 | } |
495 | |
496 | TEST(TBDv4, MultipleTargetsSamePlatform) { |
497 | static const char TBDv4MultipleTargetsSamePlatform[] = |
498 | "--- !tapi-tbd\n" |
499 | "tbd-version: 4\n" |
500 | "targets: [ armv7k-ios , arm64-ios]\n" |
501 | "install-name: Test.dylib\n" |
502 | "...\n" ; |
503 | |
504 | Expected<TBDFile> Result = TextAPIReader::get( |
505 | InputBuffer: MemoryBufferRef(TBDv4MultipleTargetsSamePlatform, "Test.tbd" )); |
506 | EXPECT_TRUE(!!Result); |
507 | TBDFile File = std::move(Result.get()); |
508 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
509 | EXPECT_EQ(AK_arm64 | AK_armv7k, File->getArchitectures()); |
510 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
511 | EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin()); |
512 | |
513 | SmallString<4096> Buffer; |
514 | raw_svector_ostream OS(Buffer); |
515 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
516 | EXPECT_TRUE(!WriteResult); |
517 | EXPECT_EQ(stripWhitespace(TBDv4MultipleTargetsSamePlatform), |
518 | stripWhitespace(Buffer.c_str())); |
519 | } |
520 | |
521 | TEST(TBDv4, Target_maccatalyst) { |
522 | static const char TBDv4TargetMacCatalyst[] = |
523 | "--- !tapi-tbd\n" |
524 | "tbd-version: 4\n" |
525 | "targets: [ x86_64-maccatalyst ]\n" |
526 | "install-name: Test.dylib\n" |
527 | "...\n" ; |
528 | |
529 | Expected<TBDFile> Result = |
530 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4TargetMacCatalyst, "Test.tbd" )); |
531 | EXPECT_TRUE(!!Result); |
532 | TBDFile File = std::move(Result.get()); |
533 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
534 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
535 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
536 | EXPECT_EQ(PLATFORM_MACCATALYST, *File->getPlatforms().begin()); |
537 | |
538 | SmallString<4096> Buffer; |
539 | raw_svector_ostream OS(Buffer); |
540 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
541 | EXPECT_TRUE(!WriteResult); |
542 | EXPECT_EQ(stripWhitespace(TBDv4TargetMacCatalyst), |
543 | stripWhitespace(Buffer.c_str())); |
544 | } |
545 | |
546 | TEST(TBDv4, Target_maccatalyst2) { |
547 | static const char TBDv4TargetMacCatalyst[] = |
548 | "--- !tapi-tbd\n" |
549 | "tbd-version: 4\n" |
550 | "targets: [ x86_64-maccatalyst ]\n" |
551 | "install-name: Test.dylib\n" |
552 | "...\n" ; |
553 | |
554 | Expected<TBDFile> Result = |
555 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4TargetMacCatalyst, "Test.tbd" )); |
556 | EXPECT_TRUE(!!Result); |
557 | TBDFile File = std::move(Result.get()); |
558 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
559 | EXPECT_EQ(getPlatformFromName("ios-macabi" ), *File->getPlatforms().begin()); |
560 | } |
561 | |
562 | TEST(TBDv4, Target_x86_ios) { |
563 | static const char TBDv4Targetx86iOS[] = "--- !tapi-tbd\n" |
564 | "tbd-version: 4\n" |
565 | "targets: [ x86_64-ios ]\n" |
566 | "install-name: Test.dylib\n" |
567 | "...\n" ; |
568 | |
569 | Expected<TBDFile> Result = |
570 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4Targetx86iOS, "Test.tbd" )); |
571 | EXPECT_TRUE(!!Result); |
572 | TBDFile File = std::move(Result.get()); |
573 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
574 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
575 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
576 | EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin()); |
577 | |
578 | SmallString<4096> Buffer; |
579 | raw_svector_ostream OS(Buffer); |
580 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
581 | EXPECT_TRUE(!WriteResult); |
582 | EXPECT_EQ(stripWhitespace(TBDv4Targetx86iOS), |
583 | stripWhitespace(Buffer.c_str())); |
584 | } |
585 | |
586 | TEST(TBDv4, Target_arm_bridgeOS) { |
587 | static const char TBDv4PlatformBridgeOS[] = "--- !tapi-tbd\n" |
588 | "tbd-version: 4\n" |
589 | "targets: [ armv7k-bridgeos ]\n" |
590 | "install-name: Test.dylib\n" |
591 | "...\n" ; |
592 | |
593 | Expected<TBDFile> Result = |
594 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4PlatformBridgeOS, "Test.tbd" )); |
595 | EXPECT_TRUE(!!Result); |
596 | TBDFile File = std::move(Result.get()); |
597 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
598 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
599 | EXPECT_EQ(PLATFORM_BRIDGEOS, *File->getPlatforms().begin()); |
600 | EXPECT_EQ(ArchitectureSet(AK_armv7k), File->getArchitectures()); |
601 | |
602 | SmallString<4096> Buffer; |
603 | raw_svector_ostream OS(Buffer); |
604 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
605 | EXPECT_TRUE(!WriteResult); |
606 | EXPECT_EQ(stripWhitespace(TBDv4PlatformBridgeOS), |
607 | stripWhitespace(Buffer.c_str())); |
608 | } |
609 | |
610 | TEST(TBDv4, Target_arm_iOS) { |
611 | static const char TBDv4ArchArm64e[] = "--- !tapi-tbd\n" |
612 | "tbd-version: 4\n" |
613 | "targets: [ arm64e-ios ]\n" |
614 | "install-name: Test.dylib\n" |
615 | "...\n" ; |
616 | |
617 | Expected<TBDFile> Result = |
618 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4ArchArm64e, "Test.tbd" )); |
619 | EXPECT_TRUE(!!Result); |
620 | TBDFile File = std::move(Result.get()); |
621 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
622 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
623 | EXPECT_EQ(PLATFORM_IOS, *File->getPlatforms().begin()); |
624 | EXPECT_EQ(ArchitectureSet(AK_arm64e), File->getArchitectures()); |
625 | |
626 | SmallString<4096> Buffer; |
627 | raw_svector_ostream OS(Buffer); |
628 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
629 | EXPECT_TRUE(!WriteResult); |
630 | EXPECT_EQ(stripWhitespace(TBDv4ArchArm64e), stripWhitespace(Buffer.c_str())); |
631 | } |
632 | |
633 | TEST(TBDv4, Target_x86_macos) { |
634 | static const char TBDv4Targetx86MacOS[] = "--- !tapi-tbd\n" |
635 | "tbd-version: 4\n" |
636 | "targets: [ x86_64-macos ]\n" |
637 | "install-name: Test.dylib\n" |
638 | "...\n" ; |
639 | |
640 | Expected<TBDFile> Result = |
641 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4Targetx86MacOS, "Test.tbd" )); |
642 | EXPECT_TRUE(!!Result); |
643 | TBDFile File = std::move(Result.get()); |
644 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
645 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
646 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
647 | EXPECT_EQ(PLATFORM_MACOS, *File->getPlatforms().begin()); |
648 | |
649 | SmallString<4096> Buffer; |
650 | raw_svector_ostream OS(Buffer); |
651 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
652 | EXPECT_TRUE(!WriteResult); |
653 | EXPECT_EQ(stripWhitespace(TBDv4Targetx86MacOS), |
654 | stripWhitespace(Buffer.c_str())); |
655 | } |
656 | |
657 | TEST(TBDv4, Target_x86_ios_simulator) { |
658 | static const char TBDv4Targetx86iOSSim[] = |
659 | "--- !tapi-tbd\n" |
660 | "tbd-version: 4\n" |
661 | "targets: [ x86_64-ios-simulator ]\n" |
662 | "install-name: Test.dylib\n" |
663 | "...\n" ; |
664 | |
665 | Expected<TBDFile> Result = |
666 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4Targetx86iOSSim, "Test.tbd" )); |
667 | EXPECT_TRUE(!!Result); |
668 | TBDFile File = std::move(Result.get()); |
669 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
670 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
671 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
672 | EXPECT_EQ(PLATFORM_IOSSIMULATOR, *File->getPlatforms().begin()); |
673 | |
674 | SmallString<4096> Buffer; |
675 | raw_svector_ostream OS(Buffer); |
676 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
677 | EXPECT_TRUE(!WriteResult); |
678 | EXPECT_EQ(stripWhitespace(TBDv4Targetx86iOSSim), |
679 | stripWhitespace(Buffer.c_str())); |
680 | } |
681 | |
682 | TEST(TBDv4, Target_x86_tvos_simulator) { |
683 | static const char TBDv4x86tvOSSim[] = "--- !tapi-tbd\n" |
684 | "tbd-version: 4\n" |
685 | "targets: [ x86_64-tvos-simulator ]\n" |
686 | "install-name: Test.dylib\n" |
687 | "...\n" ; |
688 | |
689 | Expected<TBDFile> Result = |
690 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4x86tvOSSim, "Test.tbd" )); |
691 | EXPECT_TRUE(!!Result); |
692 | TBDFile File = std::move(Result.get()); |
693 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
694 | EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); |
695 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
696 | EXPECT_EQ(PLATFORM_TVOSSIMULATOR, *File->getPlatforms().begin()); |
697 | |
698 | SmallString<4096> Buffer; |
699 | raw_svector_ostream OS(Buffer); |
700 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
701 | EXPECT_TRUE(!WriteResult); |
702 | EXPECT_EQ(stripWhitespace(TBDv4x86tvOSSim), stripWhitespace(Buffer.c_str())); |
703 | } |
704 | |
705 | TEST(TBDv4, Target_i386_watchos_simulator) { |
706 | static const char TBDv4i386watchOSSim[] = |
707 | "--- !tapi-tbd\n" |
708 | "tbd-version: 4\n" |
709 | "targets: [ i386-watchos-simulator ]\n" |
710 | "install-name: Test.dylib\n" |
711 | "...\n" ; |
712 | |
713 | Expected<TBDFile> Result = |
714 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4i386watchOSSim, "Test.tbd" )); |
715 | EXPECT_TRUE(!!Result); |
716 | TBDFile File = std::move(Result.get()); |
717 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
718 | EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures()); |
719 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
720 | EXPECT_EQ(PLATFORM_WATCHOSSIMULATOR, *File->getPlatforms().begin()); |
721 | |
722 | SmallString<4096> Buffer; |
723 | raw_svector_ostream OS(Buffer); |
724 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
725 | EXPECT_TRUE(!WriteResult); |
726 | EXPECT_EQ(stripWhitespace(TBDv4i386watchOSSim), |
727 | stripWhitespace(Buffer.c_str())); |
728 | } |
729 | |
730 | TEST(TBDv4, Target_i386_driverkit) { |
731 | static const char TBDv4i386DriverKit[] = "--- !tapi-tbd\n" |
732 | "tbd-version: 4\n" |
733 | "targets: [ i386-driverkit ]\n" |
734 | "install-name: Test.dylib\n" |
735 | "...\n" ; |
736 | |
737 | Expected<TBDFile> Result = |
738 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4i386DriverKit, "Test.tbd" )); |
739 | EXPECT_TRUE(!!Result); |
740 | TBDFile File = std::move(Result.get()); |
741 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
742 | EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures()); |
743 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
744 | EXPECT_EQ(PLATFORM_DRIVERKIT, *File->getPlatforms().begin()); |
745 | |
746 | SmallString<4096> Buffer; |
747 | raw_svector_ostream OS(Buffer); |
748 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
749 | EXPECT_TRUE(!WriteResult); |
750 | EXPECT_EQ(stripWhitespace(TBDv4i386DriverKit), |
751 | stripWhitespace(Buffer.c_str())); |
752 | } |
753 | |
754 | TEST(TBDv4, Target_arm64_xros) { |
755 | static const char TBDv4ArchArm64e[] = |
756 | "--- !tapi-tbd\n" |
757 | "tbd-version: 4\n" |
758 | "targets: [ arm64e-xros, arm64e-xros-simulator ]\n" |
759 | "install-name: Test.dylib\n" |
760 | "...\n" ; |
761 | |
762 | auto Result = |
763 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4ArchArm64e, "Test.tbd" )); |
764 | EXPECT_TRUE(!!Result); |
765 | auto File = std::move(Result.get()); |
766 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
767 | PlatformSet ExpectedSet; |
768 | ExpectedSet.insert(V: PLATFORM_XROS); |
769 | ExpectedSet.insert(V: PLATFORM_XROS_SIMULATOR); |
770 | EXPECT_EQ(File->getPlatforms().size(), 2U); |
771 | for (auto Platform : File->getPlatforms()) |
772 | EXPECT_EQ(ExpectedSet.count(Platform), 1U); |
773 | |
774 | EXPECT_EQ(ArchitectureSet(AK_arm64e), File->getArchitectures()); |
775 | |
776 | SmallString<4096> Buffer; |
777 | raw_svector_ostream OS(Buffer); |
778 | auto WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
779 | EXPECT_TRUE(!WriteResult); |
780 | EXPECT_EQ(stripWhitespace(TBDv4ArchArm64e), stripWhitespace(Buffer.c_str())); |
781 | } |
782 | |
783 | TEST(TBDv4, Swift_1) { |
784 | static const char TBDv4SwiftVersion1[] = "--- !tapi-tbd\n" |
785 | "tbd-version: 4\n" |
786 | "targets: [ x86_64-macos ]\n" |
787 | "install-name: Test.dylib\n" |
788 | "swift-abi-version: 1\n" |
789 | "...\n" ; |
790 | |
791 | Expected<TBDFile> Result = |
792 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4SwiftVersion1, "Test.tbd" )); |
793 | EXPECT_TRUE(!!Result); |
794 | TBDFile File = std::move(Result.get()); |
795 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
796 | EXPECT_EQ(1U, File->getSwiftABIVersion()); |
797 | |
798 | // No writer test because we emit "swift-abi-version:1.0". |
799 | } |
800 | |
801 | TEST(TBDv4, Swift_2) { |
802 | static const char TBDv4Swift2[] = "--- !tapi-tbd\n" |
803 | "tbd-version: 4\n" |
804 | "targets: [ x86_64-macos ]\n" |
805 | "install-name: Test.dylib\n" |
806 | "swift-abi-version: 2\n" |
807 | "...\n" ; |
808 | |
809 | Expected<TBDFile> Result = |
810 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4Swift2, "Test.tbd" )); |
811 | EXPECT_TRUE(!!Result); |
812 | TBDFile File = std::move(Result.get()); |
813 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
814 | EXPECT_EQ(2U, File->getSwiftABIVersion()); |
815 | |
816 | // No writer test because we emit "swift-abi-version:2.0". |
817 | } |
818 | |
819 | TEST(TBDv4, Swift_5) { |
820 | static const char TBDv4SwiftVersion5[] = "--- !tapi-tbd\n" |
821 | "tbd-version: 4\n" |
822 | "targets: [ x86_64-macos ]\n" |
823 | "install-name: Test.dylib\n" |
824 | "swift-abi-version: 5\n" |
825 | "...\n" ; |
826 | |
827 | Expected<TBDFile> Result = |
828 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4SwiftVersion5, "Test.tbd" )); |
829 | EXPECT_TRUE(!!Result); |
830 | TBDFile File = std::move(Result.get()); |
831 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
832 | EXPECT_EQ(5U, File->getSwiftABIVersion()); |
833 | |
834 | SmallString<4096> Buffer; |
835 | raw_svector_ostream OS(Buffer); |
836 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
837 | EXPECT_TRUE(!WriteResult); |
838 | EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion5), |
839 | stripWhitespace(Buffer.c_str())); |
840 | } |
841 | |
842 | TEST(TBDv4, Swift_99) { |
843 | static const char TBDv4SwiftVersion99[] = "--- !tapi-tbd\n" |
844 | "tbd-version: 4\n" |
845 | "targets: [ x86_64-macos ]\n" |
846 | "install-name: Test.dylib\n" |
847 | "swift-abi-version: 99\n" |
848 | "...\n" ; |
849 | |
850 | Expected<TBDFile> Result = |
851 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4SwiftVersion99, "Test.tbd" )); |
852 | EXPECT_TRUE(!!Result); |
853 | TBDFile File = std::move(Result.get()); |
854 | EXPECT_EQ(FileType::TBD_V4, File->getFileType()); |
855 | EXPECT_EQ(99U, File->getSwiftABIVersion()); |
856 | |
857 | SmallString<4096> Buffer; |
858 | raw_svector_ostream OS(Buffer); |
859 | Error WriteResult = TextAPIWriter::writeToStream(OS, File: *File); |
860 | EXPECT_TRUE(!WriteResult); |
861 | EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion99), |
862 | stripWhitespace(Buffer.c_str())); |
863 | } |
864 | |
865 | TEST(TBDv4, NotForSharedCache) { |
866 | |
867 | static const char TBDv4NotForSharedCache[] = |
868 | "--- !tapi-tbd\n" |
869 | "tbd-version: 4\n" |
870 | "targets: [ arm64-macos ]\n" |
871 | "flags: [ not_for_dyld_shared_cache ]\n" |
872 | "install-name: /S/L/F/Foo.framework/Foo\n" |
873 | "...\n" ; |
874 | |
875 | Expected<TBDFile> Result = |
876 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4NotForSharedCache, "Test.tbd" )); |
877 | EXPECT_TRUE(!!Result); |
878 | Target ExpectedTarget = Target(AK_arm64, PLATFORM_MACOS); |
879 | TBDFile ReadFile = std::move(Result.get()); |
880 | EXPECT_EQ(FileType::TBD_V4, ReadFile->getFileType()); |
881 | EXPECT_EQ(std::string("/S/L/F/Foo.framework/Foo" ), |
882 | ReadFile->getInstallName()); |
883 | EXPECT_TRUE(ReadFile->targets().begin() != ReadFile->targets().end()); |
884 | EXPECT_EQ(*ReadFile->targets().begin(), ExpectedTarget); |
885 | EXPECT_TRUE(ReadFile->isOSLibNotForSharedCache()); |
886 | } |
887 | |
888 | TEST(TBDv4, InvalidArchitecture) { |
889 | static const char TBDv4UnknownArch[] = "--- !tapi-tbd\n" |
890 | "tbd-version: 4\n" |
891 | "targets: [ foo-macos ]\n" |
892 | "install-name: Test.dylib\n" |
893 | "...\n" ; |
894 | |
895 | Expected<TBDFile> Result = |
896 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4UnknownArch, "Test.tbd" )); |
897 | EXPECT_FALSE(!!Result); |
898 | std::string ErrorMessage = toString(E: Result.takeError()); |
899 | EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown " |
900 | "architecture\ntargets: [ foo-macos ]\n" |
901 | " ^~~~~~~~~~\n" , |
902 | ErrorMessage); |
903 | } |
904 | |
905 | TEST(TBDv4, InvalidPlatform) { |
906 | static const char TBDv4FInvalidPlatform[] = "--- !tapi-tbd\n" |
907 | "tbd-version: 4\n" |
908 | "targets: [ x86_64-maos ]\n" |
909 | "install-name: Test.dylib\n" |
910 | "...\n" ; |
911 | |
912 | Expected<TBDFile> Result = |
913 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4FInvalidPlatform, "Test.tbd" )); |
914 | EXPECT_FALSE(!!Result); |
915 | std::string ErrorMessage = toString(E: Result.takeError()); |
916 | EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: " |
917 | "[ x86_64-maos ]\n" |
918 | " ^~~~~~~~~~~~\n" , |
919 | ErrorMessage); |
920 | } |
921 | |
922 | TEST(TBDv4, MalformedFile1) { |
923 | static const char TBDv4MalformedFile1[] = "--- !tapi-tbd\n" |
924 | "tbd-version: 4\n" |
925 | "...\n" ; |
926 | |
927 | Expected<TBDFile> Result = |
928 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4MalformedFile1, "Test.tbd" )); |
929 | EXPECT_FALSE(!!Result); |
930 | std::string ErrorMessage = toString(E: Result.takeError()); |
931 | ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key " |
932 | "'targets'\ntbd-version: 4\n^\n" , |
933 | ErrorMessage); |
934 | } |
935 | |
936 | TEST(TBDv4, MalformedFile2) { |
937 | static const char TBDv4MalformedFile2[] = "--- !tapi-tbd\n" |
938 | "tbd-version: 4\n" |
939 | "targets: [ x86_64-macos ]\n" |
940 | "install-name: Test.dylib\n" |
941 | "foobar: \"unsupported key\"\n" |
942 | "...\n" ; |
943 | |
944 | Expected<TBDFile> Result = |
945 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4MalformedFile2, "Test.tbd" )); |
946 | EXPECT_FALSE(!!Result); |
947 | std::string ErrorMessage = toString(E: Result.takeError()); |
948 | ASSERT_EQ( |
949 | "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: " |
950 | "\"unsupported key\"\n^~~~~~\n" , |
951 | ErrorMessage); |
952 | } |
953 | |
954 | TEST(TBDv4, MalformedFile3) { |
955 | static const char TBDv4MalformedSwift[] = "--- !tapi-tbd\n" |
956 | "tbd-version: 4\n" |
957 | "targets: [ x86_64-macos ]\n" |
958 | "install-name: Test.dylib\n" |
959 | "swift-abi-version: 1.1\n" |
960 | "...\n" ; |
961 | |
962 | Expected<TBDFile> Result = |
963 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4MalformedSwift, "Test.tbd" )); |
964 | EXPECT_FALSE(!!Result); |
965 | std::string ErrorMessage = toString(E: Result.takeError()); |
966 | EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI " |
967 | "version.\nswift-abi-version: 1.1\n ^~~\n" , |
968 | ErrorMessage); |
969 | } |
970 | |
971 | TEST(TBDv4, InterfaceEquality) { |
972 | static const char TBDv4File[] = |
973 | "--- !tapi-tbd\n" |
974 | "tbd-version: 4\n" |
975 | "targets: [ i386-macos, x86_64-macos, x86_64-ios, i386-maccatalyst, " |
976 | "x86_64-maccatalyst ]\n" |
977 | "install-name: Umbrella.framework/Umbrella\n" |
978 | "current-version: 1.2.3\n" |
979 | "compatibility-version: 1.2\n" |
980 | "swift-abi-version: 5\n" |
981 | "parent-umbrella:\n" |
982 | " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" |
983 | " umbrella: System\n" |
984 | "allowable-clients:\n" |
985 | " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n" |
986 | " clients: [ ClientA ]\n" |
987 | "reexported-libraries:\n" |
988 | " - targets: [ i386-macos ]\n" |
989 | " libraries: [ /System/Library/Frameworks/A.framework/A ]\n" |
990 | "exports:\n" |
991 | " - targets: [ i386-macos ]\n" |
992 | " symbols: [ _symA ]\n" |
993 | " objc-classes: []\n" |
994 | " objc-eh-types: []\n" |
995 | " objc-ivars: []\n" |
996 | " weak-symbols: []\n" |
997 | " thread-local-symbols: []\n" |
998 | " - targets: [ x86_64-ios ]\n" |
999 | " symbols: [_symB]\n" |
1000 | " - targets: [ x86_64-macos, x86_64-ios ]\n" |
1001 | " symbols: [_symAB]\n" |
1002 | " - targets: [ i386-maccatalyst ]\n" |
1003 | " weak-symbols: [ _symC ]\n" |
1004 | " - targets: [ i386-maccatalyst, x86_64-maccatalyst ]\n" |
1005 | " symbols: [ _symA ]\n" |
1006 | " objc-classes: [ Class1 ]\n" |
1007 | " - targets: [ x86_64-maccatalyst ]\n" |
1008 | " symbols: [ _symAB ]\n" |
1009 | "reexports:\n" |
1010 | " - targets: [ i386-macos ]\n" |
1011 | " symbols: [_symC]\n" |
1012 | " objc-classes: []\n" |
1013 | " objc-eh-types: []\n" |
1014 | " objc-ivars: []\n" |
1015 | " weak-symbols: []\n" |
1016 | " thread-local-symbols: []\n" |
1017 | "undefineds:\n" |
1018 | " - targets: [ i386-macos ]\n" |
1019 | " symbols: [ _symD ]\n" |
1020 | " objc-classes: []\n" |
1021 | " objc-eh-types: []\n" |
1022 | " objc-ivars: []\n" |
1023 | " weak-symbols: []\n" |
1024 | " thread-local-symbols: []\n" |
1025 | "...\n" ; |
1026 | |
1027 | Expected<TBDFile> ResultA = |
1028 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "TestA.tbd" )); |
1029 | EXPECT_TRUE(!!ResultA); |
1030 | InterfaceFile FileA = std::move(*ResultA.get()); |
1031 | Expected<TBDFile> ResultB = |
1032 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "TestB.tbd" )); |
1033 | EXPECT_TRUE(!!ResultB); |
1034 | InterfaceFile FileB = std::move(*ResultB.get()); |
1035 | EXPECT_TRUE(FileA == FileB); |
1036 | } |
1037 | |
1038 | TEST(TBDv4, InterfaceDiffVersionsEquality) { |
1039 | static const char TBDv4File[] = |
1040 | "--- !tapi-tbd\n" |
1041 | "tbd-version: 4\n" |
1042 | "targets: [ i386-macos, x86_64-macos ]\n" |
1043 | "install-name: Umbrella.framework/Umbrella\n" |
1044 | "current-version: 1.2.3\n" |
1045 | "compatibility-version: 1.0\n" |
1046 | "swift-abi-version: 5\n" |
1047 | "parent-umbrella:\n" |
1048 | " - targets: [ i386-macos, x86_64-macos ]\n" |
1049 | " umbrella: System\n" |
1050 | "allowable-clients:\n" |
1051 | " - targets: [ i386-macos, x86_64-macos ]\n" |
1052 | " clients: [ ClientA ]\n" |
1053 | "reexported-libraries:\n" |
1054 | " - targets: [ i386-macos ]\n" |
1055 | " libraries: [ /System/Library/Frameworks/A.framework/A ]\n" |
1056 | "exports:\n" |
1057 | " - targets: [ i386-macos ]\n" |
1058 | " symbols: [ _sym5 ]\n" |
1059 | " objc-classes: [ class3]\n" |
1060 | " objc-eh-types: []\n" |
1061 | " objc-ivars: [ class1._ivar3 ]\n" |
1062 | " weak-symbols: [ _weak3 ]\n" |
1063 | " - targets: [ x86_64-macos ]\n" |
1064 | " symbols: [_symAB]\n" |
1065 | " - targets: [ i386-macos, x86_64-macos ]\n" |
1066 | " symbols: [_symA]\n" |
1067 | " objc-classes: [ class1, class2 ]\n" |
1068 | " objc-eh-types: [ class1 ]\n" |
1069 | " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n" |
1070 | " weak-symbols: [ _weak1, _weak2 ]\n" |
1071 | " thread-local-symbols: [ _tlv1, _tlv3 ]\n" |
1072 | "undefineds:\n" |
1073 | " - targets: [ i386-macos ]\n" |
1074 | " symbols: [ _symC ]\n" |
1075 | " objc-classes: []\n" |
1076 | " objc-eh-types: []\n" |
1077 | " objc-ivars: []\n" |
1078 | " weak-symbols: []\n" |
1079 | " thread-local-symbols: []\n" |
1080 | "...\n" ; |
1081 | |
1082 | static const char TBDv3File[] = |
1083 | "--- !tapi-tbd-v3\n" |
1084 | "archs: [ i386, x86_64 ]\n" |
1085 | "platform: macosx\n" |
1086 | "install-name: Umbrella.framework/Umbrella\n" |
1087 | "current-version: 1.2.3\n" |
1088 | "compatibility-version: 1.0\n" |
1089 | "swift-abi-version: 5\n" |
1090 | "parent-umbrella: System\n" |
1091 | "exports:\n" |
1092 | " - archs: [ i386, x86_64 ]\n" |
1093 | " allowable-clients: [ ClientA ]\n" |
1094 | " symbols: [ _symA ]\n" |
1095 | " objc-classes: [ class1, class2 ]\n" |
1096 | " objc-eh-types: [ class1 ]\n" |
1097 | " objc-ivars: [ class1._ivar1, class1._ivar2 ]\n" |
1098 | " weak-def-symbols: [ _weak1, _weak2 ]\n" |
1099 | " thread-local-symbols: [ _tlv1, _tlv3 ]\n" |
1100 | " - archs: [ i386 ]\n" |
1101 | " re-exports: [ /System/Library/Frameworks/A.framework/A ]\n" |
1102 | " symbols: [ _sym5 ]\n" |
1103 | " objc-classes: [ class3 ]\n" |
1104 | " objc-ivars: [ class1._ivar3 ]\n" |
1105 | " weak-def-symbols: [ _weak3 ]\n" |
1106 | " - archs: [ x86_64 ]\n" |
1107 | " symbols: [ _symAB ]\n" |
1108 | "undefineds:\n" |
1109 | " - archs: [ i386 ]\n" |
1110 | " symbols: [ _symC ]\n" |
1111 | "...\n" ; |
1112 | |
1113 | Expected<TBDFile> ResultA = |
1114 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "TestA.tbd" )); |
1115 | EXPECT_TRUE(!!ResultA); |
1116 | InterfaceFile FileA = std::move(*ResultA.get()); |
1117 | Expected<TBDFile> ResultB = |
1118 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv3File, "TestB.tbd" )); |
1119 | EXPECT_TRUE(!!ResultB); |
1120 | InterfaceFile FileB = std::move(*ResultB.get()); |
1121 | EXPECT_TRUE(FileA == FileB); |
1122 | } |
1123 | |
1124 | TEST(TBDv4, InterfaceInequality) { |
1125 | static const char TBDv4File[] = "--- !tapi-tbd\n" |
1126 | "tbd-version: 4\n" |
1127 | "targets: [ i386-macos, x86_64-macos ]\n" |
1128 | "install-name: Umbrella.framework/Umbrella\n" |
1129 | "...\n" ; |
1130 | |
1131 | Expected<TBDFile> ResultA = |
1132 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "TestA.tbd" )); |
1133 | EXPECT_TRUE(!!ResultA); |
1134 | InterfaceFile FileA = std::move(*ResultA.get()); |
1135 | Expected<TBDFile> ResultB = |
1136 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv4File, "TestB.tbd" )); |
1137 | EXPECT_TRUE(!!ResultB); |
1138 | InterfaceFile FileB = std::move(*ResultB.get()); |
1139 | |
1140 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1141 | File->addTarget(Target(AK_x86_64, PLATFORM_IOS)); |
1142 | })); |
1143 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1144 | File->setCurrentVersion(PackedVersion(1, 2, 3)); |
1145 | File->setCompatibilityVersion(PackedVersion(1, 0, 0)); |
1146 | })); |
1147 | EXPECT_TRUE(checkEqualityOnTransform( |
1148 | FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); })); |
1149 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1150 | File->setTwoLevelNamespace(false); |
1151 | })); |
1152 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1153 | File->setApplicationExtensionSafe(false); |
1154 | })); |
1155 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1156 | File->addParentUmbrella(Target(AK_x86_64, PLATFORM_MACOS), "System.dylib" ); |
1157 | })); |
1158 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1159 | File->addAllowableClient("ClientA" , Target(AK_i386, PLATFORM_MACOS)); |
1160 | })); |
1161 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1162 | File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A" , |
1163 | Target(AK_i386, PLATFORM_MACOS)); |
1164 | })); |
1165 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1166 | File->addSymbol(EncodeKind::GlobalSymbol, "_symA" , |
1167 | {Target(AK_x86_64, PLATFORM_MACOS)}); |
1168 | })); |
1169 | EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) { |
1170 | InterfaceFile Document; |
1171 | Document.setFileType(FileType::TBD_V4); |
1172 | Document.addTargets(TargetList{Target(AK_i386, PLATFORM_MACOS), |
1173 | Target(AK_x86_64, PLATFORM_MACOS)}); |
1174 | Document.setInstallName("/System/Library/Frameworks/A.framework/A" ); |
1175 | File->addDocument(std::make_shared<InterfaceFile>(std::move(Document))); |
1176 | })); |
1177 | } |
1178 | |
1179 | } // end namespace TBDv4 |
1180 | |