1 //===- unittest/Format/FormatTestTextProto.cpp ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "FormatTestBase.h"
11 #define DEBUG_TYPE "format-test-text-proto"
18 class FormatTestTextProto
: public FormatTestBase
{
20 virtual FormatStyle
getDefaultStyle() const override
{
21 FormatStyle Style
= getGoogleStyle(FormatStyle::LK_TextProto
);
22 Style
.ColumnLimit
= 60; // To make writing tests easier.
27 TEST_F(FormatTestTextProto
, KeepsTopLevelEntriesFittingALine
) {
28 verifyFormat("field_a: OK field_b: OK field_c: OK field_d: OK field_e: OK");
31 TEST_F(FormatTestTextProto
, SupportsMessageFields
) {
32 verifyFormat("msg_field: {}");
34 verifyFormat("msg_field: { field_a: A }");
36 verifyFormat("msg_field: { field_a: \"OK\" field_b: 123 }");
38 verifyFormat("msg_field: {\n"
46 verifyFormat("msg_field {}");
48 verifyFormat("msg_field { field_a: A }");
50 verifyFormat("msg_field { field_a: \"OK\" field_b: 123 }");
52 verifyFormat("msg_field {\n"
60 " field_h: 1234.567e-89\n"
63 verifyFormat("msg_field: { msg_field { field_a: 1 } }");
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"
72 " description: \"the third item has a description\"\n"
76 TEST_F(FormatTestTextProto
, AvoidsTopLevelBinPacking
) {
77 verifyFormat("field_a: OK\n"
84 verifyFormat("field_a: OK\n"
87 "msg_field: { field_d: 123 }\n"
91 verifyFormat("field_a: OK\n"
94 "msg_field: { field_d: 123 field_e: OK }");
98 " field_b { field_c: OK }\n"
103 verifyFormat("field_a: OK,\n"
104 "field_b { field_c: OK },\n"
109 TEST_F(FormatTestTextProto
, AddsNewlinesAfterTrailingComments
) {
110 verifyFormat("field_a: OK // Comment\n"
113 verifyFormat("field_a: OK\n"
115 " field_b: OK // Comment\n"
118 verifyFormat("field_a: OK\n"
120 " field_b: OK // Comment\n"
124 TEST_F(FormatTestTextProto
, ImplicitStringLiteralConcatenation
) {
125 verifyFormat("field_a: 'aaaaa'\n"
127 verifyFormat("field_a: \"aaaaa\"\n"
129 FormatStyle Style
= getGoogleStyle(FormatStyle::LK_TextProto
);
130 Style
.AlwaysBreakBeforeMultilineStrings
= true;
131 verifyFormat("field_a:\n"
135 verifyFormat("field_a:\n"
141 TEST_F(FormatTestTextProto
, SupportsAngleBracketMessageFields
) {
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"
159 verifyFormat("msg_field <\n"
160 " field_a { field_b: 1 },\n"
161 " field_c: < f_d: 2 >\n"
164 verifyFormat("msg_field: <\n"
170 verifyFormat("msg_field: <\n"
171 " field_a { field_b: 1 },\n"
172 " field_c: < fd_d: 2 >\n"
175 verifyFormat("field_a: \"OK\",\n"
176 "msg_field: < field_b: 123 >,\n"
179 verifyFormat("field_a < field_b: 1 >,\n"
180 "msg_fid: < fiel_b: 123 >,\n"
183 verifyFormat("field_a < field_b: 1 >\n"
184 "msg_fied: < field_b: 123 >\n"
187 verifyFormat("field <\n"
188 " field < field: <> >,\n"
191 "field: < field: 1 >");
193 verifyFormat("msg_field <\n"
201 verifyFormat("msg_field: <>\n"
203 "msg_field: < field_d: 123 >\n"
205 "msg_field: < field_d: 12 >");
207 verifyFormat("field_a: OK,\n"
208 "field_b < field_c: OK >,\n"
209 "field_d: < 12.5 >,\n"
212 verifyFormat("field_a: OK\n"
213 "field_b < field_c: OK >\n"
214 "field_d: < 12.5 >\n"
217 verifyFormat("msg_field <\n"
219 " field_b < field_c: OK >,\n"
220 " field_d: < 12.5 >,\n"
224 verifyFormat("msg_field <\n"
225 " field_a: < field: OK >,\n"
226 " field_b < field_c: OK >,\n"
227 " field_d: < 12.5 >,\n"
231 verifyFormat("msg_field: <\n"
233 " msg_field: { field_b: OK }\n"
239 verifyFormat("field_a {\n"
241 " field_b: < field_c: 1 >\n"
246 verifyFormat("field_a: {\n"
248 " field_b: < field_c: 1 >\n"
253 verifyFormat("field_a: <\n"
261 " field_x {} // Comment\n"
262 " field_y: { field_z: 1 }\n"
266 " field_x <> // Comment\n"
267 " field_y: < field_z: 1 >\n"
271 " field: < field: 1 >\n"
272 " field: < field: 2 >\n"
273 " field: < field: 3 >\n"
274 " field: < field: 4 >\n"
280 "field_c < field < field <> > >");
282 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
284 "data < key: value >");
286 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
288 "data < key: value >\n"
291 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
293 "data < key: value >\n"
294 "data { key: value }");
296 verifyFormat("app {\n"
297 " app_id: 'com.javax.swing.salsa.latino'\n"
299 " data < key: value >\n"
302 verifyFormat("app: {\n"
303 " app_id: 'com.javax.swing.salsa.latino'\n"
305 " data < key: value >\n"
308 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
309 "headheadheadheadheadhead_id: 1\n"
310 "product_data { product { 1 } }");
312 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
313 "headheadheadheadheadhead_id: 1\n"
314 "product_data < product { 1 } >");
316 verifyFormat("app_id: 'com.javax.swing.salsa.latino'\n"
317 "headheadheadheadheadhead_id: 1\n"
318 "product_data < product < 1 > >");
320 verifyFormat("app <\n"
321 " app_id: 'com.javax.swing.salsa.latino'\n"
322 " headheadheadheadheadhead_id: 1\n"
323 " product_data < product { 1 } >\n"
326 verifyFormat("dcccwrnfioeruvginerurneitinfo {\n"
327 " exte3nsionrnfvui { key: value }\n"
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.
338 " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
343 TEST_F(FormatTestTextProto
, KeepsLongStringLiteralsOnSameLine
) {
346 " text: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaaaa\"\n"
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");
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"
367 "## another double-hash comment.\n"
368 "### a triple-hash comment\n"
370 "### another triple-hash comment\n"
371 "#### a quadriple-hash comment\n"
373 "#### another quadriple-hash comment",
375 "##this is a double-hash comment.\n"
377 "## another double-hash comment.\n"
378 "###a triple-hash comment\n"
380 "### another triple-hash comment\n"
381 "####a quadriple-hash comment\n"
383 "#### another quadriple-hash comment",
386 // Ensure we support a common pattern for naming sections.
387 EXPECT_EQ("##############\n"
390 format("##############\n"
395 EXPECT_EQ("///////////////\n"
398 format("///////////////\n"
404 TEST_F(FormatTestTextProto
, FormatsExtensions
) {
405 verifyFormat("[type] { key: value }");
406 verifyFormat("[type] {\n"
407 " keyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: value\n"
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"
415 verifyFormat("msg {\n"
417 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
420 verifyFormat("key: value\n"
421 "[a.b] { key: value }");
422 verifyFormat("msg: <\n"
424 " [a.b.c/d.e]: < key: value >\n"
426 " key: valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n"
430 " [h.i.j] < key: value >\n"
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"
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.
453 "[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n"
457 "[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n"
459 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
462 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n"
465 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n"
469 "aaaaaaaaaaaaaaa {\n"
472 " eeeeeeeeeeeee: \"The lazy coo cat jumps over the lazy hot dog\"\n"
478 TEST_F(FormatTestTextProto
, SpacesAroundPercents
) {
479 verifyFormat("key: %d");
480 verifyFormat("key: 0x%04x");
481 verifyFormat("key: \"%d %d\"");
484 TEST_F(FormatTestTextProto
, FormatsRepeatedListInitializers
) {
485 verifyFormat("keys: []");
486 verifyFormat("keys: [ 1 ]");
487 verifyFormat("keys: [ 'ala', 'bala' ]");
488 verifyFormat("keys: [\n"
497 verifyFormat("key: item\n"
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
);
528 TEST_F(FormatTestTextProto
, AcceptsOperatorAsKey
) {
529 verifyFormat("aaaaaaaaaaa: <\n"
531 " ccccccccccccccccccccccc: <\n"
535 " operator { key: value }\n"
541 TEST_F(FormatTestTextProto
, BreaksConsecutiveStringLiterals
) {
542 verifyFormat("ala: \"str1\"\n"
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"
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"
568 verifyFormat("keys: <\n"
569 " data: { item: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }\n"
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"
580 " item: 'aaaaaaaaaaaaaaaa'\n"
583 verifyFormat("key: valueeeeeeee\n"
585 " item: 'aaaaaaaaaaaaaaaa'\n"
588 verifyFormat("key: valueeeeeeee\n"
594 verifyFormat("key: valueeeeeeee\n"
596 " item: 'aaaaaaaaaaa'\n"
599 verifyFormat("key: valueeeeeeee\n"
601 " item: 'aaaaaaaaaaa'\n"
604 verifyFormat("key: valueeeeeeee\n"
606 " item: 'aaaaaaaaaaa'\n"
609 verifyFormat("key: valueeeeeeee\n"
611 " item: 'aaaaaaaaaaa'\n"
614 verifyFormat("key: valueeeeeeee\n"
616 " item: 'aaaaaaaaaaa'\n"
619 verifyFormat("key: valueeeeeeee\n"
622 " item: 'aaaaaaaaaaaaaaaa'\n"
624 verifyFormat("key: valueeeeeeee\n"
627 " item: 'aaaaaaaaaaaaaaaa'\n"
629 verifyFormat("key: valueeeeeeee\n"
632 " item: 'aaaaaaaaaaaaaaaa'\n"
634 verifyFormat("key: valueeeeeeee\n"
636 " sub { key: value }\n"
637 " item: 'aaaaaaaaaaaaaaaa'\n"
639 verifyFormat("key: valueeeeeeee\n"
642 " item: 'aaaaaaaaaaaaaaaa'\n"
644 verifyFormat("key: valueeeeeeee\n"
646 " sub < sub_2: {} >\n"
647 " item: 'aaaaaaaaaaaaaaaa'\n"
649 verifyFormat("key: valueeeeeeee\n"
653 " item: 'aaaaaaaaaaaaaaaa'\n"
655 verifyFormat("key: valueeeeeeee\n"
658 " sub < sub_2: {} >\n"
659 " item: 'aaaaaaaaaaaaaaaa'\n"
661 verifyFormat("sub: {\n"
662 " key: valueeeeeeee\n"
665 " item: 'aaaaaaaaaaaaaaaa'\n"
668 verifyFormat("sub: {\n"
673 verifyFormat("sub: {\n"
680 TEST_F(FormatTestTextProto
, PreventBreaksBetweenKeyAndSubmessages
) {
681 verifyFormat("submessage: {\n"
682 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n"
684 verifyFormat("submessage {\n"
685 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n"
687 verifyFormat("submessage: <\n"
688 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n"
690 verifyFormat("submessage <\n"
691 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n"
693 verifyFormat("repeatedd: [\n"
694 " 'eyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n"
696 // "{" is going over the column limit.
698 "submessageeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee: {\n"
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"
717 "# endfile comment");
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"
729 verifyFormat("submessage: {\n"
740 } // namespace format
741 } // end namespace clang