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