OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 // TODO(kalman): More tests: | |
6 // - Keys/values containing dots. | |
7 // - More than one active settings object. | |
8 // - Failure cases | |
9 | |
10 #include "chrome/browser/extensions/extension_settings_storage_unittest.h" | |
11 | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/json/json_writer.h" | |
14 #include "base/values.h" | |
15 #include "chrome/browser/extensions/extension_settings.h" | |
16 | |
17 // Define macros for these to get the __LINE__ expansion. | |
18 // Undefined at the end of the file. | |
19 #define newCallback(expected) \ | |
20 (new AssertEqualsCallback((expected), false, __LINE__)) | |
21 #define newQuittingCallback(expected) \ | |
22 (new AssertEqualsCallback((expected), true, __LINE__)) | |
23 | |
24 namespace { | |
25 | |
26 // Wait for the QuitTask on the current message loop. Converse of running a | |
27 // storage function with a newQuittingCallback(). | |
28 void waitForQuit() { | |
29 MessageLoop::current()->Run(); | |
dgrogan
2011/06/18 01:54:40
When do you use Run vs RunAllPending?
not at google - send to devlin
2011/06/20 05:33:11
I don't think RunAllPending would work, at least w
dgrogan
2011/06/21 02:36:05
Thanks for the good explanation.
not at google - send to devlin
2011/06/22 09:40:38
Ah, very nice. Thank you.
| |
30 } | |
31 | |
32 // Callback from GetStorage() which places the new storage in a given location. | |
33 // Posts a QuitTask to the current message loop when done. | |
34 class GetStorageCallback : public ExtensionSettings::Callback { | |
35 public: | |
36 explicit GetStorageCallback(ExtensionSettingsStorage** storagePtr) | |
37 : storagePtr_(storagePtr) { | |
38 *storagePtr = NULL; | |
39 } | |
40 | |
41 ~GetStorageCallback() {} | |
42 | |
43 void Run(ExtensionSettingsStorage* storage) { | |
44 DCHECK(*storagePtr_ == NULL); | |
45 *storagePtr_ = storage; | |
46 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
47 } | |
48 | |
49 private: | |
50 ExtensionSettingsStorage** storagePtr_; | |
51 }; | |
52 | |
53 // Callback from storage methods which performs the test assertions. | |
54 class AssertEqualsCallback : public ExtensionSettingsStorage::Callback { | |
55 public: | |
56 AssertEqualsCallback(DictionaryValue* expected, bool quit_when_done, int line) | |
57 : expected_(expected), quit_when_done_(quit_when_done), line_(line), | |
58 called_(false) { | |
59 } | |
60 | |
61 ~AssertEqualsCallback() { | |
62 // Need to DCHECK since ASSERT_* can't be used from destructors. | |
63 DCHECK(called_); | |
64 } | |
65 | |
66 void OnSuccess(DictionaryValue* actual) { | |
67 // Post quit task first so that it always runs even if the test fails. | |
68 MaybePostQuitTask(); | |
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
70 ASSERT_FALSE(called_) << "Callback has already been called"; | |
71 called_ = true; | |
72 ASSERT_TRUE(expected_->Equals(actual)) << "Values are different:\n" << | |
73 "Line: " << line_ << "\n" << | |
74 "Expected: " << GetJson(expected_) << | |
75 "Got: " << GetJson(actual); | |
76 delete actual; | |
77 } | |
78 | |
79 void OnFailure(const std::string& message) { | |
80 // Post quit task first so that it always runs even if the test fails. | |
81 MaybePostQuitTask(); | |
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
83 ASSERT_FALSE(called_) << "Callback has already been called"; | |
84 called_ = true; | |
85 // No tests allow failure (yet). | |
86 ASSERT_TRUE(false) << "Callback failed on line " << line_; | |
87 } | |
88 | |
89 private: | |
90 std::string GetJson(Value* value) { | |
91 std::string json; | |
92 base::JSONWriter::Write(value, true, &json); | |
93 return json; | |
94 } | |
95 | |
96 void MaybePostQuitTask() { | |
97 if (quit_when_done_) { | |
98 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
99 } | |
100 } | |
101 | |
102 DictionaryValue* expected_; | |
103 bool quit_when_done_; | |
104 int line_; | |
105 bool called_; | |
106 }; | |
107 | |
108 class TestSettingsCallback : public ExtensionSettings::Callback { | |
109 public: | |
110 explicit TestSettingsCallback(ExtensionSettingsStorage** storagePtr) | |
111 : storagePtr_(storagePtr) { | |
112 *storagePtr_ = NULL; | |
113 } | |
114 | |
115 void Run(ExtensionSettingsStorage* storage) { | |
116 DCHECK(*storagePtr_ == NULL); | |
117 DCHECK(storage != NULL); | |
118 *storagePtr_ = storage; | |
119 } | |
120 | |
121 private: | |
122 ExtensionSettingsStorage** storagePtr_; | |
123 }; | |
124 | |
125 std::string key1() { | |
126 return "foo"; | |
127 } | |
128 | |
129 std::string key2() { | |
130 return "bar"; | |
131 } | |
132 | |
133 std::string key3() { | |
134 return "baz"; | |
135 } | |
136 | |
137 Value* val1() { | |
138 Value* val = NULL; | |
139 if (val == NULL) { | |
140 val = Value::CreateStringValue(key1() + "Value"); | |
141 } | |
142 return val; | |
143 } | |
144 | |
145 Value* val2() { | |
146 static Value* val = NULL; | |
147 if (val == NULL) { | |
148 val = Value::CreateStringValue(key2() + "Value"); | |
149 } | |
150 return val; | |
151 } | |
152 | |
153 Value* val3() { | |
154 static Value* val = NULL; | |
155 if (val == NULL) { | |
156 val = Value::CreateStringValue(key3() + "Value"); | |
157 } | |
158 return val; | |
159 } | |
160 | |
161 ListValue* emptyList() { | |
162 static ListValue* val = NULL; | |
163 if (val == NULL) { | |
164 val = new ListValue(); | |
165 } | |
166 return val; | |
167 } | |
168 | |
169 ListValue* list1() { | |
170 static ListValue* val = NULL; | |
171 if (val == NULL) { | |
172 val = new ListValue(); | |
173 val->Append(Value::CreateStringValue(key1())); | |
174 } | |
175 return val; | |
176 } | |
177 | |
178 ListValue* list2() { | |
179 static ListValue* val = NULL; | |
180 if (val == NULL) { | |
181 val = new ListValue(); | |
182 val->Append(Value::CreateStringValue(key2())); | |
183 } | |
184 return val; | |
185 } | |
186 | |
187 ListValue* list12() { | |
188 static ListValue* val = NULL; | |
189 if (val == NULL) { | |
190 val = new ListValue(); | |
191 val->Append(Value::CreateStringValue(key1())); | |
192 val->Append(Value::CreateStringValue(key2())); | |
193 } | |
194 return val; | |
195 } | |
196 | |
197 ListValue* list13() { | |
198 static ListValue* val = NULL; | |
199 if (val == NULL) { | |
200 val = new ListValue(); | |
201 val->Append(Value::CreateStringValue(key1())); | |
202 val->Append(Value::CreateStringValue(key3())); | |
203 } | |
204 return val; | |
205 } | |
206 | |
207 ListValue* list123() { | |
208 static ListValue* val = NULL; | |
209 if (val == NULL) { | |
210 val = new ListValue(); | |
211 val->Append(Value::CreateStringValue(key1())); | |
212 val->Append(Value::CreateStringValue(key2())); | |
213 val->Append(Value::CreateStringValue(key3())); | |
214 } | |
215 return val; | |
216 } | |
217 | |
218 DictionaryValue* emptyDict() { | |
219 static DictionaryValue* val = NULL; | |
220 if (val == NULL) { | |
221 val = new DictionaryValue(); | |
222 } | |
223 return val; | |
224 } | |
225 | |
226 DictionaryValue* dict1() { | |
227 static DictionaryValue* val = NULL; | |
228 if (val == NULL) { | |
229 val = new DictionaryValue(); | |
230 val->Set(key1(), val1()->DeepCopy()); | |
231 } | |
232 return val; | |
233 } | |
234 | |
235 DictionaryValue* dict12() { | |
236 static DictionaryValue* val = NULL; | |
237 if (val == NULL) { | |
238 val = new DictionaryValue(); | |
239 val->Set(key1(), val1()->DeepCopy()); | |
240 val->Set(key2(), val2()->DeepCopy()); | |
241 } | |
242 return val; | |
243 } | |
244 | |
245 DictionaryValue* dict123() { | |
246 static DictionaryValue* val = NULL; | |
247 if (val == NULL) { | |
248 val = new DictionaryValue(); | |
249 val->Set(key1(), val1()->DeepCopy()); | |
250 val->Set(key2(), val2()->DeepCopy()); | |
251 val->Set(key3(), val3()->DeepCopy()); | |
252 } | |
253 return val; | |
254 } | |
255 | |
256 } // namespace | |
257 | |
258 void ExtensionSettingsStorageTest::SetUp() { | |
259 ui_message_loop_ = new MessageLoopForUI(); | |
260 ui_thread_ = new BrowserThread(BrowserThread::UI, MessageLoop::current()); | |
261 file_thread_ = new BrowserThread(BrowserThread::FILE); | |
262 file_thread_->Start(); | |
263 | |
264 FilePath temp_dir; | |
265 file_util::CreateNewTempDirectory("", &temp_dir); | |
266 settings_ = new ExtensionSettings(temp_dir); | |
267 | |
268 storage_ = NULL; | |
269 settings_->GetStorageForTesting(GetParam(), "fakeExtension", | |
270 new GetStorageCallback(&storage_)); | |
271 waitForQuit(); | |
272 DCHECK(storage_ != NULL); | |
273 } | |
274 | |
275 void ExtensionSettingsStorageTest::TearDown() { | |
276 delete settings_; | |
277 | |
278 file_thread_->Stop(); | |
279 delete file_thread_; | |
280 delete ui_thread_; | |
281 delete ui_message_loop_; | |
282 } | |
283 | |
284 TEST_P(ExtensionSettingsStorageTest, GetWhenEmpty) { | |
285 storage_->Get(key1(), newCallback(emptyDict())); | |
286 storage_->Get(key2(), newCallback(emptyDict())); | |
287 storage_->Get(key3(), newCallback(emptyDict())); | |
288 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
289 storage_->Get(*list1(), newCallback(emptyDict())); | |
290 storage_->Get(*list123(), newCallback(emptyDict())); | |
291 | |
292 storage_->Get(newQuittingCallback(emptyDict())); | |
293 waitForQuit(); | |
294 } | |
295 | |
296 TEST_P(ExtensionSettingsStorageTest, GetWithSingleValue) { | |
297 storage_->Set(key1(), *val1(), newQuittingCallback(dict1())); | |
298 waitForQuit(); | |
299 | |
300 storage_->Get(key1(), newCallback(dict1())); | |
301 storage_->Get(key2(), newCallback(emptyDict())); | |
302 storage_->Get(key3(), newCallback(emptyDict())); | |
303 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
304 storage_->Get(*list1(), newCallback(dict1())); | |
305 storage_->Get(*list2(), newCallback(emptyDict())); | |
306 storage_->Get(*list123(), newCallback(dict1())); | |
307 | |
308 storage_->Get(newQuittingCallback(dict1())); | |
309 waitForQuit(); | |
310 } | |
311 | |
312 TEST_P(ExtensionSettingsStorageTest, GetWithMultipleValues) { | |
313 storage_->Set(*dict12(), newQuittingCallback(dict12())); | |
314 waitForQuit(); | |
315 | |
316 storage_->Get(key1(), newCallback(dict1())); | |
317 storage_->Get(key3(), newCallback(emptyDict())); | |
318 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
319 storage_->Get(*list1(), newCallback(dict1())); | |
320 storage_->Get(*list13(), newCallback(dict1())); | |
321 storage_->Get(*list12(), newCallback(dict12())); | |
322 storage_->Get(*list123(), newCallback(dict12())); | |
323 | |
324 storage_->Get(newQuittingCallback(dict12())); | |
325 waitForQuit(); | |
326 } | |
327 | |
328 TEST_P(ExtensionSettingsStorageTest, RemoveWhenEmpty) { | |
329 storage_->Remove(key1(), newQuittingCallback(emptyDict())); | |
330 waitForQuit(); | |
331 | |
332 storage_->Get(key1(), newCallback(emptyDict())); | |
333 storage_->Get(*list1(), newCallback(emptyDict())); | |
334 | |
335 storage_->Get(newQuittingCallback(emptyDict())); | |
336 waitForQuit(); | |
337 } | |
338 | |
339 TEST_P(ExtensionSettingsStorageTest, RemoveWithSingleValue) { | |
340 storage_->Set(key1(), *val1(), newQuittingCallback(dict1())); | |
341 waitForQuit(); | |
342 storage_->Remove(key1(), newQuittingCallback(emptyDict())); | |
343 waitForQuit(); | |
344 | |
345 storage_->Get(key1(), newCallback(emptyDict())); | |
346 storage_->Get(key2(), newCallback(emptyDict())); | |
347 storage_->Get(*list1(), newCallback(emptyDict())); | |
348 storage_->Get(*list12(), newCallback(emptyDict())); | |
349 | |
350 storage_->Get(newQuittingCallback(emptyDict())); | |
351 waitForQuit(); | |
352 } | |
353 | |
354 TEST_P(ExtensionSettingsStorageTest, RemoveWithMultipleValues) { | |
355 storage_->Set(*dict123(), newQuittingCallback(dict123())); | |
356 waitForQuit(); | |
357 storage_->Remove(key3(), newQuittingCallback(emptyDict())); | |
358 waitForQuit(); | |
359 | |
360 storage_->Get(key1(), newCallback(dict1())); | |
361 storage_->Get(key3(), newCallback(emptyDict())); | |
362 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
363 storage_->Get(*list1(), newCallback(dict1())); | |
364 storage_->Get(*list13(), newCallback(dict1())); | |
365 storage_->Get(*list12(), newCallback(dict12())); | |
366 storage_->Get(*list123(), newCallback(dict12())); | |
367 storage_->Get(newCallback(dict12())); | |
368 | |
369 storage_->Remove(*list2(), newQuittingCallback(emptyDict())); | |
370 waitForQuit(); | |
371 | |
372 storage_->Get(key1(), newCallback(dict1())); | |
373 storage_->Get(key2(), newCallback(emptyDict())); | |
374 storage_->Get(key3(), newCallback(emptyDict())); | |
375 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
376 storage_->Get(*list1(), newCallback(dict1())); | |
377 storage_->Get(*list2(), newCallback(emptyDict())); | |
378 storage_->Get(*list123(), newCallback(dict1())); | |
379 | |
380 storage_->Get(newQuittingCallback(dict1())); | |
381 waitForQuit(); | |
382 } | |
383 | |
384 TEST_P(ExtensionSettingsStorageTest, SetWhenOverwriting) { | |
385 DictionaryValue key1Val2; | |
386 key1Val2.Set(key1(), val2()->DeepCopy()); | |
387 storage_->Set(key1(), *val2(), newQuittingCallback(&key1Val2)); | |
388 waitForQuit(); | |
389 | |
390 storage_->Set(*dict12(), newQuittingCallback(dict12())); | |
391 waitForQuit(); | |
392 | |
393 storage_->Get(key1(), newCallback(dict1())); | |
394 storage_->Get(key3(), newCallback(emptyDict())); | |
395 storage_->Get(*emptyList(), newCallback(emptyDict())); | |
396 storage_->Get(*list1(), newCallback(dict1())); | |
397 storage_->Get(*list13(), newCallback(dict1())); | |
398 storage_->Get(*list12(), newCallback(dict12())); | |
399 storage_->Get(*list123(), newCallback(dict12())); | |
400 | |
401 storage_->Get(newQuittingCallback(dict12())); | |
402 waitForQuit(); | |
403 } | |
404 | |
405 TEST_P(ExtensionSettingsStorageTest, ClearWhenEmpty) { | |
406 storage_->Clear(newQuittingCallback(emptyDict())); | |
407 waitForQuit(); | |
408 | |
409 storage_->Get(key1(), newCallback(emptyDict())); | |
410 storage_->Get(*list1(), newCallback(emptyDict())); | |
411 | |
412 storage_->Get(newQuittingCallback(emptyDict())); | |
413 waitForQuit(); | |
414 } | |
415 | |
416 TEST_P(ExtensionSettingsStorageTest, ClearWhenNotEmpty) { | |
417 storage_->Set(*dict12(), newQuittingCallback(dict12())); | |
418 waitForQuit(); | |
419 storage_->Clear(newQuittingCallback(emptyDict())); | |
420 waitForQuit(); | |
421 | |
422 storage_->Get(key1(), newCallback(emptyDict())); | |
423 storage_->Get(*list1(), newCallback(emptyDict())); | |
424 | |
425 storage_->Get(newQuittingCallback(emptyDict())); | |
426 waitForQuit(); | |
427 } | |
428 | |
429 #undef newCallback | |
430 #undef newQuittingCallback | |
OLD | NEW |