Compare commits

...

12 Commits

Author SHA1 Message Date
translatewiki.net
67611b4645 Localisation updates from https://translatewiki.net. 2026-01-15 13:07:46 +01:00
Veloman Yunkan
650f2d0027 Merge pull request #1255 from pippotadde/fix-empty-pattern-737
Fix: avoid error on empty search pattern (#1255)
2026-01-12 12:38:07 +04:00
Veloman Yunkan
b6a13d9b03 Minor cosmetic clean-up
Performed minor cosmetic clean-up in the ServerSearchTest.searchResults
unit-test:

1. Fixed alignment in test data
2. Moved the test point for search query "yellow submarine" out of the
   set of test points for search query "jazz"
2026-01-12 12:21:56 +04:00
pippotadde
86f125f8fb Fix: avoid error on empty search pattern 2026-01-12 12:18:53 +04:00
pippotadde
3cd8554733 Tools: Add kiwix::trim() helper and unit tests 2025-12-28 20:31:51 +01:00
Kelson
a10f0f287f Merge pull request #1262 from kiwix/carriage-return-after-error
Carriage return after error
2025-12-27 11:55:07 +01:00
Emmanuel Engelhart
cdf48fc987 Add carriage return after error 2025-12-27 11:40:28 +01:00
Veloman Yunkan
ba598bda9b Merge pull request #1259 from pippotadde/pr_yellow_tests
Testing of a search pattern containing a space
2025-12-23 21:36:58 +04:00
pippotadde
0ad2710884 Tests: add yellow submarine search case 2025-12-23 17:02:52 +01:00
pippotadde
ab31ed9ca5 Tests: deduplicate yellow search results 2025-12-23 17:01:13 +01:00
Veloman Yunkan
86cbc303cb Merge pull request #1258 from pippotadde/pr_viewerjs
Frontend: guard empty search input
2025-12-23 17:50:25 +04:00
pippotadde
19d9bc36c8 Frontend: guard empty search input 2025-12-23 14:30:42 +01:00
9 changed files with 100 additions and 136 deletions

View File

@@ -242,7 +242,7 @@ const std::string& Book::Illustration::getData() const
try {
data = download(url);
} catch(...) {
std::cerr << "Cannot download favicon from " << url;
std::cerr << "Cannot download favicon from " << url << std::endl;
}
}
}

View File

@@ -346,11 +346,6 @@ SearchInfo InternalServer::getSearchInfo(const RequestContext& request) const
geoQuery = GeoQuery(latitude, longitude, distance);
} catch(const std::out_of_range&) {}
catch(const std::invalid_argument&) {}
if (!geoQuery && pattern.empty()) {
throw Error(nonParameterizedMessage("no-query"));
}
return SearchInfo(pattern, geoQuery, bookIds.second, bookIds.first);
}
@@ -366,7 +361,7 @@ zim::Query SearchInfo::getZimQuery(bool verbose) const {
if (verbose) {
std::cout << "Performing query '" << pattern<< "'";
}
query.setQuery(pattern);
query.setQuery(kiwix::trim(pattern));
if (geoQuery) {
if (verbose) {
std::cout << " with geo query '" << geoQuery.distance << "&(" << geoQuery.latitude << ";" << geoQuery.longitude << ")'";

View File

@@ -29,7 +29,8 @@
#include <unicode/uniset.h>
#include <unicode/ustring.h>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <iomanip>
#include <regex>
@@ -450,3 +451,11 @@ std::string kiwix::getSlugifiedFileName(const std::string& filename)
#endif
return std::regex_replace(filename, reservedCharsReg, "_");
}
std::string kiwix::trim(const std::string& s)
{
auto is_space = [](unsigned char c) { return std::isspace(c); };
auto start = std::find_if_not(s.begin(), s.end(), is_space);
auto end = std::find_if_not(s.rbegin(), s.rend(), is_space).base();
return (start < end) ? std::string(start, end) : std::string();
}

View File

@@ -60,6 +60,8 @@ std::string escapeForJSON(const std::string& s, bool escapeQuote = true);
std::string urlEncode(const std::string& value);
std::string urlDecode(const std::string& value, bool component = false);
std::string trim(const std::string& s);
std::string join(const std::vector<std::string>& list, const std::string& sep);
std::string ucAll(const std::string& word);

View File

@@ -1,15 +1,17 @@
{
"@metadata": {
"authors": [
"Akmaie Ajam"
"Akmaie Ajam",
"Bennylin",
"Penyuwangi"
]
},
"name": "Bahasa Inggris",
"suggest-full-text-search": "mengandung '{{{SEARCH_TERMS}}}'...",
"no-such-book": "Tidak ada buku seperti ini: {{BOOK_NAME}}",
"too-many-books": "Terlalu banyak buku yang diminta ({{NB_BOOKS}}) dimana batasnya adalah {{LIMIT}}",
"too-many-books": "Terlalu banyak buku yang diminta ({{NB_BOOKS}}), batasnya adalah {{LIMIT}}",
"no-book-found": "Tidak ada buku yang sesuai kriteria yang dipilih",
"url-not-found": "URL yang diminta \"{{url}}\" tidak ditemukan di server ini.",
"url-not-found": "URL yang diminta \"{{url}}\" tidak ditemukan di peladen ini.",
"suggest-search": "Lakukan pencarian teks lengkap untuk <a href=\"{{{SEARCH_URL}}}\">{{PATTERN}}</a>",
"random-article-failure": "Waduh! Gagal memilih artikel acak :(",
"invalid-raw-data-type": "{{DATATYPE}} bukan permintaan yang sah untuk konten mentah.",
@@ -21,9 +23,9 @@
"400-page-heading": "Permintaan tidak sah",
"404-page-title": "Konten tidak ditemukan",
"404-page-heading": "Tidak Ditemukan",
"500-page-title": "Kesalahan Server Internal",
"500-page-heading": "Kesalahan Server Internal",
"500-page-text": "Terjadi kesalahan server internal. Kami mohon maaf atas hal ini :/",
"500-page-title": "Galat Peladen Internal",
"500-page-heading": "Aduh. Halaman tidak bekerja.",
"500-page-text": "Jalur yang diminta tidak dapat diantar dengan benar:",
"fulltext-search-unavailable": "Pencarian teks lengkap tidak tersedia",
"no-search-results": "Mesin pencari teks lengkap tidak tersedia untuk konten ini.",
"search-results-page-title": "Pencarian: {{SEARCH_PATTERN}}",
@@ -52,10 +54,10 @@
"torrent-download-link-text": "BitTorrent",
"torrent-download-alt-text": "Unduh melalui BitTorrent",
"library-opds-feed-all-entries": "Umpan OPDS Perpustakaan - Semua entri",
"filter-by-tag": "Saring berdasarkan tag \"{{{TAG}}}\"",
"stop-filtering-by-tag": "Berhenti penyaringan berdasarkan tag \"{{{TAG}}}\"",
"library-opds-feed-parameterised": "Umpan OPDS Perpustakaan - entri yang cocok dengan {{#LANG}}\nBahasa: {{LANG}} {{/LANG}}{{#CATEGORY}}\nKategori: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nTag: {{TAG}} {{/TAG}}{{#Q}}\nKueri: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Selamat datang di Server Kiwix",
"filter-by-tag": "Saring berdasarkan tanda \"{{{TAG}}}\"",
"stop-filtering-by-tag": "Hentikan penyaringan berdasarkan tanda \"{{{TAG}}}\"",
"library-opds-feed-parameterised": "Umpan OPDS Perpustakaan - entri yang cocok dengan {{#LANG}}\nBahasa: {{LANG}} {{/LANG}}{{#CATEGORY}}\nKategori: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nTanda: {{TAG}} {{/TAG}}{{#Q}}\nKueri: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Selamat datang di Peladen Kiwix",
"download-links-heading": "Tautan unduhan untuk <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Unduh buku",
"preview-book": "Pratayang",

View File

@@ -83,6 +83,7 @@ function quasiUriEncode(s, specialSymbols) {
function performSearch() {
const searchbox = document.getElementById('kiwixsearchbox');
if (!searchbox.value.trim()) { return;}
const q = encodeURIComponent(searchbox.value);
gotoUrl(`/search?books.name=${currentBook}&pattern=${q}&userlang=${viewerState.uiLanguage}`);
}

View File

@@ -77,7 +77,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=42e90cb9" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=00e0fdf3" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=6192cae1" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
@@ -338,7 +338,7 @@ R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=b4e29e
<script type="text/javascript" src="./skin/polyfills.js?cacheid=a0e0343d"></script>
<script type="module" src="./skin/i18n.js?cacheid=e9a10ac1" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=08955948" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=00e0fdf3" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=6192cae1" defer></script>
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
@@ -438,7 +438,6 @@ TEST_F(ServerTest, CacheIdsOfStaticResourcesMatchTheSha1HashOfResourceContent)
const char* urls400[] = {
"/ROOT%23%3F/search",
"/ROOT%23%3F/search?content=zimfile",
"/ROOT%23%3F/search?content=non-existing-book&pattern=asdfqwerty",
"/ROOT%23%3F/search?content=non-existing-book&pattern=asd<qwerty",
"/ROOT%23%3F/search?books.name=non-exsitent-book&pattern=asd<qwerty",
@@ -1052,17 +1051,6 @@ TEST_F(ServerTest, Http400HtmlError)
<p>
Too many books requested (4) where limit is 3
</p>
)" },
{ /* url */ "/ROOT%23%3F/search?content=zimfile",
expected_kiwix_response_data==R"({ "CSS_URL" : false, "PAGE_HEADING" : { "msgid" : "400-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "400-page-title", "params" : { } }, "details" : [ { "p" : { "msgid" : "invalid-request", "params" : { "url" : "/ROOT%23%3F/search?content=zimfile" } } }, { "p" : { "msgid" : "no-query", "params" : { } } } ] })" &&
expected_body==R"(
<h1>Invalid request</h1>
<p>
The requested URL "/ROOT%23%3F/search?content=zimfile" is not a valid request.
</p>
<p>
No query provided.
</p>
)" },
{ /* url */ "/ROOT%23%3F/search?content=non-existing-book&pattern=asdfqwerty",
expected_kiwix_response_data==R"({ "CSS_URL" : false, "PAGE_HEADING" : { "msgid" : "400-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "400-page-title", "params" : { } }, "details" : [ { "p" : { "msgid" : "invalid-request", "params" : { "url" : "/ROOT%23%3F/search?content=non-existing-book&pattern=asdfqwerty" } } }, { "p" : { "msgid" : "no-such-book", "params" : { "BOOK_NAME" : "non-existing-book" } } } ] })" &&
@@ -1085,19 +1073,6 @@ TEST_F(ServerTest, Http400HtmlError)
<p>
No such book: non-existing-book
</p>
)" },
// There is a flaw in our way to handle query string, we cannot differenciate
// between `pattern` and `pattern=`
{ /* url */ "/ROOT%23%3F/search?books.filter.lang=eng&pattern",
expected_kiwix_response_data==R"({ "CSS_URL" : false, "PAGE_HEADING" : { "msgid" : "400-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "400-page-title", "params" : { } }, "details" : [ { "p" : { "msgid" : "invalid-request", "params" : { "url" : "/ROOT%23%3F/search?books.filter.lang=eng&pattern" } } }, { "p" : { "msgid" : "no-query", "params" : { } } } ] })" &&
expected_body==R"(
<h1>Invalid request</h1>
<p>
The requested URL "/ROOT%23%3F/search?books.filter.lang=eng&pattern" is not a valid request.
</p>
<p>
No query provided.
</p>
)" },
{ /* url */ "/ROOT%23%3F/search?pattern=foo",
expected_kiwix_response_data==R"({ "CSS_URL" : false, "PAGE_HEADING" : { "msgid" : "400-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "400-page-title", "params" : { } }, "details" : [ { "p" : { "msgid" : "invalid-request", "params" : { "url" : "/ROOT%23%3F/search?pattern=foo" } } }, { "p" : { "msgid" : "too-many-books", "params" : { "LIMIT" : "3", "NB_BOOKS" : "4" } } } ] })" &&
@@ -1110,20 +1085,6 @@ TEST_F(ServerTest, Http400HtmlError)
Too many books requested (4) where limit is 3
</p>
)" },
// Testing of translation
{ /* url */ "/ROOT%23%3F/search?content=zimfile&userlang=test",
expected_page_title=="[I18N TESTING] Invalid request ($400 fine must be paid)" &&
expected_kiwix_response_data==R"({ "CSS_URL" : false, "PAGE_HEADING" : { "msgid" : "400-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "400-page-title", "params" : { } }, "details" : [ { "p" : { "msgid" : "invalid-request", "params" : { "url" : "/ROOT%23%3F/search?content=zimfile&userlang=test" } } }, { "p" : { "msgid" : "no-query", "params" : { } } } ] })" &&
expected_body==R"(
<h1>[I18N TESTING] -400 karma for an invalid request</h1>
<p>
[I18N TESTING] Invalid URL: "/ROOT%23%3F/search?content=zimfile&userlang=test"
</p>
<p>
[I18N TESTING] Kiwix can read your thoughts but it is against GDPR. Please provide your query explicitly.
</p>
)" },
};
for ( const auto& t : testData ) {
@@ -1154,20 +1115,6 @@ TEST_F(ServerTest, HttpXmlError)
};
const std::vector<TestData> testData{
{ /* url */ "/ROOT%23%3F/search?format=xml",
/* HTTP status code */ 400,
/* expected response XML */ R"(
<error>Invalid request</error>
<detail>The requested URL "/ROOT%23%3F/search?format=xml" is not a valid request.</detail>
<detail>Too many books requested (4) where limit is 3</detail>
)" },
{ /* url */ "/ROOT%23%3F/search?format=xml&content=zimfile",
/* HTTP status code */ 400,
/* expected response XML */ R"(
<error>Invalid request</error>
<detail>The requested URL "/ROOT%23%3F/search?format=xml&content=zimfile" is not a valid request.</detail>
<detail>No query provided.</detail>
)" },
{ /* url */ "/ROOT%23%3F/search?format=xml&content=non-existing-book&pattern=asdfqwerty",
/* HTTP status code */ 400,
/* expected response XML */ R"(
@@ -1181,15 +1128,6 @@ TEST_F(ServerTest, HttpXmlError)
<error>Invalid request</error>
<detail>The requested URL "/ROOT%23%3F/search?format=xml&content=non-existing-book&pattern=a%22%3Cscript%20foo%3E" is not a valid request.</detail>
<detail>No such book: non-existing-book</detail>
)" },
// There is a flaw in our way to handle query string, we cannot differenciate
// between `pattern` and `pattern=`
{ /* url */ "/ROOT%23%3F/search?format=xml&books.filter.lang=eng&pattern",
/* HTTP status code */ 400,
/* expected response XML */ R"(
<error>Invalid request</error>
<detail>The requested URL "/ROOT%23%3F/search?format=xml&books.filter.lang=eng&pattern" is not a valid request.</detail>
<detail>No query provided.</detail>
)" },
{ /* url */ "/ROOT%23%3F/search?format=xml&pattern=foo",
/* HTTP status code */ 400,
@@ -2363,3 +2301,8 @@ R"(const viewerSettings = {
)");
}
}
TEST_F(ServerTest, EmptyPatternSearchDoesNotError)
{
EXPECT_EQ(200, zfs1_->GET("/ROOT%23%3F/search?content=zimfile")->status);
}

View File

@@ -689,6 +689,24 @@ bool isSubSnippet(std::string subSnippet, const std::string& superSnippet)
#define RAYCHARLESZIMID "6f1d19d0-633f-087b-fb55-7ac324ff9baf"
#define EXAMPLEZIMID "5dc0b3af-5df2-0925-f0ca-d2bf75e78af6"
const std::vector<SearchResult> YELLOW_SEARCH_RESULTS = {
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/Eleanor_Rigby",
/*title*/ "Eleanor Rigby",
/*snippet*/ R"SNIPPET(...-side "<b>Yellow</b> Submarine" (double A-side) Released 5)SNIPPET" "\xC2\xA0" "August" "\xC2\xA0" "1966" "\xC2\xA0" R"SNIPPET((1966-08-05) Format 7-inch single Recorded 2829 April &amp; 6 June 1966 Studio EMI, London Genre Baroque pop, art rock Length 2:08 Label Parlophone (UK), Capitol (US) Songwriter(s) LennonMcCartney Producer(s) George Martin The Beatles singles chronology "Paperback Writer" (1966) "Eleanor Rigby" / "<b>Yellow</b> Submarine" (1966) "Strawberry Fields Forever" / "Penny Lane" (1967) Music video "Eleanor Rigby" on YouTube The song continued the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "201"
),
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/If_You_Go_Away",
/*title*/ "If You Go Away",
/*snippet*/ R"SNIPPET(...standard and has been recorded by many artists, including Greta Keller, for whom some say McKuen wrote the lyrics. "If You Go Away" Single by Damita Jo from the album If You Go Away B-side "<b>Yellow</b> Days" Released 1966 Genre Jazz Length 3:49 Label Epic Records Songwriter(s) Jacques Brel, Rod McKuen Producer(s) Bob Morgan Damita Jo singles chronology "Gotta Travel On" (1965) "If You Go Away" (1966) "Walk Away" (1967) Damita Jo reached #10 on the Adult Contemporary chart and #68 on the Billboard Hot 100 in 1966 for her version of the song. Terry Jacks recorded a version of the song which was released as a single in 1974 and reached #29 on the Adult Contemporary chart, #68 on the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "204"
)
};
struct TestData
{
struct PaginationEntry
@@ -935,6 +953,26 @@ struct TestData
TEST(ServerSearchTest, searchResults)
{
const TestData testData[] = {
{
/* query */ "pattern=&books.id=" RAYCHARLESZIMID,
/* start */ -1,
/* resultsPerPage */ 0,
/* totalResultCount */ 0,
/* firstResultIndex */ 0,
/* results */ {},
/* pagination */ {}
},
{
/* query */ "pattern=%20&books.id=" RAYCHARLESZIMID,
/* start */ -1,
/* resultsPerPage */ 0,
/* totalResultCount */ 0,
/* firstResultIndex */ 0,
/* results */ {},
/* pagination */ {}
},
{
/* query */ "pattern=velomanyunkan&books.id=" RAYCHARLESZIMID,
/* start */ -1,
@@ -980,24 +1018,8 @@ TEST(ServerSearchTest, searchResults)
/* resultsPerPage */ 0,
/* totalResultCount */ 2,
/* firstResultIndex */ 0,
/* results */ {
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/Eleanor_Rigby",
/*title*/ "Eleanor Rigby",
/*snippet*/ R"SNIPPET(...-side "<b>Yellow</b> Submarine" (double A-side) Released 5 August 1966 (1966-08-05) Format 7-inch single Recorded 2829 April &amp; 6 June 1966 Studio EMI, London Genre Baroque pop, art rock Length 2:08 Label Parlophone (UK), Capitol (US) Songwriter(s) LennonMcCartney Producer(s) George Martin The Beatles singles chronology "Paperback Writer" (1966) "Eleanor Rigby" / "<b>Yellow</b> Submarine" (1966) "Strawberry Fields Forever" / "Penny Lane" (1967) Music video "Eleanor Rigby" on YouTube The song continued the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "201"
),
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/If_You_Go_Away",
/*title*/ "If You Go Away",
/*snippet*/ R"SNIPPET(...standard and has been recorded by many artists, including Greta Keller, for whom some say McKuen wrote the lyrics. "If You Go Away" Single by Damita Jo from the album If You Go Away B-side "<b>Yellow</b> Days" Released 1966 Genre Jazz Length 3:49 Label Epic Records Songwriter(s) Jacques Brel, Rod McKuen Producer(s) Bob Morgan Damita Jo singles chronology "Gotta Travel On" (1965) "If You Go Away" (1966) "Walk Away" (1967) Damita Jo reached #10 on the Adult Contemporary chart and #68 on the Billboard Hot 100 in 1966 for her version of the song. Terry Jacks recorded a version of the song which was released as a single in 1974 and reached #29 on the Adult Contemporary chart, #68 on the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "204"
)
},
/* pagination */ {}
/* results */ YELLOW_SEARCH_RESULTS,
/* pagination */ {}
},
{
@@ -1006,50 +1028,28 @@ TEST(ServerSearchTest, searchResults)
/* resultsPerPage */ 0,
/* totalResultCount */ 2,
/* firstResultIndex */ 0,
/* results */ {
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/Eleanor_Rigby",
/*title*/ "Eleanor Rigby",
/*snippet*/ R"SNIPPET(...-side "<b>Yellow</b> Submarine" (double A-side) Released 5 August 1966 (1966-08-05) Format 7-inch single Recorded 2829 April &amp; 6 June 1966 Studio EMI, London Genre Baroque pop, art rock Length 2:08 Label Parlophone (UK), Capitol (US) Songwriter(s) LennonMcCartney Producer(s) George Martin The Beatles singles chronology "Paperback Writer" (1966) "Eleanor Rigby" / "<b>Yellow</b> Submarine" (1966) "Strawberry Fields Forever" / "Penny Lane" (1967) Music video "Eleanor Rigby" on YouTube The song continued the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "201"
),
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/If_You_Go_Away",
/*title*/ "If You Go Away",
/*snippet*/ R"SNIPPET(...standard and has been recorded by many artists, including Greta Keller, for whom some say McKuen wrote the lyrics. "If You Go Away" Single by Damita Jo from the album If You Go Away B-side "<b>Yellow</b> Days" Released 1966 Genre Jazz Length 3:49 Label Epic Records Songwriter(s) Jacques Brel, Rod McKuen Producer(s) Bob Morgan Damita Jo singles chronology "Gotta Travel On" (1965) "If You Go Away" (1966) "Walk Away" (1967) Damita Jo reached #10 on the Adult Contemporary chart and #68 on the Billboard Hot 100 in 1966 for her version of the song. Terry Jacks recorded a version of the song which was released as a single in 1974 and reached #29 on the Adult Contemporary chart, #68 on the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "204"
)
},
/* pagination */ {}
/* results */ YELLOW_SEARCH_RESULTS,
/* pagination */ {}
},
{
/* query */ "pattern=yellow&books.id=" RAYCHARLESZIMID,
/* query */ "pattern=%20yellow%20&books.id=" RAYCHARLESZIMID,
/* start */ 0,
/* resultsPerPage */ 0,
/* totalResultCount */ 2,
/* firstResultIndex */ 0,
/* results */ {
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/Eleanor_Rigby",
/*title*/ "Eleanor Rigby",
/*snippet*/ R"SNIPPET(...-side "<b>Yellow</b> Submarine" (double A-side) Released 5 August 1966 (1966-08-05) Format 7-inch single Recorded 2829 April &amp; 6 June 1966 Studio EMI, London Genre Baroque pop, art rock Length 2:08 Label Parlophone (UK), Capitol (US) Songwriter(s) LennonMcCartney Producer(s) George Martin The Beatles singles chronology "Paperback Writer" (1966) "Eleanor Rigby" / "<b>Yellow</b> Submarine" (1966) "Strawberry Fields Forever" / "Penny Lane" (1967) Music video "Eleanor Rigby" on YouTube The song continued the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "201"
),
/* results */ YELLOW_SEARCH_RESULTS,
/* pagination */ {}
},
SEARCH_RESULT(
/*link*/ "/ROOT%23%3F/content/zimfile/A/If_You_Go_Away",
/*title*/ "If You Go Away",
/*snippet*/ R"SNIPPET(...standard and has been recorded by many artists, including Greta Keller, for whom some say McKuen wrote the lyrics. "If You Go Away" Single by Damita Jo from the album If You Go Away B-side "<b>Yellow</b> Days" Released 1966 Genre Jazz Length 3:49 Label Epic Records Songwriter(s) Jacques Brel, Rod McKuen Producer(s) Bob Morgan Damita Jo singles chronology "Gotta Travel On" (1965) "If You Go Away" (1966) "Walk Away" (1967) Damita Jo reached #10 on the Adult Contemporary chart and #68 on the Billboard Hot 100 in 1966 for her version of the song. Terry Jacks recorded a version of the song which was released as a single in 1974 and reached #29 on the Adult Contemporary chart, #68 on the......)SNIPPET",
/*bookTitle*/ "Ray Charles",
/*wordCount*/ "204"
)
},
/* pagination */ {}
{
/* query */ "pattern=yellow%20submarine&books.id=" RAYCHARLESZIMID,
/* start */ 0,
/* resultsPerPage */ 0,
/* totalResultCount */ 1,
/* firstResultIndex */ 0,
/* results */ { YELLOW_SEARCH_RESULTS[0] },
/* pagination */ {}
},
{

View File

@@ -184,4 +184,16 @@ TEST(stringTools, getSlugifiedFileName)
#endif
}
TEST(stringTools, Trim)
{
EXPECT_EQ(kiwix::trim(""), "");
EXPECT_EQ(kiwix::trim("abc123"), "abc123");
EXPECT_EQ(kiwix::trim(" abc123"), "abc123");
EXPECT_EQ(kiwix::trim("abc123 "), "abc123");
EXPECT_EQ(kiwix::trim(" abc123 "), "abc123");
EXPECT_EQ(kiwix::trim("abc 123"), "abc 123");
EXPECT_EQ(kiwix::trim(" "), "");
EXPECT_EQ(kiwix::trim("\t abc123 \n"), "abc123");
}
};