Clang Project

clang_source_code/unittests/Tooling/HeaderIncludesTest.cpp
1//===- unittest/Tooling/CleanupTest.cpp - Include insertion/deletion tests ===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
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"
14
15#include "gtest/gtest.h"
16
17namespace clang {
18namespace tooling {
19namespace {
20
21class HeaderIncludesTest : public ::testing::Test {
22protected:
23  std::string insert(llvm::StringRef Codellvm::StringRef Header) {
24    HeaderIncludes Includes(FileName, Code, Style);
25     (0) . __assert_fail ("Header.startswith(\"\\\"\") || Header.startswith(\"<\")", "/home/seafit/code_projects/clang_source/clang/unittests/Tooling/HeaderIncludesTest.cpp", 25, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Header.startswith("\"") || Header.startswith("<"));
26    auto R = Includes.insert(Header.trim("\"<>"), Header.startswith("<"));
27    if (!R)
28      return Code;
29    auto Result = applyAllReplacements(Code, Replacements(*R));
30    EXPECT_TRUE(static_cast<bool>(Result));
31    return *Result;
32  }
33
34  std::string remove(llvm::StringRef Codellvm::StringRef Header) {
35    HeaderIncludes Includes(FileName, Code, Style);
36     (0) . __assert_fail ("Header.startswith(\"\\\"\") || Header.startswith(\"<\")", "/home/seafit/code_projects/clang_source/clang/unittests/Tooling/HeaderIncludesTest.cpp", 36, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">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));
40    return *Result;
41  }
42
43  const std::string FileName = "fix.cpp";
44  IncludeStyle Style = format::getLLVMStyle().IncludeStyle;
45};
46
47TEST_F(HeaderIncludesTest, NoExistingIncludeWithoutDefine) {
48  std::string Code = "int main() {}";
49  std::string Expected = "#include \"a.h\"\n"
50                         "int main() {}";
51  EXPECT_EQ(Expected, insert(Code"\"a.h\""));
52}
53
54TEST_F(HeaderIncludesTest, NoExistingIncludeWithDefine) {
55  std::string Code = "#ifndef A_H\n"
56                     "#define A_H\n"
57                     "class A {};\n"
58                     "#define MMM 123\n"
59                     "#endif";
60  std::string Expected = "#ifndef A_H\n"
61                         "#define A_H\n"
62                         "#include \"b.h\"\n"
63                         "class A {};\n"
64                         "#define MMM 123\n"
65                         "#endif";
66
67  EXPECT_EQ(Expected, insert(Code"\"b.h\""));
68}
69
70TEST_F(HeaderIncludesTest, InsertBeforeCategoryWithLowerPriority) {
71  std::string Code = "#ifndef A_H\n"
72                     "#define A_H\n"
73                     "\n"
74                     "\n"
75                     "\n"
76                     "#include <vector>\n"
77                     "class A {};\n"
78                     "#define MMM 123\n"
79                     "#endif";
80  std::string Expected = "#ifndef A_H\n"
81                         "#define A_H\n"
82                         "\n"
83                         "\n"
84                         "\n"
85                         "#include \"a.h\"\n"
86                         "#include <vector>\n"
87                         "class A {};\n"
88                         "#define MMM 123\n"
89                         "#endif";
90
91  EXPECT_EQ(Expected, insert(Code"\"a.h\""));
92}
93
94TEST_F(HeaderIncludesTest, InsertAfterMainHeader) {
95  std::string Code = "#include \"fix.h\"\n"
96                     "\n"
97                     "int main() {}";
98  std::string Expected = "#include \"fix.h\"\n"
99                         "#include <a>\n"
100                         "\n"
101                         "int main() {}";
102  Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
103              .IncludeStyle;
104  EXPECT_EQ(Expected, insert(Code"<a>"));
105}
106
107TEST_F(HeaderIncludesTest, InsertBeforeSystemHeaderLLVM) {
108  std::string Code = "#include <memory>\n"
109                     "\n"
110                     "int main() {}";
111  std::string Expected = "#include \"z.h\"\n"
112                         "#include <memory>\n"
113                         "\n"
114                         "int main() {}";
115  EXPECT_EQ(Expected, insert(Code"\"z.h\""));
116}
117
118TEST_F(HeaderIncludesTest, InsertAfterSystemHeaderGoogle) {
119  std::string Code = "#include <memory>\n"
120                     "\n"
121                     "int main() {}";
122  std::string Expected = "#include <memory>\n"
123                         "#include \"z.h\"\n"
124                         "\n"
125                         "int main() {}";
126  Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
127              .IncludeStyle;
128  EXPECT_EQ(Expected, insert(Code"\"z.h\""));
129}
130
131TEST_F(HeaderIncludesTest, InsertOneIncludeLLVMStyle) {
132  std::string Code = "#include \"x/fix.h\"\n"
133                     "#include \"a.h\"\n"
134                     "#include \"b.h\"\n"
135                     "#include \"clang/Format/Format.h\"\n"
136                     "#include <memory>\n";
137  std::string Expected = "#include \"x/fix.h\"\n"
138                         "#include \"a.h\"\n"
139                         "#include \"b.h\"\n"
140                         "#include \"clang/Format/Format.h\"\n"
141                         "#include \"llvm/x/y.h\"\n"
142                         "#include <memory>\n";
143  EXPECT_EQ(Expected, insert(Code"\"llvm/x/y.h\""));
144}
145
146TEST_F(HeaderIncludesTest, InsertIntoBlockSorted) {
147  std::string Code = "#include \"x/fix.h\"\n"
148                     "#include \"a.h\"\n"
149                     "#include \"c.h\"\n"
150                     "#include <memory>\n";
151  std::string Expected = "#include \"x/fix.h\"\n"
152                         "#include \"a.h\"\n"
153                         "#include \"b.h\"\n"
154                         "#include \"c.h\"\n"
155                         "#include <memory>\n";
156  EXPECT_EQ(Expected, insert(Code"\"b.h\""));
157}
158
159TEST_F(HeaderIncludesTest, InsertIntoFirstBlockOfSameKind) {
160  std::string Code = "#include \"x/fix.h\"\n"
161                     "#include \"c.h\"\n"
162                     "#include \"e.h\"\n"
163                     "#include \"f.h\"\n"
164                     "#include <memory>\n"
165                     "#include <vector>\n"
166                     "#include \"m.h\"\n"
167                     "#include \"n.h\"\n";
168  std::string Expected = "#include \"x/fix.h\"\n"
169                         "#include \"c.h\"\n"
170                         "#include \"d.h\"\n"
171                         "#include \"e.h\"\n"
172                         "#include \"f.h\"\n"
173                         "#include <memory>\n"
174                         "#include <vector>\n"
175                         "#include \"m.h\"\n"
176                         "#include \"n.h\"\n";
177  EXPECT_EQ(Expected, insert(Code"\"d.h\""));
178}
179
180TEST_F(HeaderIncludesTest, InsertIntoSystemBlockSorted) {
181  std::string Code = "#include \"x/fix.h\"\n"
182                     "#include \"a.h\"\n"
183                     "#include \"c.h\"\n"
184                     "#include <a>\n"
185                     "#include <z>\n";
186  std::string Expected = "#include \"x/fix.h\"\n"
187                         "#include \"a.h\"\n"
188                         "#include \"c.h\"\n"
189                         "#include <a>\n"
190                         "#include <vector>\n"
191                         "#include <z>\n";
192  EXPECT_EQ(Expected, insert(Code"<vector>"));
193}
194
195TEST_F(HeaderIncludesTest, InsertNewSystemIncludeGoogleStyle) {
196  std::string Code = "#include \"x/fix.h\"\n"
197                     "\n"
198                     "#include \"y/a.h\"\n"
199                     "#include \"z/b.h\"\n";
200  // FIXME: inserting after the empty line following the main header might be
201  // preferred.
202  std::string Expected = "#include \"x/fix.h\"\n"
203                         "#include <vector>\n"
204                         "\n"
205                         "#include \"y/a.h\"\n"
206                         "#include \"z/b.h\"\n";
207  Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
208              .IncludeStyle;
209  EXPECT_EQ(Expected, insert(Code"<vector>"));
210}
211
212TEST_F(HeaderIncludesTest, NotConfusedByDefine) {
213  std::string Code = "void f() {}\n"
214                     "#define A \\\n"
215                     "  int i;";
216  std::string Expected = "#include <vector>\n"
217                         "void f() {}\n"
218                         "#define A \\\n"
219                         "  int i;";
220  EXPECT_EQ(Expected, insert(Code"<vector>"));
221}
222
223TEST_F(HeaderIncludesTest, SkippedTopComment) {
224  std::string Code = "// comment\n"
225                     "\n"
226                     "   // comment\n";
227  std::string Expected = "// comment\n"
228                         "\n"
229                         "   // comment\n"
230                         "#include <vector>\n";
231  EXPECT_EQ(Expected, insert(Code"<vector>"));
232}
233
234TEST_F(HeaderIncludesTest, SkippedMixedComments) {
235  std::string Code = "// comment\n"
236                     "// comment \\\n"
237                     " comment continued\n"
238                     "/*\n"
239                     "* comment\n"
240                     "*/\n";
241  std::string Expected = "// comment\n"
242                         "// comment \\\n"
243                         " comment continued\n"
244                         "/*\n"
245                         "* comment\n"
246                         "*/\n"
247                         "#include <vector>\n";
248  EXPECT_EQ(Expected, insert(Code"<vector>"));
249}
250
251TEST_F(HeaderIncludesTest, MultipleBlockCommentsInOneLine) {
252  std::string Code = "/*\n"
253                     "* comment\n"
254                     "*/ /* comment\n"
255                     "*/\n"
256                     "\n\n"
257                     "/* c1 */ /*c2 */\n";
258  std::string Expected = "/*\n"
259                         "* comment\n"
260                         "*/ /* comment\n"
261                         "*/\n"
262                         "\n\n"
263                         "/* c1 */ /*c2 */\n"
264                         "#include <vector>\n";
265  EXPECT_EQ(Expected, insert(Code"<vector>"));
266}
267
268TEST_F(HeaderIncludesTest, CodeAfterComments) {
269  std::string Code = "/*\n"
270                     "* comment\n"
271                     "*/ /* comment\n"
272                     "*/\n"
273                     "\n\n"
274                     "/* c1 */ /*c2 */\n"
275                     "\n"
276                     "int x;\n";
277  std::string Expected = "/*\n"
278                         "* comment\n"
279                         "*/ /* comment\n"
280                         "*/\n"
281                         "\n\n"
282                         "/* c1 */ /*c2 */\n"
283                         "\n"
284                         "#include <vector>\n"
285                         "int x;\n";
286  EXPECT_EQ(Expected, insert(Code"<vector>"));
287}
288
289TEST_F(HeaderIncludesTest, FakeHeaderGuardIfDef) {
290  std::string Code = "// comment \n"
291                     "#ifdef X\n"
292                     "#define X\n";
293  std::string Expected = "// comment \n"
294                         "#include <vector>\n"
295                         "#ifdef X\n"
296                         "#define X\n";
297  EXPECT_EQ(Expected, insert(Code"<vector>"));
298}
299
300TEST_F(HeaderIncludesTest, RealHeaderGuardAfterComments) {
301  std::string Code = "// comment \n"
302                     "#ifndef X\n"
303                     "#define X\n"
304                     "int x;\n"
305                     "#define Y 1\n";
306  std::string Expected = "// comment \n"
307                         "#ifndef X\n"
308                         "#define X\n"
309                         "#include <vector>\n"
310                         "int x;\n"
311                         "#define Y 1\n";
312  EXPECT_EQ(Expected, insert(Code"<vector>"));
313}
314
315TEST_F(HeaderIncludesTest, PragmaOnce) {
316  std::string Code = "// comment \n"
317                     "#pragma once\n"
318                     "int x;\n";
319  std::string Expected = "// comment \n"
320                         "#pragma once\n"
321                         "#include <vector>\n"
322                         "int x;\n";
323  EXPECT_EQ(Expected, insert(Code"<vector>"));
324}
325
326TEST_F(HeaderIncludesTest, IfNDefWithNoDefine) {
327  std::string Code = "// comment \n"
328                     "#ifndef X\n"
329                     "int x;\n"
330                     "#define Y 1\n";
331  std::string Expected = "// comment \n"
332                         "#include <vector>\n"
333                         "#ifndef X\n"
334                         "int x;\n"
335                         "#define Y 1\n";
336  EXPECT_EQ(Expected, insert(Code"<vector>"));
337}
338
339TEST_F(HeaderIncludesTest, FakeHeaderGuard) {
340  std::string Code = "// comment \n"
341                     "#ifndef X\n"
342                     "#define 1\n";
343  std::string Expected = "// comment \n"
344                         "#include <vector>\n"
345                         "#ifndef X\n"
346                         "#define 1\n";
347  EXPECT_EQ(Expected, insert(Code"<vector>"));
348}
349
350TEST_F(HeaderIncludesTest, HeaderGuardWithComment) {
351  std::string Code = "// comment \n"
352                     "#ifndef X // comment\n"
353                     "// comment\n"
354                     "/* comment\n"
355                     "*/\n"
356                     "/* comment */ #define X\n"
357                     "int x;\n"
358                     "#define Y 1\n";
359  std::string Expected = "// comment \n"
360                         "#ifndef X // comment\n"
361                         "// comment\n"
362                         "/* comment\n"
363                         "*/\n"
364                         "/* comment */ #define X\n"
365                         "#include <vector>\n"
366                         "int x;\n"
367                         "#define Y 1\n";
368  EXPECT_EQ(Expected, insert(Code"<vector>"));
369}
370
371TEST_F(HeaderIncludesTest, EmptyCode) {
372  std::string Code = "";
373  std::string Expected = "#include <vector>\n";
374  EXPECT_EQ(Expected, insert(Code"<vector>"));
375}
376
377TEST_F(HeaderIncludesTest, NoNewLineAtTheEndOfCode) {
378  std::string Code = "#include <map>";
379  std::string Expected = "#include <map>\n#include <vector>\n";
380  EXPECT_EQ(Expected, insert(Code"<vector>"));
381}
382
383TEST_F(HeaderIncludesTest, SkipExistingHeaders) {
384  std::string Code = "#include \"a.h\"\n"
385                     "#include <vector>\n";
386  std::string Expected = "#include \"a.h\"\n"
387                         "#include <vector>\n";
388  EXPECT_EQ(Expected, insert(Code"<vector>"));
389  EXPECT_EQ(Expected, insert(Code"\"a.h\""));
390}
391
392TEST_F(HeaderIncludesTest, AddIncludesWithDifferentForms) {
393  std::string Code = "#include <vector>\n";
394  // FIXME: this might not be the best behavior.
395  std::string Expected = "#include \"vector\"\n"
396                         "#include <vector>\n";
397  EXPECT_EQ(Expected, insert(Code"\"vector\""));
398}
399
400TEST_F(HeaderIncludesTest, NoInsertionAfterCode) {
401  std::string Code = "#include \"a.h\"\n"
402                     "void f() {}\n"
403                     "#include \"b.h\"\n";
404  std::string Expected = "#include \"a.h\"\n"
405                         "#include \"c.h\"\n"
406                         "void f() {}\n"
407                         "#include \"b.h\"\n";
408  EXPECT_EQ(Expected, insert(Code"\"c.h\""));
409}
410
411TEST_F(HeaderIncludesTest, NoInsertionInStringLiteral) {
412  std::string Code = "#include \"a.h\"\n"
413                     "const char[] = R\"(\n"
414                     "#include \"b.h\"\n"
415                     ")\";\n";
416  std::string Expected = "#include \"a.h\"\n"
417                         "#include \"c.h\"\n"
418                         "const char[] = R\"(\n"
419                         "#include \"b.h\"\n"
420                         ")\";\n";
421  EXPECT_EQ(Expected, insert(Code"\"c.h\""));
422}
423
424TEST_F(HeaderIncludesTest, NoInsertionAfterOtherDirective) {
425  std::string Code = "#include \"a.h\"\n"
426                     "#ifdef X\n"
427                     "#include \"b.h\"\n"
428                     "#endif\n";
429  std::string Expected = "#include \"a.h\"\n"
430                         "#include \"c.h\"\n"
431                         "#ifdef X\n"
432                         "#include \"b.h\"\n"
433                         "#endif\n";
434  EXPECT_EQ(Expected, insert(Code"\"c.h\""));
435}
436
437TEST_F(HeaderIncludesTest, CanInsertAfterLongSystemInclude) {
438  std::string Code = "#include \"a.h\"\n"
439                     "// comment\n\n"
440                     "#include <a/b/c/d/e.h>\n";
441  std::string Expected = "#include \"a.h\"\n"
442                         "// comment\n\n"
443                         "#include <a/b/c/d/e.h>\n"
444                         "#include <x.h>\n";
445  EXPECT_EQ(Expected, insert(Code"<x.h>"));
446}
447
448TEST_F(HeaderIncludesTest, CanInsertAfterComment) {
449  std::string Code = "#include \"a.h\"\n"
450                     "// Comment\n"
451                     "\n"
452                     "/* Comment */\n"
453                     "// Comment\n"
454                     "\n"
455                     "#include \"b.h\"\n";
456  std::string Expected = "#include \"a.h\"\n"
457                         "// Comment\n"
458                         "\n"
459                         "/* Comment */\n"
460                         "// Comment\n"
461                         "\n"
462                         "#include \"b.h\"\n"
463                         "#include \"c.h\"\n";
464  EXPECT_EQ(Expected, insert(Code"\"c.h\""));
465}
466
467TEST_F(HeaderIncludesTest, LongCommentsInTheBeginningOfFile) {
468  std::string Code = "// Loooooooooooooooooooooooooong comment\n"
469                     "// Loooooooooooooooooooooooooong comment\n"
470                     "// Loooooooooooooooooooooooooong comment\n"
471                     "#include <string>\n"
472                     "#include <vector>\n"
473                     "\n"
474                     "#include \"a.h\"\n"
475                     "#include \"b.h\"\n";
476  std::string Expected = "// Loooooooooooooooooooooooooong comment\n"
477                         "// Loooooooooooooooooooooooooong comment\n"
478                         "// Loooooooooooooooooooooooooong comment\n"
479                         "#include <string>\n"
480                         "#include <vector>\n"
481                         "\n"
482                         "#include \"a.h\"\n"
483                         "#include \"b.h\"\n"
484                         "#include \"third.h\"\n";
485  Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp)
486              .IncludeStyle;
487  EXPECT_EQ(Expected, insert(Code"\"third.h\""));
488}
489
490TEST_F(HeaderIncludesTest, SimpleDeleteInclude) {
491  std::string Code = "#include \"abc.h\"\n"
492                     "#include \"xyz.h\" // comment\n"
493                     "int x;\n";
494  std::string Expected = "#include \"abc.h\"\n"
495                         "int x;\n";
496  EXPECT_EQ(Expected, remove(Code"\"xyz.h\""));
497}
498
499TEST_F(HeaderIncludesTest, DeleteQuotedOnly) {
500  std::string Code = "#include \"abc.h\"\n"
501                     "#include <abc.h>\n"
502                     "int x;\n";
503  std::string Expected = "#include <abc.h>\n"
504                         "int x;\n";
505  EXPECT_EQ(Expected, remove(Code"\"abc.h\""));
506}
507
508TEST_F(HeaderIncludesTest, DeleteAllCode) {
509  std::string Code = "#include \"xyz.h\"\n";
510  std::string Expected = "";
511  EXPECT_EQ(Expected, remove(Code"\"xyz.h\""));
512}
513
514TEST_F(HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) {
515  std::string Code = "#include \"xyz.h\"\n"
516                     "#include \"xyz\"\n"
517                     "#include <xyz.h>\n";
518  std::string Expected = "#include \"xyz.h\"\n"
519                         "#include \"xyz\"\n";
520  EXPECT_EQ(Expected, remove(Code"<xyz.h>"));
521}
522
523TEST_F(HeaderIncludesTest, CanDeleteAfterCode) {
524  std::string Code = "#include \"a.h\"\n"
525                     "void f() {}\n"
526                     "#include \"b.h\"\n";
527  std::string Expected = "#include \"a.h\"\n"
528                         "void f() {}\n";
529  EXPECT_EQ(Expected, remove(Code"\"b.h\""));
530}
531
532// namespace
533// namespace tooling
534// namespace clang
535