// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/drive/chromeos/search_metadata.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/i18n/string_search.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace drive {
namespace internal {
namespace {
// A simple wrapper for testing FindAndHighlightWrapper(). It just converts the
// query text parameter to FixedPatternStringSearchIgnoringCaseAndAccents.
bool FindAndHighlightWrapper(
const std::string& text,
const std::string& query_text,
std::string* highlighted_text) {
std::vector<std::unique_ptr<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
queries;
queries.push_back(std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
base::UTF8ToUTF16(query_text)));
return FindAndHighlight(text, queries, highlighted_text);
}
} // namespace
TEST(SearchMetadataSimpleTest, FindAndHighlight_ZeroMatches) {
std::string highlighted_text;
EXPECT_FALSE(FindAndHighlightWrapper("text", "query", &highlighted_text));
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_EmptyText) {
std::string highlighted_text;
EXPECT_FALSE(FindAndHighlightWrapper("", "query", &highlighted_text));
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_EmptyQuery) {
std::vector<std::unique_ptr<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
queries;
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlight("hello", queries, &highlighted_text));
EXPECT_EQ("hello", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_FullMatch) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("hello", "hello", &highlighted_text));
EXPECT_EQ("<b>hello</b>", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_StartWith) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("hello, world", "hello",
&highlighted_text));
EXPECT_EQ("<b>hello</b>, world", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_EndWith) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("hello, world", "world",
&highlighted_text));
EXPECT_EQ("hello, <b>world</b>", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_InTheMiddle) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("yo hello, world", "hello",
&highlighted_text));
EXPECT_EQ("yo <b>hello</b>, world", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_MultipeMatches) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("yoyoyoyoy", "yoy", &highlighted_text));
// Only the first match is highlighted.
EXPECT_EQ("<b>yoy</b>oyoyoy", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_IgnoreCase) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("HeLLo", "hello", &highlighted_text));
EXPECT_EQ("<b>HeLLo</b>", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_IgnoreCaseNonASCII) {
std::string highlighted_text;
// Case and accent ignorance in Greek. Find "socra" in "Socra'tes".
EXPECT_TRUE(FindAndHighlightWrapper(
"\xCE\xA3\xCF\x89\xCE\xBA\xCF\x81\xCE\xAC\xCF\x84\xCE\xB7\xCF\x82",
"\xCF\x83\xCF\x89\xCE\xBA\xCF\x81\xCE\xB1", &highlighted_text));
EXPECT_EQ(
"<b>\xCE\xA3\xCF\x89\xCE\xBA\xCF\x81\xCE\xAC</b>\xCF\x84\xCE\xB7\xCF\x82",
highlighted_text);
// In Japanese characters.
// Find Hiragana "pi" + "(small)ya" in Katakana "hi" + semi-voiced-mark + "ya"
EXPECT_TRUE(FindAndHighlightWrapper(
"\xE3\x81\xB2\xE3\x82\x9A\xE3\x82\x83\xE3\x83\xBC",
"\xE3\x83\x94\xE3\x83\xA4",
&highlighted_text));
EXPECT_EQ(
"<b>\xE3\x81\xB2\xE3\x82\x9A\xE3\x82\x83</b>\xE3\x83\xBC",
highlighted_text);
}
TEST(SearchMetadataSimpleTest, MultiTextBySingleQuery) {
std::vector<std::unique_ptr<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
queries;
queries.push_back(std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
u"hello"));
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlight("hello", queries, &highlighted_text));
EXPECT_EQ("<b>hello</b>", highlighted_text);
EXPECT_FALSE(FindAndHighlight("goodbye", queries, &highlighted_text));
EXPECT_TRUE(FindAndHighlight("1hello2", queries, &highlighted_text));
EXPECT_EQ("1<b>hello</b>2", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_MetaChars) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("<hello>", "hello", &highlighted_text));
EXPECT_EQ("<<b>hello</b>>", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_MoreMetaChars) {
std::string highlighted_text;
EXPECT_TRUE(FindAndHighlightWrapper("a&b&c&d", "b&c", &highlighted_text));
EXPECT_EQ("a&<b>b&c</b>&d", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_SurrogatePair) {
std::string highlighted_text;
// \xF0\x9F\x98\x81 (U+1F601) is a surrogate pair for smile icon of emoji.
EXPECT_TRUE(FindAndHighlightWrapper("hi\xF0\x9F\x98\x81hello",
"i\xF0\x9F\x98\x81", &highlighted_text));
EXPECT_EQ("h<b>i\xF0\x9F\x98\x81</b>hello", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_MultipleQueries) {
std::vector<std::unique_ptr<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
queries;
queries.push_back(std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
u"hello"));
queries.push_back(
std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(u"good"));
std::string highlighted_text;
EXPECT_TRUE(
FindAndHighlight("good morning, hello", queries, &highlighted_text));
EXPECT_EQ("<b>good</b> morning, <b>hello</b>", highlighted_text);
}
TEST(SearchMetadataSimpleTest, FindAndHighlight_OverlappingHighlights) {
std::vector<std::unique_ptr<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
queries;
queries.push_back(std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
u"morning"));
queries.push_back(
std::make_unique<
base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(u"ing,"));
std::string highlighted_text;
EXPECT_TRUE(
FindAndHighlight("good morning, hello", queries, &highlighted_text));
EXPECT_EQ("good <b>morning,</b> hello", highlighted_text);
}
} // namespace internal
} // namespace drive