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 IncludeDirective Directive
= IncludeDirective::Include
) {
25 HeaderIncludes
Includes(FileName
, Code
, Style
);
26 assert(Header
.starts_with("\"") || Header
.starts_with("<"));
27 auto R
= Includes
.insert(Header
.trim("\"<>"), Header
.starts_with("<"),
30 return std::string(Code
);
31 auto Result
= applyAllReplacements(Code
, Replacements(*R
));
32 EXPECT_TRUE(static_cast<bool>(Result
));
36 std::string
remove(llvm::StringRef Code
, llvm::StringRef Header
) {
37 HeaderIncludes
Includes(FileName
, Code
, Style
);
38 assert(Header
.starts_with("\"") || Header
.starts_with("<"));
40 Includes
.remove(Header
.trim("\"<>"), Header
.starts_with("<"));
41 auto Result
= applyAllReplacements(Code
, Replaces
);
42 EXPECT_TRUE(static_cast<bool>(Result
));
46 std::string FileName
= "fix.cpp";
47 IncludeStyle Style
= format::getLLVMStyle().IncludeStyle
;
50 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithoutDefine
) {
51 std::string Code
= "int main() {}";
52 std::string Expected
= "#include \"a.h\"\n"
54 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
57 TEST_F(HeaderIncludesTest
, RepeatedIncludes
) {
59 for (int i
= 0; i
< 100; ++i
) {
60 Code
+= "#include \"a.h\"\n";
62 std::string Expected
= Code
+ "#include \"a2.h\"\n";
63 EXPECT_EQ(Expected
, insert(Code
, "\"a2.h\""));
66 TEST_F(HeaderIncludesTest
, InsertImportWithSameInclude
) {
67 std::string Code
= "#include \"a.h\"\n";
68 std::string Expected
= Code
+ "#import \"a.h\"\n";
69 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\"", IncludeDirective::Import
));
72 TEST_F(HeaderIncludesTest
, DontInsertAlreadyImported
) {
73 std::string Code
= "#import \"a.h\"\n";
74 EXPECT_EQ(Code
, insert(Code
, "\"a.h\"", IncludeDirective::Import
));
77 TEST_F(HeaderIncludesTest
, DeleteImportAndSameInclude
) {
78 std::string Code
= R
"cpp(
82 EXPECT_EQ("\nint x;", remove(Code
, "<abc.h>"));
85 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithDefine
) {
86 std::string Code
= "#ifndef A_H\n"
91 std::string Expected
= "#ifndef A_H\n"
98 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
101 TEST_F(HeaderIncludesTest
, InsertBeforeCategoryWithLowerPriority
) {
102 std::string Code
= "#ifndef A_H\n"
107 "#include <vector>\n"
111 std::string Expected
= "#ifndef A_H\n"
117 "#include <vector>\n"
122 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
125 TEST_F(HeaderIncludesTest
, InsertAfterMainHeader
) {
126 std::string Code
= "#include \"fix.h\"\n"
129 std::string Expected
= "#include \"fix.h\"\n"
133 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
135 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
137 FileName
= "fix.cu.cpp";
138 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
140 FileName
= "fix_test.cu.cpp";
141 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
143 FileName
= "bar.cpp";
144 EXPECT_NE(Expected
, insert(Code
, "<a>")) << "Not main header";
147 TEST_F(HeaderIncludesTest
, InsertMainHeader
) {
148 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
150 FileName
= "fix.cpp";
151 EXPECT_EQ(R
"cpp(#include "fix
.h
"
152 #include "a
.h
")cpp", insert("#include \"a.h\"", "\"fix.h\""));
154 // Respect the original main-file header.
155 EXPECT_EQ(R
"cpp(#include "z
/fix
.h
"
157 )cpp", insert("#include \"z/fix.h\"", "\"a/fix.h\""));
160 TEST_F(HeaderIncludesTest
, InsertBeforeSystemHeaderLLVM
) {
161 std::string Code
= "#include <memory>\n"
164 std::string Expected
= "#include \"z.h\"\n"
165 "#include <memory>\n"
168 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
171 TEST_F(HeaderIncludesTest
, InsertAfterSystemHeaderGoogle
) {
172 std::string Code
= "#include <memory>\n"
175 std::string Expected
= "#include <memory>\n"
179 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
181 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
184 TEST_F(HeaderIncludesTest
, InsertOneIncludeLLVMStyle
) {
185 std::string Code
= "#include \"x/fix.h\"\n"
188 "#include \"clang/Format/Format.h\"\n"
189 "#include <memory>\n";
190 std::string Expected
= "#include \"x/fix.h\"\n"
193 "#include \"clang/Format/Format.h\"\n"
194 "#include \"llvm/x/y.h\"\n"
195 "#include <memory>\n";
196 EXPECT_EQ(Expected
, insert(Code
, "\"llvm/x/y.h\""));
199 TEST_F(HeaderIncludesTest
, InsertIntoBlockSorted
) {
200 std::string Code
= "#include \"x/fix.h\"\n"
203 "#include <memory>\n";
204 std::string Expected
= "#include \"x/fix.h\"\n"
208 "#include <memory>\n";
209 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
212 TEST_F(HeaderIncludesTest
, InsertIntoFirstBlockOfSameKind
) {
213 std::string Code
= "#include \"x/fix.h\"\n"
217 "#include <memory>\n"
218 "#include <vector>\n"
220 "#include \"n.h\"\n";
221 std::string Expected
= "#include \"x/fix.h\"\n"
226 "#include <memory>\n"
227 "#include <vector>\n"
229 "#include \"n.h\"\n";
230 EXPECT_EQ(Expected
, insert(Code
, "\"d.h\""));
233 TEST_F(HeaderIncludesTest
, InsertIntoSystemBlockSorted
) {
234 std::string Code
= "#include \"x/fix.h\"\n"
239 std::string Expected
= "#include \"x/fix.h\"\n"
243 "#include <vector>\n"
245 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
248 TEST_F(HeaderIncludesTest
, InsertNewSystemIncludeGoogleStyle
) {
249 std::string Code
= "#include \"x/fix.h\"\n"
251 "#include \"y/a.h\"\n"
252 "#include \"z/b.h\"\n";
253 // FIXME: inserting after the empty line following the main header might be
255 std::string Expected
= "#include \"x/fix.h\"\n"
256 "#include <vector>\n"
258 "#include \"y/a.h\"\n"
259 "#include \"z/b.h\"\n";
260 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
262 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
265 TEST_F(HeaderIncludesTest
, NotConfusedByDefine
) {
266 std::string Code
= "void f() {}\n"
269 std::string Expected
= "#include <vector>\n"
273 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
276 TEST_F(HeaderIncludesTest
, SkippedTopComment
) {
277 std::string Code
= "// comment\n"
280 std::string Expected
= "// comment\n"
283 "#include <vector>\n";
284 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
287 TEST_F(HeaderIncludesTest
, SkippedMixedComments
) {
288 std::string Code
= "// comment\n"
290 " comment continued\n"
294 std::string Expected
= "// comment\n"
296 " comment continued\n"
300 "#include <vector>\n";
301 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
304 TEST_F(HeaderIncludesTest
, MultipleBlockCommentsInOneLine
) {
305 std::string Code
= "/*\n"
310 "/* c1 */ /*c2 */\n";
311 std::string Expected
= "/*\n"
317 "#include <vector>\n";
318 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
321 TEST_F(HeaderIncludesTest
, CodeAfterComments
) {
322 std::string Code
= "/*\n"
330 std::string Expected
= "/*\n"
337 "#include <vector>\n"
339 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
342 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfDef
) {
343 std::string Code
= "// comment \n"
346 std::string Expected
= "// comment \n"
347 "#include <vector>\n"
350 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
353 TEST_F(HeaderIncludesTest
, RealHeaderGuardAfterComments
) {
354 std::string Code
= "// comment \n"
359 std::string Expected
= "// comment \n"
362 "#include <vector>\n"
365 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
368 TEST_F(HeaderIncludesTest
, PragmaOnce
) {
369 std::string Code
= "// comment \n"
372 std::string Expected
= "// comment \n"
374 "#include <vector>\n"
376 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
379 TEST_F(HeaderIncludesTest
, IfNDefWithNoDefine
) {
380 std::string Code
= "// comment \n"
384 std::string Expected
= "// comment \n"
385 "#include <vector>\n"
389 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
392 TEST_F(HeaderIncludesTest
, FakeHeaderGuard
) {
393 std::string Code
= "// comment \n"
396 std::string Expected
= "// comment \n"
397 "#include <vector>\n"
400 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
403 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfnDef
) {
404 std::string Code
= "#ifndef A_H\n"
407 std::string Expected
= "#include \"b.h\"\n"
412 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
415 TEST_F(HeaderIncludesTest
, HeaderGuardWithComment
) {
416 std::string Code
= "// comment \n"
417 "#ifndef X // comment\n"
421 "/* comment */ #define X\n"
424 std::string Expected
= "// comment \n"
425 "#ifndef X // comment\n"
429 "/* comment */ #define X\n"
430 "#include <vector>\n"
433 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
436 TEST_F(HeaderIncludesTest
, EmptyCode
) {
437 std::string Code
= "";
438 std::string Expected
= "#include <vector>\n";
439 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
442 TEST_F(HeaderIncludesTest
, NoNewLineAtTheEndOfCode
) {
443 std::string Code
= "#include <map>";
444 std::string Expected
= "#include <map>\n#include <vector>\n";
445 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
448 TEST_F(HeaderIncludesTest
, SkipExistingHeaders
) {
449 std::string Code
= "#include \"a.h\"\n"
450 "#include <vector>\n";
451 std::string Expected
= "#include \"a.h\"\n"
452 "#include <vector>\n";
453 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
454 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
457 TEST_F(HeaderIncludesTest
, AddIncludesWithDifferentForms
) {
458 std::string Code
= "#include <vector>\n";
459 // FIXME: this might not be the best behavior.
460 std::string Expected
= "#include \"vector\"\n"
461 "#include <vector>\n";
462 EXPECT_EQ(Expected
, insert(Code
, "\"vector\""));
465 TEST_F(HeaderIncludesTest
, NoInsertionAfterCode
) {
466 std::string Code
= "#include \"a.h\"\n"
468 "#include \"b.h\"\n";
469 std::string Expected
= "#include \"a.h\"\n"
472 "#include \"b.h\"\n";
473 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
476 TEST_F(HeaderIncludesTest
, NoInsertionInStringLiteral
) {
477 std::string Code
= "#include \"a.h\"\n"
478 "const char[] = R\"(\n"
481 std::string Expected
= "#include \"a.h\"\n"
483 "const char[] = R\"(\n"
486 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
489 TEST_F(HeaderIncludesTest
, NoInsertionAfterOtherDirective
) {
490 std::string Code
= "#include \"a.h\"\n"
494 std::string Expected
= "#include \"a.h\"\n"
499 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
502 TEST_F(HeaderIncludesTest
, CanInsertAfterLongSystemInclude
) {
503 std::string Code
= "#include \"a.h\"\n"
505 "#include <a/b/c/d/e.h>\n";
506 std::string Expected
= "#include \"a.h\"\n"
508 "#include <a/b/c/d/e.h>\n"
510 EXPECT_EQ(Expected
, insert(Code
, "<x.h>"));
513 TEST_F(HeaderIncludesTest
, CanInsertAfterComment
) {
514 std::string Code
= "#include \"a.h\"\n"
520 "#include \"b.h\"\n";
521 std::string Expected
= "#include \"a.h\"\n"
528 "#include \"c.h\"\n";
529 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
532 TEST_F(HeaderIncludesTest
, LongCommentsInTheBeginningOfFile
) {
533 std::string Code
= "// Loooooooooooooooooooooooooong comment\n"
534 "// Loooooooooooooooooooooooooong comment\n"
535 "// Loooooooooooooooooooooooooong comment\n"
536 "#include <string>\n"
537 "#include <vector>\n"
540 "#include \"b.h\"\n";
541 std::string Expected
= "// Loooooooooooooooooooooooooong comment\n"
542 "// Loooooooooooooooooooooooooong comment\n"
543 "// Loooooooooooooooooooooooooong comment\n"
544 "#include <string>\n"
545 "#include <vector>\n"
549 "#include \"third.h\"\n";
550 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
552 EXPECT_EQ(Expected
, insert(Code
, "\"third.h\""));
555 TEST_F(HeaderIncludesTest
, SimpleDeleteInclude
) {
556 std::string Code
= "#include \"abc.h\"\n"
557 "#include \"xyz.h\" // comment\n"
559 std::string Expected
= "#include \"abc.h\"\n"
561 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
564 TEST_F(HeaderIncludesTest
, DeleteQuotedOnly
) {
565 std::string Code
= "#include \"abc.h\"\n"
568 std::string Expected
= "#include <abc.h>\n"
570 EXPECT_EQ(Expected
, remove(Code
, "\"abc.h\""));
573 TEST_F(HeaderIncludesTest
, DeleteAllCode
) {
574 std::string Code
= "#include \"xyz.h\"\n";
575 std::string Expected
= "";
576 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
579 TEST_F(HeaderIncludesTest
, DeleteOnlyIncludesWithSameQuote
) {
580 std::string Code
= "#include \"xyz.h\"\n"
582 "#include <xyz.h>\n";
583 std::string Expected
= "#include \"xyz.h\"\n"
584 "#include \"xyz\"\n";
585 EXPECT_EQ(Expected
, remove(Code
, "<xyz.h>"));
588 TEST_F(HeaderIncludesTest
, CanDeleteAfterCode
) {
589 std::string Code
= "#include \"a.h\"\n"
591 "#include \"b.h\"\n";
592 std::string Expected
= "#include \"a.h\"\n"
594 EXPECT_EQ(Expected
, remove(Code
, "\"b.h\""));
598 } // namespace tooling