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