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
.startswith("\"") || Header
.startswith("<"));
28 Includes
.insert(Header
.trim("\"<>"), Header
.startswith("<"), Directive
);
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
.startswith("\"") || Header
.startswith("<"));
39 auto Replaces
= Includes
.remove(Header
.trim("\"<>"), Header
.startswith("<"));
40 auto Result
= applyAllReplacements(Code
, Replaces
);
41 EXPECT_TRUE(static_cast<bool>(Result
));
45 std::string FileName
= "fix.cpp";
46 IncludeStyle Style
= format::getLLVMStyle().IncludeStyle
;
49 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithoutDefine
) {
50 std::string Code
= "int main() {}";
51 std::string Expected
= "#include \"a.h\"\n"
53 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
56 TEST_F(HeaderIncludesTest
, RepeatedIncludes
) {
58 for (int i
= 0; i
< 100; ++i
) {
59 Code
+= "#include \"a.h\"\n";
61 std::string Expected
= Code
+ "#include \"a2.h\"\n";
62 EXPECT_EQ(Expected
, insert(Code
, "\"a2.h\""));
65 TEST_F(HeaderIncludesTest
, InsertImportWithSameInclude
) {
66 std::string Code
= "#include \"a.h\"\n";
67 std::string Expected
= Code
+ "#import \"a.h\"\n";
68 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\"", IncludeDirective::Import
));
71 TEST_F(HeaderIncludesTest
, DontInsertAlreadyImported
) {
72 std::string Code
= "#import \"a.h\"\n";
73 EXPECT_EQ(Code
, insert(Code
, "\"a.h\"", IncludeDirective::Import
));
76 TEST_F(HeaderIncludesTest
, DeleteImportAndSameInclude
) {
77 std::string Code
= R
"cpp(
81 EXPECT_EQ("\nint x;", remove(Code
, "<abc.h>"));
84 TEST_F(HeaderIncludesTest
, NoExistingIncludeWithDefine
) {
85 std::string Code
= "#ifndef A_H\n"
90 std::string Expected
= "#ifndef A_H\n"
97 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
100 TEST_F(HeaderIncludesTest
, InsertBeforeCategoryWithLowerPriority
) {
101 std::string Code
= "#ifndef A_H\n"
106 "#include <vector>\n"
110 std::string Expected
= "#ifndef A_H\n"
116 "#include <vector>\n"
121 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
124 TEST_F(HeaderIncludesTest
, InsertAfterMainHeader
) {
125 std::string Code
= "#include \"fix.h\"\n"
128 std::string Expected
= "#include \"fix.h\"\n"
132 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
134 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
136 FileName
= "fix.cu.cpp";
137 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
139 FileName
= "fix_test.cu.cpp";
140 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
142 FileName
= "bar.cpp";
143 EXPECT_NE(Expected
, insert(Code
, "<a>")) << "Not main header";
146 TEST_F(HeaderIncludesTest
, InsertMainHeader
) {
147 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
149 FileName
= "fix.cpp";
150 EXPECT_EQ(R
"cpp(#include "fix
.h
"
151 #include "a
.h
")cpp", insert("#include \"a.h\"", "\"fix.h\""));
153 // Respect the original main-file header.
154 EXPECT_EQ(R
"cpp(#include "z
/fix
.h
"
156 )cpp", insert("#include \"z/fix.h\"", "\"a/fix.h\""));
159 TEST_F(HeaderIncludesTest
, InsertBeforeSystemHeaderLLVM
) {
160 std::string Code
= "#include <memory>\n"
163 std::string Expected
= "#include \"z.h\"\n"
164 "#include <memory>\n"
167 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
170 TEST_F(HeaderIncludesTest
, InsertAfterSystemHeaderGoogle
) {
171 std::string Code
= "#include <memory>\n"
174 std::string Expected
= "#include <memory>\n"
178 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
180 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
183 TEST_F(HeaderIncludesTest
, InsertOneIncludeLLVMStyle
) {
184 std::string Code
= "#include \"x/fix.h\"\n"
187 "#include \"clang/Format/Format.h\"\n"
188 "#include <memory>\n";
189 std::string Expected
= "#include \"x/fix.h\"\n"
192 "#include \"clang/Format/Format.h\"\n"
193 "#include \"llvm/x/y.h\"\n"
194 "#include <memory>\n";
195 EXPECT_EQ(Expected
, insert(Code
, "\"llvm/x/y.h\""));
198 TEST_F(HeaderIncludesTest
, InsertIntoBlockSorted
) {
199 std::string Code
= "#include \"x/fix.h\"\n"
202 "#include <memory>\n";
203 std::string Expected
= "#include \"x/fix.h\"\n"
207 "#include <memory>\n";
208 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
211 TEST_F(HeaderIncludesTest
, InsertIntoFirstBlockOfSameKind
) {
212 std::string Code
= "#include \"x/fix.h\"\n"
216 "#include <memory>\n"
217 "#include <vector>\n"
219 "#include \"n.h\"\n";
220 std::string Expected
= "#include \"x/fix.h\"\n"
225 "#include <memory>\n"
226 "#include <vector>\n"
228 "#include \"n.h\"\n";
229 EXPECT_EQ(Expected
, insert(Code
, "\"d.h\""));
232 TEST_F(HeaderIncludesTest
, InsertIntoSystemBlockSorted
) {
233 std::string Code
= "#include \"x/fix.h\"\n"
238 std::string Expected
= "#include \"x/fix.h\"\n"
242 "#include <vector>\n"
244 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
247 TEST_F(HeaderIncludesTest
, InsertNewSystemIncludeGoogleStyle
) {
248 std::string Code
= "#include \"x/fix.h\"\n"
250 "#include \"y/a.h\"\n"
251 "#include \"z/b.h\"\n";
252 // FIXME: inserting after the empty line following the main header might be
254 std::string Expected
= "#include \"x/fix.h\"\n"
255 "#include <vector>\n"
257 "#include \"y/a.h\"\n"
258 "#include \"z/b.h\"\n";
259 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
261 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
264 TEST_F(HeaderIncludesTest
, NotConfusedByDefine
) {
265 std::string Code
= "void f() {}\n"
268 std::string Expected
= "#include <vector>\n"
272 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
275 TEST_F(HeaderIncludesTest
, SkippedTopComment
) {
276 std::string Code
= "// comment\n"
279 std::string Expected
= "// comment\n"
282 "#include <vector>\n";
283 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
286 TEST_F(HeaderIncludesTest
, SkippedMixedComments
) {
287 std::string Code
= "// comment\n"
289 " comment continued\n"
293 std::string Expected
= "// comment\n"
295 " comment continued\n"
299 "#include <vector>\n";
300 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
303 TEST_F(HeaderIncludesTest
, MultipleBlockCommentsInOneLine
) {
304 std::string Code
= "/*\n"
309 "/* c1 */ /*c2 */\n";
310 std::string Expected
= "/*\n"
316 "#include <vector>\n";
317 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
320 TEST_F(HeaderIncludesTest
, CodeAfterComments
) {
321 std::string Code
= "/*\n"
329 std::string Expected
= "/*\n"
336 "#include <vector>\n"
338 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
341 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfDef
) {
342 std::string Code
= "// comment \n"
345 std::string Expected
= "// comment \n"
346 "#include <vector>\n"
349 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
352 TEST_F(HeaderIncludesTest
, RealHeaderGuardAfterComments
) {
353 std::string Code
= "// comment \n"
358 std::string Expected
= "// comment \n"
361 "#include <vector>\n"
364 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
367 TEST_F(HeaderIncludesTest
, PragmaOnce
) {
368 std::string Code
= "// comment \n"
371 std::string Expected
= "// comment \n"
373 "#include <vector>\n"
375 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
378 TEST_F(HeaderIncludesTest
, IfNDefWithNoDefine
) {
379 std::string Code
= "// comment \n"
383 std::string Expected
= "// comment \n"
384 "#include <vector>\n"
388 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
391 TEST_F(HeaderIncludesTest
, FakeHeaderGuard
) {
392 std::string Code
= "// comment \n"
395 std::string Expected
= "// comment \n"
396 "#include <vector>\n"
399 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
402 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfnDef
) {
403 std::string Code
= "#ifndef A_H\n"
406 std::string Expected
= "#include \"b.h\"\n"
411 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
414 TEST_F(HeaderIncludesTest
, HeaderGuardWithComment
) {
415 std::string Code
= "// comment \n"
416 "#ifndef X // comment\n"
420 "/* comment */ #define X\n"
423 std::string Expected
= "// comment \n"
424 "#ifndef X // comment\n"
428 "/* comment */ #define X\n"
429 "#include <vector>\n"
432 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
435 TEST_F(HeaderIncludesTest
, EmptyCode
) {
436 std::string Code
= "";
437 std::string Expected
= "#include <vector>\n";
438 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
441 TEST_F(HeaderIncludesTest
, NoNewLineAtTheEndOfCode
) {
442 std::string Code
= "#include <map>";
443 std::string Expected
= "#include <map>\n#include <vector>\n";
444 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
447 TEST_F(HeaderIncludesTest
, SkipExistingHeaders
) {
448 std::string Code
= "#include \"a.h\"\n"
449 "#include <vector>\n";
450 std::string Expected
= "#include \"a.h\"\n"
451 "#include <vector>\n";
452 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
453 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
456 TEST_F(HeaderIncludesTest
, AddIncludesWithDifferentForms
) {
457 std::string Code
= "#include <vector>\n";
458 // FIXME: this might not be the best behavior.
459 std::string Expected
= "#include \"vector\"\n"
460 "#include <vector>\n";
461 EXPECT_EQ(Expected
, insert(Code
, "\"vector\""));
464 TEST_F(HeaderIncludesTest
, NoInsertionAfterCode
) {
465 std::string Code
= "#include \"a.h\"\n"
467 "#include \"b.h\"\n";
468 std::string Expected
= "#include \"a.h\"\n"
471 "#include \"b.h\"\n";
472 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
475 TEST_F(HeaderIncludesTest
, NoInsertionInStringLiteral
) {
476 std::string Code
= "#include \"a.h\"\n"
477 "const char[] = R\"(\n"
480 std::string Expected
= "#include \"a.h\"\n"
482 "const char[] = R\"(\n"
485 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
488 TEST_F(HeaderIncludesTest
, NoInsertionAfterOtherDirective
) {
489 std::string Code
= "#include \"a.h\"\n"
493 std::string Expected
= "#include \"a.h\"\n"
498 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
501 TEST_F(HeaderIncludesTest
, CanInsertAfterLongSystemInclude
) {
502 std::string Code
= "#include \"a.h\"\n"
504 "#include <a/b/c/d/e.h>\n";
505 std::string Expected
= "#include \"a.h\"\n"
507 "#include <a/b/c/d/e.h>\n"
509 EXPECT_EQ(Expected
, insert(Code
, "<x.h>"));
512 TEST_F(HeaderIncludesTest
, CanInsertAfterComment
) {
513 std::string Code
= "#include \"a.h\"\n"
519 "#include \"b.h\"\n";
520 std::string Expected
= "#include \"a.h\"\n"
527 "#include \"c.h\"\n";
528 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
531 TEST_F(HeaderIncludesTest
, LongCommentsInTheBeginningOfFile
) {
532 std::string Code
= "// Loooooooooooooooooooooooooong comment\n"
533 "// Loooooooooooooooooooooooooong comment\n"
534 "// Loooooooooooooooooooooooooong comment\n"
535 "#include <string>\n"
536 "#include <vector>\n"
539 "#include \"b.h\"\n";
540 std::string Expected
= "// Loooooooooooooooooooooooooong comment\n"
541 "// Loooooooooooooooooooooooooong comment\n"
542 "// Loooooooooooooooooooooooooong comment\n"
543 "#include <string>\n"
544 "#include <vector>\n"
548 "#include \"third.h\"\n";
549 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
551 EXPECT_EQ(Expected
, insert(Code
, "\"third.h\""));
554 TEST_F(HeaderIncludesTest
, SimpleDeleteInclude
) {
555 std::string Code
= "#include \"abc.h\"\n"
556 "#include \"xyz.h\" // comment\n"
558 std::string Expected
= "#include \"abc.h\"\n"
560 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
563 TEST_F(HeaderIncludesTest
, DeleteQuotedOnly
) {
564 std::string Code
= "#include \"abc.h\"\n"
567 std::string Expected
= "#include <abc.h>\n"
569 EXPECT_EQ(Expected
, remove(Code
, "\"abc.h\""));
572 TEST_F(HeaderIncludesTest
, DeleteAllCode
) {
573 std::string Code
= "#include \"xyz.h\"\n";
574 std::string Expected
= "";
575 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
578 TEST_F(HeaderIncludesTest
, DeleteOnlyIncludesWithSameQuote
) {
579 std::string Code
= "#include \"xyz.h\"\n"
581 "#include <xyz.h>\n";
582 std::string Expected
= "#include \"xyz.h\"\n"
583 "#include \"xyz\"\n";
584 EXPECT_EQ(Expected
, remove(Code
, "<xyz.h>"));
587 TEST_F(HeaderIncludesTest
, CanDeleteAfterCode
) {
588 std::string Code
= "#include \"a.h\"\n"
590 "#include \"b.h\"\n";
591 std::string Expected
= "#include \"a.h\"\n"
593 EXPECT_EQ(Expected
, remove(Code
, "\"b.h\""));
597 } // namespace tooling