CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
737 lines
17 KiB
C++
737 lines
17 KiB
C++
//===-- SymbolDocumentationTests.cpp --------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "SymbolDocumentation.h"
|
|
|
|
#include "support/Markup.h"
|
|
#include "clang/Basic/CommentOptions.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
|
|
TEST(SymbolDocumentation, DetailedDocToMarkup) {
|
|
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{
|
|
"brief\n\nfoo bar",
|
|
"foo bar",
|
|
"foo bar",
|
|
"foo bar",
|
|
},
|
|
{
|
|
"brief\n\nfoo\nbar\n",
|
|
"foo\nbar",
|
|
"foo\nbar",
|
|
"foo bar",
|
|
},
|
|
{
|
|
"brief\n\nfoo\n\nbar\n",
|
|
"foo\n\nbar",
|
|
"foo\n\nbar",
|
|
"foo\n\nbar",
|
|
},
|
|
{
|
|
"brief\n\nfoo \\p bar baz",
|
|
"foo `bar` baz",
|
|
"foo `bar` baz",
|
|
"foo bar baz",
|
|
},
|
|
{
|
|
"brief\n\nfoo \\e bar baz",
|
|
"foo \\*bar\\* baz",
|
|
"foo *bar* baz",
|
|
"foo *bar* baz",
|
|
},
|
|
{
|
|
"brief\n\nfoo \\b bar baz",
|
|
"foo \\*\\*bar\\*\\* baz",
|
|
"foo **bar** baz",
|
|
"foo **bar** baz",
|
|
},
|
|
{
|
|
"brief\n\nfoo \\ref bar baz",
|
|
"foo \\*\\*\\\\ref\\*\\* `bar` baz",
|
|
"foo **\\ref** `bar` baz",
|
|
"foo **\\ref** bar baz",
|
|
},
|
|
{
|
|
"brief\n\nfoo @ref bar baz",
|
|
"foo \\*\\*@ref\\*\\* `bar` baz",
|
|
"foo **@ref** `bar` baz",
|
|
"foo **@ref** bar baz",
|
|
},
|
|
{
|
|
"\\brief this is a \\n\nbrief description",
|
|
"",
|
|
"",
|
|
"",
|
|
},
|
|
{
|
|
"brief\n\n\\throw exception foo",
|
|
"\\*\\*\\\\throw\\*\\* `exception` foo",
|
|
"**\\throw** `exception` foo",
|
|
"**\\throw** exception foo",
|
|
},
|
|
{
|
|
R"(\brief this is a brief description
|
|
|
|
\li item 1
|
|
\li item 2
|
|
\arg item 3)",
|
|
R"(- item 1
|
|
|
|
- item 2
|
|
|
|
- item 3)",
|
|
R"(- item 1
|
|
|
|
- item 2
|
|
|
|
- item 3)",
|
|
R"(- item 1
|
|
|
|
- item 2
|
|
|
|
- item 3)",
|
|
},
|
|
{
|
|
"brief\n\n\\defgroup mygroup this is a group\nthis is not a group "
|
|
"description",
|
|
"\\*\\*@defgroup\\*\\* `mygroup this is a group`\n\nthis is not a "
|
|
"group "
|
|
"description",
|
|
"**@defgroup** `mygroup this is a group`\n\nthis is not a group "
|
|
"description",
|
|
"**@defgroup** `mygroup this is a group`\n\nthis is not a group "
|
|
"description",
|
|
},
|
|
{
|
|
R"(brief
|
|
|
|
\verbatim
|
|
this is a
|
|
verbatim block containing
|
|
some verbatim text
|
|
\endverbatim)",
|
|
R"(\*\*@verbatim\*\*
|
|
|
|
```
|
|
this is a
|
|
verbatim block containing
|
|
some verbatim text
|
|
```
|
|
|
|
\*\*@endverbatim\*\*)",
|
|
R"(**@verbatim**
|
|
|
|
```
|
|
this is a
|
|
verbatim block containing
|
|
some verbatim text
|
|
```
|
|
|
|
**@endverbatim**)",
|
|
R"(**@verbatim**
|
|
|
|
this is a
|
|
verbatim block containing
|
|
some verbatim text
|
|
|
|
**@endverbatim**)",
|
|
},
|
|
{
|
|
"brief\n\n@param foo this is a parameter\n@param bar this is another "
|
|
"parameter",
|
|
"",
|
|
"",
|
|
"",
|
|
},
|
|
{
|
|
R"(@brief brief docs
|
|
|
|
@param foo this is a parameter
|
|
|
|
\brief another brief?
|
|
|
|
\details these are details
|
|
|
|
More description
|
|
documentation)",
|
|
R"(\*\*\\brief\*\* another brief?
|
|
|
|
these are details
|
|
|
|
More description
|
|
documentation)",
|
|
R"(**\brief** another brief?
|
|
|
|
these are details
|
|
|
|
More description
|
|
documentation)",
|
|
R"(**\brief** another brief?
|
|
|
|
these are details
|
|
|
|
More description documentation)",
|
|
},
|
|
{
|
|
R"(brief
|
|
|
|
<b>this is a bold text</b>
|
|
normal text<i>this is an italic text</i>
|
|
<code>this is a code block</code>)",
|
|
R"(\<b>this is a bold text\</b>
|
|
normal text\<i>this is an italic text\</i>
|
|
\<code>this is a code block\</code>)",
|
|
R"(\<b>this is a bold text\</b>
|
|
normal text\<i>this is an italic text\</i>
|
|
\<code>this is a code block\</code>)",
|
|
"<b>this is a bold text</b> normal text<i>this is an italic text</i> "
|
|
"<code>this is a code block</code>",
|
|
},
|
|
{"brief\n\n@note This is a note",
|
|
R"(\*\*Note:\*\*
|
|
This is a note)",
|
|
R"(**Note:**
|
|
This is a note)",
|
|
R"(**Note:**
|
|
This is a note)"},
|
|
{R"(brief
|
|
|
|
Paragraph 1
|
|
@note This is a note
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
\*\*Note:\*\*
|
|
This is a note
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
**Note:**
|
|
This is a note
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
**Note:**
|
|
This is a note
|
|
|
|
Paragraph 2)"},
|
|
{"brief\n\n@warning This is a warning",
|
|
R"(\*\*Warning:\*\*
|
|
This is a warning)",
|
|
R"(**Warning:**
|
|
This is a warning)",
|
|
R"(**Warning:**
|
|
This is a warning)"},
|
|
{R"(brief
|
|
|
|
Paragraph 1
|
|
@warning This is a warning
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
\*\*Warning:\*\*
|
|
This is a warning
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
**Warning:**
|
|
This is a warning
|
|
|
|
Paragraph 2)",
|
|
R"(Paragraph 1
|
|
|
|
**Warning:**
|
|
This is a warning
|
|
|
|
Paragraph 2)"},
|
|
{R"(@note this is not treated as brief
|
|
|
|
@brief this is the brief
|
|
|
|
Another paragraph)",
|
|
R"(\*\*Note:\*\*
|
|
this is not treated as brief
|
|
|
|
Another paragraph)",
|
|
R"(**Note:**
|
|
this is not treated as brief
|
|
|
|
Another paragraph)",
|
|
R"(**Note:**
|
|
this is not treated as brief
|
|
|
|
Another paragraph)"},
|
|
{R"(
|
|
@brief Some brief
|
|
)",
|
|
"", "", ""},
|
|
{R"(
|
|
Some brief
|
|
)",
|
|
"", "", ""},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.detailedDocToMarkup(Doc);
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
TEST(SymbolDocumentation, RetvalCommand) {
|
|
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{"@retval", "", "", ""},
|
|
{R"(@retval MyReturnVal
|
|
@retval MyOtherReturnVal)",
|
|
R"(- `MyReturnVal`
|
|
- `MyOtherReturnVal`)",
|
|
R"(- `MyReturnVal`
|
|
- `MyOtherReturnVal`)",
|
|
R"(- MyReturnVal
|
|
- MyOtherReturnVal)"},
|
|
{R"(@retval MyReturnVal if foo
|
|
@retval MyOtherReturnVal if bar)",
|
|
R"(- `MyReturnVal` - if foo
|
|
- `MyOtherReturnVal` - if bar)",
|
|
R"(- `MyReturnVal` - if foo
|
|
- `MyOtherReturnVal` - if bar)",
|
|
R"(- MyReturnVal - if foo
|
|
- MyOtherReturnVal - if bar)"},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.retvalsToMarkup(Doc);
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
TEST(SymbolDocumentation, DoxygenCodeBlocks) {
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{R"(@code
|
|
int code() { return 0; }
|
|
@endcode
|
|
@code{.cpp}
|
|
int code_lang() { return 0; }
|
|
@endcode
|
|
@code{.c++}
|
|
int code_lang_plus() { return 0; }
|
|
@endcode
|
|
@code{.py}
|
|
class A:
|
|
pass
|
|
@endcode
|
|
@code{nolang}
|
|
class B:
|
|
pass
|
|
@endcode)",
|
|
R"(```
|
|
int code() { return 0; }
|
|
```
|
|
|
|
```cpp
|
|
int code_lang() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int code_lang_plus() { return 0; }
|
|
```
|
|
|
|
```py
|
|
class A:
|
|
pass
|
|
```
|
|
|
|
```nolang
|
|
class B:
|
|
pass
|
|
```)",
|
|
R"(```
|
|
int code() { return 0; }
|
|
```
|
|
|
|
```cpp
|
|
int code_lang() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int code_lang_plus() { return 0; }
|
|
```
|
|
|
|
```py
|
|
class A:
|
|
pass
|
|
```
|
|
|
|
```nolang
|
|
class B:
|
|
pass
|
|
```)",
|
|
R"(int code() { return 0; }
|
|
|
|
int code_lang() { return 0; }
|
|
|
|
int code_lang_plus() { return 0; }
|
|
|
|
class A:
|
|
pass
|
|
|
|
class B:
|
|
pass)"},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.detailedDocToMarkup(Doc);
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
TEST(SymbolDocumentation, MarkdownCodeBlocks) {
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{R"(```
|
|
int backticks() { return 0; }
|
|
```
|
|
```cpp
|
|
int backticks_lang() { return 0; }
|
|
```
|
|
```c++
|
|
int backticks_lang_plus() { return 0; }
|
|
```
|
|
~~~
|
|
int tilde() { return 0; }
|
|
~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
int tilde_many() { return 0; }
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~{.c++}
|
|
int tilde_many_lang() { return 0; }
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
```py
|
|
class A:
|
|
pass
|
|
```
|
|
```python
|
|
class B:
|
|
pass
|
|
```
|
|
~~~{.python}
|
|
class C:
|
|
pass
|
|
~~~
|
|
)",
|
|
R"(```
|
|
int backticks() { return 0; }
|
|
```
|
|
|
|
```cpp
|
|
int backticks_lang() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int backticks_lang_plus() { return 0; }
|
|
```
|
|
|
|
```
|
|
int tilde() { return 0; }
|
|
```
|
|
|
|
```
|
|
int tilde_many() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int tilde_many_lang() { return 0; }
|
|
```
|
|
|
|
```py
|
|
class A:
|
|
pass
|
|
```
|
|
|
|
```python
|
|
class B:
|
|
pass
|
|
```
|
|
|
|
```python
|
|
class C:
|
|
pass
|
|
```)",
|
|
R"(```
|
|
int backticks() { return 0; }
|
|
```
|
|
|
|
```cpp
|
|
int backticks_lang() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int backticks_lang_plus() { return 0; }
|
|
```
|
|
|
|
```
|
|
int tilde() { return 0; }
|
|
```
|
|
|
|
```
|
|
int tilde_many() { return 0; }
|
|
```
|
|
|
|
```c++
|
|
int tilde_many_lang() { return 0; }
|
|
```
|
|
|
|
```py
|
|
class A:
|
|
pass
|
|
```
|
|
|
|
```python
|
|
class B:
|
|
pass
|
|
```
|
|
|
|
```python
|
|
class C:
|
|
pass
|
|
```)",
|
|
R"(int backticks() { return 0; }
|
|
|
|
int backticks_lang() { return 0; }
|
|
|
|
int backticks_lang_plus() { return 0; }
|
|
|
|
int tilde() { return 0; }
|
|
|
|
int tilde_many() { return 0; }
|
|
|
|
int tilde_many_lang() { return 0; }
|
|
|
|
class A:
|
|
pass
|
|
|
|
class B:
|
|
pass
|
|
|
|
class C:
|
|
pass)"},
|
|
{R"(```
|
|
// this code block is missing end backticks
|
|
|
|
)",
|
|
R"(```
|
|
// this code block is missing end backticks
|
|
```)",
|
|
R"(```
|
|
// this code block is missing end backticks
|
|
```)",
|
|
R"(// this code block is missing end backticks)"},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.detailedDocToMarkup(Doc);
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
TEST(SymbolDocumentation, MarkdownCodeBlocksSeparation) {
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{R"(@note Show that code blocks are correctly separated
|
|
```
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
```)",
|
|
R"(\*\*Note:\*\*
|
|
Show that code blocks are correctly separated
|
|
|
|
```
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
```)",
|
|
R"(**Note:**
|
|
Show that code blocks are correctly separated
|
|
|
|
```
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
```)",
|
|
R"(**Note:**
|
|
Show that code blocks are correctly separated
|
|
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; })"},
|
|
{R"(@note Show that code blocks are correctly separated
|
|
~~~~~~~~~
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
~~~~~~~~~)",
|
|
R"(\*\*Note:\*\*
|
|
Show that code blocks are correctly separated
|
|
|
|
```
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
```)",
|
|
R"(**Note:**
|
|
Show that code blocks are correctly separated
|
|
|
|
```
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; }
|
|
```)",
|
|
R"(**Note:**
|
|
Show that code blocks are correctly separated
|
|
|
|
/// Without the markdown preprocessing, this line and the line above would be part of the @note paragraph.
|
|
|
|
/// With preprocessing, the code block is correctly separated from the @note paragraph.
|
|
/// Also note that without preprocessing, all doxygen commands inside code blocks, like @p would be incorrectly interpreted.
|
|
int function() { return 0; })"},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.detailedDocToMarkup(Doc);
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
TEST(SymbolDocumentation, MarkdownCodeSpans) {
|
|
CommentOptions CommentOpts;
|
|
|
|
struct Case {
|
|
llvm::StringRef Documentation;
|
|
llvm::StringRef ExpectedRenderEscapedMarkdown;
|
|
llvm::StringRef ExpectedRenderMarkdown;
|
|
llvm::StringRef ExpectedRenderPlainText;
|
|
} Cases[] = {
|
|
{R"(`this is a code span with @p and \c inside`)",
|
|
R"(\`this is a code span with @p and \\c inside\`)",
|
|
R"(`this is a code span with @p and \c inside`)",
|
|
R"(`this is a code span with @p and \c inside`)"},
|
|
{R"(<escaped> `<not-escaped>`)", R"(\<escaped> \`\<not-escaped>\`)",
|
|
R"(\<escaped> `<not-escaped>`)", R"(<escaped> `<not-escaped>`)"},
|
|
{R"(<escaped> \`<escaped> doxygen commands not parsed @p, \c, @note, \warning \`)",
|
|
R"(\<escaped> \\\`\<escaped> doxygen commands not parsed @p, \\c, @note, \\warning \\\`)",
|
|
R"(\<escaped> \`\<escaped> doxygen commands not parsed @p, \c, @note, \warning \`)",
|
|
R"(<escaped> \`<escaped> doxygen commands not parsed @p, \c, @note, \warning \`)"},
|
|
{R"(`multi
|
|
line
|
|
\c span`)",
|
|
R"(\`multi
|
|
line
|
|
\\c span\`)",
|
|
R"(`multi
|
|
line
|
|
\c span`)",
|
|
R"(`multi line
|
|
\c span`)"},
|
|
};
|
|
for (const auto &C : Cases) {
|
|
markup::Document Doc;
|
|
SymbolDocCommentVisitor SymbolDoc(C.Documentation, CommentOpts);
|
|
|
|
SymbolDoc.briefToMarkup(Doc.addParagraph());
|
|
|
|
EXPECT_EQ(Doc.asPlainText(), C.ExpectedRenderPlainText);
|
|
EXPECT_EQ(Doc.asMarkdown(), C.ExpectedRenderMarkdown);
|
|
EXPECT_EQ(Doc.asEscapedMarkdown(), C.ExpectedRenderEscapedMarkdown);
|
|
}
|
|
}
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|