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
, NoExistingIncludeWithDefine
) {
55 std::string Code
= "#ifndef A_H\n"
60 std::string Expected
= "#ifndef A_H\n"
67 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
70 TEST_F(HeaderIncludesTest
, InsertBeforeCategoryWithLowerPriority
) {
71 std::string Code
= "#ifndef A_H\n"
80 std::string Expected
= "#ifndef A_H\n"
91 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
94 TEST_F(HeaderIncludesTest
, InsertAfterMainHeader
) {
95 std::string Code
= "#include \"fix.h\"\n"
98 std::string Expected
= "#include \"fix.h\"\n"
102 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
104 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
106 FileName
= "fix.cu.cpp";
107 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
109 FileName
= "fix_test.cu.cpp";
110 EXPECT_EQ(Expected
, insert(Code
, "<a>"));
112 FileName
= "bar.cpp";
113 EXPECT_NE(Expected
, insert(Code
, "<a>")) << "Not main header";
116 TEST_F(HeaderIncludesTest
, InsertBeforeSystemHeaderLLVM
) {
117 std::string Code
= "#include <memory>\n"
120 std::string Expected
= "#include \"z.h\"\n"
121 "#include <memory>\n"
124 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
127 TEST_F(HeaderIncludesTest
, InsertAfterSystemHeaderGoogle
) {
128 std::string Code
= "#include <memory>\n"
131 std::string Expected
= "#include <memory>\n"
135 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
137 EXPECT_EQ(Expected
, insert(Code
, "\"z.h\""));
140 TEST_F(HeaderIncludesTest
, InsertOneIncludeLLVMStyle
) {
141 std::string Code
= "#include \"x/fix.h\"\n"
144 "#include \"clang/Format/Format.h\"\n"
145 "#include <memory>\n";
146 std::string Expected
= "#include \"x/fix.h\"\n"
149 "#include \"clang/Format/Format.h\"\n"
150 "#include \"llvm/x/y.h\"\n"
151 "#include <memory>\n";
152 EXPECT_EQ(Expected
, insert(Code
, "\"llvm/x/y.h\""));
155 TEST_F(HeaderIncludesTest
, InsertIntoBlockSorted
) {
156 std::string Code
= "#include \"x/fix.h\"\n"
159 "#include <memory>\n";
160 std::string Expected
= "#include \"x/fix.h\"\n"
164 "#include <memory>\n";
165 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
168 TEST_F(HeaderIncludesTest
, InsertIntoFirstBlockOfSameKind
) {
169 std::string Code
= "#include \"x/fix.h\"\n"
173 "#include <memory>\n"
174 "#include <vector>\n"
176 "#include \"n.h\"\n";
177 std::string Expected
= "#include \"x/fix.h\"\n"
182 "#include <memory>\n"
183 "#include <vector>\n"
185 "#include \"n.h\"\n";
186 EXPECT_EQ(Expected
, insert(Code
, "\"d.h\""));
189 TEST_F(HeaderIncludesTest
, InsertIntoSystemBlockSorted
) {
190 std::string Code
= "#include \"x/fix.h\"\n"
195 std::string Expected
= "#include \"x/fix.h\"\n"
199 "#include <vector>\n"
201 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
204 TEST_F(HeaderIncludesTest
, InsertNewSystemIncludeGoogleStyle
) {
205 std::string Code
= "#include \"x/fix.h\"\n"
207 "#include \"y/a.h\"\n"
208 "#include \"z/b.h\"\n";
209 // FIXME: inserting after the empty line following the main header might be
211 std::string Expected
= "#include \"x/fix.h\"\n"
212 "#include <vector>\n"
214 "#include \"y/a.h\"\n"
215 "#include \"z/b.h\"\n";
216 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
218 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
221 TEST_F(HeaderIncludesTest
, NotConfusedByDefine
) {
222 std::string Code
= "void f() {}\n"
225 std::string Expected
= "#include <vector>\n"
229 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
232 TEST_F(HeaderIncludesTest
, SkippedTopComment
) {
233 std::string Code
= "// comment\n"
236 std::string Expected
= "// comment\n"
239 "#include <vector>\n";
240 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
243 TEST_F(HeaderIncludesTest
, SkippedMixedComments
) {
244 std::string Code
= "// comment\n"
246 " comment continued\n"
250 std::string Expected
= "// comment\n"
252 " comment continued\n"
256 "#include <vector>\n";
257 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
260 TEST_F(HeaderIncludesTest
, MultipleBlockCommentsInOneLine
) {
261 std::string Code
= "/*\n"
266 "/* c1 */ /*c2 */\n";
267 std::string Expected
= "/*\n"
273 "#include <vector>\n";
274 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
277 TEST_F(HeaderIncludesTest
, CodeAfterComments
) {
278 std::string Code
= "/*\n"
286 std::string Expected
= "/*\n"
293 "#include <vector>\n"
295 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
298 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfDef
) {
299 std::string Code
= "// comment \n"
302 std::string Expected
= "// comment \n"
303 "#include <vector>\n"
306 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
309 TEST_F(HeaderIncludesTest
, RealHeaderGuardAfterComments
) {
310 std::string Code
= "// comment \n"
315 std::string Expected
= "// comment \n"
318 "#include <vector>\n"
321 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
324 TEST_F(HeaderIncludesTest
, PragmaOnce
) {
325 std::string Code
= "// comment \n"
328 std::string Expected
= "// comment \n"
330 "#include <vector>\n"
332 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
335 TEST_F(HeaderIncludesTest
, IfNDefWithNoDefine
) {
336 std::string Code
= "// comment \n"
340 std::string Expected
= "// comment \n"
341 "#include <vector>\n"
345 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
348 TEST_F(HeaderIncludesTest
, FakeHeaderGuard
) {
349 std::string Code
= "// comment \n"
352 std::string Expected
= "// comment \n"
353 "#include <vector>\n"
356 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
359 TEST_F(HeaderIncludesTest
, FakeHeaderGuardIfnDef
) {
360 std::string Code
= "#ifndef A_H\n"
363 std::string Expected
= "#include \"b.h\"\n"
368 EXPECT_EQ(Expected
, insert(Code
, "\"b.h\""));
371 TEST_F(HeaderIncludesTest
, HeaderGuardWithComment
) {
372 std::string Code
= "// comment \n"
373 "#ifndef X // comment\n"
377 "/* comment */ #define X\n"
380 std::string Expected
= "// comment \n"
381 "#ifndef X // comment\n"
385 "/* comment */ #define X\n"
386 "#include <vector>\n"
389 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
392 TEST_F(HeaderIncludesTest
, EmptyCode
) {
393 std::string Code
= "";
394 std::string Expected
= "#include <vector>\n";
395 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
398 TEST_F(HeaderIncludesTest
, NoNewLineAtTheEndOfCode
) {
399 std::string Code
= "#include <map>";
400 std::string Expected
= "#include <map>\n#include <vector>\n";
401 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
404 TEST_F(HeaderIncludesTest
, SkipExistingHeaders
) {
405 std::string Code
= "#include \"a.h\"\n"
406 "#include <vector>\n";
407 std::string Expected
= "#include \"a.h\"\n"
408 "#include <vector>\n";
409 EXPECT_EQ(Expected
, insert(Code
, "<vector>"));
410 EXPECT_EQ(Expected
, insert(Code
, "\"a.h\""));
413 TEST_F(HeaderIncludesTest
, AddIncludesWithDifferentForms
) {
414 std::string Code
= "#include <vector>\n";
415 // FIXME: this might not be the best behavior.
416 std::string Expected
= "#include \"vector\"\n"
417 "#include <vector>\n";
418 EXPECT_EQ(Expected
, insert(Code
, "\"vector\""));
421 TEST_F(HeaderIncludesTest
, NoInsertionAfterCode
) {
422 std::string Code
= "#include \"a.h\"\n"
424 "#include \"b.h\"\n";
425 std::string Expected
= "#include \"a.h\"\n"
428 "#include \"b.h\"\n";
429 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
432 TEST_F(HeaderIncludesTest
, NoInsertionInStringLiteral
) {
433 std::string Code
= "#include \"a.h\"\n"
434 "const char[] = R\"(\n"
437 std::string Expected
= "#include \"a.h\"\n"
439 "const char[] = R\"(\n"
442 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
445 TEST_F(HeaderIncludesTest
, NoInsertionAfterOtherDirective
) {
446 std::string Code
= "#include \"a.h\"\n"
450 std::string Expected
= "#include \"a.h\"\n"
455 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
458 TEST_F(HeaderIncludesTest
, CanInsertAfterLongSystemInclude
) {
459 std::string Code
= "#include \"a.h\"\n"
461 "#include <a/b/c/d/e.h>\n";
462 std::string Expected
= "#include \"a.h\"\n"
464 "#include <a/b/c/d/e.h>\n"
466 EXPECT_EQ(Expected
, insert(Code
, "<x.h>"));
469 TEST_F(HeaderIncludesTest
, CanInsertAfterComment
) {
470 std::string Code
= "#include \"a.h\"\n"
476 "#include \"b.h\"\n";
477 std::string Expected
= "#include \"a.h\"\n"
484 "#include \"c.h\"\n";
485 EXPECT_EQ(Expected
, insert(Code
, "\"c.h\""));
488 TEST_F(HeaderIncludesTest
, LongCommentsInTheBeginningOfFile
) {
489 std::string Code
= "// Loooooooooooooooooooooooooong comment\n"
490 "// Loooooooooooooooooooooooooong comment\n"
491 "// Loooooooooooooooooooooooooong comment\n"
492 "#include <string>\n"
493 "#include <vector>\n"
496 "#include \"b.h\"\n";
497 std::string Expected
= "// Loooooooooooooooooooooooooong comment\n"
498 "// Loooooooooooooooooooooooooong comment\n"
499 "// Loooooooooooooooooooooooooong comment\n"
500 "#include <string>\n"
501 "#include <vector>\n"
505 "#include \"third.h\"\n";
506 Style
= format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp
)
508 EXPECT_EQ(Expected
, insert(Code
, "\"third.h\""));
511 TEST_F(HeaderIncludesTest
, SimpleDeleteInclude
) {
512 std::string Code
= "#include \"abc.h\"\n"
513 "#include \"xyz.h\" // comment\n"
515 std::string Expected
= "#include \"abc.h\"\n"
517 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
520 TEST_F(HeaderIncludesTest
, DeleteQuotedOnly
) {
521 std::string Code
= "#include \"abc.h\"\n"
524 std::string Expected
= "#include <abc.h>\n"
526 EXPECT_EQ(Expected
, remove(Code
, "\"abc.h\""));
529 TEST_F(HeaderIncludesTest
, DeleteAllCode
) {
530 std::string Code
= "#include \"xyz.h\"\n";
531 std::string Expected
= "";
532 EXPECT_EQ(Expected
, remove(Code
, "\"xyz.h\""));
535 TEST_F(HeaderIncludesTest
, DeleteOnlyIncludesWithSameQuote
) {
536 std::string Code
= "#include \"xyz.h\"\n"
538 "#include <xyz.h>\n";
539 std::string Expected
= "#include \"xyz.h\"\n"
540 "#include \"xyz\"\n";
541 EXPECT_EQ(Expected
, remove(Code
, "<xyz.h>"));
544 TEST_F(HeaderIncludesTest
, CanDeleteAfterCode
) {
545 std::string Code
= "#include \"a.h\"\n"
547 "#include \"b.h\"\n";
548 std::string Expected
= "#include \"a.h\"\n"
550 EXPECT_EQ(Expected
, remove(Code
, "\"b.h\""));
554 } // namespace tooling