xref: /llvm-project/llvm/unittests/TextAPI/TextStubV3Tests.cpp (revision d9a9872ec4760762fdc467ef283cea302a3742e5)
1 //===-- TextStubV3Tests.cpp - TBD V3 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 #include "TextStubHelpers.h"
9 #include "llvm/TextAPI/InterfaceFile.h"
10 #include "llvm/TextAPI/TextAPIReader.h"
11 #include "llvm/TextAPI/TextAPIWriter.h"
12 #include "gtest/gtest.h"
13 #include <string>
14 #include <vector>
15 
16 using namespace llvm;
17 using namespace llvm::MachO;
18 
19 static ExportedSymbol TBDv3Symbols[] = {
20     {EncodeKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
21     {EncodeKind::GlobalSymbol, "_sym1", false, false},
22     {EncodeKind::GlobalSymbol, "_sym2", false, false},
23     {EncodeKind::GlobalSymbol, "_sym3", false, false},
24     {EncodeKind::GlobalSymbol, "_sym4", false, false},
25     {EncodeKind::GlobalSymbol, "_sym5", false, false},
26     {EncodeKind::GlobalSymbol, "_tlv1", false, true},
27     {EncodeKind::GlobalSymbol, "_tlv3", false, true},
28     {EncodeKind::GlobalSymbol, "_weak1", true, false},
29     {EncodeKind::GlobalSymbol, "_weak2", true, false},
30     {EncodeKind::GlobalSymbol, "_weak3", true, false},
31     {EncodeKind::ObjectiveCClass, "class1", false, false},
32     {EncodeKind::ObjectiveCClass, "class2", false, false},
33     {EncodeKind::ObjectiveCClass, "class3", false, false},
34     {EncodeKind::ObjectiveCClassEHType, "class1", false, false},
35     {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
36     {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
37     {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
38 };
39 
40 namespace TBDv3 {
41 
TEST(TBDv3,ReadFile)42 TEST(TBDv3, ReadFile) {
43   static const char TBDv3File1[] =
44       "--- !tapi-tbd-v3\n"
45       "archs: [ armv7, arm64 ]\n"
46       "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
47       "         'arm64: 11111111-1111-1111-1111-111111111111']\n"
48       "platform: ios\n"
49       "flags: [ installapi ]\n"
50       "install-name: Test.dylib\n"
51       "current-version: 2.3.4\n"
52       "compatibility-version: 1.0\n"
53       "swift-abi-version: 1.1\n"
54       "parent-umbrella: Umbrella.dylib\n"
55       "exports:\n"
56       "  - archs: [ armv7, arm64 ]\n"
57       "    allowable-clients: [ clientA ]\n"
58       "    re-exports: [ /usr/lib/libfoo.dylib ]\n"
59       "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
60       "    objc-classes: [ class1, class2 ]\n"
61       "    objc-eh-types: [ class1 ]\n"
62       "    objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
63       "    weak-def-symbols: [ _weak1, _weak2 ]\n"
64       "    thread-local-symbols: [ _tlv1, _tlv3 ]\n"
65       "  - archs: [ armv7 ]\n"
66       "    symbols: [ _sym5 ]\n"
67       "    objc-classes: [ class3 ]\n"
68       "    objc-ivars: [ class1._ivar3 ]\n"
69       "    weak-def-symbols: [ _weak3 ]\n"
70       "    thread-local-symbols: [ _tlv3 ]\n"
71       "...\n";
72 
73   Expected<TBDFile> Result =
74       TextAPIReader::get(MemoryBufferRef(TBDv3File1, "Test.tbd"));
75   EXPECT_TRUE(!!Result);
76   TBDFile File = std::move(Result.get());
77   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
78   auto Archs = AK_armv7 | AK_arm64;
79   auto Platform = PLATFORM_IOS;
80   TargetList Targets;
81   for (auto &&arch : Archs)
82     Targets.emplace_back(Target(arch, Platform));
83   EXPECT_EQ(Archs, File->getArchitectures());
84   TargetToAttr Uuids = {{Target(AK_armv7, PLATFORM_UNKNOWN),
85                          "00000000-0000-0000-0000-000000000000"},
86                         {Target(AK_arm64, PLATFORM_UNKNOWN),
87                          "11111111-1111-1111-1111-111111111111"}};
88   EXPECT_EQ(File->getPlatforms().size(), 1U);
89   EXPECT_EQ(Platform, *File->getPlatforms().begin());
90   EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
91   EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
92   EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
93   EXPECT_EQ(2U, File->getSwiftABIVersion());
94   EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
95   EXPECT_TRUE(File->isTwoLevelNamespace());
96   EXPECT_TRUE(File->isApplicationExtensionSafe());
97   InterfaceFileRef client("clientA", Targets);
98   InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);
99   EXPECT_EQ(1U, File->allowableClients().size());
100   EXPECT_EQ(client, File->allowableClients().front());
101   EXPECT_EQ(1U, File->reexportedLibraries().size());
102   EXPECT_EQ(reexport, File->reexportedLibraries().front());
103 
104   ExportedSymbolSeq Exports;
105   for (const auto *Sym : File->symbols()) {
106     EXPECT_FALSE(Sym->isWeakReferenced());
107     EXPECT_FALSE(Sym->isUndefined());
108     Exports.emplace_back(
109         ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),
110                        Sym->isWeakDefined(), Sym->isThreadLocalValue()});
111   }
112   llvm::sort(Exports);
113 
114   EXPECT_EQ(std::size(TBDv3Symbols), Exports.size());
115   EXPECT_TRUE(
116       std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));
117 }
118 
TEST(TBDv3,ReadMultipleDocuments)119 TEST(TBDv3, ReadMultipleDocuments) {
120   static const char TBDv3Inlines[] =
121       "--- !tapi-tbd-v3\n"
122       "archs: [ armv7, arm64 ]\n"
123       "platform: ios\n"
124       "install-name: Test.dylib\n"
125       "current-version: 2.3.4\n"
126       "compatibility-version: 1.0\n"
127       "swift-abi-version: 1.1\n"
128       "parent-umbrella: Umbrella.dylib\n"
129       "exports:\n"
130       "  - archs: [ armv7, arm64 ]\n"
131       "    allowable-clients: [ clientA ]\n"
132       "    re-exports: [ /usr/lib/libfoo.dylib,\n"
133       "                  TestInline.dylib ]\n"
134       "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
135       "    objc-classes: [ class1, class2 ]\n"
136       "    objc-eh-types: [ class1 ]\n"
137       "    objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
138       "    weak-def-symbols: [ _weak1, _weak2 ]\n"
139       "    thread-local-symbols: [ _tlv1, _tlv3 ]\n"
140       "  - archs: [ armv7 ]\n"
141       "    symbols: [ _sym5 ]\n"
142       "    objc-classes: [ class3 ]\n"
143       "    objc-ivars: [ class1._ivar3 ]\n"
144       "    weak-def-symbols: [ _weak3 ]\n"
145       "    thread-local-symbols: [ _tlv3 ]\n"
146       "--- !tapi-tbd-v3\n"
147       "archs: [ armv7, arm64 ]\n"
148       "platform: ios\n"
149       "install-name: TestInline.dylib\n"
150       "swift-abi-version: 1.1\n"
151       "exports:\n"
152       "  - archs: [ armv7, arm64 ]\n"
153       "    symbols: [ _sym5, _sym6 ]\n"
154       "...\n";
155 
156   Expected<TBDFile> Result =
157       TextAPIReader::get(MemoryBufferRef(TBDv3Inlines, "Test.tbd"));
158   EXPECT_TRUE(!!Result);
159   TBDFile File = std::move(Result.get());
160   EXPECT_EQ(File->documents().size(), 1U);
161   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
162   auto Archs = AK_armv7 | AK_arm64;
163   auto Platform = PLATFORM_IOS;
164   TargetList Targets;
165   for (auto &&arch : Archs)
166     Targets.emplace_back(Target(arch, Platform));
167   EXPECT_EQ(Archs, File->getArchitectures());
168   TargetToAttr Uuids = {{Target(AK_armv7, PLATFORM_UNKNOWN),
169                          "00000000-0000-0000-0000-000000000000"},
170                         {Target(AK_arm64, PLATFORM_UNKNOWN),
171                          "11111111-1111-1111-1111-111111111111"}};
172   EXPECT_EQ(File->getPlatforms().size(), 1U);
173   EXPECT_EQ(Platform, *File->getPlatforms().begin());
174   EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
175   EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
176   EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
177   EXPECT_EQ(2U, File->getSwiftABIVersion());
178   EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
179   EXPECT_TRUE(File->isTwoLevelNamespace());
180   EXPECT_TRUE(File->isApplicationExtensionSafe());
181   InterfaceFileRef Client("clientA", Targets);
182   const std::vector<InterfaceFileRef> Reexports = {
183       InterfaceFileRef("/usr/lib/libfoo.dylib", Targets),
184       InterfaceFileRef("TestInline.dylib", Targets)};
185   EXPECT_EQ(1U, File->allowableClients().size());
186   EXPECT_EQ(Client, File->allowableClients().front());
187   EXPECT_EQ(2U, File->reexportedLibraries().size());
188   EXPECT_EQ(Reexports, File->reexportedLibraries());
189 
190   ExportedSymbolSeq Exports;
191   for (const auto *Sym : File->symbols()) {
192     EXPECT_FALSE(Sym->isWeakReferenced());
193     EXPECT_FALSE(Sym->isUndefined());
194     Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),
195                                         Sym->isWeakDefined(),
196                                         Sym->isThreadLocalValue()});
197   }
198   llvm::sort(Exports);
199 
200   EXPECT_EQ(std::size(TBDv3Symbols), Exports.size());
201   EXPECT_TRUE(
202       std::equal(Exports.begin(), Exports.end(), std::begin(TBDv3Symbols)));
203 
204   // Check Second Document
205   Exports.clear();
206   TBDReexportFile Document = File->documents().front();
207   EXPECT_EQ(FileType::TBD_V3, Document->getFileType());
208   EXPECT_EQ(Archs, Document->getArchitectures());
209   EXPECT_EQ(Platform, *Document->getPlatforms().begin());
210   EXPECT_EQ(std::string("TestInline.dylib"), Document->getInstallName());
211   EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCurrentVersion());
212   EXPECT_EQ(PackedVersion(1, 0, 0), Document->getCompatibilityVersion());
213   EXPECT_EQ(2U, Document->getSwiftABIVersion());
214 
215   for (const auto *Sym : Document->symbols()) {
216     EXPECT_FALSE(Sym->isWeakReferenced());
217     EXPECT_FALSE(Sym->isUndefined());
218     Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName().str(),
219                                         Sym->isWeakDefined(),
220                                         Sym->isThreadLocalValue()});
221   }
222   llvm::sort(Exports);
223 
224   ExportedSymbolSeq DocumentSymbols{
225       {EncodeKind::GlobalSymbol, "_sym5", false, false},
226       {EncodeKind::GlobalSymbol, "_sym6", false, false},
227   };
228 
229   EXPECT_EQ(DocumentSymbols.size(), Exports.size());
230   EXPECT_TRUE(
231       std::equal(Exports.begin(), Exports.end(), DocumentSymbols.begin()));
232 }
233 
TEST(TBDv3,WriteFile)234 TEST(TBDv3, WriteFile) {
235   static const char TBDv3File3[] =
236       "--- !tapi-tbd-v3\n"
237       "archs:           [ i386, x86_64 ]\n"
238       "platform:        macosx\n"
239       "install-name:    '/usr/lib/libfoo.dylib'\n"
240       "current-version: 1.2.3\n"
241       "compatibility-version: 0\n"
242       "swift-abi-version: 5\n"
243       "exports:\n"
244       "  - archs:           [ i386 ]\n"
245       "    symbols:         [ _sym1 ]\n"
246       "    weak-def-symbols: [ _sym2 ]\n"
247       "    thread-local-symbols: [ _sym3 ]\n"
248       "  - archs:           [ x86_64 ]\n"
249       "    allowable-clients: [ clientA ]\n"
250       "    re-exports:      [ '/usr/lib/libfoo.dylib' ]\n"
251       "    objc-classes:    [ Class1 ]\n"
252       "    objc-eh-types:   [ Class1 ]\n"
253       "    objc-ivars:      [ Class1._ivar1 ]\n"
254       "...\n";
255 
256   InterfaceFile File;
257   TargetList Targets;
258   for (auto &&arch : AK_i386 | AK_x86_64)
259     Targets.emplace_back(Target(arch, PLATFORM_MACOS));
260   File.setPath("libfoo.dylib");
261   File.setInstallName("/usr/lib/libfoo.dylib");
262   File.setFileType(FileType::TBD_V3);
263   File.addTargets(Targets);
264   File.setCurrentVersion(PackedVersion(1, 2, 3));
265   File.setTwoLevelNamespace();
266   File.setApplicationExtensionSafe();
267   File.setSwiftABIVersion(5);
268   File.setObjCConstraint(ObjCConstraintType::Retain_Release);
269   File.addAllowableClient("clientA", Targets[1]);
270   File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);
271   File.addSymbol(EncodeKind::GlobalSymbol, "_sym1", {Targets[0]});
272   File.addSymbol(EncodeKind::GlobalSymbol, "_sym2", {Targets[0]},
273                  SymbolFlags::WeakDefined);
274   File.addSymbol(EncodeKind::GlobalSymbol, "_sym3", {Targets[0]},
275                  SymbolFlags::ThreadLocalValue);
276   File.addSymbol(EncodeKind::ObjectiveCClass, "Class1", {Targets[1]});
277   File.addSymbol(EncodeKind::ObjectiveCClassEHType, "Class1", {Targets[1]});
278   File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "Class1._ivar1",
279                  {Targets[1]});
280 
281   SmallString<4096> Buffer;
282   raw_svector_ostream OS(Buffer);
283   Error Result = TextAPIWriter::writeToStream(OS, File);
284   EXPECT_FALSE(Result);
285   EXPECT_STREQ(TBDv3File3, Buffer.c_str());
286 }
287 
TEST(TBDv3,WriteMultipleDocuments)288 TEST(TBDv3, WriteMultipleDocuments) {
289   static const char TBDv3Inlines[] =
290       "--- !tapi-tbd-v3\n"
291       "archs:           [ i386, x86_64 ]\n"
292       "platform:        zippered\n"
293       "install-name:    '/usr/lib/libfoo.dylib'\n"
294       "current-version: 1.2.3\n"
295       "compatibility-version: 0\n"
296       "swift-abi-version: 5\n"
297       "exports:\n"
298       "  - archs:           [ x86_64 ]\n"
299       "    allowable-clients: [ clientA ]\n"
300       "    re-exports:      [ '/usr/lib/libbar.dylib' ]\n"
301       "  - archs:           [ i386, x86_64 ]\n"
302       "    symbols:         [ _sym1 ]\n"
303       "    objc-classes:    [ Class1 ]\n"
304       "    objc-eh-types:   [ Class1 ]\n"
305       "    objc-ivars:      [ Class1._ivar1 ]\n"
306       "    weak-def-symbols: [ _sym2 ]\n"
307       "    thread-local-symbols: [ _symA ]\n"
308       "--- !tapi-tbd-v3\n"
309       "archs:           [ i386 ]\n"
310       "platform:        macosx\n"
311       "install-name:    '/usr/lib/libbar.dylib'\n"
312       "current-version: 0\n"
313       "compatibility-version: 0\n"
314       "swift-abi-version: 5\n"
315       "objc-constraint: none\n"
316       "exports:\n"
317       "  - archs:           [ i386 ]\n"
318       "    symbols:         [ _sym3, _sym4 ]\n"
319       "...\n";
320 
321   InterfaceFile File;
322   TargetList Targets;
323   for (auto &&arch : AK_i386 | AK_x86_64) {
324     Targets.emplace_back(Target(arch, PLATFORM_MACOS));
325     Targets.emplace_back(Target(arch, PLATFORM_MACCATALYST));
326   }
327   File.addTargets(Targets);
328   File.setPath("libfoo.dylib");
329   File.setInstallName("/usr/lib/libfoo.dylib");
330   File.setFileType(FileType::TBD_V3);
331   File.setCurrentVersion(PackedVersion(1, 2, 3));
332   File.setTwoLevelNamespace();
333   File.setApplicationExtensionSafe();
334   File.setSwiftABIVersion(5);
335   File.setObjCConstraint(ObjCConstraintType::Retain_Release);
336   File.addAllowableClient("clientA", Targets[2]);
337   File.addReexportedLibrary("/usr/lib/libbar.dylib", Targets[2]);
338   File.addSymbol(EncodeKind::GlobalSymbol, "_sym1", Targets);
339   File.addSymbol(EncodeKind::GlobalSymbol, "_sym2", Targets,
340                  SymbolFlags::WeakDefined);
341   File.addSymbol(EncodeKind::GlobalSymbol, "_symA", Targets,
342                  SymbolFlags::ThreadLocalValue);
343   File.addSymbol(EncodeKind::ObjectiveCClass, "Class1", Targets);
344   File.addSymbol(EncodeKind::ObjectiveCClassEHType, "Class1", Targets);
345   File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "Class1._ivar1",
346                  Targets);
347 
348   // Inline document
349   InterfaceFile Document;
350   Targets = {Target(AK_i386, PLATFORM_MACOS)};
351   Document.addTargets(Targets);
352   Document.setPath("libbar.dylib");
353   Document.setInstallName("/usr/lib/libbar.dylib");
354   Document.setFileType(FileType::TBD_V3);
355   Document.setTwoLevelNamespace();
356   Document.setApplicationExtensionSafe();
357   Document.setSwiftABIVersion(5);
358   Document.addSymbol(EncodeKind::GlobalSymbol, "_sym3", Targets);
359   Document.addSymbol(EncodeKind::GlobalSymbol, "_sym4", Targets);
360   File.addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
361 
362   SmallString<4096> Buffer;
363   raw_svector_ostream OS(Buffer);
364   Error Result = TextAPIWriter::writeToStream(OS, File);
365   EXPECT_FALSE(Result);
366   EXPECT_STREQ(TBDv3Inlines, Buffer.c_str());
367 }
368 
TEST(TBDv3,Platform_macOS)369 TEST(TBDv3, Platform_macOS) {
370   static const char TBDv3PlatformMacOS[] = "--- !tapi-tbd-v3\n"
371                                            "archs: [ x86_64 ]\n"
372                                            "platform: macosx\n"
373                                            "install-name: Test.dylib\n"
374                                            "...\n";
375 
376   Expected<TBDFile> Result =
377       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformMacOS, "Test.tbd"));
378   EXPECT_TRUE(!!Result);
379   auto Platform = PLATFORM_MACOS;
380   TBDFile File = std::move(Result.get());
381   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
382   EXPECT_EQ(File->getPlatforms().size(), 1U);
383   EXPECT_EQ(Platform, *File->getPlatforms().begin());
384 
385   SmallString<4096> Buffer;
386   raw_svector_ostream OS(Buffer);
387   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
388   EXPECT_TRUE(!WriteResult);
389   EXPECT_EQ(stripWhitespace(TBDv3PlatformMacOS),
390             stripWhitespace(Buffer.c_str()));
391 }
392 
TEST(TBDv3,Platform_iOS)393 TEST(TBDv3, Platform_iOS) {
394   static const char TBDv3PlatformiOS[] = "--- !tapi-tbd-v3\n"
395                                          "archs: [ arm64 ]\n"
396                                          "platform: ios\n"
397                                          "install-name: Test.dylib\n"
398                                          "...\n";
399 
400   Expected<TBDFile> Result =
401       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOS, "Test.tbd"));
402   EXPECT_TRUE(!!Result);
403   auto Platform = PLATFORM_IOS;
404   TBDFile File = std::move(Result.get());
405   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
406   EXPECT_EQ(File->getPlatforms().size(), 1U);
407   EXPECT_EQ(Platform, *File->getPlatforms().begin());
408 
409   SmallString<4096> Buffer;
410   raw_svector_ostream OS(Buffer);
411   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
412   EXPECT_TRUE(!WriteResult);
413   EXPECT_EQ(stripWhitespace(TBDv3PlatformiOS), stripWhitespace(Buffer.c_str()));
414 }
415 
TEST(TBDv3,Platform_watchOS)416 TEST(TBDv3, Platform_watchOS) {
417   static const char TBDv3watchOS[] = "--- !tapi-tbd-v3\n"
418                                      "archs: [ armv7k ]\n"
419                                      "platform: watchos\n"
420                                      "install-name: Test.dylib\n"
421                                      "...\n";
422 
423   Expected<TBDFile> Result =
424       TextAPIReader::get(MemoryBufferRef(TBDv3watchOS, "Test.tbd"));
425   EXPECT_TRUE(!!Result);
426   auto Platform = PLATFORM_WATCHOS;
427   TBDFile File = std::move(Result.get());
428   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
429   EXPECT_EQ(File->getPlatforms().size(), 1U);
430   EXPECT_EQ(Platform, *File->getPlatforms().begin());
431 
432   SmallString<4096> Buffer;
433   raw_svector_ostream OS(Buffer);
434   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
435   EXPECT_TRUE(!WriteResult);
436   EXPECT_EQ(stripWhitespace(TBDv3watchOS), stripWhitespace(Buffer.c_str()));
437 }
438 
TEST(TBDv3,Platform_tvOS)439 TEST(TBDv3, Platform_tvOS) {
440   static const char TBDv3PlatformtvOS[] = "--- !tapi-tbd-v3\n"
441                                           "archs: [ arm64 ]\n"
442                                           "platform: tvos\n"
443                                           "install-name: Test.dylib\n"
444                                           "...\n";
445 
446   Expected<TBDFile> Result =
447       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOS, "Test.tbd"));
448   EXPECT_TRUE(!!Result);
449   TBDFile File = std::move(Result.get());
450   auto Platform = PLATFORM_TVOS;
451   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
452   EXPECT_EQ(File->getPlatforms().size(), 1U);
453   EXPECT_EQ(Platform, *File->getPlatforms().begin());
454 
455   SmallString<4096> Buffer;
456   raw_svector_ostream OS(Buffer);
457   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
458   EXPECT_FALSE(WriteResult);
459   EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOS),
460             stripWhitespace(Buffer.c_str()));
461 }
462 
TEST(TBDv3,Platform_bridgeOS)463 TEST(TBDv3, Platform_bridgeOS) {
464   static const char TBDv3BridgeOS[] = "--- !tapi-tbd-v3\n"
465                                       "archs: [ armv7k ]\n"
466                                       "platform: bridgeos\n"
467                                       "install-name: Test.dylib\n"
468                                       "...\n";
469 
470   Expected<TBDFile> Result =
471       TextAPIReader::get(MemoryBufferRef(TBDv3BridgeOS, "Test.tbd"));
472   EXPECT_TRUE(!!Result);
473   auto Platform = PLATFORM_BRIDGEOS;
474   TBDFile File = std::move(Result.get());
475   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
476   EXPECT_EQ(File->getPlatforms().size(), 1U);
477   EXPECT_EQ(Platform, *File->getPlatforms().begin());
478 
479   SmallString<4096> Buffer;
480   raw_svector_ostream OS(Buffer);
481   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
482   EXPECT_TRUE(!WriteResult);
483   EXPECT_EQ(stripWhitespace(TBDv3BridgeOS), stripWhitespace(Buffer.c_str()));
484 }
485 
TEST(TBDv3,Platform_macCatalyst)486 TEST(TBDv3, Platform_macCatalyst) {
487   static const char TBDv3PlatformiOSmac[] = "--- !tapi-tbd-v3\n"
488                                             "archs: [ armv7k ]\n"
489                                             "platform: maccatalyst\n"
490                                             "install-name: Test.dylib\n"
491                                             "...\n";
492 
493   Expected<TBDFile> Result =
494       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSmac, "Test.tbd"));
495   EXPECT_TRUE(!!Result);
496   auto Platform = PLATFORM_MACCATALYST;
497   TBDFile File = std::move(Result.get());
498   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
499   EXPECT_EQ(Platform, *File->getPlatforms().begin());
500 
501   SmallString<4096> Buffer;
502   raw_svector_ostream OS(Buffer);
503   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
504   EXPECT_TRUE(!WriteResult);
505   EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSmac),
506             stripWhitespace(Buffer.c_str()));
507 }
508 
TEST(TBDv3,Platform_zippered)509 TEST(TBDv3, Platform_zippered) {
510   static const char TBDv3PlatformZippered[] = "--- !tapi-tbd-v3\n"
511                                               "archs: [ armv7k ]\n"
512                                               "platform: zippered\n"
513                                               "install-name: Test.dylib\n"
514                                               "...\n";
515 
516   Expected<TBDFile> Result =
517       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformZippered, "Test.tbd"));
518   EXPECT_TRUE(!!Result);
519   TBDFile File = std::move(Result.get());
520   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
521 
522   PlatformSet Platforms;
523   Platforms.insert(PLATFORM_MACOS);
524   Platforms.insert(PLATFORM_MACCATALYST);
525   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
526   for (auto Platform : File->getPlatforms())
527 	    EXPECT_EQ(Platforms.count(Platform), 1U);
528 
529   SmallString<4096> Buffer;
530   raw_svector_ostream OS(Buffer);
531   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
532   EXPECT_TRUE(!WriteResult);
533   EXPECT_EQ(stripWhitespace(TBDv3PlatformZippered),
534             stripWhitespace(Buffer.c_str()));
535 }
536 
TEST(TBDv3,Platform_iOSSim)537 TEST(TBDv3, Platform_iOSSim) {
538   static const char TBDv3PlatformiOSsim[] = "--- !tapi-tbd-v3\n"
539                                             "archs: [ x86_64 ]\n"
540                                             "platform: ios\n"
541                                             "install-name: Test.dylib\n"
542                                             "...\n";
543 
544   Expected<TBDFile> Result =
545       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformiOSsim, "Test.tbd"));
546   EXPECT_TRUE(!!Result);
547   auto Platform = PLATFORM_IOSSIMULATOR;
548   TBDFile File = std::move(Result.get());
549   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
550   EXPECT_EQ(File->getPlatforms().size(), 1U);
551   EXPECT_EQ(Platform, *File->getPlatforms().begin());
552 
553   SmallString<4096> Buffer;
554   raw_svector_ostream OS(Buffer);
555   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
556   EXPECT_TRUE(!WriteResult);
557   EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSsim),
558             stripWhitespace(Buffer.c_str()));
559 }
560 
TEST(TBDv3,Platform_watchOSSim)561 TEST(TBDv3, Platform_watchOSSim) {
562   static const char TBDv3watchOSsim[] = "--- !tapi-tbd-v3\n"
563                                         "archs: [ x86_64 ]\n"
564                                         "platform: watchos\n"
565                                         "install-name: Test.dylib\n"
566                                         "...\n";
567 
568   Expected<TBDFile> Result =
569       TextAPIReader::get(MemoryBufferRef(TBDv3watchOSsim, "Test.tbd"));
570   EXPECT_TRUE(!!Result);
571   auto Platform = PLATFORM_WATCHOSSIMULATOR;
572   TBDFile File = std::move(Result.get());
573   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
574   EXPECT_EQ(File->getPlatforms().size(), 1U);
575   EXPECT_EQ(Platform, *File->getPlatforms().begin());
576 
577   SmallString<4096> Buffer;
578   raw_svector_ostream OS(Buffer);
579   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
580   EXPECT_TRUE(!WriteResult);
581   EXPECT_EQ(stripWhitespace(TBDv3watchOSsim), stripWhitespace(Buffer.c_str()));
582 }
583 
TEST(TBDv3,Platform_tvOSSim)584 TEST(TBDv3, Platform_tvOSSim) {
585   static const char TBDv3PlatformtvOSsim[] = "--- !tapi-tbd-v3\n"
586                                              "archs: [ x86_64 ]\n"
587                                              "platform: tvos\n"
588                                              "install-name: Test.dylib\n"
589                                              "...\n";
590 
591   Expected<TBDFile> Result =
592       TextAPIReader::get(MemoryBufferRef(TBDv3PlatformtvOSsim, "Test.tbd"));
593   EXPECT_TRUE(!!Result);
594   TBDFile File = std::move(Result.get());
595   auto Platform = PLATFORM_TVOSSIMULATOR;
596   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
597   EXPECT_EQ(File->getPlatforms().size(), 1U);
598   EXPECT_EQ(Platform, *File->getPlatforms().begin());
599 
600   SmallString<4096> Buffer;
601   raw_svector_ostream OS(Buffer);
602   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
603   EXPECT_TRUE(!WriteResult);
604   EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOSsim),
605             stripWhitespace(Buffer.c_str()));
606 }
607 
TEST(TBDv3,Arch_arm64e)608 TEST(TBDv3, Arch_arm64e) {
609   static const char TBDv3ArchArm64e[] = "--- !tapi-tbd-v3\n"
610                                         "archs: [ arm64, arm64e ]\n"
611                                         "platform: ios\n"
612                                         "install-name: Test.dylib\n"
613                                         "...\n";
614 
615   Expected<TBDFile> Result =
616       TextAPIReader::get(MemoryBufferRef(TBDv3ArchArm64e, "Test.tbd"));
617   EXPECT_TRUE(!!Result);
618   TBDFile File = std::move(Result.get());
619   auto Platform = PLATFORM_IOS;
620   auto Archs = AK_arm64 | AK_arm64e;
621   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
622   EXPECT_EQ(File->getPlatforms().size(), 1U);
623   EXPECT_EQ(Platform, *File->getPlatforms().begin());
624   EXPECT_EQ(Archs, File->getArchitectures());
625 
626   SmallString<4096> Buffer;
627   raw_svector_ostream OS(Buffer);
628   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
629   EXPECT_TRUE(!WriteResult);
630   EXPECT_EQ(stripWhitespace(TBDv3ArchArm64e), stripWhitespace(Buffer.c_str()));
631 }
632 
TEST(TBDv3,Swift_1_0)633 TEST(TBDv3, Swift_1_0) {
634   static const char TBDv3Swift1[] = "--- !tapi-tbd-v3\n"
635                                     "archs: [ arm64 ]\n"
636                                     "platform: ios\n"
637                                     "install-name: Test.dylib\n"
638                                     "swift-abi-version: 1.0\n"
639                                     "...\n";
640 
641   Expected<TBDFile> Result =
642       TextAPIReader::get(MemoryBufferRef(TBDv3Swift1, "Test.tbd"));
643   EXPECT_TRUE(!!Result);
644   TBDFile File = std::move(Result.get());
645   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
646   EXPECT_EQ(1U, File->getSwiftABIVersion());
647 
648   SmallString<4096> Buffer;
649   raw_svector_ostream OS(Buffer);
650   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
651   EXPECT_TRUE(!WriteResult);
652   EXPECT_EQ(stripWhitespace(TBDv3Swift1), stripWhitespace(Buffer.c_str()));
653 }
654 
TEST(TBDv3,Swift_1_1)655 TEST(TBDv3, Swift_1_1) {
656   static const char TBDv3Swift1Dot[] = "--- !tapi-tbd-v3\n"
657                                        "archs: [ arm64 ]\n"
658                                        "platform: ios\n"
659                                        "install-name: Test.dylib\n"
660                                        "swift-abi-version: 1.1\n"
661                                        "...\n";
662 
663   Expected<TBDFile> Result =
664       TextAPIReader::get(MemoryBufferRef(TBDv3Swift1Dot, "Test.tbd"));
665   EXPECT_TRUE(!!Result);
666   TBDFile File = std::move(Result.get());
667   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
668   EXPECT_EQ(2U, File->getSwiftABIVersion());
669 
670   SmallString<4096> Buffer;
671   raw_svector_ostream OS(Buffer);
672   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
673   EXPECT_TRUE(!WriteResult);
674   EXPECT_EQ(stripWhitespace(TBDv3Swift1Dot), stripWhitespace(Buffer.c_str()));
675 }
676 
TEST(TBDv3,Swift_2_0)677 TEST(TBDv3, Swift_2_0) {
678   static const char TBDv3Swift2[] = "--- !tapi-tbd-v3\n"
679                                     "archs: [ arm64 ]\n"
680                                     "platform: ios\n"
681                                     "install-name: Test.dylib\n"
682                                     "swift-abi-version: 2.0\n"
683                                     "...\n";
684 
685   Expected<TBDFile> Result =
686       TextAPIReader::get(MemoryBufferRef(TBDv3Swift2, "Test.tbd"));
687   EXPECT_TRUE(!!Result);
688   TBDFile File = std::move(Result.get());
689   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
690   EXPECT_EQ(3U, File->getSwiftABIVersion());
691 
692   SmallString<4096> Buffer;
693   raw_svector_ostream OS(Buffer);
694   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
695   EXPECT_TRUE(!WriteResult);
696   EXPECT_EQ(stripWhitespace(TBDv3Swift2), stripWhitespace(Buffer.c_str()));
697 }
698 
TEST(TBDv3,Swift_3_0)699 TEST(TBDv3, Swift_3_0) {
700   static const char TBDv3Swift3[] = "--- !tapi-tbd-v3\n"
701                                     "archs: [ arm64 ]\n"
702                                     "platform: ios\n"
703                                     "install-name: Test.dylib\n"
704                                     "swift-abi-version: 3.0\n"
705                                     "...\n";
706 
707   Expected<TBDFile> Result =
708       TextAPIReader::get(MemoryBufferRef(TBDv3Swift3, "Test.tbd"));
709   EXPECT_TRUE(!!Result);
710   TBDFile File = std::move(Result.get());
711   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
712   EXPECT_EQ(4U, File->getSwiftABIVersion());
713 
714   SmallString<4096> Buffer;
715   raw_svector_ostream OS(Buffer);
716   Error WriteResult = TextAPIWriter::writeToStream(OS, *File);
717   EXPECT_TRUE(!WriteResult);
718   EXPECT_EQ(stripWhitespace(TBDv3Swift3), stripWhitespace(Buffer.c_str()));
719 }
720 
TEST(TBDv3,Swift_4_0)721 TEST(TBDv3, Swift_4_0) {
722   static const char TBDv3Swift4[] = "--- !tapi-tbd-v3\n"
723                                     "archs: [ arm64 ]\n"
724                                     "platform: ios\n"
725                                     "install-name: Test.dylib\n"
726                                     "swift-abi-version: 4.0\n"
727                                     "...\n";
728 
729   Expected<TBDFile> Result =
730       TextAPIReader::get(MemoryBufferRef(TBDv3Swift4, "Test.tbd"));
731   EXPECT_FALSE(!!Result);
732   std::string ErrorMessage = toString(Result.takeError());
733   EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
734             "version.\nswift-abi-version: 4.0\n                   ^~~\n",
735             ErrorMessage);
736 }
737 
TEST(TBDv3,Swift_5)738 TEST(TBDv3, Swift_5) {
739   static const char TBDv3Swift5[] = "--- !tapi-tbd-v3\n"
740                                     "archs: [ arm64 ]\n"
741                                     "platform: ios\n"
742                                     "install-name: Test.dylib\n"
743                                     "swift-abi-version: 5\n"
744                                     "...\n";
745 
746   Expected<TBDFile> Result =
747       TextAPIReader::get(MemoryBufferRef(TBDv3Swift5, "Test.tbd"));
748   EXPECT_TRUE(!!Result);
749   TBDFile File = std::move(Result.get());
750   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
751   EXPECT_EQ(5U, File->getSwiftABIVersion());
752 }
753 
TEST(TBDv3,Swift_99)754 TEST(TBDv3, Swift_99) {
755   static const char TBDv3Swift99[] = "--- !tapi-tbd-v3\n"
756                                      "archs: [ arm64 ]\n"
757                                      "platform: ios\n"
758                                      "install-name: Test.dylib\n"
759                                      "swift-abi-version: 99\n"
760                                      "...\n";
761 
762   Expected<TBDFile> Result =
763       TextAPIReader::get(MemoryBufferRef(TBDv3Swift99, "Test.tbd"));
764   EXPECT_TRUE(!!Result);
765   TBDFile File = std::move(Result.get());
766   EXPECT_EQ(FileType::TBD_V3, File->getFileType());
767   EXPECT_EQ(99U, File->getSwiftABIVersion());
768 }
769 
TEST(TBDv3,UnknownArchitecture)770 TEST(TBDv3, UnknownArchitecture) {
771   static const char TBDv3FileUnknownArch[] = "--- !tapi-tbd-v3\n"
772                                              "archs: [ foo ]\n"
773                                              "platform: macosx\n"
774                                              "install-name: Test.dylib\n"
775                                              "...\n";
776 
777   Expected<TBDFile> Result =
778       TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownArch, "Test.tbd"));
779   EXPECT_TRUE(!!Result);
780 }
781 
TEST(TBDv3,UnknownPlatform)782 TEST(TBDv3, UnknownPlatform) {
783   static const char TBDv3FileUnknownPlatform[] = "--- !tapi-tbd-v3\n"
784                                                  "archs: [ i386 ]\n"
785                                                  "platform: newOS\n"
786                                                  "...\n";
787 
788   Expected<TBDFile> Result =
789       TextAPIReader::get(MemoryBufferRef(TBDv3FileUnknownPlatform, "Test.tbd"));
790   EXPECT_FALSE(!!Result);
791   std::string ErrorMessage = toString(Result.takeError());
792   EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
793             "newOS\n          ^~~~~\n",
794             ErrorMessage);
795 }
796 
TEST(TBDv3,MalformedFile1)797 TEST(TBDv3, MalformedFile1) {
798   static const char TBDv3FileMalformed1[] = "--- !tapi-tbd-v3\n"
799                                             "archs: [ arm64 ]\n"
800                                             "foobar: \"Unsupported key\"\n"
801                                             "...\n";
802 
803   Expected<TBDFile> Result =
804       TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed1, "Test.tbd"));
805   EXPECT_FALSE(!!Result);
806   std::string ErrorMessage = toString(Result.takeError());
807   ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
808             "'platform'\narchs: [ arm64 ]\n^\n",
809             ErrorMessage);
810 }
811 
TEST(TBDv3,MalformedFile2)812 TEST(TBDv3, MalformedFile2) {
813   static const char TBDv3FileMalformed2[] = "--- !tapi-tbd-v3\n"
814                                             "archs: [ arm64 ]\n"
815                                             "platform: ios\n"
816                                             "install-name: Test.dylib\n"
817                                             "foobar: \"Unsupported key\"\n"
818                                             "...\n";
819 
820   Expected<TBDFile> Result =
821       TextAPIReader::get(MemoryBufferRef(TBDv3FileMalformed2, "Test.tbd"));
822   EXPECT_FALSE(!!Result);
823   std::string ErrorMessage = toString(Result.takeError());
824   ASSERT_EQ(
825       "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: "
826       "\"Unsupported key\"\n^~~~~~\n",
827       ErrorMessage);
828 }
829 
TEST(TBDv3,InterfaceEquality)830 TEST(TBDv3, InterfaceEquality) {
831   static const char TBDv3File[] =
832       "--- !tapi-tbd-v3\n"
833       "archs: [ armv7, arm64 ]\n"
834       "uuids: [ 'armv7: 00000000-0000-0000-0000-000000000000',\n"
835       "         'arm64: 11111111-1111-1111-1111-111111111111']\n"
836       "platform: ios\n"
837       "flags: [ installapi ]\n"
838       "install-name: Test.dylib\n"
839       "current-version: 2.3.4\n"
840       "compatibility-version: 1.0\n"
841       "swift-abi-version: 1.1\n"
842       "parent-umbrella: Umbrella.dylib\n"
843       "exports:\n"
844       "  - archs: [ armv7, arm64 ]\n"
845       "    allowable-clients: [ clientA ]\n"
846       "    re-exports: [ /usr/lib/libfoo.dylib ]\n"
847       "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
848       "    objc-classes: [ class1, class2 ]\n"
849       "    objc-eh-types: [ class1 ]\n"
850       "    objc-ivars: [ class1._ivar1, class1._ivar2 ]\n"
851       "    weak-def-symbols: [ _weak1, _weak2 ]\n"
852       "    thread-local-symbols: [ _tlv1, _tlv3 ]\n"
853       "  - archs: [ armv7 ]\n"
854       "    symbols: [ _sym5 ]\n"
855       "    objc-classes: [ class3 ]\n"
856       "    objc-ivars: [ class1._ivar3 ]\n"
857       "    weak-def-symbols: [ _weak3 ]\n"
858       "    thread-local-symbols: [ _tlv3 ]\n"
859       "--- !tapi-tbd-v3\n"
860       "archs:           [ i386 ]\n"
861       "platform:        macosx\n"
862       "install-name:    '/usr/lib/libbar.dylib'\n"
863       "current-version: 0\n"
864       "compatibility-version: 0\n"
865       "swift-abi-version: 5\n"
866       "objc-constraint: none\n"
867       "exports:\n"
868       "  - archs:           [ i386 ]\n"
869       "    symbols:         [ _sym3, _sym4 ]\n"
870       "...\n";
871   Expected<TBDFile> ResultA =
872       TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd"));
873   EXPECT_TRUE(!!ResultA);
874   InterfaceFile FileA = std::move(*ResultA.get());
875   Expected<TBDFile> ResultB =
876       TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd"));
877   EXPECT_TRUE(!!ResultB);
878   InterfaceFile FileB = std::move(*ResultB.get());
879   EXPECT_FALSE(FileA.getPath() == FileB.getPath());
880   EXPECT_TRUE(FileA == FileB);
881 }
882 
883 
884 
TEST(TBDv3,InterfaceInequality)885 TEST(TBDv3, InterfaceInequality) {
886   static const char TBDv3File[] = "--- !tapi-tbd-v3\n"
887                                   "archs: [ armv7, arm64 ]\n"
888                                   "platform: ios\n"
889                                   "install-name: Test.dylib\n"
890                                   "...\n";
891 
892   Expected<TBDFile> ResultA =
893       TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestA.tbd"));
894   EXPECT_TRUE(!!ResultA);
895   InterfaceFile FileA = std::move(*ResultA.get());
896   Expected<TBDFile> ResultB =
897       TextAPIReader::get(MemoryBufferRef(TBDv3File, "TestB.tbd"));
898   EXPECT_TRUE(!!ResultB);
899   InterfaceFile FileB = std::move(*ResultB.get());
900 
901   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
902     File->addTarget(Target(AK_x86_64, PLATFORM_IOS));
903   }));
904   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
905     File->setCurrentVersion(PackedVersion(1, 2, 3));
906     File->setCompatibilityVersion(PackedVersion(1, 0, 0));
907   }));
908   EXPECT_TRUE(checkEqualityOnTransform(
909       FileA, FileB, [](InterfaceFile *File) { File->setSwiftABIVersion(5); }));
910   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
911     File->setTwoLevelNamespace(false);
912   }));
913   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
914     File->setApplicationExtensionSafe(false);
915   }));
916   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
917     File->addParentUmbrella(Target(AK_armv7, PLATFORM_IOS), "Umbrella.dylib");
918   }));
919   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
920     File->addAllowableClient("ClientA", Target(AK_armv7, PLATFORM_IOS));
921   }));
922   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
923     File->addReexportedLibrary("/System/Library/Frameworks/A.framework/A",
924                                Target(AK_armv7, PLATFORM_IOS));
925   }));
926   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
927     File->addSymbol(EncodeKind::GlobalSymbol, "_symA",
928                     {Target(AK_arm64, PLATFORM_IOS)});
929   }));
930   EXPECT_TRUE(checkEqualityOnTransform(FileA, FileB, [](InterfaceFile *File) {
931     InterfaceFile Document;
932     Document.setFileType(FileType::TBD_V3);
933     Document.addTargets(TargetList{Target(AK_armv7, PLATFORM_IOS),
934                                    Target(AK_arm64, PLATFORM_IOS)});
935     Document.setInstallName("/System/Library/Frameworks/A.framework/A");
936     File->addDocument(std::make_shared<InterfaceFile>(std::move(Document)));
937   }));
938 }
939 
940 } // namespace TBDv3
941