OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/message_loop.h" | |
9 #include "base/message_loop_proxy.h" | |
10 #include "base/path_service.h" | 8 #include "base/path_service.h" |
11 #include "base/scoped_temp_dir.h" | 9 #include "base/scoped_temp_dir.h" |
12 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
13 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/threading/sequenced_worker_pool.h" | |
14 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
15 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
16 #include "base/values.h" | 15 #include "base/values.h" |
17 #include "chrome/common/chrome_paths.h" | 16 #include "chrome/common/chrome_paths.h" |
18 #include "chrome/common/json_pref_store.h" | 17 #include "chrome/common/json_pref_store.h" |
19 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
22 | 21 |
23 namespace { | 22 namespace { |
24 | 23 |
25 class MockPrefStoreObserver : public PrefStore::Observer { | 24 class MockPrefStoreObserver : public PrefStore::Observer { |
26 public: | 25 public: |
27 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&)); | 26 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&)); |
28 MOCK_METHOD1(OnInitializationCompleted, void (bool)); | 27 MOCK_METHOD1(OnInitializationCompleted, void (bool)); |
29 }; | 28 }; |
30 | 29 |
31 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { | 30 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { |
32 public: | 31 public: |
33 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); | 32 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); |
34 }; | 33 }; |
35 | 34 |
36 } // namespace | 35 } // namespace |
37 | 36 |
38 class JsonPrefStoreTest : public testing::Test { | 37 class JsonPrefStoreTest : public testing::Test { |
39 protected: | 38 protected: |
40 virtual void SetUp() { | 39 virtual void SetUp() OVERRIDE { |
41 message_loop_proxy_ = base::MessageLoopProxy::current(); | |
42 | |
43 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 40 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
44 | 41 |
45 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_)); | 42 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_dir_)); |
46 data_dir_ = data_dir_.AppendASCII("pref_service"); | 43 data_dir_ = data_dir_.AppendASCII("pref_service"); |
47 ASSERT_TRUE(file_util::PathExists(data_dir_)); | 44 ASSERT_TRUE(file_util::PathExists(data_dir_)); |
48 } | 45 } |
49 | 46 |
50 // The path to temporary directory used to contain the test operations. | 47 // The path to temporary directory used to contain the test operations. |
51 ScopedTempDir temp_dir_; | 48 ScopedTempDir temp_dir_; |
52 // The path to the directory where the test data is stored. | 49 // The path to the directory where the test data is stored. |
53 FilePath data_dir_; | 50 FilePath data_dir_; |
54 // A message loop that we can use as the file thread message loop. | 51 // A message loop that we need for timers. |
Mattias Nissler (ping if slow)
2012/10/22 17:28:21
It's actually not used for timers?
zel
2012/10/24 02:20:11
hmm, still no idea where these comments come from.
| |
55 MessageLoop message_loop_; | 52 MessageLoop message_loop_; |
56 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | |
57 }; | 53 }; |
58 | 54 |
59 // Test fallback behavior for a nonexistent file. | 55 // Test fallback behavior for a nonexistent file. |
60 TEST_F(JsonPrefStoreTest, NonExistentFile) { | 56 TEST_F(JsonPrefStoreTest, NonExistentFile) { |
61 FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); | 57 FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); |
62 ASSERT_FALSE(file_util::PathExists(bogus_input_file)); | 58 ASSERT_FALSE(file_util::PathExists(bogus_input_file)); |
63 scoped_refptr<JsonPrefStore> pref_store = | 59 scoped_refptr<JsonPrefStore> pref_store = |
64 new JsonPrefStore(bogus_input_file, message_loop_proxy_.get()); | 60 JsonPrefStore::Create( |
61 bogus_input_file, message_loop_.message_loop_proxy()); | |
65 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, | 62 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, |
66 pref_store->ReadPrefs()); | 63 pref_store->ReadPrefs()); |
67 EXPECT_FALSE(pref_store->ReadOnly()); | 64 EXPECT_FALSE(pref_store->ReadOnly()); |
68 } | 65 } |
69 | 66 |
70 // Test fallback behavior for an invalid file. | 67 // Test fallback behavior for an invalid file. |
71 TEST_F(JsonPrefStoreTest, InvalidFile) { | 68 TEST_F(JsonPrefStoreTest, InvalidFile) { |
72 FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json"); | 69 FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json"); |
73 FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json"); | 70 FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json"); |
74 ASSERT_TRUE(file_util::CopyFile(invalid_file_original, invalid_file)); | 71 ASSERT_TRUE(file_util::CopyFile(invalid_file_original, invalid_file)); |
75 scoped_refptr<JsonPrefStore> pref_store = | 72 scoped_refptr<JsonPrefStore> pref_store = |
76 new JsonPrefStore(invalid_file, message_loop_proxy_.get()); | 73 JsonPrefStore::Create( |
74 invalid_file, message_loop_.message_loop_proxy()); | |
77 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, | 75 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, |
78 pref_store->ReadPrefs()); | 76 pref_store->ReadPrefs()); |
79 EXPECT_FALSE(pref_store->ReadOnly()); | 77 EXPECT_FALSE(pref_store->ReadOnly()); |
80 | 78 |
81 // The file should have been moved aside. | 79 // The file should have been moved aside. |
82 EXPECT_FALSE(file_util::PathExists(invalid_file)); | 80 EXPECT_FALSE(file_util::PathExists(invalid_file)); |
83 FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad"); | 81 FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad"); |
84 EXPECT_TRUE(file_util::PathExists(moved_aside)); | 82 EXPECT_TRUE(file_util::PathExists(moved_aside)); |
85 EXPECT_TRUE(file_util::TextContentsEqual(invalid_file_original, | 83 EXPECT_TRUE(file_util::TextContentsEqual(invalid_file_original, |
86 moved_aside)); | 84 moved_aside)); |
87 } | 85 } |
88 | 86 |
89 // This function is used to avoid code duplication while testing synchronous and | 87 // This function is used to avoid code duplication while testing synchronous and |
90 // asynchronous version of the JsonPrefStore loading. | 88 // asynchronous version of the JsonPrefStore loading. |
91 void RunBasicJsonPrefStoreTest(JsonPrefStore *pref_store, | 89 void RunBasicJsonPrefStoreTest(JsonPrefStore* pref_store, |
92 const FilePath& output_file, | 90 const FilePath& output_file, |
93 const FilePath& golden_output_file) { | 91 const FilePath& golden_output_file) { |
94 const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs"; | 92 const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs"; |
95 const char kMaxTabs[] = "tabs.max_tabs"; | 93 const char kMaxTabs[] = "tabs.max_tabs"; |
96 const char kLongIntPref[] = "long_int.pref"; | 94 const char kLongIntPref[] = "long_int.pref"; |
97 | 95 |
98 std::string cnn("http://www.cnn.com"); | 96 std::string cnn("http://www.cnn.com"); |
99 | 97 |
100 const Value* actual; | 98 const Value* actual; |
101 EXPECT_EQ(PrefStore::READ_OK, | 99 EXPECT_EQ(PrefStore::READ_OK, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 } | 157 } |
160 | 158 |
161 TEST_F(JsonPrefStoreTest, Basic) { | 159 TEST_F(JsonPrefStoreTest, Basic) { |
162 ASSERT_TRUE(file_util::CopyFile(data_dir_.AppendASCII("read.json"), | 160 ASSERT_TRUE(file_util::CopyFile(data_dir_.AppendASCII("read.json"), |
163 temp_dir_.path().AppendASCII("write.json"))); | 161 temp_dir_.path().AppendASCII("write.json"))); |
164 | 162 |
165 // Test that the persistent value can be loaded. | 163 // Test that the persistent value can be loaded. |
166 FilePath input_file = temp_dir_.path().AppendASCII("write.json"); | 164 FilePath input_file = temp_dir_.path().AppendASCII("write.json"); |
167 ASSERT_TRUE(file_util::PathExists(input_file)); | 165 ASSERT_TRUE(file_util::PathExists(input_file)); |
168 scoped_refptr<JsonPrefStore> pref_store = | 166 scoped_refptr<JsonPrefStore> pref_store = |
169 new JsonPrefStore(input_file, message_loop_proxy_.get()); | 167 JsonPrefStore::Create( |
168 input_file, message_loop_.message_loop_proxy()); | |
170 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); | 169 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
171 ASSERT_FALSE(pref_store->ReadOnly()); | 170 ASSERT_FALSE(pref_store->ReadOnly()); |
172 | 171 |
173 // The JSON file looks like this: | 172 // The JSON file looks like this: |
174 // { | 173 // { |
175 // "homepage": "http://www.cnn.com", | 174 // "homepage": "http://www.cnn.com", |
176 // "some_directory": "/usr/local/", | 175 // "some_directory": "/usr/local/", |
177 // "tabs": { | 176 // "tabs": { |
178 // "new_windows_in_tabs": true, | 177 // "new_windows_in_tabs": true, |
179 // "max_tabs": 20 | 178 // "max_tabs": 20 |
180 // } | 179 // } |
181 // } | 180 // } |
182 | 181 |
183 RunBasicJsonPrefStoreTest(pref_store, | 182 RunBasicJsonPrefStoreTest(pref_store, |
184 input_file, | 183 input_file, |
185 data_dir_.AppendASCII("write.golden.json")); | 184 data_dir_.AppendASCII("write.golden.json")); |
186 } | 185 } |
187 | 186 |
188 TEST_F(JsonPrefStoreTest, BasicAsync) { | 187 TEST_F(JsonPrefStoreTest, BasicAsync) { |
189 ASSERT_TRUE(file_util::CopyFile(data_dir_.AppendASCII("read.json"), | 188 ASSERT_TRUE(file_util::CopyFile(data_dir_.AppendASCII("read.json"), |
190 temp_dir_.path().AppendASCII("write.json"))); | 189 temp_dir_.path().AppendASCII("write.json"))); |
191 | 190 |
192 // Test that the persistent value can be loaded. | 191 // Test that the persistent value can be loaded. |
193 FilePath input_file = temp_dir_.path().AppendASCII("write.json"); | 192 FilePath input_file = temp_dir_.path().AppendASCII("write.json"); |
194 ASSERT_TRUE(file_util::PathExists(input_file)); | 193 ASSERT_TRUE(file_util::PathExists(input_file)); |
195 scoped_refptr<JsonPrefStore> pref_store = | 194 scoped_refptr<JsonPrefStore> pref_store = |
196 new JsonPrefStore(input_file, message_loop_proxy_.get()); | 195 JsonPrefStore::Create( |
196 input_file, message_loop_.message_loop_proxy()); | |
197 | 197 |
198 MockPrefStoreObserver mock_observer; | 198 { |
199 pref_store->AddObserver(&mock_observer); | 199 MockPrefStoreObserver mock_observer; |
200 pref_store->AddObserver(&mock_observer); | |
200 | 201 |
201 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate; | 202 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate; |
202 pref_store->ReadPrefsAsync(mock_error_delegate); | 203 pref_store->ReadPrefsAsync(mock_error_delegate); |
203 | 204 |
204 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); | 205 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); |
205 EXPECT_CALL(*mock_error_delegate, | 206 EXPECT_CALL(*mock_error_delegate, |
206 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0); | 207 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0); |
207 message_loop_.RunAllPending(); | 208 message_loop_.RunAllPending(); |
208 pref_store->RemoveObserver(&mock_observer); | 209 pref_store->RemoveObserver(&mock_observer); |
209 | 210 |
210 ASSERT_FALSE(pref_store->ReadOnly()); | 211 ASSERT_FALSE(pref_store->ReadOnly()); |
212 } | |
211 | 213 |
212 // The JSON file looks like this: | 214 // The JSON file looks like this: |
213 // { | 215 // { |
214 // "homepage": "http://www.cnn.com", | 216 // "homepage": "http://www.cnn.com", |
215 // "some_directory": "/usr/local/", | 217 // "some_directory": "/usr/local/", |
216 // "tabs": { | 218 // "tabs": { |
217 // "new_windows_in_tabs": true, | 219 // "new_windows_in_tabs": true, |
218 // "max_tabs": 20 | 220 // "max_tabs": 20 |
219 // } | 221 // } |
220 // } | 222 // } |
221 | 223 |
222 RunBasicJsonPrefStoreTest(pref_store, | 224 RunBasicJsonPrefStoreTest(pref_store, |
223 input_file, | 225 input_file, |
224 data_dir_.AppendASCII("write.golden.json")); | 226 data_dir_.AppendASCII("write.golden.json")); |
225 } | 227 } |
226 | 228 |
227 // Tests asynchronous reading of the file when there is no file. | 229 // Tests asynchronous reading of the file when there is no file. |
228 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) { | 230 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) { |
229 FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); | 231 FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); |
230 ASSERT_FALSE(file_util::PathExists(bogus_input_file)); | 232 ASSERT_FALSE(file_util::PathExists(bogus_input_file)); |
231 scoped_refptr<JsonPrefStore> pref_store = | 233 scoped_refptr<JsonPrefStore> pref_store = |
232 new JsonPrefStore(bogus_input_file, message_loop_proxy_.get()); | 234 JsonPrefStore::Create( |
235 bogus_input_file, message_loop_.message_loop_proxy()); | |
233 MockPrefStoreObserver mock_observer; | 236 MockPrefStoreObserver mock_observer; |
234 pref_store->AddObserver(&mock_observer); | 237 pref_store->AddObserver(&mock_observer); |
235 | 238 |
236 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate; | 239 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate; |
237 pref_store->ReadPrefsAsync(mock_error_delegate); | 240 pref_store->ReadPrefsAsync(mock_error_delegate); |
238 | 241 |
239 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); | 242 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); |
240 EXPECT_CALL(*mock_error_delegate, | 243 EXPECT_CALL(*mock_error_delegate, |
241 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1); | 244 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1); |
242 message_loop_.RunAllPending(); | 245 message_loop_.RunAllPending(); |
243 pref_store->RemoveObserver(&mock_observer); | 246 pref_store->RemoveObserver(&mock_observer); |
244 | 247 |
245 EXPECT_FALSE(pref_store->ReadOnly()); | 248 EXPECT_FALSE(pref_store->ReadOnly()); |
246 } | 249 } |
247 | 250 |
248 TEST_F(JsonPrefStoreTest, NeedsEmptyValue) { | 251 TEST_F(JsonPrefStoreTest, NeedsEmptyValue) { |
249 FilePath pref_file = temp_dir_.path().AppendASCII("write.json"); | 252 FilePath pref_file = temp_dir_.path().AppendASCII("write.json"); |
250 | 253 |
251 ASSERT_TRUE(file_util::CopyFile( | 254 ASSERT_TRUE(file_util::CopyFile( |
252 data_dir_.AppendASCII("read.need_empty_value.json"), | 255 data_dir_.AppendASCII("read.need_empty_value.json"), |
253 pref_file)); | 256 pref_file)); |
254 | 257 |
255 // Test that the persistent value can be loaded. | 258 // Test that the persistent value can be loaded. |
256 ASSERT_TRUE(file_util::PathExists(pref_file)); | 259 ASSERT_TRUE(file_util::PathExists(pref_file)); |
257 scoped_refptr<JsonPrefStore> pref_store = | 260 scoped_refptr<JsonPrefStore> pref_store = |
258 new JsonPrefStore(pref_file, message_loop_proxy_.get()); | 261 JsonPrefStore::Create( |
262 pref_file, message_loop_.message_loop_proxy()); | |
259 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); | 263 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
260 ASSERT_FALSE(pref_store->ReadOnly()); | 264 ASSERT_FALSE(pref_store->ReadOnly()); |
261 | 265 |
262 // The JSON file looks like this: | 266 // The JSON file looks like this: |
263 // { | 267 // { |
264 // "list": [ 1 ], | 268 // "list": [ 1 ], |
265 // "list_needs_empty_value": [ 2 ], | 269 // "list_needs_empty_value": [ 2 ], |
266 // "dict": { | 270 // "dict": { |
267 // "dummy": true, | 271 // "dummy": true, |
268 // }, | 272 // }, |
(...skipping 15 matching lines...) Expand all Loading... | |
284 // Write to file. | 288 // Write to file. |
285 pref_store->CommitPendingWrite(); | 289 pref_store->CommitPendingWrite(); |
286 MessageLoop::current()->RunAllPending(); | 290 MessageLoop::current()->RunAllPending(); |
287 | 291 |
288 // Compare to expected output. | 292 // Compare to expected output. |
289 FilePath golden_output_file = | 293 FilePath golden_output_file = |
290 data_dir_.AppendASCII("write.golden.need_empty_value.json"); | 294 data_dir_.AppendASCII("write.golden.need_empty_value.json"); |
291 ASSERT_TRUE(file_util::PathExists(golden_output_file)); | 295 ASSERT_TRUE(file_util::PathExists(golden_output_file)); |
292 EXPECT_TRUE(file_util::TextContentsEqual(golden_output_file, pref_file)); | 296 EXPECT_TRUE(file_util::TextContentsEqual(golden_output_file, pref_file)); |
293 } | 297 } |
OLD | NEW |