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