Commit 80dc1ec7 authored by mattreynolds's avatar mattreynolds Committed by Commit bot

Factor out AutocompleteMatch creation from BookmarkProvider

Move the logic for converting from TitledUrlMatch items to
AutocompleteMatch items out of BookmarkProvider into places where it can
be shared with other AutocompleteProviders.

BUG=630769

Review-Url: https://codereview.chromium.org/2583763003
Cr-Commit-Position: refs/heads/master@{#442009}
parent ba3bd9c5
......@@ -100,6 +100,7 @@ source_set("unit_tests") {
"bookmark_index_unittest.cc",
"bookmark_model_unittest.cc",
"bookmark_utils_unittest.cc",
"titled_url_match_unittest.cc",
]
if (toolkit_views) {
......
......@@ -29,6 +29,9 @@ struct TitledUrlMatch;
// TitledUrlNodes that contain that string in their title or URL.
class TitledUrlIndex {
public:
// Constructs a TitledUrlIndex. |sorter| is used to construct a sorted list
// of matches when matches are returned from the index. If null, matches are
// returned unsorted.
TitledUrlIndex(std::unique_ptr<TitledUrlNodeSorter> sorter);
~TitledUrlIndex();
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/bookmarks/browser/titled_url_match.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace bookmarks {
using MatchPositions = TitledUrlMatch::MatchPositions;
TEST(TitledUrlMatchTest, EmptyOffsetsForEmptyMatchPositions) {
auto offsets = TitledUrlMatch::OffsetsFromMatchPositions(MatchPositions());
EXPECT_TRUE(offsets.empty());
}
TEST(TitledUrlMatchTest, OffsetsFromMatchPositions) {
MatchPositions match_positions = {{1, 3}, {4, 5}, {10, 15}};
std::vector<size_t> expected_offsets = {1, 3, 4, 5, 10, 15};
auto offsets = TitledUrlMatch::OffsetsFromMatchPositions(match_positions);
EXPECT_TRUE(
std::equal(offsets.begin(), offsets.end(), expected_offsets.begin()));
}
TEST(TitledUrlMatchTest, ReplaceOffsetsInEmptyMatchPositions) {
auto match_positions = TitledUrlMatch::ReplaceOffsetsInMatchPositions(
MatchPositions(), std::vector<size_t>());
EXPECT_TRUE(match_positions.empty());
}
TEST(TitledUrlMatchTest, ReplaceOffsetsInMatchPositions) {
MatchPositions orig_match_positions = {{1, 3}, {4, 5}, {10, 15}};
std::vector<size_t> offsets = {0, 2, 3, 4, 9, 14};
MatchPositions expected_match_positions = {{0, 2}, {3, 4}, {9, 14}};
auto match_positions = TitledUrlMatch::ReplaceOffsetsInMatchPositions(
orig_match_positions, offsets);
EXPECT_TRUE(std::equal(match_positions.begin(), match_positions.end(),
expected_match_positions.begin()));
}
TEST(TitledUrlMatchTest, ReplaceOffsetsRemovesItemsWithNposOffsets) {
MatchPositions orig_match_positions = {{1, 3}, {4, 5}, {10, 15}, {17, 20}};
std::vector<size_t> offsets = {0,
base::string16::npos,
base::string16::npos,
4,
base::string16::npos,
base::string16::npos,
17,
20};
MatchPositions expected_match_positions = {{17, 20}};
auto match_positions = TitledUrlMatch::ReplaceOffsetsInMatchPositions(
orig_match_positions, offsets);
EXPECT_TRUE(std::equal(match_positions.begin(), match_positions.end(),
expected_match_positions.begin()));
}
}
......@@ -95,6 +95,8 @@ static_library("browser") {
"shortcuts_provider.h",
"suggestion_answer.cc",
"suggestion_answer.h",
"titled_url_match_utils.cc",
"titled_url_match_utils.h",
"url_index_private_data.cc",
"url_index_private_data.h",
"url_prefix.cc",
......@@ -243,6 +245,7 @@ source_set("unit_tests") {
"shortcuts_database_unittest.cc",
"shortcuts_provider_unittest.cc",
"suggestion_answer_unittest.cc",
"titled_url_match_utils_unittest.cc",
"url_prefix_unittest.cc",
"zero_suggest_provider_unittest.cc",
]
......
......@@ -17,40 +17,14 @@
#include "components/metrics/proto/omnibox_input_type.pb.h"
#include "components/omnibox/browser/autocomplete_provider_client.h"
#include "components/omnibox/browser/autocomplete_result.h"
#include "components/omnibox/browser/history_provider.h"
#include "components/omnibox/browser/url_prefix.h"
#include "components/omnibox/browser/titled_url_match_utils.h"
#include "components/prefs/pref_service.h"
#include "components/url_formatter/url_formatter.h"
#include "url/url_constants.h"
using bookmarks::BookmarkNode;
using bookmarks::TitledUrlMatch;
using TitledUrlMatches = std::vector<TitledUrlMatch>;
namespace {
// Removes leading spaces from |title| before displaying, otherwise it looks
// funny. In the process, corrects |title_match_positions| so the correct
// characters are highlighted.
void CorrectTitleAndMatchPositions(
base::string16* title,
TitledUrlMatch::MatchPositions* title_match_positions) {
size_t leading_whitespace_chars = title->length();
base::TrimWhitespace(*title, base::TRIM_LEADING, title);
leading_whitespace_chars-= title->length();
if (leading_whitespace_chars == 0)
return;
for (query_parser::Snippet::MatchPositions::iterator it =
title_match_positions->begin();
it != title_match_positions->end(); ++it) {
(*it) = query_parser::Snippet::MatchPosition(
it->first - leading_whitespace_chars,
it->second - leading_whitespace_chars);
}
}
} // namespace
// BookmarkProvider ------------------------------------------------------------
BookmarkProvider::BookmarkProvider(AutocompleteProviderClient* client)
......@@ -107,13 +81,15 @@ void BookmarkProvider::DoAutocomplete(const AutocompleteInput& input) {
if (matches.empty())
return; // There were no matches.
const base::string16 fixed_up_input(FixupUserInput(input).second);
for (TitledUrlMatches::const_iterator i = matches.begin(); i != matches.end();
++i) {
// Create and score the AutocompleteMatch. If its score is 0 then the
// match is discarded.
AutocompleteMatch match(TitledUrlMatchToACMatch(input, fixed_up_input, *i));
if (match.relevance > 0)
matches_.push_back(match);
for (const auto& bookmark_match : matches) {
// Score the TitledUrlMatch. If its score is greater than 0 then the
// AutocompleteMatch is created and added to matches_.
int relevance = CalculateBookmarkMatchRelevance(bookmark_match);
if (relevance > 0) {
matches_.push_back(TitledUrlMatchToAutocompleteMatch(
bookmark_match, AutocompleteMatchType::BOOKMARK_TITLE, relevance,
this, client_->GetSchemeClassifier(), input, fixed_up_input));
}
}
// Sort and clip the resulting matches.
......@@ -155,69 +131,8 @@ class ScoringFunctor {
} // namespace
AutocompleteMatch BookmarkProvider::TitledUrlMatchToACMatch(
const AutocompleteInput& input,
const base::string16& fixed_up_input_text,
const TitledUrlMatch& bookmark_match) {
// The AutocompleteMatch we construct is non-deletable because the only
// way to support this would be to delete the underlying bookmark, which is
// unlikely to be what the user intends.
AutocompleteMatch match(this, 0, false,
AutocompleteMatchType::BOOKMARK_TITLE);
base::string16 title(bookmark_match.node->GetTitledUrlNodeTitle());
TitledUrlMatch::MatchPositions new_title_match_positions =
bookmark_match.title_match_positions;
CorrectTitleAndMatchPositions(&title, &new_title_match_positions);
const GURL& url(bookmark_match.node->GetTitledUrlNodeUrl());
const base::string16& url_utf16 = base::UTF8ToUTF16(url.spec());
size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset(
input.text(), fixed_up_input_text, false, url_utf16);
match.destination_url = url;
const size_t match_start = bookmark_match.url_match_positions.empty() ?
0 : bookmark_match.url_match_positions[0].first;
const bool trim_http = !AutocompleteInput::HasHTTPScheme(input.text()) &&
((match_start == base::string16::npos) || (match_start != 0));
std::vector<size_t> offsets = TitledUrlMatch::OffsetsFromMatchPositions(
bookmark_match.url_match_positions);
// In addition to knowing how |offsets| is transformed, we need to know how
// |inline_autocomplete_offset| is transformed. We add it to the end of
// |offsets|, compute how everything is transformed, then remove it from the
// end.
offsets.push_back(inline_autocomplete_offset);
match.contents = url_formatter::FormatUrlWithOffsets(
url, url_formatter::kFormatUrlOmitAll &
~(trim_http ? 0 : url_formatter::kFormatUrlOmitHTTP),
net::UnescapeRule::SPACES, nullptr, nullptr, &offsets);
inline_autocomplete_offset = offsets.back();
offsets.pop_back();
TitledUrlMatch::MatchPositions new_url_match_positions =
TitledUrlMatch::ReplaceOffsetsInMatchPositions(
bookmark_match.url_match_positions, offsets);
match.contents_class =
ClassificationsFromMatch(new_url_match_positions,
match.contents.size(),
true);
match.fill_into_edit =
AutocompleteInput::FormattedStringWithEquivalentMeaning(
url, match.contents, client_->GetSchemeClassifier());
if (inline_autocomplete_offset != base::string16::npos) {
// |inline_autocomplete_offset| may be beyond the end of the
// |fill_into_edit| if the user has typed an URL with a scheme and the
// last character typed is a slash. That slash is removed by the
// FormatURLWithOffsets call above.
if (inline_autocomplete_offset < match.fill_into_edit.length()) {
match.inline_autocompletion =
match.fill_into_edit.substr(inline_autocomplete_offset);
}
match.allowed_to_be_default_match = match.inline_autocompletion.empty() ||
!HistoryProvider::PreventInlineAutocomplete(input);
}
match.description = title;
match.description_class =
ClassificationsFromMatch(bookmark_match.title_match_positions,
match.description.size(),
false);
int BookmarkProvider::CalculateBookmarkMatchRelevance(
const TitledUrlMatch& bookmark_match) const {
// Summary on how a relevance score is determined for the match:
//
// For each match within the bookmark's title or URL (or both), calculate a
......@@ -268,7 +183,9 @@ AutocompleteMatch BookmarkProvider::TitledUrlMatchToACMatch(
// and, for each additional reference beyond the one for the bookmark being
// scored up to a maximum of three, the score is boosted by a fixed amount
// given by |kURLCountBoost|, below.
//
base::string16 title(bookmark_match.node->GetTitledUrlNodeTitle());
const GURL& url(bookmark_match.node->GetTitledUrlNodeUrl());
// Pretend empty titles are identical to the URL.
if (title.empty())
......@@ -297,46 +214,19 @@ AutocompleteMatch BookmarkProvider::TitledUrlMatchToACMatch(
const int kMaxBookmarkScore = bookmarklet_without_title_match ? 799 : 1199;
const double kBookmarkScoreRange =
static_cast<double>(kMaxBookmarkScore - kBaseBookmarkScore);
match.relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) +
kBaseBookmarkScore;
int relevance = static_cast<int>(normalized_sum * kBookmarkScoreRange) +
kBaseBookmarkScore;
// Don't waste any time searching for additional referenced URLs if we
// already have a perfect title match.
if (match.relevance >= kMaxBookmarkScore)
return match;
if (relevance >= kMaxBookmarkScore)
return relevance;
// Boost the score if the bookmark's URL is referenced by other bookmarks.
const int kURLCountBoost[4] = { 0, 75, 125, 150 };
std::vector<const BookmarkNode*> nodes;
bookmark_model_->GetNodesByURL(url, &nodes);
DCHECK_GE(std::min(arraysize(kURLCountBoost), nodes.size()), 1U);
match.relevance +=
relevance +=
kURLCountBoost[std::min(arraysize(kURLCountBoost), nodes.size()) - 1];
match.relevance = std::min(kMaxBookmarkScore, match.relevance);
return match;
}
// static
ACMatchClassifications BookmarkProvider::ClassificationsFromMatch(
const query_parser::Snippet::MatchPositions& positions,
size_t text_length,
bool is_url) {
ACMatchClassification::Style url_style =
is_url ? ACMatchClassification::URL : ACMatchClassification::NONE;
ACMatchClassifications classifications;
if (positions.empty()) {
if (text_length > 0)
classifications.push_back(ACMatchClassification(0, url_style));
return classifications;
}
for (query_parser::Snippet::MatchPositions::const_iterator i =
positions.begin();
i != positions.end();
++i) {
AutocompleteMatch::ACMatchClassifications new_class;
AutocompleteMatch::ClassifyLocationInString(i->first, i->second - i->first,
text_length, url_style, &new_class);
classifications = AutocompleteMatch::MergeClassifications(
classifications, new_class);
}
return classifications;
relevance = std::min(kMaxBookmarkScore, relevance);
return relevance;
}
......@@ -12,9 +12,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/query_parser/snippet.h"
class AutocompleteProviderClient;
......@@ -55,24 +53,9 @@ class BookmarkProvider : public AutocompleteProvider {
// |matches_|.
void DoAutocomplete(const AutocompleteInput& input);
// Compose an AutocompleteMatch based on |match| that has 1) the URL of
// |match|'s bookmark, and 2) the bookmark's title, not the URL's page
// title, as the description. |input| is used to compute the match's
// inline_autocompletion. |fixed_up_input_text| is used in that way as well;
// it's passed separately so this function doesn't have to compute it.
AutocompleteMatch TitledUrlMatchToACMatch(
const AutocompleteInput& input,
const base::string16& fixed_up_input_text,
const bookmarks::TitledUrlMatch& match);
// Converts |positions| into ACMatchClassifications and returns the
// classifications. |text_length| is used to determine the need to add an
// 'unhighlighted' classification span so the tail of the source string
// properly highlighted.
static ACMatchClassifications ClassificationsFromMatch(
const query_parser::Snippet::MatchPositions& positions,
size_t text_length,
bool is_url);
// Calculates the relevance score for |match|.
int CalculateBookmarkMatchRelevance(
const bookmarks::TitledUrlMatch& match) const;
AutocompleteProviderClient* client_;
bookmarks::BookmarkModel* bookmark_model_;
......
......@@ -25,6 +25,7 @@
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/mock_autocomplete_provider_client.h"
#include "components/omnibox/browser/test_scheme_classifier.h"
#include "components/omnibox/browser/titled_url_match_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -422,8 +423,10 @@ TEST_F(BookmarkProviderTest, InlineAutocompletion) {
node.SetTitle(base::ASCIIToUTF16(query_data[i].url));
TitledUrlMatch bookmark_match;
bookmark_match.node = &node;
const AutocompleteMatch& ac_match = provider_->TitledUrlMatchToACMatch(
input, fixed_up_input, bookmark_match);
int relevance = provider_->CalculateBookmarkMatchRelevance(bookmark_match);
const AutocompleteMatch& ac_match = TitledUrlMatchToAutocompleteMatch(
bookmark_match, AutocompleteMatchType::BOOKMARK_TITLE, relevance,
provider_.get(), classifier_, input, fixed_up_input);
EXPECT_EQ(query_data[i].allowed_to_be_default_match,
ac_match.allowed_to_be_default_match) << description;
EXPECT_EQ(base::ASCIIToUTF16(query_data[i].inline_autocompletion),
......
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/omnibox/browser/titled_url_match_utils.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/titled_url_node.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/history_provider.h"
#include "components/omnibox/browser/url_prefix.h"
#include "components/url_formatter/url_formatter.h"
namespace {
// Converts |positions| into ACMatchClassifications and returns the
// classifications. |text_length| is used to determine the need to add an
// 'unhighlighted' classification span so the tail of the source string
// properly highlighted.
ACMatchClassifications ClassificationsFromMatchPositions(
const bookmarks::TitledUrlMatch::MatchPositions& positions,
size_t text_length,
bool is_url) {
ACMatchClassification::Style url_style =
is_url ? ACMatchClassification::URL : ACMatchClassification::NONE;
ACMatchClassifications classifications;
if (positions.empty()) {
if (text_length > 0) {
classifications.push_back(ACMatchClassification(0, url_style));
}
return classifications;
}
for (bookmarks::TitledUrlMatch::MatchPositions::const_iterator i =
positions.begin();
i != positions.end(); ++i) {
AutocompleteMatch::ACMatchClassifications new_class;
AutocompleteMatch::ClassifyLocationInString(
i->first, i->second - i->first, text_length, url_style, &new_class);
classifications =
AutocompleteMatch::MergeClassifications(classifications, new_class);
}
return classifications;
}
} // namespace
namespace bookmarks {
AutocompleteMatch TitledUrlMatchToAutocompleteMatch(
const TitledUrlMatch& titled_url_match,
AutocompleteMatchType::Type type,
int relevance,
AutocompleteProvider* provider,
const AutocompleteSchemeClassifier& scheme_classifier,
const AutocompleteInput& input,
const base::string16& fixed_up_input_text) {
const GURL& url = titled_url_match.node->GetTitledUrlNodeUrl();
base::string16 title = titled_url_match.node->GetTitledUrlNodeTitle();
// The AutocompleteMatch we construct is non-deletable because the only way to
// support this would be to delete the underlying object that created the
// titled_url_match. E.g., for the bookmark provider this would mean deleting
// the underlying bookmark, which is unlikely to be what the user intends.
AutocompleteMatch match(provider, relevance, false, type);
TitledUrlMatch::MatchPositions new_title_match_positions =
titled_url_match.title_match_positions;
CorrectTitleAndMatchPositions(&title, &new_title_match_positions);
const base::string16& url_utf16 = base::UTF8ToUTF16(url.spec());
size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset(
input.text(), fixed_up_input_text, false, url_utf16);
match.destination_url = url;
const size_t match_start =
titled_url_match.url_match_positions.empty()
? 0
: titled_url_match.url_match_positions[0].first;
const bool trim_http =
!AutocompleteInput::HasHTTPScheme(input.text()) &&
((match_start == base::string16::npos) || (match_start != 0));
std::vector<size_t> offsets = TitledUrlMatch::OffsetsFromMatchPositions(
titled_url_match.url_match_positions);
// In addition to knowing how |offsets| is transformed, we need to know how
// |inline_autocomplete_offset| is transformed. We add it to the end of
// |offsets|, compute how everything is transformed, then remove it from the
// end.
offsets.push_back(inline_autocomplete_offset);
match.contents = url_formatter::FormatUrlWithOffsets(
url, url_formatter::kFormatUrlOmitAll &
~(trim_http ? 0 : url_formatter::kFormatUrlOmitHTTP),
net::UnescapeRule::SPACES, nullptr, nullptr, &offsets);
inline_autocomplete_offset = offsets.back();
offsets.pop_back();
TitledUrlMatch::MatchPositions new_url_match_positions =
TitledUrlMatch::ReplaceOffsetsInMatchPositions(
titled_url_match.url_match_positions, offsets);
match.contents_class = ClassificationsFromMatchPositions(
new_url_match_positions, match.contents.size(), true);
match.fill_into_edit =
AutocompleteInput::FormattedStringWithEquivalentMeaning(
url, match.contents, scheme_classifier);
if (inline_autocomplete_offset != base::string16::npos) {
// |inline_autocomplete_offset| may be beyond the end of the
// |fill_into_edit| if the user has typed an URL with a scheme and the
// last character typed is a slash. That slash is removed by the
// FormatURLWithOffsets call above.
if (inline_autocomplete_offset < match.fill_into_edit.length()) {
match.inline_autocompletion =
match.fill_into_edit.substr(inline_autocomplete_offset);
}
match.allowed_to_be_default_match =
match.inline_autocompletion.empty() ||
!HistoryProvider::PreventInlineAutocomplete(input);
}
match.description = title;
match.description_class = ClassificationsFromMatchPositions(
titled_url_match.title_match_positions, match.description.size(), false);
return match;
}
void CorrectTitleAndMatchPositions(
base::string16* title,
TitledUrlMatch::MatchPositions* title_match_positions) {
size_t leading_whitespace_chars = title->length();
base::TrimWhitespace(*title, base::TRIM_LEADING, title);
leading_whitespace_chars -= title->length();
if (leading_whitespace_chars == 0)
return;
for (TitledUrlMatch::MatchPositions::iterator it =
title_match_positions->begin();
it != title_match_positions->end(); ++it) {
it->first -= leading_whitespace_chars;
it->second -= leading_whitespace_chars;
}
}
} // namespace bookmarks
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_OMNIBOX_BROWSER_TITLED_URL_MATCH_UTILS_H_
#define COMPONENTS_OMNIBOX_BROWSER_TITLED_URL_MATCH_UTILS_H_
#include "base/strings/string16.h"
#include "components/bookmarks/browser/titled_url_match.h"
#include "components/omnibox/browser/autocomplete_match_type.h"
class AutocompleteInput;
class AutocompleteProvider;
class AutocompleteSchemeClassifier;
struct AutocompleteMatch;
namespace bookmarks {
// Compose an AutocompleteMatch based on |match| that has the match's URL and
// page title, type |type|, and relevance score |relevance|. |input| is used to
// compute the match's inline_autocompletion. |fixed_up_input_text| is used in
// that way as well; it's passed separately so this function doesn't have to
// compute it.
AutocompleteMatch TitledUrlMatchToAutocompleteMatch(
const TitledUrlMatch& match,
AutocompleteMatchType::Type type,
int relevance,
AutocompleteProvider* provider,
const AutocompleteSchemeClassifier& scheme_classifier,
const AutocompleteInput& input,
const base::string16& fixed_up_input_text);
// Removes leading spaces from |title| before displaying, otherwise it looks
// funny. In the process, corrects |title_match_positions| so the correct
// characters are highlighted.
void CorrectTitleAndMatchPositions(
base::string16* title,
TitledUrlMatch::MatchPositions* title_match_positions);
} // namespace bookmarks
#endif // COMPONENTS_OMNIBOX_BROWSER_TITLED_URL_MATCH_UTILS_H_
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/omnibox/browser/titled_url_match_utils.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/titled_url_match.h"
#include "components/bookmarks/browser/titled_url_node.h"
#include "components/metrics/proto/omnibox_event.pb.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/test_scheme_classifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using bookmarks::TitledUrlMatchToAutocompleteMatch;
using bookmarks::CorrectTitleAndMatchPositions;
namespace {
// A simple AutocompleteProvider that does nothing.
class MockAutocompleteProvider : public AutocompleteProvider {
public:
MockAutocompleteProvider(Type type) : AutocompleteProvider(type) {}
void Start(const AutocompleteInput& input, bool minimal_changes) override {}
private:
~MockAutocompleteProvider() override {}
};
class MockTitledUrlNode : public bookmarks::TitledUrlNode {
public:
MockTitledUrlNode(const base::string16& title, const GURL& url)
: title_(title), url_(url) {}
// TitledUrlNode
const base::string16& GetTitledUrlNodeTitle() const override {
return title_;
}
const GURL& GetTitledUrlNodeUrl() const override { return url_; }
private:
base::string16 title_;
GURL url_;
};
} // namespace
bool operator==(const ACMatchClassification& lhs,
const ACMatchClassification& rhs) {
return (lhs.offset == rhs.offset) && (lhs.style == rhs.style);
}
TEST(TitledUrlMatchUtilsTest, TitledUrlMatchToAutocompleteMatch) {
base::string16 input_text(base::ASCIIToUTF16("goo"));
base::string16 match_title(base::ASCIIToUTF16("Google Search"));
base::string16 match_url_string(
base::ASCIIToUTF16("https://www.google.com/"));
GURL match_url(match_url_string);
bookmarks::TitledUrlMatch::MatchPositions title_match_positions = {{0, 3}};
bookmarks::TitledUrlMatch::MatchPositions url_match_positions = {{12, 15}};
AutocompleteMatchType::Type type = AutocompleteMatchType::BOOKMARK_TITLE;
int relevance = 123;
MockTitledUrlNode node(match_title, match_url);
bookmarks::TitledUrlMatch titled_url_match;
titled_url_match.node = &node;
titled_url_match.title_match_positions = title_match_positions;
titled_url_match.url_match_positions = url_match_positions;
scoped_refptr<MockAutocompleteProvider> provider =
new MockAutocompleteProvider(AutocompleteProvider::Type::TYPE_BOOKMARK);
TestSchemeClassifier classifier;
AutocompleteInput input(input_text, base::string16::npos, std::string(),
GURL(), metrics::OmniboxEventProto::NTP, false, false,
true, true, false, classifier);
const base::string16 fixed_up_input(input_text);
AutocompleteMatch autocomplete_match = TitledUrlMatchToAutocompleteMatch(
titled_url_match, type, relevance, provider.get(), classifier, input,
fixed_up_input);
ACMatchClassifications expected_contents_class = {
{0, ACMatchClassification::URL},
{12, ACMatchClassification::URL | ACMatchClassification::MATCH},
{15, ACMatchClassification::URL},
};
ACMatchClassifications expected_description_class = {
{0, ACMatchClassification::MATCH}, {3, ACMatchClassification::NONE},
};
base::string16 expected_inline_autocompletion(base::ASCIIToUTF16("gle.com"));
base::string16 expected_contents(
base::ASCIIToUTF16("https://www.google.com"));
EXPECT_EQ(provider.get(), autocomplete_match.provider);
EXPECT_EQ(type, autocomplete_match.type);
EXPECT_EQ(relevance, autocomplete_match.relevance);
EXPECT_EQ(match_url, autocomplete_match.destination_url);
EXPECT_EQ(expected_contents, autocomplete_match.contents);
EXPECT_TRUE(std::equal(expected_contents_class.begin(),
expected_contents_class.end(),
autocomplete_match.contents_class.begin()));
EXPECT_EQ(match_title, autocomplete_match.description);
EXPECT_TRUE(std::equal(expected_description_class.begin(),
expected_description_class.end(),
autocomplete_match.description_class.begin()));
EXPECT_EQ(expected_contents, autocomplete_match.fill_into_edit);
EXPECT_TRUE(autocomplete_match.allowed_to_be_default_match);
EXPECT_EQ(expected_inline_autocompletion,
autocomplete_match.inline_autocompletion);
}
TEST(TitledUrlMatchUtilsTest, EmptyInlineAutocompletion) {
// The search term matches the title but not the URL. Since there is no URL
// match, the inline autocompletion string will be empty.
base::string16 input_text(base::ASCIIToUTF16("goo"));
base::string16 match_title(base::ASCIIToUTF16("Email by Google"));
base::string16 match_url_string(base::ASCIIToUTF16("https://www.gmail.com/"));
GURL match_url(match_url_string);
bookmarks::TitledUrlMatch::MatchPositions title_match_positions = {{9, 12}};
bookmarks::TitledUrlMatch::MatchPositions url_match_positions;
AutocompleteMatchType::Type type = AutocompleteMatchType::BOOKMARK_TITLE;
int relevance = 123;
MockTitledUrlNode node(match_title, match_url);
bookmarks::TitledUrlMatch titled_url_match;
titled_url_match.node = &node;
titled_url_match.title_match_positions = title_match_positions;
titled_url_match.url_match_positions = url_match_positions;
scoped_refptr<MockAutocompleteProvider> provider =
new MockAutocompleteProvider(AutocompleteProvider::Type::TYPE_BOOKMARK);
TestSchemeClassifier classifier;
AutocompleteInput input(input_text, base::string16::npos, std::string(),
GURL(), metrics::OmniboxEventProto::NTP, false, false,
true, true, false, classifier);
const base::string16 fixed_up_input(input_text);
AutocompleteMatch autocomplete_match = TitledUrlMatchToAutocompleteMatch(
titled_url_match, type, relevance, provider.get(), classifier, input,
fixed_up_input);
ACMatchClassifications expected_contents_class = {
{0, ACMatchClassification::URL},
};
ACMatchClassifications expected_description_class = {
{0, ACMatchClassification::NONE},
{9, ACMatchClassification::MATCH},
{12, ACMatchClassification::NONE},
};
base::string16 expected_contents(base::ASCIIToUTF16("https://www.gmail.com"));
EXPECT_EQ(provider.get(), autocomplete_match.provider);
EXPECT_EQ(type, autocomplete_match.type);
EXPECT_EQ(relevance, autocomplete_match.relevance);
EXPECT_EQ(match_url, autocomplete_match.destination_url);
EXPECT_EQ(expected_contents, autocomplete_match.contents);
EXPECT_TRUE(std::equal(expected_contents_class.begin(),
expected_contents_class.end(),
autocomplete_match.contents_class.begin()));
EXPECT_EQ(match_title, autocomplete_match.description);
EXPECT_TRUE(std::equal(expected_description_class.begin(),
expected_description_class.end(),
autocomplete_match.description_class.begin()));
EXPECT_EQ(expected_contents, autocomplete_match.fill_into_edit);
EXPECT_FALSE(autocomplete_match.allowed_to_be_default_match);
EXPECT_TRUE(autocomplete_match.inline_autocompletion.empty());
}
TEST(TitledUrlMatchUtilsTest, CorrectTitleAndMatchPositions) {
bookmarks::TitledUrlMatch::MatchPositions match_positions = {{2, 6},
{10, 15}};
base::string16 title = base::ASCIIToUTF16(" Leading whitespace");
bookmarks::TitledUrlMatch::MatchPositions expected_match_positions = {
{0, 4}, {8, 13}};
base::string16 expected_title = base::ASCIIToUTF16("Leading whitespace");
CorrectTitleAndMatchPositions(&title, &match_positions);
EXPECT_EQ(expected_title, title);
EXPECT_TRUE(std::equal(match_positions.begin(), match_positions.end(),
expected_match_positions.begin()));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment