Commit | Line | Data |
---|---|---|
dac5c838 PP |
1 | /* |
2 | * test_bt_values.c | |
3 | * | |
705b853d | 4 | * Babeltrace value objects tests |
dac5c838 PP |
5 | * |
6 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation | |
7 | * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; under version 2 of the License. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License along | |
19 | * with this program; if not, write to the Free Software Foundation, Inc., | |
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
22 | ||
9d408fca | 23 | #include <babeltrace/ref.h> |
dac5c838 PP |
24 | #include <babeltrace/values.h> |
25 | #include <assert.h> | |
26 | #include <string.h> | |
27 | #include "tap/tap.h" | |
28 | ||
b6ba7620 | 29 | #define NR_TESTS 249 |
8bbe269d | 30 | |
dac5c838 PP |
31 | static |
32 | void test_null(void) | |
33 | { | |
34 | ok(bt_value_null, "bt_value_null is not NULL"); | |
35 | ok(bt_value_is_null(bt_value_null), | |
36 | "bt_value_null is a null value object"); | |
83509119 | 37 | bt_get(bt_value_null); |
dac5c838 | 38 | pass("getting bt_value_null does not cause a crash"); |
83509119 | 39 | bt_put(bt_value_null); |
dac5c838 PP |
40 | pass("putting bt_value_null does not cause a crash"); |
41 | ||
83509119 | 42 | bt_get(NULL); |
dac5c838 | 43 | pass("getting NULL does not cause a crash"); |
83509119 | 44 | bt_put(NULL); |
dac5c838 PP |
45 | pass("putting NULL does not cause a crash"); |
46 | ||
47 | ok(bt_value_get_type(NULL) == BT_VALUE_TYPE_UNKNOWN, | |
48 | "bt_value_get_type(NULL) returns BT_VALUE_TYPE_UNKNOWN"); | |
49 | } | |
50 | ||
51 | static | |
52 | void test_bool(void) | |
53 | { | |
54 | int ret; | |
c55a9f58 | 55 | bt_bool value; |
dac5c838 PP |
56 | struct bt_value *obj; |
57 | ||
58 | obj = bt_value_bool_create(); | |
59 | ok(obj && bt_value_is_bool(obj), | |
60 | "bt_value_bool_create() returns a boolean value object"); | |
61 | ||
c55a9f58 | 62 | value = BT_TRUE; |
dac5c838 | 63 | ret = bt_value_bool_get(obj, &value); |
c55a9f58 | 64 | ok(!ret && !value, "default boolean value object value is BT_FALSE"); |
dac5c838 | 65 | |
c55a9f58 | 66 | ret = bt_value_bool_set(NULL, BT_TRUE); |
dac5c838 PP |
67 | ok(ret == BT_VALUE_STATUS_INVAL, |
68 | "bt_value_bool_set() fails with an value object set to NULL"); | |
69 | ret = bt_value_bool_get(NULL, &value); | |
70 | ok(ret == BT_VALUE_STATUS_INVAL, | |
71 | "bt_value_bool_get() fails with an value object set to NULL"); | |
72 | ret = bt_value_bool_get(obj, NULL); | |
73 | ok(ret == BT_VALUE_STATUS_INVAL, | |
74 | "bt_value_bool_get() fails with a return value set to NULL"); | |
75 | ||
c55a9f58 PP |
76 | assert(!bt_value_bool_set(obj, BT_FALSE)); |
77 | ret = bt_value_bool_set(obj, BT_TRUE); | |
dac5c838 PP |
78 | ok(!ret, "bt_value_bool_set() succeeds"); |
79 | ret = bt_value_bool_get(obj, &value); | |
80 | ok(!ret && value, "bt_value_bool_set() works"); | |
81 | ||
83509119 | 82 | BT_PUT(obj); |
dac5c838 PP |
83 | pass("putting an existing boolean value object does not cause a crash") |
84 | ||
c55a9f58 PP |
85 | value = BT_FALSE; |
86 | obj = bt_value_bool_create_init(BT_TRUE); | |
dac5c838 PP |
87 | ok(obj && bt_value_is_bool(obj), |
88 | "bt_value_bool_create_init() returns a boolean value object"); | |
89 | ret = bt_value_bool_get(obj, &value); | |
90 | ok(!ret && value, | |
91 | "bt_value_bool_create_init() sets the appropriate initial value"); | |
92 | ||
93 | assert(!bt_value_freeze(obj)); | |
c55a9f58 | 94 | ok(bt_value_bool_set(obj, BT_FALSE) == BT_VALUE_STATUS_FROZEN, |
dac5c838 | 95 | "bt_value_bool_set() cannot be called on a frozen boolean value object"); |
c55a9f58 | 96 | value = BT_FALSE; |
dac5c838 PP |
97 | ret = bt_value_bool_get(obj, &value); |
98 | ok(!ret && value, | |
99 | "bt_value_bool_set() does not alter a frozen floating point number value object"); | |
100 | ||
83509119 | 101 | BT_PUT(obj); |
dac5c838 PP |
102 | } |
103 | ||
104 | static | |
105 | void test_integer(void) | |
106 | { | |
107 | int ret; | |
108 | int64_t value; | |
109 | struct bt_value *obj; | |
110 | ||
111 | obj = bt_value_integer_create(); | |
112 | ok(obj && bt_value_is_integer(obj), | |
113 | "bt_value_integer_create() returns an integer value object"); | |
114 | ||
115 | ret = bt_value_integer_set(NULL, -12345); | |
116 | ok(ret == BT_VALUE_STATUS_INVAL, | |
117 | "bt_value_integer_set() fails with an value object set to NULL"); | |
118 | ret = bt_value_integer_get(NULL, &value); | |
119 | ok(ret == BT_VALUE_STATUS_INVAL, | |
120 | "bt_value_integer_get() fails with an value object set to NULL"); | |
121 | ret = bt_value_integer_get(obj, NULL); | |
122 | ok(ret == BT_VALUE_STATUS_INVAL, | |
123 | "bt_value_integer_get() fails with a return value set to NULL"); | |
124 | ||
125 | value = 1961; | |
126 | ret = bt_value_integer_get(obj, &value); | |
127 | ok(!ret && value == 0, "default integer value object value is 0"); | |
128 | ||
129 | ret = bt_value_integer_set(obj, -98765); | |
130 | ok(!ret, "bt_value_integer_set() succeeds"); | |
131 | ret = bt_value_integer_get(obj, &value); | |
132 | ok(!ret && value == -98765, "bt_value_integer_set() works"); | |
133 | ||
83509119 | 134 | BT_PUT(obj); |
dac5c838 PP |
135 | pass("putting an existing integer value object does not cause a crash") |
136 | ||
137 | obj = bt_value_integer_create_init(321456987); | |
138 | ok(obj && bt_value_is_integer(obj), | |
139 | "bt_value_integer_create_init() returns an integer value object"); | |
140 | ret = bt_value_integer_get(obj, &value); | |
141 | ok(!ret && value == 321456987, | |
142 | "bt_value_integer_create_init() sets the appropriate initial value"); | |
143 | ||
144 | assert(!bt_value_freeze(obj)); | |
145 | ok(bt_value_integer_set(obj, 18276) == BT_VALUE_STATUS_FROZEN, | |
146 | "bt_value_integer_set() cannot be called on a frozen integer value object"); | |
147 | value = 17; | |
148 | ret = bt_value_integer_get(obj, &value); | |
149 | ok(!ret && value == 321456987, | |
150 | "bt_value_integer_set() does not alter a frozen integer value object"); | |
151 | ||
83509119 | 152 | BT_PUT(obj); |
dac5c838 PP |
153 | } |
154 | ||
155 | static | |
156 | void test_float(void) | |
157 | { | |
158 | int ret; | |
159 | double value; | |
160 | struct bt_value *obj; | |
161 | ||
162 | obj = bt_value_float_create(); | |
163 | ok(obj && bt_value_is_float(obj), | |
164 | "bt_value_float_create() returns a floating point number value object"); | |
165 | ||
166 | ret = bt_value_float_set(NULL, 1.2345); | |
167 | ok(ret == BT_VALUE_STATUS_INVAL, | |
168 | "bt_value_float_set() fails with an value object set to NULL"); | |
169 | ret = bt_value_float_get(NULL, &value); | |
170 | ok(ret == BT_VALUE_STATUS_INVAL, | |
171 | "bt_value_float_get() fails with an value object set to NULL"); | |
172 | ret = bt_value_float_get(obj, NULL); | |
173 | ok(ret == BT_VALUE_STATUS_INVAL, | |
174 | "bt_value_float_get() fails with a return value set to NULL"); | |
175 | ||
176 | value = 17.34; | |
177 | ret = bt_value_float_get(obj, &value); | |
178 | ok(!ret && value == 0., | |
179 | "default floating point number value object value is 0"); | |
180 | ||
181 | ret = bt_value_float_set(obj, -3.1416); | |
182 | ok(!ret, "bt_value_float_set() succeeds"); | |
183 | ret = bt_value_float_get(obj, &value); | |
184 | ok(!ret && value == -3.1416, "bt_value_float_set() works"); | |
185 | ||
83509119 | 186 | BT_PUT(obj); |
dac5c838 PP |
187 | pass("putting an existing floating point number value object does not cause a crash") |
188 | ||
189 | obj = bt_value_float_create_init(33.1649758); | |
190 | ok(obj && bt_value_is_float(obj), | |
191 | "bt_value_float_create_init() returns a floating point number value object"); | |
192 | ret = bt_value_float_get(obj, &value); | |
193 | ok(!ret && value == 33.1649758, | |
194 | "bt_value_float_create_init() sets the appropriate initial value"); | |
195 | ||
196 | assert(!bt_value_freeze(obj)); | |
197 | ok(bt_value_float_set(obj, 17.88) == BT_VALUE_STATUS_FROZEN, | |
198 | "bt_value_float_set() fails with a frozen floating point number value object"); | |
199 | value = 1.2; | |
200 | ret = bt_value_float_get(obj, &value); | |
201 | ok(!ret && value == 33.1649758, | |
202 | "bt_value_float_set() does not alter a frozen floating point number value object"); | |
203 | ||
83509119 | 204 | BT_PUT(obj); |
dac5c838 PP |
205 | } |
206 | ||
207 | static | |
208 | void test_string(void) | |
209 | { | |
210 | int ret; | |
211 | const char *value; | |
212 | struct bt_value *obj; | |
213 | ||
214 | obj = bt_value_string_create(); | |
215 | ok(obj && bt_value_is_string(obj), | |
216 | "bt_value_string_create() returns a string value object"); | |
217 | ||
218 | ret = bt_value_string_set(NULL, "hoho"); | |
219 | ok(ret == BT_VALUE_STATUS_INVAL, | |
220 | "bt_value_string_set() fails with an value object set to NULL"); | |
221 | ret = bt_value_string_set(obj, NULL); | |
222 | ok(ret == BT_VALUE_STATUS_INVAL, | |
223 | "bt_value_string_set() fails with a value set to NULL"); | |
224 | ret = bt_value_string_get(NULL, &value); | |
225 | ok(ret == BT_VALUE_STATUS_INVAL, | |
226 | "bt_value_string_get() fails with an value object set to NULL"); | |
227 | ret = bt_value_string_get(obj, NULL); | |
228 | ok(ret == BT_VALUE_STATUS_INVAL, | |
229 | "bt_value_string_get() fails with a return value set to NULL"); | |
230 | ||
231 | ret = bt_value_string_get(obj, &value); | |
232 | ok(!ret && value && !strcmp(value, ""), | |
233 | "default string value object value is \"\""); | |
234 | ||
235 | ret = bt_value_string_set(obj, "hello worldz"); | |
236 | ok(!ret, "bt_value_string_set() succeeds"); | |
237 | ret = bt_value_string_get(obj, &value); | |
238 | ok(!ret && value && !strcmp(value, "hello worldz"), | |
239 | "bt_value_string_get() works"); | |
240 | ||
83509119 | 241 | BT_PUT(obj); |
dac5c838 PP |
242 | pass("putting an existing string value object does not cause a crash") |
243 | ||
244 | obj = bt_value_string_create_init(NULL); | |
245 | ok(!obj, "bt_value_string_create_init() fails with an initial value set to NULL"); | |
246 | obj = bt_value_string_create_init("initial value"); | |
247 | ok(obj && bt_value_is_string(obj), | |
248 | "bt_value_string_create_init() returns a string value object"); | |
249 | ret = bt_value_string_get(obj, &value); | |
250 | ok(!ret && value && !strcmp(value, "initial value"), | |
251 | "bt_value_string_create_init() sets the appropriate initial value"); | |
252 | ||
253 | assert(!bt_value_freeze(obj)); | |
254 | ok(bt_value_string_set(obj, "new value") == BT_VALUE_STATUS_FROZEN, | |
255 | "bt_value_string_set() fails with a frozen string value object"); | |
256 | value = ""; | |
257 | ret = bt_value_string_get(obj, &value); | |
258 | ok(!ret && value && !strcmp(value, "initial value"), | |
259 | "bt_value_string_set() does not alter a frozen string value object"); | |
260 | ||
83509119 | 261 | BT_PUT(obj); |
dac5c838 PP |
262 | } |
263 | ||
264 | static | |
265 | void test_array(void) | |
266 | { | |
267 | int ret; | |
c55a9f58 | 268 | bt_bool bool_value; |
dac5c838 PP |
269 | int64_t int_value; |
270 | double float_value; | |
271 | struct bt_value *obj; | |
272 | const char *string_value; | |
273 | struct bt_value *array_obj; | |
274 | ||
275 | array_obj = bt_value_array_create(); | |
276 | ok(array_obj && bt_value_is_array(array_obj), | |
277 | "bt_value_array_create() returns an array value object"); | |
c55a9f58 PP |
278 | ok(bt_value_array_is_empty(NULL) == BT_FALSE, |
279 | "bt_value_array_is_empty() returns BT_FALSE with an value object set to NULL"); | |
dac5c838 PP |
280 | ok(bt_value_array_is_empty(array_obj), |
281 | "initial array value object size is 0"); | |
282 | ok(bt_value_array_size(NULL) == BT_VALUE_STATUS_INVAL, | |
283 | "bt_value_array_size() fails with an array value object set to NULL"); | |
284 | ||
285 | ok(bt_value_array_append(NULL, bt_value_null) | |
286 | == BT_VALUE_STATUS_INVAL, | |
287 | "bt_value_array_append() fails with an array value object set to NULL"); | |
288 | ok(bt_value_array_append(array_obj, NULL) == BT_VALUE_STATUS_INVAL, | |
289 | "bt_value_array_append() fails with a value set to NULL"); | |
290 | ||
291 | obj = bt_value_integer_create_init(345); | |
292 | ret = bt_value_array_append(array_obj, obj); | |
83509119 | 293 | BT_PUT(obj); |
dac5c838 PP |
294 | obj = bt_value_float_create_init(-17.45); |
295 | ret |= bt_value_array_append(array_obj, obj); | |
83509119 | 296 | BT_PUT(obj); |
c55a9f58 | 297 | obj = bt_value_bool_create_init(BT_TRUE); |
dac5c838 | 298 | ret |= bt_value_array_append(array_obj, obj); |
83509119 | 299 | BT_PUT(obj); |
dac5c838 PP |
300 | ret |= bt_value_array_append(array_obj, bt_value_null); |
301 | ok(!ret, "bt_value_array_append() succeeds"); | |
302 | ok(bt_value_array_size(array_obj) == 4, | |
303 | "appending an element to an array value object increment its size"); | |
304 | ||
305 | obj = bt_value_array_get(array_obj, 4); | |
306 | ok(!obj, "getting an array value object's element at an index equal to its size fails"); | |
307 | obj = bt_value_array_get(array_obj, 5); | |
308 | ok(!obj, "getting an array value object's element at a larger index fails"); | |
309 | ||
310 | obj = bt_value_array_get(NULL, 2); | |
311 | ok(!obj, "bt_value_array_get() fails with an array value object set to NULL"); | |
312 | ||
313 | obj = bt_value_array_get(array_obj, 0); | |
314 | ok(obj && bt_value_is_integer(obj), | |
315 | "bt_value_array_get() returns an value object with the appropriate type (integer)"); | |
316 | ret = bt_value_integer_get(obj, &int_value); | |
317 | ok(!ret && int_value == 345, | |
318 | "bt_value_array_get() returns an value object with the appropriate value (integer)"); | |
83509119 | 319 | BT_PUT(obj); |
dac5c838 PP |
320 | obj = bt_value_array_get(array_obj, 1); |
321 | ok(obj && bt_value_is_float(obj), | |
322 | "bt_value_array_get() returns an value object with the appropriate type (floating point number)"); | |
323 | ret = bt_value_float_get(obj, &float_value); | |
324 | ok(!ret && float_value == -17.45, | |
325 | "bt_value_array_get() returns an value object with the appropriate value (floating point number)"); | |
83509119 | 326 | BT_PUT(obj); |
dac5c838 PP |
327 | obj = bt_value_array_get(array_obj, 2); |
328 | ok(obj && bt_value_is_bool(obj), | |
329 | "bt_value_array_get() returns an value object with the appropriate type (boolean)"); | |
330 | ret = bt_value_bool_get(obj, &bool_value); | |
331 | ok(!ret && bool_value, | |
332 | "bt_value_array_get() returns an value object with the appropriate value (boolean)"); | |
83509119 | 333 | BT_PUT(obj); |
dac5c838 PP |
334 | obj = bt_value_array_get(array_obj, 3); |
335 | ok(obj == bt_value_null, | |
336 | "bt_value_array_get() returns an value object with the appropriate type (null)"); | |
337 | ||
338 | ok(bt_value_array_set(NULL, 0, bt_value_null) == | |
339 | BT_VALUE_STATUS_INVAL, | |
340 | "bt_value_array_set() fails with an array value object set to NULL"); | |
341 | ok(bt_value_array_set(array_obj, 0, NULL) == BT_VALUE_STATUS_INVAL, | |
342 | "bt_value_array_set() fails with an element value object set to NULL"); | |
343 | ok(bt_value_array_set(array_obj, 4, bt_value_null) == | |
344 | BT_VALUE_STATUS_INVAL, | |
345 | "bt_value_array_set() fails with an invalid index"); | |
346 | obj = bt_value_integer_create_init(1001); | |
347 | assert(obj); | |
348 | ok(!bt_value_array_set(array_obj, 2, obj), | |
349 | "bt_value_array_set() succeeds"); | |
83509119 | 350 | BT_PUT(obj); |
dac5c838 PP |
351 | obj = bt_value_array_get(array_obj, 2); |
352 | ok(obj && bt_value_is_integer(obj), | |
353 | "bt_value_array_set() inserts an value object with the appropriate type"); | |
354 | ret = bt_value_integer_get(obj, &int_value); | |
355 | assert(!ret); | |
356 | ok(int_value == 1001, | |
357 | "bt_value_array_set() inserts an value object with the appropriate value"); | |
83509119 | 358 | BT_PUT(obj); |
dac5c838 | 359 | |
c55a9f58 | 360 | ret = bt_value_array_append_bool(array_obj, BT_FALSE); |
dac5c838 | 361 | ok(!ret, "bt_value_array_append_bool() succeeds"); |
c55a9f58 | 362 | ok(bt_value_array_append_bool(NULL, BT_TRUE) == BT_VALUE_STATUS_INVAL, |
dac5c838 PP |
363 | "bt_value_array_append_bool() fails with an array value object set to NULL"); |
364 | ret = bt_value_array_append_integer(array_obj, 98765); | |
365 | ok(!ret, "bt_value_array_append_integer() succeeds"); | |
366 | ok(bt_value_array_append_integer(NULL, 18765) == | |
367 | BT_VALUE_STATUS_INVAL, | |
368 | "bt_value_array_append_integer() fails with an array value object set to NULL"); | |
369 | ret = bt_value_array_append_float(array_obj, 2.49578); | |
370 | ok(!ret, "bt_value_array_append_float() succeeds"); | |
371 | ok(bt_value_array_append_float(NULL, 1.49578) == | |
372 | BT_VALUE_STATUS_INVAL, | |
373 | "bt_value_array_append_float() fails with an array value object set to NULL"); | |
374 | ret = bt_value_array_append_string(array_obj, "bt_value"); | |
375 | ok(!ret, "bt_value_array_append_string() succeeds"); | |
376 | ok(bt_value_array_append_string(NULL, "bt_obj") == | |
377 | BT_VALUE_STATUS_INVAL, | |
378 | "bt_value_array_append_string() fails with an array value object set to NULL"); | |
5b79e8bf PP |
379 | ret = bt_value_array_append_empty_array(array_obj); |
380 | ok(!ret, "bt_value_array_append_empty_array() succeeds"); | |
381 | ok(bt_value_array_append_empty_array(NULL) == BT_VALUE_STATUS_INVAL, | |
382 | "bt_value_array_append_empty_array() fails with an array value object set to NULL"); | |
383 | ret = bt_value_array_append_empty_map(array_obj); | |
384 | ok(!ret, "bt_value_array_append_empty_map() succeeds"); | |
385 | ok(bt_value_array_append_empty_map(NULL) == BT_VALUE_STATUS_INVAL, | |
386 | "bt_value_array_append_empty_map() fails with an array value object set to NULL"); | |
dac5c838 PP |
387 | |
388 | ok(bt_value_array_size(array_obj) == 10, | |
389 | "the bt_value_array_append_*() functions increment the array value object's size"); | |
390 | ok(!bt_value_array_is_empty(array_obj), | |
391 | "map value object is not empty"); | |
392 | ||
393 | obj = bt_value_array_get(array_obj, 4); | |
394 | ok(obj && bt_value_is_bool(obj), | |
395 | "bt_value_array_append_bool() appends a boolean value object"); | |
396 | ret = bt_value_bool_get(obj, &bool_value); | |
397 | ok(!ret && !bool_value, | |
398 | "bt_value_array_append_bool() appends the appropriate value"); | |
83509119 | 399 | BT_PUT(obj); |
dac5c838 PP |
400 | obj = bt_value_array_get(array_obj, 5); |
401 | ok(obj && bt_value_is_integer(obj), | |
402 | "bt_value_array_append_integer() appends an integer value object"); | |
403 | ret = bt_value_integer_get(obj, &int_value); | |
404 | ok(!ret && int_value == 98765, | |
405 | "bt_value_array_append_integer() appends the appropriate value"); | |
83509119 | 406 | BT_PUT(obj); |
dac5c838 PP |
407 | obj = bt_value_array_get(array_obj, 6); |
408 | ok(obj && bt_value_is_float(obj), | |
409 | "bt_value_array_append_float() appends a floating point number value object"); | |
410 | ret = bt_value_float_get(obj, &float_value); | |
411 | ok(!ret && float_value == 2.49578, | |
412 | "bt_value_array_append_float() appends the appropriate value"); | |
83509119 | 413 | BT_PUT(obj); |
dac5c838 PP |
414 | obj = bt_value_array_get(array_obj, 7); |
415 | ok(obj && bt_value_is_string(obj), | |
416 | "bt_value_array_append_string() appends a string value object"); | |
417 | ret = bt_value_string_get(obj, &string_value); | |
418 | ok(!ret && string_value && !strcmp(string_value, "bt_value"), | |
419 | "bt_value_array_append_string() appends the appropriate value"); | |
83509119 | 420 | BT_PUT(obj); |
dac5c838 PP |
421 | obj = bt_value_array_get(array_obj, 8); |
422 | ok(obj && bt_value_is_array(obj), | |
5b79e8bf | 423 | "bt_value_array_append_empty_array() appends an array value object"); |
dac5c838 | 424 | ok(bt_value_array_is_empty(obj), |
5b79e8bf | 425 | "bt_value_array_append_empty_array() an empty array value object"); |
83509119 | 426 | BT_PUT(obj); |
dac5c838 PP |
427 | obj = bt_value_array_get(array_obj, 9); |
428 | ok(obj && bt_value_is_map(obj), | |
5b79e8bf | 429 | "bt_value_array_append_empty_map() appends a map value object"); |
dac5c838 | 430 | ok(bt_value_map_is_empty(obj), |
5b79e8bf | 431 | "bt_value_array_append_empty_map() an empty map value object"); |
83509119 | 432 | BT_PUT(obj); |
dac5c838 PP |
433 | |
434 | assert(!bt_value_freeze(array_obj)); | |
435 | ok(bt_value_array_append(array_obj, bt_value_null) == | |
436 | BT_VALUE_STATUS_FROZEN, | |
437 | "bt_value_array_append() fails with a frozen array value object"); | |
c55a9f58 | 438 | ok(bt_value_array_append_bool(array_obj, BT_FALSE) == |
dac5c838 PP |
439 | BT_VALUE_STATUS_FROZEN, |
440 | "bt_value_array_append_bool() fails with a frozen array value object"); | |
441 | ok(bt_value_array_append_integer(array_obj, 23) == | |
442 | BT_VALUE_STATUS_FROZEN, | |
443 | "bt_value_array_append_integer() fails with a frozen array value object"); | |
444 | ok(bt_value_array_append_float(array_obj, 2.34) == | |
445 | BT_VALUE_STATUS_FROZEN, | |
446 | "bt_value_array_append_float() fails with a frozen array value object"); | |
447 | ok(bt_value_array_append_string(array_obj, "yayayayaya") == | |
448 | BT_VALUE_STATUS_FROZEN, | |
449 | "bt_value_array_append_string() fails with a frozen array value object"); | |
5b79e8bf | 450 | ok(bt_value_array_append_empty_array(array_obj) == |
dac5c838 | 451 | BT_VALUE_STATUS_FROZEN, |
5b79e8bf PP |
452 | "bt_value_array_append_empty_array() fails with a frozen array value object"); |
453 | ok(bt_value_array_append_empty_map(array_obj) == | |
dac5c838 | 454 | BT_VALUE_STATUS_FROZEN, |
5b79e8bf | 455 | "bt_value_array_append_empty_map() fails with a frozen array value object"); |
dac5c838 PP |
456 | ok(bt_value_array_set(array_obj, 2, bt_value_null) == |
457 | BT_VALUE_STATUS_FROZEN, | |
458 | "bt_value_array_set() fails with a frozen array value object"); | |
459 | ok(bt_value_array_size(array_obj) == 10, | |
460 | "appending to a frozen array value object does not change its size"); | |
461 | ||
462 | obj = bt_value_array_get(array_obj, 1); | |
463 | assert(obj); | |
464 | ok(bt_value_float_set(obj, 14.52) == BT_VALUE_STATUS_FROZEN, | |
465 | "freezing an array value object also freezes its elements"); | |
83509119 | 466 | BT_PUT(obj); |
dac5c838 | 467 | |
83509119 | 468 | BT_PUT(array_obj); |
dac5c838 PP |
469 | pass("putting an existing array value object does not cause a crash") |
470 | } | |
471 | ||
472 | static | |
c55a9f58 | 473 | bt_bool test_map_foreach_cb_count(const char *key, struct bt_value *object, |
dac5c838 PP |
474 | void *data) |
475 | { | |
476 | int *count = data; | |
477 | ||
478 | if (*count == 3) { | |
c55a9f58 | 479 | return BT_FALSE; |
dac5c838 PP |
480 | } |
481 | ||
482 | (*count)++; | |
483 | ||
c55a9f58 | 484 | return BT_TRUE; |
dac5c838 PP |
485 | } |
486 | ||
487 | struct map_foreach_checklist { | |
c55a9f58 PP |
488 | bt_bool bool1; |
489 | bt_bool int1; | |
490 | bt_bool float1; | |
491 | bt_bool null1; | |
492 | bt_bool bool2; | |
493 | bt_bool int2; | |
494 | bt_bool float2; | |
495 | bt_bool string2; | |
496 | bt_bool array2; | |
497 | bt_bool map2; | |
dac5c838 PP |
498 | }; |
499 | ||
500 | static | |
c55a9f58 | 501 | bt_bool test_map_foreach_cb_check(const char *key, struct bt_value *object, |
dac5c838 PP |
502 | void *data) |
503 | { | |
504 | int ret; | |
505 | struct map_foreach_checklist *checklist = data; | |
506 | ||
c55a9f58 | 507 | if (!strcmp(key, "bt_bool")) { |
dac5c838 | 508 | if (checklist->bool1) { |
c55a9f58 | 509 | fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\""); |
dac5c838 | 510 | } else { |
c55a9f58 | 511 | bt_bool val = BT_FALSE; |
dac5c838 PP |
512 | |
513 | ret = bt_value_bool_get(object, &val); | |
c55a9f58 | 514 | ok(!ret, "test_map_foreach_cb_check(): success getting \"bt_bool\" value"); |
dac5c838 PP |
515 | |
516 | if (val) { | |
c55a9f58 PP |
517 | pass("test_map_foreach_cb_check(): \"bt_bool\" value object has the right value"); |
518 | checklist->bool1 = BT_TRUE; | |
dac5c838 | 519 | } else { |
c55a9f58 | 520 | fail("test_map_foreach_cb_check(): \"bt_bool\" value object has the wrong value"); |
dac5c838 PP |
521 | } |
522 | } | |
523 | } else if (!strcmp(key, "int")) { | |
524 | if (checklist->int1) { | |
525 | fail("test_map_foreach_cb_check(): duplicate key \"int\""); | |
526 | } else { | |
527 | int64_t val = 0; | |
528 | ||
529 | ret = bt_value_integer_get(object, &val); | |
530 | ok(!ret, "test_map_foreach_cb_check(): success getting \"int\" value"); | |
531 | ||
532 | if (val == 19457) { | |
533 | pass("test_map_foreach_cb_check(): \"int\" value object has the right value"); | |
c55a9f58 | 534 | checklist->int1 = BT_TRUE; |
dac5c838 PP |
535 | } else { |
536 | fail("test_map_foreach_cb_check(): \"int\" value object has the wrong value"); | |
537 | } | |
538 | } | |
539 | } else if (!strcmp(key, "float")) { | |
540 | if (checklist->float1) { | |
541 | fail("test_map_foreach_cb_check(): duplicate key \"float\""); | |
542 | } else { | |
543 | double val = 0; | |
544 | ||
545 | ret = bt_value_float_get(object, &val); | |
546 | ok(!ret, "test_map_foreach_cb_check(): success getting \"float\" value"); | |
547 | ||
548 | if (val == 5.444) { | |
549 | pass("test_map_foreach_cb_check(): \"float\" value object has the right value"); | |
c55a9f58 | 550 | checklist->float1 = BT_TRUE; |
dac5c838 PP |
551 | } else { |
552 | fail("test_map_foreach_cb_check(): \"float\" value object has the wrong value"); | |
553 | } | |
554 | } | |
555 | } else if (!strcmp(key, "null")) { | |
556 | if (checklist->null1) { | |
c55a9f58 | 557 | fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\""); |
dac5c838 PP |
558 | } else { |
559 | ok(bt_value_is_null(object), "test_map_foreach_cb_check(): success getting \"null\" value object"); | |
c55a9f58 | 560 | checklist->null1 = BT_TRUE; |
dac5c838 PP |
561 | } |
562 | } else if (!strcmp(key, "bool2")) { | |
563 | if (checklist->bool2) { | |
564 | fail("test_map_foreach_cb_check(): duplicate key \"bool2\""); | |
565 | } else { | |
c55a9f58 | 566 | bt_bool val = BT_FALSE; |
dac5c838 PP |
567 | |
568 | ret = bt_value_bool_get(object, &val); | |
569 | ok(!ret, "test_map_foreach_cb_check(): success getting \"bool2\" value"); | |
570 | ||
571 | if (val) { | |
572 | pass("test_map_foreach_cb_check(): \"bool2\" value object has the right value"); | |
c55a9f58 | 573 | checklist->bool2 = BT_TRUE; |
dac5c838 PP |
574 | } else { |
575 | fail("test_map_foreach_cb_check(): \"bool2\" value object has the wrong value"); | |
576 | } | |
577 | } | |
578 | } else if (!strcmp(key, "int2")) { | |
579 | if (checklist->int2) { | |
580 | fail("test_map_foreach_cb_check(): duplicate key \"int2\""); | |
581 | } else { | |
582 | int64_t val = 0; | |
583 | ||
584 | ret = bt_value_integer_get(object, &val); | |
585 | ok(!ret, "test_map_foreach_cb_check(): success getting \"int2\" value"); | |
586 | ||
587 | if (val == 98765) { | |
588 | pass("test_map_foreach_cb_check(): \"int2\" value object has the right value"); | |
c55a9f58 | 589 | checklist->int2 = BT_TRUE; |
dac5c838 PP |
590 | } else { |
591 | fail("test_map_foreach_cb_check(): \"int2\" value object has the wrong value"); | |
592 | } | |
593 | } | |
594 | } else if (!strcmp(key, "float2")) { | |
595 | if (checklist->float2) { | |
596 | fail("test_map_foreach_cb_check(): duplicate key \"float2\""); | |
597 | } else { | |
598 | double val = 0; | |
599 | ||
600 | ret = bt_value_float_get(object, &val); | |
601 | ok(!ret, "test_map_foreach_cb_check(): success getting \"float2\" value"); | |
602 | ||
603 | if (val == -49.0001) { | |
604 | pass("test_map_foreach_cb_check(): \"float2\" value object has the right value"); | |
c55a9f58 | 605 | checklist->float2 = BT_TRUE; |
dac5c838 PP |
606 | } else { |
607 | fail("test_map_foreach_cb_check(): \"float2\" value object has the wrong value"); | |
608 | } | |
609 | } | |
610 | } else if (!strcmp(key, "string2")) { | |
611 | if (checklist->string2) { | |
612 | fail("test_map_foreach_cb_check(): duplicate key \"string2\""); | |
613 | } else { | |
614 | const char *val; | |
615 | ||
616 | ret = bt_value_string_get(object, &val); | |
617 | ok(!ret, "test_map_foreach_cb_check(): success getting \"string2\" value"); | |
618 | ||
619 | if (val && !strcmp(val, "bt_value")) { | |
620 | pass("test_map_foreach_cb_check(): \"string2\" value object has the right value"); | |
c55a9f58 | 621 | checklist->string2 = BT_TRUE; |
dac5c838 PP |
622 | } else { |
623 | fail("test_map_foreach_cb_check(): \"string2\" value object has the wrong value"); | |
624 | } | |
625 | } | |
626 | } else if (!strcmp(key, "array2")) { | |
627 | if (checklist->array2) { | |
628 | fail("test_map_foreach_cb_check(): duplicate key \"array2\""); | |
629 | } else { | |
630 | ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array2\" value object"); | |
631 | ok(bt_value_array_is_empty(object), | |
632 | "test_map_foreach_cb_check(): \"array2\" value object is empty"); | |
c55a9f58 | 633 | checklist->array2 = BT_TRUE; |
dac5c838 PP |
634 | } |
635 | } else if (!strcmp(key, "map2")) { | |
636 | if (checklist->map2) { | |
637 | fail("test_map_foreach_cb_check(): duplicate key \"map2\""); | |
638 | } else { | |
639 | ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map2\" value object"); | |
640 | ok(bt_value_map_is_empty(object), | |
641 | "test_map_foreach_cb_check(): \"map2\" value object is empty"); | |
c55a9f58 | 642 | checklist->map2 = BT_TRUE; |
dac5c838 PP |
643 | } |
644 | } else { | |
645 | fail("test_map_foreach_cb_check(): unknown map key \"%s\"", key); | |
646 | } | |
647 | ||
c55a9f58 | 648 | return BT_TRUE; |
dac5c838 PP |
649 | } |
650 | ||
651 | static | |
652 | void test_map(void) | |
653 | { | |
654 | int ret; | |
655 | int count = 0; | |
c55a9f58 | 656 | bt_bool bool_value; |
dac5c838 PP |
657 | int64_t int_value; |
658 | double float_value; | |
659 | struct bt_value *obj; | |
660 | struct bt_value *map_obj; | |
661 | struct map_foreach_checklist checklist; | |
662 | ||
663 | map_obj = bt_value_map_create(); | |
664 | ok(map_obj && bt_value_is_map(map_obj), | |
665 | "bt_value_map_create() returns a map value object"); | |
666 | ok(bt_value_map_size(map_obj) == 0, | |
667 | "initial map value object size is 0"); | |
668 | ok(bt_value_map_size(NULL) == BT_VALUE_STATUS_INVAL, | |
669 | "bt_value_map_size() fails with a map value object set to NULL"); | |
670 | ||
671 | ok(bt_value_map_insert(NULL, "hello", bt_value_null) == | |
672 | BT_VALUE_STATUS_INVAL, | |
673 | "bt_value_array_insert() fails with a map value object set to NULL"); | |
674 | ok(bt_value_map_insert(map_obj, NULL, bt_value_null) == | |
675 | BT_VALUE_STATUS_INVAL, | |
676 | "bt_value_array_insert() fails with a key set to NULL"); | |
677 | ok(bt_value_map_insert(map_obj, "yeah", NULL) == | |
678 | BT_VALUE_STATUS_INVAL, | |
679 | "bt_value_array_insert() fails with an element value object set to NULL"); | |
680 | ||
681 | obj = bt_value_integer_create_init(19457); | |
682 | ret = bt_value_map_insert(map_obj, "int", obj); | |
83509119 | 683 | BT_PUT(obj); |
dac5c838 PP |
684 | obj = bt_value_float_create_init(5.444); |
685 | ret |= bt_value_map_insert(map_obj, "float", obj); | |
83509119 | 686 | BT_PUT(obj); |
dac5c838 | 687 | obj = bt_value_bool_create(); |
c55a9f58 | 688 | ret |= bt_value_map_insert(map_obj, "bt_bool", obj); |
83509119 | 689 | BT_PUT(obj); |
dac5c838 PP |
690 | ret |= bt_value_map_insert(map_obj, "null", bt_value_null); |
691 | ok(!ret, "bt_value_map_insert() succeeds"); | |
692 | ok(bt_value_map_size(map_obj) == 4, | |
693 | "inserting an element into a map value object increment its size"); | |
694 | ||
c55a9f58 PP |
695 | obj = bt_value_bool_create_init(BT_TRUE); |
696 | ret = bt_value_map_insert(map_obj, "bt_bool", obj); | |
83509119 | 697 | BT_PUT(obj); |
dac5c838 PP |
698 | ok(!ret, "bt_value_map_insert() accepts an existing key"); |
699 | ||
700 | obj = bt_value_map_get(map_obj, NULL); | |
701 | ok(!obj, "bt_value_map_get() fails with a key set to NULL"); | |
c55a9f58 | 702 | obj = bt_value_map_get(NULL, "bt_bool"); |
dac5c838 PP |
703 | ok(!obj, "bt_value_map_get() fails with a map value object set to NULL"); |
704 | ||
705 | obj = bt_value_map_get(map_obj, "life"); | |
706 | ok(!obj, "bt_value_map_get() fails with an non existing key"); | |
707 | obj = bt_value_map_get(map_obj, "float"); | |
708 | ok(obj && bt_value_is_float(obj), | |
709 | "bt_value_map_get() returns an value object with the appropriate type (float)"); | |
710 | ret = bt_value_float_get(obj, &float_value); | |
711 | ok(!ret && float_value == 5.444, | |
712 | "bt_value_map_get() returns an value object with the appropriate value (float)"); | |
83509119 | 713 | BT_PUT(obj); |
dac5c838 PP |
714 | obj = bt_value_map_get(map_obj, "int"); |
715 | ok(obj && bt_value_is_integer(obj), | |
716 | "bt_value_map_get() returns an value object with the appropriate type (integer)"); | |
717 | ret = bt_value_integer_get(obj, &int_value); | |
718 | ok(!ret && int_value == 19457, | |
719 | "bt_value_map_get() returns an value object with the appropriate value (integer)"); | |
83509119 | 720 | BT_PUT(obj); |
dac5c838 PP |
721 | obj = bt_value_map_get(map_obj, "null"); |
722 | ok(obj && bt_value_is_null(obj), | |
723 | "bt_value_map_get() returns an value object with the appropriate type (null)"); | |
c55a9f58 | 724 | obj = bt_value_map_get(map_obj, "bt_bool"); |
dac5c838 PP |
725 | ok(obj && bt_value_is_bool(obj), |
726 | "bt_value_map_get() returns an value object with the appropriate type (boolean)"); | |
727 | ret = bt_value_bool_get(obj, &bool_value); | |
728 | ok(!ret && bool_value, | |
729 | "bt_value_map_get() returns an value object with the appropriate value (boolean)"); | |
83509119 | 730 | BT_PUT(obj); |
dac5c838 | 731 | |
c55a9f58 | 732 | ret = bt_value_map_insert_bool(map_obj, "bool2", BT_TRUE); |
dac5c838 | 733 | ok(!ret, "bt_value_map_insert_bool() succeeds"); |
c55a9f58 | 734 | ok(bt_value_map_insert_bool(NULL, "bool2", BT_FALSE) == |
dac5c838 PP |
735 | BT_VALUE_STATUS_INVAL, |
736 | "bt_value_map_insert_bool() fails with a map value object set to NULL"); | |
737 | ret = bt_value_map_insert_integer(map_obj, "int2", 98765); | |
738 | ok(!ret, "bt_value_map_insert_integer() succeeds"); | |
739 | ok(bt_value_map_insert_integer(NULL, "int2", 1001) == | |
740 | BT_VALUE_STATUS_INVAL, | |
741 | "bt_value_map_insert_integer() fails with a map value object set to NULL"); | |
742 | ret = bt_value_map_insert_float(map_obj, "float2", -49.0001); | |
743 | ok(!ret, "bt_value_map_insert_float() succeeds"); | |
744 | ok(bt_value_map_insert_float(NULL, "float2", 495) == | |
745 | BT_VALUE_STATUS_INVAL, | |
746 | "bt_value_map_insert_float() fails with a map value object set to NULL"); | |
747 | ret = bt_value_map_insert_string(map_obj, "string2", "bt_value"); | |
748 | ok(!ret, "bt_value_map_insert_string() succeeds"); | |
749 | ok(bt_value_map_insert_string(NULL, "string2", "bt_obj") == | |
750 | BT_VALUE_STATUS_INVAL, | |
751 | "bt_value_map_insert_string() fails with a map value object set to NULL"); | |
5b79e8bf PP |
752 | ret = bt_value_map_insert_empty_array(map_obj, "array2"); |
753 | ok(!ret, "bt_value_map_insert_empty_array() succeeds"); | |
754 | ok(bt_value_map_insert_empty_array(NULL, "array2") == BT_VALUE_STATUS_INVAL, | |
755 | "bt_value_map_insert_empty_array() fails with a map value object set to NULL"); | |
756 | ret = bt_value_map_insert_empty_map(map_obj, "map2"); | |
757 | ok(!ret, "bt_value_map_insert_empty_map() succeeds"); | |
758 | ok(bt_value_map_insert_empty_map(NULL, "map2") == BT_VALUE_STATUS_INVAL, | |
759 | "bt_value_map_insert_empty_map() fails with a map value object set to NULL"); | |
dac5c838 PP |
760 | |
761 | ok(bt_value_map_size(map_obj) == 10, | |
762 | "the bt_value_map_insert*() functions increment the map value object's size"); | |
763 | ||
764 | ok(!bt_value_map_has_key(map_obj, "hello"), | |
765 | "map value object does not have key \"hello\""); | |
c55a9f58 PP |
766 | ok(bt_value_map_has_key(map_obj, "bt_bool"), |
767 | "map value object has key \"bt_bool\""); | |
dac5c838 PP |
768 | ok(bt_value_map_has_key(map_obj, "int"), |
769 | "map value object has key \"int\""); | |
770 | ok(bt_value_map_has_key(map_obj, "float"), | |
771 | "map value object has key \"float\""); | |
772 | ok(bt_value_map_has_key(map_obj, "null"), | |
773 | "map value object has key \"null\""); | |
774 | ok(bt_value_map_has_key(map_obj, "bool2"), | |
775 | "map value object has key \"bool2\""); | |
776 | ok(bt_value_map_has_key(map_obj, "int2"), | |
777 | "map value object has key \"int2\""); | |
778 | ok(bt_value_map_has_key(map_obj, "float2"), | |
779 | "map value object has key \"float2\""); | |
780 | ok(bt_value_map_has_key(map_obj, "string2"), | |
781 | "map value object has key \"string2\""); | |
782 | ok(bt_value_map_has_key(map_obj, "array2"), | |
783 | "map value object has key \"array2\""); | |
784 | ok(bt_value_map_has_key(map_obj, "map2"), | |
785 | "map value object has key \"map2\""); | |
786 | ||
787 | ok(bt_value_map_foreach(NULL, test_map_foreach_cb_count, &count) == | |
788 | BT_VALUE_STATUS_INVAL, | |
789 | "bt_value_map_foreach() fails with a map value object set to NULL"); | |
790 | ok(bt_value_map_foreach(map_obj, NULL, &count) == | |
791 | BT_VALUE_STATUS_INVAL, | |
792 | "bt_value_map_foreach() fails with a user function set to NULL"); | |
793 | ret = bt_value_map_foreach(map_obj, test_map_foreach_cb_count, &count); | |
794 | ok(ret == BT_VALUE_STATUS_CANCELLED && count == 3, | |
c55a9f58 | 795 | "bt_value_map_foreach() breaks the loop when the user function returns BT_FALSE"); |
dac5c838 PP |
796 | |
797 | memset(&checklist, 0, sizeof(checklist)); | |
798 | ret = bt_value_map_foreach(map_obj, test_map_foreach_cb_check, | |
799 | &checklist); | |
800 | ok(ret == BT_VALUE_STATUS_OK, | |
801 | "bt_value_map_foreach() succeeds with test_map_foreach_cb_check()"); | |
802 | ok(checklist.bool1 && checklist.int1 && checklist.float1 && | |
803 | checklist.null1 && checklist.bool2 && checklist.int2 && | |
804 | checklist.float2 && checklist.string2 && | |
805 | checklist.array2 && checklist.map2, | |
806 | "bt_value_map_foreach() iterates over all the map value object's elements"); | |
807 | ||
808 | assert(!bt_value_freeze(map_obj)); | |
809 | ok(bt_value_map_insert(map_obj, "allo", bt_value_null) == | |
810 | BT_VALUE_STATUS_FROZEN, | |
811 | "bt_value_map_insert() fails with a frozen map value object"); | |
c55a9f58 | 812 | ok(bt_value_map_insert_bool(map_obj, "duh", BT_FALSE) == |
dac5c838 PP |
813 | BT_VALUE_STATUS_FROZEN, |
814 | "bt_value_map_insert_bool() fails with a frozen array value object"); | |
815 | ok(bt_value_map_insert_integer(map_obj, "duh", 23) == | |
816 | BT_VALUE_STATUS_FROZEN, | |
817 | "bt_value_map_insert_integer() fails with a frozen array value object"); | |
818 | ok(bt_value_map_insert_float(map_obj, "duh", 2.34) == | |
819 | BT_VALUE_STATUS_FROZEN, | |
820 | "bt_value_map_insert_float() fails with a frozen array value object"); | |
821 | ok(bt_value_map_insert_string(map_obj, "duh", "yayayayaya") == | |
822 | BT_VALUE_STATUS_FROZEN, | |
823 | "bt_value_map_insert_string() fails with a frozen array value object"); | |
5b79e8bf | 824 | ok(bt_value_map_insert_empty_array(map_obj, "duh") == |
dac5c838 | 825 | BT_VALUE_STATUS_FROZEN, |
5b79e8bf PP |
826 | "bt_value_map_insert_empty_array() fails with a frozen array value object"); |
827 | ok(bt_value_map_insert_empty_map(map_obj, "duh") == | |
dac5c838 | 828 | BT_VALUE_STATUS_FROZEN, |
5b79e8bf | 829 | "bt_value_map_insert_empty_map() fails with a frozen array value object"); |
dac5c838 PP |
830 | ok(bt_value_map_size(map_obj) == 10, |
831 | "appending to a frozen map value object does not change its size"); | |
832 | ||
83509119 | 833 | BT_PUT(map_obj); |
dac5c838 PP |
834 | pass("putting an existing map value object does not cause a crash") |
835 | } | |
836 | ||
837 | static | |
838 | void test_types(void) | |
839 | { | |
840 | test_null(); | |
841 | test_bool(); | |
842 | test_integer(); | |
843 | test_float(); | |
844 | test_string(); | |
845 | test_array(); | |
846 | test_map(); | |
847 | } | |
848 | ||
849 | static | |
850 | void test_compare_null(void) | |
851 | { | |
852 | ok(!bt_value_compare(bt_value_null, NULL), | |
853 | "cannot compare null value object and NULL"); | |
854 | ok(!bt_value_compare(NULL, bt_value_null), | |
855 | "cannot compare NULL and null value object"); | |
856 | ok(bt_value_compare(bt_value_null, bt_value_null), | |
857 | "null value objects are equivalent"); | |
858 | } | |
859 | ||
860 | static | |
861 | void test_compare_bool(void) | |
862 | { | |
c55a9f58 PP |
863 | struct bt_value *bool1 = bt_value_bool_create_init(BT_FALSE); |
864 | struct bt_value *bool2 = bt_value_bool_create_init(BT_TRUE); | |
865 | struct bt_value *bool3 = bt_value_bool_create_init(BT_FALSE); | |
dac5c838 PP |
866 | |
867 | assert(bool1 && bool2 && bool3); | |
868 | ok(!bt_value_compare(bt_value_null, bool1), | |
c55a9f58 | 869 | "cannot compare null value object and bt_bool value object"); |
dac5c838 | 870 | ok(!bt_value_compare(bool1, bool2), |
c55a9f58 | 871 | "boolean value objects are not equivalent (BT_FALSE and BT_TRUE)"); |
dac5c838 | 872 | ok(bt_value_compare(bool1, bool3), |
c55a9f58 | 873 | "boolean value objects are equivalent (BT_FALSE and BT_FALSE)"); |
dac5c838 | 874 | |
83509119 JG |
875 | BT_PUT(bool1); |
876 | BT_PUT(bool2); | |
877 | BT_PUT(bool3); | |
dac5c838 PP |
878 | } |
879 | ||
880 | static | |
881 | void test_compare_integer(void) | |
882 | { | |
883 | struct bt_value *int1 = bt_value_integer_create_init(10); | |
884 | struct bt_value *int2 = bt_value_integer_create_init(-23); | |
885 | struct bt_value *int3 = bt_value_integer_create_init(10); | |
886 | ||
887 | assert(int1 && int2 && int3); | |
888 | ok(!bt_value_compare(bt_value_null, int1), | |
889 | "cannot compare null value object and integer value object"); | |
890 | ok(!bt_value_compare(int1, int2), | |
891 | "integer value objects are not equivalent (10 and -23)"); | |
892 | ok(bt_value_compare(int1, int3), | |
893 | "integer value objects are equivalent (10 and 10)"); | |
894 | ||
83509119 JG |
895 | BT_PUT(int1); |
896 | BT_PUT(int2); | |
897 | BT_PUT(int3); | |
dac5c838 PP |
898 | } |
899 | ||
900 | static | |
901 | void test_compare_float(void) | |
902 | { | |
903 | struct bt_value *float1 = bt_value_float_create_init(17.38); | |
904 | struct bt_value *float2 = bt_value_float_create_init(-14.23); | |
905 | struct bt_value *float3 = bt_value_float_create_init(17.38); | |
906 | ||
907 | assert(float1 && float2 && float3); | |
908 | ||
909 | ok(!bt_value_compare(bt_value_null, float1), | |
910 | "cannot compare null value object and floating point number value object"); | |
911 | ok(!bt_value_compare(float1, float2), | |
912 | "floating point number value objects are not equivalent (17.38 and -14.23)"); | |
913 | ok(bt_value_compare(float1, float3), | |
914 | "floating point number value objects are equivalent (17.38 and 17.38)"); | |
915 | ||
83509119 JG |
916 | BT_PUT(float1); |
917 | BT_PUT(float2); | |
918 | BT_PUT(float3); | |
dac5c838 PP |
919 | } |
920 | ||
921 | static | |
922 | void test_compare_string(void) | |
923 | { | |
924 | struct bt_value *string1 = bt_value_string_create_init("hello"); | |
925 | struct bt_value *string2 = bt_value_string_create_init("bt_value"); | |
926 | struct bt_value *string3 = bt_value_string_create_init("hello"); | |
927 | ||
928 | assert(string1 && string2 && string3); | |
929 | ||
930 | ok(!bt_value_compare(bt_value_null, string1), | |
931 | "cannot compare null value object and string value object"); | |
932 | ok(!bt_value_compare(string1, string2), | |
933 | "string value objects are not equivalent (\"hello\" and \"bt_value\")"); | |
934 | ok(bt_value_compare(string1, string3), | |
935 | "string value objects are equivalent (\"hello\" and \"hello\")"); | |
936 | ||
83509119 JG |
937 | BT_PUT(string1); |
938 | BT_PUT(string2); | |
939 | BT_PUT(string3); | |
dac5c838 PP |
940 | } |
941 | ||
942 | static | |
943 | void test_compare_array(void) | |
944 | { | |
945 | struct bt_value *array1 = bt_value_array_create(); | |
946 | struct bt_value *array2 = bt_value_array_create(); | |
947 | struct bt_value *array3 = bt_value_array_create(); | |
948 | ||
949 | assert(array1 && array2 && array3); | |
950 | ||
951 | ok(bt_value_compare(array1, array2), | |
952 | "empty array value objects are equivalent"); | |
953 | ||
954 | assert(!bt_value_array_append_integer(array1, 23)); | |
955 | assert(!bt_value_array_append_float(array1, 14.2)); | |
c55a9f58 | 956 | assert(!bt_value_array_append_bool(array1, BT_FALSE)); |
dac5c838 PP |
957 | assert(!bt_value_array_append_float(array2, 14.2)); |
958 | assert(!bt_value_array_append_integer(array2, 23)); | |
c55a9f58 | 959 | assert(!bt_value_array_append_bool(array2, BT_FALSE)); |
dac5c838 PP |
960 | assert(!bt_value_array_append_integer(array3, 23)); |
961 | assert(!bt_value_array_append_float(array3, 14.2)); | |
c55a9f58 | 962 | assert(!bt_value_array_append_bool(array3, BT_FALSE)); |
dac5c838 PP |
963 | assert(bt_value_array_size(array1) == 3); |
964 | assert(bt_value_array_size(array2) == 3); | |
965 | assert(bt_value_array_size(array3) == 3); | |
966 | ||
967 | ok(!bt_value_compare(bt_value_null, array1), | |
968 | "cannot compare null value object and array value object"); | |
969 | ok(!bt_value_compare(array1, array2), | |
c55a9f58 | 970 | "array value objects are not equivalent ([23, 14.2, BT_FALSE] and [14.2, 23, BT_FALSE])"); |
dac5c838 | 971 | ok(bt_value_compare(array1, array3), |
c55a9f58 | 972 | "array value objects are equivalent ([23, 14.2, BT_FALSE] and [23, 14.2, BT_FALSE])"); |
dac5c838 | 973 | |
83509119 JG |
974 | BT_PUT(array1); |
975 | BT_PUT(array2); | |
976 | BT_PUT(array3); | |
dac5c838 PP |
977 | } |
978 | ||
979 | static | |
980 | void test_compare_map(void) | |
981 | { | |
982 | struct bt_value *map1 = bt_value_map_create(); | |
983 | struct bt_value *map2 = bt_value_map_create(); | |
984 | struct bt_value *map3 = bt_value_map_create(); | |
985 | ||
986 | assert(map1 && map2 && map3); | |
987 | ||
988 | ok(bt_value_compare(map1, map2), | |
989 | "empty map value objects are equivalent"); | |
990 | ||
991 | assert(!bt_value_map_insert_integer(map1, "one", 23)); | |
992 | assert(!bt_value_map_insert_float(map1, "two", 14.2)); | |
c55a9f58 | 993 | assert(!bt_value_map_insert_bool(map1, "three", BT_FALSE)); |
dac5c838 PP |
994 | assert(!bt_value_map_insert_float(map2, "one", 14.2)); |
995 | assert(!bt_value_map_insert_integer(map2, "two", 23)); | |
c55a9f58 PP |
996 | assert(!bt_value_map_insert_bool(map2, "three", BT_FALSE)); |
997 | assert(!bt_value_map_insert_bool(map3, "three", BT_FALSE)); | |
dac5c838 PP |
998 | assert(!bt_value_map_insert_integer(map3, "one", 23)); |
999 | assert(!bt_value_map_insert_float(map3, "two", 14.2)); | |
1000 | assert(bt_value_map_size(map1) == 3); | |
1001 | assert(bt_value_map_size(map2) == 3); | |
1002 | assert(bt_value_map_size(map3) == 3); | |
1003 | ||
1004 | ok(!bt_value_compare(bt_value_null, map1), | |
1005 | "cannot compare null value object and map value object"); | |
1006 | ok(!bt_value_compare(map1, map2), | |
1007 | "map value objects are not equivalent"); | |
1008 | ok(bt_value_compare(map1, map3), | |
1009 | "map value objects are equivalent"); | |
1010 | ||
83509119 JG |
1011 | BT_PUT(map1); |
1012 | BT_PUT(map2); | |
1013 | BT_PUT(map3); | |
dac5c838 PP |
1014 | } |
1015 | ||
1016 | static | |
1017 | void test_compare(void) | |
1018 | { | |
1019 | ok(!bt_value_compare(NULL, NULL), "cannot compare NULL and NULL"); | |
1020 | test_compare_null(); | |
1021 | test_compare_bool(); | |
1022 | test_compare_integer(); | |
1023 | test_compare_float(); | |
1024 | test_compare_string(); | |
1025 | test_compare_array(); | |
1026 | test_compare_map(); | |
1027 | } | |
1028 | ||
1029 | static | |
1030 | void test_copy(void) | |
1031 | { | |
1032 | /* | |
1033 | * Here's the deal here. If we make sure that each value object | |
1034 | * of our deep copy has a different address than its source, | |
c55a9f58 | 1035 | * and that bt_value_compare() returns BT_TRUE for the top-level |
dac5c838 PP |
1036 | * value object, taking into account that we test the correctness of |
1037 | * bt_value_compare() elsewhere, then the deep copy is a | |
1038 | * success. | |
1039 | */ | |
1040 | struct bt_value *null_copy_obj; | |
1041 | struct bt_value *bool_obj, *bool_copy_obj; | |
1042 | struct bt_value *integer_obj, *integer_copy_obj; | |
1043 | struct bt_value *float_obj, *float_copy_obj; | |
1044 | struct bt_value *string_obj, *string_copy_obj; | |
1045 | struct bt_value *array_obj, *array_copy_obj; | |
1046 | struct bt_value *map_obj, *map_copy_obj; | |
1047 | ||
c55a9f58 | 1048 | bool_obj = bt_value_bool_create_init(BT_TRUE); |
dac5c838 PP |
1049 | integer_obj = bt_value_integer_create_init(23); |
1050 | float_obj = bt_value_float_create_init(-3.1416); | |
1051 | string_obj = bt_value_string_create_init("test"); | |
1052 | array_obj = bt_value_array_create(); | |
1053 | map_obj = bt_value_map_create(); | |
1054 | ||
1055 | assert(bool_obj && integer_obj && float_obj && string_obj && | |
1056 | array_obj && map_obj); | |
1057 | ||
1058 | assert(!bt_value_array_append(array_obj, bool_obj)); | |
1059 | assert(!bt_value_array_append(array_obj, integer_obj)); | |
1060 | assert(!bt_value_array_append(array_obj, float_obj)); | |
1061 | assert(!bt_value_array_append(array_obj, bt_value_null)); | |
1062 | assert(!bt_value_map_insert(map_obj, "array", array_obj)); | |
1063 | assert(!bt_value_map_insert(map_obj, "string", string_obj)); | |
1064 | ||
1065 | map_copy_obj = bt_value_copy(NULL); | |
1066 | ok(!map_copy_obj, | |
1067 | "bt_value_copy() fails with a source value object set to NULL"); | |
1068 | ||
1069 | map_copy_obj = bt_value_copy(map_obj); | |
1070 | ok(map_copy_obj, | |
1071 | "bt_value_copy() succeeds"); | |
1072 | ||
1073 | ok(map_obj != map_copy_obj, | |
1074 | "bt_value_copy() returns a different pointer (map)"); | |
1075 | string_copy_obj = bt_value_map_get(map_copy_obj, "string"); | |
1076 | ok(string_copy_obj != string_obj, | |
1077 | "bt_value_copy() returns a different pointer (string)"); | |
1078 | array_copy_obj = bt_value_map_get(map_copy_obj, "array"); | |
1079 | ok(array_copy_obj != array_obj, | |
1080 | "bt_value_copy() returns a different pointer (array)"); | |
1081 | bool_copy_obj = bt_value_array_get(array_copy_obj, 0); | |
1082 | ok(bool_copy_obj != bool_obj, | |
c55a9f58 | 1083 | "bt_value_copy() returns a different pointer (bt_bool)"); |
dac5c838 PP |
1084 | integer_copy_obj = bt_value_array_get(array_copy_obj, 1); |
1085 | ok(integer_copy_obj != integer_obj, | |
1086 | "bt_value_copy() returns a different pointer (integer)"); | |
1087 | float_copy_obj = bt_value_array_get(array_copy_obj, 2); | |
1088 | ok(float_copy_obj != float_obj, | |
1089 | "bt_value_copy() returns a different pointer (float)"); | |
1090 | null_copy_obj = bt_value_array_get(array_copy_obj, 3); | |
1091 | ok(null_copy_obj == bt_value_null, | |
1092 | "bt_value_copy() returns the same pointer (null)"); | |
1093 | ||
1094 | ok(bt_value_compare(map_obj, map_copy_obj), | |
1095 | "source and destination value objects have the same content"); | |
1096 | ||
83509119 JG |
1097 | BT_PUT(bool_copy_obj); |
1098 | BT_PUT(integer_copy_obj); | |
1099 | BT_PUT(float_copy_obj); | |
1100 | BT_PUT(string_copy_obj); | |
1101 | BT_PUT(array_copy_obj); | |
1102 | BT_PUT(map_copy_obj); | |
1103 | BT_PUT(bool_obj); | |
1104 | BT_PUT(integer_obj); | |
1105 | BT_PUT(float_obj); | |
1106 | BT_PUT(string_obj); | |
1107 | BT_PUT(array_obj); | |
1108 | BT_PUT(map_obj); | |
dac5c838 PP |
1109 | } |
1110 | ||
b6ba7620 | 1111 | static |
c55a9f58 | 1112 | bt_bool compare_map_elements(struct bt_value *map_a, struct bt_value *map_b, |
b6ba7620 PP |
1113 | const char *key) |
1114 | { | |
1115 | struct bt_value *elem_a = NULL; | |
1116 | struct bt_value *elem_b = NULL; | |
c55a9f58 | 1117 | bt_bool equal; |
b6ba7620 PP |
1118 | |
1119 | elem_a = bt_value_map_get(map_a, key); | |
1120 | elem_b = bt_value_map_get(map_b, key); | |
1121 | equal = bt_value_compare(elem_a, elem_b); | |
1122 | BT_PUT(elem_a); | |
1123 | BT_PUT(elem_b); | |
1124 | ||
1125 | return equal; | |
1126 | } | |
1127 | ||
1128 | static | |
1129 | void test_extend(void) | |
1130 | { | |
1131 | struct bt_value *base_map = bt_value_map_create(); | |
1132 | struct bt_value *extension_map = bt_value_map_create(); | |
1133 | struct bt_value *extended_map = NULL; | |
1134 | struct bt_value *array = bt_value_array_create(); | |
1135 | enum bt_value_status status; | |
1136 | ||
1137 | assert(base_map); | |
1138 | assert(extension_map); | |
1139 | assert(array); | |
c55a9f58 | 1140 | status = bt_value_map_insert_bool(base_map, "file", BT_TRUE); |
b6ba7620 | 1141 | assert(status == BT_VALUE_STATUS_OK); |
c55a9f58 | 1142 | status = bt_value_map_insert_bool(base_map, "edit", BT_FALSE); |
b6ba7620 PP |
1143 | assert(status == BT_VALUE_STATUS_OK); |
1144 | status = bt_value_map_insert_integer(base_map, "selection", 17); | |
1145 | assert(status == BT_VALUE_STATUS_OK); | |
1146 | status = bt_value_map_insert_integer(base_map, "find", -34); | |
1147 | assert(status == BT_VALUE_STATUS_OK); | |
c55a9f58 | 1148 | status = bt_value_map_insert_bool(extension_map, "edit", BT_TRUE); |
b6ba7620 PP |
1149 | assert(status == BT_VALUE_STATUS_OK); |
1150 | status = bt_value_map_insert_integer(extension_map, "find", 101); | |
1151 | assert(status == BT_VALUE_STATUS_OK); | |
1152 | status = bt_value_map_insert_float(extension_map, "project", -404); | |
1153 | assert(status == BT_VALUE_STATUS_OK); | |
1154 | bt_value_freeze(base_map); | |
1155 | bt_value_freeze(extension_map); | |
1156 | bt_value_freeze(array); | |
1157 | ok(!bt_value_map_extend(NULL, extension_map), | |
1158 | "bt_value_map_extend() fails with a NULL base object"); | |
1159 | ok(!bt_value_map_extend(base_map, NULL), | |
1160 | "bt_value_map_extend() fails with a NULL extension object"); | |
1161 | ok(!bt_value_map_extend(array, extension_map), | |
1162 | "bt_value_map_extend() fails with a non-map base object"); | |
1163 | ok(!bt_value_map_extend(base_map, array), | |
1164 | "bt_value_map_extend() fails with a non-map extension object"); | |
1165 | extended_map = bt_value_map_extend(base_map, extension_map); | |
1166 | ok(extended_map, "bt_value_map_extend() succeeds"); | |
1167 | ok(bt_value_map_size(extended_map) == 5, | |
1168 | "bt_value_map_extend() returns a map object with the correct size"); | |
1169 | ok(compare_map_elements(base_map, extended_map, "file"), | |
1170 | "bt_value_map_extend() picks the appropriate element (file)"); | |
1171 | ok(compare_map_elements(extension_map, extended_map, "edit"), | |
1172 | "bt_value_map_extend() picks the appropriate element (edit)"); | |
1173 | ok(compare_map_elements(base_map, extended_map, "selection"), | |
1174 | "bt_value_map_extend() picks the appropriate element (selection)"); | |
1175 | ok(compare_map_elements(extension_map, extended_map, "find"), | |
1176 | "bt_value_map_extend() picks the appropriate element (find)"); | |
1177 | ok(compare_map_elements(extension_map, extended_map, "project"), | |
1178 | "bt_value_map_extend() picks the appropriate element (project)"); | |
1179 | ||
1180 | BT_PUT(array); | |
1181 | BT_PUT(base_map); | |
1182 | BT_PUT(extension_map); | |
1183 | BT_PUT(extended_map); | |
1184 | } | |
1185 | ||
dac5c838 PP |
1186 | static |
1187 | void test_macros(void) | |
1188 | { | |
1189 | struct bt_value *obj = bt_value_bool_create(); | |
1190 | struct bt_value *src; | |
f62d1f55 | 1191 | struct bt_value *dst = NULL; |
dac5c838 PP |
1192 | |
1193 | assert(obj); | |
83509119 JG |
1194 | BT_PUT(obj); |
1195 | ok(!obj, "BT_PUT() resets the variable to NULL"); | |
dac5c838 PP |
1196 | |
1197 | obj = bt_value_bool_create(); | |
1198 | assert(obj); | |
1199 | src = obj; | |
83509119 JG |
1200 | BT_MOVE(dst, src); |
1201 | ok(!src, "BT_MOVE() resets the source variable to NULL"); | |
1202 | ok(dst == obj, "BT_MOVE() moves the ownership"); | |
dac5c838 | 1203 | |
83509119 | 1204 | BT_PUT(dst); |
dac5c838 PP |
1205 | } |
1206 | ||
1207 | static | |
1208 | void test_freeze(void) | |
1209 | { | |
1210 | struct bt_value *obj; | |
1211 | ||
1212 | ok(bt_value_freeze(NULL) == BT_VALUE_STATUS_INVAL, | |
1213 | "bt_value_freeze() fails with an value object set to NULL"); | |
1214 | ok(!bt_value_freeze(bt_value_null), | |
1215 | "bt_value_freeze() succeeds with a null value object"); | |
1216 | ||
1217 | ok(!bt_value_is_frozen(NULL), "NULL is not frozen"); | |
1218 | ok(bt_value_is_frozen(bt_value_null), | |
1219 | "the null singleton is frozen"); | |
1220 | obj = bt_value_integer_create(); | |
1221 | assert(obj); | |
1222 | ok(!bt_value_is_frozen(obj), | |
c55a9f58 | 1223 | "bt_value_is_frozen() returns BT_FALSE with a fresh value object"); |
dac5c838 PP |
1224 | assert(!bt_value_freeze(obj)); |
1225 | ok(!bt_value_freeze(obj), | |
1226 | "bt_value_freeze() passes with a frozen value object"); | |
1227 | ok(bt_value_is_frozen(obj), | |
c55a9f58 | 1228 | "bt_value_is_frozen() returns BT_TRUE with a frozen value object"); |
dac5c838 | 1229 | |
83509119 | 1230 | BT_PUT(obj); |
dac5c838 PP |
1231 | } |
1232 | ||
1233 | int main(void) | |
1234 | { | |
8bbe269d | 1235 | plan_tests(NR_TESTS); |
dac5c838 PP |
1236 | |
1237 | test_macros(); | |
1238 | test_freeze(); | |
1239 | test_types(); | |
1240 | test_compare(); | |
1241 | test_copy(); | |
b6ba7620 | 1242 | test_extend(); |
dac5c838 PP |
1243 | |
1244 | return 0; | |
1245 | } |