1 | //===-- TextStubV2Tests.cpp - TBD V2 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 TBDv2Symbols[] = { |
20 | {.Kind: EncodeKind::GlobalSymbol, .Name: "$ld$hide$os9.0$_sym1" , .Weak: false, .ThreadLocalValue: false}, |
21 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym1" , .Weak: false, .ThreadLocalValue: false}, |
22 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym2" , .Weak: false, .ThreadLocalValue: false}, |
23 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym3" , .Weak: false, .ThreadLocalValue: false}, |
24 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym4" , .Weak: false, .ThreadLocalValue: false}, |
25 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym5" , .Weak: false, .ThreadLocalValue: false}, |
26 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_tlv1" , .Weak: false, .ThreadLocalValue: true}, |
27 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_tlv2" , .Weak: false, .ThreadLocalValue: true}, |
28 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_tlv3" , .Weak: false, .ThreadLocalValue: true}, |
29 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak1" , .Weak: true, .ThreadLocalValue: false}, |
30 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak2" , .Weak: true, .ThreadLocalValue: false}, |
31 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak3" , .Weak: true, .ThreadLocalValue: false}, |
32 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class1" , .Weak: false, .ThreadLocalValue: false}, |
33 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class2" , .Weak: false, .ThreadLocalValue: false}, |
34 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class3" , .Weak: false, .ThreadLocalValue: false}, |
35 | {.Kind: EncodeKind::ObjectiveCInstanceVariable, .Name: "class1._ivar1" , .Weak: false, .ThreadLocalValue: false}, |
36 | {.Kind: EncodeKind::ObjectiveCInstanceVariable, .Name: "class1._ivar2" , .Weak: false, .ThreadLocalValue: false}, |
37 | {.Kind: EncodeKind::ObjectiveCInstanceVariable, .Name: "class1._ivar3" , .Weak: false, .ThreadLocalValue: false}, |
38 | }; |
39 | |
40 | namespace TBDv2 { |
41 | |
42 | TEST(TBDv2, ReadFile) { |
43 | static const char TBDv2File1[] = |
44 | "--- !tapi-tbd-v2\n" |
45 | "archs: [ armv7, armv7s, armv7k, arm64 ]\n" |
46 | "platform: ios\n" |
47 | "flags: [ installapi ]\n" |
48 | "install-name: Test.dylib\n" |
49 | "current-version: 2.3.4\n" |
50 | "compatibility-version: 1.0\n" |
51 | "swift-version: 1.1\n" |
52 | "parent-umbrella: Umbrella.dylib\n" |
53 | "exports:\n" |
54 | " - archs: [ armv7, armv7s, armv7k, arm64 ]\n" |
55 | " allowable-clients: [ clientA ]\n" |
56 | " re-exports: [ /usr/lib/libfoo.dylib ]\n" |
57 | " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n" |
58 | " objc-classes: [ _class1, _class2 ]\n" |
59 | " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n" |
60 | " weak-def-symbols: [ _weak1, _weak2 ]\n" |
61 | " thread-local-symbols: [ _tlv1, _tlv2 ]\n" |
62 | " - archs: [ armv7, armv7s, armv7k ]\n" |
63 | " symbols: [ _sym5 ]\n" |
64 | " objc-classes: [ _class3 ]\n" |
65 | " objc-ivars: [ _class1._ivar3 ]\n" |
66 | " weak-def-symbols: [ _weak3 ]\n" |
67 | " thread-local-symbols: [ _tlv3 ]\n" |
68 | "...\n" ; |
69 | |
70 | Expected<TBDFile> Result = |
71 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2File1, "Test.tbd" )); |
72 | EXPECT_TRUE(!!Result); |
73 | TBDFile File = std::move(Result.get()); |
74 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
75 | auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64; |
76 | auto Platform = PLATFORM_IOS; |
77 | TargetList Targets; |
78 | for (auto &&arch : Archs) |
79 | Targets.emplace_back(Args: Target(arch, Platform)); |
80 | EXPECT_EQ(Archs, File->getArchitectures()); |
81 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
82 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
83 | EXPECT_EQ(std::string("Test.dylib" ), File->getInstallName()); |
84 | EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion()); |
85 | EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion()); |
86 | EXPECT_EQ(2U, File->getSwiftABIVersion()); |
87 | EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint()); |
88 | EXPECT_TRUE(File->isTwoLevelNamespace()); |
89 | EXPECT_TRUE(File->isApplicationExtensionSafe()); |
90 | InterfaceFileRef client("clientA" , Targets); |
91 | InterfaceFileRef reexport("/usr/lib/libfoo.dylib" , Targets); |
92 | EXPECT_EQ(1U, File->allowableClients().size()); |
93 | EXPECT_EQ(client, File->allowableClients().front()); |
94 | EXPECT_EQ(1U, File->reexportedLibraries().size()); |
95 | EXPECT_EQ(reexport, File->reexportedLibraries().front()); |
96 | |
97 | ExportedSymbolSeq Exports; |
98 | for (const auto *Sym : File->symbols()) { |
99 | EXPECT_FALSE(Sym->isWeakReferenced()); |
100 | EXPECT_FALSE(Sym->isUndefined()); |
101 | Exports.emplace_back( |
102 | args: ExportedSymbol{.Kind: Sym->getKind(), .Name: std::string(Sym->getName()), |
103 | .Weak: Sym->isWeakDefined(), .ThreadLocalValue: Sym->isThreadLocalValue()}); |
104 | } |
105 | llvm::sort(C&: Exports); |
106 | |
107 | EXPECT_EQ(std::size(TBDv2Symbols), Exports.size()); |
108 | EXPECT_TRUE( |
109 | std::equal(Exports.begin(), Exports.end(), std::begin(TBDv2Symbols))); |
110 | } |
111 | |
112 | TEST(TBDv2, ReadFile2) { |
113 | static const char TBDv2File2[] = |
114 | "--- !tapi-tbd-v2\n" |
115 | "archs: [ armv7, armv7s, armv7k, arm64 ]\n" |
116 | "platform: ios\n" |
117 | "flags: [ flat_namespace, not_app_extension_safe ]\n" |
118 | "install-name: Test.dylib\n" |
119 | "swift-version: 1.1\n" |
120 | "exports:\n" |
121 | " - archs: [ armv7, armv7s, armv7k, arm64 ]\n" |
122 | " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n" |
123 | " objc-classes: [ _class1, _class2 ]\n" |
124 | " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n" |
125 | " weak-def-symbols: [ _weak1, _weak2 ]\n" |
126 | " thread-local-symbols: [ _tlv1, _tlv2 ]\n" |
127 | " - archs: [ armv7, armv7s, armv7k ]\n" |
128 | " symbols: [ _sym5 ]\n" |
129 | " objc-classes: [ _class3 ]\n" |
130 | " objc-ivars: [ _class1._ivar3 ]\n" |
131 | " weak-def-symbols: [ _weak3 ]\n" |
132 | " thread-local-symbols: [ _tlv3 ]\n" |
133 | "undefineds:\n" |
134 | " - archs: [ armv7, armv7s, armv7k, arm64 ]\n" |
135 | " symbols: [ _undefSym1, _undefSym2, _undefSym3 ]\n" |
136 | " objc-classes: [ _undefClass1, _undefClass2 ]\n" |
137 | " objc-ivars: [ _undefClass1._ivar1, _undefClass1._ivar2 ]\n" |
138 | " weak-ref-symbols: [ _undefWeak1, _undefWeak2 ]\n" |
139 | "...\n" ; |
140 | |
141 | Expected<TBDFile> Result = |
142 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2File2, "Test.tbd" )); |
143 | EXPECT_TRUE(!!Result); |
144 | TBDFile File = std::move(Result.get()); |
145 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
146 | auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64; |
147 | auto Platform = PLATFORM_IOS; |
148 | TargetList Targets; |
149 | for (auto &&arch : Archs) |
150 | Targets.emplace_back(Args: Target(arch, Platform)); |
151 | EXPECT_EQ(Archs, File->getArchitectures()); |
152 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
153 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
154 | EXPECT_EQ(std::string("Test.dylib" ), File->getInstallName()); |
155 | EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion()); |
156 | EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion()); |
157 | EXPECT_EQ(2U, File->getSwiftABIVersion()); |
158 | EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint()); |
159 | EXPECT_FALSE(File->isTwoLevelNamespace()); |
160 | EXPECT_FALSE(File->isApplicationExtensionSafe()); |
161 | EXPECT_EQ(0U, File->allowableClients().size()); |
162 | EXPECT_EQ(0U, File->reexportedLibraries().size()); |
163 | } |
164 | |
165 | TEST(TBDv2, WriteFile) { |
166 | static const char TBDv2File3[] = |
167 | "--- !tapi-tbd-v2\n" |
168 | "archs: [ i386, x86_64 ]\n" |
169 | "platform: macosx\n" |
170 | "install-name: '/usr/lib/libfoo.dylib'\n" |
171 | "current-version: 1.2.3\n" |
172 | "compatibility-version: 0\n" |
173 | "swift-version: 5\n" |
174 | "exports:\n" |
175 | " - archs: [ i386 ]\n" |
176 | " symbols: [ _sym1 ]\n" |
177 | " weak-def-symbols: [ _sym2 ]\n" |
178 | " thread-local-symbols: [ _sym3 ]\n" |
179 | " - archs: [ x86_64 ]\n" |
180 | " allowable-clients: [ clientA ]\n" |
181 | " re-exports: [ '/usr/lib/libfoo.dylib' ]\n" |
182 | " symbols: [ '_OBJC_EHTYPE_$_Class1' ]\n" |
183 | " objc-classes: [ _Class1 ]\n" |
184 | " objc-ivars: [ _Class1._ivar1 ]\n" |
185 | "...\n" ; |
186 | |
187 | InterfaceFile File; |
188 | TargetList Targets; |
189 | for (auto &&arch : AK_i386 | AK_x86_64) |
190 | Targets.emplace_back(Args: Target(arch, PLATFORM_MACOS)); |
191 | File.setPath("libfoo.dylib" ); |
192 | File.setInstallName("/usr/lib/libfoo.dylib" ); |
193 | File.setFileType(FileType::TBD_V2); |
194 | File.addTargets(Targets); |
195 | File.setCurrentVersion(PackedVersion(1, 2, 3)); |
196 | File.setTwoLevelNamespace(); |
197 | File.setApplicationExtensionSafe(); |
198 | File.setSwiftABIVersion(5); |
199 | File.setObjCConstraint(ObjCConstraintType::Retain_Release); |
200 | File.addAllowableClient(InstallName: "clientA" , Target: Targets[1]); |
201 | File.addReexportedLibrary(InstallName: "/usr/lib/libfoo.dylib" , Target: Targets[1]); |
202 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym1" , Target&: {Targets[0]}); |
203 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym2" , Target&: {Targets[0]}, |
204 | Flags: SymbolFlags::WeakDefined); |
205 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym3" , Target&: {Targets[0]}, |
206 | Flags: SymbolFlags::ThreadLocalValue); |
207 | File.addSymbol(Kind: EncodeKind::ObjectiveCClass, Name: "Class1" , Target&: {Targets[1]}); |
208 | File.addSymbol(Kind: EncodeKind::ObjectiveCClassEHType, Name: "Class1" , Target&: {Targets[1]}); |
209 | File.addSymbol(Kind: EncodeKind::ObjectiveCInstanceVariable, Name: "Class1._ivar1" , |
210 | Target&: {Targets[1]}); |
211 | |
212 | SmallString<4096> Buffer; |
213 | raw_svector_ostream OS(Buffer); |
214 | Error Result = TextAPIWriter::writeToStream(OS, File); |
215 | EXPECT_FALSE(Result); |
216 | EXPECT_STREQ(TBDv2File3, Buffer.c_str()); |
217 | } |
218 | |
219 | TEST(TBDv2, Platform_macOS) { |
220 | static const char TBDv2PlatformMacOS[] = "--- !tapi-tbd-v2\n" |
221 | "archs: [ x86_64 ]\n" |
222 | "platform: macosx\n" |
223 | "install-name: Test.dylib\n" |
224 | "...\n" ; |
225 | |
226 | Expected<TBDFile> Result = |
227 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2PlatformMacOS, "Test.tbd" )); |
228 | EXPECT_TRUE(!!Result); |
229 | TBDFile File = std::move(Result.get()); |
230 | auto Platform = PLATFORM_MACOS; |
231 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
232 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
233 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
234 | } |
235 | |
236 | TEST(TBDv2, Platform_iOS) { |
237 | static const char TBDv2PlatformiOS[] = "--- !tapi-tbd-v2\n" |
238 | "archs: [ arm64 ]\n" |
239 | "platform: ios\n" |
240 | "install-name: Test.dylib\n" |
241 | "...\n" ; |
242 | |
243 | Expected<TBDFile> Result = |
244 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2PlatformiOS, "Test.tbd" )); |
245 | EXPECT_TRUE(!!Result); |
246 | auto Platform = PLATFORM_IOS; |
247 | TBDFile File = std::move(Result.get()); |
248 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
249 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
250 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
251 | } |
252 | |
253 | TEST(TBDv2, Platform_watchOS) { |
254 | static const char TBDv2PlatformWatchOS[] = "--- !tapi-tbd-v2\n" |
255 | "archs: [ armv7k ]\n" |
256 | "platform: watchos\n" |
257 | "install-name: Test.dylib\n" |
258 | "...\n" ; |
259 | |
260 | Expected<TBDFile> Result = |
261 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2PlatformWatchOS, "Test.tbd" )); |
262 | EXPECT_TRUE(!!Result); |
263 | auto Platform = PLATFORM_WATCHOS; |
264 | TBDFile File = std::move(Result.get()); |
265 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
266 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
267 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
268 | } |
269 | |
270 | TEST(TBDv2, Platform_tvOS) { |
271 | static const char TBDv2PlatformtvOS[] = "--- !tapi-tbd-v2\n" |
272 | "archs: [ arm64 ]\n" |
273 | "platform: tvos\n" |
274 | "install-name: Test.dylib\n" |
275 | "...\n" ; |
276 | |
277 | Expected<TBDFile> Result = |
278 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2PlatformtvOS, "Test.tbd" )); |
279 | EXPECT_TRUE(!!Result); |
280 | auto Platform = PLATFORM_TVOS; |
281 | TBDFile File = std::move(Result.get()); |
282 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
283 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
284 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
285 | } |
286 | |
287 | TEST(TBDv2, Platform_bridgeOS) { |
288 | static const char TBDv2BridgeOS[] = "--- !tapi-tbd-v2\n" |
289 | "archs: [ armv7k ]\n" |
290 | "platform: bridgeos\n" |
291 | "install-name: Test.dylib\n" |
292 | "...\n" ; |
293 | |
294 | Expected<TBDFile> Result = |
295 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2BridgeOS, "Test.tbd" )); |
296 | EXPECT_TRUE(!!Result); |
297 | auto Platform = PLATFORM_BRIDGEOS; |
298 | TBDFile File = std::move(Result.get()); |
299 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
300 | EXPECT_EQ(File->getPlatforms().size(), 1U); |
301 | EXPECT_EQ(Platform, *File->getPlatforms().begin()); |
302 | } |
303 | |
304 | TEST(TBDv2, Swift_1_0) { |
305 | static const char TBDv2Swift1[] = "--- !tapi-tbd-v2\n" |
306 | "archs: [ arm64 ]\n" |
307 | "platform: ios\n" |
308 | "install-name: Test.dylib\n" |
309 | "swift-version: 1.0\n" |
310 | "...\n" ; |
311 | |
312 | Expected<TBDFile> Result = |
313 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift1, "Test.tbd" )); |
314 | EXPECT_TRUE(!!Result); |
315 | TBDFile File = std::move(Result.get()); |
316 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
317 | EXPECT_EQ(1U, File->getSwiftABIVersion()); |
318 | } |
319 | |
320 | TEST(TBDv2, Swift_1_1) { |
321 | static const char TBDv2Swift1dot[] = "--- !tapi-tbd-v2\n" |
322 | "archs: [ arm64 ]\n" |
323 | "platform: ios\n" |
324 | "install-name: Test.dylib\n" |
325 | "swift-version: 1.1\n" |
326 | "...\n" ; |
327 | |
328 | Expected<TBDFile> Result = |
329 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift1dot, "Test.tbd" )); |
330 | EXPECT_TRUE(!!Result); |
331 | TBDFile File = std::move(Result.get()); |
332 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
333 | EXPECT_EQ(2U, File->getSwiftABIVersion()); |
334 | } |
335 | |
336 | TEST(TBDv2, Swift_2_0) { |
337 | static const char tbd_v2_swift_2_0[] = "--- !tapi-tbd-v2\n" |
338 | "archs: [ arm64 ]\n" |
339 | "platform: ios\n" |
340 | "install-name: Test.dylib\n" |
341 | "swift-version: 2.0\n" |
342 | "...\n" ; |
343 | |
344 | Expected<TBDFile> Result = |
345 | TextAPIReader::get(InputBuffer: MemoryBufferRef(tbd_v2_swift_2_0, "Test.tbd" )); |
346 | EXPECT_TRUE(!!Result); |
347 | TBDFile File = std::move(Result.get()); |
348 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
349 | EXPECT_EQ(3U, File->getSwiftABIVersion()); |
350 | } |
351 | |
352 | TEST(TBDv2, Swift_3_0) { |
353 | static const char TBDv2Swift3[] = "--- !tapi-tbd-v2\n" |
354 | "archs: [ arm64 ]\n" |
355 | "platform: ios\n" |
356 | "install-name: Test.dylib\n" |
357 | "swift-version: 3.0\n" |
358 | "...\n" ; |
359 | |
360 | Expected<TBDFile> Result = |
361 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift3, "Test.tbd" )); |
362 | EXPECT_TRUE(!!Result); |
363 | TBDFile File = std::move(Result.get()); |
364 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
365 | EXPECT_EQ(4U, File->getSwiftABIVersion()); |
366 | } |
367 | |
368 | TEST(TBDv2, Swift_4_0) { |
369 | static const char TBDv2Swift4[] = "--- !tapi-tbd-v2\n" |
370 | "archs: [ arm64 ]\n" |
371 | "platform: ios\n" |
372 | "install-name: Test.dylib\n" |
373 | "swift-version: 4.0\n" |
374 | "...\n" ; |
375 | |
376 | Expected<TBDFile> Result = |
377 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift4, "Test.tbd" )); |
378 | EXPECT_FALSE(!!Result); |
379 | std::string ErrorMessage = toString(E: Result.takeError()); |
380 | EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI " |
381 | "version.\nswift-version: 4.0\n ^~~\n" , |
382 | ErrorMessage); |
383 | } |
384 | |
385 | TEST(TBDv2, Swift_5) { |
386 | static const char TBDv2Swift5[] = "--- !tapi-tbd-v2\n" |
387 | "archs: [ arm64 ]\n" |
388 | "platform: ios\n" |
389 | "install-name: Test.dylib\n" |
390 | "swift-version: 5\n" |
391 | "...\n" ; |
392 | |
393 | Expected<TBDFile> Result = |
394 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift5, "Test.tbd" )); |
395 | EXPECT_TRUE(!!Result); |
396 | TBDFile File = std::move(Result.get()); |
397 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
398 | EXPECT_EQ(5U, File->getSwiftABIVersion()); |
399 | } |
400 | |
401 | TEST(TBDv2, Swift_99) { |
402 | static const char TBDv2Swift99[] = "--- !tapi-tbd-v2\n" |
403 | "archs: [ arm64 ]\n" |
404 | "platform: ios\n" |
405 | "install-name: Test.dylib\n" |
406 | "swift-version: 99\n" |
407 | "...\n" ; |
408 | |
409 | Expected<TBDFile> Result = |
410 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2Swift99, "Test.tbd" )); |
411 | EXPECT_TRUE(!!Result); |
412 | TBDFile File = std::move(Result.get()); |
413 | EXPECT_EQ(FileType::TBD_V2, File->getFileType()); |
414 | EXPECT_EQ(99U, File->getSwiftABIVersion()); |
415 | } |
416 | |
417 | TEST(TBDv2, UnknownArchitecture) { |
418 | static const char TBDv2FileUnknownArch[] = "--- !tapi-tbd-v2\n" |
419 | "archs: [ foo ]\n" |
420 | "platform: macosx\n" |
421 | "install-name: Test.dylib\n" |
422 | "...\n" ; |
423 | Expected<TBDFile> Result = |
424 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2FileUnknownArch, "Test.tbd" )); |
425 | EXPECT_TRUE(!!Result); |
426 | } |
427 | |
428 | TEST(TBDv2, UnknownPlatform) { |
429 | static const char TBDv2FileUnknownPlatform[] = "--- !tapi-tbd-v2\n" |
430 | "archs: [ i386 ]\n" |
431 | "platform: newOS\n" |
432 | "...\n" ; |
433 | |
434 | Expected<TBDFile> Result = |
435 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2FileUnknownPlatform, "Test.tbd" )); |
436 | EXPECT_FALSE(!!Result); |
437 | std::string ErrorMessage = toString(E: Result.takeError()); |
438 | EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: " |
439 | "newOS\n ^~~~~\n" , |
440 | ErrorMessage); |
441 | } |
442 | |
443 | TEST(TBDv2, InvalidPlatform) { |
444 | static const char TBDv2FileInvalidPlatform[] = "--- !tapi-tbd-v2\n" |
445 | "archs: [ i386 ]\n" |
446 | "platform: iosmac\n" |
447 | "install-name: Test.dylib\n" |
448 | "...\n" ; |
449 | |
450 | Expected<TBDFile> Result = |
451 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2FileInvalidPlatform, "Test.tbd" )); |
452 | EXPECT_FALSE(!!Result); |
453 | std::string ErrorMessage = toString(E: Result.takeError()); |
454 | EXPECT_EQ("malformed file\nTest.tbd:3:11: error: invalid platform\nplatform: " |
455 | "iosmac\n ^~~~~~\n" , |
456 | ErrorMessage); |
457 | } |
458 | |
459 | TEST(TBDv2, MalformedFile1) { |
460 | static const char TBDv2FileMalformed1[] = "--- !tapi-tbd-v2\n" |
461 | "archs: [ arm64 ]\n" |
462 | "foobar: \"Unsupported key\"\n" |
463 | "...\n" ; |
464 | |
465 | Expected<TBDFile> Result = |
466 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2FileMalformed1, "Test.tbd" )); |
467 | EXPECT_FALSE(!!Result); |
468 | std::string ErrorMessage = toString(E: Result.takeError()); |
469 | ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key " |
470 | "'platform'\narchs: [ arm64 ]\n^\n" , |
471 | ErrorMessage); |
472 | } |
473 | |
474 | TEST(TBDv2, MalformedFile2) { |
475 | static const char TBDv2FileMalformed2[] = "--- !tapi-tbd-v2\n" |
476 | "archs: [ arm64 ]\n" |
477 | "platform: ios\n" |
478 | "install-name: Test.dylib\n" |
479 | "foobar: \"Unsupported key\"\n" |
480 | "...\n" ; |
481 | |
482 | Expected<TBDFile> Result = |
483 | TextAPIReader::get(InputBuffer: MemoryBufferRef(TBDv2FileMalformed2, "Test.tbd" )); |
484 | EXPECT_FALSE(!!Result); |
485 | std::string ErrorMessage = toString(E: Result.takeError()); |
486 | ASSERT_EQ( |
487 | "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: " |
488 | "\"Unsupported key\"\n^~~~~~\n" , |
489 | ErrorMessage); |
490 | } |
491 | |
492 | } // namespace TBDv2 |
493 | |