| Index: webkit/dom_storage/dom_storage_database_unittest.cc
|
| diff --git a/webkit/dom_storage/dom_storage_database_unittest.cc b/webkit/dom_storage/dom_storage_database_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7f4290c0f7dc53084a8b126a03c9981e36eddc37
|
| --- /dev/null
|
| +++ b/webkit/dom_storage/dom_storage_database_unittest.cc
|
| @@ -0,0 +1,285 @@
|
| +// 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/dom_storage_database.h"
|
| +
|
| +#include "base/file_path.h"
|
| +#include "base/path_service.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 DomStorageDatabaseTest : public testing::Test {
|
| + protected:
|
| + virtual void SetUp() {
|
| + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
| + file_name_ = temp_dir_.path().AppendASCII("TestDomStorageDatabase.db");
|
| + }
|
| +
|
| + void CreateV1Table(sql::Connection* db) {
|
| + ASSERT_FALSE(db->is_open());
|
| + ASSERT_TRUE(db->Open(file_name_));
|
| + 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, value.data(), value.length() * sizeof(char16));
|
| + ASSERT_TRUE(stmt.is_valid());
|
| + stmt.Run();
|
| + }
|
| +
|
| + DomStorageDatabase::ValuesMap ReadAllRows(sql::Connection* db) {
|
| + DomStorageDatabase::ValuesMap 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);
|
| + string16 value;
|
| + stmt.ColumnBlobAsString16(1, &value);
|
| + values[key] = value;
|
| + }
|
| + return values;
|
| + }
|
| +
|
| + void CheckValuesMatch(sql::Connection* db,
|
| + const DomStorageDatabase::ValuesMap& expected) {
|
| + const DomStorageDatabase::ValuesMap values_read = ReadAllRows(db);
|
| + EXPECT_EQ(expected.size(), values_read.size());
|
| +
|
| + DomStorageDatabase::ValuesMap::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(DomStorageDatabaseTest, SimpleOpenAndClose) {
|
| + DomStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.LazyOpen());
|
| + 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(DomStorageDatabaseTest, TestUpgradesV1TableToV2) {
|
| + DomStorageDatabase db(file_name_);
|
| + db.db_.reset(new sql::Connection());
|
| + CreateV1Table(db.db_.get());
|
| + db.Close();
|
| +
|
| + db.LazyOpen();
|
| + 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(DomStorageDatabaseTest, TestIsOpen) {
|
| + DomStorageDatabase db(file_name_);
|
| + EXPECT_FALSE(db.IsOpen());
|
| + ASSERT_TRUE(db.LazyOpen());
|
| + EXPECT_TRUE(db.IsOpen());
|
| + db.Close();
|
| + EXPECT_FALSE(db.IsOpen());
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, SimpleRead) {
|
| + DomStorageDatabase db(file_name_);
|
| + db.LazyOpen();
|
| +
|
| + const string16 kCannedKey = ASCIIToUTF16("name");
|
| + const string16 kCannedValue = ASCIIToUTF16("Joe Bloggs");
|
| +
|
| + InsertDataV2(db.db_.get(), kCannedKey, kCannedValue);
|
| + DomStorageDatabase::ValuesMap values;
|
| + db.ReadAllValues(&values);
|
| +
|
| + EXPECT_EQ(1u, values.size());
|
| + EXPECT_NE(values.end(), values.find(kCannedKey));
|
| + EXPECT_EQ(kCannedValue, values[kCannedKey]);
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, SimpleWrite) {
|
| + DomStorageDatabase db(file_name_);
|
| +
|
| + DomStorageDatabase::ValuesMap 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.WriteValues(storage));
|
| +
|
| + CheckValuesMatch(db.db_.get(), storage);
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, UpgradeFromV1ToV2NoData) {
|
| + DomStorageDatabase db(file_name_);
|
| + db.db_.reset(new sql::Connection());
|
| + 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(DomStorageDatabaseTest, UpgradeFromV1ToV2WithData) {
|
| + const string16 kCannedKey = ASCIIToUTF16("foo");
|
| + const string16 kCannedValue = ASCIIToUTF16("bar");
|
| + DomStorageDatabase::ValuesMap expected;
|
| + expected[kCannedKey] = kCannedValue;
|
| +
|
| + {
|
| + DomStorageDatabase db(file_name_);
|
| + db.db_.reset(new sql::Connection());
|
| + 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));
|
| +
|
| + 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));
|
| +
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| + }
|
| +
|
| + // Now open the db again and check that the data is consistent.
|
| + {
|
| + DomStorageDatabase db(file_name_);
|
| + ASSERT_TRUE(db.LazyOpen());
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| + }
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, TestOpenCloseDataPreserved) {
|
| + DomStorageDatabase db(file_name_);
|
| +
|
| + ASSERT_TRUE(db.LazyOpen());
|
| +
|
| + const string16 kCannedKey = ASCIIToUTF16("test");
|
| + const string16 kCannedValue = ASCIIToUTF16("data");
|
| + InsertDataV2(db.db_.get(), kCannedKey, kCannedValue);
|
| + db.Close();
|
| +
|
| + ASSERT_TRUE(db.LazyOpen());
|
| + DomStorageDatabase::ValuesMap expected;
|
| + expected[kCannedKey] = kCannedValue;
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, TestSimpleRemoveOneValue) {
|
| + DomStorageDatabase db(file_name_);
|
| +
|
| + ASSERT_TRUE(db.LazyOpen());
|
| + const string16 kCannedKey = ASCIIToUTF16("test");
|
| + const string16 kCannedValue = ASCIIToUTF16("data");
|
| + InsertDataV2(db.db_.get(), kCannedKey, kCannedValue);
|
| +
|
| + DomStorageDatabase::ValuesMap expected;
|
| + expected[kCannedKey] = kCannedValue;
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| +
|
| + DomStorageDatabase::ValuesSet values;
|
| + values.insert(kCannedKey);
|
| +
|
| + db.RemoveValues(values);
|
| +
|
| + expected.clear();
|
| + CheckValuesMatch(db.db_.get(), expected);
|
| +}
|
| +
|
| +TEST_F(DomStorageDatabaseTest, TestCanOpenAndReadWebCoreDatabase) {
|
| + {
|
| + FilePath webcore_database;
|
| + PathService::Get(base::DIR_SOURCE_ROOT, &webcore_database);
|
| + webcore_database = webcore_database.AppendASCII("webkit");
|
| + webcore_database = webcore_database.AppendASCII("data");
|
| + webcore_database = webcore_database.AppendASCII("dom_storage");
|
| + webcore_database =
|
| + webcore_database.AppendASCII("webcore_test_database.localstorage");
|
| +
|
| + DomStorageDatabase db(webcore_database);
|
| +
|
| + DomStorageDatabase::ValuesMap values;
|
| + db.ReadAllValues(&values);
|
| + EXPECT_EQ(2u, values.size());
|
| +
|
| + DomStorageDatabase::ValuesMap::const_iterator it =
|
| + values.find(ASCIIToUTF16("value"));
|
| + EXPECT_NE(values.end(), it);
|
| + EXPECT_EQ(ASCIIToUTF16("I am in local storage!"), it->second);
|
| +
|
| + it = values.find(ASCIIToUTF16("timestamp"));
|
| + EXPECT_NE(values.end(), it);
|
| + EXPECT_EQ(ASCIIToUTF16("1326738338841"), it->second);
|
| +
|
| + it = values.find(ASCIIToUTF16("not_there"));
|
| + EXPECT_EQ(values.end(), it);
|
| + }
|
| +}
|
| +
|
| +} // namespace dom_storage
|
|
|