blob: 53e9bd9362c2f6d88faefe1f5c120b60628ab224 [file] [log] [blame]
Cyndy Ishidaf9d81622019-10-10 04:24:44 +00001//===-- 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
15using namespace llvm;
16using namespace llvm::MachO;
17
18struct ExampleSymbol {
19 SymbolKind Kind;
20 std::string Name;
21 bool WeakDefined;
22 bool ThreadLocalValue;
23};
24using ExampleSymbolSeq = std::vector<ExampleSymbol>;
25using UUIDs = std::vector<std::pair<Target, std::string>>;
26
27inline bool operator<(const ExampleSymbol &LHS, const ExampleSymbol &RHS) {
28 return std::tie(LHS.Kind, LHS.Name) < std::tie(RHS.Kind, RHS.Name);
29}
30
31inline 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
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -080036inline std::string stripWhitespace(std::string s) {
37 s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
38 return s;
39}
40
Cyndy Ishidaf9d81622019-10-10 04:24:44 +000041static ExampleSymbol TBDv4ExportedSymbols[] = {
42 {SymbolKind::GlobalSymbol, "_symA", false, false},
43 {SymbolKind::GlobalSymbol, "_symAB", false, false},
44 {SymbolKind::GlobalSymbol, "_symB", false, false},
45};
46
47static ExampleSymbol TBDv4ReexportedSymbols[] = {
48 {SymbolKind::GlobalSymbol, "_symC", false, false},
49};
50
51static ExampleSymbol TBDv4UndefinedSymbols[] = {
52 {SymbolKind::GlobalSymbol, "_symD", false, false},
53};
54
55namespace TBDv4 {
56
57TEST(TBDv4, ReadFile) {
58 static const char tbd_v4_file[] =
59 "--- !tapi-tbd\n"
60 "tbd-version: 4\n"
61 "targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
62 "uuids:\n"
63 " - target: i386-macos\n"
64 " value: 00000000-0000-0000-0000-000000000000\n"
65 " - target: x86_64-macos\n"
66 " value: 11111111-1111-1111-1111-111111111111\n"
67 " - target: x86_64-ios\n"
68 " value: 11111111-1111-1111-1111-111111111111\n"
69 "flags: [ flat_namespace, installapi ]\n"
70 "install-name: Umbrella.framework/Umbrella\n"
71 "current-version: 1.2.3\n"
72 "compatibility-version: 1.2\n"
73 "swift-abi-version: 5\n"
74 "parent-umbrella:\n"
75 " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
76 " umbrella: System\n"
77 "allowable-clients:\n"
78 " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
79 " clients: [ ClientA ]\n"
80 "reexported-libraries:\n"
81 " - targets: [ i386-macos ]\n"
82 " libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
83 "exports:\n"
84 " - targets: [ i386-macos ]\n"
85 " symbols: [ _symA ]\n"
86 " objc-classes: []\n"
87 " objc-eh-types: []\n"
88 " objc-ivars: []\n"
89 " weak-symbols: []\n"
90 " thread-local-symbols: []\n"
91 " - targets: [ x86_64-ios ]\n"
92 " symbols: [_symB]\n"
93 " - targets: [ x86_64-macos, x86_64-ios ]\n"
94 " symbols: [_symAB]\n"
95 "reexports:\n"
96 " - targets: [ i386-macos ]\n"
97 " symbols: [_symC]\n"
98 " objc-classes: []\n"
99 " objc-eh-types: []\n"
100 " objc-ivars: []\n"
101 " weak-symbols: []\n"
102 " thread-local-symbols: []\n"
103 "undefineds:\n"
104 " - targets: [ i386-macos ]\n"
105 " symbols: [ _symD ]\n"
106 " objc-classes: []\n"
107 " objc-eh-types: []\n"
108 " objc-ivars: []\n"
109 " weak-symbols: []\n"
110 " thread-local-symbols: []\n"
111 "...\n";
112
113 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v4_file, "Test.tbd"));
114 EXPECT_TRUE(!!Result);
115 auto File = std::move(Result.get());
116 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
117 PlatformSet Platforms;
118 Platforms.insert(PlatformKind::macOS);
119 Platforms.insert(PlatformKind::iOS);
120 auto Archs = AK_i386 | AK_x86_64;
121 TargetList Targets = {
122 Target(AK_i386, PlatformKind::macOS),
123 Target(AK_x86_64, PlatformKind::macOS),
124 Target(AK_x86_64, PlatformKind::iOS),
125 };
126 UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
127 {Targets[1], "11111111-1111-1111-1111-111111111111"},
128 {Targets[2], "11111111-1111-1111-1111-111111111111"}};
129 EXPECT_EQ(Archs, File->getArchitectures());
130 EXPECT_EQ(uuids, File->uuids());
131 EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
132 for (auto Platform : File->getPlatforms())
133 EXPECT_EQ(Platforms.count(Platform), 1U);
134 EXPECT_EQ(std::string("Umbrella.framework/Umbrella"), File->getInstallName());
135 EXPECT_EQ(PackedVersion(1, 2, 3), File->getCurrentVersion());
136 EXPECT_EQ(PackedVersion(1, 2, 0), File->getCompatibilityVersion());
137 EXPECT_EQ(5U, File->getSwiftABIVersion());
138 EXPECT_FALSE(File->isTwoLevelNamespace());
139 EXPECT_TRUE(File->isApplicationExtensionSafe());
140 EXPECT_TRUE(File->isInstallAPI());
141 InterfaceFileRef client("ClientA", Targets);
142 InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
143 {Targets[0]});
144 EXPECT_EQ(1U, File->allowableClients().size());
145 EXPECT_EQ(client, File->allowableClients().front());
146 EXPECT_EQ(1U, File->reexportedLibraries().size());
147 EXPECT_EQ(reexport, File->reexportedLibraries().front());
148
149 ExampleSymbolSeq Exports, Reexports, Undefineds;
150 ExampleSymbol temp;
151 for (const auto *Sym : File->symbols()) {
Benjamin Krameradcd0262020-01-28 20:23:46 +0100152 temp = ExampleSymbol{Sym->getKind(), std::string(Sym->getName()),
153 Sym->isWeakDefined(), Sym->isThreadLocalValue()};
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000154 EXPECT_FALSE(Sym->isWeakReferenced());
155 if (Sym->isUndefined())
156 Undefineds.emplace_back(std::move(temp));
157 else
158 Sym->isReexported() ? Reexports.emplace_back(std::move(temp))
159 : Exports.emplace_back(std::move(temp));
160 }
161 llvm::sort(Exports.begin(), Exports.end());
162 llvm::sort(Reexports.begin(), Reexports.end());
163 llvm::sort(Undefineds.begin(), Undefineds.end());
164
165 EXPECT_EQ(sizeof(TBDv4ExportedSymbols) / sizeof(ExampleSymbol),
166 Exports.size());
167 EXPECT_EQ(sizeof(TBDv4ReexportedSymbols) / sizeof(ExampleSymbol),
168 Reexports.size());
169 EXPECT_EQ(sizeof(TBDv4UndefinedSymbols) / sizeof(ExampleSymbol),
170 Undefineds.size());
171 EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
172 std::begin(TBDv4ExportedSymbols)));
173 EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
174 std::begin(TBDv4ReexportedSymbols)));
175 EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
176 std::begin(TBDv4UndefinedSymbols)));
177}
178
179TEST(TBDv4, WriteFile) {
180 static const char tbd_v4_file[] =
181 "--- !tapi-tbd\n"
182 "tbd-version: 4\n"
183 "targets: [ i386-macos, x86_64-ios-simulator ]\n"
184 "uuids:\n"
185 " - target: i386-macos\n"
186 " value: 00000000-0000-0000-0000-000000000000\n"
187 " - target: x86_64-ios-simulator\n"
188 " value: 11111111-1111-1111-1111-111111111111\n"
189 "flags: [ installapi ]\n"
190 "install-name: 'Umbrella.framework/Umbrella'\n"
191 "current-version: 1.2.3\n"
192 "compatibility-version: 0\n"
193 "swift-abi-version: 5\n"
194 "parent-umbrella:\n"
195 " - targets: [ i386-macos, x86_64-ios-simulator ]\n"
196 " umbrella: System\n"
197 "allowable-clients:\n"
198 " - targets: [ i386-macos ]\n"
199 " clients: [ ClientA ]\n"
200 "exports:\n"
201 " - targets: [ i386-macos ]\n"
202 " symbols: [ _symA ]\n"
203 " objc-classes: [ Class1 ]\n"
204 " weak-symbols: [ _symC ]\n"
205 " - targets: [ x86_64-ios-simulator ]\n"
206 " symbols: [ _symB ]\n"
207 "...\n";
208
209 InterfaceFile File;
210 TargetList Targets = {
211 Target(AK_i386, PlatformKind::macOS),
212 Target(AK_x86_64, PlatformKind::iOSSimulator),
213 };
214 UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
215 {Targets[1], "11111111-1111-1111-1111-111111111111"}};
216 File.setInstallName("Umbrella.framework/Umbrella");
217 File.setFileType(FileType::TBD_V4);
218 File.addTargets(Targets);
219 File.addUUID(uuids[0].first, uuids[0].second);
220 File.addUUID(uuids[1].first, uuids[1].second);
221 File.setCurrentVersion(PackedVersion(1, 2, 3));
222 File.setTwoLevelNamespace();
223 File.setInstallAPI(true);
224 File.setApplicationExtensionSafe(true);
225 File.setSwiftABIVersion(5);
226 File.addAllowableClient("ClientA", Targets[0]);
227 File.addParentUmbrella(Targets[0], "System");
228 File.addParentUmbrella(Targets[1], "System");
229 File.addSymbol(SymbolKind::GlobalSymbol, "_symA", {Targets[0]});
230 File.addSymbol(SymbolKind::GlobalSymbol, "_symB", {Targets[1]});
231 File.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
232 SymbolFlags::WeakDefined);
233 File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[0]});
234
235 SmallString<4096> Buffer;
236 raw_svector_ostream OS(Buffer);
237 auto Result = TextAPIWriter::writeToStream(OS, File);
238 EXPECT_FALSE(Result);
239 EXPECT_STREQ(tbd_v4_file, Buffer.c_str());
240}
241
242TEST(TBDv4, MultipleTargets) {
243 static const char tbd_multiple_targets[] =
244 "--- !tapi-tbd\n"
245 "tbd-version: 4\n"
246 "targets: [ i386-maccatalyst, x86_64-tvos, arm64-ios ]\n"
247 "install-name: Test.dylib\n"
248 "...\n";
249
250 auto Result =
251 TextAPIReader::get(MemoryBufferRef(tbd_multiple_targets, "Test.tbd"));
252 EXPECT_TRUE(!!Result);
253 PlatformSet Platforms;
254 Platforms.insert(PlatformKind::macCatalyst);
255 Platforms.insert(PlatformKind::tvOS);
256 Platforms.insert(PlatformKind::iOS);
257 auto File = std::move(Result.get());
258 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
259 EXPECT_EQ(AK_x86_64 | AK_arm64 | AK_i386, File->getArchitectures());
260 EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
261 for (auto Platform : File->getPlatforms())
262 EXPECT_EQ(Platforms.count(Platform), 1U);
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800263
264 SmallString<4096> Buffer;
265 raw_svector_ostream OS(Buffer);
266 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
267 EXPECT_TRUE(!WriteResult);
268 EXPECT_EQ(stripWhitespace(tbd_multiple_targets),
269 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000270}
271
272TEST(TBDv4, MultipleTargetsSameArch) {
273 static const char tbd_targets_same_arch[] =
274 "--- !tapi-tbd\n"
275 "tbd-version: 4\n"
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800276 "targets: [ x86_64-tvos , x86_64-maccatalyst ]\n"
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000277 "install-name: Test.dylib\n"
278 "...\n";
279
280 auto Result =
281 TextAPIReader::get(MemoryBufferRef(tbd_targets_same_arch, "Test.tbd"));
282 EXPECT_TRUE(!!Result);
283 PlatformSet Platforms;
284 Platforms.insert(PlatformKind::tvOS);
285 Platforms.insert(PlatformKind::macCatalyst);
286 auto File = std::move(Result.get());
287 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
288 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
289 EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
290 for (auto Platform : File->getPlatforms())
291 EXPECT_EQ(Platforms.count(Platform), 1U);
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800292
293 SmallString<4096> Buffer;
294 raw_svector_ostream OS(Buffer);
295 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
296 EXPECT_TRUE(!WriteResult);
297 EXPECT_EQ(stripWhitespace(tbd_targets_same_arch),
298 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000299}
300
301TEST(TBDv4, MultipleTargetsSamePlatform) {
302 static const char tbd_multiple_targets_same_platform[] =
303 "--- !tapi-tbd\n"
304 "tbd-version: 4\n"
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800305 "targets: [ armv7k-ios , arm64-ios]\n"
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000306 "install-name: Test.dylib\n"
307 "...\n";
308
309 auto Result = TextAPIReader::get(
310 MemoryBufferRef(tbd_multiple_targets_same_platform, "Test.tbd"));
311 EXPECT_TRUE(!!Result);
312 auto File = std::move(Result.get());
313 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
314 EXPECT_EQ(AK_arm64 | AK_armv7k, File->getArchitectures());
315 EXPECT_EQ(File->getPlatforms().size(), 1U);
316 EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800317
318 SmallString<4096> Buffer;
319 raw_svector_ostream OS(Buffer);
320 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
321 EXPECT_TRUE(!WriteResult);
322 EXPECT_EQ(stripWhitespace(tbd_multiple_targets_same_platform),
323 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000324}
325
326TEST(TBDv4, Target_maccatalyst) {
327 static const char tbd_target_maccatalyst[] =
328 "--- !tapi-tbd\n"
329 "tbd-version: 4\n"
330 "targets: [ x86_64-maccatalyst ]\n"
331 "install-name: Test.dylib\n"
332 "...\n";
333
334 auto Result =
335 TextAPIReader::get(MemoryBufferRef(tbd_target_maccatalyst, "Test.tbd"));
336 EXPECT_TRUE(!!Result);
337 auto File = std::move(Result.get());
338 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
339 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
340 EXPECT_EQ(File->getPlatforms().size(), 1U);
341 EXPECT_EQ(PlatformKind::macCatalyst, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800342
343 SmallString<4096> Buffer;
344 raw_svector_ostream OS(Buffer);
345 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
346 EXPECT_TRUE(!WriteResult);
347 EXPECT_EQ(stripWhitespace(tbd_target_maccatalyst),
348 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000349}
350
351TEST(TBDv4, Target_x86_ios) {
352 static const char tbd_target_x86_ios[] = "--- !tapi-tbd\n"
353 "tbd-version: 4\n"
354 "targets: [ x86_64-ios ]\n"
355 "install-name: Test.dylib\n"
356 "...\n";
357
358 auto Result =
359 TextAPIReader::get(MemoryBufferRef(tbd_target_x86_ios, "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::iOS, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800366
367 SmallString<4096> Buffer;
368 raw_svector_ostream OS(Buffer);
369 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
370 EXPECT_TRUE(!WriteResult);
371 EXPECT_EQ(stripWhitespace(tbd_target_x86_ios),
372 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000373}
374
375TEST(TBDv4, Target_arm_bridgeOS) {
376 static const char tbd_platform_bridgeos[] = "--- !tapi-tbd\n"
377 "tbd-version: 4\n"
378 "targets: [ armv7k-bridgeos ]\n"
379 "install-name: Test.dylib\n"
380 "...\n";
381
382 auto Result =
383 TextAPIReader::get(MemoryBufferRef(tbd_platform_bridgeos, "Test.tbd"));
384 EXPECT_TRUE(!!Result);
385 auto File = std::move(Result.get());
386 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
387 EXPECT_EQ(File->getPlatforms().size(), 1U);
388 EXPECT_EQ(PlatformKind::bridgeOS, *File->getPlatforms().begin());
389 EXPECT_EQ(ArchitectureSet(AK_armv7k), File->getArchitectures());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800390
391 SmallString<4096> Buffer;
392 raw_svector_ostream OS(Buffer);
393 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
394 EXPECT_TRUE(!WriteResult);
395 EXPECT_EQ(stripWhitespace(tbd_platform_bridgeos),
396 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000397}
398
399TEST(TBDv4, Target_x86_macos) {
400 static const char tbd_x86_macos[] = "--- !tapi-tbd\n"
401 "tbd-version: 4\n"
402 "targets: [ x86_64-macos ]\n"
403 "install-name: Test.dylib\n"
404 "...\n";
405
406 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_x86_macos, "Test.tbd"));
407 EXPECT_TRUE(!!Result);
408 auto File = std::move(Result.get());
409 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
410 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
411 EXPECT_EQ(File->getPlatforms().size(), 1U);
412 EXPECT_EQ(PlatformKind::macOS, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800413
414 SmallString<4096> Buffer;
415 raw_svector_ostream OS(Buffer);
416 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
417 EXPECT_TRUE(!WriteResult);
418 EXPECT_EQ(stripWhitespace(tbd_x86_macos), stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000419}
420
421TEST(TBDv4, Target_x86_ios_simulator) {
422 static const char tbd_x86_ios_sim[] = "--- !tapi-tbd\n"
423 "tbd-version: 4\n"
424 "targets: [ x86_64-ios-simulator ]\n"
425 "install-name: Test.dylib\n"
426 "...\n";
427
428 auto Result =
429 TextAPIReader::get(MemoryBufferRef(tbd_x86_ios_sim, "Test.tbd"));
430 EXPECT_TRUE(!!Result);
431 auto File = std::move(Result.get());
432 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
433 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
434 EXPECT_EQ(File->getPlatforms().size(), 1U);
435 EXPECT_EQ(PlatformKind::iOSSimulator, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800436
437 SmallString<4096> Buffer;
438 raw_svector_ostream OS(Buffer);
439 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
440 EXPECT_TRUE(!WriteResult);
441 EXPECT_EQ(stripWhitespace(tbd_x86_ios_sim), stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000442}
443
444TEST(TBDv4, Target_x86_tvos_simulator) {
445 static const char tbd_x86_tvos_sim[] =
446 "--- !tapi-tbd\n"
447 "tbd-version: 4\n"
448 "targets: [ x86_64-tvos-simulator ]\n"
449 "install-name: Test.dylib\n"
450 "...\n";
451
452 auto Result =
453 TextAPIReader::get(MemoryBufferRef(tbd_x86_tvos_sim, "Test.tbd"));
454 EXPECT_TRUE(!!Result);
455 auto File = std::move(Result.get());
456 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
457 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
458 EXPECT_EQ(File->getPlatforms().size(), 1U);
459 EXPECT_EQ(PlatformKind::tvOSSimulator, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800460
461 SmallString<4096> Buffer;
462 raw_svector_ostream OS(Buffer);
463 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
464 EXPECT_TRUE(!WriteResult);
465 EXPECT_EQ(stripWhitespace(tbd_x86_tvos_sim), stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000466}
467
468TEST(TBDv4, Target_i386_watchos_simulator) {
469 static const char tbd_i386_watchos_sim[] =
470 "--- !tapi-tbd\n"
471 "tbd-version: 4\n"
472 "targets: [ i386-watchos-simulator ]\n"
473 "install-name: Test.dylib\n"
474 "...\n";
475
476 auto Result =
477 TextAPIReader::get(MemoryBufferRef(tbd_i386_watchos_sim, "Test.tbd"));
478 EXPECT_TRUE(!!Result);
479 auto File = std::move(Result.get());
480 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
481 EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures());
482 EXPECT_EQ(File->getPlatforms().size(), 1U);
483 EXPECT_EQ(PlatformKind::watchOSSimulator, *File->getPlatforms().begin());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800484
485 SmallString<4096> Buffer;
486 raw_svector_ostream OS(Buffer);
487 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
488 EXPECT_TRUE(!WriteResult);
489 EXPECT_EQ(stripWhitespace(tbd_i386_watchos_sim),
490 stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000491}
492
493TEST(TBDv4, Swift_1) {
494 static const char tbd_swift_1[] = "--- !tapi-tbd\n"
495 "tbd-version: 4\n"
496 "targets: [ x86_64-macos ]\n"
497 "install-name: Test.dylib\n"
498 "swift-abi-version: 1\n"
499 "...\n";
500
501 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_1, "Test.tbd"));
502 EXPECT_TRUE(!!Result);
503 auto File = std::move(Result.get());
504 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
505 EXPECT_EQ(1U, File->getSwiftABIVersion());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800506
507 // No writer test because we emit "swift-abi-version:1.0".
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000508}
509
510TEST(TBDv4, Swift_2) {
Jonas Devlieghereb14937c2020-01-23 22:48:29 -0800511 static const char tbd_v4_swift_2[] = "--- !tapi-tbd\n"
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000512 "tbd-version: 4\n"
513 "targets: [ x86_64-macos ]\n"
514 "install-name: Test.dylib\n"
515 "swift-abi-version: 2\n"
516 "...\n";
517
Jonas Devlieghereb14937c2020-01-23 22:48:29 -0800518 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v4_swift_2, "Test.tbd"));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000519 EXPECT_TRUE(!!Result);
520 auto File = std::move(Result.get());
521 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
522 EXPECT_EQ(2U, File->getSwiftABIVersion());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800523
524 // No writer test because we emit "swift-abi-version:2.0".
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000525}
526
527TEST(TBDv4, Swift_5) {
528 static const char tbd_swift_5[] = "--- !tapi-tbd\n"
529 "tbd-version: 4\n"
530 "targets: [ x86_64-macos ]\n"
531 "install-name: Test.dylib\n"
532 "swift-abi-version: 5\n"
533 "...\n";
534
535 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_5, "Test.tbd"));
536 EXPECT_TRUE(!!Result);
537 auto File = std::move(Result.get());
538 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
539 EXPECT_EQ(5U, File->getSwiftABIVersion());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800540
541 SmallString<4096> Buffer;
542 raw_svector_ostream OS(Buffer);
543 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
544 EXPECT_TRUE(!WriteResult);
545 EXPECT_EQ(stripWhitespace(tbd_swift_5), stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000546}
547
548TEST(TBDv4, Swift_99) {
549 static const char tbd_swift_99[] = "--- !tapi-tbd\n"
550 "tbd-version: 4\n"
551 "targets: [ x86_64-macos ]\n"
552 "install-name: Test.dylib\n"
553 "swift-abi-version: 99\n"
554 "...\n";
555
556 auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_99, "Test.tbd"));
557 EXPECT_TRUE(!!Result);
558 auto File = std::move(Result.get());
559 EXPECT_EQ(FileType::TBD_V4, File->getFileType());
560 EXPECT_EQ(99U, File->getSwiftABIVersion());
Jonas Devliegherec6e8bfe72020-02-13 12:47:40 -0800561
562 SmallString<4096> Buffer;
563 raw_svector_ostream OS(Buffer);
564 auto WriteResult = TextAPIWriter::writeToStream(OS, *File);
565 EXPECT_TRUE(!WriteResult);
566 EXPECT_EQ(stripWhitespace(tbd_swift_99), stripWhitespace(Buffer.c_str()));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000567}
568
569TEST(TBDv4, InvalidArchitecture) {
570 static const char tbd_file_unknown_architecture[] =
571 "--- !tapi-tbd\n"
572 "tbd-version: 4\n"
573 "targets: [ foo-macos ]\n"
574 "install-name: Test.dylib\n"
575 "...\n";
576
577 auto Result = TextAPIReader::get(
578 MemoryBufferRef(tbd_file_unknown_architecture, "Test.tbd"));
579 EXPECT_FALSE(!!Result);
580 auto errorMessage = toString(Result.takeError());
581 EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown "
582 "architecture\ntargets: [ foo-macos ]\n"
583 " ^~~~~~~~~~\n",
584 errorMessage);
585}
586
587TEST(TBDv4, InvalidPlatform) {
588 static const char tbd_file_invalid_platform[] = "--- !tapi-tbd\n"
589 "tbd-version: 4\n"
590 "targets: [ x86_64-maos ]\n"
591 "install-name: Test.dylib\n"
592 "...\n";
593
594 auto Result = TextAPIReader::get(
595 MemoryBufferRef(tbd_file_invalid_platform, "Test.tbd"));
596 EXPECT_FALSE(!!Result);
597 auto errorMessage = toString(Result.takeError());
598 EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: "
599 "[ x86_64-maos ]\n"
600 " ^~~~~~~~~~~~\n",
601 errorMessage);
602}
603
604TEST(TBDv4, MalformedFile1) {
605 static const char malformed_file1[] = "--- !tapi-tbd\n"
606 "tbd-version: 4\n"
607 "...\n";
608
609 auto Result =
610 TextAPIReader::get(MemoryBufferRef(malformed_file1, "Test.tbd"));
611 EXPECT_FALSE(!!Result);
612 auto errorMessage = toString(Result.takeError());
613 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
614 "'targets'\ntbd-version: 4\n^\n",
615 errorMessage);
616}
617
618TEST(TBDv4, MalformedFile2) {
619 static const char malformed_file2[] = "--- !tapi-tbd\n"
620 "tbd-version: 4\n"
621 "targets: [ x86_64-macos ]\n"
622 "install-name: Test.dylib\n"
623 "foobar: \"unsupported key\"\n";
624
625 auto Result =
626 TextAPIReader::get(MemoryBufferRef(malformed_file2, "Test.tbd"));
627 EXPECT_FALSE(!!Result);
628 auto errorMessage = toString(Result.takeError());
629 ASSERT_EQ(
630 "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
631 "\"unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
632 errorMessage);
633}
634
635TEST(TBDv4, MalformedFile3) {
Jonas Devlieghereb14937c2020-01-23 22:48:29 -0800636 static const char tbd_v4_swift_1_1[] = "--- !tapi-tbd\n"
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000637 "tbd-version: 4\n"
638 "targets: [ x86_64-macos ]\n"
639 "install-name: Test.dylib\n"
640 "swift-abi-version: 1.1\n"
641 "...\n";
642
643 auto Result =
Jonas Devlieghereb14937c2020-01-23 22:48:29 -0800644 TextAPIReader::get(MemoryBufferRef(tbd_v4_swift_1_1, "Test.tbd"));
Cyndy Ishidaf9d81622019-10-10 04:24:44 +0000645 EXPECT_FALSE(!!Result);
646 auto errorMessage = toString(Result.takeError());
647 EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
648 "version.\nswift-abi-version: 1.1\n ^~~\n",
649 errorMessage);
650}
651
652} // end namespace TBDv4