1 | //===- unittest/Format/FormatTestTextProto.cpp ----------------------------===// |
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 | |
19 | class FormatTestTextProto : public ::testing::Test { |
20 | protected: |
21 | static std::string format(llvm::StringRef Code, unsigned Offset, |
22 | unsigned Length, const FormatStyle &Style) { |
23 | LLVM_DEBUG(llvm::errs() << "---\n"); |
24 | LLVM_DEBUG(llvm::errs() << Code << "\n\n"); |
25 | std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); |
26 | tooling::Replacements Replaces = reformat(Style, Code, Ranges); |
27 | auto Result = applyAllReplacements(Code, Replaces); |
28 | EXPECT_TRUE(static_cast<bool>(Result)); |
29 | LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); |
30 | return *Result; |
31 | } |
32 | |
33 | static std::string format(llvm::StringRef Code, const FormatStyle &Style) { |
34 | return format(Code, 0, Code.size(), Style); |
35 | } |
36 | |
37 | static void verifyFormat(llvm::StringRef Code, const FormatStyle &Style) { |
38 | EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; |
39 | EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); |
40 | } |
41 | |
42 | static void verifyFormat(llvm::StringRef Code) { |
43 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
44 | Style.ColumnLimit = 60; // To make writing tests easier. |
45 | verifyFormat(Code, Style); |
46 | } |
47 | }; |
48 | |
49 | TEST_F(FormatTestTextProto, KeepsTopLevelEntriesFittingALine) { |
50 | verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK"); |
51 | } |
52 | |
53 | TEST_F(FormatTestTextProto, SupportsMessageFields) { |
54 | verifyFormat("msg_field: {}"); |
55 | |
56 | verifyFormat("msg_field: { field_a: A }"); |
57 | |
58 | verifyFormat("msg_field: { field_a: \"OK\" field_b: 123 }"); |
59 | |
60 | verifyFormat("msg_field: {\n" |
61 | " field_a: 1\n" |
62 | " field_b: OK\n" |
63 | " field_c: \"OK\"\n" |
64 | " field_d: 123\n" |
65 | " field_e: 23\n" |
66 | "}"); |
67 | |
68 | verifyFormat("msg_field {}"); |
69 | |
70 | verifyFormat("msg_field { field_a: A }"); |
71 | |
72 | verifyFormat("msg_field { field_a: \"OK\" field_b: 123 }"); |
73 | |
74 | verifyFormat("msg_field {\n" |
75 | " field_a: 1\n" |
76 | " field_b: OK\n" |
77 | " field_c: \"OK\"\n" |
78 | " field_d: 123\n" |
79 | " field_e: 23.0\n" |
80 | " field_f: false\n" |
81 | " field_g: 'lala'\n" |
82 | " field_h: 1234.567e-89\n" |
83 | "}"); |
84 | |
85 | verifyFormat("msg_field: { msg_field { field_a: 1 } }"); |
86 | |
87 | verifyFormat("id: \"ala.bala\"\n" |
88 | "item { type: ITEM_A rank: 1 score: 90.0 }\n" |
89 | "item { type: ITEM_B rank: 2 score: 70.5 }\n" |
90 | "item {\n" |
91 | " type: ITEM_A\n" |
92 | " rank: 3\n" |
93 | " score: 20.0\n" |
94 | " description: \"the third item has a description\"\n" |
95 | "}"); |
96 | } |
97 | |
98 | TEST_F(FormatTestTextProto, AvoidsTopLevelBinPacking) { |
99 | verifyFormat("field_a: OK\n" |
100 | "field_b: OK\n" |
101 | "field_c: OK\n" |
102 | "field_d: OK\n" |
103 | "field_e: OK\n" |
104 | "field_f: OK"); |
105 | |
106 | verifyFormat("field_a: OK\n" |
107 | "field_b: \"OK\"\n" |
108 | "field_c: \"OK\"\n" |
109 | "msg_field: { field_d: 123 }\n" |
110 | "field_e: OK\n" |
111 | "field_f: OK"); |
112 | |
113 | verifyFormat("field_a: OK\n" |
114 | "field_b: \"OK\"\n" |
115 | "field_c: \"OK\"\n" |
116 | "msg_field: { field_d: 123 field_e: OK }"); |
117 | |
118 | verifyFormat("a: {\n" |
119 | " field_a: OK\n" |
120 | " field_b { field_c: OK }\n" |
121 | " field_d: OKOKOK\n" |
122 | " field_e: OK\n" |
123 | "}"); |
124 | |
125 | verifyFormat("field_a: OK,\n" |
126 | "field_b { field_c: OK },\n" |
127 | "field_d: OKOKOK,\n" |
128 | "field_e: OK"); |
129 | } |
130 | |
131 | TEST_F(FormatTestTextProto, AddsNewlinesAfterTrailingComments) { |
132 | verifyFormat("field_a: OK // Comment\n" |
133 | "field_b: 1"); |
134 | |
135 | verifyFormat("field_a: OK\n" |
136 | "msg_field: {\n" |
137 | " field_b: OK // Comment\n" |
138 | "}"); |
139 | |
140 | verifyFormat("field_a: OK\n" |
141 | "msg_field {\n" |
142 | " field_b: OK // Comment\n" |
143 | "}"); |
144 | } |
145 | |
146 | TEST_F(FormatTestTextProto, ImplicitStringLiteralConcatenation) { |
147 | verifyFormat("field_a: 'aaaaa'\n" |
148 | " 'bbbbb'"); |
149 | verifyFormat("field_a: \"aaaaa\"\n" |
150 | " \"bbbbb\""); |
151 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
152 | Style.AlwaysBreakBeforeMultilineStrings = true; |
153 | verifyFormat("field_a:\n" |
154 | " 'aaaaa'\n" |
155 | " 'bbbbb'", |
156 | Style); |
157 | verifyFormat("field_a:\n" |
158 | " \"aaaaa\"\n" |
159 | " \"bbbbb\"", |
160 | Style); |
161 | } |
162 | |
163 | TEST_F(FormatTestTextProto, SupportsAngleBracketMessageFields) { |
164 | // Single-line tests |
165 | verifyFormat("msg_field <>"); |
166 | verifyFormat("msg_field: <>"); |
167 | verifyFormat("msg_field < field_a: OK >"); |
168 | verifyFormat("msg_field: < field_a: 123 >"); |
169 | verifyFormat("msg_field < field_a <> >"); |
170 | verifyFormat("msg_field < field_a < field_b <> > >"); |
171 | verifyFormat("msg_field: < field_a < field_b: <> > >"); |
172 | verifyFormat("msg_field < field_a: OK, field_b: \"OK\" >"); |
173 | verifyFormat("msg_field: < field_a: OK, field_b: \"OK\" >"); |
174 | // Multiple lines tests |
175 | verifyFormat("msg_field <\n" |
176 | " field_a: OK\n" |
177 | " field_b: <>,\n" |
178 | " field_c: OK\n" |
179 | ">"); |
180 | |
181 | verifyFormat("msg_field <\n" |
182 | " field_a { field_b: 1 },\n" |
183 | " field_c: < f_d: 2 >\n" |
184 | ">"); |
185 | |
186 | verifyFormat("msg_field: <\n" |
187 | " field_a: OK\n" |
188 | " field_b: <>,\n" |
189 | " field_c: OK\n" |
190 | ">"); |
191 | |
192 | verifyFormat("msg_field: <\n" |
193 | " field_a { field_b: 1 },\n" |
194 | " field_c: < fd_d: 2 >\n" |
195 | ">"); |
196 | |
197 | verifyFormat("field_a: \"OK\",\n" |
198 | "msg_field: < field_b: 123 >,\n" |
199 | "field_c: {}"); |
200 | |
201 | verifyFormat("field_a < field_b: 1 >,\n" |
202 | "msg_fid: < fiel_b: 123 >,\n" |
203 | "field_c <>"); |
204 | |
205 | verifyFormat("field_a < field_b: 1 >\n" |
206 | "msg_fied: < field_b: 123 >\n" |
207 | "field_c <>"); |
208 | |
209 | verifyFormat("field <\n" |
210 | " field < field: <> >,\n" |
211 | " field <>\n" |
212 | ">\n" |
213 | "field: < field: 1 >"); |
214 | |
215 | verifyFormat("msg_field <\n" |
216 | " field_a: OK\n" |
217 | " field_b: \"OK\"\n" |
218 | " field_c: 1\n" |
219 | " field_d: 12.5\n" |
220 | " field_e: OK\n" |
221 | ">"); |
222 | |
223 | verifyFormat("msg_field: <>\n" |
224 | "field_c: \"OK\",\n" |
225 | "msg_field: < field_d: 123 >\n" |
226 | "field_e: OK\n" |
227 | "msg_field: < field_d: 12 >"); |
228 | |
229 | verifyFormat("field_a: OK,\n" |
230 | "field_b < field_c: OK >,\n" |
231 | "field_d: < 12.5 >,\n" |
232 | "field_e: OK"); |
233 | |
234 | verifyFormat("field_a: OK\n" |
235 | "field_b < field_c: OK >\n" |
236 | "field_d: < 12.5 >\n" |
237 | "field_e: OKOKOK"); |
238 | |
239 | verifyFormat("msg_field <\n" |
240 | " field_a: OK,\n" |
241 | " field_b < field_c: OK >,\n" |
242 | " field_d: < 12.5 >,\n" |
243 | " field_e: OK\n" |
244 | ">"); |
245 | |
246 | verifyFormat("msg_field <\n" |
247 | " field_a: < field: OK >,\n" |
248 | " field_b < field_c: OK >,\n" |
249 | " field_d: < 12.5 >,\n" |
250 | " field_e: OK,\n" |
251 | ">"); |
252 | |
253 | verifyFormat("msg_field: <\n" |
254 | " field_a: \"OK\"\n" |
255 | " msg_field: { field_b: OK }\n" |
256 | " field_g: OK\n" |
257 | " field_g: OK\n" |
258 | " field_g: OK\n" |
259 | ">"); |
260 | |
261 | verifyFormat("field_a {\n" |
262 | " field_d: ok\n" |
263 | " field_b: < field_c: 1 >\n" |
264 | " field_d: ok\n" |
265 | " field_d: ok\n" |
266 | "}"); |
267 | |
268 | verifyFormat("field_a: {\n" |
269 | " field_d: ok\n" |
270 | " field_b: < field_c: 1 >\n" |
271 | " field_d: ok\n" |
272 | " field_d: ok\n" |
273 | "}"); |
274 | |
275 | verifyFormat("field_a: <\n" |
276 | " f1: 1,\n" |
277 | " f2: <>\n" |
278 | ">\n" |
279 | "field_b <\n" |
280 | " field_b1: <>\n" |
281 | " field_b2: ok,\n" |
282 | " field_b3: <\n" |
283 | " field_x {} // Comment\n" |
284 | " field_y: { field_z: 1 }\n" |
285 | " field_w: ok\n" |
286 | " >\n" |
287 | " field {\n" |
288 | " field_x <> // Comment\n" |
289 | " field_y: < field_z: 1 >\n" |
290 | " field_w: ok\n" |
291 | " msg_field: <\n" |
292 | " field: <>\n" |
293 | " field: < field: 1 >\n" |
294 | " field: < field: 2 >\n" |
295 | " field: < field: 3 >\n" |
296 | " field: < field: 4 >\n" |
297 | " field: ok\n" |
298 | " >\n" |
299 | " }\n" |
300 | ">\n" |
301 | "field: OK,\n" |
302 | "field_c < field < field <> > >"); |
303 | |
304 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
305 | "head_id: 1\n" |
306 | "data < key: value >"); |
307 | |
308 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
309 | "head_id: 1\n" |
310 | "data < key: value >\n" |
311 | "tail_id: 2"); |
312 | |
313 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
314 | "head_id: 1\n" |
315 | "data < key: value >\n" |
316 | "data { key: value }"); |
317 | |
318 | verifyFormat("app {\n" |
319 | " app_id: 'com.javax.swing.salsa.latino'\n" |
320 | " head_id: 1\n" |
321 | " data < key: value >\n" |
322 | "}"); |
323 | |
324 | verifyFormat("app: {\n" |
325 | " app_id: 'com.javax.swing.salsa.latino'\n" |
326 | " head_id: 1\n" |
327 | " data < key: value >\n" |
328 | "}"); |
329 | |
330 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
331 | "headheadheadheadheadhead_id: 1\n" |
332 | "product_data { product { 1 } }"); |
333 | |
334 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
335 | "headheadheadheadheadhead_id: 1\n" |
336 | "product_data < product { 1 } >"); |
337 | |
338 | verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n" |
339 | "headheadheadheadheadhead_id: 1\n" |
340 | "product_data < product < 1 > >"); |
341 | |
342 | verifyFormat("app <\n" |
343 | " app_id: 'com.javax.swing.salsa.latino'\n" |
344 | " headheadheadheadheadhead_id: 1\n" |
345 | " product_data < product { 1 } >\n" |
346 | ">"); |
347 | |
348 | verifyFormat("dcccwrnfioeruvginerurneitinfo {\n" |
349 | " exte3nsionrnfvui { key: value }\n" |
350 | "}"); |
351 | } |
352 | |
353 | TEST_F(FormatTestTextProto, DiscardsUnbreakableTailIfCanBreakAfter) { |
354 | // The two closing braces count towards the string UnbreakableTailLength, but |
355 | // since we have broken after the corresponding opening braces, we don't |
356 | // consider that length for string breaking. |
357 | verifyFormat( |
358 | "foo: {\n" |
359 | " bar: {\n" |
360 | " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n" |
361 | " }\n" |
362 | "}"); |
363 | } |
364 | |
365 | TEST_F(FormatTestTextProto, KeepsLongStringLiteralsOnSameLine) { |
366 | verifyFormat( |
367 | "foo: {\n" |
368 | " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaaaa\"\n" |
369 | "}"); |
370 | } |
371 | |
372 | TEST_F(FormatTestTextProto, KeepsCommentsIndentedInList) { |
373 | verifyFormat("aaaaaaaaaa: 100\n" |
374 | "bbbbbbbbbbbbbbbbbbbbbbbbbbb: 200\n" |
375 | "# Single line comment for stuff here.\n" |
376 | "cccccccccccccccccccccccc: 3849\n" |
377 | "# Multiline comment for stuff here.\n" |
378 | "# Multiline comment for stuff here.\n" |
379 | "# Multiline comment for stuff here.\n" |
380 | "cccccccccccccccccccccccc: 3849"); |
381 | } |
382 | |
383 | TEST_F(FormatTestTextProto, UnderstandsHashHashComments) { |
384 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
385 | Style.ColumnLimit = 60; // To make writing tests easier. |
386 | EXPECT_EQ("aaa: 100\n" |
387 | "##this is a double-hash comment.\n" |
388 | "bb: 100\n" |
389 | "## another double-hash comment.\n" |
390 | "### a triple-hash comment\n" |
391 | "cc: 200\n" |
392 | "#### a quadriple-hash comment\n" |
393 | "dd: 100\n", |
394 | format("aaa: 100\n" |
395 | "##this is a double-hash comment.\n" |
396 | "bb: 100\n" |
397 | "## another double-hash comment.\n" |
398 | "### a triple-hash comment\n" |
399 | "cc: 200\n" |
400 | "#### a quadriple-hash comment\n" |
401 | "dd: 100\n", |
402 | Style)); |
403 | } |
404 | |
405 | TEST_F(FormatTestTextProto, FormatsExtensions) { |
406 | verifyFormat("[type] { key: value }"); |
407 | verifyFormat("[type] {\n" |
408 | " keyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: value\n" |
409 | "}"); |
410 | verifyFormat("[type.type] { key: value }"); |
411 | verifyFormat("[type.type] < key: value >"); |
412 | verifyFormat("[type.type/type.type] { key: value }"); |
413 | verifyFormat("msg {\n" |
414 | " [type.type] { key: value }\n" |
415 | "}"); |
416 | verifyFormat("msg {\n" |
417 | " [type.type] {\n" |
418 | " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" |
419 | " }\n" |
420 | "}"); |
421 | verifyFormat("key: value\n" |
422 | "[a.b] { key: value }"); |
423 | verifyFormat("msg: <\n" |
424 | " key: value\n" |
425 | " [a.b.c/d.e]: < key: value >\n" |
426 | " [f.g]: <\n" |
427 | " key: valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n" |
428 | " key: {}\n" |
429 | " >\n" |
430 | " key {}\n" |
431 | " [h.i.j] < key: value >\n" |
432 | " [a]: {\n" |
433 | " [b.c]: {}\n" |
434 | " [d] <>\n" |
435 | " [e/f]: 1\n" |
436 | " }\n" |
437 | ">"); |
438 | verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n" |
439 | " .longg.longlong] { key: value }"); |
440 | verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n" |
441 | " .longg.longlong] {\n" |
442 | " key: value\n" |
443 | " key: value\n" |
444 | " key: value\n" |
445 | " key: value\n" |
446 | "}"); |
447 | verifyFormat("[longg.long.long.long.long.long.long.long.long.long\n" |
448 | " .long/longg.longlong] { key: value }"); |
449 | verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n" |
450 | " bbbbbbbbbbbbbb] { key: value }"); |
451 | // These go over the column limit intentionally, since the alternative |
452 | // [aa..a\n] is worse. |
453 | verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n" |
454 | " key: value\n" |
455 | "}"); |
456 | verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n" |
457 | " [type.type] {\n" |
458 | " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" |
459 | " }\n" |
460 | "}"); |
461 | verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n" |
462 | " bbbbbbb] {\n" |
463 | " [type.type] {\n" |
464 | " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" |
465 | " }\n" |
466 | "}"); |
467 | verifyFormat( |
468 | "aaaaaaaaaaaaaaa {\n" |
469 | " bbbbbb {\n" |
470 | " [a.b/cy] {\n" |
471 | " eeeeeeeeeeeee: \"The lazy coo cat jumps over the lazy hot dog\"\n" |
472 | " }\n" |
473 | " }\n" |
474 | "}"); |
475 | } |
476 | |
477 | TEST_F(FormatTestTextProto, SpacesAroundPercents) { |
478 | verifyFormat("key: %d"); |
479 | verifyFormat("key: 0x%04x"); |
480 | verifyFormat("key: \"%d %d\""); |
481 | } |
482 | |
483 | TEST_F(FormatTestTextProto, FormatsRepeatedListInitializers) { |
484 | verifyFormat("keys: []"); |
485 | verifyFormat("keys: [ 1 ]"); |
486 | verifyFormat("keys: [ 'ala', 'bala' ]"); |
487 | verifyFormat("keys: [\n" |
488 | " 'ala',\n" |
489 | " 'bala',\n" |
490 | " 'porto',\n" |
491 | " 'kala',\n" |
492 | " 'too',\n" |
493 | " 'long',\n" |
494 | " 'ng'\n" |
495 | "]"); |
496 | verifyFormat("key: item\n" |
497 | "keys: [\n" |
498 | " 'ala',\n" |
499 | " 'bala',\n" |
500 | " 'porto',\n" |
501 | " 'kala',\n" |
502 | " 'too',\n" |
503 | " 'long',\n" |
504 | " 'long',\n" |
505 | " 'long'\n" |
506 | "]\n" |
507 | "key: item\n" |
508 | "msg {\n" |
509 | " key: item\n" |
510 | " keys: [\n" |
511 | " 'ala',\n" |
512 | " 'bala',\n" |
513 | " 'porto',\n" |
514 | " 'kala',\n" |
515 | " 'too',\n" |
516 | " 'long',\n" |
517 | " 'long'\n" |
518 | " ]\n" |
519 | "}\n" |
520 | "key: value" |
521 | ); |
522 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
523 | Style.ColumnLimit = 60; // To make writing tests easier. |
524 | Style.Cpp11BracedListStyle = true; |
525 | verifyFormat("keys: [1]", Style); |
526 | } |
527 | |
528 | TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) { |
529 | verifyFormat("aaaaaaaaaaa: <\n" |
530 | " bbbbbbbbb: <\n" |
531 | " ccccccccccccccccccccccc: <\n" |
532 | " operator: 1\n" |
533 | " operator: 2\n" |
534 | " operator: 3\n" |
535 | " operator { key: value }\n" |
536 | " >\n" |
537 | " >\n" |
538 | ">"); |
539 | } |
540 | |
541 | TEST_F(FormatTestTextProto, BreaksConsecutiveStringLiterals) { |
542 | verifyFormat("ala: \"str1\"\n" |
543 | " \"str2\"\n"); |
544 | } |
545 | |
546 | TEST_F(FormatTestTextProto, PutsMultipleEntriesInExtensionsOnNewlines) { |
547 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
548 | verifyFormat("pppppppppp: {\n" |
549 | " ssssss: \"http://example.com/blahblahblah\"\n" |
550 | " ppppppp: \"sssss/MMMMMMMMMMMM\"\n" |
551 | " [ns.sssss.eeeeeeeee.eeeeeeeeeeeeeee] { begin: 24 end: 252 }\n" |
552 | " [ns.sssss.eeeeeeeee.eeeeeeeeeeeeeee] {\n" |
553 | " begin: 24\n" |
554 | " end: 252\n" |
555 | " key: value\n" |
556 | " key: value\n" |
557 | " }\n" |
558 | "}", Style); |
559 | } |
560 | |
561 | TEST_F(FormatTestTextProto, BreaksAfterBraceFollowedByClosingBraceOnNextLine) { |
562 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
563 | Style.ColumnLimit = 60; |
564 | verifyFormat("keys: [\n" |
565 | " data: { item: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }\n" |
566 | "]"); |
567 | verifyFormat("keys: <\n" |
568 | " data: { item: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }\n" |
569 | ">"); |
570 | } |
571 | |
572 | TEST_F(FormatTestTextProto, BreaksEntriesOfSubmessagesContainingSubmessages) { |
573 | FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); |
574 | Style.ColumnLimit = 60; |
575 | // The column limit allows for the keys submessage to be put on 1 line, but we |
576 | // break it since it contains a submessage an another entry. |
577 | verifyFormat("key: valueeeeeeee\n" |
578 | "keys: {\n" |
579 | " item: 'aaaaaaaaaaaaaaaa'\n" |
580 | " sub <>\n" |
581 | "}"); |
582 | verifyFormat("key: valueeeeeeee\n" |
583 | "keys: {\n" |
584 | " item: 'aaaaaaaaaaaaaaaa'\n" |
585 | " sub {}\n" |
586 | "}"); |
587 | verifyFormat("key: valueeeeeeee\n" |
588 | "keys: {\n" |
589 | " sub {}\n" |
590 | " sub: <>\n" |
591 | " sub: []\n" |
592 | "}"); |
593 | verifyFormat("key: valueeeeeeee\n" |
594 | "keys: {\n" |
595 | " item: 'aaaaaaaaaaa'\n" |
596 | " sub { msg: 1 }\n" |
597 | "}"); |
598 | verifyFormat("key: valueeeeeeee\n" |
599 | "keys: {\n" |
600 | " item: 'aaaaaaaaaaa'\n" |
601 | " sub: { msg: 1 }\n" |
602 | "}"); |
603 | verifyFormat("key: valueeeeeeee\n" |
604 | "keys: {\n" |
605 | " item: 'aaaaaaaaaaa'\n" |
606 | " sub < msg: 1 >\n" |
607 | "}"); |
608 | verifyFormat("key: valueeeeeeee\n" |
609 | "keys: {\n" |
610 | " item: 'aaaaaaaaaaa'\n" |
611 | " sub: [ msg: 1 ]\n" |
612 | "}"); |
613 | verifyFormat("key: valueeeeeeee\n" |
614 | "keys: <\n" |
615 | " item: 'aaaaaaaaaaa'\n" |
616 | " sub: [ 1, 2 ]\n" |
617 | ">"); |
618 | verifyFormat("key: valueeeeeeee\n" |
619 | "keys: {\n" |
620 | " sub {}\n" |
621 | " item: 'aaaaaaaaaaaaaaaa'\n" |
622 | "}"); |
623 | verifyFormat("key: valueeeeeeee\n" |
624 | "keys: {\n" |
625 | " sub: []\n" |
626 | " item: 'aaaaaaaaaaaaaaaa'\n" |
627 | "}"); |
628 | verifyFormat("key: valueeeeeeee\n" |
629 | "keys: {\n" |
630 | " sub <>\n" |
631 | " item: 'aaaaaaaaaaaaaaaa'\n" |
632 | "}"); |
633 | verifyFormat("key: valueeeeeeee\n" |
634 | "keys: {\n" |
635 | " sub { key: value }\n" |
636 | " item: 'aaaaaaaaaaaaaaaa'\n" |
637 | "}"); |
638 | verifyFormat("key: valueeeeeeee\n" |
639 | "keys: {\n" |
640 | " sub: [ 1, 2 ]\n" |
641 | " item: 'aaaaaaaaaaaaaaaa'\n" |
642 | "}"); |
643 | verifyFormat("key: valueeeeeeee\n" |
644 | "keys: {\n" |
645 | " sub < sub_2: {} >\n" |
646 | " item: 'aaaaaaaaaaaaaaaa'\n" |
647 | "}"); |
648 | verifyFormat("key: valueeeeeeee\n" |
649 | "keys: {\n" |
650 | " item: data\n" |
651 | " sub: [ 1, 2 ]\n" |
652 | " item: 'aaaaaaaaaaaaaaaa'\n" |
653 | "}"); |
654 | verifyFormat("key: valueeeeeeee\n" |
655 | "keys: {\n" |
656 | " item: data\n" |
657 | " sub < sub_2: {} >\n" |
658 | " item: 'aaaaaaaaaaaaaaaa'\n" |
659 | "}"); |
660 | verifyFormat("sub: {\n" |
661 | " key: valueeeeeeee\n" |
662 | " keys: {\n" |
663 | " sub: [ 1, 2 ]\n" |
664 | " item: 'aaaaaaaaaaaaaaaa'\n" |
665 | " }\n" |
666 | "}"); |
667 | verifyFormat("sub: {\n" |
668 | " key: 1\n" |
669 | " sub: {}\n" |
670 | "}\n" |
671 | "# comment\n"); |
672 | verifyFormat("sub: {\n" |
673 | " key: 1\n" |
674 | " # comment\n" |
675 | " sub: {}\n" |
676 | "}"); |
677 | } |
678 | |
679 | TEST_F(FormatTestTextProto, PreventBreaksBetweenKeyAndSubmessages) { |
680 | verifyFormat("submessage: {\n" |
681 | " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" |
682 | "}"); |
683 | verifyFormat("submessage {\n" |
684 | " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" |
685 | "}"); |
686 | verifyFormat("submessage: <\n" |
687 | " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" |
688 | ">"); |
689 | verifyFormat("submessage <\n" |
690 | " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" |
691 | ">"); |
692 | verifyFormat("repeatedd: [\n" |
693 | " 'eyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" |
694 | "]"); |
695 | // "{" is going over the column limit. |
696 | verifyFormat( |
697 | "submessageeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee: {\n" |
698 | " key: 'aaaaa'\n" |
699 | "}"); |
700 | } |
701 | |
702 | TEST_F(FormatTestTextProto, FormatsCommentsAtEndOfFile) { |
703 | verifyFormat("key: value\n" |
704 | "# endfile comment"); |
705 | verifyFormat("key: value\n" |
706 | "// endfile comment"); |
707 | verifyFormat("key: value\n" |
708 | "// endfile comment 1\n" |
709 | "// endfile comment 2"); |
710 | verifyFormat("submessage { key: value }\n" |
711 | "# endfile comment"); |
712 | verifyFormat("submessage <\n" |
713 | " key: value\n" |
714 | " item {}\n" |
715 | ">\n" |
716 | "# endfile comment"); |
717 | } |
718 | |
719 | TEST_F(FormatTestTextProto, KeepsAmpersandsNextToKeys) { |
720 | verifyFormat("@tmpl { field: 1 }"); |
721 | verifyFormat("@placeholder: 1"); |
722 | verifyFormat("@name <>"); |
723 | verifyFormat("submessage: @base { key: value }"); |
724 | verifyFormat("submessage: @base {\n" |
725 | " key: value\n" |
726 | " item: {}\n" |
727 | "}"); |
728 | verifyFormat("submessage: {\n" |
729 | " msg: @base {\n" |
730 | " yolo: {}\n" |
731 | " key: value\n" |
732 | " }\n" |
733 | " key: value\n" |
734 | "}"); |
735 | } |
736 | |
737 | } // end namespace tooling |
738 | } // end namespace clang |
739 | |