// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "base/message_loop.h" #include "base/time.h" #include "base/utf_string_conversions.h" #include "chrome/browser/predictors/autocomplete_action_predictor_table.h" #include "chrome/browser/predictors/predictor_database.h" #include "chrome/browser/predictors/predictor_database_factory.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; using base::TimeDelta; using content::BrowserThread; using predictors::AutocompleteActionPredictorTable; namespace predictors { class AutocompleteActionPredictorTableTest : public testing::Test { public: AutocompleteActionPredictorTableTest(); virtual ~AutocompleteActionPredictorTableTest(); virtual void SetUp(); virtual void TearDown(); size_t CountRecords() const; void AddAll(); bool RowsAreEqual(const AutocompleteActionPredictorTable::Row& lhs, const AutocompleteActionPredictorTable::Row& rhs) const; TestingProfile* profile() { return &profile_; } protected: // Test functions that can be run against this text fixture or // AutocompleteActionPredictorTableReopenTest that inherits from this. void TestGetRow(); void TestAddAndUpdateRows(); void TestDeleteRows(); void TestDeleteAllRows(); AutocompleteActionPredictorTable::Rows test_db_; private: TestingProfile profile_; scoped_ptr db_; MessageLoop loop_; content::TestBrowserThread db_thread_; }; class AutocompleteActionPredictorTableReopenTest : public AutocompleteActionPredictorTableTest { public: virtual void SetUp() { // By calling SetUp twice, we make sure that the table already exists for // this fixture. AutocompleteActionPredictorTableTest::SetUp(); AutocompleteActionPredictorTableTest::TearDown(); AutocompleteActionPredictorTableTest::SetUp(); } }; AutocompleteActionPredictorTableTest::AutocompleteActionPredictorTableTest() : loop_(MessageLoop::TYPE_DEFAULT), db_thread_(BrowserThread::DB, &loop_) { } AutocompleteActionPredictorTableTest::~AutocompleteActionPredictorTableTest() { } void AutocompleteActionPredictorTableTest::SetUp() { db_.reset(new PredictorDatabase(&profile_)); loop_.RunUntilIdle(); test_db_.push_back(AutocompleteActionPredictorTable::Row( "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", ASCIIToUTF16("goog"), GURL("http://www.google.com/"), 1, 0)); test_db_.push_back(AutocompleteActionPredictorTable::Row( "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", ASCIIToUTF16("slash"), GURL("http://slashdot.org/"), 3, 2)); test_db_.push_back(AutocompleteActionPredictorTable::Row( "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", ASCIIToUTF16("news"), GURL("http://slashdot.org/"), 0, 1)); } void AutocompleteActionPredictorTableTest::TearDown() { db_.reset(NULL); loop_.RunUntilIdle(); test_db_.clear(); } size_t AutocompleteActionPredictorTableTest::CountRecords() const { sql::Statement s(db_->GetDatabase()->GetUniqueStatement( "SELECT count(*) FROM network_action_predictor")); EXPECT_TRUE(s.Step()); return static_cast(s.ColumnInt(0)); } void AutocompleteActionPredictorTableTest::AddAll() { db_->autocomplete_table()->AddAndUpdateRows( test_db_, AutocompleteActionPredictorTable::Rows()); EXPECT_EQ(test_db_.size(), CountRecords()); } bool AutocompleteActionPredictorTableTest::RowsAreEqual( const AutocompleteActionPredictorTable::Row& lhs, const AutocompleteActionPredictorTable::Row& rhs) const { return (lhs.id == rhs.id && lhs.user_text == rhs.user_text && lhs.url == rhs.url && lhs.number_of_hits == rhs.number_of_hits && lhs.number_of_misses == rhs.number_of_misses); } void AutocompleteActionPredictorTableTest::TestGetRow() { db_->autocomplete_table()->AddAndUpdateRows( AutocompleteActionPredictorTable::Rows(1, test_db_[0]), AutocompleteActionPredictorTable::Rows()); AutocompleteActionPredictorTable::Row row; db_->autocomplete_table()->GetRow(test_db_[0].id, &row); EXPECT_TRUE(RowsAreEqual(test_db_[0], row)) << "Expected: Row with id " << test_db_[0].id << "\n" << "Got: Row with id " << row.id; } void AutocompleteActionPredictorTableTest::TestAddAndUpdateRows() { EXPECT_EQ(0U, CountRecords()); AutocompleteActionPredictorTable::Rows rows_to_add; rows_to_add.push_back(test_db_[0]); rows_to_add.push_back(test_db_[1]); db_->autocomplete_table()->AddAndUpdateRows( rows_to_add, AutocompleteActionPredictorTable::Rows()); EXPECT_EQ(2U, CountRecords()); AutocompleteActionPredictorTable::Row row1 = test_db_[1]; row1.number_of_hits = row1.number_of_hits + 1; db_->autocomplete_table()->AddAndUpdateRows( AutocompleteActionPredictorTable::Rows(1, test_db_[2]), AutocompleteActionPredictorTable::Rows(1, row1)); EXPECT_EQ(3U, CountRecords()); AutocompleteActionPredictorTable::Row updated_row1; db_->autocomplete_table()->GetRow(test_db_[1].id, &updated_row1); EXPECT_TRUE(RowsAreEqual(row1, updated_row1)) << "Expected: Row with id " << row1.id << "\n" << "Got: Row with id " << updated_row1.id; AutocompleteActionPredictorTable::Row row0 = test_db_[0]; row0.number_of_hits = row0.number_of_hits + 2; AutocompleteActionPredictorTable::Row row2 = test_db_[2]; row2.number_of_hits = row2.number_of_hits + 2; AutocompleteActionPredictorTable::Rows rows_to_update; rows_to_update.push_back(row0); rows_to_update.push_back(row2); db_->autocomplete_table()->AddAndUpdateRows( AutocompleteActionPredictorTable::Rows(), rows_to_update); EXPECT_EQ(3U, CountRecords()); AutocompleteActionPredictorTable::Row updated_row0, updated_row2; db_->autocomplete_table()->GetRow(test_db_[0].id, &updated_row0); db_->autocomplete_table()->GetRow(test_db_[2].id, &updated_row2); EXPECT_TRUE(RowsAreEqual(row0, updated_row0)) << "Expected: Row with id " << row0.id << "\n" << "Got: Row with id " << updated_row0.id; EXPECT_TRUE(RowsAreEqual(row2, updated_row2)) << "Expected: Row with id " << row2.id << "\n" << "Got: Row with id " << updated_row2.id; } void AutocompleteActionPredictorTableTest::TestDeleteRows() { AddAll(); std::vector id_list; id_list.push_back(test_db_[0].id); id_list.push_back(test_db_[2].id); db_->autocomplete_table()->DeleteRows(id_list); EXPECT_EQ(test_db_.size() - 2, CountRecords()); AutocompleteActionPredictorTable::Row row; db_->autocomplete_table()->GetRow(test_db_[1].id, &row); EXPECT_TRUE(RowsAreEqual(test_db_[1], row)); } void AutocompleteActionPredictorTableTest::TestDeleteAllRows() { AddAll(); db_->autocomplete_table()->DeleteAllRows(); EXPECT_EQ(0U, CountRecords()); } // AutocompleteActionPredictorTableTest tests TEST_F(AutocompleteActionPredictorTableTest, GetRow) { TestGetRow(); } TEST_F(AutocompleteActionPredictorTableTest, AddAndUpdateRows) { TestAddAndUpdateRows(); } TEST_F(AutocompleteActionPredictorTableTest, DeleteRows) { TestDeleteRows(); } TEST_F(AutocompleteActionPredictorTableTest, DeleteAllRows) { TestDeleteAllRows(); } // AutocompleteActionPredictorTableReopenTest tests TEST_F(AutocompleteActionPredictorTableReopenTest, GetRow) { TestGetRow(); } TEST_F(AutocompleteActionPredictorTableReopenTest, AddAndUpdateRows) { TestAddAndUpdateRows(); } TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteRows) { TestDeleteRows(); } TEST_F(AutocompleteActionPredictorTableReopenTest, DeleteAllRows) { TestDeleteAllRows(); } } // namespace predictors