mirror of https://github.com/kiwix/libkiwix.git
Moved TestData out of ServerTest.searchResults
Now that ServerTest.searchResults is in a separate cpp file, there are no reasons for hiding its test data definition inside the unit test function. The diff is much-much simpler if whitespace changes are ignored.
This commit is contained in:
parent
1c98b00128
commit
ddd639eaa1
|
@ -583,60 +583,58 @@ bool isSubSnippet(std::string subSnippet, const std::string& superSnippet)
|
||||||
#define RAYCHARLESZIMID "6f1d19d0-633f-087b-fb55-7ac324ff9baf"
|
#define RAYCHARLESZIMID "6f1d19d0-633f-087b-fb55-7ac324ff9baf"
|
||||||
#define EXAMPLEZIMID "5dc0b3af-5df2-0925-f0ca-d2bf75e78af6"
|
#define EXAMPLEZIMID "5dc0b3af-5df2-0925-f0ca-d2bf75e78af6"
|
||||||
|
|
||||||
TEST_F(ServerTest, searchResults)
|
struct TestData
|
||||||
{
|
{
|
||||||
struct TestData
|
struct PaginationEntry
|
||||||
{
|
{
|
||||||
struct PaginationEntry
|
std::string label;
|
||||||
{
|
size_t start;
|
||||||
std::string label;
|
bool selected;
|
||||||
size_t start;
|
};
|
||||||
bool selected;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string query;
|
std::string query;
|
||||||
int start;
|
int start;
|
||||||
size_t resultsPerPage;
|
size_t resultsPerPage;
|
||||||
size_t totalResultCount;
|
size_t totalResultCount;
|
||||||
size_t firstResultIndex;
|
size_t firstResultIndex;
|
||||||
std::vector<std::string> results;
|
std::vector<std::string> results;
|
||||||
std::vector<PaginationEntry> pagination;
|
std::vector<PaginationEntry> pagination;
|
||||||
|
|
||||||
static std::string makeUrl(const std::string& query, int start, size_t resultsPerPage)
|
static std::string makeUrl(const std::string& query, int start, size_t resultsPerPage)
|
||||||
{
|
{
|
||||||
std::string url = "/ROOT/search?" + query;
|
std::string url = "/ROOT/search?" + query;
|
||||||
|
|
||||||
if ( start >= 0 ) {
|
if ( start >= 0 ) {
|
||||||
url += "&start=" + to_string(start);
|
url += "&start=" + to_string(start);
|
||||||
}
|
|
||||||
|
|
||||||
if ( resultsPerPage != 0 ) {
|
|
||||||
url += "&pageLength=" + to_string(resultsPerPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getPattern() const
|
if ( resultsPerPage != 0 ) {
|
||||||
{
|
url += "&pageLength=" + to_string(resultsPerPage);
|
||||||
const std::string p = "pattern=";
|
|
||||||
const size_t i = query.find(p);
|
|
||||||
std::string r = query.substr(i + p.size());
|
|
||||||
return r.substr(0, r.find("&"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url() const
|
return url;
|
||||||
{
|
}
|
||||||
return makeUrl(query, start, resultsPerPage);
|
|
||||||
|
std::string getPattern() const
|
||||||
|
{
|
||||||
|
const std::string p = "pattern=";
|
||||||
|
const size_t i = query.find(p);
|
||||||
|
std::string r = query.substr(i + p.size());
|
||||||
|
return r.substr(0, r.find("&"));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url() const
|
||||||
|
{
|
||||||
|
return makeUrl(query, start, resultsPerPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expectedHeader() const
|
||||||
|
{
|
||||||
|
if ( totalResultCount == 0 ) {
|
||||||
|
return "\n No results were found for <b>\"" + getPattern() + "\"</b>";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string expectedHeader() const
|
std::string header = R"( Results
|
||||||
{
|
|
||||||
if ( totalResultCount == 0 ) {
|
|
||||||
return "\n No results were found for <b>\"" + getPattern() + "\"</b>";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string header = R"( Results
|
|
||||||
<b>
|
<b>
|
||||||
FIRSTRESULT-LASTRESULT
|
FIRSTRESULT-LASTRESULT
|
||||||
</b> of <b>
|
</b> of <b>
|
||||||
|
@ -646,127 +644,129 @@ TEST_F(ServerTest, searchResults)
|
||||||
</b>
|
</b>
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const size_t lastResultIndex = std::min(totalResultCount, firstResultIndex + results.size() - 1);
|
const size_t lastResultIndex = std::min(totalResultCount, firstResultIndex + results.size() - 1);
|
||||||
header = replace(header, "FIRSTRESULT", to_string(firstResultIndex));
|
header = replace(header, "FIRSTRESULT", to_string(firstResultIndex));
|
||||||
header = replace(header, "LASTRESULT", to_string(lastResultIndex));
|
header = replace(header, "LASTRESULT", to_string(lastResultIndex));
|
||||||
header = replace(header, "RESULTCOUNT", to_string(totalResultCount));
|
header = replace(header, "RESULTCOUNT", to_string(totalResultCount));
|
||||||
header = replace(header, "PATTERN", getPattern());
|
header = replace(header, "PATTERN", getPattern());
|
||||||
return header;
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expectedResultsString() const
|
||||||
|
{
|
||||||
|
if ( results.empty() ) {
|
||||||
|
return "\n ";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string expectedResultsString() const
|
std::string s;
|
||||||
{
|
for ( const auto& r : results ) {
|
||||||
if ( results.empty() ) {
|
s += "\n <li>";
|
||||||
return "\n ";
|
s += maskSnippetsInSearchResults(r);
|
||||||
|
s += " </li>";
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expectedFooter() const
|
||||||
|
{
|
||||||
|
if ( pagination.empty() ) {
|
||||||
|
return "\n ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "\n <ul>\n";
|
||||||
|
for ( const auto& p : pagination ) {
|
||||||
|
const auto url = makeUrl(query, p.start, resultsPerPage);
|
||||||
|
oss << " <li>\n";
|
||||||
|
oss << " <a ";
|
||||||
|
if ( p.selected ) {
|
||||||
|
oss << "class=\"selected\"";
|
||||||
}
|
}
|
||||||
|
oss << "\n href=\"" << url << "\">\n";
|
||||||
std::string s;
|
oss << " " << p.label << "\n";
|
||||||
for ( const auto& r : results ) {
|
oss << " </a>\n";
|
||||||
s += "\n <li>";
|
oss << " </li>\n";
|
||||||
s += maskSnippetsInSearchResults(r);
|
|
||||||
s += " </li>";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
oss << " </ul>";
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string expectedFooter() const
|
std::string expectedHtml() const
|
||||||
|
{
|
||||||
|
return makeSearchResultsHtml(
|
||||||
|
getPattern(),
|
||||||
|
expectedHeader(),
|
||||||
|
expectedResultsString(),
|
||||||
|
expectedFooter()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestContext testContext() const
|
||||||
|
{
|
||||||
|
return TestContext{ { "url", url() } };
|
||||||
|
}
|
||||||
|
|
||||||
|
void check(const std::string& html) const
|
||||||
|
{
|
||||||
|
EXPECT_EQ(maskSnippetsInSearchResults(html), expectedHtml())
|
||||||
|
<< testContext();
|
||||||
|
|
||||||
|
checkSnippets(extractSearchResultSnippets(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::vector<std::string> Snippets;
|
||||||
|
|
||||||
|
static Snippets extractSearchResultSnippets(const std::string& html)
|
||||||
|
{
|
||||||
|
Snippets snippets;
|
||||||
|
const std::regex snippetRegex("<cite>(.*)</cite>");
|
||||||
|
std::sregex_iterator snippetIt(html.begin(), html.end(), snippetRegex);
|
||||||
|
const std::sregex_iterator end;
|
||||||
|
for ( ; snippetIt != end; ++snippetIt)
|
||||||
{
|
{
|
||||||
if ( pagination.empty() ) {
|
const std::smatch snippetMatch = *snippetIt;
|
||||||
return "\n ";
|
snippets.push_back(snippetMatch[1].str());
|
||||||
}
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "\n <ul>\n";
|
|
||||||
for ( const auto& p : pagination ) {
|
|
||||||
const auto url = makeUrl(query, p.start, resultsPerPage);
|
|
||||||
oss << " <li>\n";
|
|
||||||
oss << " <a ";
|
|
||||||
if ( p.selected ) {
|
|
||||||
oss << "class=\"selected\"";
|
|
||||||
}
|
|
||||||
oss << "\n href=\"" << url << "\">\n";
|
|
||||||
oss << " " << p.label << "\n";
|
|
||||||
oss << " </a>\n";
|
|
||||||
oss << " </li>\n";
|
|
||||||
}
|
|
||||||
oss << " </ul>";
|
|
||||||
return oss.str();
|
|
||||||
}
|
}
|
||||||
|
return snippets;
|
||||||
|
}
|
||||||
|
|
||||||
std::string expectedHtml() const
|
void checkSnippets(const Snippets& snippets) const
|
||||||
|
{
|
||||||
|
ASSERT_EQ(snippets.size(), results.size());
|
||||||
|
for ( size_t i = 0; i < results.size(); ++i )
|
||||||
{
|
{
|
||||||
return makeSearchResultsHtml(
|
const auto& r = results[i];
|
||||||
getPattern(),
|
const auto expectedSnippet = extractSearchResultSnippets(r);
|
||||||
expectedHeader(),
|
ASSERT_EQ(1u, expectedSnippet.size())
|
||||||
expectedResultsString(),
|
<< "Multiple snippets in test data:"
|
||||||
expectedFooter()
|
<< "\n" << r;
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
TestContext testContext() const
|
if ( snippets[i] != expectedSnippet[0] ) {
|
||||||
{
|
std::cout << "Trying a weaker check for a mismatching snippet...\n";
|
||||||
return TestContext{ { "url", url() } };
|
checkMismatchingSnippet(snippets[i], expectedSnippet[0]);
|
||||||
}
|
|
||||||
|
|
||||||
void check(const std::string& html) const
|
|
||||||
{
|
|
||||||
EXPECT_EQ(maskSnippetsInSearchResults(html), expectedHtml())
|
|
||||||
<< testContext();
|
|
||||||
|
|
||||||
checkSnippets(extractSearchResultSnippets(html));
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef std::vector<std::string> Snippets;
|
|
||||||
|
|
||||||
static Snippets extractSearchResultSnippets(const std::string& html)
|
|
||||||
{
|
|
||||||
Snippets snippets;
|
|
||||||
const std::regex snippetRegex("<cite>(.*)</cite>");
|
|
||||||
std::sregex_iterator snippetIt(html.begin(), html.end(), snippetRegex);
|
|
||||||
const std::sregex_iterator end;
|
|
||||||
for ( ; snippetIt != end; ++snippetIt)
|
|
||||||
{
|
|
||||||
const std::smatch snippetMatch = *snippetIt;
|
|
||||||
snippets.push_back(snippetMatch[1].str());
|
|
||||||
}
|
|
||||||
return snippets;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkSnippets(const Snippets& snippets) const
|
|
||||||
{
|
|
||||||
ASSERT_EQ(snippets.size(), results.size());
|
|
||||||
for ( size_t i = 0; i < results.size(); ++i )
|
|
||||||
{
|
|
||||||
const auto& r = results[i];
|
|
||||||
const auto expectedSnippet = extractSearchResultSnippets(r);
|
|
||||||
ASSERT_EQ(1u, expectedSnippet.size())
|
|
||||||
<< "Multiple snippets in test data:"
|
|
||||||
<< "\n" << r;
|
|
||||||
|
|
||||||
if ( snippets[i] != expectedSnippet[0] ) {
|
|
||||||
std::cout << "Trying a weaker check for a mismatching snippet...\n";
|
|
||||||
checkMismatchingSnippet(snippets[i], expectedSnippet[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void checkMismatchingSnippet(std::string actual, std::string expected) const
|
void checkMismatchingSnippet(std::string actual, std::string expected) const
|
||||||
{
|
{
|
||||||
TestContext testContext{
|
TestContext testContext{
|
||||||
{ "url", url() },
|
{ "url", url() },
|
||||||
{ "actual snippet", actual },
|
{ "actual snippet", actual },
|
||||||
{ "expected snippet", expected }
|
{ "expected snippet", expected }
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(isValidSnippet(actual)) << testContext;
|
ASSERT_TRUE(isValidSnippet(actual)) << testContext;
|
||||||
ASSERT_TRUE(isValidSnippet(expected)) << testContext;
|
ASSERT_TRUE(isValidSnippet(expected)) << testContext;
|
||||||
|
|
||||||
if ( !isSubSnippet(actual, expected) ) {
|
if ( !isSubSnippet(actual, expected) ) {
|
||||||
EXPECT_EQ(actual, expected) << testContext;
|
EXPECT_EQ(actual, expected) << testContext;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(ServerTest, searchResults)
|
||||||
|
{
|
||||||
const TestData testData[] = {
|
const TestData testData[] = {
|
||||||
{
|
{
|
||||||
/* query */ "pattern=velomanyunkan&books.id=" RAYCHARLESZIMID,
|
/* query */ "pattern=velomanyunkan&books.id=" RAYCHARLESZIMID,
|
||||||
|
|
Loading…
Reference in New Issue