Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: chrome/browser/extensions/extension_settings_storage_unittest.cc

Issue 7189029: Implement an initial extension settings API. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Add missing files Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698