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 | {.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: "_tlv3" , .Weak: false, .ThreadLocalValue: true}, |
28 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak1" , .Weak: true, .ThreadLocalValue: false}, |
29 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak2" , .Weak: true, .ThreadLocalValue: false}, |
30 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_weak3" , .Weak: true, .ThreadLocalValue: false}, |
31 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class1" , .Weak: false, .ThreadLocalValue: false}, |
32 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class2" , .Weak: false, .ThreadLocalValue: false}, |
33 | {.Kind: EncodeKind::ObjectiveCClass, .Name: "class3" , .Weak: false, .ThreadLocalValue: false}, |
34 | {.Kind: EncodeKind::ObjectiveCClassEHType, .Name: "class1" , .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 TBDv3 { |
41 | |
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(InputBuffer: 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(Args: 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 | args: ExportedSymbol{.Kind: Sym->getKind(), .Name: std::string(Sym->getName()), |
110 | .Weak: Sym->isWeakDefined(), .ThreadLocalValue: Sym->isThreadLocalValue()}); |
111 | } |
112 | llvm::sort(C&: 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 | |
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(InputBuffer: 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(Args: 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(args: ExportedSymbol{.Kind: Sym->getKind(), .Name: Sym->getName().str(), |
195 | .Weak: Sym->isWeakDefined(), |
196 | .ThreadLocalValue: Sym->isThreadLocalValue()}); |
197 | } |
198 | llvm::sort(C&: 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(args: ExportedSymbol{.Kind: Sym->getKind(), .Name: Sym->getName().str(), |
219 | .Weak: Sym->isWeakDefined(), |
220 | .ThreadLocalValue: Sym->isThreadLocalValue()}); |
221 | } |
222 | llvm::sort(C&: Exports); |
223 | |
224 | ExportedSymbolSeq DocumentSymbols{ |
225 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym5" , .Weak: false, .ThreadLocalValue: false}, |
226 | {.Kind: EncodeKind::GlobalSymbol, .Name: "_sym6" , .Weak: false, .ThreadLocalValue: false}, |
227 | }; |
228 | |
229 | EXPECT_EQ(DocumentSymbols.size(), Exports.size()); |
230 | EXPECT_TRUE( |
231 | std::equal(Exports.begin(), Exports.end(), DocumentSymbols.begin())); |
232 | } |
233 | |
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(Args: 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(InstallName: "clientA" , Target: Targets[1]); |
270 | File.addReexportedLibrary(InstallName: "/usr/lib/libfoo.dylib" , Target: Targets[1]); |
271 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym1" , Target&: {Targets[0]}); |
272 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym2" , Target&: {Targets[0]}, |
273 | Flags: SymbolFlags::WeakDefined); |
274 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym3" , Target&: {Targets[0]}, |
275 | Flags: SymbolFlags::ThreadLocalValue); |
276 | File.addSymbol(Kind: EncodeKind::ObjectiveCClass, Name: "Class1" , Target&: {Targets[1]}); |
277 | File.addSymbol(Kind: EncodeKind::ObjectiveCClassEHType, Name: "Class1" , Target&: {Targets[1]}); |
278 | File.addSymbol(Kind: EncodeKind::ObjectiveCInstanceVariable, Name: "Class1._ivar1" , |
279 | Target&: {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 | |
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(Args: Target(arch, PLATFORM_MACOS)); |
325 | Targets.emplace_back(Args: 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(InstallName: "clientA" , Target: Targets[2]); |
337 | File.addReexportedLibrary(InstallName: "/usr/lib/libbar.dylib" , Target: Targets[2]); |
338 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym1" , Targets); |
339 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym2" , Targets, |
340 | Flags: SymbolFlags::WeakDefined); |
341 | File.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_symA" , Targets, |
342 | Flags: SymbolFlags::ThreadLocalValue); |
343 | File.addSymbol(Kind: EncodeKind::ObjectiveCClass, Name: "Class1" , Targets); |
344 | File.addSymbol(Kind: EncodeKind::ObjectiveCClassEHType, Name: "Class1" , Targets); |
345 | File.addSymbol(Kind: EncodeKind::ObjectiveCInstanceVariable, Name: "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(Kind: EncodeKind::GlobalSymbol, Name: "_sym3" , Targets); |
359 | Document.addSymbol(Kind: EncodeKind::GlobalSymbol, Name: "_sym4" , Targets); |
360 | File.addDocument(Document: std::make_shared<InterfaceFile>(args: 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 | |
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(InputBuffer: 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: *File); |
388 | EXPECT_TRUE(!WriteResult); |
389 | EXPECT_EQ(stripWhitespace(TBDv3PlatformMacOS), |
390 | stripWhitespace(Buffer.c_str())); |
391 | } |
392 | |
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(InputBuffer: 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: *File); |
412 | EXPECT_TRUE(!WriteResult); |
413 | EXPECT_EQ(stripWhitespace(TBDv3PlatformiOS), stripWhitespace(Buffer.c_str())); |
414 | } |
415 | |
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(InputBuffer: 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: *File); |
435 | EXPECT_TRUE(!WriteResult); |
436 | EXPECT_EQ(stripWhitespace(TBDv3watchOS), stripWhitespace(Buffer.c_str())); |
437 | } |
438 | |
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(InputBuffer: 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: *File); |
458 | EXPECT_FALSE(WriteResult); |
459 | EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOS), |
460 | stripWhitespace(Buffer.c_str())); |
461 | } |
462 | |
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(InputBuffer: 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: *File); |
482 | EXPECT_TRUE(!WriteResult); |
483 | EXPECT_EQ(stripWhitespace(TBDv3BridgeOS), stripWhitespace(Buffer.c_str())); |
484 | } |
485 | |
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(InputBuffer: 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: *File); |
504 | EXPECT_TRUE(!WriteResult); |
505 | EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSmac), |
506 | stripWhitespace(Buffer.c_str())); |
507 | } |
508 | |
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(InputBuffer: 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(V: PLATFORM_MACOS); |
524 | Platforms.insert(V: 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: *File); |
532 | EXPECT_TRUE(!WriteResult); |
533 | EXPECT_EQ(stripWhitespace(TBDv3PlatformZippered), |
534 | stripWhitespace(Buffer.c_str())); |
535 | } |
536 | |
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(InputBuffer: 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: *File); |
556 | EXPECT_TRUE(!WriteResult); |
557 | EXPECT_EQ(stripWhitespace(TBDv3PlatformiOSsim), |
558 | stripWhitespace(Buffer.c_str())); |
559 | } |
560 | |
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(InputBuffer: 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: *File); |
580 | EXPECT_TRUE(!WriteResult); |
581 | EXPECT_EQ(stripWhitespace(TBDv3watchOSsim), stripWhitespace(Buffer.c_str())); |
582 | } |
583 | |
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(InputBuffer: 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: *File); |
603 | EXPECT_TRUE(!WriteResult); |
604 | EXPECT_EQ(stripWhitespace(TBDv3PlatformtvOSsim), |
605 | stripWhitespace(Buffer.c_str())); |
606 | } |
607 | |
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(InputBuffer: 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: *File); |
629 | EXPECT_TRUE(!WriteResult); |
630 | EXPECT_EQ(stripWhitespace(TBDv3ArchArm64e), stripWhitespace(Buffer.c_str())); |
631 | } |
632 | |
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(InputBuffer: 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: *File); |
651 | EXPECT_TRUE(!WriteResult); |
652 | EXPECT_EQ(stripWhitespace(TBDv3Swift1), stripWhitespace(Buffer.c_str())); |
653 | } |
654 | |
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(InputBuffer: 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: *File); |
673 | EXPECT_TRUE(!WriteResult); |
674 | EXPECT_EQ(stripWhitespace(TBDv3Swift1Dot), stripWhitespace(Buffer.c_str())); |
675 | } |
676 | |
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(InputBuffer: 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: *File); |
695 | EXPECT_TRUE(!WriteResult); |
696 | EXPECT_EQ(stripWhitespace(TBDv3Swift2), stripWhitespace(Buffer.c_str())); |
697 | } |
698 | |
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(InputBuffer: 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: *File); |
717 | EXPECT_TRUE(!WriteResult); |
718 | EXPECT_EQ(stripWhitespace(TBDv3Swift3), stripWhitespace(Buffer.c_str())); |
719 | } |
720 | |
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(InputBuffer: MemoryBufferRef(TBDv3Swift4, "Test.tbd" )); |
731 | EXPECT_FALSE(!!Result); |
732 | std::string ErrorMessage = toString(E: 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 | |
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(InputBuffer: 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 | |
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(InputBuffer: 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 | |
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(InputBuffer: MemoryBufferRef(TBDv3FileUnknownArch, "Test.tbd" )); |
779 | EXPECT_TRUE(!!Result); |
780 | } |
781 | |
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(InputBuffer: MemoryBufferRef(TBDv3FileUnknownPlatform, "Test.tbd" )); |
790 | EXPECT_FALSE(!!Result); |
791 | std::string ErrorMessage = toString(E: Result.takeError()); |
792 | EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: " |
793 | "newOS\n ^~~~~\n" , |
794 | ErrorMessage); |
795 | } |
796 | |
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(InputBuffer: MemoryBufferRef(TBDv3FileMalformed1, "Test.tbd" )); |
805 | EXPECT_FALSE(!!Result); |
806 | std::string ErrorMessage = toString(E: 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 | |
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(InputBuffer: MemoryBufferRef(TBDv3FileMalformed2, "Test.tbd" )); |
822 | EXPECT_FALSE(!!Result); |
823 | std::string ErrorMessage = toString(E: 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 | |
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(InputBuffer: MemoryBufferRef(TBDv3File, "TestA.tbd" )); |
873 | EXPECT_TRUE(!!ResultA); |
874 | InterfaceFile FileA = std::move(*ResultA.get()); |
875 | Expected<TBDFile> ResultB = |
876 | TextAPIReader::get(InputBuffer: 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 | |
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(InputBuffer: MemoryBufferRef(TBDv3File, "TestA.tbd" )); |
894 | EXPECT_TRUE(!!ResultA); |
895 | InterfaceFile FileA = std::move(*ResultA.get()); |
896 | Expected<TBDFile> ResultB = |
897 | TextAPIReader::get(InputBuffer: 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 | |