1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 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
53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <stdio.h>
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <fstream>
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string>
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <vector>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "app/sql/connection.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "app/sql/statement.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "app/sql/transaction.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/file_path.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/file_util.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/path_service.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/time.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/in_memory_url_index.h"
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/history/in_memory_database.h"
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_paths.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The test version of the history url database table ('url') is contained in
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// a database file created from a text file('url_history_provider_test.db.txt').
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The only difference between this table and a live 'urls' table from a
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// profile is that the last_visit_time column in the test table contains a
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// number specifying the number of days relative to 'today' to which the
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// absolute time should be set during the test setup stage.
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The format of the test database text file is of a SQLite .dump file.
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Note that only lines whose first character is an upper-case letter are
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// processed when creating the test database.
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass InMemoryURLIndexTest : public testing::Test,
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             public InMemoryDatabase {
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  InMemoryURLIndexTest() { InitFromScratch(); }
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Test setup.
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void SetUp() {
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Create and populate a working copy of the URL history database.
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath history_proto_path;
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    PathService::Get(chrome::DIR_TEST_DATA, &history_proto_path);
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    history_proto_path = history_proto_path.Append(
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("History"));
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    history_proto_path = history_proto_path.Append(TestDBName());
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_TRUE(file_util::PathExists(history_proto_path));
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::ifstream proto_file(history_proto_path.value().c_str());
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    static const size_t kCommandBufferMaxSize = 2048;
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    char sql_cmd_line[kCommandBufferMaxSize];
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    sql::Connection& db(GetDB());
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    {
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      sql::Transaction transaction(&db);
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transaction.Begin();
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      while (!proto_file.eof()) {
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        proto_file.getline(sql_cmd_line, kCommandBufferMaxSize);
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (!proto_file.eof()) {
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // We only process lines which begin with a upper-case letter.
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          // TODO(mrossetti): Can iswupper() be used here?
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          if (sql_cmd_line[0] >= 'A' && sql_cmd_line[0] <= 'Z') {
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            std::string sql_cmd(sql_cmd_line);
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            sql::Statement sql_stmt(db.GetUniqueStatement(sql_cmd_line));
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            EXPECT_TRUE(sql_stmt.Run());
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          }
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transaction.Commit();
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    proto_file.close();
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Update the last_visit_time table column
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // such that it represents a time relative to 'now'.
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    sql::Statement statement(db.GetUniqueStatement(
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        "SELECT" HISTORY_URL_ROW_FIELDS "FROM urls;"));
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_TRUE(statement);
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    base::Time time_right_now = base::Time::NowFromSystemTime();
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::TimeDelta day_delta = base::TimeDelta::FromDays(1);
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    {
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      sql::Transaction transaction(&db);
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transaction.Begin();
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      while (statement.Step()) {
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        URLRow row;
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FillURLRow(statement, &row);
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        base::Time last_visit = time_right_now;
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        for (int64 i = row.last_visit().ToInternalValue(); i > 0; --i)
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          last_visit -= day_delta;
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        row.set_last_visit(last_visit);
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        UpdateURLRow(row.id(), row);
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transaction.Commit();
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual FilePath::StringType TestDBName() const {
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return FILE_PATH_LITERAL("url_history_provider_test.db.txt");
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  URLRow MakeURLRow(const char* url,
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    const char* title,
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    int visit_count,
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    int last_visit_ago,
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    int typed_count) {
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    URLRow row(GURL(url), 0);
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    row.set_title(UTF8ToUTF16(title));
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    row.set_visit_count(visit_count);
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    row.set_typed_count(typed_count);
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    row.set_last_visit(base::Time::NowFromSystemTime() -
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       base::TimeDelta::FromDays(last_visit_ago));
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return row;
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Vector Make1Term(const char* term) {
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    InMemoryURLIndex::String16Vector terms;
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    terms.push_back(UTF8ToUTF16(term));
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return terms;
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Vector Make2Terms(const char* term_1,
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                              const char* term_2) {
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    InMemoryURLIndex::String16Vector terms;
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    terms.push_back(UTF8ToUTF16(term_1));
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    terms.push_back(UTF8ToUTF16(term_2));
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return terms;
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<InMemoryURLIndex> url_index_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass LimitedInMemoryURLIndexTest : public InMemoryURLIndexTest {
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath::StringType TestDBName() const {
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return FILE_PATH_LITERAL("url_history_provider_test_limited.db.txt");
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ExpandedInMemoryURLIndexTest : public InMemoryURLIndexTest {
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void SetUp() {
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    InMemoryURLIndexTest::SetUp();
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Add 600 more history items.
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // NOTE: Keep the string length constant at least the length of the format
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // string plus 5 to account for a 3 digit number and terminator.
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    char url_format[] = "http://www.google.com/%d";
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const size_t kMaxLen = arraysize(url_format) + 5;
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    char url_string[kMaxLen + 1];
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (int i = 0; i < 600; ++i) {
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      base::snprintf(url_string, kMaxLen, url_format, i);
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      URLRow row(MakeURLRow(url_string, "Google Search", 20, 0, 20));
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      AddURL(row);
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(InMemoryURLIndexTest, Construction) {
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(url_index_.get());
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(LimitedInMemoryURLIndexTest, Initialization) {
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Verify that the database contains the expected number of items, which
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // is the pre-filtered count, i.e. all of the items.
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  sql::Statement statement(GetDB().GetUniqueStatement("SELECT * FROM urls;"));
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(statement);
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  uint64 row_count = 0;
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  while (statement.Step()) ++row_count;
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, row_count);
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url_index_.reset(new InMemoryURLIndex);
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url_index_->Init(this, "en,ja,hi,zh");
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, url_index_->history_item_count_);
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // history_info_map_ should have the same number of items as were filtered.
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, url_index_->history_info_map_.size());
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(36U, url_index_->char_word_map_.size());
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(17U, url_index_->word_map_.size());
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(InMemoryURLIndexTest, Retrieval) {
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  InMemoryURLIndex::String16Vector terms;
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The term will be lowercased by the search.
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // See if a very specific term gives a single result.
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("DrudgeReport"));
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, matches.size());
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify that we got back the result we expected.
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(5, matches[0].url_info.id());
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("http://drudgereport.com/", matches[0].url_info.url().spec());
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(ASCIIToUTF16("DRUDGE REPORT 2010"), matches[0].url_info.title());
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Search which should result in multiple results.
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  terms.clear();
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("drudge"));
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches = url_index_->HistoryItemsForTerms(terms);
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(2U, matches.size());
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The results should be in descending score order.
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GE(matches[0].raw_score, matches[1].raw_score);
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Search which should result in nearly perfect result.
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  terms.clear();
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("https"));
212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("NearlyPerfectResult"));
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  matches = url_index_->HistoryItemsForTerms(terms);
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1U, matches.size());
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The results should have a very high score.
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_GT(matches[0].raw_score, 900);
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(32, matches[0].url_info.id());
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("https://nearlyperfectresult.com/",
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            matches[0].url_info.url().spec());  // Note: URL gets lowercased.
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(ASCIIToUTF16("Practically Perfect Search Result"),
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            matches[0].url_info.title());
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Search which should result in very poor result.
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  terms.clear();
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("z"));
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("y"));
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("x"));
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  matches = url_index_->HistoryItemsForTerms(terms);
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1U, matches.size());
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The results should have a poor score.
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_LT(matches[0].raw_score, 500);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(33, matches[0].url_info.id());
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("http://quiteuselesssearchresultxyz.com/",
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            matches[0].url_info.url().spec());  // Note: URL gets lowercased.
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(ASCIIToUTF16("Practically Useless Search Result"),
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            matches[0].url_info.title());
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Search which will match at the end of an URL with encoded characters.
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.clear();
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("ice"));
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches = url_index_->HistoryItemsForTerms(terms);
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1U, matches.size());
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExpandedInMemoryURLIndexTest, ShortCircuit) {
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Vector terms;
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // A search for 'w' should short-circuit and not return any matches.
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("w"));
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(matches.empty());
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // A search for 'working' should not short-circuit.
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.clear();
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("working"));
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches = url_index_->HistoryItemsForTerms(terms);
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, matches.size());
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(InMemoryURLIndexTest, TitleSearch) {
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  url_index_.reset(new InMemoryURLIndex());
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Signal if someone has changed the test DB.
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(25U, url_index_->history_info_map_.size());
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Vector terms;
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ensure title is being searched.
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("MORTGAGE"));
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("RATE"));
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  terms.push_back(ASCIIToUTF16("DROPS"));
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, matches.size());
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify that we got back the result we expected.
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, matches[0].url_info.id());
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("http://www.reuters.com/article/idUSN0839880620100708",
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            matches[0].url_info.url().spec());
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(ASCIIToUTF16(
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "UPDATE 1-US 30-yr mortgage rate drops to new record low | Reuters"),
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      matches[0].url_info.title());
2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
285dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, Char16Utilities) {
286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 term = ASCIIToUTF16("drudgereport");
287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 expected = ASCIIToUTF16("drugepot");
288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(expected.size(),
289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            InMemoryURLIndex::Char16SetFromString16(term).size());
290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::Char16Vector c_vector =
291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      InMemoryURLIndex::Char16VectorFromString16(term);
292dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(expected.size(), c_vector.size());
293dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
294dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::Char16Vector::const_iterator c_iter = c_vector.begin();
295dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (string16::const_iterator s_iter = expected.begin();
296dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen       s_iter != expected.end(); ++s_iter, ++c_iter)
297dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(*s_iter, *c_iter);
298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(InMemoryURLIndexTest, StaticFunctions) {
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test WordVectorFromString16
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 string_a(ASCIIToUTF16("http://www.google.com/ frammy the brammy"));
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Vector string_vec =
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::WordVectorFromString16(string_a, false);
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(7U, string_vec.size());
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // See if we got the words we expected.
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("http"), string_vec[0]);
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("www"), string_vec[1]);
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("google"), string_vec[2]);
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("com"), string_vec[3]);
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("frammy"), string_vec[4]);
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("the"), string_vec[5]);
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("brammy"), string_vec[6]);
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string_vec = InMemoryURLIndex::WordVectorFromString16(string_a, true);
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(5U, string_vec.size());
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("http://"), string_vec[0]);
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("www.google.com/"), string_vec[1]);
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("frammy"), string_vec[2]);
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("the"), string_vec[3]);
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(UTF8ToUTF16("brammy"), string_vec[4]);
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test WordSetFromString16
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 string_b(ASCIIToUTF16(
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "http://web.google.com/search Google Web Search"));
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InMemoryURLIndex::String16Set string_set =
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::WordSetFromString16(string_b);
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(5U, string_set.size());
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // See if we got the words we expected.
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(string_set.find(UTF8ToUTF16("com")) != string_set.end());
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(string_set.find(UTF8ToUTF16("google")) != string_set.end());
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(string_set.find(UTF8ToUTF16("http")) != string_set.end());
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(string_set.find(UTF8ToUTF16("search")) != string_set.end());
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(string_set.find(UTF8ToUTF16("web")) != string_set.end());
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test SortAndDeoverlap
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TermMatches matches_a;
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(1, 13, 10));
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(2, 23, 10));
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(3, 3, 10));
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(4, 40, 5));
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TermMatches matches_b = InMemoryURLIndex::SortAndDeoverlap(matches_a);
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Nothing should have been eliminated.
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(matches_a.size(), matches_b.size());
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The order should now be 3, 1, 2, 4.
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(3, matches_b[0].term_num);
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, matches_b[1].term_num);
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, matches_b[2].term_num);
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4, matches_b[3].term_num);
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(5, 18, 10));
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(TermMatch(6, 38, 5));
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_b = InMemoryURLIndex::SortAndDeoverlap(matches_a);
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Two matches should have been eliminated.
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(matches_a.size() - 2, matches_b.size());
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The order should now be 3, 1, 2, 6.
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(3, matches_b[0].term_num);
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, matches_b[1].term_num);
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, matches_b[2].term_num);
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(6, matches_b[3].term_num);
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test MatchTermInString
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TermMatches matches_c = InMemoryURLIndex::MatchTermInString(
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UTF8ToUTF16("x"), UTF8ToUTF16("axbxcxdxex fxgx/hxixjx.kx"), 123);
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(11U, matches_c.size());
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const size_t expected_offsets[] = { 1, 3, 5, 7, 9, 12, 14, 17, 19, 21, 24 };
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (int i = 0; i < 11; ++i)
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(expected_offsets[i], matches_c[i].offset);
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(InMemoryURLIndexTest, OffsetsAndTermMatches) {
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test OffsetsFromTermMatches
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  history::TermMatches matches_a;
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(history::TermMatch(1, 1, 2));
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(history::TermMatch(2, 4, 3));
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(history::TermMatch(3, 9, 1));
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(history::TermMatch(3, 10, 1));
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  matches_a.push_back(history::TermMatch(4, 14, 5));
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<size_t> offsets =
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::OffsetsFromTermMatches(matches_a);
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const size_t expected_offsets_a[] = {1, 4, 9, 10, 14};
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(offsets.size(), arraysize(expected_offsets_a));
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < offsets.size(); ++i)
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(expected_offsets_a[i], offsets[i]);
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test ReplaceOffsetsInTermMatches
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  offsets[2] = string16::npos;
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  history::TermMatches matches_b =
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ReplaceOffsetsInTermMatches(matches_a, offsets);
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const size_t expected_offsets_b[] = {1, 4, 10, 14};
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(arraysize(expected_offsets_b), matches_b.size());
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < matches_b.size(); ++i)
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(expected_offsets_b[i], matches_b[i].offset);
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
395dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, TypedCharacterCaching) {
396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify that match results for previously typed characters are retained
397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // (in the term_char_word_set_cache_) and reused, if possible, in future
398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // autocompletes.
399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
400dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
401dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
402dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify that we can find something that already exists.
403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::String16Vector terms;
404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 term = ASCIIToUTF16("drudgerepo");
405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(term);
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size());
407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
408dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  {
409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Exercise the term matching cache with the same term.
410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::Char16Vector uni_chars =
411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        InMemoryURLIndex::Char16VectorFromString16(term);
412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(uni_chars.size(), 7U);  // Equivalent to 'degopru'
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(6U, url_index_->CachedResultsIndexForTerm(uni_chars));
414dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
415dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
416dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  {
417dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Back off a character.
418dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::Char16Vector uni_chars =
419dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        InMemoryURLIndex::Char16VectorFromString16(ASCIIToUTF16("drudgerep"));
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(6U, uni_chars.size());  // Equivalent to 'degpru'
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(5U, url_index_->CachedResultsIndexForTerm(uni_chars));
422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
424dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  {
425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Add a couple of characters.
426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::Char16Vector uni_chars =
427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        InMemoryURLIndex::Char16VectorFromString16(
428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            ASCIIToUTF16("drudgereporta"));
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(9U, uni_chars.size());  // Equivalent to 'adegoprtu'
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(6U, url_index_->CachedResultsIndexForTerm(uni_chars));
431dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
433dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  {
434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Use different string.
435dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::Char16Vector uni_chars =
436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        InMemoryURLIndex::Char16VectorFromString16(ASCIIToUTF16("abcde"));
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(5U, uni_chars.size());
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(static_cast<size_t>(-1),
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              url_index_->CachedResultsIndexForTerm(uni_chars));
440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
442dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(InMemoryURLIndexTest, Scoring) {
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  URLRow row_a(MakeURLRow("http://abcdef", "fedcba", 3, 30, 1));
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on position.
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_a(
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_a, Make1Term("abc")));
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_b(
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_a, Make1Term("bcd")));
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GT(scored_a.raw_score, scored_b.raw_score);
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on length.
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_c(
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_a, Make1Term("abcd")));
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_LT(scored_a.raw_score, scored_c.raw_score);
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on order.
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_d(
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_a, Make2Terms("abc", "def")));
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_e(
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_a, Make2Terms("def", "abc")));
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GT(scored_d.raw_score, scored_e.raw_score);
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on visit_count.
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  URLRow row_b(MakeURLRow("http://abcdef", "fedcba", 10, 30, 1));
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_f(
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_b, Make1Term("abc")));
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GT(scored_f.raw_score, scored_a.raw_score);
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on last_visit.
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  URLRow row_c(MakeURLRow("http://abcdef", "fedcba", 3, 10, 1));
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_g(
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_c, Make1Term("abc")));
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GT(scored_g.raw_score, scored_a.raw_score);
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test scores based on typed_count.
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  URLRow row_d(MakeURLRow("http://abcdef", "fedcba", 3, 30, 10));
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScoredHistoryMatch scored_h(
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      InMemoryURLIndex::ScoredMatchForURL(row_d, Make1Term("abc")));
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_GT(scored_h.raw_score, scored_a.raw_score);
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
478dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, AddNewRows) {
479dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
480dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
481dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::String16Vector terms;
482dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
483dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify that the row we're going to add does not already exist.
484dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  URLID new_row_id = 87654321;
485dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Newly created URLRows get a last_visit time of 'right now' so it should
486dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // qualify as a quick result candidate.
487dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("brokeandalone"));
488dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty());
489dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
490dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Add a new row.
491dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  URLRow new_row(GURL("http://www.brokeandaloneinmanitoba.com/"), new_row_id);
492dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  new_row.set_last_visit(base::Time::Now());
493dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->UpdateURL(new_row_id, new_row);
494dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
495dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Verify that we can retrieve it.
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size());
497dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
498dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Add it again just to be sure that is harmless.
499dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->UpdateURL(new_row_id, new_row);
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size());
501dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
502dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
503dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, DeleteRows) {
504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->Init(this, "en,ja,hi,zh");
506dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::String16Vector terms;
507dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
508dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Make sure we actually get an existing result.
509dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  terms.push_back(ASCIIToUTF16("DrudgeReport"));
510dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1U, matches.size());
512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
513dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Determine the row id for that result, delete that id, then search again.
514dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->DeleteURL(matches[0].url_info.id());
515dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty());
516dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
517dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
518dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, CacheFilePath) {
519dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL(
520dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "/flammmy/frammy/"))));
521dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  FilePath full_file_path;
522dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_->GetCacheFilePath(&full_file_path);
523dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<FilePath::StringType> expected_parts;
524dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  FilePath(FILE_PATH_LITERAL("/flammmy/frammy/History Provider Cache")).
525dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      GetComponents(&expected_parts);
526dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::vector<FilePath::StringType> actual_parts;
527dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  full_file_path.GetComponents(&actual_parts);
528dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(expected_parts.size(), actual_parts.size());
529dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t count = expected_parts.size();
530dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (size_t i = 0; i < count; ++i)
531dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected_parts[i], actual_parts[i]);
532dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
533dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
534dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(InMemoryURLIndexTest, CacheSaveRestore) {
535dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Save the cache to a protobuf, restore it, and compare the results.
536dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy"))));
537dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex& url_index(*(url_index_.get()));
538dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index.Init(this, "en,ja,hi,zh");
539dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  in_memory_url_index::InMemoryURLIndexCacheItem index_cache;
540dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index.SavePrivateData(&index_cache);
541dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
542dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Capture our private data so we can later compare for equality.
543dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int history_item_count(url_index.history_item_count_);
544dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::String16Vector word_list(url_index.word_list_);
545dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::WordMap word_map(url_index.word_map_);
546dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::CharWordIDMap char_word_map(url_index.char_word_map_);
547dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::WordIDHistoryMap word_id_history_map(
548dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      url_index.word_id_history_map_);
549dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InMemoryURLIndex::HistoryInfoMap history_info_map(
550dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      url_index.history_info_map_);
551dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
552dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Prove that there is really something there.
553dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_GT(url_index.history_item_count_, 0);
554dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(url_index.word_list_.empty());
555dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(url_index.word_map_.empty());
556dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(url_index.char_word_map_.empty());
557dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(url_index.word_id_history_map_.empty());
558dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(url_index.history_info_map_.empty());
559dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
560dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Clear and then prove it's clear.
561dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  url_index.ClearPrivateData();
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, url_index.history_item_count_);
563dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.word_list_.empty());
564dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.word_map_.empty());
565dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.char_word_map_.empty());
566dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.word_id_history_map_.empty());
567dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.history_info_map_.empty());
568dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
569dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Restore the cache.
570dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(url_index.RestorePrivateData(index_cache));
571dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
572dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Compare the restored and captured for equality.
573dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(history_item_count, url_index.history_item_count_);
574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(word_list.size(), url_index.word_list_.size());
575dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(word_map.size(), url_index.word_map_.size());
576dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(char_word_map.size(), url_index.char_word_map_.size());
577dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(word_id_history_map.size(), url_index.word_id_history_map_.size());
578dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(history_info_map.size(), url_index.history_info_map_.size());
579dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // WordList must be index-by-index equal.
580dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t count = word_list.size();
581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (size_t i = 0; i < count; ++i)
582dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(word_list[i], url_index.word_list_[i]);
583dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (InMemoryURLIndex::CharWordIDMap::const_iterator expected =
584dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        char_word_map.begin(); expected != char_word_map.end(); ++expected) {
585dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::CharWordIDMap::const_iterator actual =
586dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        url_index.char_word_map_.find(expected->first);
587dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ASSERT_TRUE(url_index.char_word_map_.end() != actual);
588dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const InMemoryURLIndex::WordIDSet& expected_set(expected->second);
589dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const InMemoryURLIndex::WordIDSet& actual_set(actual->second);
590dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ASSERT_EQ(expected_set.size(), actual_set.size());
591dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    for (InMemoryURLIndex::WordIDSet::const_iterator set_iter =
592dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        expected_set.begin(); set_iter != expected_set.end(); ++set_iter)
593dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      EXPECT_GT(actual_set.count(*set_iter), 0U);
594dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
595dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (InMemoryURLIndex::WordIDHistoryMap::const_iterator expected =
596dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      word_id_history_map.begin(); expected != word_id_history_map.end();
597dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ++expected) {
598dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::WordIDHistoryMap::const_iterator actual =
599dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        url_index.word_id_history_map_.find(expected->first);
600dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ASSERT_TRUE(url_index.word_id_history_map_.end() != actual);
601dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const InMemoryURLIndex::HistoryIDSet& expected_set(expected->second);
602dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const InMemoryURLIndex::HistoryIDSet& actual_set(actual->second);
603dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ASSERT_EQ(expected_set.size(), actual_set.size());
604dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    for (InMemoryURLIndex::HistoryIDSet::const_iterator set_iter =
605dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        expected_set.begin(); set_iter != expected_set.end(); ++set_iter)
606dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      EXPECT_GT(actual_set.count(*set_iter), 0U);
607dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
608dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (InMemoryURLIndex::HistoryInfoMap::const_iterator expected =
609dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      history_info_map.begin(); expected != history_info_map.end();
610dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ++expected) {
611dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    InMemoryURLIndex::HistoryInfoMap::const_iterator actual =
612dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        url_index.history_info_map_.find(expected->first);
613dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ASSERT_FALSE(url_index.history_info_map_.end() == actual);
614dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const URLRow& expected_row(expected->second);
615dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const URLRow& actual_row(actual->second);
616dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected_row.visit_count(), actual_row.visit_count());
617dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected_row.typed_count(), actual_row.typed_count());
618dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected_row.last_visit(), actual_row.last_visit());
619dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected_row.url(), actual_row.url());
620dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
621dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
622dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace history
624