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