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 | |
17 | namespace clang { |
18 | namespace tooling { |
19 | namespace { |
20 | |
21 | class : public ::testing::Test { |
22 | protected: |
23 | std::string (llvm::StringRef Code, llvm::StringRef , |
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: Header.trim(Chars: "\"<>" ), IsAngled: Header.starts_with(Prefix: "<" ), |
28 | Directive); |
29 | if (!R) |
30 | return std::string(Code); |
31 | auto Result = applyAllReplacements(Code, Replaces: Replacements(*R)); |
32 | EXPECT_TRUE(static_cast<bool>(Result)); |
33 | return *Result; |
34 | } |
35 | |
36 | std::string (llvm::StringRef Code, llvm::StringRef ) { |
37 | HeaderIncludes Includes(FileName, Code, Style); |
38 | assert(Header.starts_with("\"" ) || Header.starts_with("<" )); |
39 | auto Replaces = |
40 | Includes.remove(Header: Header.trim(Chars: "\"<>" ), IsAngled: Header.starts_with(Prefix: "<" )); |
41 | auto Result = applyAllReplacements(Code, Replaces); |
42 | EXPECT_TRUE(static_cast<bool>(Result)); |
43 | return *Result; |
44 | } |
45 | |
46 | std::string = "fix.cpp" ; |
47 | IncludeStyle = format::getLLVMStyle().IncludeStyle; |
48 | }; |
49 | |
50 | TEST_F(HeaderIncludesTest, NoExistingIncludeWithoutDefine) { |
51 | std::string Code = "int main() {}" ; |
52 | std::string Expected = "#include \"a.h\"\n" |
53 | "int main() {}" ; |
54 | EXPECT_EQ(Expected, insert(Code, "\"a.h\"" )); |
55 | } |
56 | |
57 | TEST_F(HeaderIncludesTest, RepeatedIncludes) { |
58 | std::string Code; |
59 | for (int i = 0; i < 100; ++i) { |
60 | Code += "#include \"a.h\"\n" ; |
61 | } |
62 | std::string Expected = Code + "#include \"a2.h\"\n" ; |
63 | EXPECT_EQ(Expected, insert(Code, "\"a2.h\"" )); |
64 | } |
65 | |
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)); |
70 | } |
71 | |
72 | TEST_F(HeaderIncludesTest, DontInsertAlreadyImported) { |
73 | std::string Code = "#import \"a.h\"\n" ; |
74 | EXPECT_EQ(Code, insert(Code, "\"a.h\"" , IncludeDirective::Import)); |
75 | } |
76 | |
77 | TEST_F(HeaderIncludesTest, DeleteImportAndSameInclude) { |
78 | std::string Code = R"cpp( |
79 | #include <abc.h> |
80 | #import <abc.h> |
81 | int x;)cpp" ; |
82 | EXPECT_EQ("\nint x;" , remove(Code, "<abc.h>" )); |
83 | } |
84 | |
85 | TEST_F(HeaderIncludesTest, NoExistingIncludeWithDefine) { |
86 | std::string Code = "#ifndef A_H\n" |
87 | "#define A_H\n" |
88 | "class A {};\n" |
89 | "#define MMM 123\n" |
90 | "#endif" ; |
91 | std::string Expected = "#ifndef A_H\n" |
92 | "#define A_H\n" |
93 | "#include \"b.h\"\n" |
94 | "class A {};\n" |
95 | "#define MMM 123\n" |
96 | "#endif" ; |
97 | |
98 | EXPECT_EQ(Expected, insert(Code, "\"b.h\"" )); |
99 | } |
100 | |
101 | TEST_F(HeaderIncludesTest, InsertBeforeCategoryWithLowerPriority) { |
102 | std::string Code = "#ifndef A_H\n" |
103 | "#define A_H\n" |
104 | "\n" |
105 | "\n" |
106 | "\n" |
107 | "#include <vector>\n" |
108 | "class A {};\n" |
109 | "#define MMM 123\n" |
110 | "#endif" ; |
111 | std::string Expected = "#ifndef A_H\n" |
112 | "#define A_H\n" |
113 | "\n" |
114 | "\n" |
115 | "\n" |
116 | "#include \"a.h\"\n" |
117 | "#include <vector>\n" |
118 | "class A {};\n" |
119 | "#define MMM 123\n" |
120 | "#endif" ; |
121 | |
122 | EXPECT_EQ(Expected, insert(Code, "\"a.h\"" )); |
123 | } |
124 | |
125 | TEST_F(HeaderIncludesTest, InsertAfterMainHeader) { |
126 | std::string Code = "#include \"fix.h\"\n" |
127 | "\n" |
128 | "int main() {}" ; |
129 | std::string Expected = "#include \"fix.h\"\n" |
130 | "#include <a>\n" |
131 | "\n" |
132 | "int main() {}" ; |
133 | Style = format::getGoogleStyle(Language: format::FormatStyle::LanguageKind::LK_Cpp) |
134 | .IncludeStyle; |
135 | EXPECT_EQ(Expected, insert(Code, "<a>" )); |
136 | |
137 | FileName = "fix.cu.cpp" ; |
138 | EXPECT_EQ(Expected, insert(Code, "<a>" )); |
139 | |
140 | FileName = "fix_test.cu.cpp" ; |
141 | EXPECT_EQ(Expected, insert(Code, "<a>" )); |
142 | |
143 | FileName = "bar.cpp" ; |
144 | EXPECT_NE(Expected, insert(Code, "<a>" )) << "Not main header" ; |
145 | } |
146 | |
147 | TEST_F(HeaderIncludesTest, InsertMainHeader) { |
148 | Style = format::getGoogleStyle(Language: format::FormatStyle::LanguageKind::LK_Cpp) |
149 | .IncludeStyle; |
150 | FileName = "fix.cpp" ; |
151 | EXPECT_EQ(R"cpp(#include "fix.h" |
152 | #include "a.h")cpp" , insert("#include \"a.h\"" , "\"fix.h\"" )); |
153 | |
154 | // Respect the original main-file header. |
155 | EXPECT_EQ(R"cpp(#include "z/fix.h" |
156 | #include "a/fix.h" |
157 | )cpp" , insert("#include \"z/fix.h\"" , "\"a/fix.h\"" )); |
158 | } |
159 | |
160 | TEST_F(HeaderIncludesTest, InsertBeforeSystemHeaderLLVM) { |
161 | std::string Code = "#include <memory>\n" |
162 | "\n" |
163 | "int main() {}" ; |
164 | std::string Expected = "#include \"z.h\"\n" |
165 | "#include <memory>\n" |
166 | "\n" |
167 | "int main() {}" ; |
168 | EXPECT_EQ(Expected, insert(Code, "\"z.h\"" )); |
169 | } |
170 | |
171 | TEST_F(HeaderIncludesTest, InsertAfterSystemHeaderGoogle) { |
172 | std::string Code = "#include <memory>\n" |
173 | "\n" |
174 | "int main() {}" ; |
175 | std::string Expected = "#include <memory>\n" |
176 | "#include \"z.h\"\n" |
177 | "\n" |
178 | "int main() {}" ; |
179 | Style = format::getGoogleStyle(Language: format::FormatStyle::LanguageKind::LK_Cpp) |
180 | .IncludeStyle; |
181 | EXPECT_EQ(Expected, insert(Code, "\"z.h\"" )); |
182 | } |
183 | |
184 | TEST_F(HeaderIncludesTest, InsertOneIncludeLLVMStyle) { |
185 | std::string Code = "#include \"x/fix.h\"\n" |
186 | "#include \"a.h\"\n" |
187 | "#include \"b.h\"\n" |
188 | "#include \"clang/Format/Format.h\"\n" |
189 | "#include <memory>\n" ; |
190 | std::string Expected = "#include \"x/fix.h\"\n" |
191 | "#include \"a.h\"\n" |
192 | "#include \"b.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\"" )); |
197 | } |
198 | |
199 | TEST_F(HeaderIncludesTest, InsertIntoBlockSorted) { |
200 | std::string Code = "#include \"x/fix.h\"\n" |
201 | "#include \"a.h\"\n" |
202 | "#include \"c.h\"\n" |
203 | "#include <memory>\n" ; |
204 | std::string Expected = "#include \"x/fix.h\"\n" |
205 | "#include \"a.h\"\n" |
206 | "#include \"b.h\"\n" |
207 | "#include \"c.h\"\n" |
208 | "#include <memory>\n" ; |
209 | EXPECT_EQ(Expected, insert(Code, "\"b.h\"" )); |
210 | } |
211 | |
212 | TEST_F(HeaderIncludesTest, InsertIntoFirstBlockOfSameKind) { |
213 | std::string Code = "#include \"x/fix.h\"\n" |
214 | "#include \"c.h\"\n" |
215 | "#include \"e.h\"\n" |
216 | "#include \"f.h\"\n" |
217 | "#include <memory>\n" |
218 | "#include <vector>\n" |
219 | "#include \"m.h\"\n" |
220 | "#include \"n.h\"\n" ; |
221 | std::string Expected = "#include \"x/fix.h\"\n" |
222 | "#include \"c.h\"\n" |
223 | "#include \"d.h\"\n" |
224 | "#include \"e.h\"\n" |
225 | "#include \"f.h\"\n" |
226 | "#include <memory>\n" |
227 | "#include <vector>\n" |
228 | "#include \"m.h\"\n" |
229 | "#include \"n.h\"\n" ; |
230 | EXPECT_EQ(Expected, insert(Code, "\"d.h\"" )); |
231 | } |
232 | |
233 | TEST_F(HeaderIncludesTest, InsertIntoSystemBlockSorted) { |
234 | std::string Code = "#include \"x/fix.h\"\n" |
235 | "#include \"a.h\"\n" |
236 | "#include \"c.h\"\n" |
237 | "#include <a>\n" |
238 | "#include <z>\n" ; |
239 | std::string Expected = "#include \"x/fix.h\"\n" |
240 | "#include \"a.h\"\n" |
241 | "#include \"c.h\"\n" |
242 | "#include <a>\n" |
243 | "#include <vector>\n" |
244 | "#include <z>\n" ; |
245 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
246 | } |
247 | |
248 | TEST_F(HeaderIncludesTest, InsertNewSystemIncludeGoogleStyle) { |
249 | std::string Code = "#include \"x/fix.h\"\n" |
250 | "\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 |
254 | // preferred. |
255 | std::string Expected = "#include \"x/fix.h\"\n" |
256 | "#include <vector>\n" |
257 | "\n" |
258 | "#include \"y/a.h\"\n" |
259 | "#include \"z/b.h\"\n" ; |
260 | Style = format::getGoogleStyle(Language: format::FormatStyle::LanguageKind::LK_Cpp) |
261 | .IncludeStyle; |
262 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
263 | } |
264 | |
265 | TEST_F(HeaderIncludesTest, NotConfusedByDefine) { |
266 | std::string Code = "void f() {}\n" |
267 | "#define A \\\n" |
268 | " int i;" ; |
269 | std::string Expected = "#include <vector>\n" |
270 | "void f() {}\n" |
271 | "#define A \\\n" |
272 | " int i;" ; |
273 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
274 | } |
275 | |
276 | TEST_F(HeaderIncludesTest, SkippedTopComment) { |
277 | std::string Code = "// comment\n" |
278 | "\n" |
279 | " // comment\n" ; |
280 | std::string Expected = "// comment\n" |
281 | "\n" |
282 | " // comment\n" |
283 | "#include <vector>\n" ; |
284 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
285 | } |
286 | |
287 | TEST_F(HeaderIncludesTest, SkippedMixedComments) { |
288 | std::string Code = "// comment\n" |
289 | "// comment \\\n" |
290 | " comment continued\n" |
291 | "/*\n" |
292 | "* comment\n" |
293 | "*/\n" ; |
294 | std::string Expected = "// comment\n" |
295 | "// comment \\\n" |
296 | " comment continued\n" |
297 | "/*\n" |
298 | "* comment\n" |
299 | "*/\n" |
300 | "#include <vector>\n" ; |
301 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
302 | } |
303 | |
304 | TEST_F(HeaderIncludesTest, MultipleBlockCommentsInOneLine) { |
305 | std::string Code = "/*\n" |
306 | "* comment\n" |
307 | "*/ /* comment\n" |
308 | "*/\n" |
309 | "\n\n" |
310 | "/* c1 */ /*c2 */\n" ; |
311 | std::string Expected = "/*\n" |
312 | "* comment\n" |
313 | "*/ /* comment\n" |
314 | "*/\n" |
315 | "\n\n" |
316 | "/* c1 */ /*c2 */\n" |
317 | "#include <vector>\n" ; |
318 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
319 | } |
320 | |
321 | TEST_F(HeaderIncludesTest, CodeAfterComments) { |
322 | std::string Code = "/*\n" |
323 | "* comment\n" |
324 | "*/ /* comment\n" |
325 | "*/\n" |
326 | "\n\n" |
327 | "/* c1 */ /*c2 */\n" |
328 | "\n" |
329 | "int x;\n" ; |
330 | std::string Expected = "/*\n" |
331 | "* comment\n" |
332 | "*/ /* comment\n" |
333 | "*/\n" |
334 | "\n\n" |
335 | "/* c1 */ /*c2 */\n" |
336 | "\n" |
337 | "#include <vector>\n" |
338 | "int x;\n" ; |
339 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
340 | } |
341 | |
342 | TEST_F(HeaderIncludesTest, FakeHeaderGuardIfDef) { |
343 | std::string Code = "// comment \n" |
344 | "#ifdef X\n" |
345 | "#define X\n" ; |
346 | std::string Expected = "// comment \n" |
347 | "#include <vector>\n" |
348 | "#ifdef X\n" |
349 | "#define X\n" ; |
350 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
351 | } |
352 | |
353 | TEST_F(HeaderIncludesTest, RealHeaderGuardAfterComments) { |
354 | std::string Code = "// comment \n" |
355 | "#ifndef X\n" |
356 | "#define X\n" |
357 | "int x;\n" |
358 | "#define Y 1\n" ; |
359 | std::string Expected = "// comment \n" |
360 | "#ifndef X\n" |
361 | "#define X\n" |
362 | "#include <vector>\n" |
363 | "int x;\n" |
364 | "#define Y 1\n" ; |
365 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
366 | } |
367 | |
368 | TEST_F(HeaderIncludesTest, PragmaOnce) { |
369 | std::string Code = "// comment \n" |
370 | "#pragma once\n" |
371 | "int x;\n" ; |
372 | std::string Expected = "// comment \n" |
373 | "#pragma once\n" |
374 | "#include <vector>\n" |
375 | "int x;\n" ; |
376 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
377 | } |
378 | |
379 | TEST_F(HeaderIncludesTest, IfNDefWithNoDefine) { |
380 | std::string Code = "// comment \n" |
381 | "#ifndef X\n" |
382 | "int x;\n" |
383 | "#define Y 1\n" ; |
384 | std::string Expected = "// comment \n" |
385 | "#include <vector>\n" |
386 | "#ifndef X\n" |
387 | "int x;\n" |
388 | "#define Y 1\n" ; |
389 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
390 | } |
391 | |
392 | TEST_F(HeaderIncludesTest, FakeHeaderGuard) { |
393 | std::string Code = "// comment \n" |
394 | "#ifndef X\n" |
395 | "#define 1\n" ; |
396 | std::string Expected = "// comment \n" |
397 | "#include <vector>\n" |
398 | "#ifndef X\n" |
399 | "#define 1\n" ; |
400 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
401 | } |
402 | |
403 | TEST_F(HeaderIncludesTest, FakeHeaderGuardIfnDef) { |
404 | std::string Code = "#ifndef A_H\n" |
405 | "#define A_H 1\n" |
406 | "#endif" ; |
407 | std::string Expected = "#include \"b.h\"\n" |
408 | "#ifndef A_H\n" |
409 | "#define A_H 1\n" |
410 | "#endif" ; |
411 | |
412 | EXPECT_EQ(Expected, insert(Code, "\"b.h\"" )); |
413 | } |
414 | |
415 | TEST_F(HeaderIncludesTest, HeaderGuardWithComment) { |
416 | std::string Code = "// comment \n" |
417 | "#ifndef X // comment\n" |
418 | "// comment\n" |
419 | "/* comment\n" |
420 | "*/\n" |
421 | "/* comment */ #define X\n" |
422 | "int x;\n" |
423 | "#define Y 1\n" ; |
424 | std::string Expected = "// comment \n" |
425 | "#ifndef X // comment\n" |
426 | "// comment\n" |
427 | "/* comment\n" |
428 | "*/\n" |
429 | "/* comment */ #define X\n" |
430 | "#include <vector>\n" |
431 | "int x;\n" |
432 | "#define Y 1\n" ; |
433 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
434 | } |
435 | |
436 | TEST_F(HeaderIncludesTest, EmptyCode) { |
437 | std::string Code = "" ; |
438 | std::string Expected = "#include <vector>\n" ; |
439 | EXPECT_EQ(Expected, insert(Code, "<vector>" )); |
440 | } |
441 | |
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>" )); |
446 | } |
447 | |
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\"" )); |
455 | } |
456 | |
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\"" )); |
463 | } |
464 | |
465 | TEST_F(HeaderIncludesTest, NoInsertionAfterCode) { |
466 | std::string Code = "#include \"a.h\"\n" |
467 | "void f() {}\n" |
468 | "#include \"b.h\"\n" ; |
469 | std::string Expected = "#include \"a.h\"\n" |
470 | "#include \"c.h\"\n" |
471 | "void f() {}\n" |
472 | "#include \"b.h\"\n" ; |
473 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"" )); |
474 | } |
475 | |
476 | TEST_F(HeaderIncludesTest, NoInsertionInStringLiteral) { |
477 | std::string Code = "#include \"a.h\"\n" |
478 | "const char[] = R\"(\n" |
479 | "#include \"b.h\"\n" |
480 | ")\";\n" ; |
481 | std::string Expected = "#include \"a.h\"\n" |
482 | "#include \"c.h\"\n" |
483 | "const char[] = R\"(\n" |
484 | "#include \"b.h\"\n" |
485 | ")\";\n" ; |
486 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"" )); |
487 | } |
488 | |
489 | TEST_F(HeaderIncludesTest, NoInsertionAfterOtherDirective) { |
490 | std::string Code = "#include \"a.h\"\n" |
491 | "#ifdef X\n" |
492 | "#include \"b.h\"\n" |
493 | "#endif\n" ; |
494 | std::string Expected = "#include \"a.h\"\n" |
495 | "#include \"c.h\"\n" |
496 | "#ifdef X\n" |
497 | "#include \"b.h\"\n" |
498 | "#endif\n" ; |
499 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"" )); |
500 | } |
501 | |
502 | TEST_F(HeaderIncludesTest, CanInsertAfterLongSystemInclude) { |
503 | std::string Code = "#include \"a.h\"\n" |
504 | "// comment\n\n" |
505 | "#include <a/b/c/d/e.h>\n" ; |
506 | std::string Expected = "#include \"a.h\"\n" |
507 | "// comment\n\n" |
508 | "#include <a/b/c/d/e.h>\n" |
509 | "#include <x.h>\n" ; |
510 | EXPECT_EQ(Expected, insert(Code, "<x.h>" )); |
511 | } |
512 | |
513 | TEST_F(HeaderIncludesTest, CanInsertAfterComment) { |
514 | std::string Code = "#include \"a.h\"\n" |
515 | "// Comment\n" |
516 | "\n" |
517 | "/* Comment */\n" |
518 | "// Comment\n" |
519 | "\n" |
520 | "#include \"b.h\"\n" ; |
521 | std::string Expected = "#include \"a.h\"\n" |
522 | "// Comment\n" |
523 | "\n" |
524 | "/* Comment */\n" |
525 | "// Comment\n" |
526 | "\n" |
527 | "#include \"b.h\"\n" |
528 | "#include \"c.h\"\n" ; |
529 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"" )); |
530 | } |
531 | |
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" |
538 | "\n" |
539 | "#include \"a.h\"\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" |
546 | "\n" |
547 | "#include \"a.h\"\n" |
548 | "#include \"b.h\"\n" |
549 | "#include \"third.h\"\n" ; |
550 | Style = format::getGoogleStyle(Language: format::FormatStyle::LanguageKind::LK_Cpp) |
551 | .IncludeStyle; |
552 | EXPECT_EQ(Expected, insert(Code, "\"third.h\"" )); |
553 | } |
554 | |
555 | TEST_F(HeaderIncludesTest, SimpleDeleteInclude) { |
556 | std::string Code = "#include \"abc.h\"\n" |
557 | "#include \"xyz.h\" // comment\n" |
558 | "int x;\n" ; |
559 | std::string Expected = "#include \"abc.h\"\n" |
560 | "int x;\n" ; |
561 | EXPECT_EQ(Expected, remove(Code, "\"xyz.h\"" )); |
562 | } |
563 | |
564 | TEST_F(HeaderIncludesTest, DeleteQuotedOnly) { |
565 | std::string Code = "#include \"abc.h\"\n" |
566 | "#include <abc.h>\n" |
567 | "int x;\n" ; |
568 | std::string Expected = "#include <abc.h>\n" |
569 | "int x;\n" ; |
570 | EXPECT_EQ(Expected, remove(Code, "\"abc.h\"" )); |
571 | } |
572 | |
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\"" )); |
577 | } |
578 | |
579 | TEST_F(HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) { |
580 | std::string Code = "#include \"xyz.h\"\n" |
581 | "#include \"xyz\"\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>" )); |
586 | } |
587 | |
588 | TEST_F(HeaderIncludesTest, CanDeleteAfterCode) { |
589 | std::string Code = "#include \"a.h\"\n" |
590 | "void f() {}\n" |
591 | "#include \"b.h\"\n" ; |
592 | std::string Expected = "#include \"a.h\"\n" |
593 | "void f() {}\n" ; |
594 | EXPECT_EQ(Expected, remove(Code, "\"b.h\"" )); |
595 | } |
596 | |
597 | } // namespace |
598 | } // namespace tooling |
599 | } // namespace clang |
600 | |