clang-tools  10.0.0
FormattedStringTests.cpp
Go to the documentation of this file.
1 //===-- FormattedStringTests.cpp ------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "FormattedString.h"
9 #include "clang/Basic/LLVM.h"
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/Support/raw_ostream.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 
15 namespace clang {
16 namespace clangd {
17 namespace markup {
18 namespace {
19 
20 TEST(Render, Escaping) {
21  // Check some ASCII punctuation
22  Paragraph P;
23  P.appendText("*!`");
24  EXPECT_EQ(P.asMarkdown(), "\\*\\!\\`");
25 
26  // Check all ASCII punctuation.
27  P = Paragraph();
28  std::string Punctuation = R"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt";
29  // Same text, with each character escaped.
30  std::string EscapedPunctuation;
31  EscapedPunctuation.reserve(2 * Punctuation.size());
32  for (char C : Punctuation)
33  EscapedPunctuation += std::string("\\") + C;
34  P.appendText(Punctuation);
35  EXPECT_EQ(P.asMarkdown(), EscapedPunctuation);
36 
37  // In code blocks we don't need to escape ASCII punctuation.
38  P = Paragraph();
39  P.appendCode("* foo !+ bar * baz");
40  EXPECT_EQ(P.asMarkdown(), "`* foo !+ bar * baz`");
41 
42  // But we have to escape the backticks.
43  P = Paragraph();
44  P.appendCode("foo`bar`baz");
45  EXPECT_EQ(P.asMarkdown(), "`foo``bar``baz`");
46 
47  // Inline code blocks starting or ending with backticks should add spaces.
48  P = Paragraph();
49  P.appendCode("`foo");
50  EXPECT_EQ(P.asMarkdown(), "` ``foo `");
51  P = Paragraph();
52  P.appendCode("foo`");
53  EXPECT_EQ(P.asMarkdown(), "` foo`` `");
54  P = Paragraph();
55  P.appendCode("`foo`");
56  EXPECT_EQ(P.asMarkdown(), "` ``foo`` `");
57 
58  // Code blocks might need more than 3 backticks.
59  Document D;
60  D.addCodeBlock("foobarbaz `\nqux");
61  EXPECT_EQ(D.asMarkdown(), "```cpp\n"
62  "foobarbaz `\nqux\n"
63  "```");
64  D = Document();
65  D.addCodeBlock("foobarbaz ``\nqux");
66  EXPECT_THAT(D.asMarkdown(), "```cpp\n"
67  "foobarbaz ``\nqux\n"
68  "```");
69  D = Document();
70  D.addCodeBlock("foobarbaz ```\nqux");
71  EXPECT_EQ(D.asMarkdown(), "````cpp\n"
72  "foobarbaz ```\nqux\n"
73  "````");
74  D = Document();
75  D.addCodeBlock("foobarbaz ` `` ``` ```` `\nqux");
76  EXPECT_EQ(D.asMarkdown(), "`````cpp\n"
77  "foobarbaz ` `` ``` ```` `\nqux\n"
78  "`````");
79 }
80 
81 TEST(Paragraph, SeparationOfChunks) {
82  // This test keeps appending contents to a single Paragraph and checks
83  // expected accumulated contents after each one.
84  // Purpose is to check for separation between different chunks.
85  Paragraph P;
86 
87  P.appendText("after");
88  EXPECT_EQ(P.asMarkdown(), "after");
89  EXPECT_EQ(P.asPlainText(), "after");
90 
91  P.appendCode("foobar");
92  EXPECT_EQ(P.asMarkdown(), "after `foobar`");
93  EXPECT_EQ(P.asPlainText(), "after foobar");
94 
95  P.appendText("bat");
96  EXPECT_EQ(P.asMarkdown(), "after `foobar` bat");
97  EXPECT_EQ(P.asPlainText(), "after foobar bat");
98 }
99 
100 TEST(Paragraph, ExtraSpaces) {
101  // Make sure spaces inside chunks are dropped.
102  Paragraph P;
103  P.appendText("foo\n \t baz");
104  P.appendCode(" bar\n");
105  EXPECT_EQ(P.asMarkdown(), "foo baz `bar`");
106  EXPECT_EQ(P.asPlainText(), "foo baz bar");
107 }
108 
109 TEST(Paragraph, NewLines) {
110  // New lines before and after chunks are dropped.
111  Paragraph P;
112  P.appendText(" \n foo\nbar\n ");
113  P.appendCode(" \n foo\nbar \n ");
114  EXPECT_EQ(P.asMarkdown(), "foo bar `foo bar`");
115  EXPECT_EQ(P.asPlainText(), "foo bar foo bar");
116 }
117 
118 TEST(Document, Separators) {
119  Document D;
120  D.addParagraph().appendText("foo");
121  D.addCodeBlock("test");
122  D.addParagraph().appendText("bar");
123 
124  const char ExpectedMarkdown[] = R"md(foo
125 ```cpp
126 test
127 ```
128 bar)md";
129  EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
130 
131  const char ExpectedText[] = R"pt(foo
132 
133 test
134 
135 bar)pt";
136  EXPECT_EQ(D.asPlainText(), ExpectedText);
137 }
138 
139 TEST(Document, Ruler) {
140  Document D;
141  D.addParagraph().appendText("foo");
142  D.addRuler();
143 
144  // Ruler followed by paragraph.
145  D.addParagraph().appendText("bar");
146  EXPECT_EQ(D.asMarkdown(), "foo \n\n---\nbar");
147  EXPECT_EQ(D.asPlainText(), "foo\n\nbar");
148 
149  D = Document();
150  D.addParagraph().appendText("foo");
151  D.addRuler();
152  D.addCodeBlock("bar");
153  // Ruler followed by a codeblock.
154  EXPECT_EQ(D.asMarkdown(), "foo \n\n---\n```cpp\nbar\n```");
155  EXPECT_EQ(D.asPlainText(), "foo\n\nbar");
156 
157  // Ruler followed by another ruler
158  D = Document();
159  D.addParagraph().appendText("foo");
160  D.addRuler();
161  D.addRuler();
162  EXPECT_EQ(D.asMarkdown(), "foo");
163  EXPECT_EQ(D.asPlainText(), "foo");
164 
165  // Multiple rulers between blocks
166  D.addRuler();
167  D.addParagraph().appendText("foo");
168  EXPECT_EQ(D.asMarkdown(), "foo \n\n---\nfoo");
169  EXPECT_EQ(D.asPlainText(), "foo\n\nfoo");
170 }
171 
172 TEST(Document, Heading) {
173  Document D;
174  D.addHeading(1).appendText("foo");
175  D.addHeading(2).appendText("bar");
176  D.addParagraph().appendText("baz");
177  EXPECT_EQ(D.asMarkdown(), "# foo \n## bar \nbaz");
178  EXPECT_EQ(D.asPlainText(), "foo\nbar\nbaz");
179 }
180 
181 TEST(CodeBlock, Render) {
182  Document D;
183  // Code blocks preserves any extra spaces.
184  D.addCodeBlock("foo\n bar\n baz");
185 
186  llvm::StringRef ExpectedMarkdown =
187  R"md(```cpp
188 foo
189  bar
190  baz
191 ```)md";
192  llvm::StringRef ExpectedPlainText =
193  R"pt(foo
194  bar
195  baz)pt";
196  EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
197  EXPECT_EQ(D.asPlainText(), ExpectedPlainText);
198  D.addCodeBlock("foo");
199  ExpectedMarkdown =
200  R"md(```cpp
201 foo
202  bar
203  baz
204 ```
205 ```cpp
206 foo
207 ```)md";
208  EXPECT_EQ(D.asMarkdown(), ExpectedMarkdown);
209  ExpectedPlainText =
210  R"pt(foo
211  bar
212  baz
213 
214 foo)pt";
215  EXPECT_EQ(D.asPlainText(), ExpectedPlainText);
216 }
217 
218 TEST(BulletList, Render) {
219  BulletList L;
220  // Flat list
221  L.addItem().addParagraph().appendText("foo");
222  EXPECT_EQ(L.asMarkdown(), "- foo");
223  EXPECT_EQ(L.asPlainText(), "- foo");
224 
225  L.addItem().addParagraph().appendText("bar");
226  llvm::StringRef Expected = R"md(- foo
227 - bar)md";
228  EXPECT_EQ(L.asMarkdown(), Expected);
229  EXPECT_EQ(L.asPlainText(), Expected);
230 
231  // Nested list, with a single item.
232  Document &D = L.addItem();
233  // First item with foo\nbaz
234  D.addParagraph().appendText("foo");
235  D.addParagraph().appendText("baz");
236 
237  // Nest one level.
238  Document &Inner = D.addBulletList().addItem();
239  Inner.addParagraph().appendText("foo");
240 
241  // Nest one more level.
242  BulletList &InnerList = Inner.addBulletList();
243  // Single item, baz\nbaz
244  Document &DeepDoc = InnerList.addItem();
245  DeepDoc.addParagraph().appendText("baz");
246  DeepDoc.addParagraph().appendText("baz");
247  StringRef ExpectedMarkdown = R"md(- foo
248 - bar
249 - foo
250  baz
251  - foo
252  - baz
253  baz)md";
254  EXPECT_EQ(L.asMarkdown(), ExpectedMarkdown);
255  StringRef ExpectedPlainText = R"pt(- foo
256 - bar
257 - foo
258  baz
259  - foo
260  - baz
261  baz)pt";
262  EXPECT_EQ(L.asPlainText(), ExpectedPlainText);
263 
264  // Termination
265  Inner.addParagraph().appendText("after");
266  ExpectedMarkdown = R"md(- foo
267 - bar
268 - foo
269  baz
270  - foo
271  - baz
272  baz
273 
274  after)md";
275  EXPECT_EQ(L.asMarkdown(), ExpectedMarkdown);
276  ExpectedPlainText = R"pt(- foo
277 - bar
278 - foo
279  baz
280  - foo
281  - baz
282  baz
283  after)pt";
284  EXPECT_EQ(L.asPlainText(), ExpectedPlainText);
285 }
286 
287 } // namespace
288 } // namespace markup
289 } // namespace clangd
290 } // namespace clang
TEST(BackgroundQueueTest, Priority)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< const char * > Expected