1 // Copyright (c) 2012 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 "chrome/browser/autocomplete/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 "chrome/browser/autocomplete/autocomplete_input.h"
15 #include "chrome/browser/autocomplete/autocomplete_match.h"
16 #include "chrome/browser/autocomplete/autocomplete_provider.h"
17 #include "chrome/browser/omnibox/omnibox_field_trial.h"
18 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
19 #include "chrome/browser/search_engines/template_url_service.h"
20 #include "chrome/browser/search_engines/template_url_service_test_util.h"
21 #include "chrome/common/autocomplete_match_type.h"
22 #include "chrome/common/metrics/variations/variations_util.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "components/variations/entropy_provider.h"
25 #include "testing/gtest/include/gtest/gtest.h"
29 struct AutocompleteMatchTestData
{
30 std::string destination_url
;
31 AutocompleteMatch::Type type
;
34 const AutocompleteMatchTestData kVerbatimMatches
[] = {
35 { "http://search-what-you-typed/",
36 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
},
37 { "http://url-what-you-typed/", AutocompleteMatchType::URL_WHAT_YOU_TYPED
},
40 const AutocompleteMatchTestData kNonVerbatimMatches
[] = {
41 { "http://search-history/", AutocompleteMatchType::SEARCH_HISTORY
},
42 { "http://history-title/", AutocompleteMatchType::HISTORY_TITLE
},
45 // Adds |count| AutocompleteMatches to |matches|.
46 void PopulateAutocompleteMatchesFromTestData(
47 const AutocompleteMatchTestData
* data
,
50 ASSERT_TRUE(matches
!= NULL
);
51 for (size_t i
= 0; i
< count
; ++i
) {
52 AutocompleteMatch match
;
53 match
.destination_url
= GURL(data
[i
].destination_url
);
55 matches
->empty() ? 1300 : (matches
->back().relevance
- 100);
56 match
.allowed_to_be_default_match
= true;
57 match
.type
= data
[i
].type
;
58 matches
->push_back(match
);
64 class AutocompleteResultTest
: public testing::Test
{
67 // Used to build a url for the AutocompleteMatch. The URL becomes
68 // "http://" + ('a' + |url_id|) (e.g. an ID of 2 yields "http://b").
71 // ID of the provider.
78 std::vector
<AutocompleteMatch
> duplicate_matches
;
81 AutocompleteResultTest() {
82 // Destroy the existing FieldTrialList before creating a new one to avoid
84 field_trial_list_
.reset();
85 field_trial_list_
.reset(new base::FieldTrialList(
86 new metrics::SHA1EntropyProvider("foo")));
87 chrome_variations::testing::ClearAllVariationParams();
90 virtual void SetUp() OVERRIDE
{
91 #if defined(OS_ANDROID)
92 TemplateURLPrepopulateData::InitCountryCode(
93 std::string() /* unknown country code */);
96 test_util_
.VerifyLoad();
99 virtual void TearDown() OVERRIDE
{
100 test_util_
.TearDown();
103 // Configures |match| from |data|.
104 static void PopulateAutocompleteMatch(const TestData
& data
,
105 AutocompleteMatch
* match
);
107 // Adds |count| AutocompleteMatches to |matches|.
108 static void PopulateAutocompleteMatches(const TestData
* data
,
112 // Asserts that |result| has |expected_count| matches matching |expected|.
113 void AssertResultMatches(const AutocompleteResult
& result
,
114 const TestData
* expected
,
115 size_t expected_count
);
117 // Creates an AutocompleteResult from |last| and |current|. The two are
118 // merged by |CopyOldMatches| and compared by |AssertResultMatches|.
119 void RunCopyOldMatchesTest(const TestData
* last
, size_t last_size
,
120 const TestData
* current
, size_t current_size
,
121 const TestData
* expected
, size_t expected_size
);
124 TemplateURLServiceTestUtil test_util_
;
127 scoped_ptr
<base::FieldTrialList
> field_trial_list_
;
129 DISALLOW_COPY_AND_ASSIGN(AutocompleteResultTest
);
133 void AutocompleteResultTest::PopulateAutocompleteMatch(
134 const TestData
& data
,
135 AutocompleteMatch
* match
) {
136 match
->provider
= reinterpret_cast<AutocompleteProvider
*>(data
.provider_id
);
137 match
->fill_into_edit
= base::IntToString16(data
.url_id
);
138 std::string
url_id(1, data
.url_id
+ 'a');
139 match
->destination_url
= GURL("http://" + url_id
);
140 match
->relevance
= data
.relevance
;
141 match
->allowed_to_be_default_match
= true;
142 match
->duplicate_matches
= data
.duplicate_matches
;
146 void AutocompleteResultTest::PopulateAutocompleteMatches(
147 const TestData
* data
,
149 ACMatches
* matches
) {
150 for (size_t i
= 0; i
< count
; ++i
) {
151 AutocompleteMatch match
;
152 PopulateAutocompleteMatch(data
[i
], &match
);
153 matches
->push_back(match
);
157 void AutocompleteResultTest::AssertResultMatches(
158 const AutocompleteResult
& result
,
159 const TestData
* expected
,
160 size_t expected_count
) {
161 ASSERT_EQ(expected_count
, result
.size());
162 for (size_t i
= 0; i
< expected_count
; ++i
) {
163 AutocompleteMatch expected_match
;
164 PopulateAutocompleteMatch(expected
[i
], &expected_match
);
165 const AutocompleteMatch
& match
= *(result
.begin() + i
);
166 EXPECT_EQ(expected_match
.provider
, match
.provider
) << i
;
167 EXPECT_EQ(expected_match
.relevance
, match
.relevance
) << i
;
168 EXPECT_EQ(expected_match
.destination_url
.spec(),
169 match
.destination_url
.spec()) << i
;
173 void AutocompleteResultTest::RunCopyOldMatchesTest(
174 const TestData
* last
, size_t last_size
,
175 const TestData
* current
, size_t current_size
,
176 const TestData
* expected
, size_t expected_size
) {
177 AutocompleteInput
input(base::ASCIIToUTF16("a"), base::string16::npos
,
178 base::string16(), GURL(),
179 AutocompleteInput::INVALID_SPEC
, false, false, false,
182 ACMatches last_matches
;
183 PopulateAutocompleteMatches(last
, last_size
, &last_matches
);
184 AutocompleteResult last_result
;
185 last_result
.AppendMatches(last_matches
);
186 last_result
.SortAndCull(input
, test_util_
.profile());
188 ACMatches current_matches
;
189 PopulateAutocompleteMatches(current
, current_size
, ¤t_matches
);
190 AutocompleteResult current_result
;
191 current_result
.AppendMatches(current_matches
);
192 current_result
.SortAndCull(input
, test_util_
.profile());
193 current_result
.CopyOldMatches(input
, last_result
, test_util_
.profile());
195 AssertResultMatches(current_result
, expected
, expected_size
);
198 // Assertion testing for AutocompleteResult::Swap.
199 TEST_F(AutocompleteResultTest
, Swap
) {
200 AutocompleteResult r1
;
201 AutocompleteResult r2
;
203 // Swap with empty shouldn't do anything interesting.
205 EXPECT_EQ(r1
.end(), r1
.default_match());
206 EXPECT_EQ(r2
.end(), r2
.default_match());
208 // Swap with a single match.
210 AutocompleteMatch match
;
212 match
.allowed_to_be_default_match
= true;
213 AutocompleteInput
input(base::ASCIIToUTF16("a"), base::string16::npos
,
214 base::string16(), GURL(),
215 AutocompleteInput::INVALID_SPEC
, false, false, false,
217 matches
.push_back(match
);
218 r1
.AppendMatches(matches
);
219 r1
.SortAndCull(input
, test_util_
.profile());
220 EXPECT_EQ(r1
.begin(), r1
.default_match());
221 EXPECT_EQ("http://a/", r1
.alternate_nav_url().spec());
223 EXPECT_TRUE(r1
.empty());
224 EXPECT_EQ(r1
.end(), r1
.default_match());
225 EXPECT_TRUE(r1
.alternate_nav_url().is_empty());
226 ASSERT_FALSE(r2
.empty());
227 EXPECT_EQ(r2
.begin(), r2
.default_match());
228 EXPECT_EQ("http://a/", r2
.alternate_nav_url().spec());
231 // Tests that if the new results have a lower max relevance score than last,
232 // any copied results have their relevance shifted down.
233 TEST_F(AutocompleteResultTest
, CopyOldMatches
) {
238 TestData current
[] = {
241 TestData result
[] = {
246 ASSERT_NO_FATAL_FAILURE(
247 RunCopyOldMatchesTest(last
, ARRAYSIZE_UNSAFE(last
),
248 current
, ARRAYSIZE_UNSAFE(current
),
249 result
, ARRAYSIZE_UNSAFE(result
)));
252 // Tests that matches are copied correctly from two distinct providers.
253 TEST_F(AutocompleteResultTest
, CopyOldMatches2
) {
260 TestData current
[] = {
264 TestData result
[] = {
271 ASSERT_NO_FATAL_FAILURE(
272 RunCopyOldMatchesTest(last
, ARRAYSIZE_UNSAFE(last
),
273 current
, ARRAYSIZE_UNSAFE(current
),
274 result
, ARRAYSIZE_UNSAFE(result
)));
277 // Tests that matches with empty destination URLs aren't treated as duplicates
279 TEST_F(AutocompleteResultTest
, SortAndCullEmptyDestinationURLs
) {
289 PopulateAutocompleteMatches(data
, arraysize(data
), &matches
);
290 matches
[1].destination_url
= GURL();
291 matches
[3].destination_url
= GURL();
292 matches
[4].destination_url
= GURL();
294 AutocompleteResult result
;
295 result
.AppendMatches(matches
);
296 AutocompleteInput
input(base::string16(), base::string16::npos
,
297 base::string16(), GURL(),
298 AutocompleteInput::INVALID_SPEC
, false, false, false,
300 result
.SortAndCull(input
, test_util_
.profile());
302 // Of the two results with the same non-empty destination URL, the
303 // lower-relevance one should be dropped. All of the results with empty URLs
305 ASSERT_EQ(4U, result
.size());
306 EXPECT_TRUE(result
.match_at(0)->destination_url
.is_empty());
307 EXPECT_EQ(1300, result
.match_at(0)->relevance
);
308 EXPECT_TRUE(result
.match_at(1)->destination_url
.is_empty());
309 EXPECT_EQ(1200, result
.match_at(1)->relevance
);
310 EXPECT_TRUE(result
.match_at(2)->destination_url
.is_empty());
311 EXPECT_EQ(1100, result
.match_at(2)->relevance
);
312 EXPECT_EQ("http://b/", result
.match_at(3)->destination_url
.spec());
313 EXPECT_EQ(1000, result
.match_at(3)->relevance
);
316 TEST_F(AutocompleteResultTest
, SortAndCullDuplicateSearchURLs
) {
317 // Register a template URL that corresponds to 'foo' search engine.
318 TemplateURLData url_data
;
319 url_data
.short_name
= base::ASCIIToUTF16("unittest");
320 url_data
.SetKeyword(base::ASCIIToUTF16("foo"));
321 url_data
.SetURL("http://www.foo.com/s?q={searchTerms}");
322 test_util_
.model()->Add(new TemplateURL(test_util_
.profile(), url_data
));
333 PopulateAutocompleteMatches(data
, arraysize(data
), &matches
);
334 matches
[0].destination_url
= GURL("http://www.foo.com/s?q=foo");
335 matches
[1].destination_url
= GURL("http://www.foo.com/s?q=foo2");
336 matches
[2].destination_url
= GURL("http://www.foo.com/s?q=foo&oq=f");
337 matches
[3].destination_url
= GURL("http://www.foo.com/s?q=foo&aqs=0");
338 matches
[4].destination_url
= GURL("http://www.foo.com/");
340 AutocompleteResult result
;
341 result
.AppendMatches(matches
);
342 AutocompleteInput
input(base::string16(), base::string16::npos
,
343 base::string16(), GURL(),
344 AutocompleteInput::INVALID_SPEC
, false, false, false,
346 result
.SortAndCull(input
, test_util_
.profile());
348 // We expect the 3rd and 4th results to be removed.
349 ASSERT_EQ(3U, result
.size());
350 EXPECT_EQ("http://www.foo.com/s?q=foo",
351 result
.match_at(0)->destination_url
.spec());
352 EXPECT_EQ(1300, result
.match_at(0)->relevance
);
353 EXPECT_EQ("http://www.foo.com/s?q=foo2",
354 result
.match_at(1)->destination_url
.spec());
355 EXPECT_EQ(1200, result
.match_at(1)->relevance
);
356 EXPECT_EQ("http://www.foo.com/",
357 result
.match_at(2)->destination_url
.spec());
358 EXPECT_EQ(900, result
.match_at(2)->relevance
);
361 TEST_F(AutocompleteResultTest
, SortAndCullWithMatchDups
) {
362 // Register a template URL that corresponds to 'foo' search engine.
363 TemplateURLData url_data
;
364 url_data
.short_name
= base::ASCIIToUTF16("unittest");
365 url_data
.SetKeyword(base::ASCIIToUTF16("foo"));
366 url_data
.SetURL("http://www.foo.com/s?q={searchTerms}");
367 test_util_
.model()->Add(new TemplateURL(test_util_
.profile(), url_data
));
369 AutocompleteMatch dup_match
;
370 dup_match
.destination_url
= GURL("http://www.foo.com/s?q=foo&oq=dup");
371 std::vector
<AutocompleteMatch
> dups
;
372 dups
.push_back(dup_match
);
375 { 0, 0, 1300, dups
},
378 { 3, 0, 1000, dups
},
384 PopulateAutocompleteMatches(data
, arraysize(data
), &matches
);
385 matches
[0].destination_url
= GURL("http://www.foo.com/s?q=foo");
386 matches
[1].destination_url
= GURL("http://www.foo.com/s?q=foo2");
387 matches
[2].destination_url
= GURL("http://www.foo.com/s?q=foo&oq=f");
388 matches
[3].destination_url
= GURL("http://www.foo.com/s?q=foo&aqs=0");
389 matches
[4].destination_url
= GURL("http://www.foo.com/");
390 matches
[5].destination_url
= GURL("http://www.foo.com/s?q=foo2&oq=f");
392 AutocompleteResult result
;
393 result
.AppendMatches(matches
);
394 AutocompleteInput
input(base::string16(), base::string16::npos
,
395 base::string16(), GURL(),
396 AutocompleteInput::INVALID_SPEC
, false, false, false,
398 result
.SortAndCull(input
, test_util_
.profile());
400 // Expect 3 unique results after SortAndCull().
401 ASSERT_EQ(3U, result
.size());
403 // Check that 3rd and 4th result got added to the first result as dups
404 // and also duplicates of the 4th match got copied.
405 ASSERT_EQ(4U, result
.match_at(0)->duplicate_matches
.size());
406 const AutocompleteMatch
* first_match
= result
.match_at(0);
407 EXPECT_EQ(matches
[2].destination_url
,
408 first_match
->duplicate_matches
.at(1).destination_url
);
409 EXPECT_EQ(dup_match
.destination_url
,
410 first_match
->duplicate_matches
.at(2).destination_url
);
411 EXPECT_EQ(matches
[3].destination_url
,
412 first_match
->duplicate_matches
.at(3).destination_url
);
414 // Check that 6th result started a new list of dups for the second result.
415 ASSERT_EQ(1U, result
.match_at(1)->duplicate_matches
.size());
416 EXPECT_EQ(matches
[5].destination_url
,
417 result
.match_at(1)->duplicate_matches
.at(0).destination_url
);
420 TEST_F(AutocompleteResultTest
, SortAndCullWithDemotionsByType
) {
423 const AutocompleteMatchTestData data
[] = {
424 { "http://history-url/", AutocompleteMatchType::HISTORY_URL
},
425 { "http://search-what-you-typed/",
426 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
},
427 { "http://history-title/", AutocompleteMatchType::HISTORY_TITLE
},
428 { "http://search-history/", AutocompleteMatchType::SEARCH_HISTORY
},
430 PopulateAutocompleteMatchesFromTestData(data
, arraysize(data
), &matches
);
432 // Demote the search history match relevance score.
433 matches
.back().relevance
= 500;
435 // Add a rule demoting history-url and killing history-title.
437 std::map
<std::string
, std::string
> params
;
438 params
[std::string(OmniboxFieldTrial::kDemoteByTypeRule
) + ":3:*"] =
439 "1:50,7:100,2:0"; // 3 == HOME_PAGE
440 ASSERT_TRUE(chrome_variations::AssociateVariationParams(
441 OmniboxFieldTrial::kBundledExperimentFieldTrialName
, "A", params
));
443 base::FieldTrialList::CreateFieldTrial(
444 OmniboxFieldTrial::kBundledExperimentFieldTrialName
, "A");
446 AutocompleteResult result
;
447 result
.AppendMatches(matches
);
448 AutocompleteInput
input(base::string16(), base::string16::npos
,
449 base::string16(), GURL(),
450 AutocompleteInput::HOME_PAGE
, false, false, false,
452 result
.SortAndCull(input
, test_util_
.profile());
454 // Check the new ordering. The history-title results should be omitted.
455 // We cannot check relevance scores because the matches are sorted by
456 // demoted relevance but the actual relevance scores are not modified.
457 ASSERT_EQ(3u, result
.size());
458 EXPECT_EQ("http://search-what-you-typed/",
459 result
.match_at(0)->destination_url
.spec());
460 EXPECT_EQ("http://history-url/",
461 result
.match_at(1)->destination_url
.spec());
462 EXPECT_EQ("http://search-history/",
463 result
.match_at(2)->destination_url
.spec());
466 TEST_F(AutocompleteResultTest
, SortAndCullWithMatchDupsAndDemotionsByType
) {
469 const AutocompleteMatchTestData data
[] = {
470 { "http://search-what-you-typed/",
471 AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED
},
472 { "http://dup-url/", AutocompleteMatchType::HISTORY_URL
},
473 { "http://dup-url/", AutocompleteMatchType::NAVSUGGEST
},
474 { "http://search-url/", AutocompleteMatchType::SEARCH_SUGGEST
},
475 { "http://history-url/", AutocompleteMatchType::HISTORY_URL
},
477 PopulateAutocompleteMatchesFromTestData(data
, arraysize(data
), &matches
);
479 // Add a rule demoting HISTORY_URL.
481 std::map
<std::string
, std::string
> params
;
482 params
[std::string(OmniboxFieldTrial::kDemoteByTypeRule
) + ":8:*"] =
483 "1:50"; // 8 == INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS
484 ASSERT_TRUE(chrome_variations::AssociateVariationParams(
485 OmniboxFieldTrial::kBundledExperimentFieldTrialName
, "C", params
));
487 base::FieldTrialList::CreateFieldTrial(
488 OmniboxFieldTrial::kBundledExperimentFieldTrialName
, "C");
491 AutocompleteResult result
;
492 result
.AppendMatches(matches
);
493 AutocompleteInput
input(
494 base::string16(), base::string16::npos
, base::string16(), GURL(),
495 AutocompleteInput::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS
, false,
497 result
.SortAndCull(input
, test_util_
.profile());
499 // The NAVSUGGEST dup-url stay above search-url since the navsuggest
500 // variant should not be demoted.
501 ASSERT_EQ(4u, result
.size());
502 EXPECT_EQ("http://search-what-you-typed/",
503 result
.match_at(0)->destination_url
.spec());
504 EXPECT_EQ("http://dup-url/",
505 result
.match_at(1)->destination_url
.spec());
506 EXPECT_EQ(AutocompleteMatchType::NAVSUGGEST
,
507 result
.match_at(1)->type
);
508 EXPECT_EQ("http://search-url/",
509 result
.match_at(2)->destination_url
.spec());
510 EXPECT_EQ("http://history-url/",
511 result
.match_at(3)->destination_url
.spec());
515 TEST_F(AutocompleteResultTest
, SortAndCullReorderForDefaultMatch
) {
524 // Check that reorder doesn't do anything if the top result
525 // is already a legal default match (which is the default from
526 // PopulateAutocompleteMatches()).
528 PopulateAutocompleteMatches(data
, arraysize(data
), &matches
);
529 AutocompleteResult result
;
530 result
.AppendMatches(matches
);
531 AutocompleteInput
input(base::string16(), base::string16::npos
,
532 base::string16(), GURL(),
533 AutocompleteInput::HOME_PAGE
, false, false, false,
535 result
.SortAndCull(input
, test_util_
.profile());
536 AssertResultMatches(result
, data
, 4);
540 // Check that reorder swaps up a result appropriately.
542 PopulateAutocompleteMatches(data
, arraysize(data
), &matches
);
543 matches
[0].allowed_to_be_default_match
= false;
544 matches
[1].allowed_to_be_default_match
= false;
545 AutocompleteResult result
;
546 result
.AppendMatches(matches
);
547 AutocompleteInput
input(base::string16(), base::string16::npos
,
548 base::string16(), GURL(),
549 AutocompleteInput::HOME_PAGE
, false, false, false,
551 result
.SortAndCull(input
, test_util_
.profile());
552 ASSERT_EQ(4U, result
.size());
553 EXPECT_EQ("http://c/", result
.match_at(0)->destination_url
.spec());
554 EXPECT_EQ("http://a/", result
.match_at(1)->destination_url
.spec());
555 EXPECT_EQ("http://b/", result
.match_at(2)->destination_url
.spec());
556 EXPECT_EQ("http://d/", result
.match_at(3)->destination_url
.spec());
560 TEST_F(AutocompleteResultTest
, ShouldHideTopMatch
) {
561 base::FieldTrialList::CreateFieldTrial("InstantExtended",
562 "Group1 hide_verbatim:1");
565 // Case 1: Top match is a verbatim match.
566 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
567 AutocompleteResult result
;
568 result
.AppendMatches(matches
);
569 EXPECT_TRUE(result
.ShouldHideTopMatch());
573 // Case 2: If the verbatim first match is followed by another verbatim match,
574 // don't hide the top verbatim match.
575 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
,
576 arraysize(kVerbatimMatches
),
578 result
.AppendMatches(matches
);
579 EXPECT_FALSE(result
.ShouldHideTopMatch());
583 // Case 3: Top match is not a verbatim match. Do not hide the top match.
584 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches
, 1, &matches
);
585 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
,
586 arraysize(kVerbatimMatches
),
588 result
.AppendMatches(matches
);
589 EXPECT_FALSE(result
.ShouldHideTopMatch());
592 TEST_F(AutocompleteResultTest
, ShouldHideTopMatchAfterCopy
) {
593 base::FieldTrialList::CreateFieldTrial("InstantExtended",
594 "Group1 hide_verbatim:1");
597 // Case 1: Top match is a verbatim match followed by only copied matches.
598 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
,
599 arraysize(kVerbatimMatches
),
601 for (size_t i
= 1; i
< arraysize(kVerbatimMatches
); ++i
)
602 matches
[i
].from_previous
= true;
603 AutocompleteResult result
;
604 result
.AppendMatches(matches
);
605 EXPECT_TRUE(result
.ShouldHideTopMatch());
608 // Case 2: The copied matches are then followed by a non-verbatim match.
609 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches
, 1, &matches
);
610 result
.AppendMatches(matches
);
611 EXPECT_TRUE(result
.ShouldHideTopMatch());
614 // Case 3: The copied matches are instead followed by a verbatim match.
615 matches
.back().from_previous
= true;
616 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
617 result
.AppendMatches(matches
);
618 EXPECT_FALSE(result
.ShouldHideTopMatch());
621 TEST_F(AutocompleteResultTest
, DoNotHideTopMatch_FieldTrialFlagDisabled
) {
622 // This test config is identical to ShouldHideTopMatch test ("Case 1") except
623 // that the "hide_verbatim" flag is disabled in the field trials.
624 base::FieldTrialList::CreateFieldTrial("InstantExtended",
625 "Group1 hide_verbatim:0");
627 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
628 AutocompleteResult result
;
629 result
.AppendMatches(matches
);
630 // Field trial flag "hide_verbatim" is disabled. Do not hide top match.
631 EXPECT_FALSE(result
.ShouldHideTopMatch());
634 TEST_F(AutocompleteResultTest
, TopMatchIsStandaloneVerbatimMatch
) {
636 AutocompleteResult result
;
637 result
.AppendMatches(matches
);
639 // Case 1: Result set is empty.
640 EXPECT_FALSE(result
.TopMatchIsStandaloneVerbatimMatch());
642 // Case 2: Top match is not a verbatim match.
643 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches
, 1, &matches
);
644 result
.AppendMatches(matches
);
645 EXPECT_FALSE(result
.TopMatchIsStandaloneVerbatimMatch());
649 // Case 3: Top match is a verbatim match.
650 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
651 result
.AppendMatches(matches
);
652 EXPECT_TRUE(result
.TopMatchIsStandaloneVerbatimMatch());
656 // Case 4: Standalone verbatim match found in AutocompleteResult.
657 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
, 1, &matches
);
658 PopulateAutocompleteMatchesFromTestData(kNonVerbatimMatches
, 1, &matches
);
659 result
.AppendMatches(matches
);
660 EXPECT_TRUE(result
.TopMatchIsStandaloneVerbatimMatch());
664 // Case 5: Multiple verbatim matches found in AutocompleteResult.
665 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches
,
666 arraysize(kVerbatimMatches
),
668 result
.AppendMatches(matches
);
669 EXPECT_FALSE(result
.ShouldHideTopMatch());