1 //===- llvm/unittest/Support/ScopedPrinterTest.cpp - ScopedPrinter tests --===// 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 "llvm/Support/ScopedPrinter.h" 10 #include "llvm/ADT/APSInt.h" 11 #include "gtest/gtest.h" 12 #include <vector> 13 14 using namespace llvm; 15 16 TEST(JSONScopedPrinterTest, PrettyPrintCtor) { 17 auto PrintFunc = [](ScopedPrinter &W) { 18 DictScope D(W); 19 W.printString("Key", "Value"); 20 }; 21 std::string StreamBuffer; 22 raw_string_ostream OS(StreamBuffer); 23 JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true); 24 JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false); 25 26 const char *PrettyPrintOut = R"({ 27 "Key": "Value" 28 })"; 29 const char *NoPrettyPrintOut = R"({"Key":"Value"})"; 30 PrintFunc(PrettyPrintWriter); 31 EXPECT_EQ(PrettyPrintOut, OS.str()); 32 StreamBuffer.clear(); 33 PrintFunc(NoPrettyPrintWriter); 34 EXPECT_EQ(NoPrettyPrintOut, OS.str()); 35 } 36 37 TEST(JSONScopedPrinterTest, DelimitedScopeCtor) { 38 std::string StreamBuffer; 39 raw_string_ostream OS(StreamBuffer); 40 { 41 JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false, 42 std::make_unique<DictScope>()); 43 DictScopeWriter.printString("Label", "DictScope"); 44 } 45 EXPECT_EQ(R"({"Label":"DictScope"})", OS.str()); 46 StreamBuffer.clear(); 47 { 48 JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false, 49 std::make_unique<ListScope>()); 50 ListScopeWriter.printString("ListScope"); 51 } 52 EXPECT_EQ(R"(["ListScope"])", OS.str()); 53 StreamBuffer.clear(); 54 { 55 JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false); 56 NoScopeWriter.printString("NoScope"); 57 } 58 EXPECT_EQ(R"("NoScope")", OS.str()); 59 } 60 61 class ScopedPrinterTest : public ::testing::Test { 62 protected: 63 std::string StreamBuffer; 64 raw_string_ostream OS; 65 ScopedPrinter Writer; 66 JSONScopedPrinter JSONWriter; 67 68 bool HasPrintedToJSON; 69 70 ScopedPrinterTest() 71 : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true), 72 HasPrintedToJSON(false) {} 73 74 using PrintFunc = function_ref<void(ScopedPrinter &)>; 75 76 void verifyScopedPrinter(StringRef Expected, PrintFunc Func) { 77 Func(Writer); 78 Writer.flush(); 79 EXPECT_EQ(Expected.str(), OS.str()); 80 StreamBuffer.clear(); 81 } 82 83 void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) { 84 { 85 DictScope D(JSONWriter); 86 Func(JSONWriter); 87 } 88 JSONWriter.flush(); 89 EXPECT_EQ(Expected.str(), OS.str()); 90 StreamBuffer.clear(); 91 HasPrintedToJSON = true; 92 } 93 94 void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut, 95 PrintFunc Func) { 96 verifyScopedPrinter(ExpectedOut, Func); 97 verifyJSONScopedPrinter(JSONExpectedOut, Func); 98 } 99 100 void TearDown() { 101 // JSONScopedPrinter fails an assert if nothing's been printed. 102 if (!HasPrintedToJSON) 103 JSONWriter.printString(""); 104 } 105 }; 106 107 TEST_F(ScopedPrinterTest, GetKind) { 108 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind()); 109 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind()); 110 } 111 112 TEST_F(ScopedPrinterTest, ClassOf) { 113 EXPECT_TRUE(ScopedPrinter::classof(&Writer)); 114 EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter)); 115 EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter)); 116 EXPECT_FALSE(JSONScopedPrinter::classof(&Writer)); 117 } 118 119 TEST_F(ScopedPrinterTest, Indent) { 120 auto PrintFunc = [](ScopedPrinter &W) { 121 W.printString("|"); 122 W.indent(); 123 W.printString("|"); 124 W.indent(2); 125 W.printString("|"); 126 }; 127 128 const char *ExpectedOut = R"(| 129 | 130 | 131 )"; 132 verifyScopedPrinter(ExpectedOut, PrintFunc); 133 } 134 135 TEST_F(ScopedPrinterTest, Unindent) { 136 auto PrintFunc = [](ScopedPrinter &W) { 137 W.indent(3); 138 W.printString("|"); 139 W.unindent(2); 140 W.printString("|"); 141 W.unindent(); 142 W.printString("|"); 143 W.unindent(); 144 W.printString("|"); 145 }; 146 147 const char *ExpectedOut = R"( | 148 | 149 | 150 | 151 )"; 152 verifyScopedPrinter(ExpectedOut, PrintFunc); 153 } 154 155 TEST_F(ScopedPrinterTest, ResetIndent) { 156 auto PrintFunc = [](ScopedPrinter &W) { 157 W.indent(4); 158 W.printString("|"); 159 W.resetIndent(); 160 W.printString("|"); 161 }; 162 163 const char *ExpectedOut = R"( | 164 | 165 )"; 166 verifyScopedPrinter(ExpectedOut, PrintFunc); 167 } 168 169 TEST_F(ScopedPrinterTest, PrintIndent) { 170 auto PrintFunc = [](ScopedPrinter &W) { 171 W.printIndent(); 172 W.printString("|"); 173 W.indent(); 174 W.printIndent(); 175 W.printString("|"); 176 }; 177 178 const char *ExpectedOut = R"(| 179 | 180 )"; 181 verifyScopedPrinter(ExpectedOut, PrintFunc); 182 } 183 184 TEST_F(ScopedPrinterTest, GetIndentLevel) { 185 EXPECT_EQ(Writer.getIndentLevel(), 0); 186 Writer.indent(); 187 EXPECT_EQ(Writer.getIndentLevel(), 1); 188 Writer.indent(); 189 EXPECT_EQ(Writer.getIndentLevel(), 2); 190 Writer.unindent(); 191 EXPECT_EQ(Writer.getIndentLevel(), 1); 192 Writer.indent(); 193 Writer.resetIndent(); 194 EXPECT_EQ(Writer.getIndentLevel(), 0); 195 Writer.unindent(); 196 EXPECT_EQ(Writer.getIndentLevel(), 0); 197 Writer.indent(); 198 EXPECT_EQ(Writer.getIndentLevel(), 1); 199 } 200 201 TEST_F(ScopedPrinterTest, SetPrefix) { 202 auto PrintFunc = [](ScopedPrinter &W) { 203 W.setPrefix("Prefix1"); 204 W.indent(); 205 W.printIndent(); 206 W.printString("|"); 207 W.unindent(); 208 W.printIndent(); 209 W.printString("|"); 210 W.setPrefix("Prefix2"); 211 W.printIndent(); 212 W.printString("|"); 213 }; 214 215 const char *ExpectedOut = R"(Prefix1 Prefix1 | 216 Prefix1Prefix1| 217 Prefix2Prefix2| 218 )"; 219 verifyScopedPrinter(ExpectedOut, PrintFunc); 220 } 221 222 TEST_F(ScopedPrinterTest, PrintEnum) { 223 auto PrintFunc = [](ScopedPrinter &W) { 224 const EnumEntry<int> EnumList[] = {{"Name1", "AltName1", 1}, 225 {"Name2", "AltName2", 2}, 226 {"Name3", "AltName3", 3}, 227 {"Name4", "AltName4", 2}}; 228 EnumEntry<int> OtherEnum{"Name5", "AltName5", 5}; 229 W.printEnum("Exists", EnumList[1].Value, ArrayRef(EnumList)); 230 W.printEnum("DoesNotExist", OtherEnum.Value, ArrayRef(EnumList)); 231 }; 232 233 const char *ExpectedOut = R"(Exists: Name2 (0x2) 234 DoesNotExist: 0x5 235 )"; 236 237 const char *JSONExpectedOut = R"({ 238 "Exists": { 239 "Name": "Name2", 240 "Value": 2 241 }, 242 "DoesNotExist": 5 243 })"; 244 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 245 } 246 247 TEST_F(ScopedPrinterTest, PrintFlag) { 248 auto PrintFunc = [](ScopedPrinter &W) { 249 const EnumEntry<uint16_t> SingleBitFlags[] = { 250 {"Name0", "AltName0", 0}, 251 {"Name1", "AltName1", 1}, 252 {"Name2", "AltName2", 1 << 1}, 253 {"Name3", "AltName3", 1 << 2}}; 254 const EnumEntry<uint16_t> UnsortedFlags[] = { 255 {"C", "c", 1}, {"B", "b", 1 << 1}, {"A", "a", 1 << 2}}; 256 const EnumEntry<uint16_t> EnumFlags[] = { 257 {"FirstByte1", "First1", 0x1u}, {"FirstByte2", "First2", 0x2u}, 258 {"FirstByte3", "First3", 0x3u}, {"SecondByte1", "Second1", 0x10u}, 259 {"SecondByte2", "Second2", 0x20u}, {"SecondByte3", "Second3", 0x30u}, 260 {"ThirdByte1", "Third1", 0x100u}, {"ThirdByte2", "Third2", 0x200u}, 261 {"ThirdByte3", "Third3", 0x300u}}; 262 W.printFlags("ZeroFlag", 0, ArrayRef(SingleBitFlags)); 263 W.printFlags("NoFlag", 1 << 3, ArrayRef(SingleBitFlags)); 264 W.printFlags("Flag1", SingleBitFlags[1].Value, ArrayRef(SingleBitFlags)); 265 W.printFlags("Flag1&3", (1 << 2) + 1, ArrayRef(SingleBitFlags)); 266 267 W.printFlags("ZeroFlagRaw", 0); 268 W.printFlags("NoFlagRaw", 1 << 3); 269 W.printFlags("Flag1Raw", SingleBitFlags[1].Value); 270 W.printFlags("Flag1&3Raw", (1 << 2) + 1); 271 272 W.printFlags("FlagSorted", (1 << 2) + (1 << 1) + 1, 273 ArrayRef(UnsortedFlags)); 274 275 uint16_t NoBitMask = 0; 276 uint16_t FirstByteMask = 0xFu; 277 uint16_t SecondByteMask = 0xF0u; 278 uint16_t ThirdByteMask = 0xF00u; 279 W.printFlags("NoBitMask", 0xFFFu, ArrayRef(EnumFlags), NoBitMask); 280 W.printFlags("FirstByteMask", 0x3u, ArrayRef(EnumFlags), FirstByteMask); 281 W.printFlags("SecondByteMask", 0x30u, ArrayRef(EnumFlags), SecondByteMask); 282 W.printFlags("ValueOutsideMask", 0x1u, ArrayRef(EnumFlags), SecondByteMask); 283 W.printFlags("FirstSecondByteMask", 0xFFu, ArrayRef(EnumFlags), 284 FirstByteMask, SecondByteMask); 285 W.printFlags("FirstSecondThirdByteMask", 0x333u, ArrayRef(EnumFlags), 286 FirstByteMask, SecondByteMask, ThirdByteMask); 287 }; 288 289 const char *ExpectedOut = R"(ZeroFlag [ (0x0) 290 ] 291 NoFlag [ (0x8) 292 ] 293 Flag1 [ (0x1) 294 Name1 (0x1) 295 ] 296 Flag1&3 [ (0x5) 297 Name1 (0x1) 298 Name3 (0x4) 299 ] 300 ZeroFlagRaw [ (0x0) 301 ] 302 NoFlagRaw [ (0x8) 303 0x8 304 ] 305 Flag1Raw [ (0x1) 306 0x1 307 ] 308 Flag1&3Raw [ (0x5) 309 0x1 310 0x4 311 ] 312 FlagSorted [ (0x7) 313 A (0x4) 314 B (0x2) 315 C (0x1) 316 ] 317 NoBitMask [ (0xFFF) 318 FirstByte1 (0x1) 319 FirstByte2 (0x2) 320 FirstByte3 (0x3) 321 SecondByte1 (0x10) 322 SecondByte2 (0x20) 323 SecondByte3 (0x30) 324 ThirdByte1 (0x100) 325 ThirdByte2 (0x200) 326 ThirdByte3 (0x300) 327 ] 328 FirstByteMask [ (0x3) 329 FirstByte3 (0x3) 330 ] 331 SecondByteMask [ (0x30) 332 SecondByte3 (0x30) 333 ] 334 ValueOutsideMask [ (0x1) 335 FirstByte1 (0x1) 336 ] 337 FirstSecondByteMask [ (0xFF) 338 ] 339 FirstSecondThirdByteMask [ (0x333) 340 FirstByte3 (0x3) 341 SecondByte3 (0x30) 342 ThirdByte3 (0x300) 343 ] 344 )"; 345 346 const char *JSONExpectedOut = R"({ 347 "ZeroFlag": { 348 "Value": 0, 349 "Flags": [] 350 }, 351 "NoFlag": { 352 "Value": 8, 353 "Flags": [] 354 }, 355 "Flag1": { 356 "Value": 1, 357 "Flags": [ 358 { 359 "Name": "Name1", 360 "Value": 1 361 } 362 ] 363 }, 364 "Flag1&3": { 365 "Value": 5, 366 "Flags": [ 367 { 368 "Name": "Name1", 369 "Value": 1 370 }, 371 { 372 "Name": "Name3", 373 "Value": 4 374 } 375 ] 376 }, 377 "ZeroFlagRaw": { 378 "Value": 0, 379 "Flags": [] 380 }, 381 "NoFlagRaw": { 382 "Value": 8, 383 "Flags": [ 384 8 385 ] 386 }, 387 "Flag1Raw": { 388 "Value": 1, 389 "Flags": [ 390 1 391 ] 392 }, 393 "Flag1&3Raw": { 394 "Value": 5, 395 "Flags": [ 396 1, 397 4 398 ] 399 }, 400 "FlagSorted": { 401 "Value": 7, 402 "Flags": [ 403 { 404 "Name": "A", 405 "Value": 4 406 }, 407 { 408 "Name": "B", 409 "Value": 2 410 }, 411 { 412 "Name": "C", 413 "Value": 1 414 } 415 ] 416 }, 417 "NoBitMask": { 418 "Value": 4095, 419 "Flags": [ 420 { 421 "Name": "FirstByte1", 422 "Value": 1 423 }, 424 { 425 "Name": "FirstByte2", 426 "Value": 2 427 }, 428 { 429 "Name": "FirstByte3", 430 "Value": 3 431 }, 432 { 433 "Name": "SecondByte1", 434 "Value": 16 435 }, 436 { 437 "Name": "SecondByte2", 438 "Value": 32 439 }, 440 { 441 "Name": "SecondByte3", 442 "Value": 48 443 }, 444 { 445 "Name": "ThirdByte1", 446 "Value": 256 447 }, 448 { 449 "Name": "ThirdByte2", 450 "Value": 512 451 }, 452 { 453 "Name": "ThirdByte3", 454 "Value": 768 455 } 456 ] 457 }, 458 "FirstByteMask": { 459 "Value": 3, 460 "Flags": [ 461 { 462 "Name": "FirstByte3", 463 "Value": 3 464 } 465 ] 466 }, 467 "SecondByteMask": { 468 "Value": 48, 469 "Flags": [ 470 { 471 "Name": "SecondByte3", 472 "Value": 48 473 } 474 ] 475 }, 476 "ValueOutsideMask": { 477 "Value": 1, 478 "Flags": [ 479 { 480 "Name": "FirstByte1", 481 "Value": 1 482 } 483 ] 484 }, 485 "FirstSecondByteMask": { 486 "Value": 255, 487 "Flags": [] 488 }, 489 "FirstSecondThirdByteMask": { 490 "Value": 819, 491 "Flags": [ 492 { 493 "Name": "FirstByte3", 494 "Value": 3 495 }, 496 { 497 "Name": "SecondByte3", 498 "Value": 48 499 }, 500 { 501 "Name": "ThirdByte3", 502 "Value": 768 503 } 504 ] 505 } 506 })"; 507 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 508 } 509 510 TEST_F(ScopedPrinterTest, PrintNumber) { 511 auto PrintFunc = [](ScopedPrinter &W) { 512 uint64_t Unsigned64Max = std::numeric_limits<uint64_t>::max(); 513 uint64_t Unsigned64Min = std::numeric_limits<uint64_t>::min(); 514 W.printNumber("uint64_t-max", Unsigned64Max); 515 W.printNumber("uint64_t-min", Unsigned64Min); 516 517 uint32_t Unsigned32Max = std::numeric_limits<uint32_t>::max(); 518 uint32_t Unsigned32Min = std::numeric_limits<uint32_t>::min(); 519 W.printNumber("uint32_t-max", Unsigned32Max); 520 W.printNumber("uint32_t-min", Unsigned32Min); 521 522 uint16_t Unsigned16Max = std::numeric_limits<uint16_t>::max(); 523 uint16_t Unsigned16Min = std::numeric_limits<uint16_t>::min(); 524 W.printNumber("uint16_t-max", Unsigned16Max); 525 W.printNumber("uint16_t-min", Unsigned16Min); 526 527 uint8_t Unsigned8Max = std::numeric_limits<uint8_t>::max(); 528 uint8_t Unsigned8Min = std::numeric_limits<uint8_t>::min(); 529 W.printNumber("uint8_t-max", Unsigned8Max); 530 W.printNumber("uint8_t-min", Unsigned8Min); 531 532 int64_t Signed64Max = std::numeric_limits<int64_t>::max(); 533 int64_t Signed64Min = std::numeric_limits<int64_t>::min(); 534 W.printNumber("int64_t-max", Signed64Max); 535 W.printNumber("int64_t-min", Signed64Min); 536 537 int32_t Signed32Max = std::numeric_limits<int32_t>::max(); 538 int32_t Signed32Min = std::numeric_limits<int32_t>::min(); 539 W.printNumber("int32_t-max", Signed32Max); 540 W.printNumber("int32_t-min", Signed32Min); 541 542 int16_t Signed16Max = std::numeric_limits<int16_t>::max(); 543 int16_t Signed16Min = std::numeric_limits<int16_t>::min(); 544 W.printNumber("int16_t-max", Signed16Max); 545 W.printNumber("int16_t-min", Signed16Min); 546 547 int8_t Signed8Max = std::numeric_limits<int8_t>::max(); 548 int8_t Signed8Min = std::numeric_limits<int8_t>::min(); 549 W.printNumber("int8_t-max", Signed8Max); 550 W.printNumber("int8_t-min", Signed8Min); 551 552 APSInt LargeNum("9999999999999999999999"); 553 W.printNumber("apsint", LargeNum); 554 555 W.printNumber("label", "value", 0); 556 }; 557 558 const char *ExpectedOut = R"(uint64_t-max: 18446744073709551615 559 uint64_t-min: 0 560 uint32_t-max: 4294967295 561 uint32_t-min: 0 562 uint16_t-max: 65535 563 uint16_t-min: 0 564 uint8_t-max: 255 565 uint8_t-min: 0 566 int64_t-max: 9223372036854775807 567 int64_t-min: -9223372036854775808 568 int32_t-max: 2147483647 569 int32_t-min: -2147483648 570 int16_t-max: 32767 571 int16_t-min: -32768 572 int8_t-max: 127 573 int8_t-min: -128 574 apsint: 9999999999999999999999 575 label: value (0) 576 )"; 577 578 const char *JSONExpectedOut = R"({ 579 "uint64_t-max": 18446744073709551615, 580 "uint64_t-min": 0, 581 "uint32_t-max": 4294967295, 582 "uint32_t-min": 0, 583 "uint16_t-max": 65535, 584 "uint16_t-min": 0, 585 "uint8_t-max": 255, 586 "uint8_t-min": 0, 587 "int64_t-max": 9223372036854775807, 588 "int64_t-min": -9223372036854775808, 589 "int32_t-max": 2147483647, 590 "int32_t-min": -2147483648, 591 "int16_t-max": 32767, 592 "int16_t-min": -32768, 593 "int8_t-max": 127, 594 "int8_t-min": -128, 595 "apsint": 9999999999999999999999, 596 "label": { 597 "Name": "value", 598 "Value": 0 599 } 600 })"; 601 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 602 } 603 604 TEST_F(ScopedPrinterTest, PrintBoolean) { 605 auto PrintFunc = [](ScopedPrinter &W) { 606 W.printBoolean("True", true); 607 W.printBoolean("False", false); 608 }; 609 610 const char *ExpectedOut = R"(True: Yes 611 False: No 612 )"; 613 614 const char *JSONExpectedOut = R"({ 615 "True": true, 616 "False": false 617 })"; 618 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 619 } 620 621 TEST_F(ScopedPrinterTest, PrintVersion) { 622 auto PrintFunc = [](ScopedPrinter &W) { 623 W.printVersion("Version", "123", "456", "789"); 624 }; 625 const char *ExpectedOut = R"(Version: 123.456.789 626 )"; 627 verifyScopedPrinter(ExpectedOut, PrintFunc); 628 } 629 630 TEST_F(ScopedPrinterTest, PrintList) { 631 auto PrintFunc = [](ScopedPrinter &W) { 632 const std::vector<uint64_t> EmptyList; 633 const std::vector<std::string> StringList = {"foo", "bar", "baz"}; 634 const bool BoolList[] = {true, false}; 635 const std::vector<uint64_t> Unsigned64List = { 636 std::numeric_limits<uint64_t>::max(), 637 std::numeric_limits<uint64_t>::min()}; 638 const std::vector<uint32_t> Unsigned32List = { 639 std::numeric_limits<uint32_t>::max(), 640 std::numeric_limits<uint32_t>::min()}; 641 const std::vector<uint16_t> Unsigned16List = { 642 std::numeric_limits<uint16_t>::max(), 643 std::numeric_limits<uint16_t>::min()}; 644 const std::vector<uint8_t> Unsigned8List = { 645 std::numeric_limits<uint8_t>::max(), 646 std::numeric_limits<uint8_t>::min()}; 647 const std::vector<int64_t> Signed64List = { 648 std::numeric_limits<int64_t>::max(), 649 std::numeric_limits<int64_t>::min()}; 650 const std::vector<int32_t> Signed32List = { 651 std::numeric_limits<int32_t>::max(), 652 std::numeric_limits<int32_t>::min()}; 653 const std::vector<int16_t> Signed16List = { 654 std::numeric_limits<int16_t>::max(), 655 std::numeric_limits<int16_t>::min()}; 656 const std::vector<int8_t> Signed8List = { 657 std::numeric_limits<int8_t>::max(), std::numeric_limits<int8_t>::min()}; 658 const std::vector<APSInt> APSIntList = {APSInt("9999999999999999999999"), 659 APSInt("-9999999999999999999999")}; 660 W.printList("EmptyList", EmptyList); 661 W.printList("StringList", StringList); 662 W.printList("BoolList", ArrayRef(BoolList)); 663 W.printList("uint64List", Unsigned64List); 664 W.printList("uint32List", Unsigned32List); 665 W.printList("uint16List", Unsigned16List); 666 W.printList("uint8List", Unsigned8List); 667 W.printList("int64List", Signed64List); 668 W.printList("int32List", Signed32List); 669 W.printList("int16List", Signed16List); 670 W.printList("int8List", Signed8List); 671 W.printList("APSIntList", APSIntList); 672 }; 673 674 const char *ExpectedOut = R"(EmptyList: [] 675 StringList: [foo, bar, baz] 676 BoolList: [1, 0] 677 uint64List: [18446744073709551615, 0] 678 uint32List: [4294967295, 0] 679 uint16List: [65535, 0] 680 uint8List: [255, 0] 681 int64List: [9223372036854775807, -9223372036854775808] 682 int32List: [2147483647, -2147483648] 683 int16List: [32767, -32768] 684 int8List: [127, -128] 685 APSIntList: [9999999999999999999999, -9999999999999999999999] 686 )"; 687 688 const char *JSONExpectedOut = R"({ 689 "EmptyList": [], 690 "StringList": [ 691 "foo", 692 "bar", 693 "baz" 694 ], 695 "BoolList": [ 696 true, 697 false 698 ], 699 "uint64List": [ 700 18446744073709551615, 701 0 702 ], 703 "uint32List": [ 704 4294967295, 705 0 706 ], 707 "uint16List": [ 708 65535, 709 0 710 ], 711 "uint8List": [ 712 255, 713 0 714 ], 715 "int64List": [ 716 9223372036854775807, 717 -9223372036854775808 718 ], 719 "int32List": [ 720 2147483647, 721 -2147483648 722 ], 723 "int16List": [ 724 32767, 725 -32768 726 ], 727 "int8List": [ 728 127, 729 -128 730 ], 731 "APSIntList": [ 732 9999999999999999999999, 733 -9999999999999999999999 734 ] 735 })"; 736 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 737 } 738 739 TEST_F(ScopedPrinterTest, PrintListPrinter) { 740 auto PrintFunc = [](ScopedPrinter &W) { 741 const std::string StringList[] = {"a", "ab", "abc"}; 742 W.printList("StringSizeList", StringList, 743 [](raw_ostream &OS, StringRef Item) { OS << Item.size(); }); 744 }; 745 746 const char *ExpectedOut = R"(StringSizeList: [1, 2, 3] 747 )"; 748 verifyScopedPrinter(ExpectedOut, PrintFunc); 749 } 750 751 TEST_F(ScopedPrinterTest, PrintHex) { 752 auto PrintFunc = [](ScopedPrinter &W) { 753 W.printHex("HexNumber", 0x10); 754 W.printHex("HexLabel", "Name", 0x10); 755 }; 756 757 const char *ExpectedOut = R"(HexNumber: 0x10 758 HexLabel: Name (0x10) 759 )"; 760 761 const char *JSONExpectedOut = R"({ 762 "HexNumber": 16, 763 "HexLabel": { 764 "Name": "Name", 765 "Value": 16 766 } 767 })"; 768 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 769 } 770 771 TEST_F(ScopedPrinterTest, PrintHexList) { 772 auto PrintFunc = [](ScopedPrinter &W) { 773 const uint64_t HexList[] = {0x1, 0x10, 0x100}; 774 W.printHexList("HexList", HexList); 775 }; 776 const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100] 777 )"; 778 779 const char *JSONExpectedOut = R"({ 780 "HexList": [ 781 1, 782 16, 783 256 784 ] 785 })"; 786 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 787 } 788 789 TEST_F(ScopedPrinterTest, PrintSymbolOffset) { 790 auto PrintFunc = [](ScopedPrinter &W) { 791 W.printSymbolOffset("SymbolOffset", "SymbolName", 0x10); 792 W.printSymbolOffset("NoSymbolOffset", "SymbolName", 0); 793 }; 794 const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10 795 NoSymbolOffset: SymbolName+0x0 796 )"; 797 798 const char *JSONExpectedOut = R"({ 799 "SymbolOffset": { 800 "SymName": "SymbolName", 801 "Offset": 16 802 }, 803 "NoSymbolOffset": { 804 "SymName": "SymbolName", 805 "Offset": 0 806 } 807 })"; 808 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 809 } 810 811 TEST_F(ScopedPrinterTest, PrintString) { 812 auto PrintFunc = [](ScopedPrinter &W) { 813 const StringRef StringRefValue("Value"); 814 const std::string StringValue = "Value"; 815 const char *CharArrayValue = "Value"; 816 W.printString("StringRef", StringRefValue); 817 W.printString("String", StringValue); 818 W.printString("CharArray", CharArrayValue); 819 ListScope L(W, "StringList"); 820 W.printString(StringRefValue); 821 }; 822 823 const char *ExpectedOut = R"(StringRef: Value 824 String: Value 825 CharArray: Value 826 StringList [ 827 Value 828 ] 829 )"; 830 831 const char *JSONExpectedOut = R"({ 832 "StringRef": "Value", 833 "String": "Value", 834 "CharArray": "Value", 835 "StringList": [ 836 "Value" 837 ] 838 })"; 839 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 840 } 841 842 TEST_F(ScopedPrinterTest, PrintBinary) { 843 auto PrintFunc = [](ScopedPrinter &W) { 844 std::vector<uint8_t> IntArray = {70, 111, 111, 66, 97, 114}; 845 std::vector<char> CharArray = {'F', 'o', 'o', 'B', 'a', 'r'}; 846 std::vector<uint8_t> InvalidChars = {255, 255}; 847 W.printBinary("Binary1", "FooBar", IntArray); 848 W.printBinary("Binary2", "FooBar", CharArray); 849 W.printBinary("Binary3", IntArray); 850 W.printBinary("Binary4", CharArray); 851 W.printBinary("Binary5", StringRef("FooBar")); 852 W.printBinary("Binary6", StringRef("Multiple Line FooBar")); 853 W.printBinaryBlock("Binary7", IntArray, 20); 854 W.printBinaryBlock("Binary8", IntArray); 855 W.printBinaryBlock("Binary9", "FooBar"); 856 W.printBinaryBlock("Binary10", "Multiple Line FooBar"); 857 W.printBinaryBlock("Binary11", InvalidChars); 858 }; 859 860 const char *ExpectedOut = R"(Binary1: FooBar (46 6F 6F 42 61 72) 861 Binary2: FooBar (46 6F 6F 42 61 72) 862 Binary3: (46 6F 6F 42 61 72) 863 Binary4: (46 6F 6F 42 61 72) 864 Binary5: (46 6F 6F 42 61 72) 865 Binary6 ( 866 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo| 867 0010: 6F426172 |oBar| 868 ) 869 Binary7 ( 870 0014: 466F6F42 6172 |FooBar| 871 ) 872 Binary8 ( 873 0000: 466F6F42 6172 |FooBar| 874 ) 875 Binary9 ( 876 0000: 466F6F42 6172 |FooBar| 877 ) 878 Binary10 ( 879 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo| 880 0010: 6F426172 |oBar| 881 ) 882 Binary11 ( 883 0000: FFFF |..| 884 ) 885 )"; 886 887 const char *JSONExpectedOut = R"({ 888 "Binary1": { 889 "Value": "FooBar", 890 "Offset": 0, 891 "Bytes": [ 892 70, 893 111, 894 111, 895 66, 896 97, 897 114 898 ] 899 }, 900 "Binary2": { 901 "Value": "FooBar", 902 "Offset": 0, 903 "Bytes": [ 904 70, 905 111, 906 111, 907 66, 908 97, 909 114 910 ] 911 }, 912 "Binary3": { 913 "Offset": 0, 914 "Bytes": [ 915 70, 916 111, 917 111, 918 66, 919 97, 920 114 921 ] 922 }, 923 "Binary4": { 924 "Offset": 0, 925 "Bytes": [ 926 70, 927 111, 928 111, 929 66, 930 97, 931 114 932 ] 933 }, 934 "Binary5": { 935 "Offset": 0, 936 "Bytes": [ 937 70, 938 111, 939 111, 940 66, 941 97, 942 114 943 ] 944 }, 945 "Binary6": { 946 "Offset": 0, 947 "Bytes": [ 948 77, 949 117, 950 108, 951 116, 952 105, 953 112, 954 108, 955 101, 956 32, 957 76, 958 105, 959 110, 960 101, 961 32, 962 70, 963 111, 964 111, 965 66, 966 97, 967 114 968 ] 969 }, 970 "Binary7": { 971 "Offset": 20, 972 "Bytes": [ 973 70, 974 111, 975 111, 976 66, 977 97, 978 114 979 ] 980 }, 981 "Binary8": { 982 "Offset": 0, 983 "Bytes": [ 984 70, 985 111, 986 111, 987 66, 988 97, 989 114 990 ] 991 }, 992 "Binary9": { 993 "Offset": 0, 994 "Bytes": [ 995 70, 996 111, 997 111, 998 66, 999 97, 1000 114 1001 ] 1002 }, 1003 "Binary10": { 1004 "Offset": 0, 1005 "Bytes": [ 1006 77, 1007 117, 1008 108, 1009 116, 1010 105, 1011 112, 1012 108, 1013 101, 1014 32, 1015 76, 1016 105, 1017 110, 1018 101, 1019 32, 1020 70, 1021 111, 1022 111, 1023 66, 1024 97, 1025 114 1026 ] 1027 }, 1028 "Binary11": { 1029 "Offset": 0, 1030 "Bytes": [ 1031 255, 1032 255 1033 ] 1034 } 1035 })"; 1036 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1037 } 1038 1039 TEST_F(ScopedPrinterTest, PrintObject) { 1040 auto PrintFunc = [](ScopedPrinter &W) { W.printObject("Object", "Value"); }; 1041 1042 const char *ExpectedOut = R"(Object: Value 1043 )"; 1044 1045 const char *JSONExpectedOut = R"({ 1046 "Object": "Value" 1047 })"; 1048 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1049 } 1050 1051 TEST_F(ScopedPrinterTest, StartLine) { 1052 auto PrintFunc = [](ScopedPrinter &W) { 1053 W.startLine() << "|"; 1054 W.indent(2); 1055 W.startLine() << "|"; 1056 W.unindent(); 1057 W.startLine() << "|"; 1058 }; 1059 1060 const char *ExpectedOut = "| | |"; 1061 verifyScopedPrinter(ExpectedOut, PrintFunc); 1062 } 1063 1064 TEST_F(ScopedPrinterTest, GetOStream) { 1065 auto PrintFunc = [](ScopedPrinter &W) { W.getOStream() << "Test"; }; 1066 1067 const char *ExpectedOut = "Test"; 1068 verifyScopedPrinter(ExpectedOut, PrintFunc); 1069 } 1070 1071 TEST_F(ScopedPrinterTest, PrintScope) { 1072 auto PrintFunc = [](ScopedPrinter &W) { 1073 { 1074 DictScope O(W, "Object"); 1075 { DictScope OO(W, "ObjectInObject"); } 1076 { ListScope LO(W, "ListInObject"); } 1077 } 1078 { 1079 ListScope L(W, "List"); 1080 { DictScope OL(W, "ObjectInList"); } 1081 { ListScope LL(W, "ListInList"); } 1082 } 1083 }; 1084 1085 const char *ExpectedOut = R"(Object { 1086 ObjectInObject { 1087 } 1088 ListInObject [ 1089 ] 1090 } 1091 List [ 1092 ObjectInList { 1093 } 1094 ListInList [ 1095 ] 1096 ] 1097 )"; 1098 1099 const char *JSONExpectedOut = R"({ 1100 "Object": { 1101 "ObjectInObject": {}, 1102 "ListInObject": [] 1103 }, 1104 "List": [ 1105 { 1106 "ObjectInList": {} 1107 }, 1108 { 1109 "ListInList": [] 1110 } 1111 ] 1112 })"; 1113 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1114 } 1115