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