1 2 //===- unittest/DebugInfo/Symbolizer/MarkupTest.cpp - Markup parser tests -===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/Symbolize/Markup.h" 11 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/ADT/SmallString.h" 14 #include "llvm/ADT/Twine.h" 15 #include "llvm/Support/FormatVariadic.h" 16 17 #include "gmock/gmock.h" 18 #include "gtest/gtest.h" 19 20 namespace { 21 22 using namespace llvm; 23 using namespace llvm::symbolize; 24 using namespace testing; 25 26 Matcher<MarkupNode> isNode(StringRef Text, StringRef Tag = "", 27 Matcher<SmallVector<StringRef>> Fields = IsEmpty()) { 28 return AllOf(Field("Text", &MarkupNode::Text, Text), 29 Field("Tag", &MarkupNode::Tag, Tag), 30 Field("Fields", &MarkupNode::Fields, Fields)); 31 } 32 33 TEST(SymbolizerMarkup, NoLines) { 34 EXPECT_EQ(MarkupParser{}.nextNode(), std::nullopt); 35 } 36 37 TEST(SymbolizerMarkup, LinesWithoutMarkup) { 38 MarkupParser Parser; 39 40 Parser.parseLine("text"); 41 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("text"))); 42 EXPECT_THAT(Parser.nextNode(), std::nullopt); 43 44 Parser.parseLine("discarded"); 45 Parser.parseLine("kept"); 46 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("kept"))); 47 EXPECT_THAT(Parser.nextNode(), std::nullopt); 48 49 Parser.parseLine("text\n"); 50 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("text\n"))); 51 EXPECT_THAT(Parser.nextNode(), std::nullopt); 52 53 Parser.parseLine("text\r\n"); 54 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("text\r\n"))); 55 EXPECT_THAT(Parser.nextNode(), std::nullopt); 56 57 Parser.parseLine("{{{"); 58 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{"))); 59 EXPECT_THAT(Parser.nextNode(), std::nullopt); 60 61 Parser.parseLine("{{{}}"); 62 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{}}"))); 63 EXPECT_THAT(Parser.nextNode(), std::nullopt); 64 65 Parser.parseLine("{{}}}"); 66 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{}}}"))); 67 EXPECT_THAT(Parser.nextNode(), std::nullopt); 68 69 Parser.parseLine("{{{}}}"); 70 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{}}}"))); 71 EXPECT_THAT(Parser.nextNode(), std::nullopt); 72 73 Parser.parseLine("{{{:field}}}"); 74 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{:field}}}"))); 75 EXPECT_THAT(Parser.nextNode(), std::nullopt); 76 77 Parser.parseLine("{{{tag:"); 78 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag:"))); 79 EXPECT_THAT(Parser.nextNode(), std::nullopt); 80 81 Parser.parseLine("{{{tag:field}}"); 82 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag:field}}"))); 83 EXPECT_THAT(Parser.nextNode(), std::nullopt); 84 85 Parser.parseLine("a\033[2mb"); 86 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("a\033[2mb"))); 87 EXPECT_THAT(Parser.nextNode(), std::nullopt); 88 89 Parser.parseLine("a\033[38mb"); 90 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("a\033[38mb"))); 91 EXPECT_THAT(Parser.nextNode(), std::nullopt); 92 93 Parser.parseLine("a\033[4mb"); 94 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("a\033[4mb"))); 95 EXPECT_THAT(Parser.nextNode(), std::nullopt); 96 } 97 98 TEST(SymbolizerMarkup, LinesWithMarkup) { 99 MarkupParser Parser; 100 101 Parser.parseLine("{{{tag}}}"); 102 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag}}}", "tag"))); 103 EXPECT_THAT(Parser.nextNode(), std::nullopt); 104 105 Parser.parseLine("{{{tag:f1:f2:f3}}}"); 106 EXPECT_THAT(Parser.nextNode(), 107 testing::Optional(isNode("{{{tag:f1:f2:f3}}}", "tag", 108 ElementsAre("f1", "f2", "f3")))); 109 EXPECT_THAT(Parser.nextNode(), std::nullopt); 110 111 Parser.parseLine("{{{tag:}}}"); 112 EXPECT_THAT(Parser.nextNode(), 113 testing::Optional(isNode("{{{tag:}}}", "tag", ElementsAre("")))); 114 EXPECT_THAT(Parser.nextNode(), std::nullopt); 115 116 Parser.parseLine("{{{tag:}}"); 117 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag:}}"))); 118 EXPECT_THAT(Parser.nextNode(), std::nullopt); 119 120 Parser.parseLine("{{{t2g}}}"); 121 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{t2g}}}", "t2g"))); 122 EXPECT_THAT(Parser.nextNode(), std::nullopt); 123 124 Parser.parseLine("{{{tAg}}}"); 125 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tAg}}}", "tAg"))); 126 EXPECT_THAT(Parser.nextNode(), std::nullopt); 127 128 Parser.parseLine("a{{{b}}}c{{{d}}}e"); 129 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("a"))); 130 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{b}}}", "b"))); 131 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("c"))); 132 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{d}}}", "d"))); 133 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("e"))); 134 EXPECT_THAT(Parser.nextNode(), std::nullopt); 135 136 Parser.parseLine("{{{}}}{{{tag}}}"); 137 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{}}}"))); 138 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag}}}", "tag"))); 139 EXPECT_THAT(Parser.nextNode(), std::nullopt); 140 141 Parser.parseLine("\033[0mA\033[1mB\033[30mC\033[37m"); 142 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\033[0m"))); 143 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("A"))); 144 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\033[1m"))); 145 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("B"))); 146 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\033[30m"))); 147 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("C"))); 148 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\033[37m"))); 149 EXPECT_THAT(Parser.nextNode(), std::nullopt); 150 151 Parser.parseLine("{{{tag:\033[0m}}}"); 152 EXPECT_THAT(Parser.nextNode(), 153 testing::Optional( 154 isNode("{{{tag:\033[0m}}}", "tag", ElementsAre("\033[0m")))); 155 EXPECT_THAT(Parser.nextNode(), std::nullopt); 156 } 157 158 TEST(SymbolizerMarkup, MultilineElements) { 159 MarkupParser Parser(/*MultilineTags=*/{"first", "second"}); 160 161 Parser.parseLine("{{{tag:"); 162 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{tag:"))); 163 EXPECT_THAT(Parser.nextNode(), std::nullopt); 164 165 Parser.parseLine("{{{first:"); 166 EXPECT_THAT(Parser.nextNode(), std::nullopt); 167 Parser.parseLine("}}}{{{second:"); 168 EXPECT_THAT( 169 Parser.nextNode(), 170 testing::Optional(isNode("{{{first:}}}", "first", ElementsAre("")))); 171 EXPECT_THAT(Parser.nextNode(), std::nullopt); 172 Parser.parseLine("}}}"); 173 EXPECT_THAT( 174 Parser.nextNode(), 175 testing::Optional(isNode("{{{second:}}}", "second", ElementsAre("")))); 176 EXPECT_THAT(Parser.nextNode(), std::nullopt); 177 178 Parser.parseLine("{{{before{{{first:"); 179 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{before"))); 180 EXPECT_THAT(Parser.nextNode(), std::nullopt); 181 Parser.parseLine("line"); 182 EXPECT_THAT(Parser.nextNode(), std::nullopt); 183 Parser.parseLine("}}}after"); 184 EXPECT_THAT(Parser.nextNode(), 185 testing::Optional( 186 isNode("{{{first:line}}}", "first", ElementsAre("line")))); 187 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("after"))); 188 EXPECT_THAT(Parser.nextNode(), std::nullopt); 189 190 Parser.parseLine("{{{first:"); 191 EXPECT_THAT(Parser.nextNode(), std::nullopt); 192 Parser.flush(); 193 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("{{{first:"))); 194 EXPECT_THAT(Parser.nextNode(), std::nullopt); 195 196 Parser.parseLine("{{{first:\n"); 197 EXPECT_THAT(Parser.nextNode(), std::nullopt); 198 Parser.parseLine("}}}\n"); 199 EXPECT_THAT( 200 Parser.nextNode(), 201 testing::Optional(isNode("{{{first:\n}}}", "first", ElementsAre("\n")))); 202 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\n"))); 203 EXPECT_THAT(Parser.nextNode(), std::nullopt); 204 205 Parser.parseLine("{{{first:\r\n"); 206 EXPECT_THAT(Parser.nextNode(), std::nullopt); 207 Parser.parseLine("}}}\r\n"); 208 EXPECT_THAT(Parser.nextNode(), 209 testing::Optional( 210 isNode("{{{first:\r\n}}}", "first", ElementsAre("\r\n")))); 211 EXPECT_THAT(Parser.nextNode(), testing::Optional(isNode("\r\n"))); 212 EXPECT_THAT(Parser.nextNode(), std::nullopt); 213 214 Parser.parseLine("{{{first:"); 215 EXPECT_THAT(Parser.nextNode(), std::nullopt); 216 Parser.parseLine("\033[0m}}}"); 217 EXPECT_THAT(Parser.nextNode(), 218 testing::Optional(isNode("{{{first:\033[0m}}}", "first", 219 ElementsAre("\033[0m")))); 220 EXPECT_THAT(Parser.nextNode(), std::nullopt); 221 } 222 223 } // namespace 224