xref: /llvm-project/llvm/unittests/DebugInfo/Symbolizer/MarkupTest.cpp (revision b6a01caa64aaac2e5db8d7953a81cbe1a139b81f)
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