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 : db_thread_(BrowserThread::DB, &loop_) { 75 } 76 77 AutocompleteActionPredictorTableTest::~AutocompleteActionPredictorTableTest() { 78 } 79 80 void AutocompleteActionPredictorTableTest::SetUp() { 81 db_.reset(new PredictorDatabase(&profile_)); 82 loop_.RunUntilIdle(); 83 84 test_db_.push_back(AutocompleteActionPredictorTable::Row( 85 "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", 86 base::ASCIIToUTF16("goog"), GURL("http://www.google.com/"), 87 1, 0)); 88 test_db_.push_back(AutocompleteActionPredictorTable::Row( 89 "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", 90 base::ASCIIToUTF16("slash"), GURL("http://slashdot.org/"), 91 3, 2)); 92 test_db_.push_back(AutocompleteActionPredictorTable::Row( 93 "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", 94 base::ASCIIToUTF16("news"), GURL("http://slashdot.org/"), 95 0, 1)); 96 } 97 98 void AutocompleteActionPredictorTableTest::TearDown() { 99 db_.reset(NULL); 100 loop_.RunUntilIdle(); 101 test_db_.clear(); 102 } 103 104 size_t AutocompleteActionPredictorTableTest::CountRecords() const { 105 sql::Statement s(db_->GetDatabase()->GetUniqueStatement( 106 "SELECT count(*) FROM network_action_predictor")); 107 EXPECT_TRUE(s.Step()); 108 return static_cast<size_t>(s.ColumnInt(0)); 109 } 110 111 void AutocompleteActionPredictorTableTest::AddAll() { 112 db_->autocomplete_table()->AddAndUpdateRows( 113 test_db_, AutocompleteActionPredictorTable::Rows()); 114 115 EXPECT_EQ(test_db_.size(), CountRecords()); 116 } 117 118 bool AutocompleteActionPredictorTableTest::RowsAreEqual( 119 const AutocompleteActionPredictorTable::Row& lhs, 120 const AutocompleteActionPredictorTable::Row& rhs) const { 121 return (lhs.id == rhs.id && 122 lhs.user_text == rhs.user_text && 123 lhs.url == rhs.url && 124 lhs.number_of_hits == rhs.number_of_hits && 125 lhs.number_of_misses == rhs.number_of_misses); 126 } 127 128 void AutocompleteActionPredictorTableTest::TestGetRow() { 129 db_->autocomplete_table()->AddAndUpdateRows( 130 AutocompleteActionPredictorTable::Rows(1, test_db_[0]), 131 AutocompleteActionPredictorTable::Rows()); 132 AutocompleteActionPredictorTable::Row row; 133 db_->autocomplete_table()->GetRow(test_db_[0].id, &row); 134 EXPECT_TRUE(RowsAreEqual(test_db_[0], row)) 135 << "Expected: Row with id " << test_db_[0].id << "\n" 136 << "Got: Row with id " << row.id; 137 } 138 139 void AutocompleteActionPredictorTableTest::TestAddAndUpdateRows() { 140 EXPECT_EQ(0U, CountRecords()); 141 142 AutocompleteActionPredictorTable::Rows rows_to_add; 143 rows_to_add.push_back(test_db_[0]); 144 rows_to_add.push_back(test_db_[1]); 145 db_->autocomplete_table()->AddAndUpdateRows( 146 rows_to_add, 147 AutocompleteActionPredictorTable::Rows()); 148 EXPECT_EQ(2U, CountRecords()); 149 150 AutocompleteActionPredictorTable::Row row1 = test_db_[1]; 151 row1.number_of_hits = row1.number_of_hits + 1; 152 db_->autocomplete_table()->AddAndUpdateRows( 153 AutocompleteActionPredictorTable::Rows(1, test_db_[2]), 154 AutocompleteActionPredictorTable::Rows(1, row1)); 155 EXPECT_EQ(3U, CountRecords()); 156 157 AutocompleteActionPredictorTable::Row updated_row1; 158 db_->autocomplete_table()->GetRow(test_db_[1].id, &updated_row1); 159 EXPECT_TRUE(RowsAreEqual(row1, updated_row1)) 160 << "Expected: Row with id " << row1.id << "\n" 161 << "Got: Row with id " << updated_row1.id; 162 163 AutocompleteActionPredictorTable::Row row0 = test_db_[0]; 164 row0.number_of_hits = row0.number_of_hits + 2; 165 AutocompleteActionPredictorTable::Row row2 = test_db_[2]; 166 row2.number_of_hits = row2.number_of_hits + 2; 167 AutocompleteActionPredictorTable::Rows rows_to_update; 168 rows_to_update.push_back(row0); 169 rows_to_update.push_back(row2); 170 db_->autocomplete_table()->AddAndUpdateRows( 171 AutocompleteActionPredictorTable::Rows(), 172 rows_to_update); 173 EXPECT_EQ(3U, CountRecords()); 174 175 AutocompleteActionPredictorTable::Row updated_row0, updated_row2; 176 db_->autocomplete_table()->GetRow(test_db_[0].id, &updated_row0); 177 db_->autocomplete_table()->GetRow(test_db_[2].id, &updated_row2); 178 EXPECT_TRUE(RowsAreEqual(row0, updated_row0)) 179 << "Expected: Row with id " << row0.id << "\n" 180 << "Got: Row with id " << updated_row0.id; 181 EXPECT_TRUE(RowsAreEqual(row2, updated_row2)) 182 << "Expected: Row with id " << row2.id << "\n" 183 << "Got: Row with id " << updated_row2.id; 184 } 185 186 void AutocompleteActionPredictorTableTest::TestDeleteRows() { 187 AddAll(); 188 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; 189 id_list.push_back(test_db_[0].id); 190 id_list.push_back(test_db_[2].id); 191 db_->autocomplete_table()->DeleteRows(id_list); 192 EXPECT_EQ(test_db_.size() - 2, CountRecords()); 193 194 AutocompleteActionPredictorTable::Row row; 195 db_->autocomplete_table()->GetRow(test_db_[1].id, &row); 196 EXPECT_TRUE(RowsAreEqual(test_db_[1], row)); 197 } 198 199 void AutocompleteActionPredictorTableTest::TestDeleteAllRows() { 200 AddAll(); 201 db_->autocomplete_table()->DeleteAllRows(); 202 EXPECT_EQ(0U, CountRecords()); 203 } 204 205 // AutocompleteActionPredictorTableTest tests 206 TEST_F(AutocompleteActionPredictorTableTest, GetRow) { 207 TestGetRow(); 208 } 209 210 TEST_F(AutocompleteActionPredictorTableTest, AddAndUpdateRows) { 211 TestAddAndUpdateRows(); 212 } 213 214 TEST_F(AutocompleteActionPredictorTableTest, DeleteRows) { 215 TestDeleteRows(); 216 } 217 218 TEST_F(AutocompleteActionPredictorTableTest, DeleteAllRows) { 219 TestDeleteAllRows(); 220 } 221 222 // AutocompleteActionPredictorTableReopenTest tests 223 TEST_F(AutocompleteActionPredictorTableReopenTest, GetRow) { 224 TestGetRow(); 225 } 226 227 TEST_F(AutocompleteActionPredictorTableReopenTest, AddAndUpdateRows) { 228 TestAddAndUpdateRows(); 229 } 230 231 TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteRows) { 232 TestDeleteRows(); 233 } 234 235 TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteAllRows) { 236 TestDeleteAllRows(); 237 } 238 239 } // namespace predictors 240