1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/message_loop/message_loop.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "base/time/time.h" 10 #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" 11 #include "chrome/browser/predictors/predictor_database.h" 12 #include "chrome/browser/predictors/predictor_database_factory.h" 13 #include "chrome/test/base/testing_profile.h" 14 #include "content/public/test/test_browser_thread.h" 15 #include "sql/statement.h" 16 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 using base::Time; 20 using base::TimeDelta; 21 using content::BrowserThread; 22 using predictors::AutocompleteActionPredictorTable; 23 24 namespace predictors { 25 26 class AutocompleteActionPredictorTableTest : public testing::Test { 27 public: 28 AutocompleteActionPredictorTableTest(); 29 virtual ~AutocompleteActionPredictorTableTest(); 30 31 virtual void SetUp(); 32 virtual void TearDown(); 33 34 size_t CountRecords() const; 35 36 void AddAll(); 37 38 bool RowsAreEqual(const AutocompleteActionPredictorTable::Row& lhs, 39 const AutocompleteActionPredictorTable::Row& rhs) const; 40 41 TestingProfile* profile() { return &profile_; } 42 43 protected: 44 45 // Test functions that can be run against this text fixture or 46 // AutocompleteActionPredictorTableReopenTest that inherits from this. 47 void TestGetRow(); 48 void TestAddAndUpdateRows(); 49 void TestDeleteRows(); 50 void TestDeleteAllRows(); 51 52 AutocompleteActionPredictorTable::Rows test_db_; 53 54 private: 55 TestingProfile profile_; 56 scoped_ptr<PredictorDatabase> db_; 57 base::MessageLoop loop_; 58 content::TestBrowserThread db_thread_; 59 }; 60 61 class AutocompleteActionPredictorTableReopenTest 62 : public AutocompleteActionPredictorTableTest { 63 public: 64 virtual void SetUp() { 65 // By calling SetUp twice, we make sure that the table already exists for 66 // this fixture. 67 AutocompleteActionPredictorTableTest::SetUp(); 68 AutocompleteActionPredictorTableTest::TearDown(); 69 AutocompleteActionPredictorTableTest::SetUp(); 70 } 71 }; 72 73 AutocompleteActionPredictorTableTest::AutocompleteActionPredictorTableTest() 74 : loop_(base::MessageLoop::TYPE_DEFAULT), 75 db_thread_(BrowserThread::DB, &loop_) { 76 } 77 78 AutocompleteActionPredictorTableTest::~AutocompleteActionPredictorTableTest() { 79 } 80 81 void AutocompleteActionPredictorTableTest::SetUp() { 82 db_.reset(new PredictorDatabase(&profile_)); 83 loop_.RunUntilIdle(); 84 85 test_db_.push_back(AutocompleteActionPredictorTable::Row( 86 "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", 87 ASCIIToUTF16("goog"), GURL("http://www.google.com/"), 88 1, 0)); 89 test_db_.push_back(AutocompleteActionPredictorTable::Row( 90 "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", 91 ASCIIToUTF16("slash"), GURL("http://slashdot.org/"), 92 3, 2)); 93 test_db_.push_back(AutocompleteActionPredictorTable::Row( 94 "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", 95 ASCIIToUTF16("news"), GURL("http://slashdot.org/"), 96 0, 1)); 97 } 98 99 void AutocompleteActionPredictorTableTest::TearDown() { 100 db_.reset(NULL); 101 loop_.RunUntilIdle(); 102 test_db_.clear(); 103 } 104 105 size_t AutocompleteActionPredictorTableTest::CountRecords() const { 106 sql::Statement s(db_->GetDatabase()->GetUniqueStatement( 107 "SELECT count(*) FROM network_action_predictor")); 108 EXPECT_TRUE(s.Step()); 109 return static_cast<size_t>(s.ColumnInt(0)); 110 } 111 112 void AutocompleteActionPredictorTableTest::AddAll() { 113 db_->autocomplete_table()->AddAndUpdateRows( 114 test_db_, AutocompleteActionPredictorTable::Rows()); 115 116 EXPECT_EQ(test_db_.size(), CountRecords()); 117 } 118 119 bool AutocompleteActionPredictorTableTest::RowsAreEqual( 120 const AutocompleteActionPredictorTable::Row& lhs, 121 const AutocompleteActionPredictorTable::Row& rhs) const { 122 return (lhs.id == rhs.id && 123 lhs.user_text == rhs.user_text && 124 lhs.url == rhs.url && 125 lhs.number_of_hits == rhs.number_of_hits && 126 lhs.number_of_misses == rhs.number_of_misses); 127 } 128 129 void AutocompleteActionPredictorTableTest::TestGetRow() { 130 db_->autocomplete_table()->AddAndUpdateRows( 131 AutocompleteActionPredictorTable::Rows(1, test_db_[0]), 132 AutocompleteActionPredictorTable::Rows()); 133 AutocompleteActionPredictorTable::Row row; 134 db_->autocomplete_table()->GetRow(test_db_[0].id, &row); 135 EXPECT_TRUE(RowsAreEqual(test_db_[0], row)) 136 << "Expected: Row with id " << test_db_[0].id << "\n" 137 << "Got: Row with id " << row.id; 138 } 139 140 void AutocompleteActionPredictorTableTest::TestAddAndUpdateRows() { 141 EXPECT_EQ(0U, CountRecords()); 142 143 AutocompleteActionPredictorTable::Rows rows_to_add; 144 rows_to_add.push_back(test_db_[0]); 145 rows_to_add.push_back(test_db_[1]); 146 db_->autocomplete_table()->AddAndUpdateRows( 147 rows_to_add, 148 AutocompleteActionPredictorTable::Rows()); 149 EXPECT_EQ(2U, CountRecords()); 150 151 AutocompleteActionPredictorTable::Row row1 = test_db_[1]; 152 row1.number_of_hits = row1.number_of_hits + 1; 153 db_->autocomplete_table()->AddAndUpdateRows( 154 AutocompleteActionPredictorTable::Rows(1, test_db_[2]), 155 AutocompleteActionPredictorTable::Rows(1, row1)); 156 EXPECT_EQ(3U, CountRecords()); 157 158 AutocompleteActionPredictorTable::Row updated_row1; 159 db_->autocomplete_table()->GetRow(test_db_[1].id, &updated_row1); 160 EXPECT_TRUE(RowsAreEqual(row1, updated_row1)) 161 << "Expected: Row with id " << row1.id << "\n" 162 << "Got: Row with id " << updated_row1.id; 163 164 AutocompleteActionPredictorTable::Row row0 = test_db_[0]; 165 row0.number_of_hits = row0.number_of_hits + 2; 166 AutocompleteActionPredictorTable::Row row2 = test_db_[2]; 167 row2.number_of_hits = row2.number_of_hits + 2; 168 AutocompleteActionPredictorTable::Rows rows_to_update; 169 rows_to_update.push_back(row0); 170 rows_to_update.push_back(row2); 171 db_->autocomplete_table()->AddAndUpdateRows( 172 AutocompleteActionPredictorTable::Rows(), 173 rows_to_update); 174 EXPECT_EQ(3U, CountRecords()); 175 176 AutocompleteActionPredictorTable::Row updated_row0, updated_row2; 177 db_->autocomplete_table()->GetRow(test_db_[0].id, &updated_row0); 178 db_->autocomplete_table()->GetRow(test_db_[2].id, &updated_row2); 179 EXPECT_TRUE(RowsAreEqual(row0, updated_row0)) 180 << "Expected: Row with id " << row0.id << "\n" 181 << "Got: Row with id " << updated_row0.id; 182 EXPECT_TRUE(RowsAreEqual(row2, updated_row2)) 183 << "Expected: Row with id " << row2.id << "\n" 184 << "Got: Row with id " << updated_row2.id; 185 } 186 187 void AutocompleteActionPredictorTableTest::TestDeleteRows() { 188 AddAll(); 189 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; 190 id_list.push_back(test_db_[0].id); 191 id_list.push_back(test_db_[2].id); 192 db_->autocomplete_table()->DeleteRows(id_list); 193 EXPECT_EQ(test_db_.size() - 2, CountRecords()); 194 195 AutocompleteActionPredictorTable::Row row; 196 db_->autocomplete_table()->GetRow(test_db_[1].id, &row); 197 EXPECT_TRUE(RowsAreEqual(test_db_[1], row)); 198 } 199 200 void AutocompleteActionPredictorTableTest::TestDeleteAllRows() { 201 AddAll(); 202 db_->autocomplete_table()->DeleteAllRows(); 203 EXPECT_EQ(0U, CountRecords()); 204 } 205 206 // AutocompleteActionPredictorTableTest tests 207 TEST_F(AutocompleteActionPredictorTableTest, GetRow) { 208 TestGetRow(); 209 } 210 211 TEST_F(AutocompleteActionPredictorTableTest, AddAndUpdateRows) { 212 TestAddAndUpdateRows(); 213 } 214 215 TEST_F(AutocompleteActionPredictorTableTest, DeleteRows) { 216 TestDeleteRows(); 217 } 218 219 TEST_F(AutocompleteActionPredictorTableTest, DeleteAllRows) { 220 TestDeleteAllRows(); 221 } 222 223 // AutocompleteActionPredictorTableReopenTest tests 224 TEST_F(AutocompleteActionPredictorTableReopenTest, GetRow) { 225 TestGetRow(); 226 } 227 228 TEST_F(AutocompleteActionPredictorTableReopenTest, AddAndUpdateRows) { 229 TestAddAndUpdateRows(); 230 } 231 232 TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteRows) { 233 TestDeleteRows(); 234 } 235 236 TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteAllRows) { 237 TestDeleteAllRows(); 238 } 239 240 } // namespace predictors 241