• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/autocomplete/autocomplete_result.h"
6 
7 #include "base/memory/scoped_ptr.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/autocomplete/autocomplete_input.h"
13 #include "chrome/browser/autocomplete/autocomplete_match.h"
14 #include "chrome/browser/autocomplete/autocomplete_provider.h"
15 #include "chrome/browser/omnibox/omnibox_field_trial.h"
16 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
17 #include "chrome/browser/search_engines/template_url_service.h"
18 #include "chrome/browser/search_engines/template_url_service_test_util.h"
19 #include "chrome/common/autocomplete_match_type.h"
20 #include "chrome/common/metrics/variations/variations_util.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "components/variations/entropy_provider.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 namespace {
26 
27 // Creates an AutocompleteMatch using |destination_url| and |type| and appends
28 // it to |matches|.
AddMatch(const std::string & destination_url,AutocompleteMatch::Type type,ACMatches * matches)29 void AddMatch(const std::string& destination_url, AutocompleteMatch::Type type,
30               ACMatches* matches) {
31   ASSERT_TRUE(matches != NULL);
32   AutocompleteMatch* last_match =
33     !matches->empty() ? &((*matches)[matches->size() - 1]) : NULL;
34   AutocompleteMatch match;
35   match.destination_url = GURL(destination_url);
36   match.relevance = last_match ? last_match->relevance - 100 : 1300;
37   match.allowed_to_be_default_match = true;
38   match.type = type;
39   matches->push_back(match);
40 }
41 
42 }  // namespace
43 
44 class AutocompleteResultTest : public testing::Test  {
45  public:
46   struct TestData {
47     // Used to build a url for the AutocompleteMatch. The URL becomes
48     // "http://" + ('a' + |url_id|) (e.g. an ID of 2 yields "http://b").
49     int url_id;
50 
51     // ID of the provider.
52     int provider_id;
53 
54     // Relevance score.
55     int relevance;
56   };
57 
AutocompleteResultTest()58   AutocompleteResultTest() {
59     // Destroy the existing FieldTrialList before creating a new one to avoid
60     // a DCHECK.
61     field_trial_list_.reset();
62     field_trial_list_.reset(new base::FieldTrialList(
63         new metrics::SHA1EntropyProvider("foo")));
64     chrome_variations::testing::ClearAllVariationParams();
65   }
66 
SetUp()67   virtual void SetUp() OVERRIDE {
68 #if defined(OS_ANDROID)
69     TemplateURLPrepopulateData::InitCountryCode(
70         std::string() /* unknown country code */);
71 #endif
72     test_util_.SetUp();
73     test_util_.VerifyLoad();
74   }
75 
TearDown()76   virtual void TearDown() OVERRIDE {
77     test_util_.TearDown();
78   }
79 
80   // Configures |match| from |data|.
81   static void PopulateAutocompleteMatch(const TestData& data,
82                                         AutocompleteMatch* match);
83 
84   // Adds |count| AutocompleteMatches to |matches|.
85   static void PopulateAutocompleteMatches(const TestData* data,
86                                           size_t count,
87                                           ACMatches* matches);
88 
89   // Asserts that |result| has |expected_count| matches matching |expected|.
90   void AssertResultMatches(const AutocompleteResult& result,
91                            const TestData* expected,
92                            size_t expected_count);
93 
94   // Creates an AutocompleteResult from |last| and |current|. The two are
95   // merged by |CopyOldMatches| and compared by |AssertResultMatches|.
96   void RunCopyOldMatchesTest(const TestData* last, size_t last_size,
97                              const TestData* current, size_t current_size,
98                              const TestData* expected, size_t expected_size);
99 
100  protected:
101   TemplateURLServiceTestUtil test_util_;
102 
103  private:
104   scoped_ptr<base::FieldTrialList> field_trial_list_;
105 
106   DISALLOW_COPY_AND_ASSIGN(AutocompleteResultTest);
107 };
108 
109 // static
PopulateAutocompleteMatch(const TestData & data,AutocompleteMatch * match)110 void AutocompleteResultTest::PopulateAutocompleteMatch(
111     const TestData& data,
112     AutocompleteMatch* match) {
113   match->provider = reinterpret_cast<AutocompleteProvider*>(data.provider_id);
114   match->fill_into_edit = base::IntToString16(data.url_id);
115   std::string url_id(1, data.url_id + 'a');
116   match->destination_url = GURL("http://" + url_id);
117   match->relevance = data.relevance;
118   match->allowed_to_be_default_match = true;
119 }
120 
121 // static
PopulateAutocompleteMatches(const TestData * data,size_t count,ACMatches * matches)122 void AutocompleteResultTest::PopulateAutocompleteMatches(
123     const TestData* data,
124     size_t count,
125     ACMatches* matches) {
126   for (size_t i = 0; i < count; ++i) {
127     AutocompleteMatch match;
128     PopulateAutocompleteMatch(data[i], &match);
129     matches->push_back(match);
130   }
131 }
132 
AssertResultMatches(const AutocompleteResult & result,const TestData * expected,size_t expected_count)133 void AutocompleteResultTest::AssertResultMatches(
134     const AutocompleteResult& result,
135     const TestData* expected,
136     size_t expected_count) {
137   ASSERT_EQ(expected_count, result.size());
138   for (size_t i = 0; i < expected_count; ++i) {
139     AutocompleteMatch expected_match;
140     PopulateAutocompleteMatch(expected[i], &expected_match);
141     const AutocompleteMatch& match = *(result.begin() + i);
142     EXPECT_EQ(expected_match.provider, match.provider) << i;
143     EXPECT_EQ(expected_match.relevance, match.relevance) << i;
144     EXPECT_EQ(expected_match.destination_url.spec(),
145               match.destination_url.spec()) << i;
146   }
147 }
148 
RunCopyOldMatchesTest(const TestData * last,size_t last_size,const TestData * current,size_t current_size,const TestData * expected,size_t expected_size)149 void AutocompleteResultTest::RunCopyOldMatchesTest(
150     const TestData* last, size_t last_size,
151     const TestData* current, size_t current_size,
152     const TestData* expected, size_t expected_size) {
153   AutocompleteInput input(ASCIIToUTF16("a"), base::string16::npos,
154                           base::string16(), GURL(),
155                           AutocompleteInput::INVALID_SPEC, false, false, false,
156                           AutocompleteInput::ALL_MATCHES);
157 
158   ACMatches last_matches;
159   PopulateAutocompleteMatches(last, last_size, &last_matches);
160   AutocompleteResult last_result;
161   last_result.AppendMatches(last_matches);
162   last_result.SortAndCull(input, test_util_.profile());
163 
164   ACMatches current_matches;
165   PopulateAutocompleteMatches(current, current_size, &current_matches);
166   AutocompleteResult current_result;
167   current_result.AppendMatches(current_matches);
168   current_result.SortAndCull(input, test_util_.profile());
169   current_result.CopyOldMatches(input, last_result, test_util_.profile());
170 
171   AssertResultMatches(current_result, expected, expected_size);
172 }
173 
174 // Assertion testing for AutocompleteResult::Swap.
TEST_F(AutocompleteResultTest,Swap)175 TEST_F(AutocompleteResultTest, Swap) {
176   AutocompleteResult r1;
177   AutocompleteResult r2;
178 
179   // Swap with empty shouldn't do anything interesting.
180   r1.Swap(&r2);
181   EXPECT_EQ(r1.end(), r1.default_match());
182   EXPECT_EQ(r2.end(), r2.default_match());
183 
184   // Swap with a single match.
185   ACMatches matches;
186   AutocompleteMatch match;
187   match.relevance = 1;
188   match.allowed_to_be_default_match = true;
189   AutocompleteInput input(ASCIIToUTF16("a"), base::string16::npos,
190                           base::string16(), GURL(),
191                           AutocompleteInput::INVALID_SPEC, false, false, false,
192                           AutocompleteInput::ALL_MATCHES);
193   matches.push_back(match);
194   r1.AppendMatches(matches);
195   r1.SortAndCull(input, test_util_.profile());
196   EXPECT_EQ(r1.begin(), r1.default_match());
197   EXPECT_EQ("http://a/", r1.alternate_nav_url().spec());
198   r1.Swap(&r2);
199   EXPECT_TRUE(r1.empty());
200   EXPECT_EQ(r1.end(), r1.default_match());
201   EXPECT_TRUE(r1.alternate_nav_url().is_empty());
202   ASSERT_FALSE(r2.empty());
203   EXPECT_EQ(r2.begin(), r2.default_match());
204   EXPECT_EQ("http://a/", r2.alternate_nav_url().spec());
205 }
206 
207 // Tests that if the new results have a lower max relevance score than last,
208 // any copied results have their relevance shifted down.
TEST_F(AutocompleteResultTest,CopyOldMatches)209 TEST_F(AutocompleteResultTest, CopyOldMatches) {
210   TestData last[] = {
211     { 0, 0, 1000 },
212     { 1, 0, 500 },
213   };
214   TestData current[] = {
215     { 2, 0, 400 },
216   };
217   TestData result[] = {
218     { 2, 0, 400 },
219     { 1, 0, 399 },
220   };
221 
222   ASSERT_NO_FATAL_FAILURE(
223       RunCopyOldMatchesTest(last, ARRAYSIZE_UNSAFE(last),
224                             current, ARRAYSIZE_UNSAFE(current),
225                             result, ARRAYSIZE_UNSAFE(result)));
226 }
227 
228 // Tests that matches are copied correctly from two distinct providers.
TEST_F(AutocompleteResultTest,CopyOldMatches2)229 TEST_F(AutocompleteResultTest, CopyOldMatches2) {
230   TestData last[] = {
231     { 0, 0, 1000 },
232     { 1, 1, 500 },
233     { 2, 0, 400 },
234     { 3, 1, 300 },
235   };
236   TestData current[] = {
237     { 4, 0, 1100 },
238     { 5, 1, 550 },
239   };
240   TestData result[] = {
241     { 4, 0, 1100 },
242     { 5, 1, 550 },
243     { 2, 0, 400 },
244     { 3, 1, 300 },
245   };
246 
247   ASSERT_NO_FATAL_FAILURE(
248       RunCopyOldMatchesTest(last, ARRAYSIZE_UNSAFE(last),
249                             current, ARRAYSIZE_UNSAFE(current),
250                             result, ARRAYSIZE_UNSAFE(result)));
251 }
252 
253 // Tests that matches with empty destination URLs aren't treated as duplicates
254 // and culled.
TEST_F(AutocompleteResultTest,SortAndCullEmptyDestinationURLs)255 TEST_F(AutocompleteResultTest, SortAndCullEmptyDestinationURLs) {
256   TestData data[] = {
257     { 1, 0, 500 },
258     { 0, 0, 1100 },
259     { 1, 0, 1000 },
260     { 0, 0, 1300 },
261     { 0, 0, 1200 },
262   };
263 
264   ACMatches matches;
265   PopulateAutocompleteMatches(data, arraysize(data), &matches);
266   matches[1].destination_url = GURL();
267   matches[3].destination_url = GURL();
268   matches[4].destination_url = GURL();
269 
270   AutocompleteResult result;
271   result.AppendMatches(matches);
272   AutocompleteInput input(base::string16(), base::string16::npos,
273                           base::string16(), GURL(),
274                           AutocompleteInput::INVALID_SPEC, false, false, false,
275                           AutocompleteInput::ALL_MATCHES);
276   result.SortAndCull(input, test_util_.profile());
277 
278   // Of the two results with the same non-empty destination URL, the
279   // lower-relevance one should be dropped.  All of the results with empty URLs
280   // should be kept.
281   ASSERT_EQ(4U, result.size());
282   EXPECT_TRUE(result.match_at(0)->destination_url.is_empty());
283   EXPECT_EQ(1300, result.match_at(0)->relevance);
284   EXPECT_TRUE(result.match_at(1)->destination_url.is_empty());
285   EXPECT_EQ(1200, result.match_at(1)->relevance);
286   EXPECT_TRUE(result.match_at(2)->destination_url.is_empty());
287   EXPECT_EQ(1100, result.match_at(2)->relevance);
288   EXPECT_EQ("http://b/", result.match_at(3)->destination_url.spec());
289   EXPECT_EQ(1000, result.match_at(3)->relevance);
290 }
291 
TEST_F(AutocompleteResultTest,SortAndCullDuplicateSearchURLs)292 TEST_F(AutocompleteResultTest, SortAndCullDuplicateSearchURLs) {
293   // Register a template URL that corresponds to 'foo' search engine.
294   TemplateURLData url_data;
295   url_data.short_name = ASCIIToUTF16("unittest");
296   url_data.SetKeyword(ASCIIToUTF16("foo"));
297   url_data.SetURL("http://www.foo.com/s?q={searchTerms}");
298   test_util_.model()->Add(new TemplateURL(test_util_.profile(), url_data));
299 
300   TestData data[] = {
301     { 0, 0, 1300 },
302     { 1, 0, 1200 },
303     { 2, 0, 1100 },
304     { 3, 0, 1000 },
305     { 4, 1, 900 },
306   };
307 
308   ACMatches matches;
309   PopulateAutocompleteMatches(data, arraysize(data), &matches);
310   matches[0].destination_url = GURL("http://www.foo.com/s?q=foo");
311   matches[1].destination_url = GURL("http://www.foo.com/s?q=foo2");
312   matches[2].destination_url = GURL("http://www.foo.com/s?q=foo&oq=f");
313   matches[3].destination_url = GURL("http://www.foo.com/s?q=foo&aqs=0");
314   matches[4].destination_url = GURL("http://www.foo.com/");
315 
316   AutocompleteResult result;
317   result.AppendMatches(matches);
318   AutocompleteInput input(base::string16(), base::string16::npos,
319                           base::string16(), GURL(),
320                           AutocompleteInput::INVALID_SPEC, false, false, false,
321                           AutocompleteInput::ALL_MATCHES);
322   result.SortAndCull(input, test_util_.profile());
323 
324   // We expect the 3rd and 4th results to be removed.
325   ASSERT_EQ(3U, result.size());
326   EXPECT_EQ("http://www.foo.com/s?q=foo",
327             result.match_at(0)->destination_url.spec());
328   EXPECT_EQ(1300, result.match_at(0)->relevance);
329   EXPECT_EQ("http://www.foo.com/s?q=foo2",
330             result.match_at(1)->destination_url.spec());
331   EXPECT_EQ(1200, result.match_at(1)->relevance);
332   EXPECT_EQ("http://www.foo.com/",
333             result.match_at(2)->destination_url.spec());
334   EXPECT_EQ(900, result.match_at(2)->relevance);
335 }
336 
TEST_F(AutocompleteResultTest,SortAndCullWithDemotionsByType)337 TEST_F(AutocompleteResultTest, SortAndCullWithDemotionsByType) {
338   // Add some matches.
339   ACMatches matches;
340   AddMatch("http://history-url/", AutocompleteMatchType::HISTORY_URL, &matches);
341   AddMatch("http://search-what-you-typed/",
342            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
343   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
344            &matches);
345 
346   // Add a search history type match and demote its relevance score.
347   AddMatch("http://search-history/", AutocompleteMatchType::SEARCH_HISTORY,
348            &matches);
349   matches[matches.size() - 1].relevance = 500;
350 
351   // Add a rule demoting history-url and killing history-title.
352   {
353     std::map<std::string, std::string> params;
354     params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] =
355         "1:50,7:100,2:0";  // 3 == HOME_PAGE
356     ASSERT_TRUE(chrome_variations::AssociateVariationParams(
357         OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
358   }
359   base::FieldTrialList::CreateFieldTrial(
360       OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
361 
362   AutocompleteResult result;
363   result.AppendMatches(matches);
364   AutocompleteInput input(base::string16(), base::string16::npos,
365                           base::string16(), GURL(),
366                           AutocompleteInput::HOME_PAGE, false, false, false,
367                           AutocompleteInput::ALL_MATCHES);
368   result.SortAndCull(input, test_util_.profile());
369 
370   // Check the new ordering.  The history-title results should be omitted.
371   // We cannot check relevance scores because the matches are sorted by
372   // demoted relevance but the actual relevance scores are not modified.
373   ASSERT_EQ(3u, result.size());
374   EXPECT_EQ("http://search-what-you-typed/",
375             result.match_at(0)->destination_url.spec());
376   EXPECT_EQ("http://history-url/",
377             result.match_at(1)->destination_url.spec());
378   EXPECT_EQ("http://search-history/",
379             result.match_at(2)->destination_url.spec());
380 }
381 
TEST_F(AutocompleteResultTest,SortAndCullWithUndemotableTypes)382 TEST_F(AutocompleteResultTest, SortAndCullWithUndemotableTypes) {
383   // Add some matches.
384   ACMatches matches(3);
385   matches[0].destination_url = GURL("http://top-history-url/");
386   matches[0].relevance = 1400;
387   matches[0].allowed_to_be_default_match = true;
388   matches[0].type = AutocompleteMatchType::HISTORY_URL;
389   matches[1].destination_url = GURL("http://history-url2/");
390   matches[1].relevance = 1300;
391   matches[1].allowed_to_be_default_match = true;
392   matches[1].type = AutocompleteMatchType::HISTORY_URL;
393   matches[2].destination_url = GURL("http://search-what-you-typed/");
394   matches[2].relevance = 1200;
395   matches[2].allowed_to_be_default_match = true;
396   matches[2].type = AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED;
397 
398   // Add a rule demoting history-url, but don't demote the top match.
399   {
400     std::map<std::string, std::string> params;
401     // 3 == HOME_PAGE
402     params[std::string(OmniboxFieldTrial::kDemoteByTypeRule) + ":3:*"] =
403         "1:50";
404     params[std::string(OmniboxFieldTrial::kUndemotableTopTypeRule) + ":3:*"] =
405         "1,5";
406     ASSERT_TRUE(chrome_variations::AssociateVariationParams(
407         OmniboxFieldTrial::kBundledExperimentFieldTrialName, "B", params));
408   }
409   base::FieldTrialList::CreateFieldTrial(
410       OmniboxFieldTrial::kBundledExperimentFieldTrialName, "B");
411 
412   AutocompleteResult result;
413   result.AppendMatches(matches);
414   AutocompleteInput input(base::string16(), base::string16::npos,
415                           base::string16(), GURL(),
416                           AutocompleteInput::HOME_PAGE, false, false, false,
417                           AutocompleteInput::ALL_MATCHES);
418   result.SortAndCull(input, test_util_.profile());
419 
420   // Check the new ordering.  The first history-url result should not be
421   // demoted, but the second result should be.
422   // We cannot check relevance scores because the matches are sorted by
423   // demoted relevance but the actual relevance scores are not modified.
424   ASSERT_EQ(3u, result.size());
425   EXPECT_EQ("http://top-history-url/",
426             result.match_at(0)->destination_url.spec());
427   EXPECT_EQ("http://search-what-you-typed/",
428             result.match_at(1)->destination_url.spec());
429   EXPECT_EQ("http://history-url2/",
430             result.match_at(2)->destination_url.spec());
431 }
432 
TEST_F(AutocompleteResultTest,SortAndCullReorderForDefaultMatch)433 TEST_F(AutocompleteResultTest, SortAndCullReorderForDefaultMatch) {
434   TestData data[] = {
435     { 0, 0, 1300 },
436     { 1, 0, 1200 },
437     { 2, 0, 1100 },
438     { 3, 0, 1000 }
439   };
440 
441   {
442     // Check that reorder doesn't do anything if the top result
443     // is already a legal default match (which is the default from
444     // PopulateAutocompleteMatches()).
445     ACMatches matches;
446     PopulateAutocompleteMatches(data, arraysize(data), &matches);
447     AutocompleteResult result;
448     result.AppendMatches(matches);
449     AutocompleteInput input(base::string16(), base::string16::npos,
450                             base::string16(), GURL(),
451                             AutocompleteInput::HOME_PAGE, false, false, false,
452                             AutocompleteInput::ALL_MATCHES);
453     result.SortAndCull(input, test_util_.profile());
454     AssertResultMatches(result, data, 4);
455   }
456 
457   {
458     // Check that reorder swaps up a result appropriately.
459     ACMatches matches;
460     PopulateAutocompleteMatches(data, arraysize(data), &matches);
461     matches[0].allowed_to_be_default_match = false;
462     matches[1].allowed_to_be_default_match = false;
463     AutocompleteResult result;
464     result.AppendMatches(matches);
465     AutocompleteInput input(base::string16(), base::string16::npos,
466                             base::string16(), GURL(),
467                             AutocompleteInput::HOME_PAGE, false, false, false,
468                             AutocompleteInput::ALL_MATCHES);
469     result.SortAndCull(input, test_util_.profile());
470     ASSERT_EQ(4U, result.size());
471     EXPECT_EQ("http://c/", result.match_at(0)->destination_url.spec());
472     EXPECT_EQ("http://a/", result.match_at(1)->destination_url.spec());
473     EXPECT_EQ("http://b/", result.match_at(2)->destination_url.spec());
474     EXPECT_EQ("http://d/", result.match_at(3)->destination_url.spec());
475   }
476 }
477 
TEST_F(AutocompleteResultTest,ShouldHideTopMatch)478 TEST_F(AutocompleteResultTest, ShouldHideTopMatch) {
479   // Add some matches.
480   ACMatches matches;
481   AddMatch("http://search-what-you-typed/",
482            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
483   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
484            &matches);
485   AddMatch("http://search-history/", AutocompleteMatchType::SEARCH_HISTORY,
486            &matches);
487 
488   base::FieldTrialList::CreateFieldTrial("InstantExtended",
489                                          "Group1 hide_verbatim:1");
490   AutocompleteResult result;
491   result.AppendMatches(matches);
492   EXPECT_TRUE(result.ShouldHideTopMatch());
493 }
494 
TEST_F(AutocompleteResultTest,DoNotHideTopMatch)495 TEST_F(AutocompleteResultTest, DoNotHideTopMatch) {
496   ACMatches matches;
497   AddMatch("http://search-what-you-typed/",
498            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
499   AddMatch("http://url-what-you-typed/",
500            AutocompleteMatchType::URL_WHAT_YOU_TYPED, &matches);
501   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
502            &matches);
503   AddMatch("http://search-history/", AutocompleteMatchType::SEARCH_HISTORY,
504            &matches);
505 
506   base::FieldTrialList::CreateFieldTrial("InstantExtended",
507                                          "Group1 hide_verbatim:1");
508   AutocompleteResult result;
509   result.AppendMatches(matches);
510   // If the verbatim first match is followed by another verbatim match, don't
511   // hide the top verbatim match.
512   EXPECT_FALSE(result.ShouldHideTopMatch());
513 }
514 
TEST_F(AutocompleteResultTest,DoNotHideTopMatch_TopMatchIsNotVerbatim)515 TEST_F(AutocompleteResultTest, DoNotHideTopMatch_TopMatchIsNotVerbatim) {
516   ACMatches matches;
517   AddMatch("http://search-history/", AutocompleteMatchType::SEARCH_HISTORY,
518            &matches);
519   AddMatch("http://search-what-you-typed/",
520            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
521   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
522            &matches);
523 
524   base::FieldTrialList::CreateFieldTrial("InstantExtended",
525                                          "Group1 hide_verbatim:1");
526   AutocompleteResult result;
527   result.AppendMatches(matches);
528   // Top match is not a verbatim type match. Do not hide the top match.
529   EXPECT_FALSE(result.ShouldHideTopMatch());
530 }
531 
TEST_F(AutocompleteResultTest,DoNotHideTopMatch_FieldTrialFlagDisabled)532 TEST_F(AutocompleteResultTest, DoNotHideTopMatch_FieldTrialFlagDisabled) {
533   // Add some matches. This test config is identical to ShouldHideTopMatch test
534   // except that the "hide_verbatim" flag is disabled in the field trials.
535   ACMatches matches;
536   AddMatch("http://search-what-you-typed/",
537            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
538   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
539            &matches);
540   AddMatch("http://search-history/", AutocompleteMatchType::SEARCH_HISTORY,
541            &matches);
542 
543   base::FieldTrialList::CreateFieldTrial("InstantExtended",
544                                          "Group1 hide_verbatim:0");
545   AutocompleteResult result;
546   result.AppendMatches(matches);
547   // Field trial flag "hide_verbatim" is disabled. Do not hide top match.
548   EXPECT_FALSE(result.ShouldHideTopMatch());
549 }
550 
TEST_F(AutocompleteResultTest,TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches)551 TEST_F(AutocompleteResultTest,
552        TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches) {
553   ACMatches matches;
554   AddMatch("http://url-what-you-typed/",
555            AutocompleteMatchType::URL_WHAT_YOU_TYPED, &matches);
556   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
557            &matches);
558 
559   AutocompleteResult result;
560   result.AppendMatches(matches);
561   EXPECT_TRUE(result.TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches());
562 }
563 
TEST_F(AutocompleteResultTest,TopMatchIsVerbatimAndHasConsecutiveVerbatimMatches)564 TEST_F(AutocompleteResultTest,
565        TopMatchIsVerbatimAndHasConsecutiveVerbatimMatches) {
566   ACMatches matches;
567   AddMatch("http://search-what-you-typed/",
568            AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, &matches);
569   AddMatch("http://url-what-you-typed/",
570            AutocompleteMatchType::URL_WHAT_YOU_TYPED, &matches);
571   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
572            &matches);
573 
574   AutocompleteResult result;
575   result.AppendMatches(matches);
576   EXPECT_FALSE(result.TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches());
577 }
578 
TEST_F(AutocompleteResultTest,TopMatchIsNotVerbatim)579 TEST_F(AutocompleteResultTest, TopMatchIsNotVerbatim) {
580   ACMatches matches;
581   AutocompleteResult result;
582   result.AppendMatches(matches);
583 
584   // Result set is empty.
585   EXPECT_FALSE(result.TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches());
586 
587   // Add a non-verbatim match to the result.
588   AddMatch("http://history-title/", AutocompleteMatchType::HISTORY_TITLE,
589            &matches);
590 
591   result.AppendMatches(matches);
592   EXPECT_FALSE(result.TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches());
593 }
594 
TEST_F(AutocompleteResultTest,TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches_SingleMatchFound)595 TEST_F(AutocompleteResultTest,
596        TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches_SingleMatchFound) {
597   ACMatches matches;
598   AddMatch("http://url-what-you-typed/",
599            AutocompleteMatchType::URL_WHAT_YOU_TYPED, &matches);
600 
601   AutocompleteResult result;
602   result.AppendMatches(matches);
603   EXPECT_TRUE(result.TopMatchIsVerbatimAndHasNoConsecutiveVerbatimMatches());
604 }
605