Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: chrome/browser/history/in_memory_url_index_unittest.cc

Issue 8291005: HQP Refactoring (in Preparation for SQLite Cache) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Rattle those Bots Senseless Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdio.h>
6
7 #include <fstream> 5 #include <fstream>
8 #include <string>
9 #include <vector>
10 6
11 #include "base/file_path.h" 7 #include "base/file_path.h"
12 #include "base/file_util.h" 8 #include "base/file_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/path_service.h" 9 #include "base/path_service.h"
10 #include "base/string16.h"
15 #include "base/string_util.h" 11 #include "base/string_util.h"
16 #include "base/time.h"
17 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/history/in_memory_database.h" 13 #include "chrome/browser/history/in_memory_database.h"
19 #include "chrome/browser/history/in_memory_url_index.h" 14 #include "chrome/browser/history/in_memory_url_index.h"
15 #include "chrome/browser/history/in_memory_url_index_types.h"
20 #include "chrome/common/chrome_paths.h" 16 #include "chrome/common/chrome_paths.h"
21 #include "sql/connection.h"
22 #include "sql/statement.h"
23 #include "sql/transaction.h" 17 #include "sql/transaction.h"
24 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
25 19
26 // The test version of the history url database table ('url') is contained in 20 // The test version of the history url database table ('url') is contained in
27 // a database file created from a text file('url_history_provider_test.db.txt'). 21 // a database file created from a text file('url_history_provider_test.db.txt').
28 // The only difference between this table and a live 'urls' table from a 22 // The only difference between this table and a live 'urls' table from a
29 // profile is that the last_visit_time column in the test table contains a 23 // profile is that the last_visit_time column in the test table contains a
30 // number specifying the number of days relative to 'today' to which the 24 // number specifying the number of days relative to 'today' to which the
31 // absolute time should be set during the test setup stage. 25 // absolute time should be set during the test setup stage.
32 // 26 //
(...skipping 19 matching lines...) Expand all
52 // Convenience function to create a URLRow with basic data for |url|, |title|, 46 // Convenience function to create a URLRow with basic data for |url|, |title|,
53 // |visit_count|, and |typed_count|. |last_visit_ago| gives the number of 47 // |visit_count|, and |typed_count|. |last_visit_ago| gives the number of
54 // days from now to set the URL's last_visit. 48 // days from now to set the URL's last_visit.
55 URLRow MakeURLRow(const char* url, 49 URLRow MakeURLRow(const char* url,
56 const char* title, 50 const char* title,
57 int visit_count, 51 int visit_count,
58 int last_visit_ago, 52 int last_visit_ago,
59 int typed_count); 53 int typed_count);
60 54
61 // Convenience functions for easily creating vectors of search terms. 55 // Convenience functions for easily creating vectors of search terms.
62 InMemoryURLIndex::String16Vector Make1Term(const char* term) const; 56 String16Vector Make1Term(const char* term) const;
63 InMemoryURLIndex::String16Vector Make2Terms(const char* term_1, 57 String16Vector Make2Terms(const char* term_1, const char* term_2) const;
64 const char* term_2) const;
65 58
66 // Validates that the given |term| is contained in |cache| and that it is 59 // Validates that the given |term| is contained in |cache| and that it is
67 // marked as in-use. 60 // marked as in-use.
68 void CheckTerm(const InMemoryURLIndex::SearchTermCacheMap& cache, 61 void CheckTerm(const InMemoryURLIndex::SearchTermCacheMap& cache,
69 string16 term) const; 62 string16 term) const;
70 63
71 scoped_ptr<InMemoryURLIndex> url_index_; 64 scoped_ptr<InMemoryURLIndex> url_index_;
72 }; 65 };
73 66
74 void InMemoryURLIndexTest::SetUp() { 67 void InMemoryURLIndexTest::SetUp() {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 int typed_count) { 131 int typed_count) {
139 URLRow row(GURL(url), 0); 132 URLRow row(GURL(url), 0);
140 row.set_title(UTF8ToUTF16(title)); 133 row.set_title(UTF8ToUTF16(title));
141 row.set_visit_count(visit_count); 134 row.set_visit_count(visit_count);
142 row.set_typed_count(typed_count); 135 row.set_typed_count(typed_count);
143 row.set_last_visit(base::Time::NowFromSystemTime() - 136 row.set_last_visit(base::Time::NowFromSystemTime() -
144 base::TimeDelta::FromDays(last_visit_ago)); 137 base::TimeDelta::FromDays(last_visit_ago));
145 return row; 138 return row;
146 } 139 }
147 140
148 InMemoryURLIndex::String16Vector InMemoryURLIndexTest::Make1Term( 141 String16Vector InMemoryURLIndexTest::Make1Term(const char* term) const {
149 const char* term) const { 142 String16Vector terms;
150 InMemoryURLIndex::String16Vector terms;
151 terms.push_back(UTF8ToUTF16(term)); 143 terms.push_back(UTF8ToUTF16(term));
152 return terms; 144 return terms;
153 } 145 }
154 146
155 InMemoryURLIndex::String16Vector InMemoryURLIndexTest::Make2Terms( 147 String16Vector InMemoryURLIndexTest::Make2Terms(const char* term_1,
156 const char* term_1, 148 const char* term_2) const {
157 const char* term_2) const { 149 String16Vector terms;
158 InMemoryURLIndex::String16Vector terms;
159 terms.push_back(UTF8ToUTF16(term_1)); 150 terms.push_back(UTF8ToUTF16(term_1));
160 terms.push_back(UTF8ToUTF16(term_2)); 151 terms.push_back(UTF8ToUTF16(term_2));
161 return terms; 152 return terms;
162 } 153 }
163 154
164 void InMemoryURLIndexTest::CheckTerm( 155 void InMemoryURLIndexTest::CheckTerm(
165 const InMemoryURLIndex::SearchTermCacheMap& cache, 156 const InMemoryURLIndex::SearchTermCacheMap& cache,
166 string16 term) const { 157 string16 term) const {
167 InMemoryURLIndex::SearchTermCacheMap::const_iterator cache_iter( 158 InMemoryURLIndex::SearchTermCacheMap::const_iterator cache_iter(
168 cache.find(term)); 159 cache.find(term));
169 ASSERT_NE(cache.end(), cache_iter) 160 ASSERT_NE(cache.end(), cache_iter)
170 << "Cache does not contain '" << term << "' but should."; 161 << "Cache does not contain '" << term << "' but should.";
171 InMemoryURLIndex::SearchTermCacheItem cache_item = cache_iter->second; 162 InMemoryURLIndex::SearchTermCacheItem cache_item = cache_iter->second;
172 EXPECT_TRUE(cache_item.used_) 163 EXPECT_TRUE(cache_item.used_)
173 << "Cache item '" << term << "' should be marked as being in use."; 164 << "Cache item '" << term << "' should be marked as being in use.";
174 } 165 }
175 166
167 // Helper function which compares two maps for equivalence. The maps' values
168 // are associative containers and their contents are compared as well.
169 template<typename T>
170 void ExpectMapOfContainersIdentical(const T& expected, const T& actual) {
171 ASSERT_EQ(expected.size(), actual.size());
172 for (typename T::const_iterator expected_iter = expected.begin();
173 expected_iter != expected.end(); ++expected_iter) {
174 typename T::const_iterator actual_iter = actual.find(expected_iter->first);
175 ASSERT_NE(actual.end(), actual_iter);
176 typename T::mapped_type const& expected_values(expected_iter->second);
177 typename T::mapped_type const& actual_values(actual_iter->second);
178 ASSERT_EQ(expected_values.size(), actual_values.size());
179 for (typename T::mapped_type::const_iterator set_iter =
180 expected_values.begin(); set_iter != expected_values.end(); ++set_iter)
181 EXPECT_EQ(actual_values.count(*set_iter),
182 expected_values.count(*set_iter));
183 }
184 }
185
186 //------------------------------------------------------------------------------
187
176 class LimitedInMemoryURLIndexTest : public InMemoryURLIndexTest { 188 class LimitedInMemoryURLIndexTest : public InMemoryURLIndexTest {
177 protected: 189 protected:
178 FilePath::StringType TestDBName() const; 190 FilePath::StringType TestDBName() const;
179 }; 191 };
180 192
181 FilePath::StringType LimitedInMemoryURLIndexTest::TestDBName() const { 193 FilePath::StringType LimitedInMemoryURLIndexTest::TestDBName() const {
182 return FILE_PATH_LITERAL("url_history_provider_test_limited.db.txt"); 194 return FILE_PATH_LITERAL("url_history_provider_test_limited.db.txt");
183 } 195 }
184 196
185 class ExpandedInMemoryURLIndexTest : public InMemoryURLIndexTest { 197 class ExpandedInMemoryURLIndexTest : public InMemoryURLIndexTest {
(...skipping 10 matching lines...) Expand all
196 const size_t kMaxLen = arraysize(url_format) + 5; 208 const size_t kMaxLen = arraysize(url_format) + 5;
197 char url_string[kMaxLen + 1]; 209 char url_string[kMaxLen + 1];
198 for (int i = 0; i < 600; ++i) { 210 for (int i = 0; i < 600; ++i) {
199 base::snprintf(url_string, kMaxLen, url_format, i); 211 base::snprintf(url_string, kMaxLen, url_format, i);
200 URLRow row(MakeURLRow(url_string, "Google Search", 20, 0, 20)); 212 URLRow row(MakeURLRow(url_string, "Google Search", 20, 0, 20));
201 AddURL(row); 213 AddURL(row);
202 } 214 }
203 } 215 }
204 216
205 TEST_F(InMemoryURLIndexTest, Construction) { 217 TEST_F(InMemoryURLIndexTest, Construction) {
206 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 218 url_index_.reset(new InMemoryURLIndex(NULL,
219 FilePath(FILE_PATH_LITERAL("/dummy"))));
207 EXPECT_TRUE(url_index_.get()); 220 EXPECT_TRUE(url_index_.get());
208 } 221 }
209 222
210 TEST_F(LimitedInMemoryURLIndexTest, Initialization) { 223 TEST_F(LimitedInMemoryURLIndexTest, Initialization) {
211 // Verify that the database contains the expected number of items, which 224 // Verify that the database contains the expected number of items, which
212 // is the pre-filtered count, i.e. all of the items. 225 // is the pre-filtered count, i.e. all of the items.
213 sql::Statement statement(GetDB().GetUniqueStatement("SELECT * FROM urls;")); 226 sql::Statement statement(GetDB().GetUniqueStatement("SELECT * FROM urls;"));
214 EXPECT_TRUE(statement); 227 EXPECT_TRUE(statement);
215 uint64 row_count = 0; 228 uint64 row_count = 0;
216 while (statement.Step()) ++row_count; 229 while (statement.Step()) ++row_count;
217 EXPECT_EQ(1U, row_count); 230 EXPECT_EQ(1U, row_count);
218 url_index_.reset(new InMemoryURLIndex); 231 url_index_.reset(new InMemoryURLIndex);
219 url_index_->Init(this, "en,ja,hi,zh"); 232 url_index_->Init(this, "en,ja,hi,zh");
220 EXPECT_EQ(1, url_index_->history_item_count_); 233 URLIndexPrivateData& private_data(*(url_index_->private_data_));
221 234
222 // history_info_map_ should have the same number of items as were filtered. 235 // history_info_map_ should have the same number of items as were filtered.
223 EXPECT_EQ(1U, url_index_->history_info_map_.size()); 236 EXPECT_EQ(1U, private_data.history_info_map_.size());
224 EXPECT_EQ(35U, url_index_->char_word_map_.size()); 237 EXPECT_EQ(35U, private_data.char_word_map_.size());
225 EXPECT_EQ(17U, url_index_->word_map_.size()); 238 EXPECT_EQ(17U, private_data.word_map_.size());
226 } 239 }
227 240
228 TEST_F(InMemoryURLIndexTest, Retrieval) { 241 TEST_F(InMemoryURLIndexTest, Retrieval) {
229 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 242 url_index_.reset(new InMemoryURLIndex(NULL,
243 FilePath(FILE_PATH_LITERAL("/dummy"))));
230 url_index_->Init(this, "en,ja,hi,zh"); 244 url_index_->Init(this, "en,ja,hi,zh");
231 // The term will be lowercased by the search. 245 // The term will be lowercased by the search.
232 246
233 // See if a very specific term gives a single result. 247 // See if a very specific term gives a single result.
234 ScoredHistoryMatches matches = 248 ScoredHistoryMatches matches =
235 url_index_->HistoryItemsForTerms(Make1Term("DrudgeReport")); 249 url_index_->HistoryItemsForTerms(Make1Term("DrudgeReport"));
236 ASSERT_EQ(1U, matches.size()); 250 ASSERT_EQ(1U, matches.size());
237 251
238 // Verify that we got back the result we expected. 252 // Verify that we got back the result we expected.
239 EXPECT_EQ(5, matches[0].url_info.id()); 253 EXPECT_EQ(5, matches[0].url_info.id());
(...skipping 12 matching lines...) Expand all
252 ASSERT_EQ(1U, matches.size()); 266 ASSERT_EQ(1U, matches.size());
253 // The results should have a very high score. 267 // The results should have a very high score.
254 EXPECT_GT(matches[0].raw_score, 900); 268 EXPECT_GT(matches[0].raw_score, 900);
255 EXPECT_EQ(32, matches[0].url_info.id()); 269 EXPECT_EQ(32, matches[0].url_info.id());
256 EXPECT_EQ("https://nearlyperfectresult.com/", 270 EXPECT_EQ("https://nearlyperfectresult.com/",
257 matches[0].url_info.url().spec()); // Note: URL gets lowercased. 271 matches[0].url_info.url().spec()); // Note: URL gets lowercased.
258 EXPECT_EQ(ASCIIToUTF16("Practically Perfect Search Result"), 272 EXPECT_EQ(ASCIIToUTF16("Practically Perfect Search Result"),
259 matches[0].url_info.title()); 273 matches[0].url_info.title());
260 274
261 // Search which should result in very poor result. 275 // Search which should result in very poor result.
262 InMemoryURLIndex::String16Vector terms; 276 String16Vector terms;
263 terms.push_back(ASCIIToUTF16("z")); 277 terms.push_back(ASCIIToUTF16("z"));
264 terms.push_back(ASCIIToUTF16("y")); 278 terms.push_back(ASCIIToUTF16("y"));
265 terms.push_back(ASCIIToUTF16("x")); 279 terms.push_back(ASCIIToUTF16("x"));
266 matches = url_index_->HistoryItemsForTerms(terms); 280 matches = url_index_->HistoryItemsForTerms(terms);
267 ASSERT_EQ(1U, matches.size()); 281 ASSERT_EQ(1U, matches.size());
268 // The results should have a poor score. 282 // The results should have a poor score.
269 EXPECT_LT(matches[0].raw_score, 500); 283 EXPECT_LT(matches[0].raw_score, 500);
270 EXPECT_EQ(33, matches[0].url_info.id()); 284 EXPECT_EQ(33, matches[0].url_info.id());
271 EXPECT_EQ("http://quiteuselesssearchresultxyz.com/", 285 EXPECT_EQ("http://quiteuselesssearchresultxyz.com/",
272 matches[0].url_info.url().spec()); // Note: URL gets lowercased. 286 matches[0].url_info.url().spec()); // Note: URL gets lowercased.
273 EXPECT_EQ(ASCIIToUTF16("Practically Useless Search Result"), 287 EXPECT_EQ(ASCIIToUTF16("Practically Useless Search Result"),
274 matches[0].url_info.title()); 288 matches[0].url_info.title());
275 289
276 // Search which will match at the end of an URL with encoded characters. 290 // Search which will match at the end of an URL with encoded characters.
277 matches = url_index_->HistoryItemsForTerms(Make1Term("ice")); 291 matches = url_index_->HistoryItemsForTerms(Make1Term("ice"));
278 ASSERT_EQ(1U, matches.size()); 292 ASSERT_EQ(1U, matches.size());
279 } 293 }
280 294
281 TEST_F(ExpandedInMemoryURLIndexTest, ShortCircuit) { 295 TEST_F(ExpandedInMemoryURLIndexTest, ShortCircuit) {
282 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 296 url_index_.reset(new InMemoryURLIndex(NULL,
297 FilePath(FILE_PATH_LITERAL("/dummy"))));
283 url_index_->Init(this, "en,ja,hi,zh"); 298 url_index_->Init(this, "en,ja,hi,zh");
284 299
285 // A search for 'w' should short-circuit and not return any matches. 300 // A search for 'w' should short-circuit and not return any matches.
286 ScoredHistoryMatches matches = 301 ScoredHistoryMatches matches =
287 url_index_->HistoryItemsForTerms(Make1Term("w")); 302 url_index_->HistoryItemsForTerms(Make1Term("w"));
288 EXPECT_TRUE(matches.empty()); 303 EXPECT_TRUE(matches.empty());
289 304
290 // A search for 'working' should not short-circuit. 305 // A search for 'working' should not short-circuit.
291 matches = url_index_->HistoryItemsForTerms(Make1Term("working")); 306 matches = url_index_->HistoryItemsForTerms(Make1Term("working"));
292 EXPECT_EQ(1U, matches.size()); 307 EXPECT_EQ(1U, matches.size());
293 } 308 }
294 309
295 TEST_F(InMemoryURLIndexTest, TitleSearch) { 310 TEST_F(InMemoryURLIndexTest, TitleSearch) {
296 url_index_.reset(new InMemoryURLIndex()); 311 url_index_.reset(new InMemoryURLIndex());
297 url_index_->Init(this, "en,ja,hi,zh"); 312 url_index_->Init(this, "en,ja,hi,zh");
298 // Signal if someone has changed the test DB. 313 // Signal if someone has changed the test DB.
299 EXPECT_EQ(27U, url_index_->history_info_map_.size()); 314 EXPECT_EQ(27U, url_index_->private_data_->history_info_map_.size());
300 InMemoryURLIndex::String16Vector terms; 315 String16Vector terms;
301 316
302 // Ensure title is being searched. 317 // Ensure title is being searched.
303 terms.push_back(ASCIIToUTF16("MORTGAGE")); 318 terms.push_back(ASCIIToUTF16("MORTGAGE"));
304 terms.push_back(ASCIIToUTF16("RATE")); 319 terms.push_back(ASCIIToUTF16("RATE"));
305 terms.push_back(ASCIIToUTF16("DROPS")); 320 terms.push_back(ASCIIToUTF16("DROPS"));
306 ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms); 321 ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
307 ASSERT_EQ(1U, matches.size()); 322 ASSERT_EQ(1U, matches.size());
308 323
309 // Verify that we got back the result we expected. 324 // Verify that we got back the result we expected.
310 EXPECT_EQ(1, matches[0].url_info.id()); 325 EXPECT_EQ(1, matches[0].url_info.id());
(...skipping 27 matching lines...) Expand all
338 353
339 matches = url_index_->HistoryItemsForTerms(Make1Term("ABRACADABR")); 354 matches = url_index_->HistoryItemsForTerms(Make1Term("ABRACADABR"));
340 ASSERT_EQ(1U, matches.size()); 355 ASSERT_EQ(1U, matches.size());
341 EXPECT_EQ(28, matches[0].url_info.id()); 356 EXPECT_EQ(28, matches[0].url_info.id());
342 357
343 matches = url_index_->HistoryItemsForTerms(Make1Term("ABRACA")); 358 matches = url_index_->HistoryItemsForTerms(Make1Term("ABRACA"));
344 ASSERT_EQ(1U, matches.size()); 359 ASSERT_EQ(1U, matches.size());
345 EXPECT_EQ(28, matches[0].url_info.id()); 360 EXPECT_EQ(28, matches[0].url_info.id());
346 } 361 }
347 362
348 TEST_F(InMemoryURLIndexTest, StaticFunctions) {
349 // Test WordVectorFromString16
350 string16 string_a(ASCIIToUTF16("http://www.google.com/ frammy the brammy"));
351 InMemoryURLIndex::String16Vector string_vec =
352 InMemoryURLIndex::WordVectorFromString16(string_a, false);
353 ASSERT_EQ(7U, string_vec.size());
354 // See if we got the words we expected.
355 EXPECT_EQ(UTF8ToUTF16("http"), string_vec[0]);
356 EXPECT_EQ(UTF8ToUTF16("www"), string_vec[1]);
357 EXPECT_EQ(UTF8ToUTF16("google"), string_vec[2]);
358 EXPECT_EQ(UTF8ToUTF16("com"), string_vec[3]);
359 EXPECT_EQ(UTF8ToUTF16("frammy"), string_vec[4]);
360 EXPECT_EQ(UTF8ToUTF16("the"), string_vec[5]);
361 EXPECT_EQ(UTF8ToUTF16("brammy"), string_vec[6]);
362
363 string_vec = InMemoryURLIndex::WordVectorFromString16(string_a, true);
364 ASSERT_EQ(5U, string_vec.size());
365 EXPECT_EQ(UTF8ToUTF16("http://"), string_vec[0]);
366 EXPECT_EQ(UTF8ToUTF16("www.google.com/"), string_vec[1]);
367 EXPECT_EQ(UTF8ToUTF16("frammy"), string_vec[2]);
368 EXPECT_EQ(UTF8ToUTF16("the"), string_vec[3]);
369 EXPECT_EQ(UTF8ToUTF16("brammy"), string_vec[4]);
370
371 // Test WordSetFromString16
372 string16 string_b(ASCIIToUTF16(
373 "http://web.google.com/search Google Web Search"));
374 InMemoryURLIndex::String16Set string_set =
375 InMemoryURLIndex::WordSetFromString16(string_b);
376 EXPECT_EQ(5U, string_set.size());
377 // See if we got the words we expected.
378 EXPECT_TRUE(string_set.find(UTF8ToUTF16("com")) != string_set.end());
379 EXPECT_TRUE(string_set.find(UTF8ToUTF16("google")) != string_set.end());
380 EXPECT_TRUE(string_set.find(UTF8ToUTF16("http")) != string_set.end());
381 EXPECT_TRUE(string_set.find(UTF8ToUTF16("search")) != string_set.end());
382 EXPECT_TRUE(string_set.find(UTF8ToUTF16("web")) != string_set.end());
383
384 // Test SortAndDeoverlap
385 TermMatches matches_a;
386 matches_a.push_back(TermMatch(1, 13, 10));
387 matches_a.push_back(TermMatch(2, 23, 10));
388 matches_a.push_back(TermMatch(3, 3, 10));
389 matches_a.push_back(TermMatch(4, 40, 5));
390 TermMatches matches_b = InMemoryURLIndex::SortAndDeoverlap(matches_a);
391 // Nothing should have been eliminated.
392 EXPECT_EQ(matches_a.size(), matches_b.size());
393 // The order should now be 3, 1, 2, 4.
394 EXPECT_EQ(3, matches_b[0].term_num);
395 EXPECT_EQ(1, matches_b[1].term_num);
396 EXPECT_EQ(2, matches_b[2].term_num);
397 EXPECT_EQ(4, matches_b[3].term_num);
398 matches_a.push_back(TermMatch(5, 18, 10));
399 matches_a.push_back(TermMatch(6, 38, 5));
400 matches_b = InMemoryURLIndex::SortAndDeoverlap(matches_a);
401 // Two matches should have been eliminated.
402 EXPECT_EQ(matches_a.size() - 2, matches_b.size());
403 // The order should now be 3, 1, 2, 6.
404 EXPECT_EQ(3, matches_b[0].term_num);
405 EXPECT_EQ(1, matches_b[1].term_num);
406 EXPECT_EQ(2, matches_b[2].term_num);
407 EXPECT_EQ(6, matches_b[3].term_num);
408
409 // Test MatchTermInString
410 TermMatches matches_c = InMemoryURLIndex::MatchTermInString(
411 UTF8ToUTF16("x"), UTF8ToUTF16("axbxcxdxex fxgx/hxixjx.kx"), 123);
412 ASSERT_EQ(11U, matches_c.size());
413 const size_t expected_offsets[] = { 1, 3, 5, 7, 9, 12, 14, 17, 19, 21, 24 };
414 for (int i = 0; i < 11; ++i)
415 EXPECT_EQ(expected_offsets[i], matches_c[i].offset);
416 }
417
418 TEST_F(InMemoryURLIndexTest, OffsetsAndTermMatches) {
419 // Test OffsetsFromTermMatches
420 history::TermMatches matches_a;
421 matches_a.push_back(history::TermMatch(1, 1, 2));
422 matches_a.push_back(history::TermMatch(2, 4, 3));
423 matches_a.push_back(history::TermMatch(3, 9, 1));
424 matches_a.push_back(history::TermMatch(3, 10, 1));
425 matches_a.push_back(history::TermMatch(4, 14, 5));
426 std::vector<size_t> offsets =
427 InMemoryURLIndex::OffsetsFromTermMatches(matches_a);
428 const size_t expected_offsets_a[] = {1, 4, 9, 10, 14};
429 ASSERT_EQ(offsets.size(), arraysize(expected_offsets_a));
430 for (size_t i = 0; i < offsets.size(); ++i)
431 EXPECT_EQ(expected_offsets_a[i], offsets[i]);
432
433 // Test ReplaceOffsetsInTermMatches
434 offsets[2] = string16::npos;
435 history::TermMatches matches_b =
436 InMemoryURLIndex::ReplaceOffsetsInTermMatches(matches_a, offsets);
437 const size_t expected_offsets_b[] = {1, 4, 10, 14};
438 ASSERT_EQ(arraysize(expected_offsets_b), matches_b.size());
439 for (size_t i = 0; i < matches_b.size(); ++i)
440 EXPECT_EQ(expected_offsets_b[i], matches_b[i].offset);
441 }
442
443 TEST_F(InMemoryURLIndexTest, TypedCharacterCaching) { 363 TEST_F(InMemoryURLIndexTest, TypedCharacterCaching) {
444 // Verify that match results for previously typed characters are retained 364 // Verify that match results for previously typed characters are retained
445 // (in the term_char_word_set_cache_) and reused, if possible, in future 365 // (in the term_char_word_set_cache_) and reused, if possible, in future
446 // autocompletes. 366 // autocompletes.
447 typedef InMemoryURLIndex::SearchTermCacheMap::iterator CacheIter; 367 typedef InMemoryURLIndex::SearchTermCacheMap::iterator CacheIter;
448 typedef InMemoryURLIndex::SearchTermCacheItem CacheItem; 368 typedef InMemoryURLIndex::SearchTermCacheItem CacheItem;
449 369
450 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 370 url_index_.reset(new InMemoryURLIndex(NULL,
371 FilePath(FILE_PATH_LITERAL("/dummy"))));
451 url_index_->Init(this, "en,ja,hi,zh"); 372 url_index_->Init(this, "en,ja,hi,zh");
452 373
453 InMemoryURLIndex::SearchTermCacheMap& cache(url_index_->search_term_cache_); 374 InMemoryURLIndex::SearchTermCacheMap& cache(url_index_->search_term_cache_);
454 375
455 // The cache should be empty at this point. 376 // The cache should be empty at this point.
456 EXPECT_EQ(0U, cache.size()); 377 EXPECT_EQ(0U, cache.size());
457 378
458 // Now simulate typing search terms into the omnibox and check the state of 379 // Now simulate typing search terms into the omnibox and check the state of
459 // the cache as each item is 'typed'. 380 // the cache as each item is 'typed'.
460 381
461 // Simulate typing "r" giving "r" in the simulated omnibox. The results for 382 // Simulate typing "r" giving "r" in the simulated omnibox. The results for
462 // 'r' will be not cached because it is only 1 character long. 383 // 'r' will be not cached because it is only 1 character long.
463 InMemoryURLIndex::String16Vector terms; 384 String16Vector terms;
464 string16 term_r = ASCIIToUTF16("r"); 385 string16 term_r = ASCIIToUTF16("r");
465 terms.push_back(term_r); 386 terms.push_back(term_r);
466 url_index_->HistoryItemsForTerms(terms); 387 url_index_->HistoryItemsForTerms(terms);
467 EXPECT_EQ(0U, cache.size()); 388 EXPECT_EQ(0U, cache.size());
468 389
469 // Simulate typing "re" giving "r re" in the simulated omnibox. 390 // Simulate typing "re" giving "r re" in the simulated omnibox.
470 string16 term_re = ASCIIToUTF16("re"); 391 string16 term_re = ASCIIToUTF16("re");
471 terms.push_back(term_re); 392 terms.push_back(term_re);
472 // 're' should be cached at this point but not 'r' as it is a single 393 // 're' should be cached at this point but not 'r' as it is a single
473 // character. 394 // character.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 InMemoryURLIndex::ScoredMatchForURL(row_c, Make1Term("abc"))); 464 InMemoryURLIndex::ScoredMatchForURL(row_c, Make1Term("abc")));
544 EXPECT_GT(scored_g.raw_score, scored_a.raw_score); 465 EXPECT_GT(scored_g.raw_score, scored_a.raw_score);
545 // Test scores based on typed_count. 466 // Test scores based on typed_count.
546 URLRow row_d(MakeURLRow("http://abcdef", "fedcba", 3, 30, 10)); 467 URLRow row_d(MakeURLRow("http://abcdef", "fedcba", 3, 30, 10));
547 ScoredHistoryMatch scored_h( 468 ScoredHistoryMatch scored_h(
548 InMemoryURLIndex::ScoredMatchForURL(row_d, Make1Term("abc"))); 469 InMemoryURLIndex::ScoredMatchForURL(row_d, Make1Term("abc")));
549 EXPECT_GT(scored_h.raw_score, scored_a.raw_score); 470 EXPECT_GT(scored_h.raw_score, scored_a.raw_score);
550 } 471 }
551 472
552 TEST_F(InMemoryURLIndexTest, AddNewRows) { 473 TEST_F(InMemoryURLIndexTest, AddNewRows) {
553 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 474 url_index_.reset(new InMemoryURLIndex(NULL,
475 FilePath(FILE_PATH_LITERAL("/dummy"))));
554 url_index_->Init(this, "en,ja,hi,zh"); 476 url_index_->Init(this, "en,ja,hi,zh");
555 InMemoryURLIndex::String16Vector terms; 477 String16Vector terms;
556 478
557 // Verify that the row we're going to add does not already exist. 479 // Verify that the row we're going to add does not already exist.
558 URLID new_row_id = 87654321; 480 URLID new_row_id = 87654321;
559 // Newly created URLRows get a last_visit time of 'right now' so it should 481 // Newly created URLRows get a last_visit time of 'right now' so it should
560 // qualify as a quick result candidate. 482 // qualify as a quick result candidate.
561 terms.push_back(ASCIIToUTF16("brokeandalone")); 483 terms.push_back(ASCIIToUTF16("brokeandalone"));
562 EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty()); 484 EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty());
563 485
564 // Add a new row. 486 // Add a new row.
565 URLRow new_row(GURL("http://www.brokeandaloneinmanitoba.com/"), new_row_id); 487 URLRow new_row(GURL("http://www.brokeandaloneinmanitoba.com/"), new_row_id);
566 new_row.set_last_visit(base::Time::Now()); 488 new_row.set_last_visit(base::Time::Now());
567 url_index_->UpdateURL(new_row_id, new_row); 489 url_index_->UpdateURL(new_row);
568 490
569 // Verify that we can retrieve it. 491 // Verify that we can retrieve it.
570 EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size()); 492 EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size());
571 493
572 // Add it again just to be sure that is harmless. 494 // Add it again just to be sure that is harmless.
573 url_index_->UpdateURL(new_row_id, new_row); 495 url_index_->UpdateURL(new_row);
574 EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size()); 496 EXPECT_EQ(1U, url_index_->HistoryItemsForTerms(terms).size());
575 } 497 }
576 498
577 TEST_F(InMemoryURLIndexTest, DeleteRows) { 499 TEST_F(InMemoryURLIndexTest, DeleteRows) {
578 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 500 url_index_.reset(new InMemoryURLIndex(NULL,
501 FilePath(FILE_PATH_LITERAL("/dummy"))));
579 url_index_->Init(this, "en,ja,hi,zh"); 502 url_index_->Init(this, "en,ja,hi,zh");
580 InMemoryURLIndex::String16Vector terms; 503 String16Vector terms;
581 504
582 // Make sure we actually get an existing result. 505 // Make sure we actually get an existing result.
583 terms.push_back(ASCIIToUTF16("DrudgeReport")); 506 terms.push_back(ASCIIToUTF16("DrudgeReport"));
584 ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms); 507 ScoredHistoryMatches matches = url_index_->HistoryItemsForTerms(terms);
585 ASSERT_EQ(1U, matches.size()); 508 ASSERT_EQ(1U, matches.size());
586 509
587 // Determine the row id for that result, delete that id, then search again. 510 // Determine the row id for that result, delete that id, then search again.
588 url_index_->DeleteURL(matches[0].url_info.id()); 511 url_index_->DeleteURL(matches[0].url_info);
589 EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty()); 512 EXPECT_TRUE(url_index_->HistoryItemsForTerms(terms).empty());
590 } 513 }
591 514
592 TEST_F(InMemoryURLIndexTest, WhitelistedURLs) { 515 TEST_F(InMemoryURLIndexTest, WhitelistedURLs) {
593 struct TestData { 516 struct TestData {
594 const std::string url_spec; 517 const std::string url_spec;
595 const bool expected_is_whitelisted; 518 const bool expected_is_whitelisted;
596 } data[] = { 519 } data[] = {
597 // URLs with whitelisted schemes. 520 // URLs with whitelisted schemes.
598 { "about:histograms", true }, 521 { "about:histograms", true },
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 { "telnet://mayor_margie:one2rule4All@www.mycity.com:6789/", false }, 578 { "telnet://mayor_margie:one2rule4All@www.mycity.com:6789/", false },
656 { "tftp://example.com/mystartupfile", false }, 579 { "tftp://example.com/mystartupfile", false },
657 { "tip://123.123.123.123/?urn:xopen:xid", false }, 580 { "tip://123.123.123.123/?urn:xopen:xid", false },
658 { "tv:nbc.com", false }, 581 { "tv:nbc.com", false },
659 { "urn:foo:A123,456", false }, 582 { "urn:foo:A123,456", false },
660 { "vemmi://zeus.mctel.fr/demo", false }, 583 { "vemmi://zeus.mctel.fr/demo", false },
661 { "wais://www.mydomain.net:8765/mydatabase", false }, 584 { "wais://www.mydomain.net:8765/mydatabase", false },
662 { "xmpp:node@example.com", false }, 585 { "xmpp:node@example.com", false },
663 { "xmpp://guest@example.com", false }, 586 { "xmpp://guest@example.com", false },
664 }; 587 };
665 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL( 588 url_index_.reset(new InMemoryURLIndex(NULL,
589 FilePath(FILE_PATH_LITERAL(
666 "/flammmy/frammy/")))); 590 "/flammmy/frammy/"))));
667 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { 591 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
668 GURL url(data[i].url_spec); 592 GURL url(data[i].url_spec);
669 EXPECT_EQ(data[i].expected_is_whitelisted, 593 EXPECT_EQ(data[i].expected_is_whitelisted,
670 url_index_->URLSchemeIsWhitelisted(url)); 594 url_index_->URLSchemeIsWhitelisted(url));
671 } 595 }
672 } 596 }
673 597
674 TEST_F(InMemoryURLIndexTest, CacheFilePath) { 598 TEST_F(InMemoryURLIndexTest, CacheFilePath) {
675 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL( 599 url_index_.reset(new InMemoryURLIndex(
676 "/flammmy/frammy/")))); 600 NULL, FilePath(FILE_PATH_LITERAL("/flammmy/frammy/"))));
677 FilePath full_file_path; 601 FilePath full_file_path;
678 url_index_->GetCacheFilePath(&full_file_path); 602 url_index_->GetCacheFilePath(&full_file_path);
679 std::vector<FilePath::StringType> expected_parts; 603 std::vector<FilePath::StringType> expected_parts;
680 FilePath(FILE_PATH_LITERAL("/flammmy/frammy/History Provider Cache")). 604 FilePath(FILE_PATH_LITERAL("/flammmy/frammy/History Provider Cache")).
681 GetComponents(&expected_parts); 605 GetComponents(&expected_parts);
682 std::vector<FilePath::StringType> actual_parts; 606 std::vector<FilePath::StringType> actual_parts;
683 full_file_path.GetComponents(&actual_parts); 607 full_file_path.GetComponents(&actual_parts);
684 ASSERT_EQ(expected_parts.size(), actual_parts.size()); 608 ASSERT_EQ(expected_parts.size(), actual_parts.size());
685 size_t count = expected_parts.size(); 609 size_t count = expected_parts.size();
686 for (size_t i = 0; i < count; ++i) 610 for (size_t i = 0; i < count; ++i)
687 EXPECT_EQ(expected_parts[i], actual_parts[i]); 611 EXPECT_EQ(expected_parts[i], actual_parts[i]);
688 } 612 }
689 613
690 TEST_F(InMemoryURLIndexTest, CacheSaveRestore) { 614 TEST_F(InMemoryURLIndexTest, CacheSaveRestore) {
691 // Save the cache to a protobuf, restore it, and compare the results. 615 // Save the cache to a protobuf, restore it, and compare the results.
692 url_index_.reset(new InMemoryURLIndex(FilePath(FILE_PATH_LITERAL("/dummy")))); 616 url_index_.reset(new InMemoryURLIndex(NULL,
617 FilePath(FILE_PATH_LITERAL("/dummy"))));
693 InMemoryURLIndex& url_index(*(url_index_.get())); 618 InMemoryURLIndex& url_index(*(url_index_.get()));
694 url_index.Init(this, "en,ja,hi,zh"); 619 url_index.Init(this, "en,ja,hi,zh");
695 in_memory_url_index::InMemoryURLIndexCacheItem index_cache; 620 in_memory_url_index::InMemoryURLIndexCacheItem index_cache;
696 url_index.SavePrivateData(&index_cache); 621 url_index.SavePrivateData(&index_cache);
697 622
698 // Capture our private data so we can later compare for equality. 623 // Capture our private data so we can later compare for equality.
699 int history_item_count(url_index.history_item_count_); 624 URLIndexPrivateData& private_data(*(url_index_->private_data_));
700 InMemoryURLIndex::String16Vector word_list(url_index.word_list_); 625 String16Vector word_list(private_data.word_list_);
701 InMemoryURLIndex::WordMap word_map(url_index.word_map_); 626 WordMap word_map(private_data.word_map_);
702 InMemoryURLIndex::CharWordIDMap char_word_map(url_index.char_word_map_); 627 CharWordIDMap char_word_map(private_data.char_word_map_);
703 InMemoryURLIndex::WordIDHistoryMap word_id_history_map( 628 WordIDHistoryMap word_id_history_map(private_data.word_id_history_map_);
704 url_index.word_id_history_map_); 629 HistoryIDWordMap history_id_word_map(private_data.history_id_word_map_);
705 InMemoryURLIndex::HistoryInfoMap history_info_map( 630 HistoryInfoMap history_info_map(private_data.history_info_map_);
706 url_index.history_info_map_);
707 631
708 // Prove that there is really something there. 632 // Prove that there is really something there.
709 EXPECT_GT(url_index.history_item_count_, 0); 633 EXPECT_FALSE(private_data.word_list_.empty());
710 EXPECT_FALSE(url_index.word_list_.empty()); 634 // available_words_ will already be empty since we have freshly built the
711 EXPECT_FALSE(url_index.word_map_.empty()); 635 // data set for this test.
712 EXPECT_FALSE(url_index.char_word_map_.empty()); 636 EXPECT_TRUE(private_data.available_words_.empty());
713 EXPECT_FALSE(url_index.word_id_history_map_.empty()); 637 EXPECT_FALSE(private_data.word_map_.empty());
714 EXPECT_FALSE(url_index.history_info_map_.empty()); 638 EXPECT_FALSE(private_data.char_word_map_.empty());
639 EXPECT_FALSE(private_data.word_id_history_map_.empty());
640 EXPECT_FALSE(private_data.history_id_word_map_.empty());
641 EXPECT_FALSE(private_data.history_info_map_.empty());
715 642
716 // Clear and then prove it's clear. 643 // Clear and then prove it's clear.
717 url_index.ClearPrivateData(); 644 url_index.ClearPrivateData();
718 EXPECT_EQ(0, url_index.history_item_count_); 645 EXPECT_TRUE(private_data.word_list_.empty());
719 EXPECT_TRUE(url_index.word_list_.empty()); 646 EXPECT_TRUE(private_data.available_words_.empty());
720 EXPECT_TRUE(url_index.word_map_.empty()); 647 EXPECT_TRUE(private_data.word_map_.empty());
721 EXPECT_TRUE(url_index.char_word_map_.empty()); 648 EXPECT_TRUE(private_data.char_word_map_.empty());
722 EXPECT_TRUE(url_index.word_id_history_map_.empty()); 649 EXPECT_TRUE(private_data.word_id_history_map_.empty());
723 EXPECT_TRUE(url_index.history_info_map_.empty()); 650 EXPECT_TRUE(private_data.history_id_word_map_.empty());
651 EXPECT_TRUE(private_data.history_info_map_.empty());
724 652
725 // Restore the cache. 653 // Restore the cache.
726 EXPECT_TRUE(url_index.RestorePrivateData(index_cache)); 654 EXPECT_TRUE(url_index.RestorePrivateData(index_cache));
727 655
728 // Compare the restored and captured for equality. 656 // Compare the restored and captured for equality.
729 EXPECT_EQ(history_item_count, url_index.history_item_count_); 657 EXPECT_EQ(word_list.size(), private_data.word_list_.size());
730 EXPECT_EQ(word_list.size(), url_index.word_list_.size()); 658 EXPECT_EQ(word_map.size(), private_data.word_map_.size());
731 EXPECT_EQ(word_map.size(), url_index.word_map_.size()); 659 EXPECT_EQ(char_word_map.size(), private_data.char_word_map_.size());
732 EXPECT_EQ(char_word_map.size(), url_index.char_word_map_.size()); 660 EXPECT_EQ(word_id_history_map.size(),
733 EXPECT_EQ(word_id_history_map.size(), url_index.word_id_history_map_.size()); 661 private_data.word_id_history_map_.size());
734 EXPECT_EQ(history_info_map.size(), url_index.history_info_map_.size()); 662 EXPECT_EQ(history_id_word_map.size(),
663 private_data.history_id_word_map_.size());
664 EXPECT_EQ(history_info_map.size(), private_data.history_info_map_.size());
735 // WordList must be index-by-index equal. 665 // WordList must be index-by-index equal.
736 size_t count = word_list.size(); 666 size_t count = word_list.size();
737 for (size_t i = 0; i < count; ++i) 667 for (size_t i = 0; i < count; ++i)
738 EXPECT_EQ(word_list[i], url_index.word_list_[i]); 668 EXPECT_EQ(word_list[i], private_data.word_list_[i]);
739 for (InMemoryURLIndex::CharWordIDMap::const_iterator expected = 669
740 char_word_map.begin(); expected != char_word_map.end(); ++expected) { 670 ExpectMapOfContainersIdentical(char_word_map,
741 InMemoryURLIndex::CharWordIDMap::const_iterator actual = 671 private_data.char_word_map_);
742 url_index.char_word_map_.find(expected->first); 672 ExpectMapOfContainersIdentical(word_id_history_map,
743 ASSERT_TRUE(url_index.char_word_map_.end() != actual); 673 private_data.word_id_history_map_);
744 const InMemoryURLIndex::WordIDSet& expected_set(expected->second); 674 ExpectMapOfContainersIdentical(history_id_word_map,
745 const InMemoryURLIndex::WordIDSet& actual_set(actual->second); 675 private_data.history_id_word_map_);
746 ASSERT_EQ(expected_set.size(), actual_set.size()); 676
747 for (InMemoryURLIndex::WordIDSet::const_iterator set_iter = 677 for (HistoryInfoMap::const_iterator expected = history_info_map.begin();
748 expected_set.begin(); set_iter != expected_set.end(); ++set_iter) 678 expected != history_info_map.end(); ++expected) {
749 EXPECT_GT(actual_set.count(*set_iter), 0U); 679 HistoryInfoMap::const_iterator actual =
750 } 680 private_data.history_info_map_.find(expected->first);
751 for (InMemoryURLIndex::WordIDHistoryMap::const_iterator expected = 681 ASSERT_FALSE(private_data.history_info_map_.end() == actual);
752 word_id_history_map.begin(); expected != word_id_history_map.end();
753 ++expected) {
754 InMemoryURLIndex::WordIDHistoryMap::const_iterator actual =
755 url_index.word_id_history_map_.find(expected->first);
756 ASSERT_TRUE(url_index.word_id_history_map_.end() != actual);
757 const InMemoryURLIndex::HistoryIDSet& expected_set(expected->second);
758 const InMemoryURLIndex::HistoryIDSet& actual_set(actual->second);
759 ASSERT_EQ(expected_set.size(), actual_set.size());
760 for (InMemoryURLIndex::HistoryIDSet::const_iterator set_iter =
761 expected_set.begin(); set_iter != expected_set.end(); ++set_iter)
762 EXPECT_GT(actual_set.count(*set_iter), 0U);
763 }
764 for (InMemoryURLIndex::HistoryInfoMap::const_iterator expected =
765 history_info_map.begin(); expected != history_info_map.end();
766 ++expected) {
767 InMemoryURLIndex::HistoryInfoMap::const_iterator actual =
768 url_index.history_info_map_.find(expected->first);
769 ASSERT_FALSE(url_index.history_info_map_.end() == actual);
770 const URLRow& expected_row(expected->second); 682 const URLRow& expected_row(expected->second);
771 const URLRow& actual_row(actual->second); 683 const URLRow& actual_row(actual->second);
772 EXPECT_EQ(expected_row.visit_count(), actual_row.visit_count()); 684 EXPECT_EQ(expected_row.visit_count(), actual_row.visit_count());
773 EXPECT_EQ(expected_row.typed_count(), actual_row.typed_count()); 685 EXPECT_EQ(expected_row.typed_count(), actual_row.typed_count());
774 EXPECT_EQ(expected_row.last_visit(), actual_row.last_visit()); 686 EXPECT_EQ(expected_row.last_visit(), actual_row.last_visit());
775 EXPECT_EQ(expected_row.url(), actual_row.url()); 687 EXPECT_EQ(expected_row.url(), actual_row.url());
776 } 688 }
777 } 689 }
778 690
779 } // namespace history 691 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698