2 //===- unittest/DebugInfo/Symbolizer/MarkupTest.cpp - Markup parser tests -===//
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
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/Symbolize/Markup.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/Support/FormatVariadic.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
22 using namespace llvm::symbolize
;
23 using namespace testing
;
25 Matcher
<MarkupNode
> isNode(StringRef Text
, StringRef Tag
= "",
26 Matcher
<SmallVector
<StringRef
>> Fields
= IsEmpty()) {
27 return AllOf(Field("Text", &MarkupNode::Text
, Text
),
28 Field("Tag", &MarkupNode::Tag
, Tag
),
29 Field("Fields", &MarkupNode::Fields
, Fields
));
32 TEST(SymbolizerMarkup
, NoLines
) {
33 EXPECT_EQ(MarkupParser
{}.nextNode(), std::nullopt
);
36 TEST(SymbolizerMarkup
, LinesWithoutMarkup
) {
39 Parser
.parseLine("text");
40 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("text")));
41 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
43 Parser
.parseLine("discarded");
44 Parser
.parseLine("kept");
45 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("kept")));
46 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
48 Parser
.parseLine("text\n");
49 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("text\n")));
50 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
52 Parser
.parseLine("text\r\n");
53 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("text\r\n")));
54 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
56 Parser
.parseLine("{{{");
57 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{")));
58 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
60 Parser
.parseLine("{{{}}");
61 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{}}")));
62 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
64 Parser
.parseLine("{{}}}");
65 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{}}}")));
66 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
68 Parser
.parseLine("{{{}}}");
69 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{}}}")));
70 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
72 Parser
.parseLine("{{{:field}}}");
73 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{:field}}}")));
74 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
76 Parser
.parseLine("{{{tag:");
77 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag:")));
78 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
80 Parser
.parseLine("{{{tag:field}}");
81 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag:field}}")));
82 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
84 Parser
.parseLine("a\033[2mb");
85 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("a\033[2mb")));
86 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
88 Parser
.parseLine("a\033[38mb");
89 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("a\033[38mb")));
90 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
92 Parser
.parseLine("a\033[4mb");
93 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("a\033[4mb")));
94 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
97 TEST(SymbolizerMarkup
, LinesWithMarkup
) {
100 Parser
.parseLine("{{{tag}}}");
101 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag}}}", "tag")));
102 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
104 Parser
.parseLine("{{{tag:f1:f2:f3}}}");
105 EXPECT_THAT(Parser
.nextNode(),
106 testing::Optional(isNode("{{{tag:f1:f2:f3}}}", "tag",
107 ElementsAre("f1", "f2", "f3"))));
108 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
110 Parser
.parseLine("{{{tag:}}}");
111 EXPECT_THAT(Parser
.nextNode(),
112 testing::Optional(isNode("{{{tag:}}}", "tag", ElementsAre(""))));
113 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
115 Parser
.parseLine("{{{tag:}}");
116 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag:}}")));
117 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
119 Parser
.parseLine("{{{t2g}}}");
120 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{t2g}}}", "t2g")));
121 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
123 Parser
.parseLine("{{{tAg}}}");
124 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tAg}}}", "tAg")));
125 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
127 Parser
.parseLine("a{{{b}}}c{{{d}}}e");
128 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("a")));
129 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{b}}}", "b")));
130 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("c")));
131 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{d}}}", "d")));
132 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("e")));
133 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
135 Parser
.parseLine("{{{}}}{{{tag}}}");
136 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{}}}")));
137 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag}}}", "tag")));
138 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
140 Parser
.parseLine("\033[0mA\033[1mB\033[30mC\033[37m");
141 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\033[0m")));
142 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("A")));
143 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\033[1m")));
144 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("B")));
145 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\033[30m")));
146 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("C")));
147 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\033[37m")));
148 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
150 Parser
.parseLine("{{{tag:\033[0m}}}");
151 EXPECT_THAT(Parser
.nextNode(),
153 isNode("{{{tag:\033[0m}}}", "tag", ElementsAre("\033[0m"))));
154 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
157 TEST(SymbolizerMarkup
, MultilineElements
) {
158 MarkupParser
Parser(/*MultilineTags=*/{"first", "second"});
160 Parser
.parseLine("{{{tag:");
161 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{tag:")));
162 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
164 Parser
.parseLine("{{{first:");
165 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
166 Parser
.parseLine("}}}{{{second:");
169 testing::Optional(isNode("{{{first:}}}", "first", ElementsAre(""))));
170 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
171 Parser
.parseLine("}}}");
174 testing::Optional(isNode("{{{second:}}}", "second", ElementsAre(""))));
175 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
177 Parser
.parseLine("{{{before{{{first:");
178 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{before")));
179 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
180 Parser
.parseLine("line");
181 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
182 Parser
.parseLine("}}}after");
183 EXPECT_THAT(Parser
.nextNode(),
185 isNode("{{{first:line}}}", "first", ElementsAre("line"))));
186 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("after")));
187 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
189 Parser
.parseLine("{{{first:");
190 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
192 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("{{{first:")));
193 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
195 Parser
.parseLine("{{{first:\n");
196 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
197 Parser
.parseLine("}}}\n");
200 testing::Optional(isNode("{{{first:\n}}}", "first", ElementsAre("\n"))));
201 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\n")));
202 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
204 Parser
.parseLine("{{{first:\r\n");
205 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
206 Parser
.parseLine("}}}\r\n");
207 EXPECT_THAT(Parser
.nextNode(),
209 isNode("{{{first:\r\n}}}", "first", ElementsAre("\r\n"))));
210 EXPECT_THAT(Parser
.nextNode(), testing::Optional(isNode("\r\n")));
211 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
213 Parser
.parseLine("{{{first:");
214 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);
215 Parser
.parseLine("\033[0m}}}");
216 EXPECT_THAT(Parser
.nextNode(),
217 testing::Optional(isNode("{{{first:\033[0m}}}", "first",
218 ElementsAre("\033[0m"))));
219 EXPECT_THAT(Parser
.nextNode(), std::nullopt
);