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"
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
;
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
,
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
);
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
{
66 MockAutocompleteProvider(Type type
): AutocompleteProvider(type
) {}
68 void Start(const AutocompleteInput
& input
, bool minimal_changes
) override
{}
71 ~MockAutocompleteProvider() override
{}
76 class AutocompleteResultTest
: public testing::Test
{
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").
83 // ID of the provider.
89 // Allowed to be default match status.
90 bool allowed_to_be_default_match
;
93 std::vector
<AutocompleteMatch
> duplicate_matches
;
96 AutocompleteResultTest() {
97 // Destroy the existing FieldTrialList before creating a new one to avoid
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
,
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();
143 scoped_ptr
<TemplateURLService
> template_url_service_
;
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
,
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
, ¤t_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.
228 EXPECT_EQ(r1
.end(), r1
.default_match());
229 EXPECT_EQ(r2
.end(), r2
.default_match());
231 // Swap with a single match.
233 AutocompleteMatch match
;
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());
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
) {
258 { 0, 1, 1000, true },
261 TestData current
[] = {
264 TestData result
[] = {
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
) {
279 { 0, 1, 1300, true },
280 { 1, 1, 1200, true },
281 { 2, 1, 1100, true },
283 TestData current
[] = {
284 { 3, 1, 1000, false },
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
[] = {
291 { 3, 1, 1000, false },
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
) {
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 },
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
[] = {
318 { 5, 1, 1000, false },
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
) {
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 },
344 TestData result
[] = {
345 { 5, 1, 1000, true },
347 { 6, 2, 800, false },
348 { 4, 1, 700, false },
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
359 TEST_F(AutocompleteResultTest
, SortAndCullEmptyDestinationURLs
) {
362 { 0, 1, 1100, true },
363 { 1, 1, 1000, true },
364 { 0, 1, 1300, true },
365 { 0, 1, 1200, true },
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
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
));
404 { 0, 1, 1300, true },
405 { 1, 1, 1200, true },
406 { 2, 1, 1100, true },
407 { 3, 1, 1000, true },
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
);
453 { 0, 1, 1300, true, dups
},
454 { 1, 1, 1200, true },
455 { 2, 1, 1100, true },
456 { 3, 1, 1000, true, dups
},
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
) {
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
) {
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
) {
593 { 0, 1, 1300, true },
594 { 1, 1, 1200, true },
595 { 2, 1, 1100, 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()).
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.
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
) {
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());
651 // Case 3: Top match is a verbatim match.
652 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
653 result
.AppendMatches(AutocompleteInput(), matches
);
654 EXPECT_TRUE(result
.TopMatchIsStandaloneVerbatimMatch());
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());