xref: /llvm-project/clang/unittests/Format/FormatTestTextProto.cpp (revision ddbe6c412bab3fe7a3ffaf6f42c49849a518b4c6)
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(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