xref: /llvm-project/llvm/unittests/TextAPI/TextStubV4Tests.cpp (revision f9d8162b573df0765b22927da779537b132365c9)
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 #include "llvm/TextAPI/MachO/InterfaceFile.h"
9 #include "llvm/TextAPI/MachO/TextAPIReader.h"
10 #include "llvm/TextAPI/MachO/TextAPIWriter.h"
11 #include "gtest/gtest.h"
12 #include <string>
13 #include <vector>
14 
15 using namespace llvm;
16 using namespace llvm::MachO;
17 
18 struct ExampleSymbol {
19   SymbolKind Kind;
20   std::string Name;
21   bool WeakDefined;
22   bool ThreadLocalValue;
23 };
24 using ExampleSymbolSeq = std::vector<ExampleSymbol>;
25 using UUIDs = std::vector<std::pair<Target, std::string>>;
26 
27 inline bool operator<(const ExampleSymbol &LHS, const ExampleSymbol &RHS) {
28   return std::tie(LHS.Kind, LHS.Name) < std::tie(RHS.Kind, RHS.Name);
29 }
30 
31 inline bool operator==(const ExampleSymbol &LHS, const ExampleSymbol &RHS) {
32   return std::tie(LHS.Kind, LHS.Name, LHS.WeakDefined, LHS.ThreadLocalValue) ==
33          std::tie(RHS.Kind, RHS.Name, RHS.WeakDefined, RHS.ThreadLocalValue);
34 }
35 
36 static ExampleSymbol TBDv4ExportedSymbols[] = {
37     {SymbolKind::GlobalSymbol, "_symA", false, false},
38     {SymbolKind::GlobalSymbol, "_symAB", false, false},
39     {SymbolKind::GlobalSymbol, "_symB", false, false},
40 };
41 
42 static ExampleSymbol TBDv4ReexportedSymbols[] = {
43     {SymbolKind::GlobalSymbol, "_symC", false, false},
44 };
45 
46 static ExampleSymbol TBDv4UndefinedSymbols[] = {
47     {SymbolKind::GlobalSymbol, "_symD", false, false},
48 };
49 
50 namespace TBDv4 {
51 
52 TEST(TBDv4, ReadFile) {
53   static const char tbd_v4_file[] =
54       "--- !tapi-tbd\n"
55       "tbd-version: 4\n"
56       "targets:  [ i386-macos, x86_64-macos, x86_64-ios ]\n"
57       "uuids:\n"
58       "  - target: i386-macos\n"
59       "    value: 00000000-0000-0000-0000-000000000000\n"
60       "  - target: x86_64-macos\n"
61       "    value: 11111111-1111-1111-1111-111111111111\n"
62       "  - target: x86_64-ios\n"
63       "    value: 11111111-1111-1111-1111-111111111111\n"
64       "flags: [ flat_namespace, installapi ]\n"
65       "install-name: Umbrella.framework/Umbrella\n"
66       "current-version: 1.2.3\n"
67       "compatibility-version: 1.2\n"
68       "swift-abi-version: 5\n"
69       "parent-umbrella:\n"
70       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
71       "    umbrella: System\n"
72       "allowable-clients:\n"
73       "  - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
74       "    clients: [ ClientA ]\n"
75       "reexported-libraries:\n"
76       "  - targets: [ i386-macos ]\n"
77       "    libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
78       "exports:\n"
79       "  - targets: [ i386-macos ]\n"
80       "    symbols: [ _symA ]\n"
81       "    objc-classes: []\n"
82       "    objc-eh-types: []\n"
83       "    objc-ivars: []\n"
84       "    weak-symbols: []\n"
85       "    thread-local-symbols: []\n"
86       "  - targets: [ x86_64-ios ]\n"
87       "    symbols: [_symB]\n"
88       "  - targets: [ x86_64-macos, x86_64-ios ]\n"
89       "    symbols: [_symAB]\n"
90       "reexports:\n"
91       "  - targets: [ i386-macos ]\n"
92       "    symbols: [_symC]\n"
93       "    objc-classes: []\n"
94       "    objc-eh-types: []\n"
95       "    objc-ivars: []\n"
96       "    weak-symbols: []\n"
97       "    thread-local-symbols: []\n"
98       "undefineds:\n"
99       "  - targets: [ i386-macos ]\n"
100       "    symbols: [ _symD ]\n"
101       "    objc-classes: []\n"
102       "    objc-eh-types: []\n"
103       "    objc-ivars: []\n"
104       "    weak-symbols: []\n"
105       "    thread-local-symbols: []\n"
106       "...\n";
107 
108   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v4_file, "Test.tbd"));
109   EXPECT_TRUE(!!Result);
110   auto File = std::move(Result.get());
111   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
112   PlatformSet Platforms;
113   Platforms.insert(PlatformKind::macOS);
114   Platforms.insert(PlatformKind::iOS);
115   auto Archs = AK_i386 | AK_x86_64;
116   TargetList Targets = {
117       Target(AK_i386, PlatformKind::macOS),
118       Target(AK_x86_64, PlatformKind::macOS),
119       Target(AK_x86_64, PlatformKind::iOS),
120   };
121   UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
122                  {Targets[1], "11111111-1111-1111-1111-111111111111"},
123                  {Targets[2], "11111111-1111-1111-1111-111111111111"}};
124   EXPECT_EQ(Archs, File->getArchitectures());
125   EXPECT_EQ(uuids, File->uuids());
126   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
127   for (auto Platform : File->getPlatforms())
128     EXPECT_EQ(Platforms.count(Platform), 1U);
129   EXPECT_EQ(std::string("Umbrella.framework/Umbrella"), File->getInstallName());
130   EXPECT_EQ(PackedVersion(1, 2, 3), File->getCurrentVersion());
131   EXPECT_EQ(PackedVersion(1, 2, 0), File->getCompatibilityVersion());
132   EXPECT_EQ(5U, File->getSwiftABIVersion());
133   EXPECT_FALSE(File->isTwoLevelNamespace());
134   EXPECT_TRUE(File->isApplicationExtensionSafe());
135   EXPECT_TRUE(File->isInstallAPI());
136   InterfaceFileRef client("ClientA", Targets);
137   InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
138                             {Targets[0]});
139   EXPECT_EQ(1U, File->allowableClients().size());
140   EXPECT_EQ(client, File->allowableClients().front());
141   EXPECT_EQ(1U, File->reexportedLibraries().size());
142   EXPECT_EQ(reexport, File->reexportedLibraries().front());
143 
144   ExampleSymbolSeq Exports, Reexports, Undefineds;
145   ExampleSymbol temp;
146   for (const auto *Sym : File->symbols()) {
147     temp = ExampleSymbol{Sym->getKind(), Sym->getName(), Sym->isWeakDefined(),
148                          Sym->isThreadLocalValue()};
149     EXPECT_FALSE(Sym->isWeakReferenced());
150     if (Sym->isUndefined())
151       Undefineds.emplace_back(std::move(temp));
152     else
153       Sym->isReexported() ? Reexports.emplace_back(std::move(temp))
154                           : Exports.emplace_back(std::move(temp));
155   }
156   llvm::sort(Exports.begin(), Exports.end());
157   llvm::sort(Reexports.begin(), Reexports.end());
158   llvm::sort(Undefineds.begin(), Undefineds.end());
159 
160   EXPECT_EQ(sizeof(TBDv4ExportedSymbols) / sizeof(ExampleSymbol),
161             Exports.size());
162   EXPECT_EQ(sizeof(TBDv4ReexportedSymbols) / sizeof(ExampleSymbol),
163             Reexports.size());
164   EXPECT_EQ(sizeof(TBDv4UndefinedSymbols) / sizeof(ExampleSymbol),
165             Undefineds.size());
166   EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
167                          std::begin(TBDv4ExportedSymbols)));
168   EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
169                          std::begin(TBDv4ReexportedSymbols)));
170   EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
171                          std::begin(TBDv4UndefinedSymbols)));
172 }
173 
174 TEST(TBDv4, WriteFile) {
175   static const char tbd_v4_file[] =
176       "--- !tapi-tbd\n"
177       "tbd-version:     4\n"
178       "targets:         [ i386-macos, x86_64-ios-simulator ]\n"
179       "uuids:\n"
180       "  - target:          i386-macos\n"
181       "    value:           00000000-0000-0000-0000-000000000000\n"
182       "  - target:          x86_64-ios-simulator\n"
183       "    value:           11111111-1111-1111-1111-111111111111\n"
184       "flags:           [ installapi ]\n"
185       "install-name:    'Umbrella.framework/Umbrella'\n"
186       "current-version: 1.2.3\n"
187       "compatibility-version: 0\n"
188       "swift-abi-version: 5\n"
189       "parent-umbrella:\n"
190       "  - targets:         [ i386-macos, x86_64-ios-simulator ]\n"
191       "    umbrella:        System\n"
192       "allowable-clients:\n"
193       "  - targets:         [ i386-macos ]\n"
194       "    clients:         [ ClientA ]\n"
195       "exports:\n"
196       "  - targets:         [ i386-macos ]\n"
197       "    symbols:         [ _symA ]\n"
198       "    objc-classes:    [ Class1 ]\n"
199       "    weak-symbols:    [ _symC ]\n"
200       "  - targets:         [ x86_64-ios-simulator ]\n"
201       "    symbols:         [ _symB ]\n"
202       "...\n";
203 
204   InterfaceFile File;
205   TargetList Targets = {
206       Target(AK_i386, PlatformKind::macOS),
207       Target(AK_x86_64, PlatformKind::iOSSimulator),
208   };
209   UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
210                  {Targets[1], "11111111-1111-1111-1111-111111111111"}};
211   File.setInstallName("Umbrella.framework/Umbrella");
212   File.setFileType(FileType::TBD_V4);
213   File.addTargets(Targets);
214   File.addUUID(uuids[0].first, uuids[0].second);
215   File.addUUID(uuids[1].first, uuids[1].second);
216   File.setCurrentVersion(PackedVersion(1, 2, 3));
217   File.setTwoLevelNamespace();
218   File.setInstallAPI(true);
219   File.setApplicationExtensionSafe(true);
220   File.setSwiftABIVersion(5);
221   File.addAllowableClient("ClientA", Targets[0]);
222   File.addParentUmbrella(Targets[0], "System");
223   File.addParentUmbrella(Targets[1], "System");
224   File.addSymbol(SymbolKind::GlobalSymbol, "_symA", {Targets[0]});
225   File.addSymbol(SymbolKind::GlobalSymbol, "_symB", {Targets[1]});
226   File.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
227                  SymbolFlags::WeakDefined);
228   File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[0]});
229 
230   SmallString<4096> Buffer;
231   raw_svector_ostream OS(Buffer);
232   auto Result = TextAPIWriter::writeToStream(OS, File);
233   EXPECT_FALSE(Result);
234   EXPECT_STREQ(tbd_v4_file, Buffer.c_str());
235 }
236 
237 TEST(TBDv4, MultipleTargets) {
238   static const char tbd_multiple_targets[] =
239       "--- !tapi-tbd\n"
240       "tbd-version: 4\n"
241       "targets: [ i386-maccatalyst, x86_64-tvos, arm64-ios ]\n"
242       "install-name: Test.dylib\n"
243       "...\n";
244 
245   auto Result =
246       TextAPIReader::get(MemoryBufferRef(tbd_multiple_targets, "Test.tbd"));
247   EXPECT_TRUE(!!Result);
248   PlatformSet Platforms;
249   Platforms.insert(PlatformKind::macCatalyst);
250   Platforms.insert(PlatformKind::tvOS);
251   Platforms.insert(PlatformKind::iOS);
252   auto File = std::move(Result.get());
253   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
254   EXPECT_EQ(AK_x86_64 | AK_arm64 | AK_i386, File->getArchitectures());
255   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
256   for (auto Platform : File->getPlatforms())
257     EXPECT_EQ(Platforms.count(Platform), 1U);
258 }
259 
260 TEST(TBDv4, MultipleTargetsSameArch) {
261   static const char tbd_targets_same_arch[] =
262       "--- !tapi-tbd\n"
263       "tbd-version: 4\n"
264       "targets: [ x86_64-maccatalyst, x86_64-tvos ]\n"
265       "install-name: Test.dylib\n"
266       "...\n";
267 
268   auto Result =
269       TextAPIReader::get(MemoryBufferRef(tbd_targets_same_arch, "Test.tbd"));
270   EXPECT_TRUE(!!Result);
271   PlatformSet Platforms;
272   Platforms.insert(PlatformKind::tvOS);
273   Platforms.insert(PlatformKind::macCatalyst);
274   auto File = std::move(Result.get());
275   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
276   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
277   EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
278   for (auto Platform : File->getPlatforms())
279     EXPECT_EQ(Platforms.count(Platform), 1U);
280 }
281 
282 TEST(TBDv4, MultipleTargetsSamePlatform) {
283   static const char tbd_multiple_targets_same_platform[] =
284       "--- !tapi-tbd\n"
285       "tbd-version: 4\n"
286       "targets: [ arm64-ios, armv7k-ios ]\n"
287       "install-name: Test.dylib\n"
288       "...\n";
289 
290   auto Result = TextAPIReader::get(
291       MemoryBufferRef(tbd_multiple_targets_same_platform, "Test.tbd"));
292   EXPECT_TRUE(!!Result);
293   auto File = std::move(Result.get());
294   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
295   EXPECT_EQ(AK_arm64 | AK_armv7k, File->getArchitectures());
296   EXPECT_EQ(File->getPlatforms().size(), 1U);
297   EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin());
298 }
299 
300 TEST(TBDv4, Target_maccatalyst) {
301   static const char tbd_target_maccatalyst[] =
302       "--- !tapi-tbd\n"
303       "tbd-version: 4\n"
304       "targets: [  x86_64-maccatalyst ]\n"
305       "install-name: Test.dylib\n"
306       "...\n";
307 
308   auto Result =
309       TextAPIReader::get(MemoryBufferRef(tbd_target_maccatalyst, "Test.tbd"));
310   EXPECT_TRUE(!!Result);
311   auto File = std::move(Result.get());
312   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
313   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
314   EXPECT_EQ(File->getPlatforms().size(), 1U);
315   EXPECT_EQ(PlatformKind::macCatalyst, *File->getPlatforms().begin());
316 }
317 
318 TEST(TBDv4, Target_x86_ios) {
319   static const char tbd_target_x86_ios[] = "--- !tapi-tbd\n"
320                                            "tbd-version: 4\n"
321                                            "targets: [  x86_64-ios ]\n"
322                                            "install-name: Test.dylib\n"
323                                            "...\n";
324 
325   auto Result =
326       TextAPIReader::get(MemoryBufferRef(tbd_target_x86_ios, "Test.tbd"));
327   EXPECT_TRUE(!!Result);
328   auto File = std::move(Result.get());
329   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
330   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
331   EXPECT_EQ(File->getPlatforms().size(), 1U);
332   EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin());
333 }
334 
335 TEST(TBDv4, Target_arm_bridgeOS) {
336   static const char tbd_platform_bridgeos[] = "--- !tapi-tbd\n"
337                                               "tbd-version: 4\n"
338                                               "targets: [  armv7k-bridgeos ]\n"
339                                               "install-name: Test.dylib\n"
340                                               "...\n";
341 
342   auto Result =
343       TextAPIReader::get(MemoryBufferRef(tbd_platform_bridgeos, "Test.tbd"));
344   EXPECT_TRUE(!!Result);
345   auto File = std::move(Result.get());
346   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
347   EXPECT_EQ(File->getPlatforms().size(), 1U);
348   EXPECT_EQ(PlatformKind::bridgeOS, *File->getPlatforms().begin());
349   EXPECT_EQ(ArchitectureSet(AK_armv7k), File->getArchitectures());
350 }
351 
352 TEST(TBDv4, Target_x86_macos) {
353   static const char tbd_x86_macos[] = "--- !tapi-tbd\n"
354                                       "tbd-version: 4\n"
355                                       "targets: [  x86_64-macos ]\n"
356                                       "install-name: Test.dylib\n"
357                                       "...\n";
358 
359   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_x86_macos, "Test.tbd"));
360   EXPECT_TRUE(!!Result);
361   auto File = std::move(Result.get());
362   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
363   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
364   EXPECT_EQ(File->getPlatforms().size(), 1U);
365   EXPECT_EQ(PlatformKind::macOS, *File->getPlatforms().begin());
366 }
367 
368 TEST(TBDv4, Target_x86_ios_simulator) {
369   static const char tbd_x86_ios_sim[] = "--- !tapi-tbd\n"
370                                         "tbd-version: 4\n"
371                                         "targets: [  x86_64-ios-simulator  ]\n"
372                                         "install-name: Test.dylib\n"
373                                         "...\n";
374 
375   auto Result =
376       TextAPIReader::get(MemoryBufferRef(tbd_x86_ios_sim, "Test.tbd"));
377   EXPECT_TRUE(!!Result);
378   auto File = std::move(Result.get());
379   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
380   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
381   EXPECT_EQ(File->getPlatforms().size(), 1U);
382   EXPECT_EQ(PlatformKind::iOSSimulator, *File->getPlatforms().begin());
383 }
384 
385 TEST(TBDv4, Target_x86_tvos_simulator) {
386   static const char tbd_x86_tvos_sim[] =
387       "--- !tapi-tbd\n"
388       "tbd-version: 4\n"
389       "targets: [  x86_64-tvos-simulator  ]\n"
390       "install-name: Test.dylib\n"
391       "...\n";
392 
393   auto Result =
394       TextAPIReader::get(MemoryBufferRef(tbd_x86_tvos_sim, "Test.tbd"));
395   EXPECT_TRUE(!!Result);
396   auto File = std::move(Result.get());
397   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
398   EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
399   EXPECT_EQ(File->getPlatforms().size(), 1U);
400   EXPECT_EQ(PlatformKind::tvOSSimulator, *File->getPlatforms().begin());
401 }
402 
403 TEST(TBDv4, Target_i386_watchos_simulator) {
404   static const char tbd_i386_watchos_sim[] =
405       "--- !tapi-tbd\n"
406       "tbd-version: 4\n"
407       "targets: [  i386-watchos-simulator  ]\n"
408       "install-name: Test.dylib\n"
409       "...\n";
410 
411   auto Result =
412       TextAPIReader::get(MemoryBufferRef(tbd_i386_watchos_sim, "Test.tbd"));
413   EXPECT_TRUE(!!Result);
414   auto File = std::move(Result.get());
415   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
416   EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures());
417   EXPECT_EQ(File->getPlatforms().size(), 1U);
418   EXPECT_EQ(PlatformKind::watchOSSimulator, *File->getPlatforms().begin());
419 }
420 
421 TEST(TBDv4, Swift_1) {
422   static const char tbd_swift_1[] = "--- !tapi-tbd\n"
423                                     "tbd-version: 4\n"
424                                     "targets: [  x86_64-macos ]\n"
425                                     "install-name: Test.dylib\n"
426                                     "swift-abi-version: 1\n"
427                                     "...\n";
428 
429   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_1, "Test.tbd"));
430   EXPECT_TRUE(!!Result);
431   auto File = std::move(Result.get());
432   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
433   EXPECT_EQ(1U, File->getSwiftABIVersion());
434 }
435 
436 TEST(TBDv4, Swift_2) {
437   static const char tbd_v1_swift_2[] = "--- !tapi-tbd\n"
438                                        "tbd-version: 4\n"
439                                        "targets: [  x86_64-macos ]\n"
440                                        "install-name: Test.dylib\n"
441                                        "swift-abi-version: 2\n"
442                                        "...\n";
443 
444   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v1_swift_2, "Test.tbd"));
445   EXPECT_TRUE(!!Result);
446   auto File = std::move(Result.get());
447   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
448   EXPECT_EQ(2U, File->getSwiftABIVersion());
449 }
450 
451 TEST(TBDv4, Swift_5) {
452   static const char tbd_swift_5[] = "--- !tapi-tbd\n"
453                                     "tbd-version: 4\n"
454                                     "targets: [  x86_64-macos ]\n"
455                                     "install-name: Test.dylib\n"
456                                     "swift-abi-version: 5\n"
457                                     "...\n";
458 
459   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_5, "Test.tbd"));
460   EXPECT_TRUE(!!Result);
461   auto File = std::move(Result.get());
462   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
463   EXPECT_EQ(5U, File->getSwiftABIVersion());
464 }
465 
466 TEST(TBDv4, Swift_99) {
467   static const char tbd_swift_99[] = "--- !tapi-tbd\n"
468                                      "tbd-version: 4\n"
469                                      "targets: [  x86_64-macos ]\n"
470                                      "install-name: Test.dylib\n"
471                                      "swift-abi-version: 99\n"
472                                      "...\n";
473 
474   auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_99, "Test.tbd"));
475   EXPECT_TRUE(!!Result);
476   auto File = std::move(Result.get());
477   EXPECT_EQ(FileType::TBD_V4, File->getFileType());
478   EXPECT_EQ(99U, File->getSwiftABIVersion());
479 }
480 
481 TEST(TBDv4, InvalidArchitecture) {
482   static const char tbd_file_unknown_architecture[] =
483       "--- !tapi-tbd\n"
484       "tbd-version: 4\n"
485       "targets: [ foo-macos ]\n"
486       "install-name: Test.dylib\n"
487       "...\n";
488 
489   auto Result = TextAPIReader::get(
490       MemoryBufferRef(tbd_file_unknown_architecture, "Test.tbd"));
491   EXPECT_FALSE(!!Result);
492   auto errorMessage = toString(Result.takeError());
493   EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown "
494             "architecture\ntargets: [ foo-macos ]\n"
495             "           ^~~~~~~~~~\n",
496             errorMessage);
497 }
498 
499 TEST(TBDv4, InvalidPlatform) {
500   static const char tbd_file_invalid_platform[] = "--- !tapi-tbd\n"
501                                                   "tbd-version: 4\n"
502                                                   "targets: [ x86_64-maos ]\n"
503                                                   "install-name: Test.dylib\n"
504                                                   "...\n";
505 
506   auto Result = TextAPIReader::get(
507       MemoryBufferRef(tbd_file_invalid_platform, "Test.tbd"));
508   EXPECT_FALSE(!!Result);
509   auto errorMessage = toString(Result.takeError());
510   EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: "
511             "[ x86_64-maos ]\n"
512             "           ^~~~~~~~~~~~\n",
513             errorMessage);
514 }
515 
516 TEST(TBDv4, MalformedFile1) {
517   static const char malformed_file1[] = "--- !tapi-tbd\n"
518                                         "tbd-version: 4\n"
519                                         "...\n";
520 
521   auto Result =
522       TextAPIReader::get(MemoryBufferRef(malformed_file1, "Test.tbd"));
523   EXPECT_FALSE(!!Result);
524   auto errorMessage = toString(Result.takeError());
525   ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
526             "'targets'\ntbd-version: 4\n^\n",
527             errorMessage);
528 }
529 
530 TEST(TBDv4, MalformedFile2) {
531   static const char malformed_file2[] = "--- !tapi-tbd\n"
532                                         "tbd-version: 4\n"
533                                         "targets: [ x86_64-macos ]\n"
534                                         "install-name: Test.dylib\n"
535                                         "foobar: \"unsupported key\"\n";
536 
537   auto Result =
538       TextAPIReader::get(MemoryBufferRef(malformed_file2, "Test.tbd"));
539   EXPECT_FALSE(!!Result);
540   auto errorMessage = toString(Result.takeError());
541   ASSERT_EQ(
542       "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
543       "\"unsupported key\"\n        ^~~~~~~~~~~~~~~~~\n",
544       errorMessage);
545 }
546 
547 TEST(TBDv4, MalformedFile3) {
548   static const char tbd_v1_swift_1_1[] = "--- !tapi-tbd\n"
549                                          "tbd-version: 4\n"
550                                          "targets: [  x86_64-macos ]\n"
551                                          "install-name: Test.dylib\n"
552                                          "swift-abi-version: 1.1\n"
553                                          "...\n";
554 
555   auto Result =
556       TextAPIReader::get(MemoryBufferRef(tbd_v1_swift_1_1, "Test.tbd"));
557   EXPECT_FALSE(!!Result);
558   auto errorMessage = toString(Result.takeError());
559   EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
560             "version.\nswift-abi-version: 1.1\n                   ^~~\n",
561             errorMessage);
562 }
563 
564 } // end namespace TBDv4
565