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