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 413 TEST_F(FormatTestTextProto, FormatsExtensions) { 414 verifyFormat("[type] { key: value }"); 415 verifyFormat("[type] {\n" 416 " keyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy: value\n" 417 "}"); 418 verifyFormat("[type.type] { key: value }"); 419 verifyFormat("[type.type] < key: value >"); 420 verifyFormat("[type.type/type.type] { key: value }"); 421 verifyFormat("msg {\n" 422 " [type.type] { key: value }\n" 423 "}"); 424 verifyFormat("msg {\n" 425 " [type.type] {\n" 426 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" 427 " }\n" 428 "}"); 429 verifyFormat("key: value\n" 430 "[a.b] { key: value }"); 431 verifyFormat("msg: <\n" 432 " key: value\n" 433 " [a.b.c/d.e]: < key: value >\n" 434 " [f.g]: <\n" 435 " key: valueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n" 436 " key: {}\n" 437 " >\n" 438 " key {}\n" 439 " [h.i.j] < key: value >\n" 440 " [a]: {\n" 441 " [b.c]: {}\n" 442 " [d] <>\n" 443 " [e/f]: 1\n" 444 " }\n" 445 ">"); 446 verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n" 447 " .longg.longlong] { key: value }"); 448 verifyFormat("[longg.long.long.long.long.long.long.long.long.long.long\n" 449 " .longg.longlong] {\n" 450 " key: value\n" 451 " key: value\n" 452 " key: value\n" 453 " key: value\n" 454 "}"); 455 verifyFormat("[longg.long.long.long.long.long.long.long.long.long\n" 456 " .long/longg.longlong] { key: value }"); 457 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n" 458 " bbbbbbbbbbbbbb] { key: value }"); 459 // These go over the column limit intentionally, since the alternative 460 // [aa..a\n] is worse. 461 verifyFormat( 462 "[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n" 463 " key: value\n" 464 "}"); 465 verifyFormat( 466 "[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] {\n" 467 " [type.type] {\n" 468 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" 469 " }\n" 470 "}"); 471 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/\n" 472 " bbbbbbb] {\n" 473 " [type.type] {\n" 474 " keyyyyyyyyyyyyyy: valuuuuuuuuuuuuuuuuuuuuuuuuue\n" 475 " }\n" 476 "}"); 477 verifyFormat( 478 "aaaaaaaaaaaaaaa {\n" 479 " bbbbbb {\n" 480 " [a.b/cy] {\n" 481 " eeeeeeeeeeeee: \"The lazy coo cat jumps over the lazy hot dog\"\n" 482 " }\n" 483 " }\n" 484 "}"); 485 } 486 487 TEST_F(FormatTestTextProto, SpacesAroundPercents) { 488 verifyFormat("key: %d"); 489 verifyFormat("key: 0x%04x"); 490 verifyFormat("key: \"%d %d\""); 491 } 492 493 TEST_F(FormatTestTextProto, FormatsRepeatedListInitializers) { 494 verifyFormat("keys: []"); 495 verifyFormat("keys: [ 1 ]"); 496 verifyFormat("keys: [ 'ala', 'bala' ]"); 497 verifyFormat("keys: [\n" 498 " 'ala',\n" 499 " 'bala',\n" 500 " 'porto',\n" 501 " 'kala',\n" 502 " 'too',\n" 503 " 'long',\n" 504 " 'ng'\n" 505 "]"); 506 verifyFormat("key: item\n" 507 "keys: [\n" 508 " 'ala',\n" 509 " 'bala',\n" 510 " 'porto',\n" 511 " 'kala',\n" 512 " 'too',\n" 513 " 'long',\n" 514 " 'long',\n" 515 " 'long'\n" 516 "]\n" 517 "key: item\n" 518 "msg {\n" 519 " key: item\n" 520 " keys: [\n" 521 " 'ala',\n" 522 " 'bala',\n" 523 " 'porto',\n" 524 " 'kala',\n" 525 " 'too',\n" 526 " 'long',\n" 527 " 'long'\n" 528 " ]\n" 529 "}\n" 530 "key: value"); 531 FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); 532 Style.ColumnLimit = 60; // To make writing tests easier. 533 Style.Cpp11BracedListStyle = true; 534 verifyFormat("keys: [1]", Style); 535 } 536 537 TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) { 538 verifyFormat("aaaaaaaaaaa: <\n" 539 " bbbbbbbbb: <\n" 540 " ccccccccccccccccccccccc: <\n" 541 " operator: 1\n" 542 " operator: 2\n" 543 " operator: 3\n" 544 " operator { key: value }\n" 545 " >\n" 546 " >\n" 547 ">"); 548 } 549 550 TEST_F(FormatTestTextProto, BreaksConsecutiveStringLiterals) { 551 verifyFormat("ala: \"str1\"\n" 552 " \"str2\"\n"); 553 } 554 555 TEST_F(FormatTestTextProto, PutsMultipleEntriesInExtensionsOnNewlines) { 556 FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); 557 verifyFormat("pppppppppp: {\n" 558 " ssssss: \"http://example.com/blahblahblah\"\n" 559 " ppppppp: \"sssss/MMMMMMMMMMMM\"\n" 560 " [ns.sssss.eeeeeeeee.eeeeeeeeeeeeeee] { begin: 24 end: 252 }\n" 561 " [ns.sssss.eeeeeeeee.eeeeeeeeeeeeeee] {\n" 562 " begin: 24\n" 563 " end: 252\n" 564 " key: value\n" 565 " key: value\n" 566 " }\n" 567 "}", 568 Style); 569 } 570 571 TEST_F(FormatTestTextProto, BreaksAfterBraceFollowedByClosingBraceOnNextLine) { 572 FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); 573 Style.ColumnLimit = 60; 574 verifyFormat("keys: [\n" 575 " data: { item: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }\n" 576 "]"); 577 verifyFormat("keys: <\n" 578 " data: { item: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }\n" 579 ">"); 580 } 581 582 TEST_F(FormatTestTextProto, BreaksEntriesOfSubmessagesContainingSubmessages) { 583 FormatStyle Style = getGoogleStyle(FormatStyle::LK_TextProto); 584 Style.ColumnLimit = 60; 585 // The column limit allows for the keys submessage to be put on 1 line, but we 586 // break it since it contains a submessage an another entry. 587 verifyFormat("key: valueeeeeeee\n" 588 "keys: {\n" 589 " item: 'aaaaaaaaaaaaaaaa'\n" 590 " sub <>\n" 591 "}"); 592 verifyFormat("key: valueeeeeeee\n" 593 "keys: {\n" 594 " item: 'aaaaaaaaaaaaaaaa'\n" 595 " sub {}\n" 596 "}"); 597 verifyFormat("key: valueeeeeeee\n" 598 "keys: {\n" 599 " sub {}\n" 600 " sub: <>\n" 601 " sub: []\n" 602 "}"); 603 verifyFormat("key: valueeeeeeee\n" 604 "keys: {\n" 605 " item: 'aaaaaaaaaaa'\n" 606 " sub { msg: 1 }\n" 607 "}"); 608 verifyFormat("key: valueeeeeeee\n" 609 "keys: {\n" 610 " item: 'aaaaaaaaaaa'\n" 611 " sub: { msg: 1 }\n" 612 "}"); 613 verifyFormat("key: valueeeeeeee\n" 614 "keys: {\n" 615 " item: 'aaaaaaaaaaa'\n" 616 " sub < msg: 1 >\n" 617 "}"); 618 verifyFormat("key: valueeeeeeee\n" 619 "keys: {\n" 620 " item: 'aaaaaaaaaaa'\n" 621 " sub: [ msg: 1 ]\n" 622 "}"); 623 verifyFormat("key: valueeeeeeee\n" 624 "keys: <\n" 625 " item: 'aaaaaaaaaaa'\n" 626 " sub: [ 1, 2 ]\n" 627 ">"); 628 verifyFormat("key: valueeeeeeee\n" 629 "keys: {\n" 630 " sub {}\n" 631 " item: 'aaaaaaaaaaaaaaaa'\n" 632 "}"); 633 verifyFormat("key: valueeeeeeee\n" 634 "keys: {\n" 635 " sub: []\n" 636 " item: 'aaaaaaaaaaaaaaaa'\n" 637 "}"); 638 verifyFormat("key: valueeeeeeee\n" 639 "keys: {\n" 640 " sub <>\n" 641 " item: 'aaaaaaaaaaaaaaaa'\n" 642 "}"); 643 verifyFormat("key: valueeeeeeee\n" 644 "keys: {\n" 645 " sub { key: value }\n" 646 " item: 'aaaaaaaaaaaaaaaa'\n" 647 "}"); 648 verifyFormat("key: valueeeeeeee\n" 649 "keys: {\n" 650 " sub: [ 1, 2 ]\n" 651 " item: 'aaaaaaaaaaaaaaaa'\n" 652 "}"); 653 verifyFormat("key: valueeeeeeee\n" 654 "keys: {\n" 655 " sub < sub_2: {} >\n" 656 " item: 'aaaaaaaaaaaaaaaa'\n" 657 "}"); 658 verifyFormat("key: valueeeeeeee\n" 659 "keys: {\n" 660 " item: data\n" 661 " sub: [ 1, 2 ]\n" 662 " item: 'aaaaaaaaaaaaaaaa'\n" 663 "}"); 664 verifyFormat("key: valueeeeeeee\n" 665 "keys: {\n" 666 " item: data\n" 667 " sub < sub_2: {} >\n" 668 " item: 'aaaaaaaaaaaaaaaa'\n" 669 "}"); 670 verifyFormat("sub: {\n" 671 " key: valueeeeeeee\n" 672 " keys: {\n" 673 " sub: [ 1, 2 ]\n" 674 " item: 'aaaaaaaaaaaaaaaa'\n" 675 " }\n" 676 "}"); 677 verifyFormat("sub: {\n" 678 " key: 1\n" 679 " sub: {}\n" 680 "}\n" 681 "# comment\n"); 682 verifyFormat("sub: {\n" 683 " key: 1\n" 684 " # comment\n" 685 " sub: {}\n" 686 "}"); 687 } 688 689 TEST_F(FormatTestTextProto, PreventBreaksBetweenKeyAndSubmessages) { 690 verifyFormat("submessage: {\n" 691 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" 692 "}"); 693 verifyFormat("submessage {\n" 694 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" 695 "}"); 696 verifyFormat("submessage: <\n" 697 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" 698 ">"); 699 verifyFormat("submessage <\n" 700 " key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" 701 ">"); 702 verifyFormat("repeatedd: [\n" 703 " 'eyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n" 704 "]"); 705 // "{" is going over the column limit. 706 verifyFormat( 707 "submessageeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee: {\n" 708 " key: 'aaaaa'\n" 709 "}"); 710 } 711 712 TEST_F(FormatTestTextProto, FormatsCommentsAtEndOfFile) { 713 verifyFormat("key: value\n" 714 "# endfile comment"); 715 verifyFormat("key: value\n" 716 "// endfile comment"); 717 verifyFormat("key: value\n" 718 "// endfile comment 1\n" 719 "// endfile comment 2"); 720 verifyFormat("submessage { key: value }\n" 721 "# endfile comment"); 722 verifyFormat("submessage <\n" 723 " key: value\n" 724 " item {}\n" 725 ">\n" 726 "# endfile comment"); 727 } 728 729 TEST_F(FormatTestTextProto, KeepsAmpersandsNextToKeys) { 730 verifyFormat("@tmpl { field: 1 }"); 731 verifyFormat("@placeholder: 1"); 732 verifyFormat("@name <>"); 733 verifyFormat("submessage: @base { key: value }"); 734 verifyFormat("submessage: @base {\n" 735 " key: value\n" 736 " item: {}\n" 737 "}"); 738 verifyFormat("submessage: {\n" 739 " msg: @base {\n" 740 " yolo: {}\n" 741 " key: value\n" 742 " }\n" 743 " key: value\n" 744 "}"); 745 } 746 747 } // namespace format 748 } // end namespace clang 749