SortIncludesTest.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "FormatTestUtils.h"
  10. #include "clang/Format/Format.h"
  11. #include "llvm/Support/Debug.h"
  12. #include "gtest/gtest.h"
  13. #define DEBUG_TYPE "format-test"
  14. namespace clang {
  15. namespace format {
  16. namespace {
  17. class SortIncludesTest : public ::testing::Test {
  18. protected:
  19. std::vector<tooling::Range> GetCodeRange(StringRef Code) {
  20. return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
  21. }
  22. std::string sort(StringRef Code, std::vector<tooling::Range> Ranges,
  23. StringRef FileName = "input.cc") {
  24. auto Replaces = sortIncludes(Style, Code, Ranges, FileName);
  25. Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
  26. auto Sorted = applyAllReplacements(Code, Replaces);
  27. EXPECT_TRUE(static_cast<bool>(Sorted));
  28. auto Result = applyAllReplacements(
  29. *Sorted, reformat(Style, *Sorted, Ranges, FileName));
  30. EXPECT_TRUE(static_cast<bool>(Result));
  31. return *Result;
  32. }
  33. std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
  34. return sort(Code, GetCodeRange(Code), FileName);
  35. }
  36. unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
  37. sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor);
  38. return Cursor;
  39. }
  40. FormatStyle Style = getLLVMStyle();
  41. };
  42. TEST_F(SortIncludesTest, BasicSorting) {
  43. EXPECT_EQ("#include \"a.h\"\n"
  44. "#include \"b.h\"\n"
  45. "#include \"c.h\"\n",
  46. sort("#include \"a.h\"\n"
  47. "#include \"c.h\"\n"
  48. "#include \"b.h\"\n"));
  49. EXPECT_EQ("// comment\n"
  50. "#include <a>\n"
  51. "#include <b>\n",
  52. sort("// comment\n"
  53. "#include <b>\n"
  54. "#include <a>\n",
  55. {tooling::Range(25, 1)}));
  56. }
  57. TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
  58. // Identical #includes have led to a failure with an unstable sort.
  59. std::string Code = "#include <a>\n"
  60. "#include <b>\n"
  61. "#include <c>\n"
  62. "#include <d>\n"
  63. "#include <e>\n"
  64. "#include <f>\n";
  65. EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty());
  66. }
  67. TEST_F(SortIncludesTest, SupportClangFormatOff) {
  68. EXPECT_EQ("#include <a>\n"
  69. "#include <b>\n"
  70. "#include <c>\n"
  71. "// clang-format off\n"
  72. "#include <b>\n"
  73. "#include <a>\n"
  74. "#include <c>\n"
  75. "// clang-format on\n",
  76. sort("#include <b>\n"
  77. "#include <a>\n"
  78. "#include <c>\n"
  79. "// clang-format off\n"
  80. "#include <b>\n"
  81. "#include <a>\n"
  82. "#include <c>\n"
  83. "// clang-format on\n"));
  84. }
  85. TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
  86. Style.SortIncludes = false;
  87. EXPECT_EQ("#include \"a.h\"\n"
  88. "#include \"c.h\"\n"
  89. "#include \"b.h\"\n",
  90. sort("#include \"a.h\"\n"
  91. "#include \"c.h\"\n"
  92. "#include \"b.h\"\n"));
  93. }
  94. TEST_F(SortIncludesTest, MixIncludeAndImport) {
  95. EXPECT_EQ("#include \"a.h\"\n"
  96. "#import \"b.h\"\n"
  97. "#include \"c.h\"\n",
  98. sort("#include \"a.h\"\n"
  99. "#include \"c.h\"\n"
  100. "#import \"b.h\"\n"));
  101. }
  102. TEST_F(SortIncludesTest, FixTrailingComments) {
  103. EXPECT_EQ("#include \"a.h\" // comment\n"
  104. "#include \"bb.h\" // comment\n"
  105. "#include \"ccc.h\"\n",
  106. sort("#include \"a.h\" // comment\n"
  107. "#include \"ccc.h\"\n"
  108. "#include \"bb.h\" // comment\n"));
  109. }
  110. TEST_F(SortIncludesTest, LeadingWhitespace) {
  111. EXPECT_EQ("#include \"a.h\"\n"
  112. "#include \"b.h\"\n"
  113. "#include \"c.h\"\n",
  114. sort(" #include \"a.h\"\n"
  115. " #include \"c.h\"\n"
  116. " #include \"b.h\"\n"));
  117. EXPECT_EQ("#include \"a.h\"\n"
  118. "#include \"b.h\"\n"
  119. "#include \"c.h\"\n",
  120. sort("# include \"a.h\"\n"
  121. "# include \"c.h\"\n"
  122. "# include \"b.h\"\n"));
  123. }
  124. TEST_F(SortIncludesTest, GreaterInComment) {
  125. EXPECT_EQ("#include \"a.h\"\n"
  126. "#include \"b.h\" // >\n"
  127. "#include \"c.h\"\n",
  128. sort("#include \"a.h\"\n"
  129. "#include \"c.h\"\n"
  130. "#include \"b.h\" // >\n"));
  131. }
  132. TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
  133. EXPECT_EQ("#include \"a.h\"\n"
  134. "#include \"c.h\"\n"
  135. "\n"
  136. "#include \"b.h\"\n",
  137. sort("#include \"a.h\"\n"
  138. "#include \"c.h\"\n"
  139. "\n"
  140. "#include \"b.h\"\n"));
  141. }
  142. TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
  143. EXPECT_EQ("#include \"a.h\"\n"
  144. "#include \"c.h\"\n"
  145. "#include <b.h>\n"
  146. "#include <d.h>\n",
  147. sort("#include <d.h>\n"
  148. "#include <b.h>\n"
  149. "#include \"c.h\"\n"
  150. "#include \"a.h\"\n"));
  151. Style = getGoogleStyle(FormatStyle::LK_Cpp);
  152. EXPECT_EQ("#include <b.h>\n"
  153. "#include <d.h>\n"
  154. "#include \"a.h\"\n"
  155. "#include \"c.h\"\n",
  156. sort("#include <d.h>\n"
  157. "#include <b.h>\n"
  158. "#include \"c.h\"\n"
  159. "#include \"a.h\"\n"));
  160. }
  161. TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
  162. EXPECT_EQ("#include \"a.h\"\n"
  163. "#include \"b.h\"\n"
  164. "#include \"c.h\"\n",
  165. sort("#include \"a.h\"\n"
  166. "#include \\\n"
  167. "\"c.h\"\n"
  168. "#include \"b.h\"\n"));
  169. }
  170. TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
  171. Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
  172. EXPECT_EQ("#include \"llvm/a.h\"\n"
  173. "#include \"b.h\"\n"
  174. "#include \"c.h\"\n",
  175. sort("#include \"llvm/a.h\"\n"
  176. "#include \"c.h\"\n"
  177. "#include \"b.h\"\n",
  178. "a.cc"));
  179. EXPECT_EQ("#include \"llvm/a.h\"\n"
  180. "#include \"b.h\"\n"
  181. "#include \"c.h\"\n",
  182. sort("#include \"llvm/a.h\"\n"
  183. "#include \"c.h\"\n"
  184. "#include \"b.h\"\n",
  185. "a_test.cc"));
  186. EXPECT_EQ("#include \"llvm/input.h\"\n"
  187. "#include \"b.h\"\n"
  188. "#include \"c.h\"\n",
  189. sort("#include \"llvm/input.h\"\n"
  190. "#include \"c.h\"\n"
  191. "#include \"b.h\"\n",
  192. "input.mm"));
  193. // Don't allow prefixes.
  194. EXPECT_EQ("#include \"b.h\"\n"
  195. "#include \"c.h\"\n"
  196. "#include \"llvm/not_a.h\"\n",
  197. sort("#include \"llvm/not_a.h\"\n"
  198. "#include \"c.h\"\n"
  199. "#include \"b.h\"\n",
  200. "a.cc"));
  201. // Don't do this for _main and other suffixes.
  202. EXPECT_EQ("#include \"b.h\"\n"
  203. "#include \"c.h\"\n"
  204. "#include \"llvm/a.h\"\n",
  205. sort("#include \"llvm/a.h\"\n"
  206. "#include \"c.h\"\n"
  207. "#include \"b.h\"\n",
  208. "a_main.cc"));
  209. // Don't do this in headers.
  210. EXPECT_EQ("#include \"b.h\"\n"
  211. "#include \"c.h\"\n"
  212. "#include \"llvm/a.h\"\n",
  213. sort("#include \"llvm/a.h\"\n"
  214. "#include \"c.h\"\n"
  215. "#include \"b.h\"\n",
  216. "a.h"));
  217. // Only do this in the first #include block.
  218. EXPECT_EQ("#include <a>\n"
  219. "\n"
  220. "#include \"b.h\"\n"
  221. "#include \"c.h\"\n"
  222. "#include \"llvm/a.h\"\n",
  223. sort("#include <a>\n"
  224. "\n"
  225. "#include \"llvm/a.h\"\n"
  226. "#include \"c.h\"\n"
  227. "#include \"b.h\"\n",
  228. "a.cc"));
  229. // Only recognize the first #include with a matching basename as main include.
  230. EXPECT_EQ("#include \"a.h\"\n"
  231. "#include \"b.h\"\n"
  232. "#include \"c.h\"\n"
  233. "#include \"llvm/a.h\"\n",
  234. sort("#include \"b.h\"\n"
  235. "#include \"a.h\"\n"
  236. "#include \"c.h\"\n"
  237. "#include \"llvm/a.h\"\n",
  238. "a.cc"));
  239. }
  240. TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) {
  241. // Setup an regex for main includes so we can cover those as well.
  242. Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
  243. // Ensure both main header detection and grouping work in a case insensitive
  244. // manner.
  245. EXPECT_EQ("#include \"llvm/A.h\"\n"
  246. "#include \"b.h\"\n"
  247. "#include \"c.h\"\n"
  248. "#include \"LLVM/z.h\"\n"
  249. "#include \"llvm/X.h\"\n"
  250. "#include \"GTest/GTest.h\"\n"
  251. "#include \"gmock/gmock.h\"\n",
  252. sort("#include \"c.h\"\n"
  253. "#include \"b.h\"\n"
  254. "#include \"GTest/GTest.h\"\n"
  255. "#include \"llvm/A.h\"\n"
  256. "#include \"gmock/gmock.h\"\n"
  257. "#include \"llvm/X.h\"\n"
  258. "#include \"LLVM/z.h\"\n",
  259. "a_TEST.cc"));
  260. }
  261. TEST_F(SortIncludesTest, NegativePriorities) {
  262. Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
  263. EXPECT_EQ("#include \"important_os_header.h\"\n"
  264. "#include \"c_main.h\"\n"
  265. "#include \"a_other.h\"\n",
  266. sort("#include \"c_main.h\"\n"
  267. "#include \"a_other.h\"\n"
  268. "#include \"important_os_header.h\"\n",
  269. "c_main.cc"));
  270. // check stable when re-run
  271. EXPECT_EQ("#include \"important_os_header.h\"\n"
  272. "#include \"c_main.h\"\n"
  273. "#include \"a_other.h\"\n",
  274. sort("#include \"important_os_header.h\"\n"
  275. "#include \"c_main.h\"\n"
  276. "#include \"a_other.h\"\n",
  277. "c_main.cc"));
  278. }
  279. TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
  280. std::string Code = "#include <ccc>\n" // Start of line: 0
  281. "#include <bbbbbb>\n" // Start of line: 15
  282. "#include <a>\n"; // Start of line: 33
  283. EXPECT_EQ(31u, newCursor(Code, 0));
  284. EXPECT_EQ(13u, newCursor(Code, 15));
  285. EXPECT_EQ(0u, newCursor(Code, 33));
  286. EXPECT_EQ(41u, newCursor(Code, 10));
  287. EXPECT_EQ(23u, newCursor(Code, 25));
  288. EXPECT_EQ(10u, newCursor(Code, 43));
  289. }
  290. TEST_F(SortIncludesTest, DeduplicateIncludes) {
  291. EXPECT_EQ("#include <a>\n"
  292. "#include <b>\n"
  293. "#include <c>\n",
  294. sort("#include <a>\n"
  295. "#include <b>\n"
  296. "#include <b>\n"
  297. "#include <b>\n"
  298. "#include <b>\n"
  299. "#include <c>\n"));
  300. }
  301. TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) {
  302. EXPECT_EQ("#include <a>\n"
  303. "#include <b>\n"
  304. "#include <c>\n",
  305. sort("#include <b>\n"
  306. "#include <a>\n"
  307. "#include <b>\n"
  308. "#include <b>\n"
  309. "#include <c>\n"
  310. "#include <b>\n"));
  311. }
  312. TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
  313. std::string Code = "#include <b>\n" // Start of line: 0
  314. "#include <a>\n" // Start of line: 13
  315. "#include <b>\n" // Start of line: 26
  316. "#include <b>\n" // Start of line: 39
  317. "#include <c>\n" // Start of line: 52
  318. "#include <b>\n"; // Start of line: 65
  319. std::string Expected = "#include <a>\n" // Start of line: 0
  320. "#include <b>\n" // Start of line: 13
  321. "#include <c>\n"; // Start of line: 26
  322. EXPECT_EQ(Expected, sort(Code));
  323. // Cursor on 'i' in "#include <a>".
  324. EXPECT_EQ(1u, newCursor(Code, 14));
  325. // Cursor on 'b' in "#include <b>".
  326. EXPECT_EQ(23u, newCursor(Code, 10));
  327. EXPECT_EQ(23u, newCursor(Code, 36));
  328. EXPECT_EQ(23u, newCursor(Code, 49));
  329. EXPECT_EQ(23u, newCursor(Code, 36));
  330. EXPECT_EQ(23u, newCursor(Code, 75));
  331. // Cursor on '#' in "#include <c>".
  332. EXPECT_EQ(26u, newCursor(Code, 52));
  333. }
  334. TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
  335. EXPECT_EQ("#include <a>\n"
  336. "#include <b>\n"
  337. "\n"
  338. "#include <b>\n"
  339. "#include <c>\n",
  340. sort("#include <a>\n"
  341. "#include <b>\n"
  342. "\n"
  343. "#include <c>\n"
  344. "#include <b>\n"
  345. "#include <b>\n"));
  346. }
  347. TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) {
  348. std::string Code = "#include <a>\n"
  349. "#include <b>\n"
  350. "#include <a>\n"
  351. "#include <a>\n"
  352. "\n"
  353. " int x ;";
  354. std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)};
  355. auto Replaces = sortIncludes(Style, Code, Ranges, "input.cpp");
  356. Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
  357. EXPECT_EQ(1u, Ranges.size());
  358. EXPECT_EQ(0u, Ranges[0].getOffset());
  359. EXPECT_EQ(26u, Ranges[0].getLength());
  360. }
  361. } // end namespace
  362. } // end namespace format
  363. } // end namespace clang