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 TBDv4File[] = 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(TBDv4File, "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 TBDv4File[] = 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(TBDv4File, Buffer.c_str()); 219 } 220 221 TEST(TBDv4, MultipleTargets) { 222 static const char TBDv4MultipleTargets[] = 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(TBDv4MultipleTargets, "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(TBDv4MultipleTargets), 248 stripWhitespace(Buffer.c_str())); 249 } 250 251 TEST(TBDv4, MultipleTargetsSameArch) { 252 static const char TBDv4TargetsSameArch[] = 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(TBDv4TargetsSameArch, "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(TBDv4TargetsSameArch), 277 stripWhitespace(Buffer.c_str())); 278 } 279 280 TEST(TBDv4, MultipleTargetsSamePlatform) { 281 static const char TBDv4MultipleTargetsSamePlatform[] = 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(TBDv4MultipleTargetsSamePlatform, "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(TBDv4MultipleTargetsSamePlatform), 302 stripWhitespace(Buffer.c_str())); 303 } 304 305 TEST(TBDv4, Target_maccatalyst) { 306 static const char TBDv4TargetMacCatalyst[] = 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(TBDv4TargetMacCatalyst, "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(TBDv4TargetMacCatalyst), 327 stripWhitespace(Buffer.c_str())); 328 } 329 330 TEST(TBDv4, Target_x86_ios) { 331 static const char TBDv4Targetx86iOS[] = "--- !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(TBDv4Targetx86iOS, "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(TBDv4Targetx86iOS), 351 stripWhitespace(Buffer.c_str())); 352 } 353 354 TEST(TBDv4, Target_arm_bridgeOS) { 355 static const char TBDv4PlatformBridgeOS[] = "--- !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(TBDv4PlatformBridgeOS, "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(TBDv4PlatformBridgeOS), 375 stripWhitespace(Buffer.c_str())); 376 } 377 378 TEST(TBDv4, Target_arm_iOS) { 379 static const char TBDv4ArchArm64e[] = "--- !tapi-tbd\n" 380 "tbd-version: 4\n" 381 "targets: [ arm64e-ios ]\n" 382 "install-name: Test.dylib\n" 383 "...\n"; 384 385 auto Result = 386 TextAPIReader::get(MemoryBufferRef(TBDv4ArchArm64e, "Test.tbd")); 387 EXPECT_TRUE(!!Result); 388 auto File = std::move(Result.get()); 389 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 390 EXPECT_EQ(File->getPlatforms().size(), 1U); 391 EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin()); 392 EXPECT_EQ(ArchitectureSet(AK_arm64e), File->getArchitectures()); 393 394 SmallString<4096> Buffer; 395 raw_svector_ostream OS(Buffer); 396 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 397 EXPECT_TRUE(!WriteResult); 398 EXPECT_EQ(stripWhitespace(TBDv4ArchArm64e), stripWhitespace(Buffer.c_str())); 399 } 400 401 TEST(TBDv4, Target_x86_macos) { 402 static const char TBDv4Targetx86MacOS[] = "--- !tapi-tbd\n" 403 "tbd-version: 4\n" 404 "targets: [ x86_64-macos ]\n" 405 "install-name: Test.dylib\n" 406 "...\n"; 407 408 auto Result = 409 TextAPIReader::get(MemoryBufferRef(TBDv4Targetx86MacOS, "Test.tbd")); 410 EXPECT_TRUE(!!Result); 411 auto File = std::move(Result.get()); 412 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 413 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); 414 EXPECT_EQ(File->getPlatforms().size(), 1U); 415 EXPECT_EQ(PlatformKind::macOS, *File->getPlatforms().begin()); 416 417 SmallString<4096> Buffer; 418 raw_svector_ostream OS(Buffer); 419 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 420 EXPECT_TRUE(!WriteResult); 421 EXPECT_EQ(stripWhitespace(TBDv4Targetx86MacOS), 422 stripWhitespace(Buffer.c_str())); 423 } 424 425 TEST(TBDv4, Target_x86_ios_simulator) { 426 static const char TBDv4Targetx86iOSSim[] = 427 "--- !tapi-tbd\n" 428 "tbd-version: 4\n" 429 "targets: [ x86_64-ios-simulator ]\n" 430 "install-name: Test.dylib\n" 431 "...\n"; 432 433 auto Result = 434 TextAPIReader::get(MemoryBufferRef(TBDv4Targetx86iOSSim, "Test.tbd")); 435 EXPECT_TRUE(!!Result); 436 auto File = std::move(Result.get()); 437 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 438 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); 439 EXPECT_EQ(File->getPlatforms().size(), 1U); 440 EXPECT_EQ(PlatformKind::iOSSimulator, *File->getPlatforms().begin()); 441 442 SmallString<4096> Buffer; 443 raw_svector_ostream OS(Buffer); 444 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 445 EXPECT_TRUE(!WriteResult); 446 EXPECT_EQ(stripWhitespace(TBDv4Targetx86iOSSim), 447 stripWhitespace(Buffer.c_str())); 448 } 449 450 TEST(TBDv4, Target_x86_tvos_simulator) { 451 static const char TBDv4x86tvOSSim[] = "--- !tapi-tbd\n" 452 "tbd-version: 4\n" 453 "targets: [ x86_64-tvos-simulator ]\n" 454 "install-name: Test.dylib\n" 455 "...\n"; 456 457 auto Result = 458 TextAPIReader::get(MemoryBufferRef(TBDv4x86tvOSSim, "Test.tbd")); 459 EXPECT_TRUE(!!Result); 460 auto File = std::move(Result.get()); 461 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 462 EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures()); 463 EXPECT_EQ(File->getPlatforms().size(), 1U); 464 EXPECT_EQ(PlatformKind::tvOSSimulator, *File->getPlatforms().begin()); 465 466 SmallString<4096> Buffer; 467 raw_svector_ostream OS(Buffer); 468 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 469 EXPECT_TRUE(!WriteResult); 470 EXPECT_EQ(stripWhitespace(TBDv4x86tvOSSim), stripWhitespace(Buffer.c_str())); 471 } 472 473 TEST(TBDv4, Target_i386_watchos_simulator) { 474 static const char TBDv4i386watchOSSim[] = 475 "--- !tapi-tbd\n" 476 "tbd-version: 4\n" 477 "targets: [ i386-watchos-simulator ]\n" 478 "install-name: Test.dylib\n" 479 "...\n"; 480 481 auto Result = 482 TextAPIReader::get(MemoryBufferRef(TBDv4i386watchOSSim, "Test.tbd")); 483 EXPECT_TRUE(!!Result); 484 auto File = std::move(Result.get()); 485 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 486 EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures()); 487 EXPECT_EQ(File->getPlatforms().size(), 1U); 488 EXPECT_EQ(PlatformKind::watchOSSimulator, *File->getPlatforms().begin()); 489 490 SmallString<4096> Buffer; 491 raw_svector_ostream OS(Buffer); 492 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 493 EXPECT_TRUE(!WriteResult); 494 EXPECT_EQ(stripWhitespace(TBDv4i386watchOSSim), 495 stripWhitespace(Buffer.c_str())); 496 } 497 498 TEST(TBDv4, Swift_1) { 499 static const char TBDv4SwiftVersion1[] = "--- !tapi-tbd\n" 500 "tbd-version: 4\n" 501 "targets: [ x86_64-macos ]\n" 502 "install-name: Test.dylib\n" 503 "swift-abi-version: 1\n" 504 "...\n"; 505 506 auto Result = 507 TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion1, "Test.tbd")); 508 EXPECT_TRUE(!!Result); 509 auto File = std::move(Result.get()); 510 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 511 EXPECT_EQ(1U, File->getSwiftABIVersion()); 512 513 // No writer test because we emit "swift-abi-version:1.0". 514 } 515 516 TEST(TBDv4, Swift_2) { 517 static const char TBDv4Swift2[] = "--- !tapi-tbd\n" 518 "tbd-version: 4\n" 519 "targets: [ x86_64-macos ]\n" 520 "install-name: Test.dylib\n" 521 "swift-abi-version: 2\n" 522 "...\n"; 523 524 auto Result = TextAPIReader::get(MemoryBufferRef(TBDv4Swift2, "Test.tbd")); 525 EXPECT_TRUE(!!Result); 526 auto File = std::move(Result.get()); 527 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 528 EXPECT_EQ(2U, File->getSwiftABIVersion()); 529 530 // No writer test because we emit "swift-abi-version:2.0". 531 } 532 533 TEST(TBDv4, Swift_5) { 534 static const char TBDv4SwiftVersion5[] = "--- !tapi-tbd\n" 535 "tbd-version: 4\n" 536 "targets: [ x86_64-macos ]\n" 537 "install-name: Test.dylib\n" 538 "swift-abi-version: 5\n" 539 "...\n"; 540 541 auto Result = 542 TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion5, "Test.tbd")); 543 EXPECT_TRUE(!!Result); 544 auto File = std::move(Result.get()); 545 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 546 EXPECT_EQ(5U, File->getSwiftABIVersion()); 547 548 SmallString<4096> Buffer; 549 raw_svector_ostream OS(Buffer); 550 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 551 EXPECT_TRUE(!WriteResult); 552 EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion5), 553 stripWhitespace(Buffer.c_str())); 554 } 555 556 TEST(TBDv4, Swift_99) { 557 static const char TBDv4SwiftVersion99[] = "--- !tapi-tbd\n" 558 "tbd-version: 4\n" 559 "targets: [ x86_64-macos ]\n" 560 "install-name: Test.dylib\n" 561 "swift-abi-version: 99\n" 562 "...\n"; 563 564 auto Result = 565 TextAPIReader::get(MemoryBufferRef(TBDv4SwiftVersion99, "Test.tbd")); 566 EXPECT_TRUE(!!Result); 567 auto File = std::move(Result.get()); 568 EXPECT_EQ(FileType::TBD_V4, File->getFileType()); 569 EXPECT_EQ(99U, File->getSwiftABIVersion()); 570 571 SmallString<4096> Buffer; 572 raw_svector_ostream OS(Buffer); 573 auto WriteResult = TextAPIWriter::writeToStream(OS, *File); 574 EXPECT_TRUE(!WriteResult); 575 EXPECT_EQ(stripWhitespace(TBDv4SwiftVersion99), 576 stripWhitespace(Buffer.c_str())); 577 } 578 579 TEST(TBDv4, InvalidArchitecture) { 580 static const char TBDv4UnknownArch[] = "--- !tapi-tbd\n" 581 "tbd-version: 4\n" 582 "targets: [ foo-macos ]\n" 583 "install-name: Test.dylib\n" 584 "...\n"; 585 586 auto Result = 587 TextAPIReader::get(MemoryBufferRef(TBDv4UnknownArch, "Test.tbd")); 588 EXPECT_FALSE(!!Result); 589 auto errorMessage = toString(Result.takeError()); 590 EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown " 591 "architecture\ntargets: [ foo-macos ]\n" 592 " ^~~~~~~~~~\n", 593 errorMessage); 594 } 595 596 TEST(TBDv4, InvalidPlatform) { 597 static const char TBDv4FInvalidPlatform[] = "--- !tapi-tbd\n" 598 "tbd-version: 4\n" 599 "targets: [ x86_64-maos ]\n" 600 "install-name: Test.dylib\n" 601 "...\n"; 602 603 auto Result = 604 TextAPIReader::get(MemoryBufferRef(TBDv4FInvalidPlatform, "Test.tbd")); 605 EXPECT_FALSE(!!Result); 606 auto errorMessage = toString(Result.takeError()); 607 EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: " 608 "[ x86_64-maos ]\n" 609 " ^~~~~~~~~~~~\n", 610 errorMessage); 611 } 612 613 TEST(TBDv4, MalformedFile1) { 614 static const char TBDv4MalformedFile1[] = "--- !tapi-tbd\n" 615 "tbd-version: 4\n" 616 "...\n"; 617 618 auto Result = 619 TextAPIReader::get(MemoryBufferRef(TBDv4MalformedFile1, "Test.tbd")); 620 EXPECT_FALSE(!!Result); 621 auto errorMessage = toString(Result.takeError()); 622 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key " 623 "'targets'\ntbd-version: 4\n^\n", 624 errorMessage); 625 } 626 627 TEST(TBDv4, MalformedFile2) { 628 static const char TBDv4MalformedFile2[] = "--- !tapi-tbd\n" 629 "tbd-version: 4\n" 630 "targets: [ x86_64-macos ]\n" 631 "install-name: Test.dylib\n" 632 "foobar: \"unsupported key\"\n"; 633 634 auto Result = 635 TextAPIReader::get(MemoryBufferRef(TBDv4MalformedFile2, "Test.tbd")); 636 EXPECT_FALSE(!!Result); 637 auto errorMessage = toString(Result.takeError()); 638 ASSERT_EQ( 639 "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: " 640 "\"unsupported key\"\n ^~~~~~~~~~~~~~~~~\n", 641 errorMessage); 642 } 643 644 TEST(TBDv4, MalformedFile3) { 645 static const char TBDv4MalformedSwift[] = "--- !tapi-tbd\n" 646 "tbd-version: 4\n" 647 "targets: [ x86_64-macos ]\n" 648 "install-name: Test.dylib\n" 649 "swift-abi-version: 1.1\n" 650 "...\n"; 651 652 auto Result = 653 TextAPIReader::get(MemoryBufferRef(TBDv4MalformedSwift, "Test.tbd")); 654 EXPECT_FALSE(!!Result); 655 auto errorMessage = toString(Result.takeError()); 656 EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI " 657 "version.\nswift-abi-version: 1.1\n ^~~\n", 658 errorMessage); 659 } 660 661 } // end namespace TBDv4 662