blob: 67515ece3be87a1d3093206981996b507e8a2d6b [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
deanm@google.com19650de2008-08-13 23:57:51 +09005#include <limits>
6
initial.commit3f4a7322008-07-27 06:49:38 +09007#include "base/values.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10class ValuesTest: public testing::Test {
11};
12
13TEST(ValuesTest, Basic) {
14 // Test basic dictionary getting/setting
15 DictionaryValue settings;
16 std::wstring homepage = L"http://google.com";
17 ASSERT_FALSE(
18 settings.GetString(L"global.homepage", &homepage));
19 ASSERT_EQ(std::wstring(L"http://google.com"), homepage);
20
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);
29
30 // Test storing a dictionary in a list.
31 ListValue* toolbar_bookmarks;
32 ASSERT_FALSE(
33 settings.GetList(L"global.toolbar.bookmarks", &toolbar_bookmarks));
34
35 toolbar_bookmarks = new ListValue;
36 settings.Set(L"global.toolbar.bookmarks", toolbar_bookmarks);
37 ASSERT_TRUE(
38 settings.GetList(L"global.toolbar.bookmarks", &toolbar_bookmarks));
39
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);
44
45 ListValue* bookmark_list;
46 ASSERT_TRUE(settings.GetList(L"global.toolbar.bookmarks", &bookmark_list));
47 DictionaryValue* bookmark;
mmentovai@google.com691ecef2008-08-22 01:24:51 +090048 ASSERT_EQ(1U, bookmark_list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +090049 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);
56}
57
58TEST(ValuesTest, BinaryValue) {
59 char* buffer = NULL;
60 // Passing a null buffer pointer doesn't yield a BinaryValue
61 BinaryValue* binary = BinaryValue::Create(buffer, 0);
62 ASSERT_FALSE(binary);
63
64 // If you want to represent an empty binary value, use a zero-length buffer.
evanm@google.com32f2c512008-08-13 11:39:51 +090065 buffer = new char[1];
initial.commit3f4a7322008-07-27 06:49:38 +090066 ASSERT_TRUE(buffer);
67 binary = BinaryValue::Create(buffer, 0);
68 ASSERT_TRUE(binary);
69 ASSERT_TRUE(binary->GetBuffer());
70 ASSERT_EQ(buffer, binary->GetBuffer());
mmentovai@google.com691ecef2008-08-22 01:24:51 +090071 ASSERT_EQ(0U, binary->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +090072 delete binary;
73 binary = NULL;
74
75 // Test the common case of a non-empty buffer
76 buffer = new char[15];
77 binary = BinaryValue::Create(buffer, 15);
78 ASSERT_TRUE(binary);
79 ASSERT_TRUE(binary->GetBuffer());
80 ASSERT_EQ(buffer, binary->GetBuffer());
mmentovai@google.com691ecef2008-08-22 01:24:51 +090081 ASSERT_EQ(15U, binary->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +090082 delete binary;
83 binary = NULL;
84
85 char stack_buffer[42];
86 memset(stack_buffer, '!', 42);
87 binary = BinaryValue::CreateWithCopiedBuffer(stack_buffer, 42);
88 ASSERT_TRUE(binary);
89 ASSERT_TRUE(binary->GetBuffer());
90 ASSERT_NE(stack_buffer, binary->GetBuffer());
mmentovai@google.com691ecef2008-08-22 01:24:51 +090091 ASSERT_EQ(42U, binary->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +090092 ASSERT_EQ(0, memcmp(stack_buffer, binary->GetBuffer(), binary->GetSize()));
93 delete binary;
94}
95
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.
98class DeletionTestValue : public Value {
99public:
100 DeletionTestValue(bool* deletion_flag) : Value(TYPE_NULL) {
101 Init(deletion_flag); // Separate function so that we can use ASSERT_*
102 }
103
104 void Init(bool* deletion_flag) {
105 ASSERT_TRUE(deletion_flag);
106 deletion_flag_ = deletion_flag;
107 *deletion_flag_ = false;
108 }
109
110 ~DeletionTestValue() {
111 *deletion_flag_ = true;
112 }
113
114private:
115 bool* deletion_flag_;
116};
117
118TEST(ValuesTest, ListDeletion) {
119 bool deletion_flag = true;
120
121 {
122 ListValue list;
123 list.Append(new DeletionTestValue(&deletion_flag));
124 EXPECT_FALSE(deletion_flag);
125 }
126 EXPECT_TRUE(deletion_flag);
127
128 {
129 ListValue list;
130 list.Append(new DeletionTestValue(&deletion_flag));
131 EXPECT_FALSE(deletion_flag);
132 list.Clear();
133 EXPECT_TRUE(deletion_flag);
134 }
135
136 {
137 ListValue list;
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);
142 }
143}
144
145TEST(ValuesTest, ListRemoval) {
146 bool deletion_flag = true;
147 Value* removed_item = NULL;
148
149 {
150 ListValue list;
151 list.Append(new DeletionTestValue(&deletion_flag));
152 EXPECT_FALSE(deletion_flag);
mmentovai@google.com691ecef2008-08-22 01:24:51 +0900153 EXPECT_EQ(1U, list.GetSize());
deanm@google.com19650de2008-08-13 23:57:51 +0900154 EXPECT_FALSE(list.Remove(std::numeric_limits<size_t>::max(),
155 &removed_item));
initial.commit3f4a7322008-07-27 06:49:38 +0900156 EXPECT_FALSE(list.Remove(1, &removed_item));
157 EXPECT_TRUE(list.Remove(0, &removed_item));
158 ASSERT_TRUE(removed_item);
mmentovai@google.com691ecef2008-08-22 01:24:51 +0900159 EXPECT_EQ(0U, list.GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900160 }
161 EXPECT_FALSE(deletion_flag);
162 delete removed_item;
163 removed_item = NULL;
164 EXPECT_TRUE(deletion_flag);
165
166 {
167 ListValue list;
168 list.Append(new DeletionTestValue(&deletion_flag));
169 EXPECT_FALSE(deletion_flag);
170 EXPECT_TRUE(list.Remove(0, NULL));
171 EXPECT_TRUE(deletion_flag);
mmentovai@google.com691ecef2008-08-22 01:24:51 +0900172 EXPECT_EQ(0U, list.GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900173 }
174}
175
176TEST(ValuesTest, DictionaryDeletion) {
177 std::wstring key = L"test";
178 bool deletion_flag = true;
179
180 {
181 DictionaryValue dict;
182 dict.Set(key, new DeletionTestValue(&deletion_flag));
183 EXPECT_FALSE(deletion_flag);
184 }
185 EXPECT_TRUE(deletion_flag);
186
187 {
188 DictionaryValue dict;
189 dict.Set(key, new DeletionTestValue(&deletion_flag));
190 EXPECT_FALSE(deletion_flag);
191 dict.Clear();
192 EXPECT_TRUE(deletion_flag);
193 }
194
195 {
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);
201 }
202}
203
204TEST(ValuesTest, DictionaryRemoval) {
205 std::wstring key = L"test";
206 bool deletion_flag = true;
207 Value* removed_item = NULL;
208
209 {
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);
218 }
219 EXPECT_FALSE(deletion_flag);
220 delete removed_item;
221 removed_item = NULL;
222 EXPECT_TRUE(deletion_flag);
223
224 {
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));
232 }
233}
234
235TEST(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);
247
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);
252
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);
259
260 DictionaryValue* copy_dict =
261 static_cast<DictionaryValue*>(original_dict.DeepCopy());
262 ASSERT_TRUE(copy_dict);
263 ASSERT_NE(copy_dict, &original_dict);
264
265 Value* copy_null = NULL;
266 ASSERT_TRUE(copy_dict->Get(L"null", &copy_null));
267 ASSERT_TRUE(copy_null);
268 ASSERT_NE(copy_null, original_null);
269 ASSERT_TRUE(copy_null->IsType(Value::TYPE_NULL));
270
271 Value* copy_bool = NULL;
272 ASSERT_TRUE(copy_dict->Get(L"bool", &copy_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(&copy_bool_value));
278 ASSERT_TRUE(copy_bool_value);
279
280 Value* copy_int = NULL;
281 ASSERT_TRUE(copy_dict->Get(L"int", &copy_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(&copy_int_value));
287 ASSERT_EQ(42, copy_int_value);
288
289 Value* copy_real = NULL;
290 ASSERT_TRUE(copy_dict->Get(L"real", &copy_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(&copy_real_value));
296 ASSERT_EQ(3.14, copy_real_value);
297
298 Value* copy_string = NULL;
299 ASSERT_TRUE(copy_dict->Get(L"string", &copy_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(&copy_string_value));
305 ASSERT_EQ(std::wstring(L"peek-a-boo"), copy_string_value);
306
307 Value* copy_binary = NULL;
308 ASSERT_TRUE(copy_dict->Get(L"binary", &copy_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()));
319
320 Value* copy_value = NULL;
321 ASSERT_TRUE(copy_dict->Get(L"list", &copy_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);
mmentovai@google.com691ecef2008-08-22 01:24:51 +0900326 ASSERT_EQ(2U, copy_list->GetSize());
initial.commit3f4a7322008-07-27 06:49:38 +0900327
328 Value* copy_list_element_0;
329 ASSERT_TRUE(copy_list->Get(0, &copy_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(&copy_list_element_0_value));
334 ASSERT_EQ(0, copy_list_element_0_value);
335
336 Value* copy_list_element_1;
337 ASSERT_TRUE(copy_list->Get(1, &copy_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(&copy_list_element_1_value));
342 ASSERT_EQ(1, copy_list_element_1_value);
343
344 delete copy_dict;
345}
346
347TEST(ValuesTest, Equals) {
348 Value* null1 = Value::CreateNullValue();
349 Value* null2 = Value::CreateNullValue();
350 EXPECT_NE(null1, null2);
351 EXPECT_TRUE(null1->Equals(null2));
352
353 Value* boolean = Value::CreateBooleanValue(false);
354 EXPECT_FALSE(null1->Equals(boolean));
355 delete null1;
356 delete null2;
357 delete boolean;
358
359 DictionaryValue dv;
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());
365
366 DictionaryValue* copy = static_cast<DictionaryValue*>(dv.DeepCopy());
367 EXPECT_TRUE(dv.Equals(copy));
368
369 ListValue* list = new ListValue;
370 list->Append(Value::CreateNullValue());
371 list->Append(new DictionaryValue);
372 dv.Set(L"f", list);
373
374 EXPECT_FALSE(dv.Equals(copy));
375 copy->Set(L"f", list->DeepCopy());
376 EXPECT_TRUE(dv.Equals(copy));
377
378 list->Append(Value::CreateBooleanValue(true));
379 EXPECT_FALSE(dv.Equals(copy));
380 delete copy;
381}
license.botf003cfe2008-08-24 09:55:55 +0900382