1 | //===- unittest/Format/FormatTestRawStrings.cpp - Formatting 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 "clang/Format/Format.h" |
10 | |
11 | #include "../Tooling/ReplacementTest.h" |
12 | #include "FormatTestUtils.h" |
13 | |
14 | #include "llvm/Support/Debug.h" |
15 | #include "llvm/Support/MemoryBuffer.h" |
16 | #include "gtest/gtest.h" |
17 | |
18 | #define DEBUG_TYPE "format-test" |
19 | |
20 | namespace clang { |
21 | namespace format { |
22 | namespace { |
23 | |
24 | class FormatTestRawStrings : public testing::Test { |
25 | protected: |
26 | enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; |
27 | |
28 | std::string format(StringRef Code, const FormatStyle &Style = getLLVMStyle(), |
29 | StatusCheck CheckComplete = SC_ExpectComplete) { |
30 | LLVM_DEBUG(llvm::errs() << "---\n" ); |
31 | LLVM_DEBUG(llvm::errs() << Code << "\n\n" ); |
32 | std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); |
33 | FormattingAttemptStatus Status; |
34 | tooling::Replacements Replaces = |
35 | reformat(Style, Code, Ranges, FileName: "<stdin>" , Status: &Status); |
36 | if (CheckComplete != SC_DoNotCheck) { |
37 | bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; |
38 | EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) |
39 | << Code << "\n\n" ; |
40 | } |
41 | ReplacementCount = Replaces.size(); |
42 | auto Result = applyAllReplacements(Code, Replaces); |
43 | EXPECT_TRUE(static_cast<bool>(Result)); |
44 | LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n" ); |
45 | return *Result; |
46 | } |
47 | |
48 | FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { |
49 | Style.ColumnLimit = ColumnLimit; |
50 | return Style; |
51 | } |
52 | |
53 | FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { |
54 | return getStyleWithColumns(Style: getLLVMStyle(), ColumnLimit); |
55 | } |
56 | |
57 | int ReplacementCount; |
58 | |
59 | FormatStyle getRawStringPbStyleWithColumns(unsigned ColumnLimit) { |
60 | FormatStyle Style = getLLVMStyle(); |
61 | Style.ColumnLimit = ColumnLimit; |
62 | Style.RawStringFormats = { |
63 | { |
64 | /*Language=*/FormatStyle::LK_TextProto, |
65 | /*Delimiters=*/{"pb" }, |
66 | /*EnclosingFunctions=*/{}, |
67 | /*CanonicalDelimiter=*/"" , |
68 | /*BasedOnStyle=*/"google" , |
69 | }, |
70 | }; |
71 | return Style; |
72 | } |
73 | |
74 | FormatStyle getRawStringLLVMCppStyleBasedOn(std::string BasedOnStyle) { |
75 | FormatStyle Style = getLLVMStyle(); |
76 | Style.RawStringFormats = { |
77 | { |
78 | /*Language=*/FormatStyle::LK_Cpp, |
79 | /*Delimiters=*/{"cpp" }, |
80 | /*EnclosingFunctions=*/{}, |
81 | /*CanonicalDelimiter=*/"" , |
82 | .BasedOnStyle: BasedOnStyle, |
83 | }, |
84 | }; |
85 | return Style; |
86 | } |
87 | |
88 | FormatStyle getRawStringGoogleCppStyleBasedOn(std::string BasedOnStyle) { |
89 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_Cpp); |
90 | Style.RawStringFormats = { |
91 | { |
92 | /*Language=*/FormatStyle::LK_Cpp, |
93 | /*Delimiters=*/{"cpp" }, |
94 | /*EnclosingFunctions=*/{}, |
95 | /*CanonicalDelimiter=*/"" , |
96 | .BasedOnStyle: BasedOnStyle, |
97 | }, |
98 | }; |
99 | return Style; |
100 | } |
101 | |
102 | // Gcc 4.8 doesn't support raw string literals in macros, which breaks some |
103 | // build bots. We use this function instead. |
104 | void expect_eq(const std::string Expected, const std::string Actual) { |
105 | EXPECT_EQ(Expected, Actual); |
106 | } |
107 | }; |
108 | |
109 | TEST_F(FormatTestRawStrings, ReformatsAccordingToBaseStyle) { |
110 | // llvm style puts '*' on the right. |
111 | // google style puts '*' on the left. |
112 | |
113 | // Use the llvm style if the raw string style has no BasedOnStyle. |
114 | expect_eq(Expected: R"test(int *i = R"cpp(int *p = nullptr;)cpp")test" , |
115 | Actual: format(Code: R"test(int * i = R"cpp(int * p = nullptr;)cpp")test" , |
116 | Style: getRawStringLLVMCppStyleBasedOn(BasedOnStyle: "" ))); |
117 | |
118 | // Use the google style if the raw string style has BasedOnStyle=google. |
119 | expect_eq(Expected: R"test(int *i = R"cpp(int* p = nullptr;)cpp")test" , |
120 | Actual: format(Code: R"test(int * i = R"cpp(int * p = nullptr;)cpp")test" , |
121 | Style: getRawStringLLVMCppStyleBasedOn(BasedOnStyle: "google" ))); |
122 | |
123 | // Use the llvm style if the raw string style has no BasedOnStyle=llvm. |
124 | expect_eq(Expected: R"test(int* i = R"cpp(int *p = nullptr;)cpp")test" , |
125 | Actual: format(Code: R"test(int * i = R"cpp(int * p = nullptr;)cpp")test" , |
126 | Style: getRawStringGoogleCppStyleBasedOn(BasedOnStyle: "llvm" ))); |
127 | } |
128 | |
129 | TEST_F(FormatTestRawStrings, UsesConfigurationOverBaseStyle) { |
130 | // llvm style puts '*' on the right. |
131 | // google style puts '*' on the left. |
132 | |
133 | // Uses the configured google style inside raw strings even if BasedOnStyle in |
134 | // the raw string format is llvm. |
135 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_Cpp); |
136 | EXPECT_EQ(0, parseConfiguration("---\n" |
137 | "Language: Cpp\n" |
138 | "BasedOnStyle: Google" , |
139 | &Style) |
140 | .value()); |
141 | Style.RawStringFormats = {{ |
142 | .Language: FormatStyle::LK_Cpp, |
143 | .Delimiters: {"cpp" }, |
144 | .EnclosingFunctions: {}, |
145 | /*CanonicalDelimiter=*/"" , |
146 | /*BasedOnStyle=*/"llvm" , |
147 | }}; |
148 | expect_eq(Expected: R"test(int* i = R"cpp(int* j = 0;)cpp";)test" , |
149 | Actual: format(Code: R"test(int * i = R"cpp(int * j = 0;)cpp";)test" , Style)); |
150 | } |
151 | |
152 | TEST_F(FormatTestRawStrings, MatchesDelimitersCaseSensitively) { |
153 | // Don't touch the 'PB' raw string, format the 'pb' raw string. |
154 | expect_eq(Expected: R"test( |
155 | s = R"PB(item:1)PB"; |
156 | t = R"pb(item: 1)pb";)test" , |
157 | Actual: format(Code: R"test( |
158 | s = R"PB(item:1)PB"; |
159 | t = R"pb(item:1)pb";)test" , |
160 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
161 | } |
162 | |
163 | TEST_F(FormatTestRawStrings, RespectsClangFormatOff) { |
164 | expect_eq(Expected: R"test( |
165 | // clang-format off |
166 | s = R"pb(item: 1)pb"; |
167 | // clang-format on |
168 | t = R"pb(item: 1)pb";)test" , |
169 | Actual: format(Code: R"test( |
170 | // clang-format off |
171 | s = R"pb(item: 1)pb"; |
172 | // clang-format on |
173 | t = R"pb(item: 1)pb";)test" , |
174 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
175 | } |
176 | |
177 | TEST_F(FormatTestRawStrings, ReformatsShortRawStringsOnSingleLine) { |
178 | expect_eq(Expected: R"test(P p = TP(R"pb()pb");)test" , |
179 | Actual: format(Code: R"test(P p = TP(R"pb( )pb");)test" , |
180 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
181 | expect_eq(Expected: R"test(P p = TP(R"pb(item_1: 1)pb");)test" , |
182 | Actual: format(Code: R"test(P p = TP(R"pb(item_1:1)pb");)test" , |
183 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
184 | expect_eq(Expected: R"test(P p = TP(R"pb(item_1: 1)pb");)test" , |
185 | Actual: format(Code: R"test(P p = TP(R"pb( item_1 : 1 )pb");)test" , |
186 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
187 | expect_eq(Expected: R"test(P p = TP(R"pb(item_1: 1 item_2: 2)pb");)test" , |
188 | Actual: format(Code: R"test(P p = TP(R"pb(item_1:1 item_2:2)pb");)test" , |
189 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
190 | // Merge two short lines into one. |
191 | expect_eq(Expected: R"test( |
192 | std::string s = R"pb( |
193 | item_1: 1 item_2: 2 |
194 | )pb"; |
195 | )test" , |
196 | Actual: format(Code: R"test( |
197 | std::string s = R"pb( |
198 | item_1:1 |
199 | item_2:2 |
200 | )pb"; |
201 | )test" , |
202 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
203 | } |
204 | |
205 | TEST_F(FormatTestRawStrings, BreaksShortRawStringsWhenNeeded) { |
206 | // The raw string contains multiple submessage entries, so break for |
207 | // readability. |
208 | expect_eq(Expected: R"test( |
209 | P p = TP(R"pb(item_1 < 1 > |
210 | item_2: { 2 })pb");)test" , |
211 | Actual: format( |
212 | Code: R"test( |
213 | P p = TP(R"pb(item_1<1> item_2:{2})pb");)test" , |
214 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
215 | } |
216 | |
217 | TEST_F(FormatTestRawStrings, BreaksRawStringsExceedingColumnLimit) { |
218 | expect_eq(Expected: R"test( |
219 | P p = TPPPPPPPPPPPPPPP( |
220 | R"pb(item_1: 1, item_2: 2)pb");)test" , |
221 | Actual: format(Code: R"test( |
222 | P p = TPPPPPPPPPPPPPPP(R"pb(item_1: 1, item_2: 2)pb");)test" , |
223 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
224 | |
225 | expect_eq(Expected: R"test( |
226 | P p = |
227 | TPPPPPPPPPPPPPPP( |
228 | R"pb(item_1: 1, |
229 | item_2: 2, |
230 | item_3: 3)pb");)test" , |
231 | Actual: format(Code: R"test( |
232 | P p = TPPPPPPPPPPPPPPP(R"pb(item_1: 1, item_2: 2, item_3: 3)pb");)test" , |
233 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
234 | |
235 | expect_eq(Expected: R"test( |
236 | P p = TP(R"pb(item_1 < 1 > |
237 | item_2: < 2 > |
238 | item_3 {})pb");)test" , |
239 | Actual: format(Code: R"test( |
240 | P p = TP(R"pb(item_1<1> item_2:<2> item_3{ })pb");)test" , |
241 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
242 | |
243 | expect_eq( |
244 | Expected: R"test( |
245 | P p = TP(R"pb(item_1: 1, |
246 | item_2: 2, |
247 | item_3: 3, |
248 | item_4: 4)pb");)test" , |
249 | Actual: format( |
250 | Code: R"test( |
251 | P p = TP(R"pb(item_1: 1, item_2: 2, item_3: 3, item_4: 4)pb");)test" , |
252 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
253 | |
254 | expect_eq(Expected: R"test( |
255 | P p = TPPPPPPPPPPPPPPP( |
256 | R"pb(item_1 < 1 >, |
257 | item_2: { 2 }, |
258 | item_3: < 3 >, |
259 | item_4: { 4 })pb");)test" , |
260 | Actual: format(Code: R"test( |
261 | P p = TPPPPPPPPPPPPPPP(R"pb(item_1<1>, item_2: {2}, item_3: <3>, item_4:{4})pb");)test" , |
262 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
263 | |
264 | // Breaks before a short raw string exceeding the column limit. |
265 | expect_eq(Expected: R"test( |
266 | FFFFFFFFFFFFFFFFFFFFFFFFFFF( |
267 | R"pb(key: 1)pb"); |
268 | P p = TPPPPPPPPPPPPPPPPPPPP( |
269 | R"pb(key: 2)pb"); |
270 | auto TPPPPPPPPPPPPPPPPPPPP = |
271 | R"pb(key: 3)pb"; |
272 | P p = TPPPPPPPPPPPPPPPPPPPP( |
273 | R"pb(i: 1, j: 2)pb"); |
274 | |
275 | int f(string s) { |
276 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF( |
277 | R"pb(key: 1)pb"); |
278 | P p = TPPPPPPPPPPPPPPPPPPPP( |
279 | R"pb(key: 2)pb"); |
280 | auto TPPPPPPPPPPPPPPPPPPPP = |
281 | R"pb(key: 3)pb"; |
282 | if (s.empty()) |
283 | P p = TPPPPPPPPPPPPPPPPPPPP( |
284 | R"pb(i: 1, j: 2)pb"); |
285 | } |
286 | )test" , |
287 | Actual: format(Code: R"test( |
288 | FFFFFFFFFFFFFFFFFFFFFFFFFFF(R"pb(key:1)pb"); |
289 | P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(key:2)pb"); |
290 | auto TPPPPPPPPPPPPPPPPPPPP = R"pb(key:3)pb"; |
291 | P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(i: 1, j:2)pb"); |
292 | |
293 | int f(string s) { |
294 | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF(R"pb(key:1)pb"); |
295 | P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(key:2)pb"); |
296 | auto TPPPPPPPPPPPPPPPPPPPP = R"pb(key:3)pb"; |
297 | if (s.empty()) |
298 | P p = TPPPPPPPPPPPPPPPPPPPP(R"pb(i: 1, j:2)pb"); |
299 | } |
300 | )test" , |
301 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
302 | } |
303 | |
304 | TEST_F(FormatTestRawStrings, FormatsRawStringArguments) { |
305 | expect_eq(Expected: R"test( |
306 | P p = TP(R"pb(key { 1 })pb", param_2);)test" , |
307 | Actual: format(Code: R"test( |
308 | P p = TP(R"pb(key{1})pb",param_2);)test" , |
309 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
310 | |
311 | expect_eq(Expected: R"test( |
312 | PPPPPPPPPPPPP(R"pb(keykeyk)pb", |
313 | param_2);)test" , |
314 | Actual: format(Code: R"test( |
315 | PPPPPPPPPPPPP(R"pb(keykeyk)pb", param_2);)test" , |
316 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
317 | |
318 | expect_eq(Expected: R"test( |
319 | P p = TP( |
320 | R"pb(item: { i: 1, s: 's' } |
321 | item: { i: 2, s: 't' })pb");)test" , |
322 | Actual: format(Code: R"test( |
323 | P p = TP(R"pb(item: {i: 1, s: 's'} item: {i: 2, s: 't'})pb");)test" , |
324 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
325 | expect_eq(Expected: R"test( |
326 | FFFFFFFFFFFFFFFFFFF( |
327 | R"pb(key: "value")pb", |
328 | R"pb(key2: "value")pb");)test" , |
329 | Actual: format(Code: R"test( |
330 | FFFFFFFFFFFFFFFFFFF(R"pb(key: "value")pb", R"pb(key2: "value")pb");)test" , |
331 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
332 | |
333 | // Formats the first out of two arguments. |
334 | expect_eq(Expected: R"test( |
335 | FFFFFFFF(R"pb(key: 1)pb", argument2); |
336 | struct S { |
337 | const s = |
338 | f(R"pb(key: 1)pb", argument2); |
339 | void f() { |
340 | if (gol) |
341 | return g(R"pb(key: 1)pb", |
342 | 132789237); |
343 | return g(R"pb(key: 1)pb", "172893"); |
344 | } |
345 | };)test" , |
346 | Actual: format(Code: R"test( |
347 | FFFFFFFF(R"pb(key:1)pb", argument2); |
348 | struct S { |
349 | const s = f(R"pb(key:1)pb", argument2); |
350 | void f() { |
351 | if (gol) |
352 | return g(R"pb(key:1)pb", 132789237); |
353 | return g(R"pb(key:1)pb", "172893"); |
354 | } |
355 | };)test" , |
356 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
357 | |
358 | // Formats the second out of two arguments. |
359 | expect_eq(Expected: R"test( |
360 | FFFFFFFF(argument1, R"pb(key: 2)pb"); |
361 | struct S { |
362 | const s = |
363 | f(argument1, R"pb(key: 2)pb"); |
364 | void f() { |
365 | if (gol) |
366 | return g(12784137, |
367 | R"pb(key: 2)pb"); |
368 | return g(17283122, R"pb(key: 2)pb"); |
369 | } |
370 | };)test" , |
371 | Actual: format(Code: R"test( |
372 | FFFFFFFF(argument1, R"pb(key:2)pb"); |
373 | struct S { |
374 | const s = f(argument1, R"pb(key:2)pb"); |
375 | void f() { |
376 | if (gol) |
377 | return g(12784137, R"pb(key:2)pb"); |
378 | return g(17283122, R"pb(key:2)pb"); |
379 | } |
380 | };)test" , |
381 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
382 | |
383 | // Formats two short raw string arguments. |
384 | expect_eq(Expected: R"test( |
385 | FFFFF(R"pb(key: 1)pb", R"pb(key: 2)pb");)test" , |
386 | Actual: format(Code: R"test( |
387 | FFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test" , |
388 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
389 | // TODO(krasimir): The original source code fits on one line, so the |
390 | // non-optimizing formatter is chosen. But after the formatting in protos is |
391 | // made, the code doesn't fit on one line anymore and further formatting |
392 | // splits it. |
393 | // |
394 | // Should we disable raw string formatting for the non-optimizing formatter? |
395 | expect_eq(Expected: R"test( |
396 | FFFFFFF(R"pb(key: 1)pb", R"pb(key: 2)pb");)test" , |
397 | Actual: format(Code: R"test( |
398 | FFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test" , |
399 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
400 | |
401 | // Formats two short raw string arguments, puts second on newline. |
402 | expect_eq(Expected: R"test( |
403 | FFFFFFFF(R"pb(key: 1)pb", |
404 | R"pb(key: 2)pb");)test" , |
405 | Actual: format(Code: R"test( |
406 | FFFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb");)test" , |
407 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
408 | |
409 | // Formats both arguments. |
410 | expect_eq(Expected: R"test( |
411 | FFFFFFFF(R"pb(key: 1)pb", |
412 | R"pb(key: 2)pb"); |
413 | struct S { |
414 | const s = f(R"pb(key: 1)pb", |
415 | R"pb(key: 2)pb"); |
416 | void f() { |
417 | if (gol) |
418 | return g(R"pb(key: 1)pb", |
419 | R"pb(key: 2)pb"); |
420 | return g(R"pb(k1)pb", R"pb(k2)pb"); |
421 | } |
422 | };)test" , |
423 | Actual: format(Code: R"test( |
424 | FFFFFFFF(R"pb(key:1)pb", R"pb(key:2)pb"); |
425 | struct S { |
426 | const s = f(R"pb(key:1)pb", R"pb(key:2)pb"); |
427 | void f() { |
428 | if (gol) |
429 | return g(R"pb(key:1)pb", R"pb(key:2)pb"); |
430 | return g(R"pb( k1 )pb", R"pb( k2 )pb"); |
431 | } |
432 | };)test" , |
433 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
434 | } |
435 | |
436 | TEST_F(FormatTestRawStrings, RawStringStartingWithNewlines) { |
437 | expect_eq(Expected: R"test( |
438 | std::string s = R"pb( |
439 | item_1: 1 |
440 | )pb"; |
441 | )test" , |
442 | Actual: format(Code: R"test( |
443 | std::string s = R"pb( |
444 | item_1:1 |
445 | )pb"; |
446 | )test" , |
447 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
448 | |
449 | expect_eq(Expected: R"test( |
450 | std::string s = R"pb( |
451 | |
452 | item_1: 1 |
453 | )pb"; |
454 | )test" , |
455 | Actual: format(Code: R"test( |
456 | std::string s = R"pb( |
457 | |
458 | item_1:1 |
459 | )pb"; |
460 | )test" , |
461 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
462 | |
463 | expect_eq(Expected: R"test( |
464 | std::string s = R"pb( |
465 | item_1: 1 |
466 | )pb"; |
467 | )test" , |
468 | Actual: format(Code: R"test( |
469 | std::string s = R"pb( |
470 | item_1:1 |
471 | |
472 | )pb"; |
473 | )test" , |
474 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
475 | |
476 | expect_eq(Expected: R"test( |
477 | std::string s = R"pb( |
478 | item_1: 1, |
479 | item_2: 2 |
480 | )pb"; |
481 | )test" , |
482 | Actual: format(Code: R"test( |
483 | std::string s = R"pb( |
484 | item_1:1, item_2:2 |
485 | )pb"; |
486 | )test" , |
487 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
488 | |
489 | expect_eq(Expected: R"test( |
490 | std::string s = R"pb( |
491 | book { |
492 | title: "Alice's Adventures" |
493 | author: "Lewis Caroll" |
494 | } |
495 | book { |
496 | title: "Peter Pan" |
497 | author: "J. M. Barrie" |
498 | } |
499 | )pb"; |
500 | )test" , |
501 | Actual: format(Code: R"test( |
502 | std::string s = R"pb( |
503 | book { title: "Alice's Adventures" author: "Lewis Caroll" } |
504 | book { title: "Peter Pan" author: "J. M. Barrie" } |
505 | )pb"; |
506 | )test" , |
507 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
508 | } |
509 | |
510 | TEST_F(FormatTestRawStrings, BreaksBeforeRawStrings) { |
511 | expect_eq(Expected: R"test( |
512 | ASSERT_TRUE( |
513 | ParseFromString(R"pb(item_1: 1)pb"), |
514 | ptr);)test" , |
515 | Actual: format(Code: R"test( |
516 | ASSERT_TRUE(ParseFromString(R"pb(item_1: 1)pb"), ptr);)test" , |
517 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
518 | |
519 | expect_eq(Expected: R"test( |
520 | ASSERT_TRUE(toolong::ParseFromString( |
521 | R"pb(item_1: 1)pb"), |
522 | ptr);)test" , |
523 | Actual: format(Code: R"test( |
524 | ASSERT_TRUE(toolong::ParseFromString(R"pb(item_1: 1)pb"), ptr);)test" , |
525 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
526 | |
527 | expect_eq(Expected: R"test( |
528 | ASSERT_TRUE(ParseFromString( |
529 | R"pb(item_1: 1, |
530 | item_2: 2)pb"), |
531 | ptr);)test" , |
532 | Actual: format(Code: R"test( |
533 | ASSERT_TRUE(ParseFromString(R"pb(item_1: 1, item_2: 2)pb"), ptr);)test" , |
534 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
535 | |
536 | expect_eq(Expected: R"test( |
537 | ASSERT_TRUE( |
538 | ParseFromString( |
539 | R"pb(item_1: 1 item_2: 2)pb"), |
540 | ptr);)test" , |
541 | Actual: format(Code: R"test( |
542 | ASSERT_TRUE(ParseFromString(R"pb(item_1: 1 item_2: 2)pb"), ptr);)test" , |
543 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
544 | } |
545 | |
546 | TEST_F(FormatTestRawStrings, RawStringsInOperands) { |
547 | // Formats the raw string first operand of a binary operator expression. |
548 | expect_eq(Expected: R"test(auto S = R"pb(item_1: 1)pb" + rest;)test" , |
549 | Actual: format(Code: R"test(auto S = R"pb(item_1:1)pb" + rest;)test" , |
550 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
551 | |
552 | expect_eq(Expected: R"test( |
553 | auto S = R"pb(item_1: 1, item_2: 2)pb" + |
554 | rest;)test" , |
555 | Actual: format(Code: R"test( |
556 | auto S = R"pb(item_1:1,item_2:2)pb"+rest;)test" , |
557 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
558 | |
559 | expect_eq(Expected: R"test( |
560 | auto S = |
561 | R"pb(item_1: 1 item_2: 2)pb" + rest;)test" , |
562 | Actual: format(Code: R"test( |
563 | auto S = R"pb(item_1:1 item_2:2)pb"+rest;)test" , |
564 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
565 | |
566 | // `rest` fits on the line after )pb", but forced on newline since the raw |
567 | // string literal is multiline. |
568 | expect_eq(Expected: R"test( |
569 | auto S = R"pb(item_1: 1, |
570 | item_2: 2, |
571 | item_3: 3)pb" + |
572 | rest;)test" , |
573 | Actual: format(Code: R"test( |
574 | auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+rest;)test" , |
575 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
576 | |
577 | expect_eq(Expected: R"test( |
578 | auto S = R"pb(item_1: 1, |
579 | item_2: 2, |
580 | item_3: 3)pb" + |
581 | longlongrest;)test" , |
582 | Actual: format(Code: R"test( |
583 | auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+longlongrest;)test" , |
584 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
585 | |
586 | // Formats the raw string second operand of a binary operator expression. |
587 | expect_eq(Expected: R"test(auto S = first + R"pb(item_1: 1)pb";)test" , |
588 | Actual: format(Code: R"test(auto S = first + R"pb(item_1:1)pb";)test" , |
589 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
590 | |
591 | expect_eq(Expected: R"test( |
592 | auto S = first + R"pb(item_1: 1, |
593 | item_2: 2)pb";)test" , |
594 | Actual: format(Code: R"test( |
595 | auto S = first+R"pb(item_1:1,item_2:2)pb";)test" , |
596 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
597 | |
598 | expect_eq(Expected: R"test( |
599 | auto S = first + R"pb(item_1: 1 |
600 | item_2: 2)pb";)test" , |
601 | Actual: format(Code: R"test( |
602 | auto S = first+R"pb(item_1:1 item_2:2)pb";)test" , |
603 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
604 | |
605 | expect_eq(Expected: R"test( |
606 | auto S = R"pb(item_1: 1, |
607 | item_2: 2, |
608 | item_3: 3)pb" + |
609 | rest;)test" , |
610 | Actual: format(Code: R"test( |
611 | auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+rest;)test" , |
612 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
613 | |
614 | expect_eq(Expected: R"test( |
615 | auto S = R"pb(item_1: 1, |
616 | item_2: 2, |
617 | item_3: 3)pb" + |
618 | longlongrest;)test" , |
619 | Actual: format(Code: R"test( |
620 | auto S = R"pb(item_1:1,item_2:2,item_3:3)pb"+longlongrest;)test" , |
621 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
622 | |
623 | // Formats the raw string operands in expressions. |
624 | expect_eq(Expected: R"test( |
625 | auto S = R"pb(item_1: 1)pb" + |
626 | R"pb(item_2: 2)pb"; |
627 | )test" , |
628 | Actual: format(Code: R"test( |
629 | auto S=R"pb(item_1:1)pb"+R"pb(item_2:2)pb"; |
630 | )test" , |
631 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
632 | |
633 | expect_eq(Expected: R"test( |
634 | auto S = R"pb(item_1: 1)pb" + |
635 | R"pb(item_2: 2)pb" + |
636 | R"pb(item_3: 3)pb"; |
637 | )test" , |
638 | Actual: format(Code: R"test( |
639 | auto S=R"pb(item_1:1)pb"+R"pb(item_2:2)pb"+R"pb(item_3:3)pb"; |
640 | )test" , |
641 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
642 | |
643 | expect_eq(Expected: R"test( |
644 | auto S = (count < 3) |
645 | ? R"pb(item_1: 1)pb" |
646 | : R"pb(item_2: 2)pb"; |
647 | )test" , |
648 | Actual: format(Code: R"test( |
649 | auto S=(count<3)?R"pb(item_1:1)pb":R"pb(item_2:2)pb"; |
650 | )test" , |
651 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
652 | |
653 | expect_eq(Expected: R"test( |
654 | auto S = |
655 | (count < 3) |
656 | ? R"pb(item_1: 1, item_2: 2)pb" |
657 | : R"pb(item_3: 3)pb"; |
658 | )test" , |
659 | Actual: format(Code: R"test( |
660 | auto S=(count<3)?R"pb(item_1:1,item_2:2)pb":R"pb(item_3:3)pb"; |
661 | )test" , |
662 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
663 | |
664 | expect_eq(Expected: R"test( |
665 | auto S = |
666 | (count < 3) |
667 | ? R"pb(item_1: 1)pb" |
668 | : R"pb(item_2: 2, item_3: 3)pb"; |
669 | )test" , |
670 | Actual: format(Code: R"test( |
671 | auto S=(count<3)?R"pb(item_1:1)pb":R"pb(item_2:2,item_3:3)pb"; |
672 | )test" , |
673 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 40))); |
674 | } |
675 | |
676 | TEST_F(FormatTestRawStrings, PrefixAndSuffixAlignment) { |
677 | // Keep the suffix at the end of line if not on newline. |
678 | expect_eq(Expected: R"test( |
679 | int s() { |
680 | auto S = PTP( |
681 | R"pb( |
682 | item_1: 1, |
683 | item_2: 2)pb"); |
684 | })test" , |
685 | Actual: format(Code: R"test( |
686 | int s() { |
687 | auto S = PTP( |
688 | R"pb( |
689 | item_1: 1, |
690 | item_2: 2)pb"); |
691 | })test" , |
692 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 20))); |
693 | |
694 | // Align the suffix with the surrounding indent if the prefix is not on |
695 | // a line of its own. |
696 | expect_eq(Expected: R"test( |
697 | int s() { |
698 | auto S = PTP(R"pb( |
699 | item_1: 1, |
700 | item_2: 2 |
701 | )pb"); |
702 | })test" , |
703 | Actual: format(Code: R"test( |
704 | int s() { |
705 | auto S = PTP(R"pb( |
706 | item_1: 1, |
707 | item_2: 2 |
708 | )pb"); |
709 | })test" , |
710 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 20))); |
711 | |
712 | // Align the prefix with the suffix if both the prefix and suffix are on a |
713 | // line of their own. |
714 | expect_eq(Expected: R"test( |
715 | int s() { |
716 | auto S = PTP( |
717 | R"pb( |
718 | item_1: 1, |
719 | item_2: 2, |
720 | )pb"); |
721 | })test" , |
722 | Actual: format(Code: R"test( |
723 | int s() { |
724 | auto S = PTP( |
725 | R"pb( |
726 | item_1: 1, |
727 | item_2: 2, |
728 | )pb"); |
729 | })test" , |
730 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 20))); |
731 | } |
732 | |
733 | TEST_F(FormatTestRawStrings, EstimatesPenalty) { |
734 | // The penalty for characters exceeding the column limit in the raw string |
735 | // forces 'hh' to be put on a newline. |
736 | expect_eq(Expected: R"test( |
737 | ff(gggggg, |
738 | hh(R"pb(key { |
739 | i1: k1 |
740 | i2: k2 |
741 | })pb")); |
742 | )test" , |
743 | Actual: format(Code: R"test( |
744 | ff(gggggg, hh(R"pb(key { |
745 | i1: k1 |
746 | i2: k2 |
747 | })pb")); |
748 | )test" , |
749 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 20))); |
750 | } |
751 | |
752 | TEST_F(FormatTestRawStrings, DontFormatNonRawStrings) { |
753 | expect_eq(Expected: R"test(a = R"pb(key:value)";)test" , |
754 | Actual: format(Code: R"test(a = R"pb(key:value)";)test" , |
755 | Style: getRawStringPbStyleWithColumns(ColumnLimit: 20))); |
756 | } |
757 | |
758 | TEST_F(FormatTestRawStrings, FormatsRawStringsWithEnclosingFunctionName) { |
759 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 40); |
760 | Style.RawStringFormats[0].EnclosingFunctions.push_back(x: "PARSE_TEXT_PROTO" ); |
761 | Style.RawStringFormats[0].EnclosingFunctions.push_back(x: "ParseTextProto" ); |
762 | expect_eq(Expected: R"test(a = PARSE_TEXT_PROTO(R"(key: value)");)test" , |
763 | Actual: format(Code: R"test(a = PARSE_TEXT_PROTO(R"(key:value)");)test" , Style)); |
764 | |
765 | expect_eq(Expected: R"test( |
766 | a = PARSE_TEXT_PROTO /**/ ( |
767 | /**/ R"(key: value)");)test" , |
768 | Actual: format(Code: R"test( |
769 | a = PARSE_TEXT_PROTO/**/(/**/R"(key:value)");)test" , |
770 | Style)); |
771 | |
772 | expect_eq(Expected: R"test( |
773 | a = ParseTextProto<ProtoType>( |
774 | R"(key: value)");)test" , |
775 | Actual: format(Code: R"test( |
776 | a = ParseTextProto<ProtoType>(R"(key:value)");)test" , |
777 | Style)); |
778 | } |
779 | |
780 | TEST_F(FormatTestRawStrings, UpdatesToCanonicalDelimiters) { |
781 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 35); |
782 | Style.RawStringFormats[0].CanonicalDelimiter = "proto" ; |
783 | Style.RawStringFormats[0].EnclosingFunctions.push_back(x: "PARSE_TEXT_PROTO" ); |
784 | |
785 | expect_eq(Expected: R"test(a = R"proto(key: value)proto";)test" , |
786 | Actual: format(Code: R"test(a = R"pb(key:value)pb";)test" , Style)); |
787 | |
788 | expect_eq(Expected: R"test(PARSE_TEXT_PROTO(R"proto(key: value)proto");)test" , |
789 | Actual: format(Code: R"test(PARSE_TEXT_PROTO(R"(key:value)");)test" , Style)); |
790 | |
791 | // Don't update to canonical delimiter if it occurs as a raw string suffix in |
792 | // the raw string content. |
793 | expect_eq(Expected: R"test(a = R"pb(key: ")proto")pb";)test" , |
794 | Actual: format(Code: R"test(a = R"pb(key:")proto")pb";)test" , Style)); |
795 | } |
796 | |
797 | TEST_F(FormatTestRawStrings, PenalizesPrefixExcessChars) { |
798 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 60); |
799 | |
800 | // The '(' in R"pb is at column 60, no break. |
801 | expect_eq(Expected: R"test( |
802 | xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrr(PARSE_TEXT_PROTO(R"pb( |
803 | Category: aaaaaaaaaaaaaaaaaaaaaaaaaa |
804 | )pb")); |
805 | )test" , |
806 | Actual: format(Code: R"test( |
807 | xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrr(PARSE_TEXT_PROTO(R"pb( |
808 | Category: aaaaaaaaaaaaaaaaaaaaaaaaaa |
809 | )pb")); |
810 | )test" , |
811 | Style)); |
812 | // The '(' in R"pb is at column 61, break. |
813 | expect_eq(Expected: R"test( |
814 | xxxxxxxaaaaax wwwwwww = |
815 | _Verxrrrrrrrrr(PARSE_TEXT_PROTO(R"pb( |
816 | Category: aaaaaaaaaaaaaaaaaaaaaaaaaa |
817 | )pb")); |
818 | )test" , |
819 | Actual: format(Code: R"test( |
820 | xxxxxxxaaaaax wwwwwww = _Verxrrrrrrrrr(PARSE_TEXT_PROTO(R"pb( |
821 | Category: aaaaaaaaaaaaaaaaaaaaaaaaaa |
822 | )pb")); |
823 | )test" , |
824 | Style)); |
825 | } |
826 | |
827 | TEST_F(FormatTestRawStrings, KeepsRBraceFolloedByMoreLBracesOnSameLine) { |
828 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 80); |
829 | |
830 | expect_eq( |
831 | Expected: R"test( |
832 | int f() { |
833 | if (1) { |
834 | TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb( |
835 | ttttttttt { |
836 | ppppppppppppp { |
837 | [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" } |
838 | [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" } |
839 | } |
840 | } |
841 | )pb"); |
842 | } |
843 | } |
844 | )test" , |
845 | Actual: format( |
846 | Code: R"test( |
847 | int f() { |
848 | if (1) { |
849 | TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb( |
850 | ttttttttt { |
851 | ppppppppppppp { |
852 | [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" } |
853 | [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" }}} |
854 | )pb"); |
855 | } |
856 | } |
857 | )test" , |
858 | Style)); |
859 | } |
860 | |
861 | TEST_F(FormatTestRawStrings, |
862 | DoNotFormatUnrecognizedDelimitersInRecognizedFunctions) { |
863 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 60); |
864 | Style.RawStringFormats[0].EnclosingFunctions.push_back(x: "EqualsProto" ); |
865 | // EqualsProto is a recognized function, but the Raw delimiter is |
866 | // unrecognized. Do not touch the string in this case, since it might be |
867 | // special. |
868 | expect_eq(Expected: R"test( |
869 | void f() { |
870 | aaaaaaaaa(bbbbbbbbb, EqualsProto(R"Raw( |
871 | item { |
872 | key: value |
873 | } |
874 | )Raw")); |
875 | })test" , |
876 | Actual: format(Code: R"test( |
877 | void f() { |
878 | aaaaaaaaa(bbbbbbbbb, EqualsProto(R"Raw( |
879 | item { |
880 | key: value |
881 | } |
882 | )Raw")); |
883 | })test" , |
884 | Style)); |
885 | } |
886 | |
887 | TEST_F(FormatTestRawStrings, |
888 | BreaksBeforeNextParamAfterMultilineRawStringParam) { |
889 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 60); |
890 | expect_eq(Expected: R"test( |
891 | int f() { |
892 | int a = g(x, R"pb( |
893 | key: 1 # |
894 | key: 2 |
895 | )pb", |
896 | 3, 4); |
897 | } |
898 | )test" , |
899 | Actual: format(Code: R"test( |
900 | int f() { |
901 | int a = g(x, R"pb( |
902 | key: 1 # |
903 | key: 2 |
904 | )pb", 3, 4); |
905 | } |
906 | )test" , |
907 | Style)); |
908 | |
909 | // Breaks after a parent of a multiline param. |
910 | expect_eq(Expected: R"test( |
911 | int f() { |
912 | int a = g(x, h(R"pb( |
913 | key: 1 # |
914 | key: 2 |
915 | )pb"), |
916 | 3, 4); |
917 | } |
918 | )test" , |
919 | Actual: format(Code: R"test( |
920 | int f() { |
921 | int a = g(x, h(R"pb( |
922 | key: 1 # |
923 | key: 2 |
924 | )pb"), 3, 4); |
925 | } |
926 | )test" , |
927 | Style)); |
928 | |
929 | expect_eq(Expected: R"test( |
930 | int f() { |
931 | int a = g(x, |
932 | h(R"pb( |
933 | key: 1 # |
934 | key: 2 |
935 | )pb", |
936 | 2), |
937 | 3, 4); |
938 | } |
939 | )test" , |
940 | Actual: format(Code: R"test( |
941 | int f() { |
942 | int a = g(x, h(R"pb( |
943 | key: 1 # |
944 | key: 2 |
945 | )pb", 2), 3, 4); |
946 | } |
947 | )test" , |
948 | Style)); |
949 | // Breaks if formatting introduces a multiline raw string. |
950 | expect_eq(Expected: R"test( |
951 | int f() { |
952 | int a = g(x, R"pb(key1: value111111111 |
953 | key2: value2222222222)pb", |
954 | 3, 4); |
955 | } |
956 | )test" , |
957 | Actual: format(Code: R"test( |
958 | int f() { |
959 | int a = g(x, R"pb(key1: value111111111 key2: value2222222222)pb", 3, 4); |
960 | } |
961 | )test" , |
962 | Style)); |
963 | // Does not force a break after an original multiline param that is |
964 | // reformatterd as on single line. |
965 | expect_eq(Expected: R"test( |
966 | int f() { |
967 | int a = g(R"pb(key: 1)pb", 2); |
968 | })test" , |
969 | Actual: format(Code: R"test( |
970 | int f() { |
971 | int a = g(R"pb(key: |
972 | 1)pb", 2); |
973 | })test" , |
974 | Style)); |
975 | } |
976 | |
977 | TEST_F(FormatTestRawStrings, IndentsLastParamAfterNewline) { |
978 | FormatStyle Style = getRawStringPbStyleWithColumns(ColumnLimit: 60); |
979 | expect_eq(Expected: R"test( |
980 | fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
981 | R"pb( |
982 | b: c |
983 | )pb");)test" , |
984 | Actual: format(Code: R"test( |
985 | fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
986 | R"pb( |
987 | b: c |
988 | )pb");)test" , |
989 | Style)); |
990 | } |
991 | |
992 | TEST_F(FormatTestRawStrings, Json) { |
993 | auto Style = getLLVMStyle(); |
994 | Style.RawStringFormats = { |
995 | { |
996 | /*Language=*/FormatStyle::LK_Json, |
997 | /*Delimiters=*/{"json" }, |
998 | /*EnclosingFunctions=*/{}, |
999 | /*CanonicalDelimiter=*/"" , |
1000 | /*BasedOnStyle=*/"llvm" , |
1001 | }, |
1002 | }; |
1003 | |
1004 | EXPECT_EQ("json = R\"json({\n" |
1005 | " \"foo\": \"bar\",\n" |
1006 | " \"str\": \"test\"\n" |
1007 | " })json\";" , |
1008 | format("json = R\"json({\n" |
1009 | " \"foo\": \"bar\",\n" |
1010 | " \"str\": \"test\"\n" |
1011 | "})json\";" , |
1012 | Style)); |
1013 | } |
1014 | |
1015 | } // end namespace |
1016 | } // end namespace format |
1017 | } // end namespace clang |
1018 | |