1d25a6503SJayson Yan //===- llvm/unittest/Support/ScopedPrinterTest.cpp - ScopedPrinter tests --===// 2d25a6503SJayson Yan // 3d25a6503SJayson Yan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4d25a6503SJayson Yan // See https://llvm.org/LICENSE.txt for license information. 5d25a6503SJayson Yan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d25a6503SJayson Yan // 7d25a6503SJayson Yan //===----------------------------------------------------------------------===// 8d25a6503SJayson Yan 9d25a6503SJayson Yan #include "llvm/Support/ScopedPrinter.h" 10d25a6503SJayson Yan #include "llvm/ADT/APSInt.h" 11c819257bSPaul Kirth #include "llvm/Support/Format.h" 12d25a6503SJayson Yan #include "gtest/gtest.h" 1389359df8SPaul Kirth #include <cmath> 14d25a6503SJayson Yan #include <vector> 15d25a6503SJayson Yan 16d25a6503SJayson Yan using namespace llvm; 17d25a6503SJayson Yan 18928d1725SJayson Yan TEST(JSONScopedPrinterTest, PrettyPrintCtor) { 19928d1725SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 20928d1725SJayson Yan DictScope D(W); 21928d1725SJayson Yan W.printString("Key", "Value"); 22928d1725SJayson Yan }; 23928d1725SJayson Yan std::string StreamBuffer; 24928d1725SJayson Yan raw_string_ostream OS(StreamBuffer); 25928d1725SJayson Yan JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true); 26928d1725SJayson Yan JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false); 27928d1725SJayson Yan 28928d1725SJayson Yan const char *PrettyPrintOut = R"({ 29928d1725SJayson Yan "Key": "Value" 30928d1725SJayson Yan })"; 31928d1725SJayson Yan const char *NoPrettyPrintOut = R"({"Key":"Value"})"; 32928d1725SJayson Yan PrintFunc(PrettyPrintWriter); 33*77bab2a6SJOE1994 EXPECT_EQ(PrettyPrintOut, StreamBuffer); 34928d1725SJayson Yan StreamBuffer.clear(); 35928d1725SJayson Yan PrintFunc(NoPrettyPrintWriter); 36*77bab2a6SJOE1994 EXPECT_EQ(NoPrettyPrintOut, StreamBuffer); 37928d1725SJayson Yan } 38928d1725SJayson Yan 39928d1725SJayson Yan TEST(JSONScopedPrinterTest, DelimitedScopeCtor) { 40928d1725SJayson Yan std::string StreamBuffer; 41928d1725SJayson Yan raw_string_ostream OS(StreamBuffer); 42928d1725SJayson Yan { 43928d1725SJayson Yan JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false, 44928d1725SJayson Yan std::make_unique<DictScope>()); 45928d1725SJayson Yan DictScopeWriter.printString("Label", "DictScope"); 46928d1725SJayson Yan } 47*77bab2a6SJOE1994 EXPECT_EQ(R"({"Label":"DictScope"})", StreamBuffer); 48928d1725SJayson Yan StreamBuffer.clear(); 49928d1725SJayson Yan { 50928d1725SJayson Yan JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false, 51928d1725SJayson Yan std::make_unique<ListScope>()); 52928d1725SJayson Yan ListScopeWriter.printString("ListScope"); 53928d1725SJayson Yan } 54*77bab2a6SJOE1994 EXPECT_EQ(R"(["ListScope"])", StreamBuffer); 55928d1725SJayson Yan StreamBuffer.clear(); 56928d1725SJayson Yan { 57928d1725SJayson Yan JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false); 58928d1725SJayson Yan NoScopeWriter.printString("NoScope"); 59928d1725SJayson Yan } 60*77bab2a6SJOE1994 EXPECT_EQ(R"("NoScope")", StreamBuffer); 61928d1725SJayson Yan } 62928d1725SJayson Yan 63d25a6503SJayson Yan class ScopedPrinterTest : public ::testing::Test { 64d25a6503SJayson Yan protected: 65d25a6503SJayson Yan std::string StreamBuffer; 66d25a6503SJayson Yan raw_string_ostream OS; 67d25a6503SJayson Yan ScopedPrinter Writer; 68928d1725SJayson Yan JSONScopedPrinter JSONWriter; 69d25a6503SJayson Yan 70928d1725SJayson Yan bool HasPrintedToJSON; 71928d1725SJayson Yan 72928d1725SJayson Yan ScopedPrinterTest() 73928d1725SJayson Yan : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true), 74928d1725SJayson Yan HasPrintedToJSON(false) {} 75d25a6503SJayson Yan 76d25a6503SJayson Yan using PrintFunc = function_ref<void(ScopedPrinter &)>; 77d25a6503SJayson Yan 78d25a6503SJayson Yan void verifyScopedPrinter(StringRef Expected, PrintFunc Func) { 79d25a6503SJayson Yan Func(Writer); 80d25a6503SJayson Yan Writer.flush(); 81*77bab2a6SJOE1994 EXPECT_EQ(Expected.str(), StreamBuffer); 82928d1725SJayson Yan StreamBuffer.clear(); 83928d1725SJayson Yan } 84928d1725SJayson Yan 85928d1725SJayson Yan void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) { 86928d1725SJayson Yan { 87928d1725SJayson Yan DictScope D(JSONWriter); 88928d1725SJayson Yan Func(JSONWriter); 89928d1725SJayson Yan } 90928d1725SJayson Yan JSONWriter.flush(); 91*77bab2a6SJOE1994 EXPECT_EQ(Expected.str(), StreamBuffer); 92928d1725SJayson Yan StreamBuffer.clear(); 93928d1725SJayson Yan HasPrintedToJSON = true; 94928d1725SJayson Yan } 95928d1725SJayson Yan 96928d1725SJayson Yan void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut, 97928d1725SJayson Yan PrintFunc Func) { 98928d1725SJayson Yan verifyScopedPrinter(ExpectedOut, Func); 99928d1725SJayson Yan verifyJSONScopedPrinter(JSONExpectedOut, Func); 100928d1725SJayson Yan } 101928d1725SJayson Yan 102928d1725SJayson Yan void TearDown() { 103928d1725SJayson Yan // JSONScopedPrinter fails an assert if nothing's been printed. 104928d1725SJayson Yan if (!HasPrintedToJSON) 105928d1725SJayson Yan JSONWriter.printString(""); 106d25a6503SJayson Yan } 107d25a6503SJayson Yan }; 108d25a6503SJayson Yan 109928d1725SJayson Yan TEST_F(ScopedPrinterTest, GetKind) { 110928d1725SJayson Yan EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind()); 111928d1725SJayson Yan EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind()); 112928d1725SJayson Yan } 113928d1725SJayson Yan 114928d1725SJayson Yan TEST_F(ScopedPrinterTest, ClassOf) { 115928d1725SJayson Yan EXPECT_TRUE(ScopedPrinter::classof(&Writer)); 116928d1725SJayson Yan EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter)); 117928d1725SJayson Yan EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter)); 118928d1725SJayson Yan EXPECT_FALSE(JSONScopedPrinter::classof(&Writer)); 119928d1725SJayson Yan } 120928d1725SJayson Yan 121d25a6503SJayson Yan TEST_F(ScopedPrinterTest, Indent) { 122d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 123d25a6503SJayson Yan W.printString("|"); 124d25a6503SJayson Yan W.indent(); 125d25a6503SJayson Yan W.printString("|"); 126d25a6503SJayson Yan W.indent(2); 127d25a6503SJayson Yan W.printString("|"); 128d25a6503SJayson Yan }; 129d25a6503SJayson Yan 130d25a6503SJayson Yan const char *ExpectedOut = R"(| 131d25a6503SJayson Yan | 132d25a6503SJayson Yan | 133d25a6503SJayson Yan )"; 134d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 135d25a6503SJayson Yan } 136d25a6503SJayson Yan 137d25a6503SJayson Yan TEST_F(ScopedPrinterTest, Unindent) { 138d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 139d25a6503SJayson Yan W.indent(3); 140d25a6503SJayson Yan W.printString("|"); 141d25a6503SJayson Yan W.unindent(2); 142d25a6503SJayson Yan W.printString("|"); 143d25a6503SJayson Yan W.unindent(); 144d25a6503SJayson Yan W.printString("|"); 145d25a6503SJayson Yan W.unindent(); 146d25a6503SJayson Yan W.printString("|"); 147d25a6503SJayson Yan }; 148d25a6503SJayson Yan 149d25a6503SJayson Yan const char *ExpectedOut = R"( | 150d25a6503SJayson Yan | 151d25a6503SJayson Yan | 152d25a6503SJayson Yan | 153d25a6503SJayson Yan )"; 154d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 155d25a6503SJayson Yan } 156d25a6503SJayson Yan 157d25a6503SJayson Yan TEST_F(ScopedPrinterTest, ResetIndent) { 158d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 159d25a6503SJayson Yan W.indent(4); 160d25a6503SJayson Yan W.printString("|"); 161d25a6503SJayson Yan W.resetIndent(); 162d25a6503SJayson Yan W.printString("|"); 163d25a6503SJayson Yan }; 164d25a6503SJayson Yan 165d25a6503SJayson Yan const char *ExpectedOut = R"( | 166d25a6503SJayson Yan | 167d25a6503SJayson Yan )"; 168d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 169d25a6503SJayson Yan } 170d25a6503SJayson Yan 171d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintIndent) { 172d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 173d25a6503SJayson Yan W.printIndent(); 174d25a6503SJayson Yan W.printString("|"); 175d25a6503SJayson Yan W.indent(); 176d25a6503SJayson Yan W.printIndent(); 177d25a6503SJayson Yan W.printString("|"); 178d25a6503SJayson Yan }; 179d25a6503SJayson Yan 180d25a6503SJayson Yan const char *ExpectedOut = R"(| 181d25a6503SJayson Yan | 182d25a6503SJayson Yan )"; 183d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 184d25a6503SJayson Yan } 185d25a6503SJayson Yan 186d25a6503SJayson Yan TEST_F(ScopedPrinterTest, GetIndentLevel) { 187d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 0); 188d25a6503SJayson Yan Writer.indent(); 189d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 1); 190d25a6503SJayson Yan Writer.indent(); 191d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 2); 192d25a6503SJayson Yan Writer.unindent(); 193d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 1); 194d25a6503SJayson Yan Writer.indent(); 195d25a6503SJayson Yan Writer.resetIndent(); 196d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 0); 197d25a6503SJayson Yan Writer.unindent(); 198d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 0); 199d25a6503SJayson Yan Writer.indent(); 200d25a6503SJayson Yan EXPECT_EQ(Writer.getIndentLevel(), 1); 201d25a6503SJayson Yan } 202d25a6503SJayson Yan 203d25a6503SJayson Yan TEST_F(ScopedPrinterTest, SetPrefix) { 204d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 205d25a6503SJayson Yan W.setPrefix("Prefix1"); 206d25a6503SJayson Yan W.indent(); 207d25a6503SJayson Yan W.printIndent(); 208d25a6503SJayson Yan W.printString("|"); 209d25a6503SJayson Yan W.unindent(); 210d25a6503SJayson Yan W.printIndent(); 211d25a6503SJayson Yan W.printString("|"); 212d25a6503SJayson Yan W.setPrefix("Prefix2"); 213d25a6503SJayson Yan W.printIndent(); 214d25a6503SJayson Yan W.printString("|"); 215d25a6503SJayson Yan }; 216d25a6503SJayson Yan 217d25a6503SJayson Yan const char *ExpectedOut = R"(Prefix1 Prefix1 | 218d25a6503SJayson Yan Prefix1Prefix1| 219d25a6503SJayson Yan Prefix2Prefix2| 220d25a6503SJayson Yan )"; 221d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 222d25a6503SJayson Yan } 223d25a6503SJayson Yan 224d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintEnum) { 225d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 226d25a6503SJayson Yan const EnumEntry<int> EnumList[] = {{"Name1", "AltName1", 1}, 227d25a6503SJayson Yan {"Name2", "AltName2", 2}, 228d25a6503SJayson Yan {"Name3", "AltName3", 3}, 229d25a6503SJayson Yan {"Name4", "AltName4", 2}}; 230d25a6503SJayson Yan EnumEntry<int> OtherEnum{"Name5", "AltName5", 5}; 23138818b60Sserge-sans-paille W.printEnum("Exists", EnumList[1].Value, ArrayRef(EnumList)); 23238818b60Sserge-sans-paille W.printEnum("DoesNotExist", OtherEnum.Value, ArrayRef(EnumList)); 233d25a6503SJayson Yan }; 234d25a6503SJayson Yan 235d25a6503SJayson Yan const char *ExpectedOut = R"(Exists: Name2 (0x2) 236d25a6503SJayson Yan DoesNotExist: 0x5 237d25a6503SJayson Yan )"; 238928d1725SJayson Yan 239928d1725SJayson Yan const char *JSONExpectedOut = R"({ 240928d1725SJayson Yan "Exists": { 24193c1a5f3SPaul Kirth "Name": "Name2", 24293c1a5f3SPaul Kirth "Value": 2 243928d1725SJayson Yan }, 244928d1725SJayson Yan "DoesNotExist": 5 245928d1725SJayson Yan })"; 246928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 247d25a6503SJayson Yan } 248d25a6503SJayson Yan 249d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintFlag) { 250d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 251d25a6503SJayson Yan const EnumEntry<uint16_t> SingleBitFlags[] = { 252d25a6503SJayson Yan {"Name0", "AltName0", 0}, 253d25a6503SJayson Yan {"Name1", "AltName1", 1}, 254d25a6503SJayson Yan {"Name2", "AltName2", 1 << 1}, 255d25a6503SJayson Yan {"Name3", "AltName3", 1 << 2}}; 256d25a6503SJayson Yan const EnumEntry<uint16_t> UnsortedFlags[] = { 257d25a6503SJayson Yan {"C", "c", 1}, {"B", "b", 1 << 1}, {"A", "a", 1 << 2}}; 258d25a6503SJayson Yan const EnumEntry<uint16_t> EnumFlags[] = { 259d25a6503SJayson Yan {"FirstByte1", "First1", 0x1u}, {"FirstByte2", "First2", 0x2u}, 260d25a6503SJayson Yan {"FirstByte3", "First3", 0x3u}, {"SecondByte1", "Second1", 0x10u}, 261d25a6503SJayson Yan {"SecondByte2", "Second2", 0x20u}, {"SecondByte3", "Second3", 0x30u}, 262d25a6503SJayson Yan {"ThirdByte1", "Third1", 0x100u}, {"ThirdByte2", "Third2", 0x200u}, 263d25a6503SJayson Yan {"ThirdByte3", "Third3", 0x300u}}; 26438818b60Sserge-sans-paille W.printFlags("ZeroFlag", 0, ArrayRef(SingleBitFlags)); 26538818b60Sserge-sans-paille W.printFlags("NoFlag", 1 << 3, ArrayRef(SingleBitFlags)); 26638818b60Sserge-sans-paille W.printFlags("Flag1", SingleBitFlags[1].Value, ArrayRef(SingleBitFlags)); 26738818b60Sserge-sans-paille W.printFlags("Flag1&3", (1 << 2) + 1, ArrayRef(SingleBitFlags)); 268d25a6503SJayson Yan 269d25a6503SJayson Yan W.printFlags("ZeroFlagRaw", 0); 270d25a6503SJayson Yan W.printFlags("NoFlagRaw", 1 << 3); 271d25a6503SJayson Yan W.printFlags("Flag1Raw", SingleBitFlags[1].Value); 272d25a6503SJayson Yan W.printFlags("Flag1&3Raw", (1 << 2) + 1); 273d25a6503SJayson Yan 274d25a6503SJayson Yan W.printFlags("FlagSorted", (1 << 2) + (1 << 1) + 1, 27538818b60Sserge-sans-paille ArrayRef(UnsortedFlags)); 276d25a6503SJayson Yan 277d25a6503SJayson Yan uint16_t NoBitMask = 0; 278d25a6503SJayson Yan uint16_t FirstByteMask = 0xFu; 279d25a6503SJayson Yan uint16_t SecondByteMask = 0xF0u; 280d25a6503SJayson Yan uint16_t ThirdByteMask = 0xF00u; 28138818b60Sserge-sans-paille W.printFlags("NoBitMask", 0xFFFu, ArrayRef(EnumFlags), NoBitMask); 28238818b60Sserge-sans-paille W.printFlags("FirstByteMask", 0x3u, ArrayRef(EnumFlags), FirstByteMask); 28338818b60Sserge-sans-paille W.printFlags("SecondByteMask", 0x30u, ArrayRef(EnumFlags), SecondByteMask); 28438818b60Sserge-sans-paille W.printFlags("ValueOutsideMask", 0x1u, ArrayRef(EnumFlags), SecondByteMask); 28538818b60Sserge-sans-paille W.printFlags("FirstSecondByteMask", 0xFFu, ArrayRef(EnumFlags), 286d25a6503SJayson Yan FirstByteMask, SecondByteMask); 28738818b60Sserge-sans-paille W.printFlags("FirstSecondThirdByteMask", 0x333u, ArrayRef(EnumFlags), 288d25a6503SJayson Yan FirstByteMask, SecondByteMask, ThirdByteMask); 289d25a6503SJayson Yan }; 290d25a6503SJayson Yan 291d25a6503SJayson Yan const char *ExpectedOut = R"(ZeroFlag [ (0x0) 292d25a6503SJayson Yan ] 293d25a6503SJayson Yan NoFlag [ (0x8) 294d25a6503SJayson Yan ] 295d25a6503SJayson Yan Flag1 [ (0x1) 296d25a6503SJayson Yan Name1 (0x1) 297d25a6503SJayson Yan ] 298d25a6503SJayson Yan Flag1&3 [ (0x5) 299d25a6503SJayson Yan Name1 (0x1) 300d25a6503SJayson Yan Name3 (0x4) 301d25a6503SJayson Yan ] 302d25a6503SJayson Yan ZeroFlagRaw [ (0x0) 303d25a6503SJayson Yan ] 304d25a6503SJayson Yan NoFlagRaw [ (0x8) 305d25a6503SJayson Yan 0x8 306d25a6503SJayson Yan ] 307d25a6503SJayson Yan Flag1Raw [ (0x1) 308d25a6503SJayson Yan 0x1 309d25a6503SJayson Yan ] 310d25a6503SJayson Yan Flag1&3Raw [ (0x5) 311d25a6503SJayson Yan 0x1 312d25a6503SJayson Yan 0x4 313d25a6503SJayson Yan ] 314d25a6503SJayson Yan FlagSorted [ (0x7) 315d25a6503SJayson Yan A (0x4) 316d25a6503SJayson Yan B (0x2) 317d25a6503SJayson Yan C (0x1) 318d25a6503SJayson Yan ] 319d25a6503SJayson Yan NoBitMask [ (0xFFF) 320d25a6503SJayson Yan FirstByte1 (0x1) 321d25a6503SJayson Yan FirstByte2 (0x2) 322d25a6503SJayson Yan FirstByte3 (0x3) 323d25a6503SJayson Yan SecondByte1 (0x10) 324d25a6503SJayson Yan SecondByte2 (0x20) 325d25a6503SJayson Yan SecondByte3 (0x30) 326d25a6503SJayson Yan ThirdByte1 (0x100) 327d25a6503SJayson Yan ThirdByte2 (0x200) 328d25a6503SJayson Yan ThirdByte3 (0x300) 329d25a6503SJayson Yan ] 330d25a6503SJayson Yan FirstByteMask [ (0x3) 331d25a6503SJayson Yan FirstByte3 (0x3) 332d25a6503SJayson Yan ] 333d25a6503SJayson Yan SecondByteMask [ (0x30) 334d25a6503SJayson Yan SecondByte3 (0x30) 335d25a6503SJayson Yan ] 336d25a6503SJayson Yan ValueOutsideMask [ (0x1) 337d25a6503SJayson Yan FirstByte1 (0x1) 338d25a6503SJayson Yan ] 339d25a6503SJayson Yan FirstSecondByteMask [ (0xFF) 340d25a6503SJayson Yan ] 341d25a6503SJayson Yan FirstSecondThirdByteMask [ (0x333) 342d25a6503SJayson Yan FirstByte3 (0x3) 343d25a6503SJayson Yan SecondByte3 (0x30) 344d25a6503SJayson Yan ThirdByte3 (0x300) 345d25a6503SJayson Yan ] 346d25a6503SJayson Yan )"; 347928d1725SJayson Yan 348928d1725SJayson Yan const char *JSONExpectedOut = R"({ 349928d1725SJayson Yan "ZeroFlag": { 35093c1a5f3SPaul Kirth "Value": 0, 351928d1725SJayson Yan "Flags": [] 352928d1725SJayson Yan }, 353928d1725SJayson Yan "NoFlag": { 35493c1a5f3SPaul Kirth "Value": 8, 355928d1725SJayson Yan "Flags": [] 356928d1725SJayson Yan }, 357928d1725SJayson Yan "Flag1": { 35893c1a5f3SPaul Kirth "Value": 1, 359928d1725SJayson Yan "Flags": [ 360928d1725SJayson Yan { 361928d1725SJayson Yan "Name": "Name1", 362928d1725SJayson Yan "Value": 1 363928d1725SJayson Yan } 364928d1725SJayson Yan ] 365928d1725SJayson Yan }, 366928d1725SJayson Yan "Flag1&3": { 36793c1a5f3SPaul Kirth "Value": 5, 368928d1725SJayson Yan "Flags": [ 369928d1725SJayson Yan { 370928d1725SJayson Yan "Name": "Name1", 371928d1725SJayson Yan "Value": 1 372928d1725SJayson Yan }, 373928d1725SJayson Yan { 374928d1725SJayson Yan "Name": "Name3", 375928d1725SJayson Yan "Value": 4 376928d1725SJayson Yan } 377928d1725SJayson Yan ] 378928d1725SJayson Yan }, 379928d1725SJayson Yan "ZeroFlagRaw": { 38093c1a5f3SPaul Kirth "Value": 0, 381928d1725SJayson Yan "Flags": [] 382928d1725SJayson Yan }, 383928d1725SJayson Yan "NoFlagRaw": { 38493c1a5f3SPaul Kirth "Value": 8, 385928d1725SJayson Yan "Flags": [ 386928d1725SJayson Yan 8 387928d1725SJayson Yan ] 388928d1725SJayson Yan }, 389928d1725SJayson Yan "Flag1Raw": { 39093c1a5f3SPaul Kirth "Value": 1, 391928d1725SJayson Yan "Flags": [ 392928d1725SJayson Yan 1 393928d1725SJayson Yan ] 394928d1725SJayson Yan }, 395928d1725SJayson Yan "Flag1&3Raw": { 39693c1a5f3SPaul Kirth "Value": 5, 397928d1725SJayson Yan "Flags": [ 398928d1725SJayson Yan 1, 399928d1725SJayson Yan 4 400928d1725SJayson Yan ] 401928d1725SJayson Yan }, 402928d1725SJayson Yan "FlagSorted": { 40393c1a5f3SPaul Kirth "Value": 7, 404928d1725SJayson Yan "Flags": [ 405928d1725SJayson Yan { 406928d1725SJayson Yan "Name": "A", 407928d1725SJayson Yan "Value": 4 408928d1725SJayson Yan }, 409928d1725SJayson Yan { 410928d1725SJayson Yan "Name": "B", 411928d1725SJayson Yan "Value": 2 412928d1725SJayson Yan }, 413928d1725SJayson Yan { 414928d1725SJayson Yan "Name": "C", 415928d1725SJayson Yan "Value": 1 416928d1725SJayson Yan } 417928d1725SJayson Yan ] 418928d1725SJayson Yan }, 419928d1725SJayson Yan "NoBitMask": { 42093c1a5f3SPaul Kirth "Value": 4095, 421928d1725SJayson Yan "Flags": [ 422928d1725SJayson Yan { 423928d1725SJayson Yan "Name": "FirstByte1", 424928d1725SJayson Yan "Value": 1 425928d1725SJayson Yan }, 426928d1725SJayson Yan { 427928d1725SJayson Yan "Name": "FirstByte2", 428928d1725SJayson Yan "Value": 2 429928d1725SJayson Yan }, 430928d1725SJayson Yan { 431928d1725SJayson Yan "Name": "FirstByte3", 432928d1725SJayson Yan "Value": 3 433928d1725SJayson Yan }, 434928d1725SJayson Yan { 435928d1725SJayson Yan "Name": "SecondByte1", 436928d1725SJayson Yan "Value": 16 437928d1725SJayson Yan }, 438928d1725SJayson Yan { 439928d1725SJayson Yan "Name": "SecondByte2", 440928d1725SJayson Yan "Value": 32 441928d1725SJayson Yan }, 442928d1725SJayson Yan { 443928d1725SJayson Yan "Name": "SecondByte3", 444928d1725SJayson Yan "Value": 48 445928d1725SJayson Yan }, 446928d1725SJayson Yan { 447928d1725SJayson Yan "Name": "ThirdByte1", 448928d1725SJayson Yan "Value": 256 449928d1725SJayson Yan }, 450928d1725SJayson Yan { 451928d1725SJayson Yan "Name": "ThirdByte2", 452928d1725SJayson Yan "Value": 512 453928d1725SJayson Yan }, 454928d1725SJayson Yan { 455928d1725SJayson Yan "Name": "ThirdByte3", 456928d1725SJayson Yan "Value": 768 457928d1725SJayson Yan } 458928d1725SJayson Yan ] 459928d1725SJayson Yan }, 460928d1725SJayson Yan "FirstByteMask": { 46193c1a5f3SPaul Kirth "Value": 3, 462928d1725SJayson Yan "Flags": [ 463928d1725SJayson Yan { 464928d1725SJayson Yan "Name": "FirstByte3", 465928d1725SJayson Yan "Value": 3 466928d1725SJayson Yan } 467928d1725SJayson Yan ] 468928d1725SJayson Yan }, 469928d1725SJayson Yan "SecondByteMask": { 47093c1a5f3SPaul Kirth "Value": 48, 471928d1725SJayson Yan "Flags": [ 472928d1725SJayson Yan { 473928d1725SJayson Yan "Name": "SecondByte3", 474928d1725SJayson Yan "Value": 48 475928d1725SJayson Yan } 476928d1725SJayson Yan ] 477928d1725SJayson Yan }, 478928d1725SJayson Yan "ValueOutsideMask": { 47993c1a5f3SPaul Kirth "Value": 1, 480928d1725SJayson Yan "Flags": [ 481928d1725SJayson Yan { 482928d1725SJayson Yan "Name": "FirstByte1", 483928d1725SJayson Yan "Value": 1 484928d1725SJayson Yan } 485928d1725SJayson Yan ] 486928d1725SJayson Yan }, 487928d1725SJayson Yan "FirstSecondByteMask": { 48893c1a5f3SPaul Kirth "Value": 255, 489928d1725SJayson Yan "Flags": [] 490928d1725SJayson Yan }, 491928d1725SJayson Yan "FirstSecondThirdByteMask": { 49293c1a5f3SPaul Kirth "Value": 819, 493928d1725SJayson Yan "Flags": [ 494928d1725SJayson Yan { 495928d1725SJayson Yan "Name": "FirstByte3", 496928d1725SJayson Yan "Value": 3 497928d1725SJayson Yan }, 498928d1725SJayson Yan { 499928d1725SJayson Yan "Name": "SecondByte3", 500928d1725SJayson Yan "Value": 48 501928d1725SJayson Yan }, 502928d1725SJayson Yan { 503928d1725SJayson Yan "Name": "ThirdByte3", 504928d1725SJayson Yan "Value": 768 505928d1725SJayson Yan } 506928d1725SJayson Yan ] 507928d1725SJayson Yan } 508928d1725SJayson Yan })"; 509928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 510d25a6503SJayson Yan } 511d25a6503SJayson Yan 512f331e13dSPaul Kirth // Format floats using the same format string as PrintNumber, so we can check 513f331e13dSPaul Kirth // the output on all platforms. 514f331e13dSPaul Kirth template <typename T, 515f331e13dSPaul Kirth std::enable_if_t<std::is_floating_point_v<T>, bool> = true> 516f331e13dSPaul Kirth std::string formatFloatString(T Val) { 517f331e13dSPaul Kirth std::string Ret; 518f331e13dSPaul Kirth raw_string_ostream OS(Ret); 519f331e13dSPaul Kirth OS << format("%5.1f", Val); 520f331e13dSPaul Kirth return Ret; 521f331e13dSPaul Kirth } 522f331e13dSPaul Kirth 523f331e13dSPaul Kirth // Format floats using the same format string used in JSON, so we can check the 524f331e13dSPaul Kirth // output on all platforms. 525f331e13dSPaul Kirth template <typename T, 526f331e13dSPaul Kirth std::enable_if_t<std::is_floating_point_v<T>, bool> = true> 527f331e13dSPaul Kirth std::string formatJsonFloatString(T Val) { 528f331e13dSPaul Kirth std::string Ret; 529f331e13dSPaul Kirth raw_string_ostream OS(Ret); 530f331e13dSPaul Kirth OS << format("%.*g", std::numeric_limits<double>::max_digits10, Val); 531f331e13dSPaul Kirth return Ret; 532f331e13dSPaul Kirth } 533f331e13dSPaul Kirth 534d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintNumber) { 5358088f5bfSPaul Kirth constexpr float MaxFloat = std::numeric_limits<float>::max(); 5368088f5bfSPaul Kirth constexpr float MinFloat = std::numeric_limits<float>::min(); 537f331e13dSPaul Kirth constexpr float InfFloat = std::numeric_limits<float>::infinity(); 538f331e13dSPaul Kirth const float NaNFloat = std::nanf("1"); 5398088f5bfSPaul Kirth constexpr double MaxDouble = std::numeric_limits<double>::max(); 5408088f5bfSPaul Kirth constexpr double MinDouble = std::numeric_limits<double>::min(); 541f331e13dSPaul Kirth constexpr double InfDouble = std::numeric_limits<double>::infinity(); 542f331e13dSPaul Kirth const double NaNDouble = std::nan("1"); 5438088f5bfSPaul Kirth 5448088f5bfSPaul Kirth auto PrintFunc = [&](ScopedPrinter &W) { 545d25a6503SJayson Yan uint64_t Unsigned64Max = std::numeric_limits<uint64_t>::max(); 546d25a6503SJayson Yan uint64_t Unsigned64Min = std::numeric_limits<uint64_t>::min(); 547d25a6503SJayson Yan W.printNumber("uint64_t-max", Unsigned64Max); 548d25a6503SJayson Yan W.printNumber("uint64_t-min", Unsigned64Min); 549d25a6503SJayson Yan 550d25a6503SJayson Yan uint32_t Unsigned32Max = std::numeric_limits<uint32_t>::max(); 551d25a6503SJayson Yan uint32_t Unsigned32Min = std::numeric_limits<uint32_t>::min(); 552d25a6503SJayson Yan W.printNumber("uint32_t-max", Unsigned32Max); 553d25a6503SJayson Yan W.printNumber("uint32_t-min", Unsigned32Min); 554d25a6503SJayson Yan 555d25a6503SJayson Yan uint16_t Unsigned16Max = std::numeric_limits<uint16_t>::max(); 556d25a6503SJayson Yan uint16_t Unsigned16Min = std::numeric_limits<uint16_t>::min(); 557d25a6503SJayson Yan W.printNumber("uint16_t-max", Unsigned16Max); 558d25a6503SJayson Yan W.printNumber("uint16_t-min", Unsigned16Min); 559d25a6503SJayson Yan 560d25a6503SJayson Yan uint8_t Unsigned8Max = std::numeric_limits<uint8_t>::max(); 561d25a6503SJayson Yan uint8_t Unsigned8Min = std::numeric_limits<uint8_t>::min(); 562d25a6503SJayson Yan W.printNumber("uint8_t-max", Unsigned8Max); 563d25a6503SJayson Yan W.printNumber("uint8_t-min", Unsigned8Min); 564d25a6503SJayson Yan 565d25a6503SJayson Yan int64_t Signed64Max = std::numeric_limits<int64_t>::max(); 566d25a6503SJayson Yan int64_t Signed64Min = std::numeric_limits<int64_t>::min(); 567d25a6503SJayson Yan W.printNumber("int64_t-max", Signed64Max); 568d25a6503SJayson Yan W.printNumber("int64_t-min", Signed64Min); 569d25a6503SJayson Yan 570d25a6503SJayson Yan int32_t Signed32Max = std::numeric_limits<int32_t>::max(); 571d25a6503SJayson Yan int32_t Signed32Min = std::numeric_limits<int32_t>::min(); 572d25a6503SJayson Yan W.printNumber("int32_t-max", Signed32Max); 573d25a6503SJayson Yan W.printNumber("int32_t-min", Signed32Min); 574d25a6503SJayson Yan 575d25a6503SJayson Yan int16_t Signed16Max = std::numeric_limits<int16_t>::max(); 576d25a6503SJayson Yan int16_t Signed16Min = std::numeric_limits<int16_t>::min(); 577d25a6503SJayson Yan W.printNumber("int16_t-max", Signed16Max); 578d25a6503SJayson Yan W.printNumber("int16_t-min", Signed16Min); 579d25a6503SJayson Yan 580d25a6503SJayson Yan int8_t Signed8Max = std::numeric_limits<int8_t>::max(); 581d25a6503SJayson Yan int8_t Signed8Min = std::numeric_limits<int8_t>::min(); 582d25a6503SJayson Yan W.printNumber("int8_t-max", Signed8Max); 583d25a6503SJayson Yan W.printNumber("int8_t-min", Signed8Min); 584d25a6503SJayson Yan 585d25a6503SJayson Yan APSInt LargeNum("9999999999999999999999"); 586d25a6503SJayson Yan W.printNumber("apsint", LargeNum); 587d25a6503SJayson Yan 588d25a6503SJayson Yan W.printNumber("label", "value", 0); 58989359df8SPaul Kirth 59089359df8SPaul Kirth W.printNumber("float-max", MaxFloat); 59189359df8SPaul Kirth W.printNumber("float-min", MinFloat); 592f331e13dSPaul Kirth W.printNumber("float-inf", InfFloat); 593f331e13dSPaul Kirth W.printNumber("float-nan", NaNFloat); 59489359df8SPaul Kirth W.printNumber("float-42.0", 42.0f); 59589359df8SPaul Kirth W.printNumber("float-42.5625", 42.5625f); 59689359df8SPaul Kirth 59789359df8SPaul Kirth W.printNumber("double-max", MaxDouble); 59889359df8SPaul Kirth W.printNumber("double-min", MinDouble); 599f331e13dSPaul Kirth W.printNumber("double-inf", InfDouble); 600f331e13dSPaul Kirth W.printNumber("double-nan", NaNDouble); 60189359df8SPaul Kirth W.printNumber("double-42.0", 42.0); 60289359df8SPaul Kirth W.printNumber("double-42.5625", 42.5625); 603d25a6503SJayson Yan }; 604d25a6503SJayson Yan 60589359df8SPaul Kirth std::string ExpectedOut = Twine( 60689359df8SPaul Kirth R"(uint64_t-max: 18446744073709551615 607d25a6503SJayson Yan uint64_t-min: 0 608d25a6503SJayson Yan uint32_t-max: 4294967295 609d25a6503SJayson Yan uint32_t-min: 0 610d25a6503SJayson Yan uint16_t-max: 65535 611d25a6503SJayson Yan uint16_t-min: 0 612d25a6503SJayson Yan uint8_t-max: 255 613d25a6503SJayson Yan uint8_t-min: 0 614d25a6503SJayson Yan int64_t-max: 9223372036854775807 615d25a6503SJayson Yan int64_t-min: -9223372036854775808 616d25a6503SJayson Yan int32_t-max: 2147483647 617d25a6503SJayson Yan int32_t-min: -2147483648 618d25a6503SJayson Yan int16_t-max: 32767 619d25a6503SJayson Yan int16_t-min: -32768 620d25a6503SJayson Yan int8_t-max: 127 621d25a6503SJayson Yan int8_t-min: -128 622d25a6503SJayson Yan apsint: 9999999999999999999999 623d25a6503SJayson Yan label: value (0) 624f331e13dSPaul Kirth float-max: )" + formatFloatString(MaxFloat) + 625f331e13dSPaul Kirth R"( 62689359df8SPaul Kirth float-min: 0.0 627f331e13dSPaul Kirth float-inf: )" + formatFloatString(InfFloat) + 628f331e13dSPaul Kirth R"( 629f331e13dSPaul Kirth float-nan: )" + formatFloatString(NaNFloat) + 630f331e13dSPaul Kirth R"( 63189359df8SPaul Kirth float-42.0: 42.0 63289359df8SPaul Kirth float-42.5625: 42.6 633f331e13dSPaul Kirth double-max: )" + formatFloatString(MaxDouble) + 63489359df8SPaul Kirth R"( 63589359df8SPaul Kirth double-min: 0.0 636f331e13dSPaul Kirth double-inf: )" + formatFloatString(InfDouble) + 637f331e13dSPaul Kirth R"( 638f331e13dSPaul Kirth double-nan: )" + formatFloatString(NaNDouble) + 639f331e13dSPaul Kirth R"( 64089359df8SPaul Kirth double-42.0: 42.0 64189359df8SPaul Kirth double-42.5625: 42.6 64289359df8SPaul Kirth )") 64389359df8SPaul Kirth .str(); 644928d1725SJayson Yan 6458088f5bfSPaul Kirth std::string JSONExpectedOut = Twine(R"({ 646928d1725SJayson Yan "uint64_t-max": 18446744073709551615, 647928d1725SJayson Yan "uint64_t-min": 0, 648928d1725SJayson Yan "uint32_t-max": 4294967295, 649928d1725SJayson Yan "uint32_t-min": 0, 650928d1725SJayson Yan "uint16_t-max": 65535, 651928d1725SJayson Yan "uint16_t-min": 0, 652928d1725SJayson Yan "uint8_t-max": 255, 653928d1725SJayson Yan "uint8_t-min": 0, 654928d1725SJayson Yan "int64_t-max": 9223372036854775807, 655928d1725SJayson Yan "int64_t-min": -9223372036854775808, 656928d1725SJayson Yan "int32_t-max": 2147483647, 657928d1725SJayson Yan "int32_t-min": -2147483648, 658928d1725SJayson Yan "int16_t-max": 32767, 659928d1725SJayson Yan "int16_t-min": -32768, 660928d1725SJayson Yan "int8_t-max": 127, 661928d1725SJayson Yan "int8_t-min": -128, 662928d1725SJayson Yan "apsint": 9999999999999999999999, 663928d1725SJayson Yan "label": { 66493c1a5f3SPaul Kirth "Name": "value", 66593c1a5f3SPaul Kirth "Value": 0 66689359df8SPaul Kirth }, 66789359df8SPaul Kirth "float-max": 3.4028234663852886e+38, 66889359df8SPaul Kirth "float-min": 1.1754943508222875e-38, 669f331e13dSPaul Kirth "float-inf": )" + formatJsonFloatString(InfFloat) + 670f331e13dSPaul Kirth R"(, 671f331e13dSPaul Kirth "float-nan": )" + formatJsonFloatString(NaNFloat) + 672f331e13dSPaul Kirth R"(, 67389359df8SPaul Kirth "float-42.0": 42, 67489359df8SPaul Kirth "float-42.5625": 42.5625, 67589359df8SPaul Kirth "double-max": 1.7976931348623157e+308, 67689359df8SPaul Kirth "double-min": 2.2250738585072014e-308, 677f331e13dSPaul Kirth "double-inf": )" + formatJsonFloatString(InfDouble) + 678f331e13dSPaul Kirth R"(, 679f331e13dSPaul Kirth "double-nan": )" + formatJsonFloatString(NaNDouble) + 680f331e13dSPaul Kirth R"(, 68189359df8SPaul Kirth "double-42.0": 42, 68289359df8SPaul Kirth "double-42.5625": 42.5625 683fa56e362SPaul Kirth })") 684fa56e362SPaul Kirth .str(); 685928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 686d25a6503SJayson Yan } 687d25a6503SJayson Yan 688d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintBoolean) { 689d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 690d25a6503SJayson Yan W.printBoolean("True", true); 691d25a6503SJayson Yan W.printBoolean("False", false); 692d25a6503SJayson Yan }; 693d25a6503SJayson Yan 694d25a6503SJayson Yan const char *ExpectedOut = R"(True: Yes 695d25a6503SJayson Yan False: No 696d25a6503SJayson Yan )"; 697928d1725SJayson Yan 698928d1725SJayson Yan const char *JSONExpectedOut = R"({ 699928d1725SJayson Yan "True": true, 700928d1725SJayson Yan "False": false 701928d1725SJayson Yan })"; 702928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 703d25a6503SJayson Yan } 704d25a6503SJayson Yan 705d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintVersion) { 706d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 707d25a6503SJayson Yan W.printVersion("Version", "123", "456", "789"); 708d25a6503SJayson Yan }; 709d25a6503SJayson Yan const char *ExpectedOut = R"(Version: 123.456.789 710d25a6503SJayson Yan )"; 711d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 712d25a6503SJayson Yan } 713d25a6503SJayson Yan 714d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintList) { 715d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 716d25a6503SJayson Yan const std::vector<uint64_t> EmptyList; 717d25a6503SJayson Yan const std::vector<std::string> StringList = {"foo", "bar", "baz"}; 718d25a6503SJayson Yan const bool BoolList[] = {true, false}; 719d25a6503SJayson Yan const std::vector<uint64_t> Unsigned64List = { 720d25a6503SJayson Yan std::numeric_limits<uint64_t>::max(), 721d25a6503SJayson Yan std::numeric_limits<uint64_t>::min()}; 722d25a6503SJayson Yan const std::vector<uint32_t> Unsigned32List = { 723d25a6503SJayson Yan std::numeric_limits<uint32_t>::max(), 724d25a6503SJayson Yan std::numeric_limits<uint32_t>::min()}; 725d25a6503SJayson Yan const std::vector<uint16_t> Unsigned16List = { 726d25a6503SJayson Yan std::numeric_limits<uint16_t>::max(), 727d25a6503SJayson Yan std::numeric_limits<uint16_t>::min()}; 728d25a6503SJayson Yan const std::vector<uint8_t> Unsigned8List = { 729d25a6503SJayson Yan std::numeric_limits<uint8_t>::max(), 730d25a6503SJayson Yan std::numeric_limits<uint8_t>::min()}; 731d25a6503SJayson Yan const std::vector<int64_t> Signed64List = { 732d25a6503SJayson Yan std::numeric_limits<int64_t>::max(), 733d25a6503SJayson Yan std::numeric_limits<int64_t>::min()}; 734d25a6503SJayson Yan const std::vector<int32_t> Signed32List = { 735d25a6503SJayson Yan std::numeric_limits<int32_t>::max(), 736d25a6503SJayson Yan std::numeric_limits<int32_t>::min()}; 737d25a6503SJayson Yan const std::vector<int16_t> Signed16List = { 738d25a6503SJayson Yan std::numeric_limits<int16_t>::max(), 739d25a6503SJayson Yan std::numeric_limits<int16_t>::min()}; 740d25a6503SJayson Yan const std::vector<int8_t> Signed8List = { 741d25a6503SJayson Yan std::numeric_limits<int8_t>::max(), std::numeric_limits<int8_t>::min()}; 742d25a6503SJayson Yan const std::vector<APSInt> APSIntList = {APSInt("9999999999999999999999"), 743d25a6503SJayson Yan APSInt("-9999999999999999999999")}; 744d25a6503SJayson Yan W.printList("EmptyList", EmptyList); 745d25a6503SJayson Yan W.printList("StringList", StringList); 74638818b60Sserge-sans-paille W.printList("BoolList", ArrayRef(BoolList)); 747d25a6503SJayson Yan W.printList("uint64List", Unsigned64List); 748d25a6503SJayson Yan W.printList("uint32List", Unsigned32List); 749d25a6503SJayson Yan W.printList("uint16List", Unsigned16List); 750d25a6503SJayson Yan W.printList("uint8List", Unsigned8List); 751d25a6503SJayson Yan W.printList("int64List", Signed64List); 752d25a6503SJayson Yan W.printList("int32List", Signed32List); 753d25a6503SJayson Yan W.printList("int16List", Signed16List); 754d25a6503SJayson Yan W.printList("int8List", Signed8List); 755d25a6503SJayson Yan W.printList("APSIntList", APSIntList); 756d25a6503SJayson Yan }; 757d25a6503SJayson Yan 758d25a6503SJayson Yan const char *ExpectedOut = R"(EmptyList: [] 759d25a6503SJayson Yan StringList: [foo, bar, baz] 760d25a6503SJayson Yan BoolList: [1, 0] 761d25a6503SJayson Yan uint64List: [18446744073709551615, 0] 762d25a6503SJayson Yan uint32List: [4294967295, 0] 763d25a6503SJayson Yan uint16List: [65535, 0] 764d25a6503SJayson Yan uint8List: [255, 0] 765d25a6503SJayson Yan int64List: [9223372036854775807, -9223372036854775808] 766d25a6503SJayson Yan int32List: [2147483647, -2147483648] 767d25a6503SJayson Yan int16List: [32767, -32768] 768d25a6503SJayson Yan int8List: [127, -128] 769d25a6503SJayson Yan APSIntList: [9999999999999999999999, -9999999999999999999999] 770d25a6503SJayson Yan )"; 771928d1725SJayson Yan 772928d1725SJayson Yan const char *JSONExpectedOut = R"({ 773928d1725SJayson Yan "EmptyList": [], 774928d1725SJayson Yan "StringList": [ 775928d1725SJayson Yan "foo", 776928d1725SJayson Yan "bar", 777928d1725SJayson Yan "baz" 778928d1725SJayson Yan ], 779928d1725SJayson Yan "BoolList": [ 780928d1725SJayson Yan true, 781928d1725SJayson Yan false 782928d1725SJayson Yan ], 783928d1725SJayson Yan "uint64List": [ 784928d1725SJayson Yan 18446744073709551615, 785928d1725SJayson Yan 0 786928d1725SJayson Yan ], 787928d1725SJayson Yan "uint32List": [ 788928d1725SJayson Yan 4294967295, 789928d1725SJayson Yan 0 790928d1725SJayson Yan ], 791928d1725SJayson Yan "uint16List": [ 792928d1725SJayson Yan 65535, 793928d1725SJayson Yan 0 794928d1725SJayson Yan ], 795928d1725SJayson Yan "uint8List": [ 796928d1725SJayson Yan 255, 797928d1725SJayson Yan 0 798928d1725SJayson Yan ], 799928d1725SJayson Yan "int64List": [ 800928d1725SJayson Yan 9223372036854775807, 801928d1725SJayson Yan -9223372036854775808 802928d1725SJayson Yan ], 803928d1725SJayson Yan "int32List": [ 804928d1725SJayson Yan 2147483647, 805928d1725SJayson Yan -2147483648 806928d1725SJayson Yan ], 807928d1725SJayson Yan "int16List": [ 808928d1725SJayson Yan 32767, 809928d1725SJayson Yan -32768 810928d1725SJayson Yan ], 811928d1725SJayson Yan "int8List": [ 812928d1725SJayson Yan 127, 813928d1725SJayson Yan -128 814928d1725SJayson Yan ], 815928d1725SJayson Yan "APSIntList": [ 816928d1725SJayson Yan 9999999999999999999999, 817928d1725SJayson Yan -9999999999999999999999 818928d1725SJayson Yan ] 819928d1725SJayson Yan })"; 820928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 821d25a6503SJayson Yan } 822d25a6503SJayson Yan 823d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintListPrinter) { 824d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 825d25a6503SJayson Yan const std::string StringList[] = {"a", "ab", "abc"}; 826d25a6503SJayson Yan W.printList("StringSizeList", StringList, 827d25a6503SJayson Yan [](raw_ostream &OS, StringRef Item) { OS << Item.size(); }); 828d25a6503SJayson Yan }; 829d25a6503SJayson Yan 830d25a6503SJayson Yan const char *ExpectedOut = R"(StringSizeList: [1, 2, 3] 831d25a6503SJayson Yan )"; 832d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 833d25a6503SJayson Yan } 834d25a6503SJayson Yan 835d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintHex) { 836d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 837d25a6503SJayson Yan W.printHex("HexNumber", 0x10); 838d25a6503SJayson Yan W.printHex("HexLabel", "Name", 0x10); 839d25a6503SJayson Yan }; 840d25a6503SJayson Yan 841d25a6503SJayson Yan const char *ExpectedOut = R"(HexNumber: 0x10 842d25a6503SJayson Yan HexLabel: Name (0x10) 843d25a6503SJayson Yan )"; 844928d1725SJayson Yan 845928d1725SJayson Yan const char *JSONExpectedOut = R"({ 846928d1725SJayson Yan "HexNumber": 16, 847928d1725SJayson Yan "HexLabel": { 84893c1a5f3SPaul Kirth "Name": "Name", 84993c1a5f3SPaul Kirth "Value": 16 850928d1725SJayson Yan } 851928d1725SJayson Yan })"; 852928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 853d25a6503SJayson Yan } 854d25a6503SJayson Yan 855d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintHexList) { 856d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 857d25a6503SJayson Yan const uint64_t HexList[] = {0x1, 0x10, 0x100}; 858d25a6503SJayson Yan W.printHexList("HexList", HexList); 859d25a6503SJayson Yan }; 860d25a6503SJayson Yan const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100] 861d25a6503SJayson Yan )"; 862928d1725SJayson Yan 863928d1725SJayson Yan const char *JSONExpectedOut = R"({ 864928d1725SJayson Yan "HexList": [ 865928d1725SJayson Yan 1, 866928d1725SJayson Yan 16, 867928d1725SJayson Yan 256 868928d1725SJayson Yan ] 869928d1725SJayson Yan })"; 870928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 871d25a6503SJayson Yan } 872d25a6503SJayson Yan 873d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintSymbolOffset) { 874d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 875d25a6503SJayson Yan W.printSymbolOffset("SymbolOffset", "SymbolName", 0x10); 876d25a6503SJayson Yan W.printSymbolOffset("NoSymbolOffset", "SymbolName", 0); 877d25a6503SJayson Yan }; 878d25a6503SJayson Yan const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10 879d25a6503SJayson Yan NoSymbolOffset: SymbolName+0x0 880d25a6503SJayson Yan )"; 881928d1725SJayson Yan 882928d1725SJayson Yan const char *JSONExpectedOut = R"({ 883928d1725SJayson Yan "SymbolOffset": { 884928d1725SJayson Yan "SymName": "SymbolName", 885928d1725SJayson Yan "Offset": 16 886928d1725SJayson Yan }, 887928d1725SJayson Yan "NoSymbolOffset": { 888928d1725SJayson Yan "SymName": "SymbolName", 889928d1725SJayson Yan "Offset": 0 890928d1725SJayson Yan } 891928d1725SJayson Yan })"; 892928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 893d25a6503SJayson Yan } 894d25a6503SJayson Yan 895d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintString) { 896d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 897d25a6503SJayson Yan const StringRef StringRefValue("Value"); 898d25a6503SJayson Yan const std::string StringValue = "Value"; 899d25a6503SJayson Yan const char *CharArrayValue = "Value"; 900d25a6503SJayson Yan W.printString("StringRef", StringRefValue); 901d25a6503SJayson Yan W.printString("String", StringValue); 902d25a6503SJayson Yan W.printString("CharArray", CharArrayValue); 903d25a6503SJayson Yan ListScope L(W, "StringList"); 904d25a6503SJayson Yan W.printString(StringRefValue); 905d25a6503SJayson Yan }; 906d25a6503SJayson Yan 907d25a6503SJayson Yan const char *ExpectedOut = R"(StringRef: Value 908d25a6503SJayson Yan String: Value 909d25a6503SJayson Yan CharArray: Value 910d25a6503SJayson Yan StringList [ 911d25a6503SJayson Yan Value 912d25a6503SJayson Yan ] 913d25a6503SJayson Yan )"; 914928d1725SJayson Yan 915928d1725SJayson Yan const char *JSONExpectedOut = R"({ 916928d1725SJayson Yan "StringRef": "Value", 917928d1725SJayson Yan "String": "Value", 918928d1725SJayson Yan "CharArray": "Value", 919928d1725SJayson Yan "StringList": [ 920928d1725SJayson Yan "Value" 921928d1725SJayson Yan ] 922928d1725SJayson Yan })"; 923928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 924d25a6503SJayson Yan } 925d25a6503SJayson Yan 926d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintBinary) { 927d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 928d25a6503SJayson Yan std::vector<uint8_t> IntArray = {70, 111, 111, 66, 97, 114}; 929d25a6503SJayson Yan std::vector<char> CharArray = {'F', 'o', 'o', 'B', 'a', 'r'}; 930d25a6503SJayson Yan std::vector<uint8_t> InvalidChars = {255, 255}; 931d25a6503SJayson Yan W.printBinary("Binary1", "FooBar", IntArray); 932d25a6503SJayson Yan W.printBinary("Binary2", "FooBar", CharArray); 933d25a6503SJayson Yan W.printBinary("Binary3", IntArray); 934d25a6503SJayson Yan W.printBinary("Binary4", CharArray); 935d25a6503SJayson Yan W.printBinary("Binary5", StringRef("FooBar")); 936d25a6503SJayson Yan W.printBinary("Binary6", StringRef("Multiple Line FooBar")); 937d25a6503SJayson Yan W.printBinaryBlock("Binary7", IntArray, 20); 938d25a6503SJayson Yan W.printBinaryBlock("Binary8", IntArray); 939d25a6503SJayson Yan W.printBinaryBlock("Binary9", "FooBar"); 940d25a6503SJayson Yan W.printBinaryBlock("Binary10", "Multiple Line FooBar"); 941d25a6503SJayson Yan W.printBinaryBlock("Binary11", InvalidChars); 942d25a6503SJayson Yan }; 943d25a6503SJayson Yan 944d25a6503SJayson Yan const char *ExpectedOut = R"(Binary1: FooBar (46 6F 6F 42 61 72) 945d25a6503SJayson Yan Binary2: FooBar (46 6F 6F 42 61 72) 946d25a6503SJayson Yan Binary3: (46 6F 6F 42 61 72) 947d25a6503SJayson Yan Binary4: (46 6F 6F 42 61 72) 948d25a6503SJayson Yan Binary5: (46 6F 6F 42 61 72) 949d25a6503SJayson Yan Binary6 ( 950d25a6503SJayson Yan 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo| 951d25a6503SJayson Yan 0010: 6F426172 |oBar| 952d25a6503SJayson Yan ) 953d25a6503SJayson Yan Binary7 ( 954d25a6503SJayson Yan 0014: 466F6F42 6172 |FooBar| 955d25a6503SJayson Yan ) 956d25a6503SJayson Yan Binary8 ( 957d25a6503SJayson Yan 0000: 466F6F42 6172 |FooBar| 958d25a6503SJayson Yan ) 959d25a6503SJayson Yan Binary9 ( 960d25a6503SJayson Yan 0000: 466F6F42 6172 |FooBar| 961d25a6503SJayson Yan ) 962d25a6503SJayson Yan Binary10 ( 963d25a6503SJayson Yan 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo| 964d25a6503SJayson Yan 0010: 6F426172 |oBar| 965d25a6503SJayson Yan ) 966d25a6503SJayson Yan Binary11 ( 967d25a6503SJayson Yan 0000: FFFF |..| 968d25a6503SJayson Yan ) 969d25a6503SJayson Yan )"; 970928d1725SJayson Yan 971928d1725SJayson Yan const char *JSONExpectedOut = R"({ 972928d1725SJayson Yan "Binary1": { 973928d1725SJayson Yan "Value": "FooBar", 974928d1725SJayson Yan "Offset": 0, 975928d1725SJayson Yan "Bytes": [ 976928d1725SJayson Yan 70, 977928d1725SJayson Yan 111, 978928d1725SJayson Yan 111, 979928d1725SJayson Yan 66, 980928d1725SJayson Yan 97, 981928d1725SJayson Yan 114 982928d1725SJayson Yan ] 983928d1725SJayson Yan }, 984928d1725SJayson Yan "Binary2": { 985928d1725SJayson Yan "Value": "FooBar", 986928d1725SJayson Yan "Offset": 0, 987928d1725SJayson Yan "Bytes": [ 988928d1725SJayson Yan 70, 989928d1725SJayson Yan 111, 990928d1725SJayson Yan 111, 991928d1725SJayson Yan 66, 992928d1725SJayson Yan 97, 993928d1725SJayson Yan 114 994928d1725SJayson Yan ] 995928d1725SJayson Yan }, 996928d1725SJayson Yan "Binary3": { 997928d1725SJayson Yan "Offset": 0, 998928d1725SJayson Yan "Bytes": [ 999928d1725SJayson Yan 70, 1000928d1725SJayson Yan 111, 1001928d1725SJayson Yan 111, 1002928d1725SJayson Yan 66, 1003928d1725SJayson Yan 97, 1004928d1725SJayson Yan 114 1005928d1725SJayson Yan ] 1006928d1725SJayson Yan }, 1007928d1725SJayson Yan "Binary4": { 1008928d1725SJayson Yan "Offset": 0, 1009928d1725SJayson Yan "Bytes": [ 1010928d1725SJayson Yan 70, 1011928d1725SJayson Yan 111, 1012928d1725SJayson Yan 111, 1013928d1725SJayson Yan 66, 1014928d1725SJayson Yan 97, 1015928d1725SJayson Yan 114 1016928d1725SJayson Yan ] 1017928d1725SJayson Yan }, 1018928d1725SJayson Yan "Binary5": { 1019928d1725SJayson Yan "Offset": 0, 1020928d1725SJayson Yan "Bytes": [ 1021928d1725SJayson Yan 70, 1022928d1725SJayson Yan 111, 1023928d1725SJayson Yan 111, 1024928d1725SJayson Yan 66, 1025928d1725SJayson Yan 97, 1026928d1725SJayson Yan 114 1027928d1725SJayson Yan ] 1028928d1725SJayson Yan }, 1029928d1725SJayson Yan "Binary6": { 1030928d1725SJayson Yan "Offset": 0, 1031928d1725SJayson Yan "Bytes": [ 1032928d1725SJayson Yan 77, 1033928d1725SJayson Yan 117, 1034928d1725SJayson Yan 108, 1035928d1725SJayson Yan 116, 1036928d1725SJayson Yan 105, 1037928d1725SJayson Yan 112, 1038928d1725SJayson Yan 108, 1039928d1725SJayson Yan 101, 1040928d1725SJayson Yan 32, 1041928d1725SJayson Yan 76, 1042928d1725SJayson Yan 105, 1043928d1725SJayson Yan 110, 1044928d1725SJayson Yan 101, 1045928d1725SJayson Yan 32, 1046928d1725SJayson Yan 70, 1047928d1725SJayson Yan 111, 1048928d1725SJayson Yan 111, 1049928d1725SJayson Yan 66, 1050928d1725SJayson Yan 97, 1051928d1725SJayson Yan 114 1052928d1725SJayson Yan ] 1053928d1725SJayson Yan }, 1054928d1725SJayson Yan "Binary7": { 1055928d1725SJayson Yan "Offset": 20, 1056928d1725SJayson Yan "Bytes": [ 1057928d1725SJayson Yan 70, 1058928d1725SJayson Yan 111, 1059928d1725SJayson Yan 111, 1060928d1725SJayson Yan 66, 1061928d1725SJayson Yan 97, 1062928d1725SJayson Yan 114 1063928d1725SJayson Yan ] 1064928d1725SJayson Yan }, 1065928d1725SJayson Yan "Binary8": { 1066928d1725SJayson Yan "Offset": 0, 1067928d1725SJayson Yan "Bytes": [ 1068928d1725SJayson Yan 70, 1069928d1725SJayson Yan 111, 1070928d1725SJayson Yan 111, 1071928d1725SJayson Yan 66, 1072928d1725SJayson Yan 97, 1073928d1725SJayson Yan 114 1074928d1725SJayson Yan ] 1075928d1725SJayson Yan }, 1076928d1725SJayson Yan "Binary9": { 1077928d1725SJayson Yan "Offset": 0, 1078928d1725SJayson Yan "Bytes": [ 1079928d1725SJayson Yan 70, 1080928d1725SJayson Yan 111, 1081928d1725SJayson Yan 111, 1082928d1725SJayson Yan 66, 1083928d1725SJayson Yan 97, 1084928d1725SJayson Yan 114 1085928d1725SJayson Yan ] 1086928d1725SJayson Yan }, 1087928d1725SJayson Yan "Binary10": { 1088928d1725SJayson Yan "Offset": 0, 1089928d1725SJayson Yan "Bytes": [ 1090928d1725SJayson Yan 77, 1091928d1725SJayson Yan 117, 1092928d1725SJayson Yan 108, 1093928d1725SJayson Yan 116, 1094928d1725SJayson Yan 105, 1095928d1725SJayson Yan 112, 1096928d1725SJayson Yan 108, 1097928d1725SJayson Yan 101, 1098928d1725SJayson Yan 32, 1099928d1725SJayson Yan 76, 1100928d1725SJayson Yan 105, 1101928d1725SJayson Yan 110, 1102928d1725SJayson Yan 101, 1103928d1725SJayson Yan 32, 1104928d1725SJayson Yan 70, 1105928d1725SJayson Yan 111, 1106928d1725SJayson Yan 111, 1107928d1725SJayson Yan 66, 1108928d1725SJayson Yan 97, 1109928d1725SJayson Yan 114 1110928d1725SJayson Yan ] 1111928d1725SJayson Yan }, 1112928d1725SJayson Yan "Binary11": { 1113928d1725SJayson Yan "Offset": 0, 1114928d1725SJayson Yan "Bytes": [ 1115928d1725SJayson Yan 255, 1116928d1725SJayson Yan 255 1117928d1725SJayson Yan ] 1118928d1725SJayson Yan } 1119928d1725SJayson Yan })"; 1120928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1121d25a6503SJayson Yan } 1122d25a6503SJayson Yan 1123d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintObject) { 1124d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { W.printObject("Object", "Value"); }; 1125d25a6503SJayson Yan 1126d25a6503SJayson Yan const char *ExpectedOut = R"(Object: Value 1127d25a6503SJayson Yan )"; 1128928d1725SJayson Yan 1129928d1725SJayson Yan const char *JSONExpectedOut = R"({ 1130928d1725SJayson Yan "Object": "Value" 1131928d1725SJayson Yan })"; 1132928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1133d25a6503SJayson Yan } 1134d25a6503SJayson Yan 1135d25a6503SJayson Yan TEST_F(ScopedPrinterTest, StartLine) { 1136d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 1137d25a6503SJayson Yan W.startLine() << "|"; 1138d25a6503SJayson Yan W.indent(2); 1139d25a6503SJayson Yan W.startLine() << "|"; 1140d25a6503SJayson Yan W.unindent(); 1141d25a6503SJayson Yan W.startLine() << "|"; 1142d25a6503SJayson Yan }; 1143d25a6503SJayson Yan 1144d25a6503SJayson Yan const char *ExpectedOut = "| | |"; 1145d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 1146d25a6503SJayson Yan } 1147d25a6503SJayson Yan 1148d25a6503SJayson Yan TEST_F(ScopedPrinterTest, GetOStream) { 1149d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { W.getOStream() << "Test"; }; 1150d25a6503SJayson Yan 1151d25a6503SJayson Yan const char *ExpectedOut = "Test"; 1152d25a6503SJayson Yan verifyScopedPrinter(ExpectedOut, PrintFunc); 1153d25a6503SJayson Yan } 1154d25a6503SJayson Yan 1155d25a6503SJayson Yan TEST_F(ScopedPrinterTest, PrintScope) { 1156d25a6503SJayson Yan auto PrintFunc = [](ScopedPrinter &W) { 1157d25a6503SJayson Yan { 1158d25a6503SJayson Yan DictScope O(W, "Object"); 1159d25a6503SJayson Yan { DictScope OO(W, "ObjectInObject"); } 1160d25a6503SJayson Yan { ListScope LO(W, "ListInObject"); } 1161d25a6503SJayson Yan } 1162d25a6503SJayson Yan { 1163d25a6503SJayson Yan ListScope L(W, "List"); 1164d25a6503SJayson Yan { DictScope OL(W, "ObjectInList"); } 1165d25a6503SJayson Yan { ListScope LL(W, "ListInList"); } 1166d25a6503SJayson Yan } 1167d25a6503SJayson Yan }; 1168d25a6503SJayson Yan 1169d25a6503SJayson Yan const char *ExpectedOut = R"(Object { 1170d25a6503SJayson Yan ObjectInObject { 1171d25a6503SJayson Yan } 1172d25a6503SJayson Yan ListInObject [ 1173d25a6503SJayson Yan ] 1174d25a6503SJayson Yan } 1175d25a6503SJayson Yan List [ 1176d25a6503SJayson Yan ObjectInList { 1177d25a6503SJayson Yan } 1178d25a6503SJayson Yan ListInList [ 1179d25a6503SJayson Yan ] 1180d25a6503SJayson Yan ] 1181d25a6503SJayson Yan )"; 1182928d1725SJayson Yan 1183928d1725SJayson Yan const char *JSONExpectedOut = R"({ 1184928d1725SJayson Yan "Object": { 1185928d1725SJayson Yan "ObjectInObject": {}, 1186928d1725SJayson Yan "ListInObject": [] 1187928d1725SJayson Yan }, 1188928d1725SJayson Yan "List": [ 1189928d1725SJayson Yan { 1190928d1725SJayson Yan "ObjectInList": {} 1191928d1725SJayson Yan }, 1192928d1725SJayson Yan { 1193928d1725SJayson Yan "ListInList": [] 1194928d1725SJayson Yan } 1195928d1725SJayson Yan ] 1196928d1725SJayson Yan })"; 1197928d1725SJayson Yan verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc); 1198d25a6503SJayson Yan } 1199