1 | //===- unittest/Format/SortIncludesTest.cpp - Include sort unit 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 "FormatTestUtils.h" |
10 | #include "clang/Format/Format.h" |
11 | #include "llvm/Support/Debug.h" |
12 | #include "gtest/gtest.h" |
13 | |
14 | #define DEBUG_TYPE "format-test" |
15 | |
16 | namespace clang { |
17 | namespace format { |
18 | namespace { |
19 | |
20 | class SortIncludesTest : public ::testing::Test { |
21 | protected: |
22 | std::vector<tooling::Range> GetCodeRange(StringRef Code) { |
23 | return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); |
24 | } |
25 | |
26 | std::string sort(StringRef Code, std::vector<tooling::Range> Ranges, |
27 | StringRef FileName = "input.cc") { |
28 | auto Replaces = sortIncludes(FmtStyle, Code, Ranges, FileName); |
29 | Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); |
30 | auto Sorted = applyAllReplacements(Code, Replaces); |
31 | EXPECT_TRUE(static_cast<bool>(Sorted)); |
32 | auto Result = applyAllReplacements( |
33 | *Sorted, reformat(FmtStyle, *Sorted, Ranges, FileName)); |
34 | EXPECT_TRUE(static_cast<bool>(Result)); |
35 | return *Result; |
36 | } |
37 | |
38 | std::string sort(StringRef Code, StringRef FileName = "input.cpp") { |
39 | return sort(Code, GetCodeRange(Code), FileName); |
40 | } |
41 | |
42 | unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { |
43 | sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.cpp", &Cursor); |
44 | return Cursor; |
45 | } |
46 | |
47 | FormatStyle FmtStyle = getLLVMStyle(); |
48 | tooling::IncludeStyle &Style = FmtStyle.IncludeStyle; |
49 | }; |
50 | |
51 | TEST_F(SortIncludesTest, BasicSorting) { |
52 | EXPECT_EQ("#include \"a.h\"\n" |
53 | "#include \"b.h\"\n" |
54 | "#include \"c.h\"\n", |
55 | sort("#include \"a.h\"\n" |
56 | "#include \"c.h\"\n" |
57 | "#include \"b.h\"\n")); |
58 | |
59 | EXPECT_EQ("// comment\n" |
60 | "#include <a>\n" |
61 | "#include <b>\n", |
62 | sort("// comment\n" |
63 | "#include <b>\n" |
64 | "#include <a>\n", |
65 | {tooling::Range(25, 1)})); |
66 | } |
67 | |
68 | TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { |
69 | // Identical #includes have led to a failure with an unstable sort. |
70 | std::string Code = "#include <a>\n" |
71 | "#include <b>\n" |
72 | "#include <c>\n" |
73 | "#include <d>\n" |
74 | "#include <e>\n" |
75 | "#include <f>\n"; |
76 | EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty()); |
77 | } |
78 | |
79 | TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) { |
80 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
81 | EXPECT_EQ("#include \"a.h\"\n" |
82 | "#include \"b.h\"\n" |
83 | "#include \"c.h\"\n", |
84 | sort("#include \"a.h\"\n" |
85 | "#include \"c.h\"\n" |
86 | "\n" |
87 | "\n" |
88 | "#include \"b.h\"\n")); |
89 | |
90 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
91 | EXPECT_EQ("#include \"a.h\"\n" |
92 | "#include \"b.h\"\n" |
93 | "#include \"c.h\"\n", |
94 | sort("#include \"a.h\"\n" |
95 | "#include \"c.h\"\n" |
96 | "\n" |
97 | "\n" |
98 | "#include \"b.h\"\n")); |
99 | } |
100 | |
101 | TEST_F(SortIncludesTest, SupportClangFormatOff) { |
102 | EXPECT_EQ("#include <a>\n" |
103 | "#include <b>\n" |
104 | "#include <c>\n" |
105 | "// clang-format off\n" |
106 | "#include <b>\n" |
107 | "#include <a>\n" |
108 | "#include <c>\n" |
109 | "// clang-format on\n", |
110 | sort("#include <b>\n" |
111 | "#include <a>\n" |
112 | "#include <c>\n" |
113 | "// clang-format off\n" |
114 | "#include <b>\n" |
115 | "#include <a>\n" |
116 | "#include <c>\n" |
117 | "// clang-format on\n")); |
118 | } |
119 | |
120 | TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) { |
121 | EXPECT_EQ("#include <a>\n" |
122 | "#include <b>\n" |
123 | "#include <c>\n" |
124 | "/* clang-format off */\n" |
125 | "#include <b>\n" |
126 | "#include <a>\n" |
127 | "#include <c>\n" |
128 | "/* clang-format on */\n", |
129 | sort("#include <b>\n" |
130 | "#include <a>\n" |
131 | "#include <c>\n" |
132 | "/* clang-format off */\n" |
133 | "#include <b>\n" |
134 | "#include <a>\n" |
135 | "#include <c>\n" |
136 | "/* clang-format on */\n")); |
137 | |
138 | // Not really turning it off |
139 | EXPECT_EQ("#include <a>\n" |
140 | "#include <b>\n" |
141 | "#include <c>\n" |
142 | "/* clang-format offically */\n" |
143 | "#include <a>\n" |
144 | "#include <b>\n" |
145 | "#include <c>\n" |
146 | "/* clang-format onwards */\n", |
147 | sort("#include <b>\n" |
148 | "#include <a>\n" |
149 | "#include <c>\n" |
150 | "/* clang-format offically */\n" |
151 | "#include <b>\n" |
152 | "#include <a>\n" |
153 | "#include <c>\n" |
154 | "/* clang-format onwards */\n")); |
155 | } |
156 | |
157 | TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { |
158 | FmtStyle.SortIncludes = false; |
159 | EXPECT_EQ("#include \"a.h\"\n" |
160 | "#include \"c.h\"\n" |
161 | "#include \"b.h\"\n", |
162 | sort("#include \"a.h\"\n" |
163 | "#include \"c.h\"\n" |
164 | "#include \"b.h\"\n")); |
165 | } |
166 | |
167 | TEST_F(SortIncludesTest, MixIncludeAndImport) { |
168 | EXPECT_EQ("#include \"a.h\"\n" |
169 | "#import \"b.h\"\n" |
170 | "#include \"c.h\"\n", |
171 | sort("#include \"a.h\"\n" |
172 | "#include \"c.h\"\n" |
173 | "#import \"b.h\"\n")); |
174 | } |
175 | |
176 | TEST_F(SortIncludesTest, FixTrailingComments) { |
177 | EXPECT_EQ("#include \"a.h\" // comment\n" |
178 | "#include \"bb.h\" // comment\n" |
179 | "#include \"ccc.h\"\n", |
180 | sort("#include \"a.h\" // comment\n" |
181 | "#include \"ccc.h\"\n" |
182 | "#include \"bb.h\" // comment\n")); |
183 | } |
184 | |
185 | TEST_F(SortIncludesTest, LeadingWhitespace) { |
186 | EXPECT_EQ("#include \"a.h\"\n" |
187 | "#include \"b.h\"\n" |
188 | "#include \"c.h\"\n", |
189 | sort(" #include \"a.h\"\n" |
190 | " #include \"c.h\"\n" |
191 | " #include \"b.h\"\n")); |
192 | EXPECT_EQ("#include \"a.h\"\n" |
193 | "#include \"b.h\"\n" |
194 | "#include \"c.h\"\n", |
195 | sort("# include \"a.h\"\n" |
196 | "# include \"c.h\"\n" |
197 | "# include \"b.h\"\n")); |
198 | } |
199 | |
200 | TEST_F(SortIncludesTest, GreaterInComment) { |
201 | EXPECT_EQ("#include \"a.h\"\n" |
202 | "#include \"b.h\" // >\n" |
203 | "#include \"c.h\"\n", |
204 | sort("#include \"a.h\"\n" |
205 | "#include \"c.h\"\n" |
206 | "#include \"b.h\" // >\n")); |
207 | } |
208 | |
209 | TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { |
210 | EXPECT_EQ("#include \"a.h\"\n" |
211 | "#include \"c.h\"\n" |
212 | "\n" |
213 | "#include \"b.h\"\n", |
214 | sort("#include \"a.h\"\n" |
215 | "#include \"c.h\"\n" |
216 | "\n" |
217 | "#include \"b.h\"\n")); |
218 | } |
219 | |
220 | TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) { |
221 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
222 | EXPECT_EQ("#include \"a.h\"\n" |
223 | "#include \"b.h\"\n" |
224 | "#include \"c.h\"\n", |
225 | sort("#include \"a.h\"\n" |
226 | "#include \"c.h\"\n" |
227 | "\n" |
228 | "#include \"b.h\"\n")); |
229 | } |
230 | |
231 | TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) { |
232 | EXPECT_EQ("#include \"a.h\"\n" |
233 | "#include \"c.h\"\n" |
234 | "// comment\n" |
235 | "#include \"b.h\"\n", |
236 | sort("#include \"c.h\"\n" |
237 | "#include \"a.h\"\n" |
238 | "// comment\n" |
239 | "#include \"b.h\"\n")); |
240 | |
241 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
242 | EXPECT_EQ("#include \"a.h\"\n" |
243 | "#include \"c.h\"\n" |
244 | "// comment\n" |
245 | "#include \"b.h\"\n", |
246 | sort("#include \"c.h\"\n" |
247 | "#include \"a.h\"\n" |
248 | "// comment\n" |
249 | "#include \"b.h\"\n")); |
250 | |
251 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
252 | EXPECT_EQ("#include \"a.h\"\n" |
253 | "#include \"c.h\"\n" |
254 | "// comment\n" |
255 | "#include \"b.h\"\n", |
256 | sort("#include \"c.h\"\n" |
257 | "#include \"a.h\"\n" |
258 | "// comment\n" |
259 | "#include \"b.h\"\n")); |
260 | } |
261 | |
262 | TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { |
263 | EXPECT_EQ("#include \"a.h\"\n" |
264 | "#include \"c.h\"\n" |
265 | "#include <b.h>\n" |
266 | "#include <d.h>\n", |
267 | sort("#include <d.h>\n" |
268 | "#include <b.h>\n" |
269 | "#include \"c.h\"\n" |
270 | "#include \"a.h\"\n")); |
271 | |
272 | FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); |
273 | EXPECT_EQ("#include <b.h>\n" |
274 | "#include <d.h>\n" |
275 | "#include \"a.h\"\n" |
276 | "#include \"c.h\"\n", |
277 | sort("#include <d.h>\n" |
278 | "#include <b.h>\n" |
279 | "#include \"c.h\"\n" |
280 | "#include \"a.h\"\n")); |
281 | } |
282 | |
283 | TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) { |
284 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
285 | EXPECT_EQ("#include \"a.h\"\n" |
286 | "#include \"c.h\"\n" |
287 | "\n" |
288 | "#include <b.h>\n" |
289 | "#include <d.h>\n", |
290 | sort("#include <d.h>\n" |
291 | "#include <b.h>\n" |
292 | "#include \"c.h\"\n" |
293 | "#include \"a.h\"\n")); |
294 | } |
295 | |
296 | TEST_F(SortIncludesTest, HandlesMultilineIncludes) { |
297 | EXPECT_EQ("#include \"a.h\"\n" |
298 | "#include \"b.h\"\n" |
299 | "#include \"c.h\"\n", |
300 | sort("#include \"a.h\"\n" |
301 | "#include \\\n" |
302 | "\"c.h\"\n" |
303 | "#include \"b.h\"\n")); |
304 | } |
305 | |
306 | TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { |
307 | Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; |
308 | EXPECT_EQ("#include \"llvm/a.h\"\n" |
309 | "#include \"b.h\"\n" |
310 | "#include \"c.h\"\n", |
311 | sort("#include \"llvm/a.h\"\n" |
312 | "#include \"c.h\"\n" |
313 | "#include \"b.h\"\n", |
314 | "a.cc")); |
315 | EXPECT_EQ("#include \"llvm/a.h\"\n" |
316 | "#include \"b.h\"\n" |
317 | "#include \"c.h\"\n", |
318 | sort("#include \"llvm/a.h\"\n" |
319 | "#include \"c.h\"\n" |
320 | "#include \"b.h\"\n", |
321 | "a_test.cc")); |
322 | EXPECT_EQ("#include \"llvm/input.h\"\n" |
323 | "#include \"b.h\"\n" |
324 | "#include \"c.h\"\n", |
325 | sort("#include \"llvm/input.h\"\n" |
326 | "#include \"c.h\"\n" |
327 | "#include \"b.h\"\n", |
328 | "input.mm")); |
329 | |
330 | // Don't allow prefixes. |
331 | EXPECT_EQ("#include \"b.h\"\n" |
332 | "#include \"c.h\"\n" |
333 | "#include \"llvm/not_a.h\"\n", |
334 | sort("#include \"llvm/not_a.h\"\n" |
335 | "#include \"c.h\"\n" |
336 | "#include \"b.h\"\n", |
337 | "a.cc")); |
338 | |
339 | // Don't do this for _main and other suffixes. |
340 | EXPECT_EQ("#include \"b.h\"\n" |
341 | "#include \"c.h\"\n" |
342 | "#include \"llvm/a.h\"\n", |
343 | sort("#include \"llvm/a.h\"\n" |
344 | "#include \"c.h\"\n" |
345 | "#include \"b.h\"\n", |
346 | "a_main.cc")); |
347 | |
348 | // Don't do this in headers. |
349 | EXPECT_EQ("#include \"b.h\"\n" |
350 | "#include \"c.h\"\n" |
351 | "#include \"llvm/a.h\"\n", |
352 | sort("#include \"llvm/a.h\"\n" |
353 | "#include \"c.h\"\n" |
354 | "#include \"b.h\"\n", |
355 | "a.h")); |
356 | |
357 | // Only do this in the first #include block. |
358 | EXPECT_EQ("#include <a>\n" |
359 | "\n" |
360 | "#include \"b.h\"\n" |
361 | "#include \"c.h\"\n" |
362 | "#include \"llvm/a.h\"\n", |
363 | sort("#include <a>\n" |
364 | "\n" |
365 | "#include \"llvm/a.h\"\n" |
366 | "#include \"c.h\"\n" |
367 | "#include \"b.h\"\n", |
368 | "a.cc")); |
369 | |
370 | // Only recognize the first #include with a matching basename as main include. |
371 | EXPECT_EQ("#include \"a.h\"\n" |
372 | "#include \"b.h\"\n" |
373 | "#include \"c.h\"\n" |
374 | "#include \"llvm/a.h\"\n", |
375 | sort("#include \"b.h\"\n" |
376 | "#include \"a.h\"\n" |
377 | "#include \"c.h\"\n" |
378 | "#include \"llvm/a.h\"\n", |
379 | "a.cc")); |
380 | } |
381 | |
382 | TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) { |
383 | Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; |
384 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
385 | |
386 | EXPECT_EQ("#include \"c.h\"\n" |
387 | "#include \"a.h\"\n" |
388 | "#include \"b.h\"\n", |
389 | sort("#include \"b.h\"\n" |
390 | "\n" |
391 | "#include \"a.h\"\n" |
392 | "#include \"c.h\"\n", |
393 | "c.cc")); |
394 | } |
395 | |
396 | TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) { |
397 | Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; |
398 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
399 | |
400 | EXPECT_EQ("#include \"a.h\"\n" |
401 | "\n" |
402 | "#include \"b.h\"\n" |
403 | "#include \"c.h\"\n", |
404 | sort("#include \"b.h\"\n" |
405 | "\n" |
406 | "#include \"a.h\"\n" |
407 | "#include \"c.h\"\n", |
408 | "a.cc")); |
409 | } |
410 | |
411 | TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) { |
412 | // Setup an regex for main includes so we can cover those as well. |
413 | Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; |
414 | |
415 | // Ensure both main header detection and grouping work in a case insensitive |
416 | // manner. |
417 | EXPECT_EQ("#include \"llvm/A.h\"\n" |
418 | "#include \"b.h\"\n" |
419 | "#include \"c.h\"\n" |
420 | "#include \"LLVM/z.h\"\n" |
421 | "#include \"llvm/X.h\"\n" |
422 | "#include \"GTest/GTest.h\"\n" |
423 | "#include \"gmock/gmock.h\"\n", |
424 | sort("#include \"c.h\"\n" |
425 | "#include \"b.h\"\n" |
426 | "#include \"GTest/GTest.h\"\n" |
427 | "#include \"llvm/A.h\"\n" |
428 | "#include \"gmock/gmock.h\"\n" |
429 | "#include \"llvm/X.h\"\n" |
430 | "#include \"LLVM/z.h\"\n", |
431 | "a_TEST.cc")); |
432 | } |
433 | |
434 | TEST_F(SortIncludesTest, NegativePriorities) { |
435 | Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}}; |
436 | EXPECT_EQ("#include \"important_os_header.h\"\n" |
437 | "#include \"c_main.h\"\n" |
438 | "#include \"a_other.h\"\n", |
439 | sort("#include \"c_main.h\"\n" |
440 | "#include \"a_other.h\"\n" |
441 | "#include \"important_os_header.h\"\n", |
442 | "c_main.cc")); |
443 | |
444 | // check stable when re-run |
445 | EXPECT_EQ("#include \"important_os_header.h\"\n" |
446 | "#include \"c_main.h\"\n" |
447 | "#include \"a_other.h\"\n", |
448 | sort("#include \"important_os_header.h\"\n" |
449 | "#include \"c_main.h\"\n" |
450 | "#include \"a_other.h\"\n", |
451 | "c_main.cc")); |
452 | } |
453 | |
454 | TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) { |
455 | Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}}; |
456 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
457 | |
458 | EXPECT_EQ("#include \"important_os_header.h\"\n" |
459 | "\n" |
460 | "#include \"c_main.h\"\n" |
461 | "\n" |
462 | "#include \"a_other.h\"\n", |
463 | sort("#include \"c_main.h\"\n" |
464 | "#include \"a_other.h\"\n" |
465 | "#include \"important_os_header.h\"\n", |
466 | "c_main.cc")); |
467 | |
468 | // check stable when re-run |
469 | EXPECT_EQ("#include \"important_os_header.h\"\n" |
470 | "\n" |
471 | "#include \"c_main.h\"\n" |
472 | "\n" |
473 | "#include \"a_other.h\"\n", |
474 | sort("#include \"important_os_header.h\"\n" |
475 | "\n" |
476 | "#include \"c_main.h\"\n" |
477 | "\n" |
478 | "#include \"a_other.h\"\n", |
479 | "c_main.cc")); |
480 | } |
481 | |
482 | TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { |
483 | std::string Code = "#include <ccc>\n" // Start of line: 0 |
484 | "#include <bbbbbb>\n" // Start of line: 15 |
485 | "#include <a>\n"; // Start of line: 33 |
486 | EXPECT_EQ(31u, newCursor(Code, 0)); |
487 | EXPECT_EQ(13u, newCursor(Code, 15)); |
488 | EXPECT_EQ(0u, newCursor(Code, 33)); |
489 | |
490 | EXPECT_EQ(41u, newCursor(Code, 10)); |
491 | EXPECT_EQ(23u, newCursor(Code, 25)); |
492 | EXPECT_EQ(10u, newCursor(Code, 43)); |
493 | } |
494 | |
495 | TEST_F(SortIncludesTest, DeduplicateIncludes) { |
496 | EXPECT_EQ("#include <a>\n" |
497 | "#include <b>\n" |
498 | "#include <c>\n", |
499 | sort("#include <a>\n" |
500 | "#include <b>\n" |
501 | "#include <b>\n" |
502 | "#include <b>\n" |
503 | "#include <b>\n" |
504 | "#include <c>\n")); |
505 | |
506 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
507 | EXPECT_EQ("#include <a>\n" |
508 | "#include <b>\n" |
509 | "#include <c>\n", |
510 | sort("#include <a>\n" |
511 | "#include <b>\n" |
512 | "\n" |
513 | "#include <b>\n" |
514 | "\n" |
515 | "#include <b>\n" |
516 | "#include <c>\n")); |
517 | |
518 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
519 | EXPECT_EQ("#include <a>\n" |
520 | "#include <b>\n" |
521 | "#include <c>\n", |
522 | sort("#include <a>\n" |
523 | "#include <b>\n" |
524 | "\n" |
525 | "#include <b>\n" |
526 | "\n" |
527 | "#include <b>\n" |
528 | "#include <c>\n")); |
529 | } |
530 | |
531 | TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) { |
532 | EXPECT_EQ("#include <a>\n" |
533 | "#include <b>\n" |
534 | "#include <c>\n", |
535 | sort("#include <b>\n" |
536 | "#include <a>\n" |
537 | "#include <b>\n" |
538 | "#include <b>\n" |
539 | "#include <c>\n" |
540 | "#include <b>\n")); |
541 | |
542 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; |
543 | EXPECT_EQ("#include <a>\n" |
544 | "#include <b>\n" |
545 | "#include <c>\n", |
546 | sort("#include <b>\n" |
547 | "#include <a>\n" |
548 | "\n" |
549 | "#include <b>\n" |
550 | "\n" |
551 | "#include <c>\n" |
552 | "#include <b>\n")); |
553 | |
554 | Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; |
555 | EXPECT_EQ("#include <a>\n" |
556 | "#include <b>\n" |
557 | "#include <c>\n", |
558 | sort("#include <b>\n" |
559 | "#include <a>\n" |
560 | "\n" |
561 | "#include <b>\n" |
562 | "\n" |
563 | "#include <c>\n" |
564 | "#include <b>\n")); |
565 | } |
566 | |
567 | TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) { |
568 | std::string Code = "#include <b>\n" // Start of line: 0 |
569 | "#include <a>\n" // Start of line: 13 |
570 | "#include <b>\n" // Start of line: 26 |
571 | "#include <b>\n" // Start of line: 39 |
572 | "#include <c>\n" // Start of line: 52 |
573 | "#include <b>\n"; // Start of line: 65 |
574 | std::string Expected = "#include <a>\n" // Start of line: 0 |
575 | "#include <b>\n" // Start of line: 13 |
576 | "#include <c>\n"; // Start of line: 26 |
577 | EXPECT_EQ(Expected, sort(Code)); |
578 | // Cursor on 'i' in "#include <a>". |
579 | EXPECT_EQ(1u, newCursor(Code, 14)); |
580 | // Cursor on 'b' in "#include <b>". |
581 | EXPECT_EQ(23u, newCursor(Code, 10)); |
582 | EXPECT_EQ(23u, newCursor(Code, 36)); |
583 | EXPECT_EQ(23u, newCursor(Code, 49)); |
584 | EXPECT_EQ(23u, newCursor(Code, 36)); |
585 | EXPECT_EQ(23u, newCursor(Code, 75)); |
586 | // Cursor on '#' in "#include <c>". |
587 | EXPECT_EQ(26u, newCursor(Code, 52)); |
588 | } |
589 | |
590 | TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) { |
591 | EXPECT_EQ("#include <a>\n" |
592 | "#include <b>\n" |
593 | "\n" |
594 | "#include <b>\n" |
595 | "#include <c>\n", |
596 | sort("#include <a>\n" |
597 | "#include <b>\n" |
598 | "\n" |
599 | "#include <c>\n" |
600 | "#include <b>\n" |
601 | "#include <b>\n")); |
602 | } |
603 | |
604 | TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) { |
605 | std::string Code = "#include <a>\n" |
606 | "#include <b>\n" |
607 | "#include <a>\n" |
608 | "#include <a>\n" |
609 | "\n" |
610 | " int x ;"; |
611 | std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)}; |
612 | auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp"); |
613 | Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); |
614 | EXPECT_EQ(1u, Ranges.size()); |
615 | EXPECT_EQ(0u, Ranges[0].getOffset()); |
616 | EXPECT_EQ(26u, Ranges[0].getLength()); |
617 | } |
618 | |
619 | TEST_F(SortIncludesTest, DoNotSortLikelyXml) { |
620 | EXPECT_EQ("<!--;\n" |
621 | "#include <b>\n" |
622 | "#include <a>\n" |
623 | "-->", |
624 | sort("<!--;\n" |
625 | "#include <b>\n" |
626 | "#include <a>\n" |
627 | "-->")); |
628 | } |
629 | |
630 | } // end namespace |
631 | } // end namespace format |
632 | } // end namespace clang |
633 | |