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