autocomplete_provider_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved. 293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Use of this source code is governed by a BSD-style license that can be 393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// found in the LICENSE file. 493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/autocomplete_provider.h" 693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/bind.h" 893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/memory/scoped_ptr.h" 993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/message_loop.h" 1093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/string16.h" 1193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/string_number_conversions.h" 1293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/string_util.h" 1393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "base/utf_string_conversions.h" 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/autocomplete_controller.h" 1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/autocomplete_input.h" 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/autocomplete_match.h" 1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/autocomplete_provider_listener.h" 1893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/keyword_provider.h" 1993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/autocomplete/search_provider.h" 2093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/search_engines/template_url.h" 2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/search_engines/template_url_service.h" 2293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/browser/search_engines/template_url_service_factory.h" 2393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/common/chrome_notification_types.h" 2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/test/base/testing_browser_process.h" 2593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "chrome/test/base/testing_profile.h" 2693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "content/public/browser/notification_observer.h" 2793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "content/public/browser/notification_registrar.h" 2893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "content/public/browser/notification_source.h" 2993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "testing/gtest/include/gtest/gtest.h" 3093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic std::ostream& operator<<(std::ostream& os, 3293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const AutocompleteResult::const_iterator& it) { 3393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return os << static_cast<const AutocompleteMatch*>(&(*it)); 3493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 3593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgnamespace { 3793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst size_t kResultsPerProvider = 3; 3893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst char kTestTemplateURLKeyword[] = "t"; 3993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 4093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 4193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Autocomplete provider that provides known results. Note that this is 4293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// refcounted so that it can also be a task on the message loop. 4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgclass TestProvider : public AutocompleteProvider { 4493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org public: 4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org TestProvider(int relevance, const string16& prefix, 4693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org Profile* profile, 4793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const string16 match_keyword) 4893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org : AutocompleteProvider(NULL, profile, AutocompleteProvider::TYPE_SEARCH), 4993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org relevance_(relevance), 5093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org prefix_(prefix), 5193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org match_keyword_(match_keyword) { 5293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 5393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org virtual void Start(const AutocompleteInput& input, 5593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org bool minimal_changes); 5693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 5793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org void set_listener(AutocompleteProviderListener* listener) { 58 listener_ = listener; 59 } 60 61 private: 62 ~TestProvider() {} 63 64 void Run(); 65 66 void AddResults(int start_at, int num); 67 void AddResultsWithSearchTermsArgs( 68 int start_at, 69 int num, 70 AutocompleteMatch::Type type, 71 const TemplateURLRef::SearchTermsArgs& search_terms_args); 72 73 int relevance_; 74 const string16 prefix_; 75 const string16 match_keyword_; 76}; 77 78void TestProvider::Start(const AutocompleteInput& input, 79 bool minimal_changes) { 80 if (minimal_changes) 81 return; 82 83 matches_.clear(); 84 85 // Generate 4 results synchronously, the rest later. 86 AddResults(0, 1); 87 AddResultsWithSearchTermsArgs( 88 1, 1, AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, 89 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("echo"))); 90 AddResultsWithSearchTermsArgs( 91 2, 1, AutocompleteMatch::NAVSUGGEST, 92 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("nav"))); 93 AddResultsWithSearchTermsArgs( 94 3, 1, AutocompleteMatch::SEARCH_SUGGEST, 95 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("query"))); 96 97 if (input.matches_requested() == AutocompleteInput::ALL_MATCHES) { 98 done_ = false; 99 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&TestProvider::Run, 100 this)); 101 } 102} 103 104void TestProvider::Run() { 105 DCHECK_GT(kResultsPerProvider, 0U); 106 AddResults(1, kResultsPerProvider); 107 done_ = true; 108 DCHECK(listener_); 109 listener_->OnProviderUpdate(true); 110} 111 112void TestProvider::AddResults(int start_at, int num) { 113 AddResultsWithSearchTermsArgs(start_at, 114 num, 115 AutocompleteMatch::URL_WHAT_YOU_TYPED, 116 TemplateURLRef::SearchTermsArgs(string16())); 117} 118 119void TestProvider::AddResultsWithSearchTermsArgs( 120 int start_at, 121 int num, 122 AutocompleteMatch::Type type, 123 const TemplateURLRef::SearchTermsArgs& search_terms_args) { 124 for (int i = start_at; i < num; i++) { 125 AutocompleteMatch match(this, relevance_ - i, false, type); 126 127 match.fill_into_edit = prefix_ + UTF8ToUTF16(base::IntToString(i)); 128 match.destination_url = GURL(UTF16ToUTF8(match.fill_into_edit)); 129 130 match.contents = match.fill_into_edit; 131 match.contents_class.push_back( 132 ACMatchClassification(0, ACMatchClassification::NONE)); 133 match.description = match.fill_into_edit; 134 match.description_class.push_back( 135 ACMatchClassification(0, ACMatchClassification::NONE)); 136 match.search_terms_args.reset( 137 new TemplateURLRef::SearchTermsArgs(search_terms_args)); 138 if (!match_keyword_.empty()) { 139 match.keyword = match_keyword_; 140 ASSERT_TRUE(match.GetTemplateURL(profile_, false) != NULL); 141 } 142 143 matches_.push_back(match); 144 } 145} 146 147class AutocompleteProviderTest : public testing::Test, 148 public content::NotificationObserver { 149 protected: 150 struct KeywordTestData { 151 const string16 fill_into_edit; 152 const string16 keyword; 153 const bool expected_keyword_result; 154 }; 155 156 struct AssistedQueryStatsTestData { 157 const AutocompleteMatch::Type match_type; 158 const std::string expected_aqs; 159 }; 160 161 protected: 162 // Registers a test TemplateURL under the given keyword. 163 void RegisterTemplateURL(const string16 keyword, 164 const std::string& template_url); 165 166 // Resets |controller_| with two TestProviders. |provider1_ptr| and 167 // |provider2_ptr| are updated to point to the new providers if non-NULL. 168 void ResetControllerWithTestProviders(bool same_destinations, 169 TestProvider** provider1_ptr, 170 TestProvider** provider2_ptr); 171 172 // Runs a query on the input "a", and makes sure both providers' input is 173 // properly collected. 174 void RunTest(); 175 176 void RunRedundantKeywordTest(const KeywordTestData* match_data, size_t size); 177 178 void RunAssistedQueryStatsTest( 179 const AssistedQueryStatsTestData* aqs_test_data, 180 size_t size); 181 182 void RunQuery(const string16 query); 183 184 void ResetControllerWithKeywordAndSearchProviders(); 185 void ResetControllerWithKeywordProvider(); 186 void RunExactKeymatchTest(bool allow_exact_keyword_match); 187 188 AutocompleteResult result_; 189 scoped_ptr<AutocompleteController> controller_; 190 191 private: 192 // content::NotificationObserver 193 virtual void Observe(int type, 194 const content::NotificationSource& source, 195 const content::NotificationDetails& details); 196 197 MessageLoopForUI message_loop_; 198 content::NotificationRegistrar registrar_; 199 TestingProfile profile_; 200}; 201 202void AutocompleteProviderTest::RegisterTemplateURL( 203 const string16 keyword, 204 const std::string& template_url) { 205 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 206 &profile_, &TemplateURLServiceFactory::BuildInstanceFor); 207 TemplateURLData data; 208 data.SetURL(template_url); 209 data.SetKeyword(keyword); 210 TemplateURL* default_t_url = new TemplateURL(&profile_, data); 211 TemplateURLService* turl_model = 212 TemplateURLServiceFactory::GetForProfile(&profile_); 213 turl_model->Add(default_t_url); 214 turl_model->SetDefaultSearchProvider(default_t_url); 215 turl_model->Load(); 216 TemplateURLID default_provider_id = default_t_url->id(); 217 ASSERT_NE(0, default_provider_id); 218} 219 220void AutocompleteProviderTest::ResetControllerWithTestProviders( 221 bool same_destinations, 222 TestProvider** provider1_ptr, 223 TestProvider** provider2_ptr) { 224 // TODO: Move it outside this method, after refactoring the existing 225 // unit tests. Specifically: 226 // (1) Make sure that AutocompleteMatch.keyword is set iff there is 227 // a corresponding call to RegisterTemplateURL; otherwise the 228 // controller flow will crash; this practically means that 229 // RunTests/ResetControllerXXX/RegisterTemplateURL should 230 // be coordinated with each other. 231 // (2) Inject test arguments rather than rely on the hardcoded values, e.g. 232 // don't rely on kResultsPerProvided and default relevance ordering 233 // (B > A). 234 RegisterTemplateURL(ASCIIToUTF16(kTestTemplateURLKeyword), 235 "http://aqs/{searchTerms}/{google:assistedQueryStats}"); 236 237 ACProviders providers; 238 239 // Construct two new providers, with either the same or different prefixes. 240 TestProvider* provider1 = new TestProvider( 241 kResultsPerProvider, 242 ASCIIToUTF16("http://a"), 243 &profile_, 244 ASCIIToUTF16(kTestTemplateURLKeyword)); 245 provider1->AddRef(); 246 providers.push_back(provider1); 247 248 TestProvider* provider2 = new TestProvider( 249 kResultsPerProvider * 2, 250 same_destinations ? ASCIIToUTF16("http://a") : ASCIIToUTF16("http://b"), 251 &profile_, 252 string16()); 253 provider2->AddRef(); 254 providers.push_back(provider2); 255 256 // Reset the controller to contain our new providers. 257 controller_.reset(new AutocompleteController(&profile_, NULL, 0)); 258 controller_->providers_.swap(providers); 259 provider1->set_listener(controller_.get()); 260 provider2->set_listener(controller_.get()); 261 262 // The providers don't complete synchronously, so listen for "result updated" 263 // notifications. 264 registrar_.Add(this, 265 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, 266 content::Source<AutocompleteController>(controller_.get())); 267 268 if (provider1_ptr) 269 *provider1_ptr = provider1; 270 if (provider2_ptr) 271 *provider2_ptr = provider2; 272} 273 274void AutocompleteProviderTest:: 275 ResetControllerWithKeywordAndSearchProviders() { 276 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 277 &profile_, &TemplateURLServiceFactory::BuildInstanceFor); 278 279 // Reset the default TemplateURL. 280 TemplateURLData data; 281 data.SetURL("http://defaultturl/{searchTerms}"); 282 TemplateURL* default_t_url = new TemplateURL(&profile_, data); 283 TemplateURLService* turl_model = 284 TemplateURLServiceFactory::GetForProfile(&profile_); 285 turl_model->Add(default_t_url); 286 turl_model->SetDefaultSearchProvider(default_t_url); 287 TemplateURLID default_provider_id = default_t_url->id(); 288 ASSERT_NE(0, default_provider_id); 289 290 // Create another TemplateURL for KeywordProvider. 291 data.short_name = ASCIIToUTF16("k"); 292 data.SetKeyword(ASCIIToUTF16("k")); 293 data.SetURL("http://keyword/{searchTerms}"); 294 TemplateURL* keyword_t_url = new TemplateURL(&profile_, data); 295 turl_model->Add(keyword_t_url); 296 ASSERT_NE(0, keyword_t_url->id()); 297 298 controller_.reset(new AutocompleteController( 299 &profile_, NULL, 300 AutocompleteProvider::TYPE_KEYWORD | AutocompleteProvider::TYPE_SEARCH)); 301} 302 303void AutocompleteProviderTest::ResetControllerWithKeywordProvider() { 304 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( 305 &profile_, &TemplateURLServiceFactory::BuildInstanceFor); 306 307 TemplateURLService* turl_model = 308 TemplateURLServiceFactory::GetForProfile(&profile_); 309 310 // Create a TemplateURL for KeywordProvider. 311 TemplateURLData data; 312 data.short_name = ASCIIToUTF16("foo.com"); 313 data.SetKeyword(ASCIIToUTF16("foo.com")); 314 data.SetURL("http://foo.com/{searchTerms}"); 315 TemplateURL* keyword_t_url = new TemplateURL(&profile_, data); 316 turl_model->Add(keyword_t_url); 317 ASSERT_NE(0, keyword_t_url->id()); 318 319 // Create another TemplateURL for KeywordProvider. 320 data.short_name = ASCIIToUTF16("bar.com"); 321 data.SetKeyword(ASCIIToUTF16("bar.com")); 322 data.SetURL("http://bar.com/{searchTerms}"); 323 keyword_t_url = new TemplateURL(&profile_, data); 324 turl_model->Add(keyword_t_url); 325 ASSERT_NE(0, keyword_t_url->id()); 326 327 controller_.reset(new AutocompleteController( 328 &profile_, NULL, AutocompleteProvider::TYPE_KEYWORD)); 329} 330 331void AutocompleteProviderTest::RunTest() { 332 RunQuery(ASCIIToUTF16("a")); 333} 334 335void AutocompleteProviderTest::RunRedundantKeywordTest( 336 const KeywordTestData* match_data, 337 size_t size) { 338 ACMatches matches; 339 for (size_t i = 0; i < size; ++i) { 340 AutocompleteMatch match; 341 match.fill_into_edit = match_data[i].fill_into_edit; 342 match.transition = content::PAGE_TRANSITION_KEYWORD; 343 match.keyword = match_data[i].keyword; 344 matches.push_back(match); 345 } 346 347 AutocompleteResult result; 348 result.AppendMatches(matches); 349 controller_->UpdateAssociatedKeywords(&result); 350 351 for (size_t j = 0; j < result.size(); ++j) { 352 EXPECT_EQ(match_data[j].expected_keyword_result, 353 result.match_at(j)->associated_keyword.get() != NULL); 354 } 355} 356 357void AutocompleteProviderTest::RunAssistedQueryStatsTest( 358 const AssistedQueryStatsTestData* aqs_test_data, 359 size_t size) { 360 // Prepare input. 361 const size_t kMaxRelevance = 1000; 362 ACMatches matches; 363 for (size_t i = 0; i < size; ++i) { 364 AutocompleteMatch match(NULL, kMaxRelevance - i, false, 365 aqs_test_data[i].match_type); 366 match.keyword = ASCIIToUTF16(kTestTemplateURLKeyword); 367 match.search_terms_args.reset( 368 new TemplateURLRef::SearchTermsArgs(string16())); 369 matches.push_back(match); 370 } 371 result_.Reset(); 372 result_.AppendMatches(matches); 373 374 // Update AQS. 375 controller_->UpdateAssistedQueryStats(&result_); 376 377 // Verify data. 378 for (size_t i = 0; i < size; ++i) { 379 EXPECT_EQ(aqs_test_data[i].expected_aqs, 380 result_.match_at(i)->search_terms_args->assisted_query_stats); 381 } 382} 383 384void AutocompleteProviderTest::RunQuery(const string16 query) { 385 result_.Reset(); 386 controller_->Start(query, string16(), true, false, true, 387 AutocompleteInput::ALL_MATCHES); 388 389 if (!controller_->done()) 390 // The message loop will terminate when all autocomplete input has been 391 // collected. 392 MessageLoop::current()->Run(); 393} 394 395void AutocompleteProviderTest::RunExactKeymatchTest( 396 bool allow_exact_keyword_match) { 397 // Send the controller input which exactly matches the keyword provider we 398 // created in ResetControllerWithKeywordAndSearchProviders(). The default 399 // match should thus be a keyword match iff |allow_exact_keyword_match| is 400 // true. 401 controller_->Start(ASCIIToUTF16("k test"), string16(), true, false, 402 allow_exact_keyword_match, 403 AutocompleteInput::SYNCHRONOUS_MATCHES); 404 EXPECT_TRUE(controller_->done()); 405 EXPECT_EQ(allow_exact_keyword_match ? 406 AutocompleteProvider::TYPE_KEYWORD : AutocompleteProvider::TYPE_SEARCH, 407 controller_->result().default_match()->provider->type()); 408} 409 410void AutocompleteProviderTest::Observe( 411 int type, 412 const content::NotificationSource& source, 413 const content::NotificationDetails& details) { 414 if (controller_->done()) { 415 result_.CopyFrom(controller_->result()); 416 MessageLoop::current()->Quit(); 417 } 418} 419 420// Tests that the default selection is set properly when updating results. 421TEST_F(AutocompleteProviderTest, Query) { 422 TestProvider* provider1 = NULL; 423 TestProvider* provider2 = NULL; 424 ResetControllerWithTestProviders(false, &provider1, &provider2); 425 RunTest(); 426 427 // Make sure the default match gets set to the highest relevance match. The 428 // highest relevance matches should come from the second provider. 429 EXPECT_EQ(kResultsPerProvider * 2, result_.size()); // two providers 430 ASSERT_NE(result_.end(), result_.default_match()); 431 EXPECT_EQ(provider2, result_.default_match()->provider); 432} 433 434// Tests assisted query stats. 435TEST_F(AutocompleteProviderTest, AssistedQueryStats) { 436 ResetControllerWithTestProviders(false, NULL, NULL); 437 RunTest(); 438 439 EXPECT_EQ(kResultsPerProvider * 2, result_.size()); // two providers 440 441 // Now, check the results from the second provider, as they should not have 442 // assisted query stats set. 443 for (size_t i = 0; i < kResultsPerProvider; ++i) { 444 EXPECT_TRUE( 445 result_.match_at(i)->search_terms_args->assisted_query_stats.empty()); 446 } 447 // The first provider has a test keyword, so AQS should be non-empty. 448 for (size_t i = kResultsPerProvider; i < kResultsPerProvider * 2; ++i) { 449 EXPECT_FALSE( 450 result_.match_at(i)->search_terms_args->assisted_query_stats.empty()); 451 } 452} 453 454TEST_F(AutocompleteProviderTest, RemoveDuplicates) { 455 TestProvider* provider1 = NULL; 456 TestProvider* provider2 = NULL; 457 ResetControllerWithTestProviders(true, &provider1, &provider2); 458 RunTest(); 459 460 // Make sure all the first provider's results were eliminated by the second 461 // provider's. 462 EXPECT_EQ(kResultsPerProvider, result_.size()); 463 for (AutocompleteResult::const_iterator i(result_.begin()); 464 i != result_.end(); ++i) 465 EXPECT_EQ(provider2, i->provider); 466} 467 468TEST_F(AutocompleteProviderTest, AllowExactKeywordMatch) { 469 ResetControllerWithKeywordAndSearchProviders(); 470 RunExactKeymatchTest(true); 471 RunExactKeymatchTest(false); 472} 473 474// Test that redundant associated keywords are removed. 475TEST_F(AutocompleteProviderTest, RedundantKeywordsIgnoredInResult) { 476 ResetControllerWithKeywordProvider(); 477 478 // Get the controller's internal members in the correct state. 479 RunQuery(ASCIIToUTF16("fo")); 480 481 { 482 KeywordTestData duplicate_url[] = { 483 { ASCIIToUTF16("fo"), string16(), false }, 484 { ASCIIToUTF16("foo.com"), string16(), true }, 485 { ASCIIToUTF16("foo.com"), string16(), false } 486 }; 487 488 SCOPED_TRACE("Duplicate url"); 489 RunRedundantKeywordTest(duplicate_url, ARRAYSIZE_UNSAFE(duplicate_url)); 490 } 491 492 { 493 KeywordTestData keyword_match[] = { 494 { ASCIIToUTF16("foo.com"), ASCIIToUTF16("foo.com"), false }, 495 { ASCIIToUTF16("foo.com"), string16(), false } 496 }; 497 498 SCOPED_TRACE("Duplicate url with keyword match"); 499 RunRedundantKeywordTest(keyword_match, ARRAYSIZE_UNSAFE(keyword_match)); 500 } 501 502 { 503 KeywordTestData multiple_keyword[] = { 504 { ASCIIToUTF16("fo"), string16(), false }, 505 { ASCIIToUTF16("foo.com"), string16(), true }, 506 { ASCIIToUTF16("foo.com"), string16(), false }, 507 { ASCIIToUTF16("bar.com"), string16(), true }, 508 }; 509 510 SCOPED_TRACE("Duplicate url with multiple keywords"); 511 RunRedundantKeywordTest(multiple_keyword, 512 ARRAYSIZE_UNSAFE(multiple_keyword)); 513 } 514} 515 516TEST_F(AutocompleteProviderTest, UpdateAssistedQueryStats) { 517 ResetControllerWithTestProviders(false, NULL, NULL); 518 519 { 520 AssistedQueryStatsTestData test_data[] = { 521 // MSVC doesn't support zero-length arrays, so supply some dummy data. 522 { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "" } 523 }; 524 SCOPED_TRACE("No matches"); 525 // Note: We pass 0 here to ignore the dummy data above. 526 RunAssistedQueryStatsTest(test_data, 0); 527 } 528 529 { 530 AssistedQueryStatsTestData test_data[] = { 531 { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "chrome.0.57" } 532 }; 533 SCOPED_TRACE("One match"); 534 RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data)); 535 } 536 537 { 538 AssistedQueryStatsTestData test_data[] = { 539 { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "chrome.0.57j58j5l2j0l3j59" }, 540 { AutocompleteMatch::URL_WHAT_YOU_TYPED, "chrome.1.57j58j5l2j0l3j59" }, 541 { AutocompleteMatch::NAVSUGGEST, "chrome.2.57j58j5l2j0l3j59" }, 542 { AutocompleteMatch::NAVSUGGEST, "chrome.3.57j58j5l2j0l3j59" }, 543 { AutocompleteMatch::SEARCH_SUGGEST, "chrome.4.57j58j5l2j0l3j59" }, 544 { AutocompleteMatch::SEARCH_SUGGEST, "chrome.5.57j58j5l2j0l3j59" }, 545 { AutocompleteMatch::SEARCH_SUGGEST, "chrome.6.57j58j5l2j0l3j59" }, 546 { AutocompleteMatch::SEARCH_HISTORY, "chrome.7.57j58j5l2j0l3j59" }, 547 }; 548 SCOPED_TRACE("Multiple matches"); 549 RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data)); 550 } 551} 552