TextStubV4Tests.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  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. #include "llvm/TextAPI/MachO/InterfaceFile.h"
  9. #include "llvm/TextAPI/MachO/TextAPIReader.h"
  10. #include "llvm/TextAPI/MachO/TextAPIWriter.h"
  11. #include "gtest/gtest.h"
  12. #include <string>
  13. #include <vector>
  14. using namespace llvm;
  15. using namespace llvm::MachO;
  16. struct ExampleSymbol {
  17. SymbolKind Kind;
  18. std::string Name;
  19. bool WeakDefined;
  20. bool ThreadLocalValue;
  21. };
  22. using ExampleSymbolSeq = std::vector<ExampleSymbol>;
  23. using UUIDs = std::vector<std::pair<Target, std::string>>;
  24. inline bool operator<(const ExampleSymbol &LHS, const ExampleSymbol &RHS) {
  25. return std::tie(LHS.Kind, LHS.Name) < std::tie(RHS.Kind, RHS.Name);
  26. }
  27. inline bool operator==(const ExampleSymbol &LHS, const ExampleSymbol &RHS) {
  28. return std::tie(LHS.Kind, LHS.Name, LHS.WeakDefined, LHS.ThreadLocalValue) ==
  29. std::tie(RHS.Kind, RHS.Name, RHS.WeakDefined, RHS.ThreadLocalValue);
  30. }
  31. static ExampleSymbol TBDv4ExportedSymbols[] = {
  32. {SymbolKind::GlobalSymbol, "_symA", false, false},
  33. {SymbolKind::GlobalSymbol, "_symAB", false, false},
  34. {SymbolKind::GlobalSymbol, "_symB", false, false},
  35. };
  36. static ExampleSymbol TBDv4ReexportedSymbols[] = {
  37. {SymbolKind::GlobalSymbol, "_symC", false, false},
  38. };
  39. static ExampleSymbol TBDv4UndefinedSymbols[] = {
  40. {SymbolKind::GlobalSymbol, "_symD", false, false},
  41. };
  42. namespace TBDv4 {
  43. TEST(TBDv4, ReadFile) {
  44. static const char tbd_v4_file[] =
  45. "--- !tapi-tbd\n"
  46. "tbd-version: 4\n"
  47. "targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
  48. "uuids:\n"
  49. " - target: i386-macos\n"
  50. " value: 00000000-0000-0000-0000-000000000000\n"
  51. " - target: x86_64-macos\n"
  52. " value: 11111111-1111-1111-1111-111111111111\n"
  53. " - target: x86_64-ios\n"
  54. " value: 11111111-1111-1111-1111-111111111111\n"
  55. "flags: [ flat_namespace, installapi ]\n"
  56. "install-name: Umbrella.framework/Umbrella\n"
  57. "current-version: 1.2.3\n"
  58. "compatibility-version: 1.2\n"
  59. "swift-abi-version: 5\n"
  60. "parent-umbrella:\n"
  61. " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
  62. " umbrella: System\n"
  63. "allowable-clients:\n"
  64. " - targets: [ i386-macos, x86_64-macos, x86_64-ios ]\n"
  65. " clients: [ ClientA ]\n"
  66. "reexported-libraries:\n"
  67. " - targets: [ i386-macos ]\n"
  68. " libraries: [ /System/Library/Frameworks/A.framework/A ]\n"
  69. "exports:\n"
  70. " - targets: [ i386-macos ]\n"
  71. " symbols: [ _symA ]\n"
  72. " objc-classes: []\n"
  73. " objc-eh-types: []\n"
  74. " objc-ivars: []\n"
  75. " weak-symbols: []\n"
  76. " thread-local-symbols: []\n"
  77. " - targets: [ x86_64-ios ]\n"
  78. " symbols: [_symB]\n"
  79. " - targets: [ x86_64-macos, x86_64-ios ]\n"
  80. " symbols: [_symAB]\n"
  81. "reexports:\n"
  82. " - targets: [ i386-macos ]\n"
  83. " symbols: [_symC]\n"
  84. " objc-classes: []\n"
  85. " objc-eh-types: []\n"
  86. " objc-ivars: []\n"
  87. " weak-symbols: []\n"
  88. " thread-local-symbols: []\n"
  89. "undefineds:\n"
  90. " - targets: [ i386-macos ]\n"
  91. " symbols: [ _symD ]\n"
  92. " objc-classes: []\n"
  93. " objc-eh-types: []\n"
  94. " objc-ivars: []\n"
  95. " weak-symbols: []\n"
  96. " thread-local-symbols: []\n"
  97. "...\n";
  98. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v4_file, "Test.tbd"));
  99. EXPECT_TRUE(!!Result);
  100. auto File = std::move(Result.get());
  101. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  102. PlatformSet Platforms;
  103. Platforms.insert(PlatformKind::macOS);
  104. Platforms.insert(PlatformKind::iOS);
  105. auto Archs = AK_i386 | AK_x86_64;
  106. TargetList Targets = {
  107. Target(AK_i386, PlatformKind::macOS),
  108. Target(AK_x86_64, PlatformKind::macOS),
  109. Target(AK_x86_64, PlatformKind::iOS),
  110. };
  111. UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
  112. {Targets[1], "11111111-1111-1111-1111-111111111111"},
  113. {Targets[2], "11111111-1111-1111-1111-111111111111"}};
  114. EXPECT_EQ(Archs, File->getArchitectures());
  115. EXPECT_EQ(uuids, File->uuids());
  116. EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
  117. for (auto Platform : File->getPlatforms())
  118. EXPECT_EQ(Platforms.count(Platform), 1U);
  119. EXPECT_EQ(std::string("Umbrella.framework/Umbrella"), File->getInstallName());
  120. EXPECT_EQ(PackedVersion(1, 2, 3), File->getCurrentVersion());
  121. EXPECT_EQ(PackedVersion(1, 2, 0), File->getCompatibilityVersion());
  122. EXPECT_EQ(5U, File->getSwiftABIVersion());
  123. EXPECT_FALSE(File->isTwoLevelNamespace());
  124. EXPECT_TRUE(File->isApplicationExtensionSafe());
  125. EXPECT_TRUE(File->isInstallAPI());
  126. InterfaceFileRef client("ClientA", Targets);
  127. InterfaceFileRef reexport("/System/Library/Frameworks/A.framework/A",
  128. {Targets[0]});
  129. EXPECT_EQ(1U, File->allowableClients().size());
  130. EXPECT_EQ(client, File->allowableClients().front());
  131. EXPECT_EQ(1U, File->reexportedLibraries().size());
  132. EXPECT_EQ(reexport, File->reexportedLibraries().front());
  133. ExampleSymbolSeq Exports, Reexports, Undefineds;
  134. ExampleSymbol temp;
  135. for (const auto *Sym : File->symbols()) {
  136. temp = ExampleSymbol{Sym->getKind(), Sym->getName(), Sym->isWeakDefined(),
  137. Sym->isThreadLocalValue()};
  138. EXPECT_FALSE(Sym->isWeakReferenced());
  139. if (Sym->isUndefined())
  140. Undefineds.emplace_back(std::move(temp));
  141. else
  142. Sym->isReexported() ? Reexports.emplace_back(std::move(temp))
  143. : Exports.emplace_back(std::move(temp));
  144. }
  145. llvm::sort(Exports.begin(), Exports.end());
  146. llvm::sort(Reexports.begin(), Reexports.end());
  147. llvm::sort(Undefineds.begin(), Undefineds.end());
  148. EXPECT_EQ(sizeof(TBDv4ExportedSymbols) / sizeof(ExampleSymbol),
  149. Exports.size());
  150. EXPECT_EQ(sizeof(TBDv4ReexportedSymbols) / sizeof(ExampleSymbol),
  151. Reexports.size());
  152. EXPECT_EQ(sizeof(TBDv4UndefinedSymbols) / sizeof(ExampleSymbol),
  153. Undefineds.size());
  154. EXPECT_TRUE(std::equal(Exports.begin(), Exports.end(),
  155. std::begin(TBDv4ExportedSymbols)));
  156. EXPECT_TRUE(std::equal(Reexports.begin(), Reexports.end(),
  157. std::begin(TBDv4ReexportedSymbols)));
  158. EXPECT_TRUE(std::equal(Undefineds.begin(), Undefineds.end(),
  159. std::begin(TBDv4UndefinedSymbols)));
  160. }
  161. TEST(TBDv4, WriteFile) {
  162. static const char tbd_v4_file[] =
  163. "--- !tapi-tbd\n"
  164. "tbd-version: 4\n"
  165. "targets: [ i386-macos, x86_64-ios-simulator ]\n"
  166. "uuids:\n"
  167. " - target: i386-macos\n"
  168. " value: 00000000-0000-0000-0000-000000000000\n"
  169. " - target: x86_64-ios-simulator\n"
  170. " value: 11111111-1111-1111-1111-111111111111\n"
  171. "flags: [ installapi ]\n"
  172. "install-name: 'Umbrella.framework/Umbrella'\n"
  173. "current-version: 1.2.3\n"
  174. "compatibility-version: 0\n"
  175. "swift-abi-version: 5\n"
  176. "parent-umbrella:\n"
  177. " - targets: [ i386-macos, x86_64-ios-simulator ]\n"
  178. " umbrella: System\n"
  179. "allowable-clients:\n"
  180. " - targets: [ i386-macos ]\n"
  181. " clients: [ ClientA ]\n"
  182. "exports:\n"
  183. " - targets: [ i386-macos ]\n"
  184. " symbols: [ _symA ]\n"
  185. " objc-classes: [ Class1 ]\n"
  186. " weak-symbols: [ _symC ]\n"
  187. " - targets: [ x86_64-ios-simulator ]\n"
  188. " symbols: [ _symB ]\n"
  189. "...\n";
  190. InterfaceFile File;
  191. TargetList Targets = {
  192. Target(AK_i386, PlatformKind::macOS),
  193. Target(AK_x86_64, PlatformKind::iOSSimulator),
  194. };
  195. UUIDs uuids = {{Targets[0], "00000000-0000-0000-0000-000000000000"},
  196. {Targets[1], "11111111-1111-1111-1111-111111111111"}};
  197. File.setInstallName("Umbrella.framework/Umbrella");
  198. File.setFileType(FileType::TBD_V4);
  199. File.addTargets(Targets);
  200. File.addUUID(uuids[0].first, uuids[0].second);
  201. File.addUUID(uuids[1].first, uuids[1].second);
  202. File.setCurrentVersion(PackedVersion(1, 2, 3));
  203. File.setTwoLevelNamespace();
  204. File.setInstallAPI(true);
  205. File.setApplicationExtensionSafe(true);
  206. File.setSwiftABIVersion(5);
  207. File.addAllowableClient("ClientA", Targets[0]);
  208. File.addParentUmbrella(Targets[0], "System");
  209. File.addParentUmbrella(Targets[1], "System");
  210. File.addSymbol(SymbolKind::GlobalSymbol, "_symA", {Targets[0]});
  211. File.addSymbol(SymbolKind::GlobalSymbol, "_symB", {Targets[1]});
  212. File.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
  213. SymbolFlags::WeakDefined);
  214. File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[0]});
  215. SmallString<4096> Buffer;
  216. raw_svector_ostream OS(Buffer);
  217. auto Result = TextAPIWriter::writeToStream(OS, File);
  218. EXPECT_FALSE(Result);
  219. EXPECT_STREQ(tbd_v4_file, Buffer.c_str());
  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. auto Result =
  229. TextAPIReader::get(MemoryBufferRef(tbd_multiple_targets, "Test.tbd"));
  230. EXPECT_TRUE(!!Result);
  231. PlatformSet Platforms;
  232. Platforms.insert(PlatformKind::macCatalyst);
  233. Platforms.insert(PlatformKind::tvOS);
  234. Platforms.insert(PlatformKind::iOS);
  235. auto File = std::move(Result.get());
  236. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  237. EXPECT_EQ(AK_x86_64 | AK_arm64 | AK_i386, File->getArchitectures());
  238. EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
  239. for (auto Platform : File->getPlatforms())
  240. EXPECT_EQ(Platforms.count(Platform), 1U);
  241. }
  242. TEST(TBDv4, MultipleTargetsSameArch) {
  243. static const char tbd_targets_same_arch[] =
  244. "--- !tapi-tbd\n"
  245. "tbd-version: 4\n"
  246. "targets: [ x86_64-maccatalyst, x86_64-tvos ]\n"
  247. "install-name: Test.dylib\n"
  248. "...\n";
  249. auto Result =
  250. TextAPIReader::get(MemoryBufferRef(tbd_targets_same_arch, "Test.tbd"));
  251. EXPECT_TRUE(!!Result);
  252. PlatformSet Platforms;
  253. Platforms.insert(PlatformKind::tvOS);
  254. Platforms.insert(PlatformKind::macCatalyst);
  255. auto File = std::move(Result.get());
  256. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  257. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  258. EXPECT_EQ(Platforms.size(), File->getPlatforms().size());
  259. for (auto Platform : File->getPlatforms())
  260. EXPECT_EQ(Platforms.count(Platform), 1U);
  261. }
  262. TEST(TBDv4, MultipleTargetsSamePlatform) {
  263. static const char tbd_multiple_targets_same_platform[] =
  264. "--- !tapi-tbd\n"
  265. "tbd-version: 4\n"
  266. "targets: [ arm64-ios, armv7k-ios ]\n"
  267. "install-name: Test.dylib\n"
  268. "...\n";
  269. auto Result = TextAPIReader::get(
  270. MemoryBufferRef(tbd_multiple_targets_same_platform, "Test.tbd"));
  271. EXPECT_TRUE(!!Result);
  272. auto File = std::move(Result.get());
  273. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  274. EXPECT_EQ(AK_arm64 | AK_armv7k, File->getArchitectures());
  275. EXPECT_EQ(File->getPlatforms().size(), 1U);
  276. EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin());
  277. }
  278. TEST(TBDv4, Target_maccatalyst) {
  279. static const char tbd_target_maccatalyst[] =
  280. "--- !tapi-tbd\n"
  281. "tbd-version: 4\n"
  282. "targets: [ x86_64-maccatalyst ]\n"
  283. "install-name: Test.dylib\n"
  284. "...\n";
  285. auto Result =
  286. TextAPIReader::get(MemoryBufferRef(tbd_target_maccatalyst, "Test.tbd"));
  287. EXPECT_TRUE(!!Result);
  288. auto File = std::move(Result.get());
  289. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  290. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  291. EXPECT_EQ(File->getPlatforms().size(), 1U);
  292. EXPECT_EQ(PlatformKind::macCatalyst, *File->getPlatforms().begin());
  293. }
  294. TEST(TBDv4, Target_x86_ios) {
  295. static const char tbd_target_x86_ios[] = "--- !tapi-tbd\n"
  296. "tbd-version: 4\n"
  297. "targets: [ x86_64-ios ]\n"
  298. "install-name: Test.dylib\n"
  299. "...\n";
  300. auto Result =
  301. TextAPIReader::get(MemoryBufferRef(tbd_target_x86_ios, "Test.tbd"));
  302. EXPECT_TRUE(!!Result);
  303. auto File = std::move(Result.get());
  304. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  305. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  306. EXPECT_EQ(File->getPlatforms().size(), 1U);
  307. EXPECT_EQ(PlatformKind::iOS, *File->getPlatforms().begin());
  308. }
  309. TEST(TBDv4, Target_arm_bridgeOS) {
  310. static const char tbd_platform_bridgeos[] = "--- !tapi-tbd\n"
  311. "tbd-version: 4\n"
  312. "targets: [ armv7k-bridgeos ]\n"
  313. "install-name: Test.dylib\n"
  314. "...\n";
  315. auto Result =
  316. TextAPIReader::get(MemoryBufferRef(tbd_platform_bridgeos, "Test.tbd"));
  317. EXPECT_TRUE(!!Result);
  318. auto File = std::move(Result.get());
  319. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  320. EXPECT_EQ(File->getPlatforms().size(), 1U);
  321. EXPECT_EQ(PlatformKind::bridgeOS, *File->getPlatforms().begin());
  322. EXPECT_EQ(ArchitectureSet(AK_armv7k), File->getArchitectures());
  323. }
  324. TEST(TBDv4, Target_x86_macos) {
  325. static const char tbd_x86_macos[] = "--- !tapi-tbd\n"
  326. "tbd-version: 4\n"
  327. "targets: [ x86_64-macos ]\n"
  328. "install-name: Test.dylib\n"
  329. "...\n";
  330. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_x86_macos, "Test.tbd"));
  331. EXPECT_TRUE(!!Result);
  332. auto File = std::move(Result.get());
  333. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  334. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  335. EXPECT_EQ(File->getPlatforms().size(), 1U);
  336. EXPECT_EQ(PlatformKind::macOS, *File->getPlatforms().begin());
  337. }
  338. TEST(TBDv4, Target_x86_ios_simulator) {
  339. static const char tbd_x86_ios_sim[] = "--- !tapi-tbd\n"
  340. "tbd-version: 4\n"
  341. "targets: [ x86_64-ios-simulator ]\n"
  342. "install-name: Test.dylib\n"
  343. "...\n";
  344. auto Result =
  345. TextAPIReader::get(MemoryBufferRef(tbd_x86_ios_sim, "Test.tbd"));
  346. EXPECT_TRUE(!!Result);
  347. auto File = std::move(Result.get());
  348. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  349. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  350. EXPECT_EQ(File->getPlatforms().size(), 1U);
  351. EXPECT_EQ(PlatformKind::iOSSimulator, *File->getPlatforms().begin());
  352. }
  353. TEST(TBDv4, Target_x86_tvos_simulator) {
  354. static const char tbd_x86_tvos_sim[] =
  355. "--- !tapi-tbd\n"
  356. "tbd-version: 4\n"
  357. "targets: [ x86_64-tvos-simulator ]\n"
  358. "install-name: Test.dylib\n"
  359. "...\n";
  360. auto Result =
  361. TextAPIReader::get(MemoryBufferRef(tbd_x86_tvos_sim, "Test.tbd"));
  362. EXPECT_TRUE(!!Result);
  363. auto File = std::move(Result.get());
  364. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  365. EXPECT_EQ(ArchitectureSet(AK_x86_64), File->getArchitectures());
  366. EXPECT_EQ(File->getPlatforms().size(), 1U);
  367. EXPECT_EQ(PlatformKind::tvOSSimulator, *File->getPlatforms().begin());
  368. }
  369. TEST(TBDv4, Target_i386_watchos_simulator) {
  370. static const char tbd_i386_watchos_sim[] =
  371. "--- !tapi-tbd\n"
  372. "tbd-version: 4\n"
  373. "targets: [ i386-watchos-simulator ]\n"
  374. "install-name: Test.dylib\n"
  375. "...\n";
  376. auto Result =
  377. TextAPIReader::get(MemoryBufferRef(tbd_i386_watchos_sim, "Test.tbd"));
  378. EXPECT_TRUE(!!Result);
  379. auto File = std::move(Result.get());
  380. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  381. EXPECT_EQ(ArchitectureSet(AK_i386), File->getArchitectures());
  382. EXPECT_EQ(File->getPlatforms().size(), 1U);
  383. EXPECT_EQ(PlatformKind::watchOSSimulator, *File->getPlatforms().begin());
  384. }
  385. TEST(TBDv4, Swift_1) {
  386. static const char tbd_swift_1[] = "--- !tapi-tbd\n"
  387. "tbd-version: 4\n"
  388. "targets: [ x86_64-macos ]\n"
  389. "install-name: Test.dylib\n"
  390. "swift-abi-version: 1\n"
  391. "...\n";
  392. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_1, "Test.tbd"));
  393. EXPECT_TRUE(!!Result);
  394. auto File = std::move(Result.get());
  395. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  396. EXPECT_EQ(1U, File->getSwiftABIVersion());
  397. }
  398. TEST(TBDv4, Swift_2) {
  399. static const char tbd_v1_swift_2[] = "--- !tapi-tbd\n"
  400. "tbd-version: 4\n"
  401. "targets: [ x86_64-macos ]\n"
  402. "install-name: Test.dylib\n"
  403. "swift-abi-version: 2\n"
  404. "...\n";
  405. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_v1_swift_2, "Test.tbd"));
  406. EXPECT_TRUE(!!Result);
  407. auto File = std::move(Result.get());
  408. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  409. EXPECT_EQ(2U, File->getSwiftABIVersion());
  410. }
  411. TEST(TBDv4, Swift_5) {
  412. static const char tbd_swift_5[] = "--- !tapi-tbd\n"
  413. "tbd-version: 4\n"
  414. "targets: [ x86_64-macos ]\n"
  415. "install-name: Test.dylib\n"
  416. "swift-abi-version: 5\n"
  417. "...\n";
  418. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_5, "Test.tbd"));
  419. EXPECT_TRUE(!!Result);
  420. auto File = std::move(Result.get());
  421. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  422. EXPECT_EQ(5U, File->getSwiftABIVersion());
  423. }
  424. TEST(TBDv4, Swift_99) {
  425. static const char tbd_swift_99[] = "--- !tapi-tbd\n"
  426. "tbd-version: 4\n"
  427. "targets: [ x86_64-macos ]\n"
  428. "install-name: Test.dylib\n"
  429. "swift-abi-version: 99\n"
  430. "...\n";
  431. auto Result = TextAPIReader::get(MemoryBufferRef(tbd_swift_99, "Test.tbd"));
  432. EXPECT_TRUE(!!Result);
  433. auto File = std::move(Result.get());
  434. EXPECT_EQ(FileType::TBD_V4, File->getFileType());
  435. EXPECT_EQ(99U, File->getSwiftABIVersion());
  436. }
  437. TEST(TBDv4, InvalidArchitecture) {
  438. static const char tbd_file_unknown_architecture[] =
  439. "--- !tapi-tbd\n"
  440. "tbd-version: 4\n"
  441. "targets: [ foo-macos ]\n"
  442. "install-name: Test.dylib\n"
  443. "...\n";
  444. auto Result = TextAPIReader::get(
  445. MemoryBufferRef(tbd_file_unknown_architecture, "Test.tbd"));
  446. EXPECT_FALSE(!!Result);
  447. auto errorMessage = toString(Result.takeError());
  448. EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown "
  449. "architecture\ntargets: [ foo-macos ]\n"
  450. " ^~~~~~~~~~\n",
  451. errorMessage);
  452. }
  453. TEST(TBDv4, InvalidPlatform) {
  454. static const char tbd_file_invalid_platform[] = "--- !tapi-tbd\n"
  455. "tbd-version: 4\n"
  456. "targets: [ x86_64-maos ]\n"
  457. "install-name: Test.dylib\n"
  458. "...\n";
  459. auto Result = TextAPIReader::get(
  460. MemoryBufferRef(tbd_file_invalid_platform, "Test.tbd"));
  461. EXPECT_FALSE(!!Result);
  462. auto errorMessage = toString(Result.takeError());
  463. EXPECT_EQ("malformed file\nTest.tbd:3:12: error: unknown platform\ntargets: "
  464. "[ x86_64-maos ]\n"
  465. " ^~~~~~~~~~~~\n",
  466. errorMessage);
  467. }
  468. TEST(TBDv4, MalformedFile1) {
  469. static const char malformed_file1[] = "--- !tapi-tbd\n"
  470. "tbd-version: 4\n"
  471. "...\n";
  472. auto Result =
  473. TextAPIReader::get(MemoryBufferRef(malformed_file1, "Test.tbd"));
  474. EXPECT_FALSE(!!Result);
  475. auto errorMessage = toString(Result.takeError());
  476. ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
  477. "'targets'\ntbd-version: 4\n^\n",
  478. errorMessage);
  479. }
  480. TEST(TBDv4, MalformedFile2) {
  481. static const char malformed_file2[] = "--- !tapi-tbd\n"
  482. "tbd-version: 4\n"
  483. "targets: [ x86_64-macos ]\n"
  484. "install-name: Test.dylib\n"
  485. "foobar: \"unsupported key\"\n";
  486. auto Result =
  487. TextAPIReader::get(MemoryBufferRef(malformed_file2, "Test.tbd"));
  488. EXPECT_FALSE(!!Result);
  489. auto errorMessage = toString(Result.takeError());
  490. ASSERT_EQ(
  491. "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
  492. "\"unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
  493. errorMessage);
  494. }
  495. TEST(TBDv4, MalformedFile3) {
  496. static const char tbd_v1_swift_1_1[] = "--- !tapi-tbd\n"
  497. "tbd-version: 4\n"
  498. "targets: [ x86_64-macos ]\n"
  499. "install-name: Test.dylib\n"
  500. "swift-abi-version: 1.1\n"
  501. "...\n";
  502. auto Result =
  503. TextAPIReader::get(MemoryBufferRef(tbd_v1_swift_1_1, "Test.tbd"));
  504. EXPECT_FALSE(!!Result);
  505. auto errorMessage = toString(Result.takeError());
  506. EXPECT_EQ("malformed file\nTest.tbd:5:20: error: invalid Swift ABI "
  507. "version.\nswift-abi-version: 1.1\n ^~~\n",
  508. errorMessage);
  509. }
  510. } // end namespace TBDv4