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