Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / omnibox / browser / autocomplete_result_unittest.cc
blob0e6566940fefc610f4e0c21fd8ec9f6ff7126c7c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/omnibox/browser/autocomplete_result.h"
7 #include <vector>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "components/metrics/proto/omnibox_event.pb.h"
15 #include "components/omnibox/browser/autocomplete_input.h"
16 #include "components/omnibox/browser/autocomplete_match.h"
17 #include "components/omnibox/browser/autocomplete_match_type.h"
18 #include "components/omnibox/browser/autocomplete_provider.h"
19 #include "components/omnibox/browser/omnibox_field_trial.h"
20 #include "components/omnibox/browser/test_scheme_classifier.h"
21 #include "components/search_engines/template_url_service.h"
22 #include "components/variations/entropy_provider.h"
23 #include "components/variations/variations_associated_data.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using metrics::OmniboxEventProto;
28 namespace {
30 struct AutocompleteMatchTestData {
31 std::string destination_url;
32 AutocompleteMatch::Type type;
35 const AutocompleteMatchTestData kVerbatimMatches[] = {
36 { "http://search-what-you-typed/",
37 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
38 { "http://url-what-you-typed/", AutocompleteMatchType::URL_WHAT_YOU_TYPED },
41 const AutocompleteMatchTestData kNonVerbatimMatches[] = {
42 { "http://search-history/", AutocompleteMatchType::SEARCH_HISTORY },
43 { "http://history-title/", AutocompleteMatchType::HISTORY_TITLE },
46 // Adds |count| AutocompleteMatches to |matches|.
47 void PopulateAutocompleteMatchesFromTestData(
48 const AutocompleteMatchTestData* data,
49 size_t count,
50 ACMatches* matches) {
51 ASSERT_TRUE(matches != NULL);
52 for (size_t i = 0; i < count; ++i) {
53 AutocompleteMatch match;
54 match.destination_url = GURL(data[i].destination_url);
55 match.relevance =
56 matches->empty() ? 1300 : (matches->back().relevance - 100);
57 match.allowed_to_be_default_match = true;
58 match.type = data[i].type;
59 matches->push_back(match);
63 // A simple AutocompleteProvider that does nothing.
64 class MockAutocompleteProvider : public AutocompleteProvider {
65 public:
66 MockAutocompleteProvider(Type type): AutocompleteProvider(type) {}
68 void Start(const AutocompleteInput& input, bool minimal_changes) override {}
70 private:
71 ~MockAutocompleteProvider() override {}
74 } // namespace
76 class AutocompleteResultTest : public testing::Test {
77 public:
78 struct TestData {
79 // Used to build a url for the AutocompleteMatch. The URL becomes
80 // "http://" + ('a' + |url_id|) (e.g. an ID of 2 yields "http://b").
81 int url_id;
83 // ID of the provider.
84 int provider_id;
86 // Relevance score.
87 int relevance;
89 // Allowed to be default match status.
90 bool allowed_to_be_default_match;
92 // Duplicate matches.
93 std::vector<AutocompleteMatch> duplicate_matches;
96 AutocompleteResultTest() {
97 // Destroy the existing FieldTrialList before creating a new one to avoid
98 // a DCHECK.
99 field_trial_list_.reset();
100 field_trial_list_.reset(new base::FieldTrialList(
101 new metrics::SHA1EntropyProvider("foo")));
102 variations::testing::ClearAllVariationParams();
104 // Create the list of mock providers. 5 is enough.
105 for (size_t i = 0; i < 5; ++i) {
106 mock_provider_list_.push_back(new MockAutocompleteProvider(
107 static_cast<AutocompleteProvider::Type>(i)));
111 void SetUp() override {
112 template_url_service_.reset(new TemplateURLService(NULL, 0));
113 template_url_service_->Load();
116 // Configures |match| from |data|.
117 void PopulateAutocompleteMatch(const TestData& data,
118 AutocompleteMatch* match);
120 // Adds |count| AutocompleteMatches to |matches|.
121 void PopulateAutocompleteMatches(const TestData* data,
122 size_t count,
123 ACMatches* matches);
125 // Asserts that |result| has |expected_count| matches matching |expected|.
126 void AssertResultMatches(const AutocompleteResult& result,
127 const TestData* expected,
128 size_t expected_count);
130 // Creates an AutocompleteResult from |last| and |current|. The two are
131 // merged by |CopyOldMatches| and compared by |AssertResultMatches|.
132 void RunCopyOldMatchesTest(const TestData* last, size_t last_size,
133 const TestData* current, size_t current_size,
134 const TestData* expected, size_t expected_size);
136 // Returns a (mock) AutocompleteProvider of given |provider_id|.
137 MockAutocompleteProvider* GetProvider(int provider_id) {
138 EXPECT_LT(provider_id, static_cast<int>(mock_provider_list_.size()));
139 return mock_provider_list_[provider_id].get();
142 protected:
143 scoped_ptr<TemplateURLService> template_url_service_;
145 private:
146 scoped_ptr<base::FieldTrialList> field_trial_list_;
148 // For every provider mentioned in TestData, we need a mock provider.
149 std::vector<scoped_refptr<MockAutocompleteProvider> > mock_provider_list_;
151 DISALLOW_COPY_AND_ASSIGN(AutocompleteResultTest);
154 void AutocompleteResultTest::PopulateAutocompleteMatch(
155 const TestData& data,
156 AutocompleteMatch* match) {
157 match->provider = GetProvider(data.provider_id);
158 match->fill_into_edit = base::IntToString16(data.url_id);
159 std::string url_id(1, data.url_id + 'a');
160 match->destination_url = GURL("http://" + url_id);
161 match->relevance = data.relevance;
162 match->allowed_to_be_default_match = data.allowed_to_be_default_match;
163 match->duplicate_matches = data.duplicate_matches;
166 void AutocompleteResultTest::PopulateAutocompleteMatches(
167 const TestData* data,
168 size_t count,
169 ACMatches* matches) {
170 for (size_t i = 0; i < count; ++i) {
171 AutocompleteMatch match;
172 PopulateAutocompleteMatch(data[i], &match);
173 matches->push_back(match);
177 void AutocompleteResultTest::AssertResultMatches(
178 const AutocompleteResult& result,
179 const TestData* expected,
180 size_t expected_count) {
181 ASSERT_EQ(expected_count, result.size());
182 for (size_t i = 0; i < expected_count; ++i) {
183 AutocompleteMatch expected_match;
184 PopulateAutocompleteMatch(expected[i], &expected_match);
185 const AutocompleteMatch& match = *(result.begin() + i);
186 EXPECT_EQ(expected_match.provider, match.provider) << i;
187 EXPECT_EQ(expected_match.relevance, match.relevance) << i;
188 EXPECT_EQ(expected_match.allowed_to_be_default_match,
189 match.allowed_to_be_default_match) << i;
190 EXPECT_EQ(expected_match.destination_url.spec(),
191 match.destination_url.spec()) << i;
195 void AutocompleteResultTest::RunCopyOldMatchesTest(
196 const TestData* last, size_t last_size,
197 const TestData* current, size_t current_size,
198 const TestData* expected, size_t expected_size) {
199 AutocompleteInput input(base::ASCIIToUTF16("a"), base::string16::npos,
200 std::string(), GURL(),
201 OmniboxEventProto::INVALID_SPEC, false, false, false,
202 true, false, TestSchemeClassifier());
204 ACMatches last_matches;
205 PopulateAutocompleteMatches(last, last_size, &last_matches);
206 AutocompleteResult last_result;
207 last_result.AppendMatches(input, last_matches);
208 last_result.SortAndCull(input, std::string(), template_url_service_.get());
210 ACMatches current_matches;
211 PopulateAutocompleteMatches(current, current_size, &current_matches);
212 AutocompleteResult current_result;
213 current_result.AppendMatches(input, current_matches);
214 current_result.SortAndCull(input, std::string(), template_url_service_.get());
215 current_result.CopyOldMatches(
216 input, std::string(), last_result, template_url_service_.get());
218 AssertResultMatches(current_result, expected, expected_size);
221 // Assertion testing for AutocompleteResult::Swap.
222 TEST_F(AutocompleteResultTest, Swap) {
223 AutocompleteResult r1;
224 AutocompleteResult r2;
226 // Swap with empty shouldn't do anything interesting.
227 r1.Swap(&r2);
228 EXPECT_EQ(r1.end(), r1.default_match());
229 EXPECT_EQ(r2.end(), r2.default_match());
231 // Swap with a single match.
232 ACMatches matches;
233 AutocompleteMatch match;
234 match.relevance = 1;
235 match.allowed_to_be_default_match = true;
236 AutocompleteInput input(base::ASCIIToUTF16("a"), base::string16::npos,
237 std::string(), GURL(),
238 OmniboxEventProto::INVALID_SPEC, false, false, false,
239 true, false, TestSchemeClassifier());
240 matches.push_back(match);
241 r1.AppendMatches(input, matches);
242 r1.SortAndCull(input, std::string(), template_url_service_.get());
243 EXPECT_EQ(r1.begin(), r1.default_match());
244 EXPECT_EQ("http://a/", r1.alternate_nav_url().spec());
245 r1.Swap(&r2);
246 EXPECT_TRUE(r1.empty());
247 EXPECT_EQ(r1.end(), r1.default_match());
248 EXPECT_TRUE(r1.alternate_nav_url().is_empty());
249 ASSERT_FALSE(r2.empty());
250 EXPECT_EQ(r2.begin(), r2.default_match());
251 EXPECT_EQ("http://a/", r2.alternate_nav_url().spec());
254 // Tests that if the new results have a lower max relevance score than last,
255 // any copied results have their relevance shifted down.
256 TEST_F(AutocompleteResultTest, CopyOldMatches) {
257 TestData last[] = {
258 { 0, 1, 1000, true },
259 { 1, 1, 500, true },
261 TestData current[] = {
262 { 2, 1, 400, true },
264 TestData result[] = {
265 { 2, 1, 400, true },
266 { 1, 1, 399, true },
269 ASSERT_NO_FATAL_FAILURE(RunCopyOldMatchesTest(last, arraysize(last),
270 current, arraysize(current),
271 result, arraysize(result)));
274 // Tests that if the new results have a lower max relevance score than last,
275 // any copied results have their relevance shifted down when the allowed to
276 // be default constraint comes into play.
277 TEST_F(AutocompleteResultTest, CopyOldMatchesAllowedToBeDefault) {
278 TestData last[] = {
279 { 0, 1, 1300, true },
280 { 1, 1, 1200, true },
281 { 2, 1, 1100, true },
283 TestData current[] = {
284 { 3, 1, 1000, false },
285 { 4, 1, 900, true },
287 // The expected results are out of relevance order because the top-scoring
288 // allowed to be default match is always pulled to the top.
289 TestData result[] = {
290 { 4, 1, 900, true },
291 { 3, 1, 1000, false },
292 { 2, 1, 899, true },
295 ASSERT_NO_FATAL_FAILURE(RunCopyOldMatchesTest(last, arraysize(last),
296 current, arraysize(current),
297 result, arraysize(result)));
300 // Tests that matches are copied correctly from two distinct providers.
301 TEST_F(AutocompleteResultTest, CopyOldMatchesMultipleProviders) {
302 TestData last[] = {
303 { 0, 1, 1300, false },
304 { 1, 2, 1250, true },
305 { 2, 1, 1200, false },
306 { 3, 2, 1150, true },
307 { 4, 1, 1100, false },
309 TestData current[] = {
310 { 5, 1, 1000, false },
311 { 6, 2, 800, true },
312 { 7, 1, 500, true },
314 // The expected results are out of relevance order because the top-scoring
315 // allowed to be default match is always pulled to the top.
316 TestData result[] = {
317 { 6, 2, 800, true },
318 { 5, 1, 1000, false },
319 { 3, 2, 799, true },
320 { 7, 1, 500, true },
321 { 4, 1, 499, false },
324 ASSERT_NO_FATAL_FAILURE(RunCopyOldMatchesTest(last, arraysize(last),
325 current, arraysize(current),
326 result, arraysize(result)));
329 // Tests that matches are copied correctly from two distinct providers when
330 // one provider doesn't have a current legal default match.
331 TEST_F(AutocompleteResultTest, CopyOldMatchesWithOneProviderWithoutDefault) {
332 TestData last[] = {
333 { 0, 2, 1250, true },
334 { 1, 2, 1150, true },
335 { 2, 1, 900, false },
336 { 3, 1, 800, false },
337 { 4, 1, 700, false },
339 TestData current[] = {
340 { 5, 1, 1000, true },
341 { 6, 2, 800, false },
342 { 7, 1, 500, true },
344 TestData result[] = {
345 { 5, 1, 1000, true },
346 { 1, 2, 999, true },
347 { 6, 2, 800, false },
348 { 4, 1, 700, false },
349 { 7, 1, 500, true },
352 ASSERT_NO_FATAL_FAILURE(RunCopyOldMatchesTest(last, arraysize(last),
353 current, arraysize(current),
354 result, arraysize(result)));
357 // Tests that matches with empty destination URLs aren't treated as duplicates
358 // and culled.
359 TEST_F(AutocompleteResultTest, SortAndCullEmptyDestinationURLs) {
360 TestData data[] = {
361 { 1, 1, 500, true },
362 { 0, 1, 1100, true },
363 { 1, 1, 1000, true },
364 { 0, 1, 1300, true },
365 { 0, 1, 1200, true },
368 ACMatches matches;
369 PopulateAutocompleteMatches(data, arraysize(data), &matches);
370 matches[1].destination_url = GURL();
371 matches[3].destination_url = GURL();
372 matches[4].destination_url = GURL();
374 AutocompleteInput input(base::string16(), base::string16::npos, std::string(),
375 GURL(), OmniboxEventProto::INVALID_SPEC, false, false,
376 false, true, false, TestSchemeClassifier());
377 AutocompleteResult result;
378 result.AppendMatches(input, matches);
379 result.SortAndCull(input, std::string(), template_url_service_.get());
381 // Of the two results with the same non-empty destination URL, the
382 // lower-relevance one should be dropped. All of the results with empty URLs
383 // should be kept.
384 ASSERT_EQ(4U, result.size());
385 EXPECT_TRUE(result.match_at(0)->destination_url.is_empty());
386 EXPECT_EQ(1300, result.match_at(0)->relevance);
387 EXPECT_TRUE(result.match_at(1)->destination_url.is_empty());
388 EXPECT_EQ(1200, result.match_at(1)->relevance);
389 EXPECT_TRUE(result.match_at(2)->destination_url.is_empty());
390 EXPECT_EQ(1100, result.match_at(2)->relevance);
391 EXPECT_EQ("http://b/", result.match_at(3)->destination_url.spec());
392 EXPECT_EQ(1000, result.match_at(3)->relevance);
395 TEST_F(AutocompleteResultTest, SortAndCullDuplicateSearchURLs) {
396 // Register a template URL that corresponds to 'foo' search engine.
397 TemplateURLData url_data;
398 url_data.SetShortName(base::ASCIIToUTF16("unittest"));
399 url_data.SetKeyword(base::ASCIIToUTF16("foo"));
400 url_data.SetURL("http://www.foo.com/s?q={searchTerms}");
401 template_url_service_.get()->Add(new TemplateURL(url_data));
403 TestData data[] = {
404 { 0, 1, 1300, true },
405 { 1, 1, 1200, true },
406 { 2, 1, 1100, true },
407 { 3, 1, 1000, true },
408 { 4, 2, 900, true },
411 ACMatches matches;
412 PopulateAutocompleteMatches(data, arraysize(data), &matches);
413 matches[0].destination_url = GURL("http://www.foo.com/s?q=foo");
414 matches[1].destination_url = GURL("http://www.foo.com/s?q=foo2");
415 matches[2].destination_url = GURL("http://www.foo.com/s?q=foo&oq=f");
416 matches[3].destination_url = GURL("http://www.foo.com/s?q=foo&aqs=0");
417 matches[4].destination_url = GURL("http://www.foo.com/");
419 AutocompleteInput input(base::string16(), base::string16::npos, std::string(),
420 GURL(), OmniboxEventProto::INVALID_SPEC, false, false,
421 false, true, false, TestSchemeClassifier());
422 AutocompleteResult result;
423 result.AppendMatches(input, matches);
424 result.SortAndCull(input, std::string(), template_url_service_.get());
426 // We expect the 3rd and 4th results to be removed.
427 ASSERT_EQ(3U, result.size());
428 EXPECT_EQ("http://www.foo.com/s?q=foo",
429 result.match_at(0)->destination_url.spec());
430 EXPECT_EQ(1300, result.match_at(0)->relevance);
431 EXPECT_EQ("http://www.foo.com/s?q=foo2",
432 result.match_at(1)->destination_url.spec());
433 EXPECT_EQ(1200, result.match_at(1)->relevance);
434 EXPECT_EQ("http://www.foo.com/",
435 result.match_at(2)->destination_url.spec());
436 EXPECT_EQ(900, result.match_at(2)->relevance);
439 TEST_F(AutocompleteResultTest, SortAndCullWithMatchDups) {
440 // Register a template URL that corresponds to 'foo' search engine.
441 TemplateURLData url_data;
442 url_data.SetShortName(base::ASCIIToUTF16("unittest"));
443 url_data.SetKeyword(base::ASCIIToUTF16("foo"));
444 url_data.SetURL("http://www.foo.com/s?q={searchTerms}");
445 template_url_service_.get()->Add(new TemplateURL(url_data));
447 AutocompleteMatch dup_match;
448 dup_match.destination_url = GURL("http://www.foo.com/s?q=foo&oq=dup");
449 std::vector<AutocompleteMatch> dups;
450 dups.push_back(dup_match);
452 TestData data[] = {
453 { 0, 1, 1300, true, dups },
454 { 1, 1, 1200, true },
455 { 2, 1, 1100, true },
456 { 3, 1, 1000, true, dups },
457 { 4, 2, 900, true },
458 { 5, 1, 800, true },
461 ACMatches matches;
462 PopulateAutocompleteMatches(data, arraysize(data), &matches);
463 matches[0].destination_url = GURL("http://www.foo.com/s?q=foo");
464 matches[1].destination_url = GURL("http://www.foo.com/s?q=foo2");
465 matches[2].destination_url = GURL("http://www.foo.com/s?q=foo&oq=f");
466 matches[3].destination_url = GURL("http://www.foo.com/s?q=foo&aqs=0");
467 matches[4].destination_url = GURL("http://www.foo.com/");
468 matches[5].destination_url = GURL("http://www.foo.com/s?q=foo2&oq=f");
470 AutocompleteInput input(base::string16(), base::string16::npos, std::string(),
471 GURL(), OmniboxEventProto::INVALID_SPEC, false, false,
472 false, true, false, TestSchemeClassifier());
473 AutocompleteResult result;
474 result.AppendMatches(input, matches);
475 result.SortAndCull(input, std::string(), template_url_service_.get());
477 // Expect 3 unique results after SortAndCull().
478 ASSERT_EQ(3U, result.size());
480 // Check that 3rd and 4th result got added to the first result as dups
481 // and also duplicates of the 4th match got copied.
482 ASSERT_EQ(4U, result.match_at(0)->duplicate_matches.size());
483 const AutocompleteMatch* first_match = result.match_at(0);
484 EXPECT_EQ(matches[2].destination_url,
485 first_match->duplicate_matches.at(1).destination_url);
486 EXPECT_EQ(dup_match.destination_url,
487 first_match->duplicate_matches.at(2).destination_url);
488 EXPECT_EQ(matches[3].destination_url,
489 first_match->duplicate_matches.at(3).destination_url);
491 // Check that 6th result started a new list of dups for the second result.
492 ASSERT_EQ(1U, result.match_at(1)->duplicate_matches.size());
493 EXPECT_EQ(matches[5].destination_url,
494 result.match_at(1)->duplicate_matches.at(0).destination_url);
497 TEST_F(AutocompleteResultTest, SortAndCullWithDemotionsByType) {
498 // Add some matches.
499 ACMatches matches;
500 const AutocompleteMatchTestData data[] = {
501 { "http://history-url/", AutocompleteMatchType::HISTORY_URL },
502 { "http://search-what-you-typed/",
503 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
504 { "http://history-title/", AutocompleteMatchType::HISTORY_TITLE },
505 { "http://search-history/", AutocompleteMatchType::SEARCH_HISTORY },
507 PopulateAutocompleteMatchesFromTestData(data, arraysize(data), &matches);
509 // Demote the search history match relevance score.
510 matches.back().relevance = 500;
512 // Add a rule demoting history-url and killing history-title.
514 std::map<std::string, std::string> params;
515 params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] =
516 "1:50,7:100,2:0"; // 3 == HOME_PAGE
517 ASSERT_TRUE(variations::AssociateVariationParams(
518 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
520 base::FieldTrialList::CreateFieldTrial(
521 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
523 AutocompleteInput input(base::string16(), base::string16::npos, std::string(),
524 GURL(), OmniboxEventProto::HOME_PAGE, false, false,
525 false, true, false, TestSchemeClassifier());
526 AutocompleteResult result;
527 result.AppendMatches(input, matches);
528 result.SortAndCull(input, std::string(), template_url_service_.get());
530 // Check the new ordering. The history-title results should be omitted.
531 // We cannot check relevance scores because the matches are sorted by
532 // demoted relevance but the actual relevance scores are not modified.
533 ASSERT_EQ(3u, result.size());
534 EXPECT_EQ("http://search-what-you-typed/",
535 result.match_at(0)->destination_url.spec());
536 EXPECT_EQ("http://history-url/",
537 result.match_at(1)->destination_url.spec());
538 EXPECT_EQ("http://search-history/",
539 result.match_at(2)->destination_url.spec());
542 TEST_F(AutocompleteResultTest, SortAndCullWithMatchDupsAndDemotionsByType) {
543 // Add some matches.
544 ACMatches matches;
545 const AutocompleteMatchTestData data[] = {
546 { "http://search-what-you-typed/",
547 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
548 { "http://dup-url/", AutocompleteMatchType::HISTORY_URL },
549 { "http://dup-url/", AutocompleteMatchType::NAVSUGGEST },
550 { "http://search-url/", AutocompleteMatchType::SEARCH_SUGGEST },
551 { "http://history-url/", AutocompleteMatchType::HISTORY_URL },
553 PopulateAutocompleteMatchesFromTestData(data, arraysize(data), &matches);
555 // Add a rule demoting HISTORY_URL.
557 std::map<std::string, std::string> params;
558 params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":8:*"] =
559 "1:50"; // 8 == INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS
560 ASSERT_TRUE(variations::AssociateVariationParams(
561 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "C", params));
563 base::FieldTrialList::CreateFieldTrial(
564 OmniboxFieldTrial::kBundledExperimentFieldTrialName, "C");
567 AutocompleteInput input(
568 base::string16(), base::string16::npos, std::string(), GURL(),
569 OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS, false,
570 false, false, true, false, TestSchemeClassifier());
571 AutocompleteResult result;
572 result.AppendMatches(input, matches);
573 result.SortAndCull(input, std::string(), template_url_service_.get());
575 // The NAVSUGGEST dup-url stay above search-url since the navsuggest
576 // variant should not be demoted.
577 ASSERT_EQ(4u, result.size());
578 EXPECT_EQ("http://search-what-you-typed/",
579 result.match_at(0)->destination_url.spec());
580 EXPECT_EQ("http://dup-url/",
581 result.match_at(1)->destination_url.spec());
582 EXPECT_EQ(AutocompleteMatchType::NAVSUGGEST,
583 result.match_at(1)->type);
584 EXPECT_EQ("http://search-url/",
585 result.match_at(2)->destination_url.spec());
586 EXPECT_EQ("http://history-url/",
587 result.match_at(3)->destination_url.spec());
591 TEST_F(AutocompleteResultTest, SortAndCullReorderForDefaultMatch) {
592 TestData data[] = {
593 { 0, 1, 1300, true },
594 { 1, 1, 1200, true },
595 { 2, 1, 1100, true },
596 { 3, 1, 1000, true }
600 // Check that reorder doesn't do anything if the top result
601 // is already a legal default match (which is the default from
602 // PopulateAutocompleteMatches()).
603 ACMatches matches;
604 PopulateAutocompleteMatches(data, arraysize(data), &matches);
605 AutocompleteInput input(base::string16(), base::string16::npos,
606 std::string(), GURL(), OmniboxEventProto::HOME_PAGE,
607 false, false, false, true, false,
608 TestSchemeClassifier());
609 AutocompleteResult result;
610 result.AppendMatches(input, matches);
611 result.SortAndCull(input, std::string(), template_url_service_.get());
612 AssertResultMatches(result, data, 4);
616 // Check that reorder swaps up a result appropriately.
617 ACMatches matches;
618 PopulateAutocompleteMatches(data, arraysize(data), &matches);
619 matches[0].allowed_to_be_default_match = false;
620 matches[1].allowed_to_be_default_match = false;
621 AutocompleteInput input(base::string16(), base::string16::npos,
622 std::string(), GURL(), OmniboxEventProto::HOME_PAGE,
623 false, false, false, true, false,
624 TestSchemeClassifier());
625 AutocompleteResult result;
626 result.AppendMatches(input, matches);
627 result.SortAndCull(input, std::string(), template_url_service_.get());
628 ASSERT_EQ(4U, result.size());
629 EXPECT_EQ("http://c/", result.match_at(0)->destination_url.spec());
630 EXPECT_EQ("http://a/", result.match_at(1)->destination_url.spec());
631 EXPECT_EQ("http://b/", result.match_at(2)->destination_url.spec());
632 EXPECT_EQ("http://d/", result.match_at(3)->destination_url.spec());
636 TEST_F(AutocompleteResultTest, TopMatchIsStandaloneVerbatimMatch) {
637 ACMatches matches;
638 AutocompleteResult result;
639 result.AppendMatches(AutocompleteInput(), matches);
641 // Case 1: Result set is empty.
642 EXPECT_FALSE(result.TopMatchIsStandaloneVerbatimMatch());
644 // Case 2: Top match is not a verbatim match.
645 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches, 1, &matches);
646 result.AppendMatches(AutocompleteInput(), matches);
647 EXPECT_FALSE(result.TopMatchIsStandaloneVerbatimMatch());
648 result.Reset();
649 matches.clear();
651 // Case 3: Top match is a verbatim match.
652 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches, 1, &matches);
653 result.AppendMatches(AutocompleteInput(), matches);
654 EXPECT_TRUE(result.TopMatchIsStandaloneVerbatimMatch());
655 result.Reset();
656 matches.clear();
658 // Case 4: Standalone verbatim match found in AutocompleteResult.
659 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches, 1, &matches);
660 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches, 1, &matches);
661 result.AppendMatches(AutocompleteInput(), matches);
662 EXPECT_TRUE(result.TopMatchIsStandaloneVerbatimMatch());
663 result.Reset();
664 matches.clear();