15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/bookmark_provider.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/strings/string_split.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_match.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/test/test_bookmark_client.h"
226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/metrics/proto/omnibox_event.pb.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_provider.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using bookmarks::BookmarkMatch;
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The bookmark corpus against which we will simulate searches.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct BookmarksTestInfo {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string title;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} bookmark_provider_test_data[] = {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "abc def", "http://www.catsanddogs.com/a" },
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "abcde", "http://www.catsanddogs.com/b" },
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "abcdef", "http://www.catsanddogs.com/c" },
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "carry carbon carefully", "http://www.catsanddogs.com/d" },
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "a definition", "http://www.catsanddogs.com/e" },
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ghi jkl", "http://www.catsanddogs.com/f" },
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "jkl ghi", "http://www.catsanddogs.com/g" },
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "frankly frankly frank", "http://www.catsanddogs.com/h" },
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "foobar foobar", "http://www.foobar.com/" },
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  { "domain", "http://www.domain.com/http/" },
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  { "repeat", "http://www.repeat.com/1/repeat/2/" },
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // For testing inline_autocompletion.
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  { "http://blah.com/", "http://blah.com/" },
46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  { "http://fiddle.com/", "http://fiddle.com/" },
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  { "http://www.www.com/", "http://www.www.com/" },
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  { "chrome://version", "chrome://version" },
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  { "chrome://omnibox", "chrome://omnibox" },
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For testing ranking with different URLs.
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "achlorhydric featherheads resuscitates mockingbirds",
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "http://www.manylongwords.com/1a" },
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "achlorhydric mockingbirds resuscitates featherhead",
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "http://www.manylongwords.com/2b" },
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "featherhead resuscitates achlorhydric mockingbirds",
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "http://www.manylongwords.com/3c" },
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "mockingbirds resuscitates featherheads achlorhydric",
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "http://www.manylongwords.com/4d" },
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // For testing URL boosting.  (URLs referenced multiple times are boosted.)
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "burning worms #1",  "http://www.burns.com/" },
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "burning worms #2",  "http://www.worms.com/" },
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "worming burns #10", "http://www.burns.com/" },
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // For testing strange spacing in bookmark titles.
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { " hello1  hello2  ", "http://whatever.com/" },
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  { "",                  "http://emptytitle.com/" },
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass BookmarkProviderTest : public testing::Test {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BookmarkProviderTest();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bookmarks::TestBookmarkClient client_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestingProfile> profile_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<BookmarkModel> model_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BookmarkProvider> provider_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkProviderTest);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
840529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochBookmarkProviderTest::BookmarkProviderTest() {
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  model_ = client_.CreateModel();
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkProviderTest::SetUp() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_.reset(new TestingProfile());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile_.get());
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  provider_ = new BookmarkProvider(profile_.get());
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(provider_.get());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider_->set_bookmark_model_for_testing(model_.get());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const BookmarkNode* other_node = model_->other_node();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(bookmark_provider_test_data); ++i) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarksTestInfo& cur(bookmark_provider_test_data[i]);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url(cur.url);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model_->AddURL(other_node, other_node->child_count(),
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::ASCIIToUTF16(cur.title), url);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Structures and functions supporting the BookmarkProviderTest.Positions
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unit test.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestBookmarkPosition {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBookmarkPosition(size_t begin, size_t end)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : begin(begin), end(end) {}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t begin;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t end;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<TestBookmarkPosition> TestBookmarkPositions;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return |positions| as a formatted string for unit test diagnostic output.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBookmarkPositionsAsString(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestBookmarkPositions& positions) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string position_string("{");
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (TestBookmarkPositions::const_iterator i = positions.begin();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != positions.end(); ++i) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i != positions.begin())
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      position_string += ", ";
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    position_string += "{" + base::IntToString(i->begin) + ", " +
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::IntToString(i->end) + "}";
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position_string += "}\n";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return position_string;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Return the positions in |matches| as a formatted string for unit test
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// diagnostic output.
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MatchesAsString16(const ACMatches& matches) {
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 matches_string;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACMatches::const_iterator i = matches.begin(); i != matches.end(); ++i) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    matches_string.append(base::ASCIIToUTF16("    '"));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matches_string.append(i->description);
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    matches_string.append(base::ASCIIToUTF16("'\n"));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return matches_string;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Comparison function for sorting search terms by descending length.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestBookmarkPositionsEqual(const TestBookmarkPosition& pos_a,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const TestBookmarkPosition& pos_b) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pos_a.begin == pos_b.begin && pos_a.end == pos_b.end;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convience function to make comparing ACMatchClassifications against the
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// test expectations structure easier.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestBookmarkPositions PositionsFromAutocompleteMatch(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AutocompleteMatch& match) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBookmarkPositions positions;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started = false;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t start = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AutocompleteMatch::ACMatchClassifications::const_iterator
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i = match.description_class.begin();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != match.description_class.end(); ++i) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i->style & AutocompleteMatch::ACMatchClassification::MATCH) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We have found the start of a match.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(started);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      started = true;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start = i->offset;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (started) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We have found the end of a match.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      started = false;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      positions.push_back(TestBookmarkPosition(start, i->offset));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start = 0;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the final position if the last match goes to the end of the
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // candidate string.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (started)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    positions.push_back(TestBookmarkPosition(start, match.description.size()));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return positions;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convience function to make comparing test expectations structure against the
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actual ACMatchClassifications easier.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestBookmarkPositions PositionsFromExpectations(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t expectations[9][2]) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestBookmarkPositions positions;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t i = 0;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The array is zero-terminated in the [1]th element.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (expectations[i][1]) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    positions.push_back(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestBookmarkPosition(expectations[i][0], expectations[i][1]));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++i;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return positions;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkProviderTest, Positions) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate searches.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Description of |positions|:
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   The first index represents the collection of positions for each expected
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   match. The count of the actual subarrays in each instance of |query_data|
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   must equal |match_count|. The second index represents each expected
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   match position. The third index represents the |start| and |end| of the
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   expected match's position within the |test_data|. This array must be
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   terminated by an entry with a value of '0' for |end|.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Example:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Consider the line for 'def' below:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     {"def", 2, {{{4, 7}, {XXX, 0}}, {{2, 5}, {11, 14}, {XXX, 0}}}},
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   There are two expected matches:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     0. {{4, 7}, {XXX, 0}}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     1. {{2, 5}, {11 ,14}, {XXX, 0}}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   For the first match, [0], there is one match within the bookmark's title
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   expected, {4, 7}, which maps to the 'def' within "abc def". The 'XXX'
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   value is ignored. The second match, [1], indicates that two matches are
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   expected within the bookmark title "a definite definition". In each case,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   the {XXX, 0} indicates the end of the subarray. Or:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                 Match #1            Match #2
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                 ------------------  ----------------------------
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  Pos1    Term        Pos1    Pos2      Term
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  ------  --------    ------  --------  --------
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     {"def", 2, {{{4, 7}, {999, 0}}, {{2, 5}, {11, 14}, {999, 0}}}},
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct QueryData {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string query;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t match_count;  // This count must match the number of major
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               // elements in the following |positions| array.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t positions[99][9][2];
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } query_data[] = {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This first set is primarily for position detection validation.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abc",                   3, {{{0, 3}, {0, 0}},
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  {{0, 3}, {0, 0}},
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  {{0, 3}, {0, 0}}}},
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abcde",                 2, {{{0, 5}, {0, 0}},
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  {{0, 5}, {0, 0}}}},
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"foo bar",               0, {{{0, 0}}}},
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"fooey bark",            0, {{{0, 0}}}},
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"def",                   2, {{{2, 5}, {0, 0}},
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  {{4, 7}, {0, 0}}}},
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"ghi jkl",               2, {{{0, 3}, {4, 7}, {0, 0}},
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  {{0, 3}, {4, 7}, {0, 0}}}},
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // NB: GetBookmarksMatching(...) uses exact match for "a" in title or URL.
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"a",                     2, {{{0, 1}, {0, 0}},
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  {{0, 0}}}},
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"a d",                   0, {{{0, 0}}}},
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"carry carbon",          1, {{{0, 5}, {6, 12}, {0, 0}}}},
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // NB: GetBookmarksMatching(...) sorts the match positions.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"carbon carry",          1, {{{0, 5}, {6, 12}, {0, 0}}}},
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"arbon",                 0, {{{0, 0}}}},
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"ar",                    0, {{{0, 0}}}},
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"arry",                  0, {{{0, 0}}}},
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Quoted terms are single terms.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"\"carry carbon\"",      1, {{{0, 12}, {0, 0}}}},
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"\"carry carbon\" care", 1, {{{0, 12}, {13, 17}, {0, 0}}}},
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Quoted terms require complete word matches.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"\"carry carbo\"",       0, {{{0, 0}}}},
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This set uses duplicated and/or overlaps search terms in the title.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"frank",                 1, {{{0, 5}, {8, 13}, {16, 21}, {0, 0}}}},
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"frankly",               1, {{{0, 7}, {8, 15}, {0, 0}}}},
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"frankly frankly",       1, {{{0, 7}, {8, 15}, {0, 0}}}},
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"foobar foo",            1, {{{0, 6}, {7, 13}, {0, 0}}}},
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"foo foobar",            1, {{{0, 6}, {7, 13}, {0, 0}}}},
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This ensures that leading whitespace in the title is removed.
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"hello",                 1, {{{0, 5}, {7, 12}, {0, 0}}}},
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This ensures that empty titles yield empty classifications.
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"emptytitle",            1, {}},
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) {
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AutocompleteInput input(base::ASCIIToUTF16(query_data[i].query),
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            base::string16::npos, base::string16(), GURL(),
2676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            metrics::OmniboxEventProto::INVALID_SPEC, false,
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            false, false, true,
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            ChromeAutocompleteSchemeClassifier(profile_.get()));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider_->Start(input, false);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ACMatches& matches(provider_->matches());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Validate number of results is as expected.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LE(matches.size(), query_data[i].match_count)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "One or more of the following matches were unexpected:\n"
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << MatchesAsString16(matches)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "For query '" << query_data[i].query << "'.";
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GE(matches.size(), query_data[i].match_count)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "One or more expected matches are missing. Matches found:\n"
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << MatchesAsString16(matches)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "for query '" << query_data[i].query << "'.";
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Validate positions within each match is as expected.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < matches.size(); ++j) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Collect the expected positions as a vector, collect the match's
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // classifications for match positions as a vector, then compare.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestBookmarkPositions expected_positions(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PositionsFromExpectations(query_data[i].positions[j]));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestBookmarkPositions actual_positions(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PositionsFromAutocompleteMatch(matches[j]));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(std::equal(expected_positions.begin(),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             expected_positions.end(),
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             actual_positions.begin(),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             TestBookmarkPositionsEqual))
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "EXPECTED: " << TestBookmarkPositionsAsString(expected_positions)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "ACTUAL:   " << TestBookmarkPositionsAsString(actual_positions)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "    for query: '" << query_data[i].query << "'.";
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BookmarkProviderTest, Rankings) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate searches.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct QueryData {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string query;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |match_count| must match the number of elements in the following
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |matches| array.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t match_count;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |matches| specifies the titles for all bookmarks expected to be matched
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // by the |query|
3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const std::string matches[3];
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } query_data[] = {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Basic ranking test.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"abc",       3, {"abcde",      // Most complete match.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "abcdef",
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "abc def"}},  // Least complete match.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"ghi",       2, {"ghi jkl",    // Matched earlier.
3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      "jkl ghi",    // Matched later.
3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      ""}},
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Rankings of exact-word matches with different URLs.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"achlorhydric",
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  3, {"achlorhydric mockingbirds resuscitates featherhead",
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "achlorhydric featherheads resuscitates mockingbirds",
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "featherhead resuscitates achlorhydric mockingbirds"}},
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"achlorhydric featherheads",
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  2, {"achlorhydric featherheads resuscitates mockingbirds",
3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      "mockingbirds resuscitates featherheads achlorhydric",
3265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      ""}},
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"mockingbirds resuscitates",
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  3, {"mockingbirds resuscitates featherheads achlorhydric",
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "achlorhydric mockingbirds resuscitates featherhead",
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "featherhead resuscitates achlorhydric mockingbirds"}},
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Ranking of exact-word matches with URL boosts.
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"worms",     2, {"burning worms #1",    // boosted
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      "burning worms #2",    // not boosted
3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                      ""}},
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Ranking of prefix matches with URL boost.
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"burn worm", 3, {"burning worms #1",    // boosted
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      "worming burns #10",   // boosted but longer title
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      "burning worms #2"}},  // not boosted
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // A query of "worm burn" will have the same results.
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {"worm burn", 3, {"burning worms #1",    // boosted
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      "worming burns #10",   // boosted but longer title
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      "burning worms #2"}},  // not boosted
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) {
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AutocompleteInput input(base::ASCIIToUTF16(query_data[i].query),
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            base::string16::npos, base::string16(), GURL(),
3486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            metrics::OmniboxEventProto::INVALID_SPEC, false,
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            false, false, true,
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            ChromeAutocompleteSchemeClassifier(profile_.get()));
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    provider_->Start(input, false);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ACMatches& matches(provider_->matches());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Validate number and content of results is as expected.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < std::max(query_data[i].match_count, matches.size());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++j) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_LT(j, query_data[i].match_count) << "    Unexpected match '"
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << base::UTF16ToUTF8(matches[j].description) << "' for query: '"
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          <<  query_data[i].query << "'.";
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (j >= query_data[i].match_count)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_LT(j, matches.size()) << "    Missing match '"
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << query_data[i].matches[j] << "' for query: '"
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << query_data[i].query << "'.";
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (j >= matches.size())
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(query_data[i].matches[j],
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::UTF16ToUTF8(matches[j].description))
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "    Mismatch at [" << base::IntToString(j) << "] for query '"
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << query_data[i].query << "'.";
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
374a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(BookmarkProviderTest, InlineAutocompletion) {
375a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Simulate searches.
376a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  struct QueryData {
377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string query;
378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string url;
379a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const bool allowed_to_be_default_match;
380a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string inline_autocompletion;
381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } query_data[] = {
382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "bla", "http://blah.com/", true, "h.com" },
383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "blah ", "http://blah.com/", false, ".com" },
384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "http://bl", "http://blah.com/", true, "ah.com" },
385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "fiddle.c", "http://fiddle.com/", true, "om" },
386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "www", "http://www.www.com/", true, ".com" },
387a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "chro", "chrome://version", true, "me://version" },
388a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "chrome://ve", "chrome://version", true, "rsion" },
389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "chrome ver", "chrome://version", false, "" },
390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "versi", "chrome://version", false, "" },
391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "abou", "chrome://omnibox", false, "" },
392a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    { "about:om", "chrome://omnibox", true, "nibox" }
393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Note: when adding a new URL to this test, be sure to add it to the list
394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // of bookmarks at the top of the file as well.  All items in this list
395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // need to be in the bookmarks list because BookmarkProvider's
396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // TitleMatchToACMatch() has an assertion that verifies the URL is
397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // actually bookmarked.
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  };
399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) {
401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string description = "for query=" + query_data[i].query +
402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        " and url=" + query_data[i].url;
403a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    AutocompleteInput input(base::ASCIIToUTF16(query_data[i].query),
404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            base::string16::npos, base::string16(), GURL(),
4056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            metrics::OmniboxEventProto::INVALID_SPEC, false,
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            false, false, true,
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            ChromeAutocompleteSchemeClassifier(profile_.get()));
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::string16 fixed_up_input(
40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        provider_->FixupUserInput(input).second);
410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    BookmarkNode node(GURL(query_data[i].url));
411a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    node.SetTitle(base::ASCIIToUTF16(query_data[i].url));
4120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BookmarkMatch bookmark_match;
413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bookmark_match.node = &node;
4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const AutocompleteMatch& ac_match = provider_->BookmarkMatchToACMatch(
4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        input, fixed_up_input, bookmark_match);
416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_EQ(query_data[i].allowed_to_be_default_match,
417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              ac_match.allowed_to_be_default_match) << description;
418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_EQ(base::ASCIIToUTF16(query_data[i].inline_autocompletion),
419a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              ac_match.inline_autocompletion) << description;
420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4230529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(BookmarkProviderTest, StripHttpAndAdjustOffsets) {
4240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Simulate searches.
4250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct QueryData {
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string query;
4270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string expected_contents;
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // |expected_contents_class| is in format offset:style,offset:style,...
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string expected_contents_class;
4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } query_data[] = {
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "foo",       "www.foobar.com",             "0:1,4:3,7:1"           },
4320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "www foo",   "www.foobar.com",             "0:3,3:1,4:3,7:1"       },
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "foo www",   "www.foobar.com",             "0:3,3:1,4:3,7:1"       },
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "foo http",  "http://www.foobar.com",      "0:3,4:1,11:3,14:1"     },
4350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "blah",      "blah.com",                   "0:3,4:1"               },
4360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "http blah", "http://blah.com",            "0:3,4:1,7:3,11:1"      },
4370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "dom",       "www.domain.com/http/",       "0:1,4:3,7:1"           },
4380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "dom http",  "http://www.domain.com/http/",
4390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "0:3,4:1,11:3,14:1,22:3,26:1"                                      },
4400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "rep",       "www.repeat.com/1/repeat/2/", "0:1,4:3,7:1,17:3,20:1" },
4410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    { "versi",     "chrome://version",           "0:1,9:3,14:1"          }
4420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
4430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) {
4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::string description = "for query=" + query_data[i].query;
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AutocompleteInput input(base::ASCIIToUTF16(query_data[i].query),
4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            base::string16::npos, base::string16(), GURL(),
4486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            metrics::OmniboxEventProto::INVALID_SPEC, false,
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            false, false, true,
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            ChromeAutocompleteSchemeClassifier(profile_.get()));
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    provider_->Start(input, false);
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const ACMatches& matches(provider_->matches());
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ASSERT_EQ(1U, matches.size()) << description;
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const AutocompleteMatch& match = matches[0];
4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(base::ASCIIToUTF16(query_data[i].expected_contents),
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              match.contents) << description;
4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::vector<std::string> class_strings;
4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::SplitString(
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        query_data[i].expected_contents_class, ',', &class_strings);
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ASSERT_EQ(class_strings.size(), match.contents_class.size())
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        << description;
4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t i = 0; i < class_strings.size(); ++i) {
4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      std::vector<std::string> chunks;
4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::SplitString(class_strings[i], ':', &chunks);
4650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ASSERT_EQ(2U, chunks.size()) << description;
4660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      size_t offset;
4670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_TRUE(base::StringToSizeT(chunks[0], &offset)) << description;
4680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(offset, match.contents_class[i].offset) << description;
4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      int style;
4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_TRUE(base::StringToInt(chunks[1], &style)) << description;
4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      EXPECT_EQ(style, match.contents_class[i].style) << description;
4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
475