| Index: webkit/dom_storage/local_storage_database_unittest.cc
|
| diff --git a/webkit/dom_storage/local_storage_database_unittest.cc b/webkit/dom_storage/local_storage_database_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c1ad1c764d205aeb5b4b0a8d921ae5b4ae180961
|
| --- /dev/null
|
| +++ b/webkit/dom_storage/local_storage_database_unittest.cc
|
| @@ -0,0 +1,230 @@
|
| +// 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 "webkit/dom_storage/local_storage_database.h"
|
| +
|
| +#include "base/file_path.h"
|
| +#include "base/scoped_temp_dir.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "sql/statement.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace dom_storage {
|
| +
|
| +class LocalStorageDatabaseTest : public testing::Test {
|
| + protected:
|
| + virtual void SetUp() {
|
| + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
| + file_name_ = temp_dir_.path().AppendASCII("TestLocalStorageDatabase.db");
|
| + }
|
| +
|
| + void CreateV1Table(sql::Connection* db) {
|
| + ASSERT_TRUE(db->Execute("DROP TABLE IF EXISTS ItemTable"));
|
| + ASSERT_TRUE(db->Execute(
|
| + "CREATE TABLE IF NOT EXISTS ItemTable ("
|
| + "key TEXT UNIQUE ON CONFLICT REPLACE, "
|
| + "value TEXT NOT NULL ON CONFLICT FAIL)"));
|
| + }
|
| +
|
| + void InsertDataV1(sql::Connection* db,
|
| + const string16& key,
|
| + const string16& value) {
|
| + sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE,
|
| + "INSERT INTO ItemTable VALUES (?,?)"));
|
| + stmt.BindString16(0, key);
|
| + stmt.BindString16(1, value);
|
| + ASSERT_TRUE(stmt.is_valid());
|
| + stmt.Run();
|
| + }
|
| +
|
| + void InsertDataV2(sql::Connection* db,
|
| + const string16& key,
|
| + const string16& value) {
|
| + sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE,
|
| + "INSERT INTO ItemTable VALUES (?,?)"));
|
| + stmt.BindString16(0, key);
|
| + stmt.BindBlob(1, UTF16ToUTF8(value).c_str(), value.size());
|
| + ASSERT_TRUE(stmt.is_valid());
|
| + stmt.Run();
|
| + }
|
| +
|
| + std::map<string16, string16> ReadAllRows(sql::Connection* db) {
|
| + std::map<string16, string16> values;
|
| + sql::Statement stmt(db->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT * from ItemTable"));
|
| + EXPECT_TRUE(stmt.is_valid());
|
| + while (stmt.Step()) {
|
| + string16 key = stmt.ColumnString16(0);
|
| +
|
| + std::string result;
|
| + stmt.ColumnBlobAsString(1, &result);
|
| + string16 value = UTF8ToUTF16(result);
|
| + values[key] = value;
|
| + }
|
| + return values;
|
| + }
|
| +
|
| + void CheckValuesMatch(sql::Connection* db,
|
| + const std::map<string16, string16>& expected) {
|
| + const std::map<string16, string16> values_read = ReadAllRows(db);
|
| + EXPECT_EQ(expected.size(), values_read.size());
|
| +
|
| + std::map<string16, string16>::const_iterator it = values_read.begin();
|
| + for (; it != values_read.end(); ++it) {
|
| + string16 key = it->first;
|
| + string16 value = it->second;
|
| + EXPECT_EQ(expected.find(key)->second, value);
|
| + }
|
| + }
|
| +
|
| + ScopedTempDir temp_dir_;
|
| + FilePath file_name_;
|
| +};
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, SimpleOpenInitAndClose) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + ASSERT_TRUE(db.Init());
|
| + EXPECT_EQ(2, db.GetVersionNumber());
|
| + EXPECT_TRUE(db.db_->DoesTableExist("ItemTable"));
|
| + // Ensure that we've got the colums we expect.
|
| + EXPECT_TRUE(db.db_->DoesColumnExist("ItemTable", "key"));
|
| + EXPECT_TRUE(db.db_->DoesColumnExist("ItemTable", "value"));
|
| + {
|
| + sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT * from ItemTable LIMIT 1"));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt.DeclaredColumnType(1));
|
| + }
|
| + db.Close();
|
| + EXPECT_FALSE(db.IsOpen());
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, TestInitUpgradesV1TableToV2) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + CreateV1Table(db.db_.get());
|
| + db.Close();
|
| +
|
| + ASSERT_TRUE(db.Open());
|
| + EXPECT_EQ(1, db.GetVersionNumber());
|
| + ASSERT_TRUE(db.Init());
|
| + EXPECT_EQ(2, db.GetVersionNumber());
|
| + sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT * from ItemTable LIMIT 1"));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt.DeclaredColumnType(1));
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, TestIsOpen) {
|
| + LocalStorageDatabase db(file_name_);
|
| + EXPECT_FALSE(db.IsOpen());
|
| + ASSERT_TRUE(db.Open());
|
| + EXPECT_TRUE(db.IsOpen());
|
| + db.Close();
|
| + EXPECT_FALSE(db.IsOpen());
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, SimpleRead) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + ASSERT_TRUE(db.Init());
|
| +
|
| + const string16 kCannedKey = ASCIIToUTF16("name");
|
| + const string16 kCannedValue = ASCIIToUTF16("Joe Bloggs");
|
| +
|
| + InsertDataV2(db.db_.get(), kCannedKey, kCannedValue);
|
| + std::map<string16, string16> values = db.ReadAllValues();
|
| +
|
| + EXPECT_EQ(1u, values.size());
|
| + EXPECT_NE(values.end(), values.find(kCannedKey));
|
| + EXPECT_EQ(kCannedValue, values[kCannedKey]);
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, SimpleWrite) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + ASSERT_TRUE(db.Init());
|
| +
|
| + std::map<string16, string16> storage;
|
| + string16 kCannedKeys[] = {
|
| + ASCIIToUTF16("test"),
|
| + ASCIIToUTF16("company"),
|
| + ASCIIToUTF16("date")
|
| + };
|
| + string16 kCannedValues[] = {
|
| + ASCIIToUTF16("123"),
|
| + ASCIIToUTF16("Google"),
|
| + ASCIIToUTF16("18-01-2012")
|
| + };
|
| + for (int i = 0; i < 3; i++) {
|
| + storage[kCannedKeys[i]] = kCannedValues[i];
|
| + }
|
| +
|
| + ASSERT_TRUE(db.WriteAllValues(storage));
|
| +
|
| + CheckValuesMatch(db.db_.get(), storage);
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, UpgradeFromV1ToV2NoData) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + CreateV1Table(db.db_.get());
|
| +
|
| + // The database has V1 structure, try to update it to V2.
|
| + sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT value from ItemTable LIMIT 1"));
|
| + ASSERT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0));
|
| +
|
| + ASSERT_TRUE(db.UpgradeVersion1To2IfNeeded());
|
| +
|
| + // Verify the db now has V2 structure.
|
| + sql::Statement stmt2(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT value from ItemTable LIMIT 1"));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt2.DeclaredColumnType(0));
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, UpgradeFromV1ToV2WithData) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + CreateV1Table(db.db_.get());
|
| +
|
| + // The database has V1 structure, try to update it to V2.
|
| + sql::Statement stmt(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT value from ItemTable LIMIT 1"));
|
| + ASSERT_EQ(sql::COLUMN_TYPE_TEXT, stmt.DeclaredColumnType(0));
|
| +
|
| + const string16 kCannedKey = ASCIIToUTF16("foo");
|
| + const string16 kCannedValue = ASCIIToUTF16("bar");
|
| + InsertDataV1(db.db_.get(), kCannedKey, kCannedValue);
|
| +
|
| + ASSERT_TRUE(db.UpgradeVersion1To2IfNeeded());
|
| +
|
| + // Verify the db now has V2 structure.
|
| + sql::Statement stmt2(db.db_->GetCachedStatement(SQL_FROM_HERE,
|
| + "SELECT value from ItemTable LIMIT 1"));
|
| + EXPECT_EQ(sql::COLUMN_TYPE_BLOB, stmt2.DeclaredColumnType(0));
|
| +
|
| + std::map<string16, string16> expected;
|
| + expected[kCannedKey] = kCannedValue;
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| +}
|
| +
|
| +TEST_F(LocalStorageDatabaseTest, TestOpenCloseDataPreserved) {
|
| + LocalStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.Open());
|
| + ASSERT_TRUE(db.Init());
|
| +
|
| + const string16 kCannedKey = ASCIIToUTF16("test");
|
| + const string16 kCannedValue = ASCIIToUTF16("data");
|
| + InsertDataV2(db.db_.get(), kCannedKey, kCannedValue);
|
| + db.Close();
|
| +
|
| + db.Open();
|
| + std::map<string16, string16> expected;
|
| + expected[kCannedKey] = kCannedValue;
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| +}
|
| +
|
| +} // namespace dom_storage
|
|
|