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