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