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