blob: a5f5898bb288276844c38fc5f18c491d293a9c21 [file] [log] [blame]
Manuel Klimekd00d6f12015-08-11 11:37:48 +00001//===---- IncludeInserterTest.cpp - clang-tidy ----------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Alexander Kornienko5f252ca2015-08-14 14:31:31 +000010#include "../clang-tidy/utils/IncludeInserter.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +000011#include "clang/Lex/Preprocessor.h"
12#include "clang/Frontend/CompilerInstance.h"
13#include "ClangTidyTest.h"
14#include "gtest/gtest.h"
15
Manuel Klimeke8c8d882015-08-11 14:21:26 +000016// FIXME: Canonicalize paths correctly on windows.
17// Currently, adding virtual files will canonicalize the paths before
18// storing the virtual entries.
19// When resolving virtual entries in the FileManager, the paths (for
20// example coming from a #include directive) are not canonicalized
21// to native paths; thus, the virtual file is not found.
22// This needs to be fixed in the FileManager before we can make
23// clang-tidy tests work.
24#if !defined(_WIN32)
25
Manuel Klimekd00d6f12015-08-11 11:37:48 +000026namespace clang {
27namespace tidy {
28namespace {
29
30class IncludeInserterCheckBase : public ClangTidyCheck {
31public:
Manuel Klimek46e82c32015-08-11 12:59:22 +000032 IncludeInserterCheckBase(StringRef CheckName, ClangTidyContext *Context)
33 : ClangTidyCheck(CheckName, Context) {}
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000034
Manuel Klimekd00d6f12015-08-11 11:37:48 +000035 void registerPPCallbacks(CompilerInstance &Compiler) override {
Etienne Bergeron2a4c00f2016-05-03 02:54:05 +000036 Inserter.reset(new utils::IncludeInserter(
37 Compiler.getSourceManager(),
38 Compiler.getLangOpts(),
39 utils::IncludeSorter::IS_Google));
Manuel Klimekd00d6f12015-08-11 11:37:48 +000040 Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
41 }
42
43 void registerMatchers(ast_matchers::MatchFinder *Finder) override {
44 Finder->addMatcher(ast_matchers::declStmt().bind("stmt"), this);
45 }
46
47 void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
Alexander Kornienko9f58fe02016-12-13 16:19:19 +000048 auto Diag = diag(Result.Nodes.getNodeAs<DeclStmt>("stmt")->getLocStart(),
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000049 "foo, bar");
50 for (StringRef header : HeadersToInclude()) {
51 auto Fixit = Inserter->CreateIncludeInsertion(
52 Result.SourceManager->getMainFileID(), header, IsAngledInclude());
53 if (Fixit) {
54 Diag << *Fixit;
55 }
Manuel Klimekd00d6f12015-08-11 11:37:48 +000056 }
Manuel Klimekd00d6f12015-08-11 11:37:48 +000057 }
58
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000059 virtual std::vector<StringRef> HeadersToInclude() const = 0;
Manuel Klimekd00d6f12015-08-11 11:37:48 +000060 virtual bool IsAngledInclude() const = 0;
61
Etienne Bergeron2a4c00f2016-05-03 02:54:05 +000062 std::unique_ptr<utils::IncludeInserter> Inserter;
Manuel Klimekd00d6f12015-08-11 11:37:48 +000063};
64
65class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
66public:
Manuel Klimek46e82c32015-08-11 12:59:22 +000067 NonSystemHeaderInserterCheck(StringRef CheckName, ClangTidyContext *Context)
68 : IncludeInserterCheckBase(CheckName, Context) {}
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000069
70 std::vector<StringRef> HeadersToInclude() const override {
71 return {"path/to/header.h"};
72 }
73 bool IsAngledInclude() const override { return false; }
74};
75
Alexander Kornienkoe3d91a52017-01-12 15:31:50 +000076class EarlyInAlphabetHeaderInserterCheck : public IncludeInserterCheckBase {
77public:
78 EarlyInAlphabetHeaderInserterCheck(StringRef CheckName, ClangTidyContext *Context)
79 : IncludeInserterCheckBase(CheckName, Context) {}
80
81 std::vector<StringRef> HeadersToInclude() const override {
82 return {"a/header.h"};
83 }
84 bool IsAngledInclude() const override { return false; }
85};
86
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000087class MultipleHeaderInserterCheck : public IncludeInserterCheckBase {
88public:
89 MultipleHeaderInserterCheck(StringRef CheckName, ClangTidyContext *Context)
90 : IncludeInserterCheckBase(CheckName, Context) {}
Daniel Jasperd30dc3f2015-08-19 21:02:27 +000091
92 std::vector<StringRef> HeadersToInclude() const override {
93 return {"path/to/header.h", "path/to/header2.h", "path/to/header.h"};
94 }
Manuel Klimekd00d6f12015-08-11 11:37:48 +000095 bool IsAngledInclude() const override { return false; }
96};
97
Alexander Kornienko8cc024e2015-08-14 12:33:25 +000098class CSystemIncludeInserterCheck : public IncludeInserterCheckBase {
99public:
Alexander Kornienko078ab132015-08-14 13:23:55 +0000100 CSystemIncludeInserterCheck(StringRef CheckName, ClangTidyContext *Context)
101 : IncludeInserterCheckBase(CheckName, Context) {}
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000102
103 std::vector<StringRef> HeadersToInclude() const override {
104 return {"stdlib.h"};
105 }
Alexander Kornienko8cc024e2015-08-14 12:33:25 +0000106 bool IsAngledInclude() const override { return true; }
107};
108
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000109class CXXSystemIncludeInserterCheck : public IncludeInserterCheckBase {
110public:
Manuel Klimek46e82c32015-08-11 12:59:22 +0000111 CXXSystemIncludeInserterCheck(StringRef CheckName, ClangTidyContext *Context)
112 : IncludeInserterCheckBase(CheckName, Context) {}
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000113
114 std::vector<StringRef> HeadersToInclude() const override { return {"set"}; }
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000115 bool IsAngledInclude() const override { return true; }
116};
117
118template <typename Check>
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000119std::string runCheckOnCode(StringRef Code, StringRef Filename) {
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000120 std::vector<ClangTidyError> Errors;
121 return test::runCheckOnCode<Check>(Code, &Errors, Filename, None,
122 ClangTidyOptions(),
123 {// Main file include
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000124 {"clang_tidy/tests/"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000125 "insert_includes_test_header.h",
126 "\n"},
127 // Non system headers
Alexander Kornienkoe3d91a52017-01-12 15:31:50 +0000128 {"a/header.h", "\n"},
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000129 {"path/to/a/header.h", "\n"},
130 {"path/to/z/header.h", "\n"},
131 {"path/to/header.h", "\n"},
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000132 {"path/to/header2.h", "\n"},
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000133 // Fake system headers.
134 {"stdlib.h", "\n"},
135 {"unistd.h", "\n"},
136 {"list", "\n"},
137 {"map", "\n"},
138 {"set", "\n"},
139 {"vector", "\n"}});
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000140}
141
142TEST(IncludeInserterTest, InsertAfterLastNonSystemInclude) {
143 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000144#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000145
146#include <list>
147#include <map>
148
149#include "path/to/a/header.h"
150
151void foo() {
152 int a = 0;
153})";
154 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000155#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000156
157#include <list>
158#include <map>
159
160#include "path/to/a/header.h"
161#include "path/to/header.h"
162
163void foo() {
164 int a = 0;
165})";
166
167 EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000168 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000169 "insert_includes_test_input2.cc"));
170}
171
172TEST(IncludeInserterTest, InsertMultipleIncludesAndDeduplicate) {
173 const char *PreCode = R"(
174#include "clang_tidy/tests/insert_includes_test_header.h"
175
176#include <list>
177#include <map>
178
179#include "path/to/a/header.h"
180
181void foo() {
182 int a = 0;
183})";
184 const char *PostCode = R"(
185#include "clang_tidy/tests/insert_includes_test_header.h"
186
187#include <list>
188#include <map>
189
190#include "path/to/a/header.h"
191#include "path/to/header.h"
192#include "path/to/header2.h"
193
194void foo() {
195 int a = 0;
196})";
197
198 EXPECT_EQ(PostCode, runCheckOnCode<MultipleHeaderInserterCheck>(
199 PreCode, "clang_tidy/tests/"
200 "insert_includes_test_input2.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000201}
202
203TEST(IncludeInserterTest, InsertBeforeFirstNonSystemInclude) {
204 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000205#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000206
207#include <list>
208#include <map>
209
210#include "path/to/z/header.h"
211
212void foo() {
213 int a = 0;
214})";
215 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000216#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000217
218#include <list>
219#include <map>
220
221#include "path/to/header.h"
222#include "path/to/z/header.h"
223
224void foo() {
225 int a = 0;
226})";
227
228 EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000229 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000230 "insert_includes_test_input2.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000231}
232
233TEST(IncludeInserterTest, InsertBetweenNonSystemIncludes) {
234 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000235#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000236
237#include <list>
238#include <map>
239
240#include "path/to/a/header.h"
241#include "path/to/z/header.h"
242
243void foo() {
244 int a = 0;
245})";
246 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000247#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000248
249#include <list>
250#include <map>
251
252#include "path/to/a/header.h"
253#include "path/to/header.h"
254#include "path/to/z/header.h"
255
256void foo() {
257 int a = 0;
258})";
259
260 EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000261 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000262 "insert_includes_test_input2.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000263}
264
265TEST(IncludeInserterTest, NonSystemIncludeAlreadyIncluded) {
266 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000267#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000268
269#include <list>
270#include <map>
271
272#include "path/to/a/header.h"
273#include "path/to/header.h"
274#include "path/to/z/header.h"
275
276void foo() {
277 int a = 0;
278})";
279 EXPECT_EQ(PreCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000280 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000281 "insert_includes_test_input2.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000282}
283
284TEST(IncludeInserterTest, InsertNonSystemIncludeAfterLastCXXSystemInclude) {
285 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000286#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000287
288#include <list>
289#include <map>
290
291void foo() {
292 int a = 0;
293})";
294 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000295#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000296
297#include <list>
298#include <map>
299
300#include "path/to/header.h"
301
302void foo() {
303 int a = 0;
304})";
305
306 EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000307 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000308 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000309}
310
311TEST(IncludeInserterTest, InsertNonSystemIncludeAfterMainFileInclude) {
312 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000313#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000314
315void foo() {
316 int a = 0;
317})";
318 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000319#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000320
321#include "path/to/header.h"
322
323void foo() {
324 int a = 0;
325})";
326
327 EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000328 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000329 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000330}
331
332TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterLastCXXSystemInclude) {
333 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000334#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000335
336#include <list>
337#include <map>
338
339#include "path/to/a/header.h"
340
341void foo() {
342 int a = 0;
343})";
344 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000345#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000346
347#include <list>
348#include <map>
349#include <set>
350
351#include "path/to/a/header.h"
352
353void foo() {
354 int a = 0;
355})";
356
357 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000358 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000359 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000360}
361
362TEST(IncludeInserterTest, InsertCXXSystemIncludeBeforeFirstCXXSystemInclude) {
363 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000364#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000365
366#include <vector>
367
368#include "path/to/a/header.h"
369
370void foo() {
371 int a = 0;
372})";
373 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000374#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000375
376#include <set>
377#include <vector>
378
379#include "path/to/a/header.h"
380
381void foo() {
382 int a = 0;
383})";
384
385 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000386 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000387 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000388}
389
390TEST(IncludeInserterTest, InsertCXXSystemIncludeBetweenCXXSystemIncludes) {
391 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000392#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000393
394#include <map>
395#include <vector>
396
397#include "path/to/a/header.h"
398
399void foo() {
400 int a = 0;
401})";
402 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000403#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000404
405#include <map>
406#include <set>
407#include <vector>
408
409#include "path/to/a/header.h"
410
411void foo() {
412 int a = 0;
413})";
414
415 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000416 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000417 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000418}
419
420TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterMainFileInclude) {
421 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000422#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000423
424#include "path/to/a/header.h"
425
426void foo() {
427 int a = 0;
428})";
429 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000430#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000431
432#include <set>
433
434#include "path/to/a/header.h"
435
436void foo() {
437 int a = 0;
438})";
439
440 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000441 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000442 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000443}
444
445TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterCSystemInclude) {
446 const char *PreCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000447#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000448
449#include <stdlib.h>
450
451#include "path/to/a/header.h"
452
453void foo() {
454 int a = 0;
455})";
456 const char *PostCode = R"(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000457#include "clang_tidy/tests/insert_includes_test_header.h"
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000458
459#include <stdlib.h>
460
461#include <set>
462
463#include "path/to/a/header.h"
464
465void foo() {
466 int a = 0;
467})";
468
469 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000470 PreCode, "clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000471 "insert_includes_test_header.cc"));
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000472}
473
Alexander Kornienko8cc024e2015-08-14 12:33:25 +0000474TEST(IncludeInserterTest, InsertCXXSystemIncludeBeforeNonSystemInclude) {
475 const char *PreCode = R"(
476#include "path/to/a/header.h"
477
478void foo() {
479 int a = 0;
480})";
481 const char *PostCode = R"(
482#include <set>
483
484#include "path/to/a/header.h"
485
486void foo() {
487 int a = 0;
488})";
489
490 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
491 PreCode, "devtools/cymbal/clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000492 "insert_includes_test_header.cc"));
Alexander Kornienko8cc024e2015-08-14 12:33:25 +0000493}
494
495TEST(IncludeInserterTest, InsertCSystemIncludeBeforeCXXSystemInclude) {
496 const char *PreCode = R"(
497#include <set>
498
499#include "path/to/a/header.h"
500
501void foo() {
502 int a = 0;
503})";
504 const char *PostCode = R"(
505#include <stdlib.h>
506
507#include <set>
508
509#include "path/to/a/header.h"
510
511void foo() {
512 int a = 0;
513})";
514
515 EXPECT_EQ(PostCode, runCheckOnCode<CSystemIncludeInserterCheck>(
516 PreCode, "devtools/cymbal/clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000517 "insert_includes_test_header.cc"));
Alexander Kornienko8cc024e2015-08-14 12:33:25 +0000518}
519
520TEST(IncludeInserterTest, InsertIncludeIfThereWasNoneBefore) {
521 const char *PreCode = R"(
522void foo() {
523 int a = 0;
524})";
525 const char *PostCode = R"(#include <set>
526
527
528void foo() {
529 int a = 0;
530})";
531
532 EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
533 PreCode, "devtools/cymbal/clang_tidy/tests/"
Daniel Jasperd30dc3f2015-08-19 21:02:27 +0000534 "insert_includes_test_header.cc"));
Alexander Kornienko8cc024e2015-08-14 12:33:25 +0000535}
536
Alexander Kornienkoe3d91a52017-01-12 15:31:50 +0000537TEST(IncludeInserterTest, DontInsertDuplicateIncludeEvenIfMiscategorized) {
538 const char *PreCode = R"(
539#include "clang_tidy/tests/insert_includes_test_header.h"
540
541#include <map>
542#include <set>
543#include <vector>
544
545#include "a/header.h"
546#include "path/to/a/header.h"
547#include "path/to/header.h"
548
549void foo() {
550 int a = 0;
551})";
552
553 const char *PostCode = R"(
554#include "clang_tidy/tests/insert_includes_test_header.h"
555
556#include <map>
557#include <set>
558#include <vector>
559
560#include "a/header.h"
561#include "path/to/a/header.h"
562#include "path/to/header.h"
563
564void foo() {
565 int a = 0;
566})";
567
568 EXPECT_EQ(PostCode, runCheckOnCode<EarlyInAlphabetHeaderInserterCheck>(
569 PreCode, "workspace_folder/clang_tidy/tests/"
570 "insert_includes_test_header.cc"));
571}
572
573TEST(IncludeInserterTest, HandleOrderInSubdirectory) {
574 const char *PreCode = R"(
575#include "clang_tidy/tests/insert_includes_test_header.h"
576
577#include <map>
578#include <set>
579#include <vector>
580
581#include "path/to/a/header.h"
582#include "path/to/header.h"
583
584void foo() {
585 int a = 0;
586})";
587
588 const char *PostCode = R"(
589#include "clang_tidy/tests/insert_includes_test_header.h"
590
591#include <map>
592#include <set>
593#include <vector>
594
595#include "a/header.h"
596#include "path/to/a/header.h"
597#include "path/to/header.h"
598
599void foo() {
600 int a = 0;
601})";
602
603 EXPECT_EQ(PostCode, runCheckOnCode<EarlyInAlphabetHeaderInserterCheck>(
604 PreCode, "workspace_folder/clang_tidy/tests/"
605 "insert_includes_test_header.cc"));
606}
607
Eugene Zelenko7da47b82016-01-26 22:32:24 +0000608} // anonymous namespace
Manuel Klimekd00d6f12015-08-11 11:37:48 +0000609} // namespace tidy
610} // namespace clang
Manuel Klimeke8c8d882015-08-11 14:21:26 +0000611
Alexander Kornienko078ab132015-08-14 13:23:55 +0000612#endif