Compare commits
3 Commits
lint
...
feat/hover
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f397e95b34 | ||
|
|
2df42abd80 | ||
|
|
d55fb3d6d2 |
@@ -104,4 +104,6 @@ auto document_format(llvm::StringRef file,
|
||||
PositionEncoding encoding = PositionEncoding::UTF16)
|
||||
-> std::vector<protocol::TextEdit>;
|
||||
|
||||
auto format_code(llvm::StringRef file, llvm::StringRef code) -> std::string;
|
||||
|
||||
} // namespace clice::feature
|
||||
|
||||
@@ -66,4 +66,20 @@ auto document_format(llvm::StringRef file,
|
||||
return edits;
|
||||
}
|
||||
|
||||
auto format_code(llvm::StringRef file, llvm::StringRef code) -> std::string {
|
||||
auto style = clang::format::getStyle(clang::format::DefaultFormatStyle,
|
||||
file,
|
||||
clang::format::DefaultFallbackStyle,
|
||||
code);
|
||||
if(!style)
|
||||
return code.str();
|
||||
|
||||
auto replacements = clang::format::reformat(*style, code, {tooling::Range(0, code.size())});
|
||||
auto result = tooling::applyAllReplacements(code, replacements);
|
||||
if(!result)
|
||||
return code.str();
|
||||
|
||||
return llvm::StringRef(*result).trim().str();
|
||||
}
|
||||
|
||||
} // namespace clice::feature
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,6 +51,15 @@ std::vector<std::pair<llvm::StringRef, llvm::ArrayRef<DoxygenInfo::BlockCommandC
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::pair<llvm::StringRef, const DoxygenInfo::ParamCommandCommentContent*>>
|
||||
DoxygenInfo::get_param_command_comments() const {
|
||||
std::vector<std::pair<llvm::StringRef, const ParamCommandCommentContent*>> res;
|
||||
for(const auto& [name, info]: param_command_comments) {
|
||||
res.emplace_back(name, &info);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Process inline commands, we only interested in `\b` (bold), `\e` (italic) and `\c` (inline code)
|
||||
///
|
||||
/// \param line The line
|
||||
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
return doc_for_return;
|
||||
}
|
||||
|
||||
std::vector<std::pair<llvm::StringRef, const ParamCommandCommentContent*>>
|
||||
get_param_command_comments() const;
|
||||
|
||||
private:
|
||||
llvm::SmallDenseMap<llvm::StringRef, std::vector<BlockCommandCommentContent>>
|
||||
block_command_comments;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "support/structed_text.h"
|
||||
#include "support/markup.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
@@ -25,22 +25,23 @@ std::unique_ptr<Block> BulletList::clone() const {
|
||||
|
||||
void BulletList::render_markdown(llvm::raw_ostream& os) const {
|
||||
for(auto& item: items) {
|
||||
os << "- " << item.as_markdown() << '\n';
|
||||
auto content = item.as_markdown();
|
||||
os << "- ";
|
||||
for(size_t i = 0; i < content.size(); ++i) {
|
||||
os << content[i];
|
||||
if(content[i] == '\n' && i + 1 < content.size())
|
||||
os << " ";
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
StructedText& BulletList::add_item() {
|
||||
Markup& BulletList::add_item() {
|
||||
return items.emplace_back();
|
||||
}
|
||||
|
||||
// Clangd inserts escape char '\' before '*', '-' and other markdown markers
|
||||
// That causes markdown comments are escaped and cannot be rendered properly
|
||||
// on editors
|
||||
// We do nothing on it. All the left comments are regarded as markdown rather
|
||||
// than plain text
|
||||
void Paragraph::render_markdown(llvm::raw_ostream& os) const {
|
||||
bool need_space = false;
|
||||
bool has_chunks = false;
|
||||
for(auto& chunk: chunks) {
|
||||
if(chunk.space_ahead || need_space) {
|
||||
os << ' ';
|
||||
@@ -58,17 +59,15 @@ void Paragraph::render_markdown(llvm::raw_ostream& os) const {
|
||||
os << '`' << chunk.content << '`';
|
||||
break;
|
||||
}
|
||||
case Kind::Strikethough: {
|
||||
case Kind::Strikethrough: {
|
||||
os << "~~" << chunk.content << "~~";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Kind::PlainText
|
||||
os << chunk.content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
has_chunks = true;
|
||||
need_space = chunk.space_after;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +75,6 @@ void Paragraph::render_markdown(llvm::raw_ostream& os) const {
|
||||
Paragraph& Paragraph::append_text(std::string text, Kind kind) {
|
||||
if(kind == Kind::PlainText) {
|
||||
llvm::StringRef s{text};
|
||||
// s = s.trim(" \t\v\f\r");
|
||||
if(s.empty()) {
|
||||
return *this;
|
||||
}
|
||||
@@ -112,6 +110,10 @@ public:
|
||||
Paragraph::render_markdown(os);
|
||||
}
|
||||
|
||||
std::unique_ptr<Block> clone() const override {
|
||||
return std::make_unique<Heading>(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned level;
|
||||
};
|
||||
@@ -119,7 +121,7 @@ private:
|
||||
class Ruler : public Block {
|
||||
public:
|
||||
void render_markdown(llvm::raw_ostream& os) const override {
|
||||
os << "\n---\n";
|
||||
os << "---\n";
|
||||
}
|
||||
|
||||
bool is_ruler() const override {
|
||||
@@ -134,7 +136,10 @@ public:
|
||||
class CodeBlock : public Block {
|
||||
public:
|
||||
void render_markdown(llvm::raw_ostream& os) const override {
|
||||
os << "```" << lang << '\n' << code << "```\n";
|
||||
os << "```" << lang << '\n' << code;
|
||||
if(!code.empty() && code.back() != '\n')
|
||||
os << '\n';
|
||||
os << "```\n";
|
||||
}
|
||||
|
||||
std::unique_ptr<Block> clone() const override {
|
||||
@@ -160,60 +165,55 @@ static std::string render_blocks(llvm::ArrayRef<std::unique_ptr<Block>> blocks)
|
||||
blocks = blocks.drop_back(blocks.end() - last.base());
|
||||
|
||||
bool last_block_was_ruler = true;
|
||||
// render
|
||||
for(const auto& b: blocks) {
|
||||
if(b->is_ruler() && last_block_was_ruler) {
|
||||
continue;
|
||||
}
|
||||
last_block_was_ruler = b->is_ruler();
|
||||
b->render_markdown(os);
|
||||
os << "\n\n";
|
||||
}
|
||||
|
||||
// Get rid of redundant empty lines introduced in plaintext while imitating
|
||||
// padding in markdown.
|
||||
std::string adjusted_result;
|
||||
llvm::StringRef trimmed_text(os.str());
|
||||
trimmed_text = trimmed_text.trim(" \t\v\f\r");
|
||||
// Collapse runs of 3+ newlines down to 2 (one blank line max).
|
||||
std::string result;
|
||||
llvm::StringRef text(os.str());
|
||||
text = text.trim();
|
||||
|
||||
llvm::copy_if(trimmed_text,
|
||||
std::back_inserter(adjusted_result),
|
||||
[&trimmed_text](const char& C) {
|
||||
return !llvm::StringRef(trimmed_text.data(), &C - trimmed_text.data() + 1)
|
||||
// We allow at most two newlines.
|
||||
.ends_with("\n\n\n");
|
||||
});
|
||||
llvm::copy_if(text, std::back_inserter(result), [&text](const char& C) {
|
||||
return !llvm::StringRef(text.data(), &C - text.data() + 1).ends_with("\n\n\n");
|
||||
});
|
||||
|
||||
return adjusted_result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void StructedText::append(StructedText& other) {
|
||||
void Markup::append(Markup& other) {
|
||||
std::move(other.blocks.begin(), other.blocks.end(), std::back_inserter(blocks));
|
||||
}
|
||||
|
||||
Paragraph& StructedText::add_paragraph() {
|
||||
Paragraph& Markup::add_paragraph() {
|
||||
blocks.emplace_back(std::make_unique<Paragraph>());
|
||||
return *static_cast<Paragraph*>(blocks.back().get());
|
||||
}
|
||||
|
||||
void StructedText::add_ruler() {
|
||||
void Markup::add_ruler() {
|
||||
blocks.push_back(std::make_unique<Ruler>());
|
||||
}
|
||||
|
||||
void StructedText::add_code_block(std::string code, std::string lang) {
|
||||
void Markup::add_code_block(std::string code, std::string lang) {
|
||||
blocks.emplace_back(std::make_unique<CodeBlock>(std::move(code), std::move(lang)));
|
||||
}
|
||||
|
||||
Paragraph& StructedText::add_heading(unsigned level) {
|
||||
Paragraph& Markup::add_heading(unsigned level) {
|
||||
blocks.emplace_back(std::make_unique<Heading>(level));
|
||||
return *static_cast<Paragraph*>(blocks.back().get());
|
||||
}
|
||||
|
||||
BulletList& StructedText::add_bullet_list() {
|
||||
BulletList& Markup::add_bullet_list() {
|
||||
blocks.push_back(std::make_unique<BulletList>());
|
||||
return *static_cast<BulletList*>(blocks.back().get());
|
||||
}
|
||||
|
||||
std::string StructedText::as_markdown() const {
|
||||
std::string Markup::as_markdown() const {
|
||||
return render_blocks(blocks);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "llvm/Support/raw_os_ostream.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clice {
|
||||
|
||||
/// Base class of structed text
|
||||
/// Base class of markup blocks
|
||||
class Block {
|
||||
public:
|
||||
virtual void render_markdown(llvm::raw_ostream& os) const = 0;
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
Italic,
|
||||
PlainText,
|
||||
InlineCode,
|
||||
Strikethough,
|
||||
Strikethrough,
|
||||
};
|
||||
void render_markdown(llvm::raw_ostream& os) const override;
|
||||
|
||||
@@ -54,7 +54,7 @@ private:
|
||||
std::vector<Chunk> chunks;
|
||||
};
|
||||
|
||||
class StructedText;
|
||||
class Markup;
|
||||
|
||||
/// Allow nested structure
|
||||
class BulletList : public Block {
|
||||
@@ -65,23 +65,23 @@ public:
|
||||
|
||||
std::unique_ptr<Block> clone() const override;
|
||||
|
||||
StructedText& add_item();
|
||||
Markup& add_item();
|
||||
|
||||
private:
|
||||
std::vector<StructedText> items;
|
||||
std::vector<Markup> items;
|
||||
};
|
||||
|
||||
class StructedText {
|
||||
class Markup {
|
||||
public:
|
||||
StructedText() = default;
|
||||
Markup() = default;
|
||||
|
||||
StructedText(const StructedText& other) {
|
||||
Markup(const Markup& other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
StructedText(StructedText&&) = default;
|
||||
Markup(Markup&&) = default;
|
||||
|
||||
StructedText& operator=(const StructedText& other) {
|
||||
Markup& operator=(const Markup& other) {
|
||||
blocks.clear();
|
||||
for(auto& b: other.blocks) {
|
||||
blocks.push_back(b->clone());
|
||||
@@ -89,9 +89,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructedText& operator=(StructedText&&) = default;
|
||||
Markup& operator=(Markup&&) = default;
|
||||
|
||||
void append(StructedText& doc);
|
||||
void append(Markup& doc);
|
||||
|
||||
Paragraph& add_paragraph();
|
||||
|
||||
@@ -35,6 +35,18 @@ TEST_CASE(IncludeSort) {
|
||||
ASSERT_NE(edits.size(), 0U);
|
||||
}
|
||||
|
||||
TEST_CASE(FormatCode) {
|
||||
auto result = feature::format_code("main.cpp", "int add( int a,int b ){return a+b;}");
|
||||
EXPECT_NE(result.find("int add("), std::string::npos);
|
||||
EXPECT_EQ(result.find(" int a,int"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(FormatCodeIdempotent) {
|
||||
auto first = feature::format_code("main.cpp", "int add( int a,int b ){return a+b;}");
|
||||
auto second = feature::format_code("main.cpp", first);
|
||||
EXPECT_EQ(first, second);
|
||||
}
|
||||
|
||||
}; // TEST_SUITE(Formatting)
|
||||
|
||||
} // namespace
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
248
tests/unit/support/markup_tests.cpp
Normal file
248
tests/unit/support/markup_tests.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
#include "test/test.h"
|
||||
#include "support/markup.h"
|
||||
|
||||
namespace clice::testing {
|
||||
|
||||
namespace {
|
||||
|
||||
TEST_SUITE(Markup) {
|
||||
|
||||
TEST_CASE(EmptyDocument) {
|
||||
Markup st;
|
||||
EXPECT_EQ(st.as_markdown(), "");
|
||||
}
|
||||
|
||||
TEST_CASE(SingleParagraph) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("hello world");
|
||||
EXPECT_EQ(st.as_markdown(), "hello world");
|
||||
}
|
||||
|
||||
TEST_CASE(PlainTextSpacing) {
|
||||
Markup st;
|
||||
auto& p = st.add_paragraph();
|
||||
p.append_text("hello");
|
||||
p.append_text("world");
|
||||
EXPECT_EQ(st.as_markdown(), "hello world");
|
||||
}
|
||||
|
||||
TEST_CASE(InlineCode) {
|
||||
Markup st;
|
||||
auto& p = st.add_paragraph();
|
||||
p.append_text("Type:");
|
||||
p.append_text("int", Paragraph::Kind::InlineCode);
|
||||
EXPECT_EQ(st.as_markdown(), "Type: `int`");
|
||||
}
|
||||
|
||||
TEST_CASE(Bold) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("important", Paragraph::Kind::Bold);
|
||||
EXPECT_EQ(st.as_markdown(), "**important**");
|
||||
}
|
||||
|
||||
TEST_CASE(Italic) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("emphasis", Paragraph::Kind::Italic);
|
||||
EXPECT_EQ(st.as_markdown(), "*emphasis*");
|
||||
}
|
||||
|
||||
TEST_CASE(Strikethrough) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("removed", Paragraph::Kind::Strikethrough);
|
||||
EXPECT_EQ(st.as_markdown(), "~~removed~~");
|
||||
}
|
||||
|
||||
TEST_CASE(MixedInline) {
|
||||
Markup st;
|
||||
auto& p = st.add_paragraph();
|
||||
p.append_text("Returns:", Paragraph::Kind::Bold);
|
||||
p.append_text("the result");
|
||||
EXPECT_EQ(st.as_markdown(), "**Returns:** the result");
|
||||
}
|
||||
|
||||
TEST_CASE(ConsecutiveInlineCode) {
|
||||
Markup st;
|
||||
auto& p = st.add_paragraph();
|
||||
p.append_text("int", Paragraph::Kind::InlineCode);
|
||||
p.append_text("x", Paragraph::Kind::InlineCode);
|
||||
EXPECT_EQ(st.as_markdown(), "`int` `x`");
|
||||
}
|
||||
|
||||
TEST_CASE(Heading) {
|
||||
Markup st;
|
||||
st.add_heading(3).append_text("Title");
|
||||
EXPECT_EQ(st.as_markdown(), "### Title");
|
||||
}
|
||||
|
||||
TEST_CASE(HeadingWithInlineCode) {
|
||||
Markup st;
|
||||
auto& h = st.add_heading(2);
|
||||
h.append_text("function");
|
||||
h.append_text("foo", Paragraph::Kind::InlineCode);
|
||||
EXPECT_EQ(st.as_markdown(), "## function `foo`");
|
||||
}
|
||||
|
||||
TEST_CASE(Ruler) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("above");
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("below");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_NE(md.find("above"), std::string::npos);
|
||||
EXPECT_NE(md.find("---"), std::string::npos);
|
||||
EXPECT_NE(md.find("below"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(ConsecutiveRulers) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("text");
|
||||
st.add_ruler();
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("more");
|
||||
auto md = st.as_markdown();
|
||||
auto first = md.find("---");
|
||||
auto second = md.find("---", first + 3);
|
||||
EXPECT_EQ(second, std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(LeadingTrailingRulers) {
|
||||
Markup st;
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("content");
|
||||
st.add_ruler();
|
||||
EXPECT_EQ(st.as_markdown(), "content");
|
||||
}
|
||||
|
||||
TEST_CASE(CodeBlock) {
|
||||
Markup st;
|
||||
st.add_code_block("int x = 0;", "cpp");
|
||||
EXPECT_EQ(st.as_markdown(), "```cpp\nint x = 0;\n```");
|
||||
}
|
||||
|
||||
TEST_CASE(CodeBlockTrailingNewline) {
|
||||
Markup st;
|
||||
st.add_code_block("int x = 0;\n", "cpp");
|
||||
EXPECT_EQ(st.as_markdown(), "```cpp\nint x = 0;\n```");
|
||||
}
|
||||
|
||||
TEST_CASE(CodeBlockNoLang) {
|
||||
Markup st;
|
||||
st.add_code_block("hello");
|
||||
EXPECT_EQ(st.as_markdown(), "```\nhello\n```");
|
||||
}
|
||||
|
||||
TEST_CASE(BulletListSimple) {
|
||||
Markup st;
|
||||
auto& list = st.add_bullet_list();
|
||||
list.add_item().add_paragraph().append_text("one");
|
||||
list.add_item().add_paragraph().append_text("two");
|
||||
list.add_item().add_paragraph().append_text("three");
|
||||
EXPECT_EQ(st.as_markdown(), "- one\n- two\n- three");
|
||||
}
|
||||
|
||||
TEST_CASE(BulletListFormatted) {
|
||||
Markup st;
|
||||
auto& list = st.add_bullet_list();
|
||||
list.add_item().add_paragraph().append_text("bold", Paragraph::Kind::Bold);
|
||||
list.add_item().add_paragraph().append_text("code", Paragraph::Kind::InlineCode);
|
||||
EXPECT_EQ(st.as_markdown(), "- **bold**\n- `code`");
|
||||
}
|
||||
|
||||
TEST_CASE(BulletListMultiline) {
|
||||
Markup st;
|
||||
auto& list = st.add_bullet_list();
|
||||
list.add_item().add_paragraph().append_text("line1\nline2");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_NE(md.find("- line1\n line2"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(BlockSeparation) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("first");
|
||||
st.add_paragraph().append_text("second");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_NE(md.find("first\n"), std::string::npos);
|
||||
EXPECT_NE(md.find("second"), std::string::npos);
|
||||
EXPECT_EQ(md.find("firstsecond"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(ParagraphThenList) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("Parameters:");
|
||||
auto& list = st.add_bullet_list();
|
||||
list.add_item().add_paragraph().append_text("int x", Paragraph::Kind::InlineCode);
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_EQ(md.find("Parameters:- "), std::string::npos);
|
||||
EXPECT_EQ(md.find("Parameters:-"), std::string::npos);
|
||||
EXPECT_NE(md.find("Parameters:"), std::string::npos);
|
||||
EXPECT_NE(md.find("- `int x`"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(HeadingThenRuler) {
|
||||
Markup st;
|
||||
st.add_heading(3).append_text("title");
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("body");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_NE(md.find("### title\n"), std::string::npos);
|
||||
EXPECT_NE(md.find("---"), std::string::npos);
|
||||
EXPECT_NE(md.find("body"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(TripleNewlineCollapse) {
|
||||
Markup st;
|
||||
st.add_paragraph().append_text("a\n\n\n\nb");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_EQ(md.find("\n\n\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(ClonePreservesHeading) {
|
||||
Markup st;
|
||||
st.add_heading(2).append_text("Title");
|
||||
Markup copy = st;
|
||||
auto md = copy.as_markdown();
|
||||
EXPECT_NE(md.find("## Title"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(NewlineChar) {
|
||||
Markup st;
|
||||
auto& p = st.add_paragraph();
|
||||
p.append_text("line1");
|
||||
p.append_newline_char();
|
||||
p.append_text("line2");
|
||||
auto md = st.as_markdown();
|
||||
EXPECT_NE(md.find("line1"), std::string::npos);
|
||||
EXPECT_NE(md.find("line2"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_CASE(FullHoverLike) {
|
||||
Markup st;
|
||||
st.add_heading(3).append_text("function").append_text("add", Paragraph::Kind::InlineCode);
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("\xe2\x86\x92").append_text("int", Paragraph::Kind::InlineCode);
|
||||
st.add_paragraph().append_text("Parameters:");
|
||||
auto& params = st.add_bullet_list();
|
||||
params.add_item().add_paragraph().append_text("int a", Paragraph::Kind::InlineCode);
|
||||
params.add_item().add_paragraph().append_text("int b", Paragraph::Kind::InlineCode);
|
||||
st.add_ruler();
|
||||
st.add_code_block("int add(int a, int b);\n", "cpp");
|
||||
|
||||
auto md = st.as_markdown();
|
||||
|
||||
EXPECT_NE(md.find("### function `add`"), std::string::npos);
|
||||
EXPECT_NE(md.find("---"), std::string::npos);
|
||||
EXPECT_NE(md.find("\xe2\x86\x92 `int`"), std::string::npos);
|
||||
EXPECT_NE(md.find("Parameters:"), std::string::npos);
|
||||
EXPECT_NE(md.find("- `int a`"), std::string::npos);
|
||||
EXPECT_NE(md.find("- `int b`"), std::string::npos);
|
||||
EXPECT_NE(md.find("```cpp"), std::string::npos);
|
||||
|
||||
EXPECT_EQ(md.find("`int`Parameters"), std::string::npos);
|
||||
EXPECT_EQ(md.find("Parameters:- "), std::string::npos);
|
||||
}
|
||||
|
||||
}; // TEST_SUITE(Markup)
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace clice::testing
|
||||
@@ -1,121 +0,0 @@
|
||||
#include "test/test.h"
|
||||
#include "support/format.h"
|
||||
#include "support/structed_text.h"
|
||||
|
||||
namespace clice::testing {
|
||||
|
||||
namespace {
|
||||
|
||||
TEST_SUITE(StructedText) {
|
||||
|
||||
TEST_CASE(Paragraph) {
|
||||
constexpr const char* cb =
|
||||
R"c(// Without processing, recommended
|
||||
char *longestPalindrome_solv2(const char *s) {
|
||||
int len = strlen(s);
|
||||
int max_start = 0;
|
||||
int max_len = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
// j = 0, max_len is odd
|
||||
// j = 1, max_len is even
|
||||
for (int j = 0; j <= 1; ++j) {
|
||||
int l = i;
|
||||
int r = i + j;
|
||||
|
||||
// expand the range from center
|
||||
while (l >= 0 && r < len && s[l] == s[r]) {
|
||||
--l;
|
||||
++r;
|
||||
}
|
||||
|
||||
++l;
|
||||
--r;
|
||||
|
||||
if (max_len < r - l + 1) {
|
||||
max_len = r - l + 1;
|
||||
max_start = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
char *res = (char *)malloc((max_len + 1) * sizeof(char));
|
||||
memcpy(res, s + max_start, max_len);
|
||||
res[max_len] = '\0';
|
||||
return res;
|
||||
}
|
||||
)c";
|
||||
StructedText st;
|
||||
st.add_paragraph().append_text("CodeBlock Example:").append_newline_char();
|
||||
st.add_code_block(cb, "c");
|
||||
auto& para = st.add_paragraph();
|
||||
para.append_text("para1").append_newline_char();
|
||||
/// std::println("{}", st.as_markdown());
|
||||
}
|
||||
|
||||
TEST_CASE(BulletList) {
|
||||
StructedText st;
|
||||
st.add_bullet_list().add_item().add_paragraph().append_text("Item1");
|
||||
st.add_bullet_list().add_item().add_paragraph().append_text("Item2",
|
||||
Paragraph::Kind::InlineCode);
|
||||
st.add_bullet_list().add_item().add_paragraph().append_text("Item3", Paragraph::Kind::Bold);
|
||||
st.add_bullet_list().add_item().add_paragraph().append_text("Item4", Paragraph::Kind::Italic);
|
||||
st.add_bullet_list().add_item().add_paragraph().append_text("Item5",
|
||||
Paragraph::Kind::Strikethough);
|
||||
/// std::println("{}", st.as_markdown());
|
||||
}
|
||||
|
||||
TEST_CASE(FullText) {
|
||||
StructedText st;
|
||||
st.add_heading(3)
|
||||
.append_text("function")
|
||||
.append_text("test_bar", Paragraph::Kind::InlineCode)
|
||||
.append_newline_char()
|
||||
.append_text("Provided by:")
|
||||
.append_text("`foo/bar/baz.h`");
|
||||
st.add_ruler();
|
||||
st.add_paragraph()
|
||||
.append_text("→")
|
||||
.append_text("int", Paragraph::Kind::InlineCode)
|
||||
.append_newline_char();
|
||||
st.add_paragraph().append_text("Paramaters:", Paragraph::Kind::Bold).append_newline_char();
|
||||
auto& params = st.add_bullet_list();
|
||||
params.add_item()
|
||||
.add_paragraph()
|
||||
.append_text("int foo", Paragraph::Kind::InlineCode)
|
||||
.append_text("doc for foo\ndoc for foo line2");
|
||||
params.add_item()
|
||||
.add_paragraph()
|
||||
.append_text("char** bar", Paragraph::Kind::InlineCode)
|
||||
.append_text("doc for bar");
|
||||
params.add_item()
|
||||
.add_paragraph()
|
||||
.append_text("char** baz", Paragraph::Kind::InlineCode)
|
||||
.append_text("doc for baz");
|
||||
st.add_paragraph().append_text(R"md(
|
||||
brief block
|
||||
brief line2
|
||||
a b c d e f
|
||||
~~~~^
|
||||
This is *Italic* **Bold** ~~Striketough~~, `InlineCode`
|
||||
)md");
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("Details:", Paragraph::Kind::Bold).append_newline_char();
|
||||
auto& details = st.add_bullet_list();
|
||||
details.add_item().add_paragraph().append_text("Detail1: blah blah...");
|
||||
details.add_item().add_paragraph().append_text("Detail2: blah blah...\n Line2: ......");
|
||||
details.add_item().add_paragraph().append_text("Detail3: blah blah...");
|
||||
st.add_ruler();
|
||||
st.add_paragraph().append_text("Details:", Paragraph::Kind::Bold).append_newline_char();
|
||||
auto& warnings = st.add_bullet_list();
|
||||
warnings.add_item().add_paragraph().append_text("warnings1: blah blah...");
|
||||
warnings.add_item().add_paragraph().append_text("warnings2: blah blah...\n Line2: ......");
|
||||
warnings.add_item().add_paragraph().append_text("warnings3: blah blah...");
|
||||
st.add_ruler();
|
||||
st.add_code_block("int test_bar(int foo, char **bar, char **baz);\n", "cpp");
|
||||
/// std::println("{}", st.as_markdown());
|
||||
}
|
||||
|
||||
}; // TEST_SUITE(StructedText)
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace clice::testing
|
||||
Reference in New Issue
Block a user