mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
test: updated tests for text formatting
Updated test data, changed additional functions and reimplemented test slots
This commit is contained in:
parent
6ffe4cd8d8
commit
d302e261d4
|
@ -20,59 +20,138 @@
|
|||
#include "src/chatlog/textformatter.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QVector>
|
||||
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
|
||||
using StringToString = QMap<QString, QString>;
|
||||
#define PAIR_FORMAT(input, output) {QStringLiteral(input), QStringLiteral(output)}
|
||||
|
||||
static const StringToString signsToTags{{"*", "b"}, {"**", "b"}, {"/", "i"}};
|
||||
using StringPair = QPair<QString, QString>;
|
||||
|
||||
static const StringToString
|
||||
commonWorkCases{// Basic
|
||||
{QStringLiteral("%1a%1"), QStringLiteral("<%2>%1a%1</%2>")},
|
||||
{QStringLiteral("%1aa%1"), QStringLiteral("<%2>%1aa%1</%2>")},
|
||||
{QStringLiteral("%1aaa%1"), QStringLiteral("<%2>%1aaa%1</%2>")},
|
||||
static const StringPair TAGS[] {
|
||||
PAIR_FORMAT("<b>", "</b>"),
|
||||
PAIR_FORMAT("<i>", "</i>"),
|
||||
PAIR_FORMAT("<u>", "</u>"),
|
||||
PAIR_FORMAT("<s>", "</s>"),
|
||||
PAIR_FORMAT("<font color=#595959><code>", "</code></font>"),
|
||||
};
|
||||
|
||||
// Additional text from both sides
|
||||
{QStringLiteral("aaa%1a%1"), QStringLiteral("aaa<%2>%1a%1</%2>")},
|
||||
{QStringLiteral("%1a%1aaa"), QStringLiteral("<%2>%1a%1</%2>aaa")},
|
||||
enum StyleType {
|
||||
BOLD,
|
||||
ITALIC,
|
||||
UNDERLINE,
|
||||
STRIKE,
|
||||
CODE,
|
||||
};
|
||||
|
||||
// Must allow same formatting more than one time, divided by two and more
|
||||
// symbols due to QRegularExpressionIterator
|
||||
{QStringLiteral("%1aaa%1 aaa %1aaa%1"),
|
||||
QStringLiteral("<%2>%1aaa%1</%2> aaa <%2>%1aaa%1</%2>")}};
|
||||
/**
|
||||
* @brief The MarkdownToTags struct maps sequence of markdown symbols to HTML tags according this
|
||||
* sequence
|
||||
*/
|
||||
struct MarkdownToTags
|
||||
{
|
||||
QString markdownSequence;
|
||||
StringPair htmlTags;
|
||||
};
|
||||
|
||||
static const QVector<QString>
|
||||
commonExceptions{// No whitespaces near to formatting symbols from both sides
|
||||
QStringLiteral("%1 a%1"), QStringLiteral("%1a %1"),
|
||||
static const QVector<MarkdownToTags> SINGLE_SIGN_MARKDOWN {
|
||||
{QStringLiteral("*"), TAGS[StyleType::BOLD]},
|
||||
{QStringLiteral("/"), TAGS[StyleType::ITALIC]},
|
||||
{QStringLiteral("_"), TAGS[StyleType::UNDERLINE]},
|
||||
{QStringLiteral("~"), TAGS[StyleType::STRIKE]},
|
||||
{QStringLiteral("`"), TAGS[StyleType::CODE]},
|
||||
};
|
||||
|
||||
// No newlines
|
||||
QStringLiteral("%1aa\n%1"),
|
||||
static const QVector<MarkdownToTags> DOUBLE_SIGN_MARKDOWN {
|
||||
{QStringLiteral("**"), TAGS[StyleType::BOLD]},
|
||||
{QStringLiteral("//"), TAGS[StyleType::ITALIC]},
|
||||
{QStringLiteral("__"), TAGS[StyleType::UNDERLINE]},
|
||||
{QStringLiteral("~~"), TAGS[StyleType::STRIKE]},
|
||||
};
|
||||
|
||||
// Only exact combinations of symbols must encapsulate formatting string
|
||||
QStringLiteral("%1%1aaa%1"), QStringLiteral("%1aaa%1%1")};
|
||||
static const QVector<MarkdownToTags> MULTI_SIGN_MARKDOWN {
|
||||
{QStringLiteral("```"), TAGS[StyleType::CODE]},
|
||||
};
|
||||
|
||||
static const StringToString singleSlash{
|
||||
// Must work with inserted tags
|
||||
{QStringLiteral("/aaa<b>aaa aaa</b>/"), QStringLiteral("<i>aaa<b>aaa aaa</b></i>")}};
|
||||
/**
|
||||
* @brief Creates single container from two
|
||||
*/
|
||||
template<class Container>
|
||||
static Container concat(const Container& first, const Container& last)
|
||||
{
|
||||
Container result;
|
||||
result.reserve(first.size() + last.size());
|
||||
result.append(first);
|
||||
result.append(last);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const StringToString doubleSign{
|
||||
{QStringLiteral("**aaa * aaa**"), QStringLiteral("<b>aaa * aaa</b>")}};
|
||||
static const QVector<MarkdownToTags> ALL_MARKDOWN_TYPES = concat(concat(SINGLE_SIGN_MARKDOWN,
|
||||
DOUBLE_SIGN_MARKDOWN),
|
||||
MULTI_SIGN_MARKDOWN);
|
||||
|
||||
static const StringToString mixedFormatting{
|
||||
static const QVector<MarkdownToTags> SINGLE_AND_DOUBLE_MARKDOWN = concat(SINGLE_SIGN_MARKDOWN,
|
||||
DOUBLE_SIGN_MARKDOWN);
|
||||
|
||||
// any markdown type must work for this data the same way
|
||||
static const QVector<StringPair> COMMON_WORK_CASES {
|
||||
PAIR_FORMAT("%1a%1", "%2%1a%1%3"),
|
||||
PAIR_FORMAT("%1aa%1", "%2%1aa%1%3"),
|
||||
PAIR_FORMAT("%1aaa%1", "%2%1aaa%1%3"),
|
||||
// Must allow same formatting more than one time
|
||||
PAIR_FORMAT("%1aaa%1 %1aaa%1", "%2%1aaa%1%3 %2%1aaa%1%3"),
|
||||
};
|
||||
|
||||
static const QVector<StringPair> SINGLE_SIGN_WORK_CASES {
|
||||
PAIR_FORMAT("a %1a%1", "a %2%1a%1%3"),
|
||||
PAIR_FORMAT("%1a%1 a", "%2%1a%1%3 a"),
|
||||
PAIR_FORMAT("a %1a%1 a", "a %2%1a%1%3 a"),
|
||||
// "Lazy" matching
|
||||
PAIR_FORMAT("%1aaa%1 aaa%1", "%2%1aaa%1%3 aaa%4"),
|
||||
};
|
||||
|
||||
// only double-sign markdown must work for this data
|
||||
static const QVector<StringPair> DOUBLE_SIGN_WORK_CASES {
|
||||
// Must apply formatting to strings which contain reserved symbols
|
||||
PAIR_FORMAT("%1aaa%2%1", "%3%1aaa%2%1%4"),
|
||||
PAIR_FORMAT("%1%2aaa%1", "%3%1%2aaa%1%4"),
|
||||
PAIR_FORMAT("%1aaa%2aaa%1", "%3%1aaa%2aaa%1%4"),
|
||||
PAIR_FORMAT("%1%2%2aaa%1", "%3%1%2%2aaa%1%4"),
|
||||
PAIR_FORMAT("%1aaa%2%2%1", "%3%1aaa%2%2%1%4"),
|
||||
PAIR_FORMAT("%1aaa%2%2aaa%1", "%3%1aaa%2%2aaa%1%4"),
|
||||
};
|
||||
|
||||
// any type of markdown must fail for this data
|
||||
static const QVector<QString> COMMON_EXCEPTIONS {
|
||||
// No empty formatting string
|
||||
QStringLiteral("%1%1"),
|
||||
// Formatting text must not start/end with whitespace symbols
|
||||
QStringLiteral("%1 %1"), QStringLiteral("%1 a%1"), QStringLiteral("%1a %1"),
|
||||
// Formatting string must be enclosed by whitespace symbols, newlines or message start/end
|
||||
QStringLiteral("a%1aa%1a"), QStringLiteral("%1aa%1a"), QStringLiteral("a%1aa%1"),
|
||||
QStringLiteral("a %1aa%1a"), QStringLiteral("a%1aa%1 a"),
|
||||
QStringLiteral("a\n%1aa%1a"), QStringLiteral("a%1aa%1\na"),
|
||||
};
|
||||
|
||||
static const QVector<QString> SINGLE_AND_DOUBLE_SIGN_EXCEPTIONS {
|
||||
// No newlines
|
||||
QStringLiteral("%1\n%1"), QStringLiteral("%1aa\n%1"), QStringLiteral("%1\naa%1"),
|
||||
QStringLiteral("%1aa\naa%1"),
|
||||
};
|
||||
|
||||
// only single-sign markdown must fail for this data
|
||||
static const QVector<QString> SINGLE_SIGN_EXCEPTIONS {
|
||||
// Reserved symbols within formatting string are disallowed
|
||||
QStringLiteral("%1aa%1a%1"), QStringLiteral("%1aa%1%1"), QStringLiteral("%1%1aa%1"),
|
||||
QStringLiteral("%1%1%1"),
|
||||
};
|
||||
|
||||
static const QVector<StringPair> MIXED_FORMATTING_SPECIAL_CASES {
|
||||
// Must allow mixed formatting if there is no tag overlap in result
|
||||
{QStringLiteral("aaa *aaa /aaa/ aaa*"), QStringLiteral("aaa <b>aaa <i>aaa</i> aaa</b>")},
|
||||
{QStringLiteral("aaa *aaa /aaa* aaa/"), QStringLiteral("aaa <b>aaa /aaa</b> aaa/")}};
|
||||
|
||||
static const StringToString multilineCode{
|
||||
// Must allow newlines
|
||||
{QStringLiteral("```int main()\n{\n return 0;\n}```"),
|
||||
QStringLiteral("<font color=#595959><code>int main()\n{\n return 0;\n}</code></font>")}};
|
||||
PAIR_FORMAT("aaa *aaa /aaa/ aaa*", "aaa <b>aaa <i>aaa</i> aaa</b>"),
|
||||
PAIR_FORMAT("aaa *aaa /aaa* aaa/", "aaa *aaa <i>aaa* aaa</i>"),
|
||||
};
|
||||
|
||||
static const StringToString urlCases{
|
||||
{QStringLiteral("https://github.com/qTox/qTox/issues/4233"),
|
||||
|
@ -116,6 +195,87 @@ static const StringToString urlCases{
|
|||
"<a href=\"http://www.site.com/part1/part2\">www.site.com/part1/part2</a>")},
|
||||
};
|
||||
|
||||
#undef PAIR_FORMAT
|
||||
|
||||
using MarkdownFunction = QString (*)(const QString&, bool);
|
||||
using InputProcessor = std::function<QString(const QString&, const MarkdownToTags&)>;
|
||||
using OutputProcessor = std::function<QString(const QString&, const MarkdownToTags&, bool)>;
|
||||
|
||||
/**
|
||||
* @brief Testing cases where markdown must work
|
||||
* @param applyMarkdown Function which is used to apply markdown
|
||||
* @param markdownToTags Which markdown type to test
|
||||
* @param testData Test data - string pairs "Source message - Message after formatting"
|
||||
* @param showSymbols True if it is supposed to leave markdown symbols after formatting, false
|
||||
* otherwise
|
||||
* @param processInput Test data is a template, which must be expanded with concrete markdown
|
||||
* symbols, everytime in different way. This function determines how to expand source message
|
||||
* depending on user need
|
||||
* @param processOutput Same as previous parameter but is applied to markdown output
|
||||
*/
|
||||
static void workCasesTest(MarkdownFunction applyMarkdown,
|
||||
const QVector<MarkdownToTags>& markdownToTags,
|
||||
const QVector<StringPair>& testData,
|
||||
bool showSymbols,
|
||||
InputProcessor processInput = nullptr,
|
||||
OutputProcessor processOutput = nullptr)
|
||||
{
|
||||
for (const MarkdownToTags& mtt: markdownToTags) {
|
||||
for (const StringPair& data: testData) {
|
||||
const QString input = processInput != nullptr ? processInput(data.first, mtt)
|
||||
: data.first;
|
||||
qDebug() << "Input:" << input;
|
||||
QString output = processOutput != nullptr ? processOutput(data.second, mtt, showSymbols)
|
||||
: data.second;
|
||||
qDebug() << "Expected output:" << output;
|
||||
QString result = applyMarkdown(input, showSymbols);
|
||||
qDebug() << "Observed output:" << result;
|
||||
QVERIFY(output == result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Testing cases where markdown must not to work
|
||||
* @param applyMarkdown Function which is used to apply markdown
|
||||
* @param markdownToTags Which markdown type to test
|
||||
* @param exceptions Collection of "source message - markdown result" pairs representing cases
|
||||
* where markdown must not to work
|
||||
* @param showSymbols True if it is supposed to leave markdown symbols after formatting, false
|
||||
* otherwise
|
||||
*/
|
||||
static void exceptionsTest(MarkdownFunction applyMarkdown,
|
||||
const QVector<MarkdownToTags>& markdownToTags,
|
||||
const QVector<QString>& exceptions,
|
||||
bool showSymbols)
|
||||
{
|
||||
for (const MarkdownToTags& mtt: markdownToTags) {
|
||||
for (const QString& e: exceptions) {
|
||||
QString processedException = e.arg(mtt.markdownSequence);
|
||||
qDebug() << "Exception: " << processedException;
|
||||
QVERIFY(processedException == applyMarkdown(processedException, showSymbols));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Testing some uncommon work cases
|
||||
* @param applyMarkdown Function which is used to apply markdown
|
||||
* @param pairs Collection of "source message - markdown result" pairs representing cases where
|
||||
* markdown must not to work
|
||||
*/
|
||||
static void specialCasesTest(MarkdownFunction applyMarkdown,
|
||||
const QVector<StringPair>& pairs)
|
||||
{
|
||||
for (const auto& p : pairs) {
|
||||
qDebug() << "Input:" << p.first;
|
||||
qDebug() << "Expected output:" << p.second;
|
||||
QString result = applyMarkdown(p.first, false);
|
||||
qDebug() << "Observed output:" << result;
|
||||
QVERIFY(p.second == result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Testing cases which are common for all types of formatting except multiline code
|
||||
* @param noSymbols True if it's not allowed to show formatting symbols
|
||||
|
@ -158,85 +318,168 @@ class TestTextFormatter : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void singleSignNoSymbolsTest();
|
||||
void slashNoSymbolsTest();
|
||||
void doubleSignNoSymbolsTest();
|
||||
void singleSignWithSymbolsTest();
|
||||
void slashWithSymbolsTest();
|
||||
void doubleSignWithSymbolsTest();
|
||||
void singleSignExceptionsTest();
|
||||
void slashExceptionsTest();
|
||||
void doubleSignExceptionsTest();
|
||||
void slashSpecialTest();
|
||||
void doubleSignSpecialTest();
|
||||
void mixedFormattingTest();
|
||||
void multilineCodeTest();
|
||||
void commonWorkCasesShowSymbols();
|
||||
void commonWorkCasesHideSymbols();
|
||||
void singleSignWorkCasesShowSymbols();
|
||||
void singleSignWorkCasesHideSymbols();
|
||||
void doubleSignWorkCasesShowSymbols();
|
||||
void doubleSignWorkCasesHideSymbols();
|
||||
void commonExceptionsShowSymbols();
|
||||
void commonExceptionsHideSymbols();
|
||||
void singleSignExceptionsShowSymbols();
|
||||
void singleSignExceptionsHideSymbols();
|
||||
void singleAndDoubleMarkdownExceptionsShowSymbols();
|
||||
void singleAndDoubleMarkdownExceptionsHideSymbols();
|
||||
void mixedFormattingSpecialCases();
|
||||
void urlTest();
|
||||
private:
|
||||
MarkdownFunction markdownFunction;
|
||||
};
|
||||
|
||||
void TestTextFormatter::singleSignNoSymbolsTest()
|
||||
static QString commonWorkCasesProcessInput(const QString& str, const MarkdownToTags& mtt)
|
||||
{
|
||||
commonTest(false, commonWorkCases, "*");
|
||||
return str.arg(mtt.markdownSequence);
|
||||
}
|
||||
|
||||
void TestTextFormatter::slashNoSymbolsTest()
|
||||
static QString commonWorkCasesProcessOutput(const QString& str,
|
||||
const MarkdownToTags& mtt,
|
||||
bool showSymbols)
|
||||
{
|
||||
commonTest(false, commonWorkCases, "/");
|
||||
const StringPair& tags = mtt.htmlTags;
|
||||
return str.arg(showSymbols ? mtt.markdownSequence : QString{}).arg(tags.first).arg(tags.second);
|
||||
}
|
||||
|
||||
void TestTextFormatter::doubleSignNoSymbolsTest()
|
||||
void TestTextFormatter::commonWorkCasesShowSymbols()
|
||||
{
|
||||
commonTest(false, commonWorkCases, "**");
|
||||
workCasesTest(markdownFunction,
|
||||
ALL_MARKDOWN_TYPES,
|
||||
COMMON_WORK_CASES,
|
||||
true,
|
||||
commonWorkCasesProcessInput,
|
||||
commonWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleSignWithSymbolsTest()
|
||||
void TestTextFormatter::commonWorkCasesHideSymbols()
|
||||
{
|
||||
commonTest(true, commonWorkCases, "*");
|
||||
workCasesTest(markdownFunction,
|
||||
ALL_MARKDOWN_TYPES,
|
||||
COMMON_WORK_CASES,
|
||||
false,
|
||||
commonWorkCasesProcessInput,
|
||||
commonWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::slashWithSymbolsTest()
|
||||
static QString singleSignWorkCasesProcessInput(const QString& str, const MarkdownToTags& mtt)
|
||||
{
|
||||
commonTest(true, commonWorkCases, "/");
|
||||
return str.arg(mtt.markdownSequence);
|
||||
}
|
||||
|
||||
void TestTextFormatter::doubleSignWithSymbolsTest()
|
||||
static QString singleSignWorkCasesProcessOutput(const QString& str,
|
||||
const MarkdownToTags& mtt,
|
||||
bool showSymbols)
|
||||
{
|
||||
commonTest(true, commonWorkCases, "**");
|
||||
const StringPair& tags = mtt.htmlTags;
|
||||
return str.arg(showSymbols ? mtt.markdownSequence : "")
|
||||
.arg(tags.first)
|
||||
.arg(tags.second)
|
||||
.arg(mtt.markdownSequence);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleSignExceptionsTest()
|
||||
void TestTextFormatter::singleSignWorkCasesShowSymbols()
|
||||
{
|
||||
commonExceptionsTest("*");
|
||||
workCasesTest(markdownFunction,
|
||||
SINGLE_SIGN_MARKDOWN,
|
||||
SINGLE_SIGN_WORK_CASES,
|
||||
true,
|
||||
singleSignWorkCasesProcessInput,
|
||||
singleSignWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::slashExceptionsTest()
|
||||
void TestTextFormatter::singleSignWorkCasesHideSymbols()
|
||||
{
|
||||
commonExceptionsTest("/");
|
||||
workCasesTest(markdownFunction,
|
||||
SINGLE_SIGN_MARKDOWN,
|
||||
SINGLE_SIGN_WORK_CASES,
|
||||
false,
|
||||
singleSignWorkCasesProcessInput,
|
||||
singleSignWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::doubleSignExceptionsTest()
|
||||
static QString doubleSignWorkCasesProcessInput(const QString& str, const MarkdownToTags& mtt)
|
||||
{
|
||||
commonExceptionsTest("**");
|
||||
return str.arg(mtt.markdownSequence).arg(mtt.markdownSequence[0]);
|
||||
}
|
||||
|
||||
void TestTextFormatter::slashSpecialTest()
|
||||
static QString doubleSignWorkCasesProcessOutput(const QString& str,
|
||||
const MarkdownToTags& mtt,
|
||||
bool showSymbols)
|
||||
{
|
||||
specialTest(singleSlash);
|
||||
const StringPair& tags = mtt.htmlTags;
|
||||
return str.arg(showSymbols ? mtt.markdownSequence : "")
|
||||
.arg(mtt.markdownSequence[0])
|
||||
.arg(tags.first)
|
||||
.arg(tags.second);
|
||||
}
|
||||
|
||||
void TestTextFormatter::doubleSignSpecialTest()
|
||||
void TestTextFormatter::doubleSignWorkCasesShowSymbols()
|
||||
{
|
||||
specialTest(doubleSign);
|
||||
workCasesTest(markdownFunction,
|
||||
DOUBLE_SIGN_MARKDOWN,
|
||||
DOUBLE_SIGN_WORK_CASES,
|
||||
true,
|
||||
doubleSignWorkCasesProcessInput,
|
||||
doubleSignWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::mixedFormattingTest()
|
||||
void TestTextFormatter::doubleSignWorkCasesHideSymbols()
|
||||
{
|
||||
specialTest(mixedFormatting);
|
||||
workCasesTest(markdownFunction,
|
||||
DOUBLE_SIGN_MARKDOWN,
|
||||
DOUBLE_SIGN_WORK_CASES,
|
||||
false,
|
||||
doubleSignWorkCasesProcessInput,
|
||||
doubleSignWorkCasesProcessOutput);
|
||||
}
|
||||
|
||||
void TestTextFormatter::multilineCodeTest()
|
||||
void TestTextFormatter::commonExceptionsShowSymbols()
|
||||
{
|
||||
specialTest(multilineCode);
|
||||
exceptionsTest(markdownFunction, ALL_MARKDOWN_TYPES, COMMON_EXCEPTIONS, true);
|
||||
}
|
||||
|
||||
void TestTextFormatter::commonExceptionsHideSymbols()
|
||||
{
|
||||
exceptionsTest(markdownFunction, ALL_MARKDOWN_TYPES, COMMON_EXCEPTIONS, false);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleSignExceptionsShowSymbols()
|
||||
{
|
||||
exceptionsTest(markdownFunction, SINGLE_SIGN_MARKDOWN, SINGLE_SIGN_EXCEPTIONS, true);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleSignExceptionsHideSymbols()
|
||||
{
|
||||
exceptionsTest(markdownFunction, SINGLE_SIGN_MARKDOWN, SINGLE_SIGN_EXCEPTIONS, false);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleAndDoubleMarkdownExceptionsShowSymbols()
|
||||
{
|
||||
exceptionsTest(markdownFunction,
|
||||
SINGLE_AND_DOUBLE_MARKDOWN,
|
||||
SINGLE_AND_DOUBLE_SIGN_EXCEPTIONS,
|
||||
true);
|
||||
}
|
||||
|
||||
void TestTextFormatter::singleAndDoubleMarkdownExceptionsHideSymbols()
|
||||
{
|
||||
exceptionsTest(markdownFunction,
|
||||
SINGLE_AND_DOUBLE_MARKDOWN,
|
||||
SINGLE_AND_DOUBLE_SIGN_EXCEPTIONS,
|
||||
false);
|
||||
}
|
||||
|
||||
void TestTextFormatter::mixedFormattingSpecialCases()
|
||||
{
|
||||
specialCasesTest(markdownFunction, MIXED_FORMATTING_SPECIAL_CASES);
|
||||
}
|
||||
|
||||
void TestTextFormatter::urlTest()
|
||||
|
|
Loading…
Reference in New Issue
Block a user