1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian 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 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/text_database.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace history { 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that all pages have "COUNTTAG" which allows us to count the number of 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pages in the database withoujt adding any extra functions to the DB object. 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kURL1[] = "http://www.google.com/"; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTime1 = 1000; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTitle1[] = "Google"; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kBody1[] = 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG Web Images Maps News Shopping Gmail more My Account | " 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Sign out Advanced Search Preferences Language Tools Advertising Programs " 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "- Business Solutions - About Google, 2008 Google"; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kURL2[] = "http://images.google.com/"; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTime2 = 2000; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTitle2[] = "Google Image Search"; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kBody2[] = 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG Web Images Maps News Shopping Gmail more My Account | " 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Sign out Advanced Image Search Preferences The most comprehensive image " 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "search on the web. Want to help improve Google Image Search? Try Google " 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Image Labeler. Advertising Programs - Business Solutions - About Google " 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "2008 Google"; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kURL3[] = "http://slashdot.org/"; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTime3 = 3000; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTitle3[] = "Slashdot: News for nerds, stuff that matters"; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kBody3[] = 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG Slashdot Log In Create Account Subscribe Firehose Why " 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Log In? Why Subscribe? Nickname Password Public Terminal Sections " 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Main Apple AskSlashdot Backslash Books Developers Games Hardware " 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Interviews IT Linux Mobile Politics Science YRO"; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the number of rows currently in the database. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint RowCount(TextDatabase* db) { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryOptions options; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue(0); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Leave end_time at now. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<TextDatabase::Match> results; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time first_time_searched; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TextDatabase::URLSet unique_urls; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("COUNTTAG", options, &results, &unique_urls, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<int>(results.size()); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Adds each of the test pages to the database. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AddAllTestData(TextDatabase* db) { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db->AddPageData( 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime1), kURL1, kTitle1, kBody1)); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db->AddPageData( 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime2), kURL2, kTitle2, kBody2)); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db->AddPageData( 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime3), kURL3, kTitle3, kBody3)); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, RowCount(db)); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ResultsHaveURL(const std::vector<TextDatabase::Match>& results, 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* url) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL gurl(url); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < results.size(); i++) { 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (results[i].url == gurl) 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TextDatabaseTest : public PlatformTest { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TextDatabaseTest() {} 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void SetUp() { 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PlatformTest::SetUp(); 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create databases with this function, which will ensure that the files are 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // deleted on shutdown. Only open one database for each file. Returns NULL on 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // failure. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set |delete_file| to delete any existing file. If we are trying to create 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the file for the first time, we don't want a previous test left in a 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // weird state to have left a file that would affect us. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TextDatabase* CreateDB(TextDatabase::DBIdent id, 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool allow_create, 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool delete_file) { 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TextDatabase* db = new TextDatabase(temp_dir_.path(), id, allow_create); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delete_file) 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(db->file_name(), false); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!db->Init()) { 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete db; 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return db; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Directory containing the databases. 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ScopedTempDir temp_dir_; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Name of the main database file. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath file_name_; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TextDatabaseTest, AttachDetach) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First database with one page. 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee1 = 200801; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db1(CreateDB(kIdee1, true, true)); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db1.get()); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db1->AddPageData( 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime1), kURL1, kTitle1, kBody1)); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Second database with one page. 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee2 = 200802; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db2(CreateDB(kIdee2, true, true)); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db2.get()); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db2->AddPageData( 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime2), kURL2, kTitle2, kBody2)); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Detach, then reattach database one. The file should exist, so we force 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // opening an existing file. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db1.reset(); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db1.reset(CreateDB(kIdee1, false, false)); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db1.get()); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We should not be able to attach this random database for which no file 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // exists. 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdeeNoExisto = 999999999; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db3(CreateDB(kIdeeNoExisto, false, true)); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(!!db3.get()); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TextDatabaseTest, AddRemove) { 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a database and add some pages to it. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee1 = 200801; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db(CreateDB(kIdee1, true, true)); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db.get()); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLID id1 = db->AddPageData( 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime1), kURL1, kTitle1, kBody1); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_NE(0, id1); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLID id2 = db->AddPageData( 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime2), kURL2, kTitle2, kBody2); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_NE(0, id2); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLID id3 = db->AddPageData( 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time::FromInternalValue(kTime3), kURL3, kTitle3, kBody3); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_NE(0, id3); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(3, RowCount(db.get())); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we can delete some of the data. 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->DeletePageData(Time::FromInternalValue(kTime1), kURL1); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2, RowCount(db.get())); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Close and reopen. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen db.reset(new TextDatabase(temp_dir_.path(), kIdee1, false)); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(db->Init()); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify that the deleted ID is gone and try to delete another one. 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2, RowCount(db.get())); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->DeletePageData(Time::FromInternalValue(kTime2), kURL2); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1, RowCount(db.get())); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TextDatabaseTest, Query) { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a database with some pages. 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee1 = 200801; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db(CreateDB(kIdee1, true, true)); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(!!db.get()); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddAllTestData(db.get()); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get all the results. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryOptions options; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue(0); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<TextDatabase::Match> results; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time first_time_searched; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TextDatabase::URLSet unique_urls; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("COUNTTAG", options, &results, &unique_urls, 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(unique_urls.empty()) << "Didn't ask for unique URLs"; 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All 3 sites should be returned in order. 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(3U, results.size()); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(kURL1), results[2].url); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(kURL2), results[1].url); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(GURL(kURL3), results[0].url); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the info on those results. 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(Time::FromInternalValue(kTime1) == results[2].time); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(Time::FromInternalValue(kTime2) == results[1].time); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(Time::FromInternalValue(kTime3) == results[0].time); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(kTitle1), UTF16ToUTF8(results[2].title)); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(kTitle2), UTF16ToUTF8(results[1].title)); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(std::string(kTitle3), UTF16ToUTF8(results[0].title)); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Should have no matches in the title. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0U, results[0].title_match_positions.size()); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0U, results[1].title_match_positions.size()); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0U, results[2].title_match_positions.size()); 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't want to be dependent on the exact snippet algorithm, but we know 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // since we searched for "COUNTTAG" which occurs at the beginning of each 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // document, that each snippet should start with that. 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(StartsWithASCII(UTF16ToUTF8(results[0].snippet.text()), 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG", false)); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(StartsWithASCII(UTF16ToUTF8(results[1].snippet.text()), 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG", false)); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(StartsWithASCII(UTF16ToUTF8(results[2].snippet.text()), 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "COUNTTAG", false)); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TextDatabaseTest, TimeRange) { 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a database with some pages. 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee1 = 200801; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db(CreateDB(kIdee1, true, true)); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db.get()); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddAllTestData(db.get()); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Beginning should be inclusive, and the ending exclusive. 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get all the results. 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryOptions options; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue(kTime1); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = Time::FromInternalValue(kTime3); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<TextDatabase::Match> results; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time first_time_searched; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TextDatabase::URLSet unique_urls; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("COUNTTAG", options, &results, &unique_urls, 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(unique_urls.empty()) << "Didn't ask for unique URLs"; 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The first and second should have been returned. 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, results.size()); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(ResultsHaveURL(results, kURL1)); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(ResultsHaveURL(results, kURL2)); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(ResultsHaveURL(results, kURL3)); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kTime1, first_time_searched.ToInternalValue()); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // --------------------------------------------------------------------------- 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do a query where there isn't a result on the begin boundary, so we can 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // test that the first time searched is set to the minimum time considered 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // instead of the min value. 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue((kTime2 - kTime1) / 2 + kTime1); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = Time::FromInternalValue(kTime3 + 1); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch results.clear(); // GetTextMatches does *not* clear the results. 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("COUNTTAG", options, &results, &unique_urls, 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(unique_urls.empty()) << "Didn't ask for unique URLs"; 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(options.begin_time.ToInternalValue(), 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch first_time_searched.ToInternalValue()); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Should have two results, the second and third. 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(2U, results.size()); 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(ResultsHaveURL(results, kURL1)); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(ResultsHaveURL(results, kURL2)); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(ResultsHaveURL(results, kURL3)); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No results should also set the first_time_searched. 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue(kTime3 + 1); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = Time::FromInternalValue(kTime3 * 100); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch results.clear(); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("COUNTTAG", options, &results, &unique_urls, 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(options.begin_time.ToInternalValue(), 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch first_time_searched.ToInternalValue()); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure that max_count works. 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TextDatabaseTest, MaxCount) { 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a database with some pages. 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kIdee1 = 200801; 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TextDatabase> db(CreateDB(kIdee1, true, true)); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(!!db.get()); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddAllTestData(db.get()); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up the query to return all the results with "Google" (should be 2), but 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with a maximum of 1. 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch QueryOptions options; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = Time::FromInternalValue(kTime1); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = Time::FromInternalValue(kTime3 + 1); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.max_count = 1; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<TextDatabase::Match> results; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time first_time_searched; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TextDatabase::URLSet unique_urls; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch db->GetTextMatches("google", options, &results, &unique_urls, 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &first_time_searched); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(unique_urls.empty()) << "Didn't ask for unique URLs"; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // There should be one result, the most recent one. 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1U, results.size()); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(ResultsHaveURL(results, kURL2)); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The max time considered should be the date of the returned item. 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(kTime2, first_time_searched.ToInternalValue()); 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace history 321