Index: chrome/browser/autocomplete/autocomplete_unittest.cc |
diff --git a/chrome/browser/autocomplete/autocomplete_unittest.cc b/chrome/browser/autocomplete/autocomplete_unittest.cc |
index 61d984f75496f96e9c543851e0d146a8e5e4b113..18eeb447dc5df28761df321f0a98030c1e5fd91a 100644 |
--- a/chrome/browser/autocomplete/autocomplete_unittest.cc |
+++ b/chrome/browser/autocomplete/autocomplete_unittest.cc |
@@ -31,16 +31,20 @@ static std::ostream& operator<<(std::ostream& os, |
namespace { |
const size_t kResultsPerProvider = 3; |
+const char kTestTemplateURLKeyword[] = "t"; |
} |
// Autocomplete provider that provides known results. Note that this is |
// refcounted so that it can also be a task on the message loop. |
class TestProvider : public AutocompleteProvider { |
public: |
- TestProvider(int relevance, const string16& prefix) |
- : AutocompleteProvider(NULL, NULL, ""), |
+ TestProvider(int relevance, const string16& prefix, |
+ Profile* profile, |
+ const string16 match_keyword) |
+ : AutocompleteProvider(NULL, profile, ""), |
relevance_(relevance), |
- prefix_(prefix) { |
+ prefix_(prefix), |
+ match_keyword_(match_keyword) { |
} |
virtual void Start(const AutocompleteInput& input, |
@@ -56,9 +60,15 @@ class TestProvider : public AutocompleteProvider { |
void Run(); |
void AddResults(int start_at, int num); |
+ void AddResultsWithSearchTermsArgs( |
+ int start_at, |
+ int num, |
+ AutocompleteMatch::Type type, |
+ const TemplateURLRef::SearchTermsArgs& search_terms_args); |
int relevance_; |
const string16 prefix_; |
+ const string16 match_keyword_; |
}; |
void TestProvider::Start(const AutocompleteInput& input, |
@@ -68,8 +78,17 @@ void TestProvider::Start(const AutocompleteInput& input, |
matches_.clear(); |
- // Generate one result synchronously, the rest later. |
+ // Generate 4 results synchronously, the rest later. |
AddResults(0, 1); |
+ AddResultsWithSearchTermsArgs( |
+ 1, 1, AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, |
+ TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("echo"))); |
+ AddResultsWithSearchTermsArgs( |
+ 2, 1, AutocompleteMatch::NAVSUGGEST, |
+ TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("nav"))); |
+ AddResultsWithSearchTermsArgs( |
+ 3, 1, AutocompleteMatch::SEARCH_SUGGEST, |
+ TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("query"))); |
if (input.matches_requested() == AutocompleteInput::ALL_MATCHES) { |
done_ = false; |
@@ -87,9 +106,19 @@ void TestProvider::Run() { |
} |
void TestProvider::AddResults(int start_at, int num) { |
+ AddResultsWithSearchTermsArgs(start_at, |
+ num, |
+ AutocompleteMatch::URL_WHAT_YOU_TYPED, |
+ TemplateURLRef::SearchTermsArgs(string16())); |
+} |
+ |
+void TestProvider::AddResultsWithSearchTermsArgs( |
+ int start_at, |
+ int num, |
+ AutocompleteMatch::Type type, |
+ const TemplateURLRef::SearchTermsArgs& search_terms_args) { |
for (int i = start_at; i < num; i++) { |
- AutocompleteMatch match(this, relevance_ - i, false, |
- AutocompleteMatch::URL_WHAT_YOU_TYPED); |
+ AutocompleteMatch match(this, relevance_ - i, false, type); |
match.fill_into_edit = prefix_ + UTF8ToUTF16(base::IntToString(i)); |
match.destination_url = GURL(UTF16ToUTF8(match.fill_into_edit)); |
@@ -100,6 +129,12 @@ void TestProvider::AddResults(int start_at, int num) { |
match.description = match.fill_into_edit; |
match.description_class.push_back( |
ACMatchClassification(0, ACMatchClassification::NONE)); |
+ match.search_terms_args.reset( |
+ new TemplateURLRef::SearchTermsArgs(search_terms_args)); |
+ if (!match_keyword_.empty()) { |
+ match.keyword = match_keyword_; |
+ ASSERT_TRUE(match.GetTemplateURL(profile_) != NULL); |
+ } |
matches_.push_back(match); |
} |
@@ -114,7 +149,16 @@ class AutocompleteProviderTest : public testing::Test, |
const bool expected_keyword_result; |
}; |
+ struct AssistedQueryStatsTestData { |
+ const AutocompleteMatch::Type match_type; |
+ const std::string expected_aqs; |
+ }; |
+ |
protected: |
+ // Registers a test TemplateURL under the given keyword. |
+ void RegisterTemplateURL(const string16 keyword, |
+ const std::string& template_url); |
+ |
void ResetControllerWithTestProviders(bool same_destinations); |
// Runs a query on the input "a", and makes sure both providers' input is |
@@ -123,6 +167,10 @@ class AutocompleteProviderTest : public testing::Test, |
void RunRedundantKeywordTest(const KeywordTestData* match_data, size_t size); |
+ void RunAssistedQueryStatsTest( |
+ const AssistedQueryStatsTestData* aqs_test_data, |
+ size_t size); |
+ |
void RunQuery(const string16 query); |
void ResetControllerWithTestProvidersWithKeywordAndSearchProviders(); |
@@ -146,20 +194,56 @@ class AutocompleteProviderTest : public testing::Test, |
TestingProfile profile_; |
}; |
+void AutocompleteProviderTest:: RegisterTemplateURL( |
+ const string16 keyword, |
+ const std::string& template_url) { |
+ TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
+ &profile_, &TemplateURLServiceFactory::BuildInstanceFor); |
+ TemplateURLData data; |
+ data.SetURL(template_url); |
+ data.SetKeyword(keyword); |
+ TemplateURL* default_t_url = new TemplateURL(&profile_, data); |
+ TemplateURLService* turl_model = |
+ TemplateURLServiceFactory::GetForProfile(&profile_); |
+ turl_model->Add(default_t_url); |
+ turl_model->SetDefaultSearchProvider(default_t_url); |
+ TemplateURLID default_provider_id = default_t_url->id(); |
+ ASSERT_NE(0, default_provider_id); |
+} |
+ |
void AutocompleteProviderTest::ResetControllerWithTestProviders( |
bool same_destinations) { |
// Forget about any existing providers. The controller owns them and will |
// Release() them below, when we delete it during the call to reset(). |
providers_.clear(); |
+ // TODO: Move it outside this method, after refactoring the existing |
+ // unit tests. Specifically: |
+ // (1) Make sure that AutocompleteMatch.keyword is set iff there is |
+ // a corresponding call to RegisterTemplateURL; otherwise the |
+ // controller flow will crash; this practically means that |
+ // RunTests/ResetControllerXXX/RegisterTemplateURL should |
+ // be coordinated with each other. |
+ // (2) Inject test arguments rather than rely on the hardcoded values, e.g. |
+ // don't rely on kResultsPerProvided and default relevance ordering |
+ // (B > A). |
+ RegisterTemplateURL(ASCIIToUTF16(kTestTemplateURLKeyword), |
+ "http://aqs/{searchTerms}/{google:assistedQueryStats}"); |
+ |
// Construct two new providers, with either the same or different prefixes. |
- TestProvider* providerA = new TestProvider(kResultsPerProvider, |
- ASCIIToUTF16("http://a")); |
+ TestProvider* providerA = |
+ new TestProvider(kResultsPerProvider, |
+ ASCIIToUTF16("http://a"), |
+ &profile_, |
+ ASCIIToUTF16(kTestTemplateURLKeyword)); |
providerA->AddRef(); |
providers_.push_back(providerA); |
- TestProvider* providerB = new TestProvider(kResultsPerProvider * 2, |
- same_destinations ? ASCIIToUTF16("http://a") : ASCIIToUTF16("http://b")); |
+ TestProvider* providerB = new TestProvider( |
+ kResultsPerProvider * 2, |
+ same_destinations ? ASCIIToUTF16("http://a") : ASCIIToUTF16("http://b"), |
+ &profile_, |
+ string16()); |
providerB->AddRef(); |
providers_.push_back(providerB); |
@@ -217,8 +301,7 @@ void AutocompleteProviderTest:: |
controller_.reset(new AutocompleteController(providers_, &profile_)); |
} |
-void AutocompleteProviderTest:: |
- ResetControllerWithKeywordProvider() { |
+void AutocompleteProviderTest::ResetControllerWithKeywordProvider() { |
TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
&profile_, &TemplateURLServiceFactory::BuildInstanceFor); |
@@ -280,10 +363,36 @@ void AutocompleteProviderTest::RunRedundantKeywordTest( |
for (size_t j = 0; j < result.size(); ++j) { |
EXPECT_EQ(match_data[j].expected_keyword_result, |
- result.match_at(j).associated_keyword.get() != NULL); |
+ result.match_at(j)->associated_keyword.get() != NULL); |
} |
} |
+void AutocompleteProviderTest::RunAssistedQueryStatsTest( |
+ const AssistedQueryStatsTestData* aqs_test_data, |
+ size_t size) { |
+ // Prepare input. |
+ const size_t kMaxRelevance = 1000; |
+ ACMatches matches; |
+ for (size_t i = 0; i < size; ++i) { |
+ AutocompleteMatch match(NULL, kMaxRelevance - i, false, |
+ aqs_test_data[i].match_type); |
+ match.keyword = ASCIIToUTF16(kTestTemplateURLKeyword); |
+ match.search_terms_args.reset( |
+ new TemplateURLRef::SearchTermsArgs(string16())); |
+ matches.push_back(match); |
+ } |
+ result_.Reset(); |
+ result_.AppendMatches(matches); |
+ |
+ // Update AQS. |
+ controller_->UpdateAssistedQueryStats(&result_); |
+ |
+ // Verify data. |
+ for (size_t i = 0; i < size; ++i) { |
+ EXPECT_EQ(aqs_test_data[i].expected_aqs, |
+ result_.match_at(i)->search_terms_args->assisted_query_stats); |
+ } |
+} |
void AutocompleteProviderTest::RunQuery(const string16 query) { |
result_.Reset(); |
@@ -335,6 +444,26 @@ TEST_F(AutocompleteProviderTest, Query) { |
EXPECT_EQ(providers_[1], result_.default_match()->provider); |
} |
+// Tests assisted query stats. |
+TEST_F(AutocompleteProviderTest, AssistedQueryStats) { |
+ ResetControllerWithTestProviders(false); |
+ RunTest(); |
+ |
+ EXPECT_EQ(kResultsPerProvider * 2, result_.size()); // two providers |
+ |
+ // Now, check the results from the second provider, as they should not have |
+ // assisted query stats set. |
+ for (size_t i = 0; i < kResultsPerProvider; ++i) { |
+ EXPECT_TRUE( |
+ result_.match_at(i)->search_terms_args->assisted_query_stats.empty()); |
+ } |
+ // The first provider has a test keyword, so AQS should be non-empty. |
+ for (size_t i = kResultsPerProvider; i < kResultsPerProvider * 2; ++i) { |
+ EXPECT_FALSE( |
+ result_.match_at(i)->search_terms_args->assisted_query_stats.empty()); |
+ } |
+} |
+ |
TEST_F(AutocompleteProviderTest, RemoveDuplicates) { |
ResetControllerWithTestProviders(true); |
RunTest(); |
@@ -395,6 +524,43 @@ TEST_F(AutocompleteProviderTest, RedundantKeywordsIgnoredInResult) { |
} |
} |
+TEST_F(AutocompleteProviderTest, UpdateAssistedQueryStats) { |
+ ResetControllerWithTestProviders(false); |
+ |
+ { |
+ AssistedQueryStatsTestData test_data[] = { |
+ // MSVC doesn't support zero-length arrays, so supply some dummy data. |
+ { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "" } |
+ }; |
+ SCOPED_TRACE("No matches"); |
+ // Note: We pass 0 here to ignore the dummy data above. |
+ RunAssistedQueryStatsTest(test_data, 0); |
+ } |
+ |
+ { |
+ AssistedQueryStatsTestData test_data[] = { |
+ { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "chrome.0.57" } |
+ }; |
+ SCOPED_TRACE("One match"); |
+ RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data)); |
+ } |
+ |
+ { |
+ AssistedQueryStatsTestData test_data[] = { |
+ { AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, "chrome.0.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::URL_WHAT_YOU_TYPED, "chrome.1.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::NAVSUGGEST, "chrome.2.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::NAVSUGGEST, "chrome.3.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::SEARCH_SUGGEST, "chrome.4.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::SEARCH_SUGGEST, "chrome.5.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::SEARCH_SUGGEST, "chrome.6.57j58j5l2j0l3j59" }, |
+ { AutocompleteMatch::SEARCH_HISTORY, "chrome.7.57j58j5l2j0l3j59" }, |
+ }; |
+ SCOPED_TRACE("Multiple matches"); |
+ RunAssistedQueryStatsTest(test_data, ARRAYSIZE_UNSAFE(test_data)); |
+ } |
+} |
+ |
typedef testing::Test AutocompleteTest; |
TEST_F(AutocompleteTest, InputType) { |