[safe-browsing] Database full hash matches like prefix match.
[chromium-blink-merge.git] / chrome / browser / autocomplete / autocomplete_result_unittest.cc
blobcee2750f497adf5957f0e4508dfb47137276da5c
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"
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 "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"
27 namespace {
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,
48 size_t count,
49 ACMatches* matches) {
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);
54 match.relevance =
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);
62 } // namespace
64 class AutocompleteResultTest : public testing::Test {
65 public:
66 struct TestData {
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").
69 int url_id;
71 // ID of the provider.
72 int provider_id;
74 // Relevance score.
75 int relevance;
77 // Duplicate matches.
78 std::vector<AutocompleteMatch> duplicate_matches;
81 AutocompleteResultTest() {
82 // Destroy the existing FieldTrialList before creating a new one to avoid
83 // a DCHECK.
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 */);
94 #endif
95 test_util_.SetUp();
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,
109 size_t count,
110 ACMatches* matches);
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);
123 protected:
124 TemplateURLServiceTestUtil test_util_;
126 private:
127 scoped_ptr<base::FieldTrialList> field_trial_list_;
129 DISALLOW_COPY_AND_ASSIGN(AutocompleteResultTest);
132 // static
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;
145 // static
146 void AutocompleteResultTest::PopulateAutocompleteMatches(
147 const TestData* data,
148 size_t count,
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,
180 true);
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, &current_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.
204 r1.Swap(&r2);
205 EXPECT_EQ(r1.end(), r1.default_match());
206 EXPECT_EQ(r2.end(), r2.default_match());
208 // Swap with a single match.
209 ACMatches matches;
210 AutocompleteMatch match;
211 match.relevance = 1;
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,
216 true);
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());
222 r1.Swap(&r2);
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) {
234 TestData last[] = {
235 { 0, 0, 1000 },
236 { 1, 0, 500 },
238 TestData current[] = {
239 { 2, 0, 400 },
241 TestData result[] = {
242 { 2, 0, 400 },
243 { 1, 0, 399 },
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) {
254 TestData last[] = {
255 { 0, 0, 1000 },
256 { 1, 1, 500 },
257 { 2, 0, 400 },
258 { 3, 1, 300 },
260 TestData current[] = {
261 { 4, 0, 1100 },
262 { 5, 1, 550 },
264 TestData result[] = {
265 { 4, 0, 1100 },
266 { 5, 1, 550 },
267 { 2, 0, 400 },
268 { 3, 1, 300 },
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
278 // and culled.
279 TEST_F(AutocompleteResultTest, SortAndCullEmptyDestinationURLs) {
280 TestData data[] = {
281 { 1, 0, 500 },
282 { 0, 0, 1100 },
283 { 1, 0, 1000 },
284 { 0, 0, 1300 },
285 { 0, 0, 1200 },
288 ACMatches matches;
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,
299 true);
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
304 // should be kept.
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));
324 TestData data[] = {
325 { 0, 0, 1300 },
326 { 1, 0, 1200 },
327 { 2, 0, 1100 },
328 { 3, 0, 1000 },
329 { 4, 1, 900 },
332 ACMatches matches;
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,
345 true);
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);
374 TestData data[] = {
375 { 0, 0, 1300, dups },
376 { 1, 0, 1200 },
377 { 2, 0, 1100 },
378 { 3, 0, 1000, dups },
379 { 4, 1, 900 },
380 { 5, 0, 800 },
383 ACMatches matches;
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,
397 true);
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) {
421 // Add some matches.
422 ACMatches matches;
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,
451 true);
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) {
467 // Add some matches.
468 ACMatches matches;
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,
496 false, false, true);
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) {
516 TestData data[] = {
517 { 0, 0, 1300 },
518 { 1, 0, 1200 },
519 { 2, 0, 1100 },
520 { 3, 0, 1000 }
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()).
527 ACMatches matches;
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,
534 true);
535 result.SortAndCull(input, test_util_.profile());
536 AssertResultMatches(result, data, 4);
540 // Check that reorder swaps up a result appropriately.
541 ACMatches matches;
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,
550 true);
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");
563 ACMatches matches;
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());
570 matches.clear();
571 result.Reset();
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),
577 &matches);
578 result.AppendMatches(matches);
579 EXPECT_FALSE(result.ShouldHideTopMatch());
580 matches.clear();
581 result.Reset();
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),
587 &matches);
588 result.AppendMatches(matches);
589 EXPECT_FALSE(result.ShouldHideTopMatch());
592 TEST_F(AutocompleteResultTest, ShouldHideTopMatchAfterCopy) {
593 base::FieldTrialList::CreateFieldTrial("InstantExtended",
594 "Group1 hide_verbatim:1");
595 ACMatches matches;
597 // Case 1: Top match is a verbatim match followed by only copied matches.
598 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches,
599 arraysize(kVerbatimMatches),
600 &matches);
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());
606 result.Reset();
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());
612 result.Reset();
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");
626 ACMatches matches;
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) {
635 ACMatches matches;
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());
646 result.Reset();
647 matches.clear();
649 // Case 3: Top match is a verbatim match.
650 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches, 1, &matches);
651 result.AppendMatches(matches);
652 EXPECT_TRUE(result.TopMatchIsStandaloneVerbatimMatch());
653 result.Reset();
654 matches.clear();
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());
661 result.Reset();
662 matches.clear();
664 // Case 5: Multiple verbatim matches found in AutocompleteResult.
665 PopulateAutocompleteMatchesFromTestData(kVerbatimMatches,
666 arraysize(kVerbatimMatches),
667 &matches);
668 result.AppendMatches(matches);
669 EXPECT_FALSE(result.ShouldHideTopMatch());