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
17using namespace llvm;
18using namespace llvm::MachO;
19
20
21namespace TBDv4 {
22
23TEST(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
162TEST(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
316TEST(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
368TEST(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
437TEST(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
467TEST(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
496TEST(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
521TEST(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
546TEST(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
562TEST(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
586TEST(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
610TEST(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
633TEST(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
657TEST(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
682TEST(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
705TEST(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
730TEST(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
754TEST(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
783TEST(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
801TEST(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
819TEST(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
842TEST(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
865TEST(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
888TEST(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
905TEST(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
922TEST(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
936TEST(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
954TEST(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
971TEST(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
1038TEST(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
1124TEST(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

source code of llvm/unittests/TextAPI/TextStubV4Tests.cpp