autocomplete_unittest.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/scoped_ptr.h"
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/notification_observer.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_registrar.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// identifiers for known autocomplete providers
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define HISTORY_IDENTIFIER L"Chrome:History"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define SEARCH_IDENTIFIER L"google.com/websearch/en"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic std::ostream& operator<<(std::ostream& os,
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                const AutocompleteResult::const_iterator& it) {
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return os << static_cast<const AutocompleteMatch*>(&(*it));
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t num_results_per_provider = 3;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Autocomplete provider that provides known results. Note that this is
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// refcounted so that it can also be a task on the message loop.
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestProvider : public AutocompleteProvider {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestProvider(int relevance, const std::wstring& prefix)
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : AutocompleteProvider(NULL, NULL, ""),
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        relevance_(relevance),
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        prefix_(prefix) {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Start(const AutocompleteInput& input,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     bool minimal_changes);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_listener(ACProviderListener* listener) {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    listener_ = listener;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~TestProvider() {}
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Run();
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddResults(int start_at, int num);
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int relevance_;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::wstring prefix_;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TestProvider::Start(const AutocompleteInput& input,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         bool minimal_changes) {
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (minimal_changes)
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  matches_.clear();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Generate one result synchronously, the rest later.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddResults(0, 1);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!input.synchronous_only()) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    done_ = false;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        this, &TestProvider::Run));
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TestProvider::Run() {
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_GT(num_results_per_provider, 0U);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddResults(1, num_results_per_provider);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done_ = true;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(listener_);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  listener_->OnProviderUpdate(true);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TestProvider::AddResults(int start_at, int num) {
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = start_at; i < num; i++) {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteMatch match(this, relevance_ - i, false,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            AutocompleteMatch::URL_WHAT_YOU_TYPED);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    match.fill_into_edit = prefix_ + UTF8ToWide(base::IntToString(i));
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    match.destination_url = GURL(WideToUTF8(match.fill_into_edit));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    match.contents = match.fill_into_edit;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    match.contents_class.push_back(
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ACMatchClassification(0, ACMatchClassification::NONE));
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    match.description = match.fill_into_edit;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    match.description_class.push_back(
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ACMatchClassification(0, ACMatchClassification::NONE));
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    matches_.push_back(match);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutocompleteProviderTest : public testing::Test,
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 public NotificationObserver {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // testing::Test
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ResetController(bool same_destinations);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Runs a query on the input "a", and makes sure both providers' input is
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // properly collected.
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RunTest();
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These providers are owned by the controller once it's created.
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ACProviders providers_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteResult result_;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NotificationObserver
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoopForUI message_loop_;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<AutocompleteController> controller_;
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompleteProviderTest::SetUp() {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED,
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetController(false);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompleteProviderTest::ResetController(bool same_destinations) {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Forget about any existing providers.  The controller owns them and will
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release() them below, when we delete it during the call to reset().
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providers_.clear();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Construct two new providers, with either the same or different prefixes.
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestProvider* providerA = new TestProvider(num_results_per_provider,
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             L"http://a");
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providerA->AddRef();
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providers_.push_back(providerA);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestProvider* providerB = new TestProvider(num_results_per_provider * 2,
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      same_destinations ? L"http://a" : L"http://b");
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providerB->AddRef();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providers_.push_back(providerB);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the controller to contain our new providers.
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteController* controller = new AutocompleteController(providers_);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller_.reset(controller);
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providerA->set_listener(controller);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  providerB->set_listener(controller);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompleteProviderTest::RunTest() {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result_.Reset();
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller_->Start(L"a", std::wstring(), true, false, false);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The message loop will terminate when all autocomplete input has been
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // collected.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutocompleteProviderTest::Observe(NotificationType type,
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const NotificationSource& source,
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const NotificationDetails& details) {
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (controller_->done()) {
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result_.CopyFrom(*(Details<const AutocompleteResult>(details).ptr()));
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Quit();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that the default selection is set properly when updating results.
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(AutocompleteProviderTest, Query) {
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTest();
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the default match gets set to the highest relevance match.  The
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // highest relevance matches should come from the second provider.
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(num_results_per_provider * 2, result_.size());  // two providers
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_NE(result_.end(), result_.default_match());
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(providers_[1], result_.default_match()->provider);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(AutocompleteProviderTest, RemoveDuplicates) {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set up the providers to provide duplicate results.
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetController(true);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RunTest();
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure all the first provider's results were eliminated by the second
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // provider's.
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(num_results_per_provider, result_.size());
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (AutocompleteResult::const_iterator i(result_.begin());
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       i != result_.end(); ++i)
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(providers_[1], i->provider);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set things back to the default for the benefit of any tests that run after
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // us.
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetController(false);
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(AutocompleteTest, InputType) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct test_data {
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const wchar_t* input;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const AutocompleteInput::Type type;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } input_cases[] = {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"", AutocompleteInput::INVALID },
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?", AutocompleteInput::FORCED_QUERY },
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?foo", AutocompleteInput::FORCED_QUERY },
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?foo bar", AutocompleteInput::FORCED_QUERY },
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?http://foo.com/bar", AutocompleteInput::FORCED_QUERY },
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo", AutocompleteInput::UNKNOWN },
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo.c", AutocompleteInput::UNKNOWN },
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo.com", AutocompleteInput::URL },
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"-.com", AutocompleteInput::UNKNOWN },
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo/bar", AutocompleteInput::URL },
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"foo;bar", AutocompleteInput::QUERY },
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo/bar baz", AutocompleteInput::UNKNOWN },
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo bar.com", AutocompleteInput::QUERY },
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo bar", AutocompleteInput::QUERY },
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo+bar", AutocompleteInput::QUERY },
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo+bar.com", AutocompleteInput::UNKNOWN },
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"\"foo:bar\"", AutocompleteInput::QUERY },
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"link:foo.com", AutocompleteInput::UNKNOWN },
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"www.foo.com:81", AutocompleteInput::URL },
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"localhost:8080", AutocompleteInput::URL },
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo.com:123456", AutocompleteInput::QUERY },
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo.com:abc", AutocompleteInput::QUERY },
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"1.2.3.4:abc", AutocompleteInput::QUERY },
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"user@foo.com", AutocompleteInput::UNKNOWN },
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"user:pass@foo.com", AutocompleteInput::UNKNOWN },
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"1.2", AutocompleteInput::UNKNOWN },
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"1.2/45", AutocompleteInput::UNKNOWN },
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"1.2:45", AutocompleteInput::UNKNOWN },
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"user@1.2:45", AutocompleteInput::UNKNOWN },
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"user:foo@1.2:45", AutocompleteInput::UNKNOWN },
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"ps/2 games", AutocompleteInput::UNKNOWN },
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"en.wikipedia.org/wiki/James Bond", AutocompleteInput::URL },
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // In Chrome itself, mailto: will get handled by ShellExecute, but in
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // unittest mode, we don't have the data loaded in the external protocol
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // handler to know this.
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // { L"mailto:abuse@foo.com", AutocompleteInput::URL },
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:http://www.foo.com/", AutocompleteInput::URL },
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"javascript:alert(\"Hey there!\");", AutocompleteInput::URL },
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"C:\\Program Files", AutocompleteInput::URL },
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"\\\\Server\\Folder\\File", AutocompleteInput::URL },
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // defined(OS_WIN)
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http:foo", AutocompleteInput::URL },
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo", AutocompleteInput::URL },
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo.c", AutocompleteInput::URL },
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo.com", AutocompleteInput::URL },
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo_bar.com", AutocompleteInput::URL },
2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"http://foo/bar baz", AutocompleteInput::URL },
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://-.com", AutocompleteInput::UNKNOWN },
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://_foo_.com", AutocompleteInput::UNKNOWN },
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo.com:abc", AutocompleteInput::QUERY },
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo.com:123456", AutocompleteInput::QUERY },
2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"http://1.2.3.4:abc", AutocompleteInput::QUERY },
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http:user@foo.com", AutocompleteInput::URL },
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://user@foo.com", AutocompleteInput::URL },
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"http:user:pass@foo.com", AutocompleteInput::URL },
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://user:pass@foo.com", AutocompleteInput::URL },
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://1.2", AutocompleteInput::URL },
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://1.2/45", AutocompleteInput::URL },
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http:ps/2 games", AutocompleteInput::URL },
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://ps/2 games", AutocompleteInput::URL },
2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    { L"https://foo.com", AutocompleteInput::URL },
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"127.0.0.1", AutocompleteInput::URL },
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"127.0.1", AutocompleteInput::UNKNOWN },
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"127.0.1/", AutocompleteInput::UNKNOWN },
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"browser.tabs.closeButtons", AutocompleteInput::UNKNOWN },
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"\u6d4b\u8bd5", AutocompleteInput::UNKNOWN },
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"[2001:]", AutocompleteInput::QUERY },  // Not a valid IP
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"[2001:dB8::1]", AutocompleteInput::URL },
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"192.168.0.256", AutocompleteInput::QUERY },  // Invalid IPv4 literal.
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"[foo.com]", AutocompleteInput::QUERY },  // Invalid IPv6 literal.
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteInput input(input_cases[i].input, std::wstring(), true, false,
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            false);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].type, input.type()) << "Input: " <<
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(AutocompleteTest, InputTypeWithDesiredTLD) {
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct test_data {
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const wchar_t* input;
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const AutocompleteInput::Type type;
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } input_cases[] = {
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"401k", AutocompleteInput::REQUESTED_URL },
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"999999999999999", AutocompleteInput::REQUESTED_URL },
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteInput input(input_cases[i].input, L"com", true, false, false);
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].type, input.type()) << "Input: " <<
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This tests for a regression where certain input in the omnibox caused us to
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// crash. As long as the test completes without crashing, we're fine.
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(AutocompleteTest, InputCrash) {
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteInput input(L"\uff65@s", std::wstring(), true, false, false);
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we can properly compare matches' relevance when at least one is
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// negative.
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(AutocompleteMatch, MoreRelevant) {
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct RelevantCases {
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int r1;
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int r2;
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool expected_result;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } cases[] = {
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {  10,   0, true  },
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {  10,  -5, true  },
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {  -5,  10, false },
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {   0,  10, false },
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { -10,  -5, true  },
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {  -5, -10, false },
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteMatch m1(NULL, 0, false, AutocompleteMatch::URL_WHAT_YOU_TYPED);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteMatch m2(NULL, 0, false, AutocompleteMatch::URL_WHAT_YOU_TYPED);
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    m1.relevance = cases[i].r1;
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    m2.relevance = cases[i].r2;
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(cases[i].expected_result,
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              AutocompleteMatch::MoreRelevant(m1, m2));
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(AutocompleteInput, ParseForEmphasizeComponent) {
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  using url_parse::Component;
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Component kInvalidComponent(0, -1);
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct test_data {
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const wchar_t* input;
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Component scheme;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Component host;
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } input_cases[] = {
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"", kInvalidComponent, kInvalidComponent },
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?", kInvalidComponent, kInvalidComponent },
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"?http://foo.com/bar", kInvalidComponent, kInvalidComponent },
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"foo/bar baz", kInvalidComponent, Component(0, 3) },
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"http://foo/bar baz", Component(0, 4), Component(7, 3) },
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"link:foo.com", Component(0, 4), kInvalidComponent },
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"www.foo.com:81", kInvalidComponent, Component(0, 11) },
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"\u6d4b\u8bd5", kInvalidComponent, Component(0, 2) },
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:http://www.foo.com/", Component(12, 4), Component(19, 11) },
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:https://example.com/",
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Component(12, 5), Component(20, 11) },
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:www.foo.com", kInvalidComponent, Component(12, 11) },
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:", Component(0, 11), kInvalidComponent },
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:garbage", kInvalidComponent, Component(12, 7) },
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:http://http://foo", Component(12, 4), Component(19, 4) },
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { L"view-source:view-source:http://example.com/",
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Component(12, 11), kInvalidComponent }
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) {
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Component scheme, host;
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteInput::ParseForEmphasizeComponents(input_cases[i].input,
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   std::wstring(),
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   &scheme,
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   &host);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteInput input(input_cases[i].input, std::wstring(), true, false,
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            false);
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].scheme.begin, scheme.begin) << "Input: " <<
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].scheme.len, scheme.len) << "Input: " <<
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].host.begin, host.begin) << "Input: " <<
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(input_cases[i].host.len, host.len) << "Input: " <<
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        input_cases[i].input;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
387