1*fa1f4cf8SSam McCall //===-- MarkupTests.cpp ---------------------------------------------------===//
2*fa1f4cf8SSam McCall //
3*fa1f4cf8SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*fa1f4cf8SSam McCall // See https://llvm.org/LICENSE.txt for license information.
5*fa1f4cf8SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*fa1f4cf8SSam McCall //
7*fa1f4cf8SSam McCall //===----------------------------------------------------------------------===//
8*fa1f4cf8SSam McCall #include "support/Markup.h"
9*fa1f4cf8SSam McCall #include "clang/Basic/LLVM.h"
10*fa1f4cf8SSam McCall #include "llvm/ADT/StringRef.h"
11*fa1f4cf8SSam McCall #include "gmock/gmock.h"
12*fa1f4cf8SSam McCall #include "gtest/gtest.h"
13*fa1f4cf8SSam McCall
14*fa1f4cf8SSam McCall namespace clang {
15*fa1f4cf8SSam McCall namespace clangd {
16*fa1f4cf8SSam McCall namespace markup {
17*fa1f4cf8SSam McCall namespace {
18*fa1f4cf8SSam McCall
escape(llvm::StringRef Text)19*fa1f4cf8SSam McCall std::string escape(llvm::StringRef Text) {
20*fa1f4cf8SSam McCall return Paragraph().appendText(Text.str()).asMarkdown();
21*fa1f4cf8SSam McCall }
22*fa1f4cf8SSam McCall
23*fa1f4cf8SSam McCall MATCHER_P(escaped, C, "") {
24*fa1f4cf8SSam McCall return testing::ExplainMatchResult(::testing::HasSubstr(std::string{'\\', C}),
25*fa1f4cf8SSam McCall arg, result_listener);
26*fa1f4cf8SSam McCall }
27*fa1f4cf8SSam McCall
28*fa1f4cf8SSam McCall MATCHER(escapedNone, "") {
29*fa1f4cf8SSam McCall return testing::ExplainMatchResult(::testing::Not(::testing::HasSubstr("\\")),
30*fa1f4cf8SSam McCall arg, result_listener);
31*fa1f4cf8SSam McCall }
32*fa1f4cf8SSam McCall
TEST(Render,Escaping)33*fa1f4cf8SSam McCall TEST(Render, Escaping) {
34*fa1f4cf8SSam McCall // Check all ASCII punctuation.
35*fa1f4cf8SSam McCall std::string Punctuation = R"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt";
36*fa1f4cf8SSam McCall std::string EscapedPunc = R"txt(!"#$%&'()\*+,-./:;<=>?@[\\]^\_\`{|}~)txt";
37*fa1f4cf8SSam McCall EXPECT_EQ(escape(Punctuation), EscapedPunc);
38*fa1f4cf8SSam McCall
39*fa1f4cf8SSam McCall // Inline code
40*fa1f4cf8SSam McCall EXPECT_EQ(escape("`foo`"), R"(\`foo\`)");
41*fa1f4cf8SSam McCall EXPECT_EQ(escape("`foo"), R"(\`foo)");
42*fa1f4cf8SSam McCall EXPECT_EQ(escape("foo`"), R"(foo\`)");
43*fa1f4cf8SSam McCall EXPECT_EQ(escape("``foo``"), R"(\`\`foo\`\`)");
44*fa1f4cf8SSam McCall // Code blocks
45*fa1f4cf8SSam McCall EXPECT_EQ(escape("```"), R"(\`\`\`)"); // This could also be inline code!
46*fa1f4cf8SSam McCall EXPECT_EQ(escape("~~~"), R"(\~~~)");
47*fa1f4cf8SSam McCall
48*fa1f4cf8SSam McCall // Rulers and headings
49*fa1f4cf8SSam McCall EXPECT_THAT(escape("## Heading"), escaped('#'));
50*fa1f4cf8SSam McCall EXPECT_THAT(escape("Foo # bar"), escapedNone());
51*fa1f4cf8SSam McCall EXPECT_EQ(escape("---"), R"(\---)");
52*fa1f4cf8SSam McCall EXPECT_EQ(escape("-"), R"(\-)");
53*fa1f4cf8SSam McCall EXPECT_EQ(escape("==="), R"(\===)");
54*fa1f4cf8SSam McCall EXPECT_EQ(escape("="), R"(\=)");
55*fa1f4cf8SSam McCall EXPECT_EQ(escape("***"), R"(\*\*\*)"); // \** could start emphasis!
56*fa1f4cf8SSam McCall
57*fa1f4cf8SSam McCall // HTML tags.
58*fa1f4cf8SSam McCall EXPECT_THAT(escape("<pre"), escaped('<'));
59*fa1f4cf8SSam McCall EXPECT_THAT(escape("< pre"), escapedNone());
60*fa1f4cf8SSam McCall EXPECT_THAT(escape("if a<b then"), escaped('<'));
61*fa1f4cf8SSam McCall EXPECT_THAT(escape("if a<b then c."), escapedNone());
62*fa1f4cf8SSam McCall EXPECT_THAT(escape("if a<b then c='foo'."), escaped('<'));
63*fa1f4cf8SSam McCall EXPECT_THAT(escape("std::vector<T>"), escaped('<'));
64*fa1f4cf8SSam McCall EXPECT_THAT(escape("std::vector<std::string>"), escaped('<'));
65*fa1f4cf8SSam McCall EXPECT_THAT(escape("std::map<int, int>"), escapedNone());
66*fa1f4cf8SSam McCall // Autolinks
67*fa1f4cf8SSam McCall EXPECT_THAT(escape("Email <foo@bar.com>"), escapedNone());
68*fa1f4cf8SSam McCall EXPECT_THAT(escape("Website <http://foo.bar>"), escapedNone());
69*fa1f4cf8SSam McCall
70*fa1f4cf8SSam McCall // Bullet lists.
71*fa1f4cf8SSam McCall EXPECT_THAT(escape("- foo"), escaped('-'));
72*fa1f4cf8SSam McCall EXPECT_THAT(escape("* foo"), escaped('*'));
73*fa1f4cf8SSam McCall EXPECT_THAT(escape("+ foo"), escaped('+'));
74*fa1f4cf8SSam McCall EXPECT_THAT(escape("+"), escaped('+'));
75*fa1f4cf8SSam McCall EXPECT_THAT(escape("a + foo"), escapedNone());
76*fa1f4cf8SSam McCall EXPECT_THAT(escape("a+ foo"), escapedNone());
77*fa1f4cf8SSam McCall EXPECT_THAT(escape("1. foo"), escaped('.'));
78*fa1f4cf8SSam McCall EXPECT_THAT(escape("a. foo"), escapedNone());
79*fa1f4cf8SSam McCall
80*fa1f4cf8SSam McCall // Emphasis.
81*fa1f4cf8SSam McCall EXPECT_EQ(escape("*foo*"), R"(\*foo\*)");
82*fa1f4cf8SSam McCall EXPECT_EQ(escape("**foo**"), R"(\*\*foo\*\*)");
83*fa1f4cf8SSam McCall EXPECT_THAT(escape("*foo"), escaped('*'));
84*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo *"), escapedNone());
85*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo * bar"), escapedNone());
86*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo_bar"), escapedNone());
87*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo _bar"), escaped('_'));
88*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo_ bar"), escaped('_'));
89*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo _ bar"), escapedNone());
90*fa1f4cf8SSam McCall
91*fa1f4cf8SSam McCall // HTML entities.
92*fa1f4cf8SSam McCall EXPECT_THAT(escape("fish &chips;"), escaped('&'));
93*fa1f4cf8SSam McCall EXPECT_THAT(escape("fish & chips;"), escapedNone());
94*fa1f4cf8SSam McCall EXPECT_THAT(escape("fish &chips"), escapedNone());
95*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo * bar"), escaped('&'));
96*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo ¯ bar"), escaped('&'));
97*fa1f4cf8SSam McCall EXPECT_THAT(escape("foo &?; bar"), escapedNone());
98*fa1f4cf8SSam McCall
99*fa1f4cf8SSam McCall // Links.
100*fa1f4cf8SSam McCall EXPECT_THAT(escape("[foo](bar)"), escaped(']'));
101*fa1f4cf8SSam McCall EXPECT_THAT(escape("[foo]: bar"), escaped(']'));
102*fa1f4cf8SSam McCall // No need to escape these, as the target never exists.
103*fa1f4cf8SSam McCall EXPECT_THAT(escape("[foo][]"), escapedNone());
104*fa1f4cf8SSam McCall EXPECT_THAT(escape("[foo][bar]"), escapedNone());
105*fa1f4cf8SSam McCall EXPECT_THAT(escape("[foo]"), escapedNone());
106*fa1f4cf8SSam McCall
107*fa1f4cf8SSam McCall // In code blocks we don't need to escape ASCII punctuation.
108*fa1f4cf8SSam McCall Paragraph P = Paragraph();
109*fa1f4cf8SSam McCall P.appendCode("* foo !+ bar * baz");
110*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "`* foo !+ bar * baz`");
111*fa1f4cf8SSam McCall
112*fa1f4cf8SSam McCall // But we have to escape the backticks.
113*fa1f4cf8SSam McCall P = Paragraph();
114*fa1f4cf8SSam McCall P.appendCode("foo`bar`baz", /*Preserve=*/true);
115*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "`foo``bar``baz`");
116*fa1f4cf8SSam McCall // In plain-text, we fall back to different quotes.
117*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "'foo`bar`baz'");
118*fa1f4cf8SSam McCall
119*fa1f4cf8SSam McCall // Inline code blocks starting or ending with backticks should add spaces.
120*fa1f4cf8SSam McCall P = Paragraph();
121*fa1f4cf8SSam McCall P.appendCode("`foo");
122*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "` ``foo `");
123*fa1f4cf8SSam McCall P = Paragraph();
124*fa1f4cf8SSam McCall P.appendCode("foo`");
125*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "` foo`` `");
126*fa1f4cf8SSam McCall P = Paragraph();
127*fa1f4cf8SSam McCall P.appendCode("`foo`");
128*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "` ``foo`` `");
129*fa1f4cf8SSam McCall
130*fa1f4cf8SSam McCall // Code blocks might need more than 3 backticks.
131*fa1f4cf8SSam McCall Document D;
132*fa1f4cf8SSam McCall D.addCodeBlock("foobarbaz `\nqux");
133*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "```cpp\n"
134*fa1f4cf8SSam McCall "foobarbaz `\nqux\n"
135*fa1f4cf8SSam McCall "```");
136*fa1f4cf8SSam McCall D = Document();
137*fa1f4cf8SSam McCall D.addCodeBlock("foobarbaz ``\nqux");
138*fa1f4cf8SSam McCall EXPECT_THAT(D.asMarkdown(), "```cpp\n"
139*fa1f4cf8SSam McCall "foobarbaz ``\nqux\n"
140*fa1f4cf8SSam McCall "```");
141*fa1f4cf8SSam McCall D = Document();
142*fa1f4cf8SSam McCall D.addCodeBlock("foobarbaz ```\nqux");
143*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "````cpp\n"
144*fa1f4cf8SSam McCall "foobarbaz ```\nqux\n"
145*fa1f4cf8SSam McCall "````");
146*fa1f4cf8SSam McCall D = Document();
147*fa1f4cf8SSam McCall D.addCodeBlock("foobarbaz ` `` ``` ```` `\nqux");
148*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "`````cpp\n"
149*fa1f4cf8SSam McCall "foobarbaz ` `` ``` ```` `\nqux\n"
150*fa1f4cf8SSam McCall "`````");
151*fa1f4cf8SSam McCall }
152*fa1f4cf8SSam McCall
TEST(Paragraph,Chunks)153*fa1f4cf8SSam McCall TEST(Paragraph, Chunks) {
154*fa1f4cf8SSam McCall Paragraph P = Paragraph();
155*fa1f4cf8SSam McCall P.appendText("One ");
156*fa1f4cf8SSam McCall P.appendCode("fish");
157*fa1f4cf8SSam McCall P.appendText(", two ");
158*fa1f4cf8SSam McCall P.appendCode("fish", /*Preserve=*/true);
159*fa1f4cf8SSam McCall
160*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "One `fish`, two `fish`");
161*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "One fish, two `fish`");
162*fa1f4cf8SSam McCall }
163*fa1f4cf8SSam McCall
TEST(Paragraph,SeparationOfChunks)164*fa1f4cf8SSam McCall TEST(Paragraph, SeparationOfChunks) {
165*fa1f4cf8SSam McCall // This test keeps appending contents to a single Paragraph and checks
166*fa1f4cf8SSam McCall // expected accumulated contents after each one.
167*fa1f4cf8SSam McCall // Purpose is to check for separation between different chunks.
168*fa1f4cf8SSam McCall Paragraph P;
169*fa1f4cf8SSam McCall
170*fa1f4cf8SSam McCall P.appendText("after ");
171*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "after");
172*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "after");
173*fa1f4cf8SSam McCall
174*fa1f4cf8SSam McCall P.appendCode("foobar").appendSpace();
175*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "after `foobar`");
176*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "after foobar");
177*fa1f4cf8SSam McCall
178*fa1f4cf8SSam McCall P.appendText("bat");
179*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "after `foobar` bat");
180*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "after foobar bat");
181*fa1f4cf8SSam McCall
182*fa1f4cf8SSam McCall P.appendCode("no").appendCode("space");
183*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "after `foobar` bat`no` `space`");
184*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "after foobar batno space");
185*fa1f4cf8SSam McCall }
186*fa1f4cf8SSam McCall
TEST(Paragraph,ExtraSpaces)187*fa1f4cf8SSam McCall TEST(Paragraph, ExtraSpaces) {
188*fa1f4cf8SSam McCall // Make sure spaces inside chunks are dropped.
189*fa1f4cf8SSam McCall Paragraph P;
190*fa1f4cf8SSam McCall P.appendText("foo\n \t baz");
191*fa1f4cf8SSam McCall P.appendCode(" bar\n");
192*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "foo baz`bar`");
193*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "foo bazbar");
194*fa1f4cf8SSam McCall }
195*fa1f4cf8SSam McCall
TEST(Paragraph,SpacesCollapsed)196*fa1f4cf8SSam McCall TEST(Paragraph, SpacesCollapsed) {
197*fa1f4cf8SSam McCall Paragraph P;
198*fa1f4cf8SSam McCall P.appendText(" foo bar ");
199*fa1f4cf8SSam McCall P.appendText(" baz ");
200*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "foo bar baz");
201*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "foo bar baz");
202*fa1f4cf8SSam McCall }
203*fa1f4cf8SSam McCall
TEST(Paragraph,NewLines)204*fa1f4cf8SSam McCall TEST(Paragraph, NewLines) {
205*fa1f4cf8SSam McCall // New lines before and after chunks are dropped.
206*fa1f4cf8SSam McCall Paragraph P;
207*fa1f4cf8SSam McCall P.appendText(" \n foo\nbar\n ");
208*fa1f4cf8SSam McCall P.appendCode(" \n foo\nbar \n ");
209*fa1f4cf8SSam McCall EXPECT_EQ(P.asMarkdown(), "foo bar `foo bar`");
210*fa1f4cf8SSam McCall EXPECT_EQ(P.asPlainText(), "foo bar foo bar");
211*fa1f4cf8SSam McCall }
212*fa1f4cf8SSam McCall
TEST(Document,Separators)213*fa1f4cf8SSam McCall TEST(Document, Separators) {
214*fa1f4cf8SSam McCall Document D;
215*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
216*fa1f4cf8SSam McCall D.addCodeBlock("test");
217*fa1f4cf8SSam McCall D.addParagraph().appendText("bar");
218*fa1f4cf8SSam McCall
219*fa1f4cf8SSam McCall const char ExpectedMarkdown[] = R"md(foo
220*fa1f4cf8SSam McCall ```cpp
221*fa1f4cf8SSam McCall test
222*fa1f4cf8SSam McCall ```
223*fa1f4cf8SSam McCall bar)md";
224*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
225*fa1f4cf8SSam McCall
226*fa1f4cf8SSam McCall const char ExpectedText[] = R"pt(foo
227*fa1f4cf8SSam McCall
228*fa1f4cf8SSam McCall test
229*fa1f4cf8SSam McCall
230*fa1f4cf8SSam McCall bar)pt";
231*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), ExpectedText);
232*fa1f4cf8SSam McCall }
233*fa1f4cf8SSam McCall
TEST(Document,Ruler)234*fa1f4cf8SSam McCall TEST(Document, Ruler) {
235*fa1f4cf8SSam McCall Document D;
236*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
237*fa1f4cf8SSam McCall D.addRuler();
238*fa1f4cf8SSam McCall
239*fa1f4cf8SSam McCall // Ruler followed by paragraph.
240*fa1f4cf8SSam McCall D.addParagraph().appendText("bar");
241*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "foo \n\n---\nbar");
242*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), "foo\n\nbar");
243*fa1f4cf8SSam McCall
244*fa1f4cf8SSam McCall D = Document();
245*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
246*fa1f4cf8SSam McCall D.addRuler();
247*fa1f4cf8SSam McCall D.addCodeBlock("bar");
248*fa1f4cf8SSam McCall // Ruler followed by a codeblock.
249*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "foo \n\n---\n```cpp\nbar\n```");
250*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), "foo\n\nbar");
251*fa1f4cf8SSam McCall
252*fa1f4cf8SSam McCall // Ruler followed by another ruler
253*fa1f4cf8SSam McCall D = Document();
254*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
255*fa1f4cf8SSam McCall D.addRuler();
256*fa1f4cf8SSam McCall D.addRuler();
257*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "foo");
258*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), "foo");
259*fa1f4cf8SSam McCall
260*fa1f4cf8SSam McCall // Multiple rulers between blocks
261*fa1f4cf8SSam McCall D.addRuler();
262*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
263*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "foo \n\n---\nfoo");
264*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), "foo\n\nfoo");
265*fa1f4cf8SSam McCall }
266*fa1f4cf8SSam McCall
TEST(Document,Append)267*fa1f4cf8SSam McCall TEST(Document, Append) {
268*fa1f4cf8SSam McCall Document D;
269*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
270*fa1f4cf8SSam McCall D.addRuler();
271*fa1f4cf8SSam McCall Document E;
272*fa1f4cf8SSam McCall E.addRuler();
273*fa1f4cf8SSam McCall E.addParagraph().appendText("bar");
274*fa1f4cf8SSam McCall D.append(std::move(E));
275*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "foo \n\n---\nbar");
276*fa1f4cf8SSam McCall }
277*fa1f4cf8SSam McCall
TEST(Document,Heading)278*fa1f4cf8SSam McCall TEST(Document, Heading) {
279*fa1f4cf8SSam McCall Document D;
280*fa1f4cf8SSam McCall D.addHeading(1).appendText("foo");
281*fa1f4cf8SSam McCall D.addHeading(2).appendText("bar");
282*fa1f4cf8SSam McCall D.addParagraph().appendText("baz");
283*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), "# foo \n## bar \nbaz");
284*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), "foo\nbar\nbaz");
285*fa1f4cf8SSam McCall }
286*fa1f4cf8SSam McCall
TEST(CodeBlock,Render)287*fa1f4cf8SSam McCall TEST(CodeBlock, Render) {
288*fa1f4cf8SSam McCall Document D;
289*fa1f4cf8SSam McCall // Code blocks preserves any extra spaces.
290*fa1f4cf8SSam McCall D.addCodeBlock("foo\n bar\n baz");
291*fa1f4cf8SSam McCall
292*fa1f4cf8SSam McCall llvm::StringRef ExpectedMarkdown =
293*fa1f4cf8SSam McCall R"md(```cpp
294*fa1f4cf8SSam McCall foo
295*fa1f4cf8SSam McCall bar
296*fa1f4cf8SSam McCall baz
297*fa1f4cf8SSam McCall ```)md";
298*fa1f4cf8SSam McCall llvm::StringRef ExpectedPlainText =
299*fa1f4cf8SSam McCall R"pt(foo
300*fa1f4cf8SSam McCall bar
301*fa1f4cf8SSam McCall baz)pt";
302*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
303*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), ExpectedPlainText);
304*fa1f4cf8SSam McCall D.addCodeBlock("foo");
305*fa1f4cf8SSam McCall ExpectedMarkdown =
306*fa1f4cf8SSam McCall R"md(```cpp
307*fa1f4cf8SSam McCall foo
308*fa1f4cf8SSam McCall bar
309*fa1f4cf8SSam McCall baz
310*fa1f4cf8SSam McCall ```
311*fa1f4cf8SSam McCall ```cpp
312*fa1f4cf8SSam McCall foo
313*fa1f4cf8SSam McCall ```)md";
314*fa1f4cf8SSam McCall EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
315*fa1f4cf8SSam McCall ExpectedPlainText =
316*fa1f4cf8SSam McCall R"pt(foo
317*fa1f4cf8SSam McCall bar
318*fa1f4cf8SSam McCall baz
319*fa1f4cf8SSam McCall
320*fa1f4cf8SSam McCall foo)pt";
321*fa1f4cf8SSam McCall EXPECT_EQ(D.asPlainText(), ExpectedPlainText);
322*fa1f4cf8SSam McCall }
323*fa1f4cf8SSam McCall
TEST(BulletList,Render)324*fa1f4cf8SSam McCall TEST(BulletList, Render) {
325*fa1f4cf8SSam McCall BulletList L;
326*fa1f4cf8SSam McCall // Flat list
327*fa1f4cf8SSam McCall L.addItem().addParagraph().appendText("foo");
328*fa1f4cf8SSam McCall EXPECT_EQ(L.asMarkdown(), "- foo");
329*fa1f4cf8SSam McCall EXPECT_EQ(L.asPlainText(), "- foo");
330*fa1f4cf8SSam McCall
331*fa1f4cf8SSam McCall L.addItem().addParagraph().appendText("bar");
332*fa1f4cf8SSam McCall llvm::StringRef Expected = R"md(- foo
333*fa1f4cf8SSam McCall - bar)md";
334*fa1f4cf8SSam McCall EXPECT_EQ(L.asMarkdown(), Expected);
335*fa1f4cf8SSam McCall EXPECT_EQ(L.asPlainText(), Expected);
336*fa1f4cf8SSam McCall
337*fa1f4cf8SSam McCall // Nested list, with a single item.
338*fa1f4cf8SSam McCall Document &D = L.addItem();
339*fa1f4cf8SSam McCall // First item with foo\nbaz
340*fa1f4cf8SSam McCall D.addParagraph().appendText("foo");
341*fa1f4cf8SSam McCall D.addParagraph().appendText("baz");
342*fa1f4cf8SSam McCall
343*fa1f4cf8SSam McCall // Nest one level.
344*fa1f4cf8SSam McCall Document &Inner = D.addBulletList().addItem();
345*fa1f4cf8SSam McCall Inner.addParagraph().appendText("foo");
346*fa1f4cf8SSam McCall
347*fa1f4cf8SSam McCall // Nest one more level.
348*fa1f4cf8SSam McCall BulletList &InnerList = Inner.addBulletList();
349*fa1f4cf8SSam McCall // Single item, baz\nbaz
350*fa1f4cf8SSam McCall Document &DeepDoc = InnerList.addItem();
351*fa1f4cf8SSam McCall DeepDoc.addParagraph().appendText("baz");
352*fa1f4cf8SSam McCall DeepDoc.addParagraph().appendText("baz");
353*fa1f4cf8SSam McCall StringRef ExpectedMarkdown = R"md(- foo
354*fa1f4cf8SSam McCall - bar
355*fa1f4cf8SSam McCall - foo
356*fa1f4cf8SSam McCall baz
357*fa1f4cf8SSam McCall - foo
358*fa1f4cf8SSam McCall - baz
359*fa1f4cf8SSam McCall baz)md";
360*fa1f4cf8SSam McCall EXPECT_EQ(L.asMarkdown(), ExpectedMarkdown);
361*fa1f4cf8SSam McCall StringRef ExpectedPlainText = R"pt(- foo
362*fa1f4cf8SSam McCall - bar
363*fa1f4cf8SSam McCall - foo
364*fa1f4cf8SSam McCall baz
365*fa1f4cf8SSam McCall - foo
366*fa1f4cf8SSam McCall - baz
367*fa1f4cf8SSam McCall baz)pt";
368*fa1f4cf8SSam McCall EXPECT_EQ(L.asPlainText(), ExpectedPlainText);
369*fa1f4cf8SSam McCall
370*fa1f4cf8SSam McCall // Termination
371*fa1f4cf8SSam McCall Inner.addParagraph().appendText("after");
372*fa1f4cf8SSam McCall ExpectedMarkdown = R"md(- foo
373*fa1f4cf8SSam McCall - bar
374*fa1f4cf8SSam McCall - foo
375*fa1f4cf8SSam McCall baz
376*fa1f4cf8SSam McCall - foo
377*fa1f4cf8SSam McCall - baz
378*fa1f4cf8SSam McCall baz
379*fa1f4cf8SSam McCall
380*fa1f4cf8SSam McCall after)md";
381*fa1f4cf8SSam McCall EXPECT_EQ(L.asMarkdown(), ExpectedMarkdown);
382*fa1f4cf8SSam McCall ExpectedPlainText = R"pt(- foo
383*fa1f4cf8SSam McCall - bar
384*fa1f4cf8SSam McCall - foo
385*fa1f4cf8SSam McCall baz
386*fa1f4cf8SSam McCall - foo
387*fa1f4cf8SSam McCall - baz
388*fa1f4cf8SSam McCall baz
389*fa1f4cf8SSam McCall after)pt";
390*fa1f4cf8SSam McCall EXPECT_EQ(L.asPlainText(), ExpectedPlainText);
391*fa1f4cf8SSam McCall }
392*fa1f4cf8SSam McCall
393*fa1f4cf8SSam McCall } // namespace
394*fa1f4cf8SSam McCall } // namespace markup
395*fa1f4cf8SSam McCall } // namespace clangd
396*fa1f4cf8SSam McCall } // namespace clang
397