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, ¤t_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