1 // Copyright (c) 2006-2008 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.
7 #include "base/values.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 class ValuesTest
: public testing::Test
{
13 TEST(ValuesTest
, Basic
) {
14 // Test basic dictionary getting/setting
15 DictionaryValue settings
;
16 std::wstring homepage
= L
"http://google.com";
18 settings
.GetString(L
"global.homepage", &homepage
));
19 ASSERT_EQ(std::wstring(L
"http://google.com"), homepage
);
21 ASSERT_FALSE(settings
.Get(L
"global", NULL
));
22 ASSERT_TRUE(settings
.Set(L
"global", Value::CreateBooleanValue(true)));
23 ASSERT_TRUE(settings
.Get(L
"global", NULL
));
24 ASSERT_TRUE(settings
.SetString(L
"global.homepage", L
"http://scurvy.com"));
25 ASSERT_TRUE(settings
.Get(L
"global", NULL
));
26 homepage
= L
"http://google.com";
27 ASSERT_TRUE(settings
.GetString(L
"global.homepage", &homepage
));
28 ASSERT_EQ(std::wstring(L
"http://scurvy.com"), homepage
);
30 // Test storing a dictionary in a list.
31 ListValue
* toolbar_bookmarks
;
33 settings
.GetList(L
"global.toolbar.bookmarks", &toolbar_bookmarks
));
35 toolbar_bookmarks
= new ListValue
;
36 settings
.Set(L
"global.toolbar.bookmarks", toolbar_bookmarks
);
38 settings
.GetList(L
"global.toolbar.bookmarks", &toolbar_bookmarks
));
40 DictionaryValue
* new_bookmark
= new DictionaryValue
;
41 new_bookmark
->SetString(L
"name", L
"Froogle");
42 new_bookmark
->SetString(L
"url", L
"http://froogle.com");
43 toolbar_bookmarks
->Append(new_bookmark
);
45 ListValue
* bookmark_list
;
46 ASSERT_TRUE(settings
.GetList(L
"global.toolbar.bookmarks", &bookmark_list
));
47 DictionaryValue
* bookmark
;
48 ASSERT_EQ(1U, bookmark_list
->GetSize());
49 ASSERT_TRUE(bookmark_list
->GetDictionary(0, &bookmark
));
50 std::wstring bookmark_name
= L
"Unnamed";
51 ASSERT_TRUE(bookmark
->GetString(L
"name", &bookmark_name
));
52 ASSERT_EQ(std::wstring(L
"Froogle"), bookmark_name
);
53 std::wstring bookmark_url
;
54 ASSERT_TRUE(bookmark
->GetString(L
"url", &bookmark_url
));
55 ASSERT_EQ(std::wstring(L
"http://froogle.com"), bookmark_url
);
58 TEST(ValuesTest
, BinaryValue
) {
60 // Passing a null buffer pointer doesn't yield a BinaryValue
61 BinaryValue
* binary
= BinaryValue::Create(buffer
, 0);
64 // If you want to represent an empty binary value, use a zero-length buffer.
67 binary
= BinaryValue::Create(buffer
, 0);
69 ASSERT_TRUE(binary
->GetBuffer());
70 ASSERT_EQ(buffer
, binary
->GetBuffer());
71 ASSERT_EQ(0U, binary
->GetSize());
75 // Test the common case of a non-empty buffer
76 buffer
= new char[15];
77 binary
= BinaryValue::Create(buffer
, 15);
79 ASSERT_TRUE(binary
->GetBuffer());
80 ASSERT_EQ(buffer
, binary
->GetBuffer());
81 ASSERT_EQ(15U, binary
->GetSize());
85 char stack_buffer
[42];
86 memset(stack_buffer
, '!', 42);
87 binary
= BinaryValue::CreateWithCopiedBuffer(stack_buffer
, 42);
89 ASSERT_TRUE(binary
->GetBuffer());
90 ASSERT_NE(stack_buffer
, binary
->GetBuffer());
91 ASSERT_EQ(42U, binary
->GetSize());
92 ASSERT_EQ(0, memcmp(stack_buffer
, binary
->GetBuffer(), binary
->GetSize()));
96 // This is a Value object that allows us to tell if it's been
97 // properly deleted by modifying the value of external flag on destruction.
98 class DeletionTestValue
: public Value
{
100 DeletionTestValue(bool* deletion_flag
) : Value(TYPE_NULL
) {
101 Init(deletion_flag
); // Separate function so that we can use ASSERT_*
104 void Init(bool* deletion_flag
) {
105 ASSERT_TRUE(deletion_flag
);
106 deletion_flag_
= deletion_flag
;
107 *deletion_flag_
= false;
110 ~DeletionTestValue() {
111 *deletion_flag_
= true;
115 bool* deletion_flag_
;
118 TEST(ValuesTest
, ListDeletion
) {
119 bool deletion_flag
= true;
123 list
.Append(new DeletionTestValue(&deletion_flag
));
124 EXPECT_FALSE(deletion_flag
);
126 EXPECT_TRUE(deletion_flag
);
130 list
.Append(new DeletionTestValue(&deletion_flag
));
131 EXPECT_FALSE(deletion_flag
);
133 EXPECT_TRUE(deletion_flag
);
138 list
.Append(new DeletionTestValue(&deletion_flag
));
139 EXPECT_FALSE(deletion_flag
);
140 EXPECT_TRUE(list
.Set(0, Value::CreateNullValue()));
141 EXPECT_TRUE(deletion_flag
);
145 TEST(ValuesTest
, ListRemoval
) {
146 bool deletion_flag
= true;
147 Value
* removed_item
= NULL
;
151 list
.Append(new DeletionTestValue(&deletion_flag
));
152 EXPECT_FALSE(deletion_flag
);
153 EXPECT_EQ(1U, list
.GetSize());
154 EXPECT_FALSE(list
.Remove(std::numeric_limits
<size_t>::max(),
156 EXPECT_FALSE(list
.Remove(1, &removed_item
));
157 EXPECT_TRUE(list
.Remove(0, &removed_item
));
158 ASSERT_TRUE(removed_item
);
159 EXPECT_EQ(0U, list
.GetSize());
161 EXPECT_FALSE(deletion_flag
);
164 EXPECT_TRUE(deletion_flag
);
168 list
.Append(new DeletionTestValue(&deletion_flag
));
169 EXPECT_FALSE(deletion_flag
);
170 EXPECT_TRUE(list
.Remove(0, NULL
));
171 EXPECT_TRUE(deletion_flag
);
172 EXPECT_EQ(0U, list
.GetSize());
176 TEST(ValuesTest
, DictionaryDeletion
) {
177 std::wstring key
= L
"test";
178 bool deletion_flag
= true;
181 DictionaryValue dict
;
182 dict
.Set(key
, new DeletionTestValue(&deletion_flag
));
183 EXPECT_FALSE(deletion_flag
);
185 EXPECT_TRUE(deletion_flag
);
188 DictionaryValue dict
;
189 dict
.Set(key
, new DeletionTestValue(&deletion_flag
));
190 EXPECT_FALSE(deletion_flag
);
192 EXPECT_TRUE(deletion_flag
);
196 DictionaryValue dict
;
197 dict
.Set(key
, new DeletionTestValue(&deletion_flag
));
198 EXPECT_FALSE(deletion_flag
);
199 dict
.Set(key
, Value::CreateNullValue());
200 EXPECT_TRUE(deletion_flag
);
204 TEST(ValuesTest
, DictionaryRemoval
) {
205 std::wstring key
= L
"test";
206 bool deletion_flag
= true;
207 Value
* removed_item
= NULL
;
210 DictionaryValue dict
;
211 dict
.Set(key
, new DeletionTestValue(&deletion_flag
));
212 EXPECT_FALSE(deletion_flag
);
213 EXPECT_TRUE(dict
.HasKey(key
));
214 EXPECT_FALSE(dict
.Remove(L
"absent key", &removed_item
));
215 EXPECT_TRUE(dict
.Remove(key
, &removed_item
));
216 EXPECT_FALSE(dict
.HasKey(key
));
217 ASSERT_TRUE(removed_item
);
219 EXPECT_FALSE(deletion_flag
);
222 EXPECT_TRUE(deletion_flag
);
225 DictionaryValue dict
;
226 dict
.Set(key
, new DeletionTestValue(&deletion_flag
));
227 EXPECT_FALSE(deletion_flag
);
228 EXPECT_TRUE(dict
.HasKey(key
));
229 EXPECT_TRUE(dict
.Remove(key
, NULL
));
230 EXPECT_TRUE(deletion_flag
);
231 EXPECT_FALSE(dict
.HasKey(key
));
235 TEST(ValuesTest
, DeepCopy
) {
236 DictionaryValue original_dict
;
237 Value
* original_null
= Value::CreateNullValue();
238 original_dict
.Set(L
"null", original_null
);
239 Value
* original_bool
= Value::CreateBooleanValue(true);
240 original_dict
.Set(L
"bool", original_bool
);
241 Value
* original_int
= Value::CreateIntegerValue(42);
242 original_dict
.Set(L
"int", original_int
);
243 Value
* original_real
= Value::CreateRealValue(3.14);
244 original_dict
.Set(L
"real", original_real
);
245 Value
* original_string
= Value::CreateStringValue(L
"peek-a-boo");
246 original_dict
.Set(L
"string", original_string
);
248 char* original_buffer
= new char[42];
249 memset(original_buffer
, '!', 42);
250 BinaryValue
* original_binary
= Value::CreateBinaryValue(original_buffer
, 42);
251 original_dict
.Set(L
"binary", original_binary
);
253 ListValue
* original_list
= new ListValue();
254 Value
* original_list_element_0
= Value::CreateIntegerValue(0);
255 original_list
->Append(original_list_element_0
);
256 Value
* original_list_element_1
= Value::CreateIntegerValue(1);
257 original_list
->Append(original_list_element_1
);
258 original_dict
.Set(L
"list", original_list
);
260 DictionaryValue
* copy_dict
=
261 static_cast<DictionaryValue
*>(original_dict
.DeepCopy());
262 ASSERT_TRUE(copy_dict
);
263 ASSERT_NE(copy_dict
, &original_dict
);
265 Value
* copy_null
= NULL
;
266 ASSERT_TRUE(copy_dict
->Get(L
"null", ©_null
));
267 ASSERT_TRUE(copy_null
);
268 ASSERT_NE(copy_null
, original_null
);
269 ASSERT_TRUE(copy_null
->IsType(Value::TYPE_NULL
));
271 Value
* copy_bool
= NULL
;
272 ASSERT_TRUE(copy_dict
->Get(L
"bool", ©_bool
));
273 ASSERT_TRUE(copy_bool
);
274 ASSERT_NE(copy_bool
, original_bool
);
275 ASSERT_TRUE(copy_bool
->IsType(Value::TYPE_BOOLEAN
));
276 bool copy_bool_value
= false;
277 ASSERT_TRUE(copy_bool
->GetAsBoolean(©_bool_value
));
278 ASSERT_TRUE(copy_bool_value
);
280 Value
* copy_int
= NULL
;
281 ASSERT_TRUE(copy_dict
->Get(L
"int", ©_int
));
282 ASSERT_TRUE(copy_int
);
283 ASSERT_NE(copy_int
, original_int
);
284 ASSERT_TRUE(copy_int
->IsType(Value::TYPE_INTEGER
));
285 int copy_int_value
= 0;
286 ASSERT_TRUE(copy_int
->GetAsInteger(©_int_value
));
287 ASSERT_EQ(42, copy_int_value
);
289 Value
* copy_real
= NULL
;
290 ASSERT_TRUE(copy_dict
->Get(L
"real", ©_real
));
291 ASSERT_TRUE(copy_real
);
292 ASSERT_NE(copy_real
, original_real
);
293 ASSERT_TRUE(copy_real
->IsType(Value::TYPE_REAL
));
294 double copy_real_value
= 0;
295 ASSERT_TRUE(copy_real
->GetAsReal(©_real_value
));
296 ASSERT_EQ(3.14, copy_real_value
);
298 Value
* copy_string
= NULL
;
299 ASSERT_TRUE(copy_dict
->Get(L
"string", ©_string
));
300 ASSERT_TRUE(copy_string
);
301 ASSERT_NE(copy_string
, original_string
);
302 ASSERT_TRUE(copy_string
->IsType(Value::TYPE_STRING
));
303 std::wstring copy_string_value
;
304 ASSERT_TRUE(copy_string
->GetAsString(©_string_value
));
305 ASSERT_EQ(std::wstring(L
"peek-a-boo"), copy_string_value
);
307 Value
* copy_binary
= NULL
;
308 ASSERT_TRUE(copy_dict
->Get(L
"binary", ©_binary
));
309 ASSERT_TRUE(copy_binary
);
310 ASSERT_NE(copy_binary
, original_binary
);
311 ASSERT_TRUE(copy_binary
->IsType(Value::TYPE_BINARY
));
312 ASSERT_NE(original_binary
->GetBuffer(),
313 static_cast<BinaryValue
*>(copy_binary
)->GetBuffer());
314 ASSERT_EQ(original_binary
->GetSize(),
315 static_cast<BinaryValue
*>(copy_binary
)->GetSize());
316 ASSERT_EQ(0, memcmp(original_binary
->GetBuffer(),
317 static_cast<BinaryValue
*>(copy_binary
)->GetBuffer(),
318 original_binary
->GetSize()));
320 Value
* copy_value
= NULL
;
321 ASSERT_TRUE(copy_dict
->Get(L
"list", ©_value
));
322 ASSERT_TRUE(copy_value
);
323 ASSERT_NE(copy_value
, original_list
);
324 ASSERT_TRUE(copy_value
->IsType(Value::TYPE_LIST
));
325 ListValue
* copy_list
= static_cast<ListValue
*>(copy_value
);
326 ASSERT_EQ(2U, copy_list
->GetSize());
328 Value
* copy_list_element_0
;
329 ASSERT_TRUE(copy_list
->Get(0, ©_list_element_0
));
330 ASSERT_TRUE(copy_list_element_0
);
331 ASSERT_NE(copy_list_element_0
, original_list_element_0
);
332 int copy_list_element_0_value
;
333 ASSERT_TRUE(copy_list_element_0
->GetAsInteger(©_list_element_0_value
));
334 ASSERT_EQ(0, copy_list_element_0_value
);
336 Value
* copy_list_element_1
;
337 ASSERT_TRUE(copy_list
->Get(1, ©_list_element_1
));
338 ASSERT_TRUE(copy_list_element_1
);
339 ASSERT_NE(copy_list_element_1
, original_list_element_1
);
340 int copy_list_element_1_value
;
341 ASSERT_TRUE(copy_list_element_1
->GetAsInteger(©_list_element_1_value
));
342 ASSERT_EQ(1, copy_list_element_1_value
);
347 TEST(ValuesTest
, Equals
) {
348 Value
* null1
= Value::CreateNullValue();
349 Value
* null2
= Value::CreateNullValue();
350 EXPECT_NE(null1
, null2
);
351 EXPECT_TRUE(null1
->Equals(null2
));
353 Value
* boolean
= Value::CreateBooleanValue(false);
354 EXPECT_FALSE(null1
->Equals(boolean
));
360 dv
.SetBoolean(L
"a", false);
361 dv
.SetInteger(L
"b", 2);
362 dv
.SetReal(L
"c", 2.5);
363 dv
.SetString(L
"d", L
"string");
364 dv
.Set(L
"e", Value::CreateNullValue());
366 DictionaryValue
* copy
= static_cast<DictionaryValue
*>(dv
.DeepCopy());
367 EXPECT_TRUE(dv
.Equals(copy
));
369 ListValue
* list
= new ListValue
;
370 list
->Append(Value::CreateNullValue());
371 list
->Append(new DictionaryValue
);
374 EXPECT_FALSE(dv
.Equals(copy
));
375 copy
->Set(L
"f", list
->DeepCopy());
376 EXPECT_TRUE(dv
.Equals(copy
));
378 list
->Append(Value::CreateBooleanValue(true));
379 EXPECT_FALSE(dv
.Equals(copy
));