1 //===- unittest/Tooling/CleanupTest.cpp - Include insertion/deletion tests ===//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
10 #include "../Tooling/ReplacementTest.h"
11 #include "../Tooling/RewriterTestContext.h"
12 #include "clang/Format/Format.h"
13 #include "clang/Tooling/Core/Replacement.h"
15 #include "gtest/gtest.h"
21 class HeaderIncludesTest
: public ::testing::Test
{
23 std::string
insert(llvm::StringRef Code
, llvm::StringRef Header
) {
24 HeaderIncludes
Includes(FileName
, Code
, Style
);
25 assert(Header
.startswith("\"") || Header
.startswith("<"));
26 auto R
= Includes
.insert(Header
.trim("\"<>"), Header
.startswith("<"));
28 return std::string(Code
);
29 auto Result
= applyAllReplacements(Code
, Replacements(*R
));
30 EXPECT_TRUE(static_cast<bool>(Result
));
34 std::string
remove(llvm::StringRef Code
, llvm::StringRef Header
) {
35 HeaderIncludes
Includes(FileName
, Code
, Style
);
36 assert(Header
.startswith("\"") || Header
.startswith("<"));
37 auto Replaces
= Includes
.remove(Header
.trim("\"<>"), Header
.startswith("<"));
38 auto Result
= applyAllReplacements(Code
, Replaces
);
39 EXPECT_TRUE(static_cast<bool>(Result
));
43 std::string FileName
= "fix.cpp";
44 IncludeStyle Style
= format::getLLVMStyle().IncludeStyle
;
47 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithoutDefine
) {
48 std::string Code
= "int main() {}";
49 std::string Expected
= "#include \"a.h\"\n"
51 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
54 TEST_F(HeaderIncludesTest
, RepeatedIncludes
) {
56 for (int i
= 0; i
< 100; ++i
) {
57 Code
+= "#include \"a.h\"\n";
59 std::string Expected
= Code
+ "#include \"a2.h\"\n";
60 EXPECT_EQ(Expected
, insert(Code
, "\"a2.h\""));
63 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithDefine
) {
64 std::string Code
= "#ifndef A_H\n"
69 std::string Expected
= "#ifndef A_H\n"
76 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
79 TEST_F(HeaderIncludesTest
, InsertBeforeCategoryWithLowerPriority
) {
80 std::string Code
= "#ifndef A_H\n"
89 std::string Expected
= "#ifndef A_H\n"
100 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
103 TEST_F(HeaderIncludesTest
, InsertAfterMainHeader
) {
104 std::string Code
= "#include \"fix.h\"\n"
107 std::string Expected
= "#include \"fix.h\"\n"
111 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
113 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
115 FileName
= "fix.cu.cpp";
116 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
118 FileName
= "fix_test.cu.cpp";
119 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
121 FileName
= "bar.cpp";
122 EXPECT_NE(Expected
, insert(Code
, "<a>")) << "Not main header";
125 TEST_F(HeaderIncludesTest
, InsertBeforeSystemHeaderLLVM
) {
126 std::string Code
= "#include <memory>\n"
129 std::string Expected
= "#include \"z.h\"\n"
130 "#include <memory>\n"
133 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
136 TEST_F(HeaderIncludesTest
, InsertAfterSystemHeaderGoogle
) {
137 std::string Code
= "#include <memory>\n"
140 std::string Expected
= "#include <memory>\n"
144 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
146 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
149 TEST_F(HeaderIncludesTest
, InsertOneIncludeLLVMStyle
) {
150 std::string Code
= "#include \"x/fix.h\"\n"
153 "#include \"clang/Format/Format.h\"\n"
154 "#include <memory>\n";
155 std::string Expected
= "#include \"x/fix.h\"\n"
158 "#include \"clang/Format/Format.h\"\n"
159 "#include \"llvm/x/y.h\"\n"
160 "#include <memory>\n";
161 EXPECT_EQ(Expected
, insert(Code
, "\"llvm/x/y.h\""));
164 TEST_F(HeaderIncludesTest
, InsertIntoBlockSorted
) {
165 std::string Code
= "#include \"x/fix.h\"\n"
168 "#include <memory>\n";
169 std::string Expected
= "#include \"x/fix.h\"\n"
173 "#include <memory>\n";
174 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
177 TEST_F(HeaderIncludesTest
, InsertIntoFirstBlockOfSameKind
) {
178 std::string Code
= "#include \"x/fix.h\"\n"
182 "#include <memory>\n"
183 "#include <vector>\n"
185 "#include \"n.h\"\n";
186 std::string Expected
= "#include \"x/fix.h\"\n"
191 "#include <memory>\n"
192 "#include <vector>\n"
194 "#include \"n.h\"\n";
195 EXPECT_EQ(Expected
, insert(Code
, "\"d.h\""));
198 TEST_F(HeaderIncludesTest
, InsertIntoSystemBlockSorted
) {
199 std::string Code
= "#include \"x/fix.h\"\n"
204 std::string Expected
= "#include \"x/fix.h\"\n"
208 "#include <vector>\n"
210 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
213 TEST_F(HeaderIncludesTest
, InsertNewSystemIncludeGoogleStyle
) {
214 std::string Code
= "#include \"x/fix.h\"\n"
216 "#include \"y/a.h\"\n"
217 "#include \"z/b.h\"\n";
218 // FIXME: inserting after the empty line following the main header might be
220 std::string Expected
= "#include \"x/fix.h\"\n"
221 "#include <vector>\n"
223 "#include \"y/a.h\"\n"
224 "#include \"z/b.h\"\n";
225 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
227 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
230 TEST_F(HeaderIncludesTest
, NotConfusedByDefine
) {
231 std::string Code
= "void f() {}\n"
234 std::string Expected
= "#include <vector>\n"
238 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
241 TEST_F(HeaderIncludesTest
, SkippedTopComment
) {
242 std::string Code
= "// comment\n"
245 std::string Expected
= "// comment\n"
248 "#include <vector>\n";
249 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
252 TEST_F(HeaderIncludesTest
, SkippedMixedComments
) {
253 std::string Code
= "// comment\n"
255 " comment continued\n"
259 std::string Expected
= "// comment\n"
261 " comment continued\n"
265 "#include <vector>\n";
266 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
269 TEST_F(HeaderIncludesTest
, MultipleBlockCommentsInOneLine
) {
270 std::string Code
= "/*\n"
275 "/* c1 */ /*c2 */\n";
276 std::string Expected
= "/*\n"
282 "#include <vector>\n";
283 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
286 TEST_F(HeaderIncludesTest
, CodeAfterComments
) {
287 std::string Code
= "/*\n"
295 std::string Expected
= "/*\n"
302 "#include <vector>\n"
304 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
307 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfDef
) {
308 std::string Code
= "// comment \n"
311 std::string Expected
= "// comment \n"
312 "#include <vector>\n"
315 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
318 TEST_F(HeaderIncludesTest
, RealHeaderGuardAfterComments
) {
319 std::string Code
= "// comment \n"
324 std::string Expected
= "// comment \n"
327 "#include <vector>\n"
330 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
333 TEST_F(HeaderIncludesTest
, PragmaOnce
) {
334 std::string Code
= "// comment \n"
337 std::string Expected
= "// comment \n"
339 "#include <vector>\n"
341 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
344 TEST_F(HeaderIncludesTest
, IfNDefWithNoDefine
) {
345 std::string Code
= "// comment \n"
349 std::string Expected
= "// comment \n"
350 "#include <vector>\n"
354 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
357 TEST_F(HeaderIncludesTest
, FakeHeaderGuard
) {
358 std::string Code
= "// comment \n"
361 std::string Expected
= "// comment \n"
362 "#include <vector>\n"
365 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
368 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfnDef
) {
369 std::string Code
= "#ifndef A_H\n"
372 std::string Expected
= "#include \"b.h\"\n"
377 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
380 TEST_F(HeaderIncludesTest
, HeaderGuardWithComment
) {
381 std::string Code
= "// comment \n"
382 "#ifndef X // comment\n"
386 "/* comment */ #define X\n"
389 std::string Expected
= "// comment \n"
390 "#ifndef X // comment\n"
394 "/* comment */ #define X\n"
395 "#include <vector>\n"
398 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
401 TEST_F(HeaderIncludesTest
, EmptyCode
) {
402 std::string Code
= "";
403 std::string Expected
= "#include <vector>\n";
404 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
407 TEST_F(HeaderIncludesTest
, NoNewLineAtTheEndOfCode
) {
408 std::string Code
= "#include <map>";
409 std::string Expected
= "#include <map>\n#include <vector>\n";
410 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
413 TEST_F(HeaderIncludesTest
, SkipExistingHeaders
) {
414 std::string Code
= "#include \"a.h\"\n"
415 "#include <vector>\n";
416 std::string Expected
= "#include \"a.h\"\n"
417 "#include <vector>\n";
418 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
419 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
422 TEST_F(HeaderIncludesTest
, AddIncludesWithDifferentForms
) {
423 std::string Code
= "#include <vector>\n";
424 // FIXME: this might not be the best behavior.
425 std::string Expected
= "#include \"vector\"\n"
426 "#include <vector>\n";
427 EXPECT_EQ(Expected
, insert(Code
, "\"vector\""));
430 TEST_F(HeaderIncludesTest
, NoInsertionAfterCode
) {
431 std::string Code
= "#include \"a.h\"\n"
433 "#include \"b.h\"\n";
434 std::string Expected
= "#include \"a.h\"\n"
437 "#include \"b.h\"\n";
438 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
441 TEST_F(HeaderIncludesTest
, NoInsertionInStringLiteral
) {
442 std::string Code
= "#include \"a.h\"\n"
443 "const char[] = R\"(\n"
446 std::string Expected
= "#include \"a.h\"\n"
448 "const char[] = R\"(\n"
451 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
454 TEST_F(HeaderIncludesTest
, NoInsertionAfterOtherDirective
) {
455 std::string Code
= "#include \"a.h\"\n"
459 std::string Expected
= "#include \"a.h\"\n"
464 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
467 TEST_F(HeaderIncludesTest
, CanInsertAfterLongSystemInclude
) {
468 std::string Code
= "#include \"a.h\"\n"
470 "#include <a/b/c/d/e.h>\n";
471 std::string Expected
= "#include \"a.h\"\n"
473 "#include <a/b/c/d/e.h>\n"
475 EXPECT_EQ(Expected
, insert(Code
, "<x.h>"));
478 TEST_F(HeaderIncludesTest
, CanInsertAfterComment
) {
479 std::string Code
= "#include \"a.h\"\n"
485 "#include \"b.h\"\n";
486 std::string Expected
= "#include \"a.h\"\n"
493 "#include \"c.h\"\n";
494 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
497 TEST_F(HeaderIncludesTest
, LongCommentsInTheBeginningOfFile
) {
498 std::string Code
= "// Loooooooooooooooooooooooooong comment\n"
499 "// Loooooooooooooooooooooooooong comment\n"
500 "// Loooooooooooooooooooooooooong comment\n"
501 "#include <string>\n"
502 "#include <vector>\n"
505 "#include \"b.h\"\n";
506 std::string Expected
= "// Loooooooooooooooooooooooooong comment\n"
507 "// Loooooooooooooooooooooooooong comment\n"
508 "// Loooooooooooooooooooooooooong comment\n"
509 "#include <string>\n"
510 "#include <vector>\n"
514 "#include \"third.h\"\n";
515 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
517 EXPECT_EQ(Expected
, insert(Code
, "\"third.h\""));
520 TEST_F(HeaderIncludesTest
, SimpleDeleteInclude
) {
521 std::string Code
= "#include \"abc.h\"\n"
522 "#include \"xyz.h\" // comment\n"
524 std::string Expected
= "#include \"abc.h\"\n"
526 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
529 TEST_F(HeaderIncludesTest
, DeleteQuotedOnly
) {
530 std::string Code
= "#include \"abc.h\"\n"
533 std::string Expected
= "#include <abc.h>\n"
535 EXPECT_EQ(Expected
, remove(Code
, "\"abc.h\""));
538 TEST_F(HeaderIncludesTest
, DeleteAllCode
) {
539 std::string Code
= "#include \"xyz.h\"\n";
540 std::string Expected
= "";
541 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
544 TEST_F(HeaderIncludesTest
, DeleteOnlyIncludesWithSameQuote
) {
545 std::string Code
= "#include \"xyz.h\"\n"
547 "#include <xyz.h>\n";
548 std::string Expected
= "#include \"xyz.h\"\n"
549 "#include \"xyz\"\n";
550 EXPECT_EQ(Expected
, remove(Code
, "<xyz.h>"));
553 TEST_F(HeaderIncludesTest
, CanDeleteAfterCode
) {
554 std::string Code
= "#include \"a.h\"\n"
556 "#include \"b.h\"\n";
557 std::string Expected
= "#include \"a.h\"\n"
559 EXPECT_EQ(Expected
, remove(Code
, "\"b.h\""));
563 } // namespace tooling