1 /*
2  * ProFTPD - FTP server testsuite
3  * Copyright (c) 2017-2018 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* JSON API tests */
26 
27 #include <math.h>
28 #include "tests.h"
29 
30 static pool *p = NULL;
31 
set_up(void)32 static void set_up(void) {
33   if (p == NULL) {
34     p = make_sub_pool(NULL);
35   }
36 
37   init_json();
38 
39   if (getenv("TEST_VERBOSE") != NULL) {
40     pr_trace_set_levels("json", 1, 20);
41   }
42 }
43 
tear_down(void)44 static void tear_down(void) {
45   if (getenv("TEST_VERBOSE") != NULL) {
46     pr_trace_set_levels("json", 0, 0);
47   }
48 
49   finish_json();
50 
51   if (p != NULL) {
52     destroy_pool(p);
53     p = NULL;
54   }
55 }
56 
START_TEST(json_object_free_test)57 START_TEST (json_object_free_test) {
58   int res;
59 
60   mark_point();
61   res = pr_json_object_free(NULL);
62   fail_unless(res < 0, "Failed to handle null json");
63   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
64     strerror(errno), errno);
65 }
66 END_TEST
67 
START_TEST(json_object_alloc_test)68 START_TEST (json_object_alloc_test) {
69   int res;
70   pr_json_object_t *json;
71 
72   mark_point();
73   json = pr_json_object_alloc(NULL);
74   fail_unless(json == NULL, "Failed to handle null pool");
75   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
76     strerror(errno), errno);
77 
78   mark_point();
79   json = pr_json_object_alloc(p);
80   fail_unless(json != NULL, "Failed to allocate object: %s", strerror(errno));
81 
82   mark_point();
83   res = pr_json_object_free(json);
84   fail_unless(res == 0, "Failed to free object: %s", strerror(errno));
85 }
86 END_TEST
87 
START_TEST(json_object_from_text_test)88 START_TEST (json_object_from_text_test) {
89   pr_json_object_t *json;
90   const char *text;
91 
92   mark_point();
93   json = pr_json_object_from_text(NULL, NULL);
94   fail_unless(json == NULL, "Failed to handle null pool");
95   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
96     strerror(errno), errno);
97 
98   mark_point();
99   json = pr_json_object_from_text(p, NULL);
100   fail_unless(json == NULL, "Failed to handle null text");
101   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
102     strerror(errno), errno);
103 
104   text = "foo bar";
105 
106   mark_point();
107   json = pr_json_object_from_text(p, text);
108   fail_unless(json == NULL, "Failed to handle invalid text '%s'", text);
109   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
110     strerror(errno), errno);
111 
112   text = "[\"foo\",\"bar\"]";
113 
114   mark_point();
115   json = pr_json_object_from_text(p, text);
116   fail_unless(json == NULL, "Failed to handle non-object text '%s'", text);
117   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
118     strerror(errno), errno);
119 
120   text = "{\"foo\":\"bar\"}";
121 
122   mark_point();
123   json = pr_json_object_from_text(p, text);
124   fail_unless(json != NULL, "Failed to handle text '%s': %s", text,
125     strerror(errno));
126 
127   (void) pr_json_object_free(json);
128 }
129 END_TEST
130 
START_TEST(json_object_to_text_test)131 START_TEST (json_object_to_text_test) {
132   const char *text, *expected;
133   pr_json_object_t *json;
134 
135   mark_point();
136   text = pr_json_object_to_text(NULL, NULL, NULL);
137   fail_unless(text == NULL, "Failed to handle null pool");
138   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
139     strerror(errno), errno);
140 
141   mark_point();
142   text = pr_json_object_to_text(p, NULL, NULL);
143   fail_unless(text == NULL, "Failed to handle null json");
144   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
145     strerror(errno), errno);
146 
147   json = pr_json_object_alloc(p);
148 
149   mark_point();
150   text = pr_json_object_to_text(p, json, NULL);
151   fail_unless(text == NULL, "Failed to handle null indent");
152   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
153     strerror(errno), errno);
154 
155   expected = "{}";
156 
157   mark_point();
158   text = pr_json_object_to_text(p, json, "");
159   fail_unless(text != NULL, "Failed to get text for object: %s",
160     strerror(errno));
161   fail_unless(strcmp(text, expected) == 0, "Expected '%s', got '%s'", expected,
162     text);
163 
164   (void) pr_json_object_set_string(p, json, "foo", "bar");
165   expected = "{\"foo\":\"bar\"}";
166 
167   mark_point();
168   text = pr_json_object_to_text(p, json, "");
169   fail_unless(text != NULL, "Failed to get text for object: %s",
170     strerror(errno));
171   fail_unless(strcmp(text, expected) == 0, "Expected '%s', got '%s'", expected,
172     text);
173 
174   (void) pr_json_object_free(json);
175 }
176 END_TEST
177 
START_TEST(json_object_count_test)178 START_TEST (json_object_count_test) {
179   int res;
180   pr_json_object_t *json;
181   const char *text;
182 
183   mark_point();
184   res = pr_json_object_count(NULL);
185   fail_unless(res < 0, "Failed to handle null json");
186   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
187     strerror(errno), errno);
188 
189   json = pr_json_object_alloc(p);
190 
191   mark_point();
192   res = pr_json_object_count(json);
193   fail_unless(res == 0, "Expected 0, got %d", res);
194 
195   (void) pr_json_object_free(json);
196 
197   text = "{\"foo\":true,\"bar\":false,\"baz\":1}";
198   json = pr_json_object_from_text(p, text);
199 
200   mark_point();
201   res = pr_json_object_count(json);
202   fail_unless(res == 3, "Expected 3, got %d", res);
203 
204   (void) pr_json_object_free(json);
205 }
206 END_TEST
207 
START_TEST(json_object_exists_test)208 START_TEST (json_object_exists_test) {
209   int res;
210   pr_json_object_t *json;
211   const char *key, *text;
212 
213   mark_point();
214   res = pr_json_object_exists(NULL, NULL);
215   fail_unless(res < 0, "Failed to handle null json");
216   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
217     strerror(errno), errno);
218 
219   json = pr_json_object_alloc(p);
220 
221   mark_point();
222   res = pr_json_object_exists(json, NULL);
223   fail_unless(res < 0, "Failed to handle null key");
224   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
225     strerror(errno), errno);
226 
227   key = "foo";
228 
229   mark_point();
230   res = pr_json_object_exists(json, key);
231   fail_unless(res == FALSE, "Expected FALSE, got %d", res);
232 
233   (void) pr_json_object_free(json);
234 
235   text = "{\"foo\":true,\"bar\":false,\"baz\":1}";
236   json = pr_json_object_from_text(p, text);
237 
238   mark_point();
239   res = pr_json_object_exists(json, key);
240   fail_unless(res == TRUE, "Expected TRUE, got %d", res);
241 
242   (void) pr_json_object_free(json);
243 }
244 END_TEST
245 
START_TEST(json_object_remove_test)246 START_TEST (json_object_remove_test) {
247   int res;
248   pr_json_object_t *json;
249   const char *key, *text;
250 
251   mark_point();
252   res = pr_json_object_remove(NULL, NULL);
253   fail_unless(res < 0, "Failed to handle null json");
254   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
255     strerror(errno), errno);
256 
257   json = pr_json_object_alloc(p);
258 
259   mark_point();
260   res = pr_json_object_remove(json, NULL);
261   fail_unless(res < 0, "Failed to handle null key");
262   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
263     strerror(errno), errno);
264 
265   key = "foo";
266 
267   mark_point();
268   res = pr_json_object_remove(json, key);
269   fail_unless(res == 0, "Failed to remove nonexistent key '%s': %s", key,
270     strerror(errno));
271 
272   res = pr_json_object_count(json);
273   fail_unless(res == 0, "Expected count 0, got %d", res);
274 
275   (void) pr_json_object_free(json);
276 
277   text = "{\"foo\":true,\"bar\":false,\"baz\":1}";
278   json = pr_json_object_from_text(p, text);
279 
280   mark_point();
281   res = pr_json_object_remove(json, key);
282   fail_unless(res == 0, "Failed to remove existing key '%s': %s", key,
283     strerror(errno));
284 
285   res = pr_json_object_count(json);
286   fail_unless(res == 2, "Expected count 2, got %d", res);
287 
288   mark_point();
289   res = pr_json_object_exists(json, key);
290   fail_unless(res == FALSE, "Expected FALSE, got %d", res);
291 
292   (void) pr_json_object_free(json);
293 }
294 END_TEST
295 
START_TEST(json_object_get_bool_test)296 START_TEST(json_object_get_bool_test) {
297   int res, val;
298   const char *key, *text;
299   pr_json_object_t *json;
300 
301   mark_point();
302   res = pr_json_object_get_bool(NULL, NULL, NULL, NULL);
303   fail_unless(res < 0, "Failed to handle null pool");
304   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
305     strerror(errno), errno);
306 
307   mark_point();
308   res = pr_json_object_get_bool(p, NULL, NULL, NULL);
309   fail_unless(res < 0, "Failed to handle null json");
310   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
311     strerror(errno), errno);
312 
313   json = pr_json_object_alloc(p);
314 
315   mark_point();
316   res = pr_json_object_get_bool(p, json, NULL, NULL);
317   fail_unless(res < 0, "Failed to handle null key");
318   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
319     strerror(errno), errno);
320 
321   key = "foo";
322 
323   mark_point();
324   res = pr_json_object_get_bool(p, json, key, NULL);
325   fail_unless(res < 0, "Failed to handle null val");
326   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
327     strerror(errno), errno);
328 
329   mark_point();
330   res = pr_json_object_get_bool(p, json, key, &val);
331   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
332   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
333     strerror(errno), errno);
334 
335   (void) pr_json_object_free(json);
336 
337   text = "{\"foo\":1,\"bar\":true}";
338   json = pr_json_object_from_text(p, text);
339 
340   mark_point();
341   res = pr_json_object_get_bool(p, json, key, &val);
342   fail_unless(res < 0, "Failed to handle non-boolean key '%s'", key);
343   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
344     strerror(errno), errno);
345 
346   key = "bar";
347 
348   mark_point();
349   res = pr_json_object_get_bool(p, json, key, &val);
350   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
351     strerror(errno));
352   fail_unless(val == TRUE, "Expected TRUE, got %d", val);
353 
354   (void) pr_json_object_free(json);
355 }
356 END_TEST
357 
START_TEST(json_object_set_bool_test)358 START_TEST(json_object_set_bool_test) {
359   int res, val = TRUE;
360   const char *key;
361   pr_json_object_t *json;
362 
363   mark_point();
364   res = pr_json_object_set_bool(NULL, NULL, NULL, 0);
365   fail_unless(res < 0, "Failed to handle null pool");
366   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
367     strerror(errno), errno);
368 
369   mark_point();
370   res = pr_json_object_set_bool(p, NULL, NULL, 0);
371   fail_unless(res < 0, "Failed to handle null json");
372   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
373     strerror(errno), errno);
374 
375   json = pr_json_object_alloc(p);
376 
377   mark_point();
378   res = pr_json_object_set_bool(p, json, NULL, 0);
379   fail_unless(res < 0, "Failed to handle null key");
380   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
381     strerror(errno), errno);
382 
383   key = "foo";
384 
385   mark_point();
386   res = pr_json_object_set_bool(p, json, key, val);
387   fail_unless(res == 0, "Failed to set key '%s' to %d: %s", key, val,
388     strerror(errno));
389 
390   val = FALSE;
391 
392   mark_point();
393   res = pr_json_object_get_bool(p, json, key, &val);
394   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
395     strerror(errno));
396   fail_unless(val == TRUE, "Expected TRUE, got %d", val);
397 
398   (void) pr_json_object_free(json);
399 }
400 END_TEST
401 
START_TEST(json_object_get_null_test)402 START_TEST(json_object_get_null_test) {
403   int res;
404   const char *key, *text;
405   pr_json_object_t *json;
406 
407   mark_point();
408   res = pr_json_object_get_null(NULL, NULL, NULL);
409   fail_unless(res < 0, "Failed to handle null pool");
410   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
411     strerror(errno), errno);
412 
413   mark_point();
414   res = pr_json_object_get_null(p, NULL, NULL);
415   fail_unless(res < 0, "Failed to handle null json");
416   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
417     strerror(errno), errno);
418 
419   json = pr_json_object_alloc(p);
420 
421   mark_point();
422   res = pr_json_object_get_null(p, json, NULL);
423   fail_unless(res < 0, "Failed to handle null key");
424   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
425     strerror(errno), errno);
426 
427   key = "foo";
428 
429   mark_point();
430   res = pr_json_object_get_null(p, json, key);
431   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
432   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
433     strerror(errno), errno);
434 
435   (void) pr_json_object_free(json);
436 
437   text = "{\"foo\":1,\"bar\":null}";
438   json = pr_json_object_from_text(p, text);
439 
440   mark_point();
441   res = pr_json_object_get_null(p, json, key);
442   fail_unless(res < 0, "Failed to handle non-null key '%s'", key);
443   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
444     strerror(errno), errno);
445 
446   key = "bar";
447 
448   mark_point();
449   res = pr_json_object_get_null(p, json, key);
450   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
451     strerror(errno));
452 
453   (void) pr_json_object_free(json);
454 }
455 END_TEST
456 
START_TEST(json_object_set_null_test)457 START_TEST(json_object_set_null_test) {
458   int res;
459   const char *key;
460   pr_json_object_t *json;
461 
462   mark_point();
463   res = pr_json_object_set_null(NULL, NULL, NULL);
464   fail_unless(res < 0, "Failed to handle null pool");
465   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
466     strerror(errno), errno);
467 
468   mark_point();
469   res = pr_json_object_set_null(p, NULL, NULL);
470   fail_unless(res < 0, "Failed to handle null json");
471   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
472     strerror(errno), errno);
473 
474   json = pr_json_object_alloc(p);
475 
476   mark_point();
477   res = pr_json_object_set_null(p, json, NULL);
478   fail_unless(res < 0, "Failed to handle null key");
479   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
480     strerror(errno), errno);
481 
482   key = "foo";
483 
484   mark_point();
485   res = pr_json_object_set_null(p, json, key);
486   fail_unless(res == 0, "Failed to set key '%s': %s", key, strerror(errno));
487 
488   mark_point();
489   res = pr_json_object_get_null(p, json, key);
490   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
491     strerror(errno));
492 
493   (void) pr_json_object_free(json);
494 }
495 END_TEST
496 
START_TEST(json_object_get_number_test)497 START_TEST(json_object_get_number_test) {
498   int res;
499   double val;
500   const char *key, *text;
501   pr_json_object_t *json;
502 
503   mark_point();
504   res = pr_json_object_get_number(NULL, NULL, NULL, NULL);
505   fail_unless(res < 0, "Failed to handle null pool");
506   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
507     strerror(errno), errno);
508 
509   mark_point();
510   res = pr_json_object_get_number(p, NULL, NULL, NULL);
511   fail_unless(res < 0, "Failed to handle null json");
512   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
513     strerror(errno), errno);
514 
515   json = pr_json_object_alloc(p);
516 
517   mark_point();
518   res = pr_json_object_get_number(p, json, NULL, NULL);
519   fail_unless(res < 0, "Failed to handle null key");
520   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
521     strerror(errno), errno);
522 
523   key = "foo";
524 
525   mark_point();
526   res = pr_json_object_get_number(p, json, key, NULL);
527   fail_unless(res < 0, "Failed to handle null val");
528   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
529     strerror(errno), errno);
530 
531   mark_point();
532   res = pr_json_object_get_number(p, json, key, &val);
533   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
534   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
535     strerror(errno), errno);
536 
537   (void) pr_json_object_free(json);
538 
539   text = "{\"foo\":false,\"bar\":7}";
540   json = pr_json_object_from_text(p, text);
541 
542   mark_point();
543   res = pr_json_object_get_number(p, json, key, &val);
544   fail_unless(res < 0, "Failed to handle non-number key '%s'", key);
545   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
546     strerror(errno), errno);
547 
548   key = "bar";
549 
550   mark_point();
551   res = pr_json_object_get_number(p, json, key, &val);
552   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
553     strerror(errno));
554   fail_unless(fabs(val) == fabs((double) 7.0), "Expected 7, got %e", val);
555 
556   (void) pr_json_object_free(json);
557 }
558 END_TEST
559 
START_TEST(json_object_set_number_test)560 START_TEST(json_object_set_number_test) {
561   int res;
562   double val = 7;
563   const char *key;
564   pr_json_object_t *json;
565 
566   mark_point();
567   res = pr_json_object_set_number(NULL, NULL, NULL, 0);
568   fail_unless(res < 0, "Failed to handle null pool");
569   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
570     strerror(errno), errno);
571 
572   mark_point();
573   res = pr_json_object_set_number(p, NULL, NULL, 0);
574   fail_unless(res < 0, "Failed to handle null json");
575   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
576     strerror(errno), errno);
577 
578   json = pr_json_object_alloc(p);
579 
580   mark_point();
581   res = pr_json_object_set_number(p, json, NULL, 0);
582   fail_unless(res < 0, "Failed to handle null key");
583   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
584     strerror(errno), errno);
585 
586   key = "foo";
587 
588   mark_point();
589   res = pr_json_object_set_number(p, json, key, val);
590   fail_unless(res == 0, "Failed to set key '%s' to %d: %s", key, val,
591     strerror(errno));
592 
593   val = 3;
594 
595   mark_point();
596   res = pr_json_object_get_number(p, json, key, &val);
597   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
598     strerror(errno));
599   fail_unless(fabs(val) == fabs((double) 7.0), "Expected 7, got %e", val);
600 
601   (void) pr_json_object_free(json);
602 }
603 END_TEST
604 
START_TEST(json_object_get_string_test)605 START_TEST(json_object_get_string_test) {
606   int res;
607   const char *key, *val, *text;
608   pr_json_object_t *json;
609 
610   mark_point();
611   res = pr_json_object_get_string(NULL, NULL, NULL, NULL);
612   fail_unless(res < 0, "Failed to handle null pool");
613   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
614     strerror(errno), errno);
615 
616   mark_point();
617   res = pr_json_object_get_string(p, NULL, NULL, NULL);
618   fail_unless(res < 0, "Failed to handle null json");
619   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
620     strerror(errno), errno);
621 
622   json = pr_json_object_alloc(p);
623 
624   mark_point();
625   res = pr_json_object_get_string(p, json, NULL, NULL);
626   fail_unless(res < 0, "Failed to handle null key");
627   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
628     strerror(errno), errno);
629 
630   key = "foo";
631 
632   mark_point();
633   res = pr_json_object_get_string(p, json, key, NULL);
634   fail_unless(res < 0, "Failed to handle null val");
635   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
636     strerror(errno), errno);
637 
638   mark_point();
639   res = pr_json_object_get_string(p, json, key, (char **) &val);
640   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
641   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
642     strerror(errno), errno);
643 
644   (void) pr_json_object_free(json);
645 
646   text = "{\"foo\":false,\"bar\":\"baz\"}";
647   json = pr_json_object_from_text(p, text);
648 
649   mark_point();
650   res = pr_json_object_get_string(p, json, key, (char **) &val);
651   fail_unless(res < 0, "Failed to handle non-string key '%s'", key);
652   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
653     strerror(errno), errno);
654 
655   key = "bar";
656 
657   mark_point();
658   res = pr_json_object_get_string(p, json, key, (char **) &val);
659   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
660     strerror(errno));
661   fail_unless(strcmp(val, "baz") == 0, "Expected 'baz', got '%s'", val);
662 
663   (void) pr_json_object_free(json);
664 
665   text = "{\"foo\":\"\"}";
666   json = pr_json_object_from_text(p, text);
667 
668   key = "foo";
669 
670   mark_point();
671   res = pr_json_object_get_string(p, json, key, (char **) &val);
672   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
673     strerror(errno));
674   fail_unless(strcmp(val, "") == 0, "Expected '', got '%s'", val);
675 
676   (void) pr_json_object_free(json);
677 }
678 END_TEST
679 
START_TEST(json_object_set_string_test)680 START_TEST(json_object_set_string_test) {
681   int res;
682   const char *key, *val;
683   pr_json_object_t *json;
684 
685   mark_point();
686   res = pr_json_object_set_string(NULL, NULL, NULL, NULL);
687   fail_unless(res < 0, "Failed to handle null pool");
688   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
689     strerror(errno), errno);
690 
691   mark_point();
692   res = pr_json_object_set_string(p, NULL, NULL, NULL);
693   fail_unless(res < 0, "Failed to handle null json");
694   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
695     strerror(errno), errno);
696 
697   json = pr_json_object_alloc(p);
698 
699   mark_point();
700   res = pr_json_object_set_string(p, json, NULL, NULL);
701   fail_unless(res < 0, "Failed to handle null key");
702   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
703     strerror(errno), errno);
704 
705   key = "foo";
706 
707   mark_point();
708   res = pr_json_object_set_string(p, json, key, NULL);
709   fail_unless(res < 0, "Failed to handle null val");
710   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
711     strerror(errno), errno);
712 
713   val = "Hello, World!";
714 
715   mark_point();
716   res = pr_json_object_set_string(p, json, key, val);
717   fail_unless(res == 0, "Failed to set key '%s' to '%s': %s", key, val,
718     strerror(errno));
719 
720   val = "glarg";
721 
722   mark_point();
723   res = pr_json_object_get_string(p, json, key, (char **) &val);
724   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
725     strerror(errno));
726   fail_unless(strcmp(val, "Hello, World!") == 0,
727     "Expected 'Hello, World!', got '%s'", val);
728 
729   (void) pr_json_object_free(json);
730 }
731 END_TEST
732 
START_TEST(json_object_get_array_test)733 START_TEST(json_object_get_array_test) {
734   int res;
735   const char *key, *text;
736   char *expected = NULL, *str = NULL;
737   pr_json_array_t *val = NULL;
738   pr_json_object_t *json;
739 
740   mark_point();
741   res = pr_json_object_get_array(NULL, NULL, NULL, NULL);
742   fail_unless(res < 0, "Failed to handle null pool");
743   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
744     strerror(errno), errno);
745 
746   mark_point();
747   res = pr_json_object_get_array(p, NULL, NULL, NULL);
748   fail_unless(res < 0, "Failed to handle null json");
749   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
750     strerror(errno), errno);
751 
752   json = pr_json_object_alloc(p);
753 
754   mark_point();
755   res = pr_json_object_get_array(p, json, NULL, NULL);
756   fail_unless(res < 0, "Failed to handle null key");
757   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
758     strerror(errno), errno);
759 
760   key = "foo";
761 
762   mark_point();
763   res = pr_json_object_get_array(p, json, key, NULL);
764   fail_unless(res < 0, "Failed to handle null val");
765   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
766     strerror(errno), errno);
767 
768   mark_point();
769   res = pr_json_object_get_array(p, json, key, &val);
770   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
771   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
772     strerror(errno), errno);
773 
774   (void) pr_json_object_free(json);
775 
776   text = "{\"foo\":false,\"bar\":[\"baz\"]}";
777   json = pr_json_object_from_text(p, text);
778 
779   mark_point();
780   res = pr_json_object_get_array(p, json, key, &val);
781   fail_unless(res < 0, "Failed to handle non-array key '%s'", key);
782   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
783     strerror(errno), errno);
784 
785   key = "bar";
786   val = NULL;
787 
788   mark_point();
789   res = pr_json_object_get_array(p, json, key, &val);
790   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
791     strerror(errno));
792   fail_unless(val != NULL, "Expected array, got null");
793 
794   expected = "[\"baz\"]";
795   str = pr_json_array_to_text(p, val, "");
796   fail_unless(strcmp(str, expected) == 0,
797     "Expected '%s', got '%s'", expected, str);
798 
799   mark_point();
800   (void) pr_json_array_free(val);
801 
802   mark_point();
803   (void) pr_json_object_free(json);
804 }
805 END_TEST
806 
START_TEST(json_object_set_array_test)807 START_TEST(json_object_set_array_test) {
808   int res;
809   const char *key, *text;
810   pr_json_array_t *val = NULL;
811   pr_json_object_t *json;
812 
813   mark_point();
814   res = pr_json_object_set_array(NULL, NULL, NULL, NULL);
815   fail_unless(res < 0, "Failed to handle null pool");
816   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
817     strerror(errno), errno);
818 
819   mark_point();
820   res = pr_json_object_set_array(p, NULL, NULL, NULL);
821   fail_unless(res < 0, "Failed to handle null json");
822   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
823     strerror(errno), errno);
824 
825   json = pr_json_object_alloc(p);
826 
827   mark_point();
828   res = pr_json_object_set_array(p, json, NULL, NULL);
829   fail_unless(res < 0, "Failed to handle null key");
830   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
831     strerror(errno), errno);
832 
833   key = "foo";
834 
835   mark_point();
836   res = pr_json_object_set_array(p, json, key, val);
837   fail_unless(res < 0, "Failed to handle null val");
838   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
839     strerror(errno), errno);
840 
841   text = "[1, 1, 2, 3, 5, 8]";
842   val = pr_json_array_from_text(p, text);
843 
844   mark_point();
845   res = pr_json_object_set_array(p, json, key, val);
846   fail_unless(res == 0, "Failed to set key '%s' to '%s': %s", key, val,
847     strerror(errno));
848 
849   val = NULL;
850 
851   mark_point();
852   res = pr_json_object_get_array(p, json, key, &val);
853   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
854     strerror(errno));
855   fail_unless(val != NULL, "Expected array, got null");
856 
857   mark_point();
858   (void) pr_json_array_free(val);
859   (void) pr_json_object_free(json);
860 }
861 END_TEST
862 
START_TEST(json_object_get_object_test)863 START_TEST(json_object_get_object_test) {
864   int res;
865   const char *key, *text;
866   char *expected = NULL, *str = NULL;
867   pr_json_object_t *json, *val = NULL;
868 
869   mark_point();
870   res = pr_json_object_get_object(NULL, NULL, NULL, NULL);
871   fail_unless(res < 0, "Failed to handle null pool");
872   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
873     strerror(errno), errno);
874 
875   mark_point();
876   res = pr_json_object_get_object(p, NULL, NULL, NULL);
877   fail_unless(res < 0, "Failed to handle null json");
878   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
879     strerror(errno), errno);
880 
881   json = pr_json_object_alloc(p);
882 
883   mark_point();
884   res = pr_json_object_get_object(p, json, NULL, NULL);
885   fail_unless(res < 0, "Failed to handle null key");
886   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
887     strerror(errno), errno);
888 
889   key = "foo";
890 
891   mark_point();
892   res = pr_json_object_get_object(p, json, key, NULL);
893   fail_unless(res < 0, "Failed to handle null val");
894   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
895     strerror(errno), errno);
896 
897   mark_point();
898   res = pr_json_object_get_object(p, json, key, &val);
899   fail_unless(res < 0, "Failed to handle nonexistent key '%s'", key);
900   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
901     strerror(errno), errno);
902 
903   (void) pr_json_object_free(json);
904 
905   text = "{\"foo\":false,\"bar\":{\"baz\":null}}";
906   json = pr_json_object_from_text(p, text);
907 
908   mark_point();
909   res = pr_json_object_get_object(p, json, key, &val);
910   fail_unless(res < 0, "Failed to handle non-object key '%s'", key);
911   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
912     strerror(errno), errno);
913 
914   key = "bar";
915   val = NULL;
916 
917   mark_point();
918   res = pr_json_object_get_object(p, json, key, &val);
919   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
920     strerror(errno));
921   fail_unless(val != NULL, "Expected object, got null");
922 
923   expected = "{\"baz\":null}";
924   str = pr_json_object_to_text(p, val, "");
925   fail_unless(strcmp(str, expected) == 0,
926     "Expected '%s', got '%s'", expected, str);
927 
928   mark_point();
929   (void) pr_json_object_free(val);
930 
931   mark_point();
932   (void) pr_json_object_free(json);
933 }
934 END_TEST
935 
START_TEST(json_object_set_object_test)936 START_TEST(json_object_set_object_test) {
937   int res;
938   const char *key, *text;
939   pr_json_object_t *json, *val = NULL;
940 
941   mark_point();
942   res = pr_json_object_set_object(NULL, NULL, NULL, NULL);
943   fail_unless(res < 0, "Failed to handle null pool");
944   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
945     strerror(errno), errno);
946 
947   mark_point();
948   res = pr_json_object_set_object(p, NULL, NULL, NULL);
949   fail_unless(res < 0, "Failed to handle null json");
950   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
951     strerror(errno), errno);
952 
953   json = pr_json_object_alloc(p);
954 
955   mark_point();
956   res = pr_json_object_set_object(p, json, NULL, NULL);
957   fail_unless(res < 0, "Failed to handle null key");
958   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
959     strerror(errno), errno);
960 
961   key = "foo";
962 
963   mark_point();
964   res = pr_json_object_set_object(p, json, key, val);
965   fail_unless(res < 0, "Failed to handle null val");
966   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
967     strerror(errno), errno);
968 
969   text = "{\"eeny\":1,\"meeny\":2,\"miny\":3,\"moe\":false}";
970   val = pr_json_object_from_text(p, text);
971 
972   mark_point();
973   res = pr_json_object_set_object(p, json, key, val);
974   fail_unless(res == 0, "Failed to set key '%s' to '%s': %s", key, val,
975     strerror(errno));
976 
977   val = NULL;
978 
979   mark_point();
980   res = pr_json_object_get_object(p, json, key, &val);
981   fail_unless(res == 0, "Failed to handle existing key '%s': %s", key,
982     strerror(errno));
983   fail_unless(val != NULL, "Expected object, got null");
984 
985   mark_point();
986   (void) pr_json_object_free(val);
987   (void) pr_json_object_free(json);
988 }
989 END_TEST
990 
START_TEST(json_array_free_test)991 START_TEST(json_array_free_test) {
992   int res;
993 
994   mark_point();
995   res = pr_json_array_free(NULL);
996   fail_unless(res < 0, "Failed to handle null json");
997   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
998     strerror(errno), errno);
999 }
1000 END_TEST
1001 
START_TEST(json_array_alloc_test)1002 START_TEST(json_array_alloc_test) {
1003   int res;
1004   pr_json_array_t *json;
1005 
1006   mark_point();
1007   json = pr_json_array_alloc(NULL);
1008   fail_unless(json == NULL, "Failed to handle null pool");
1009   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1010     strerror(errno), errno);
1011 
1012   mark_point();
1013   json = pr_json_array_alloc(p);
1014   fail_unless(json != NULL, "Failed to allocate array: %s", strerror(errno));
1015 
1016   mark_point();
1017   res = pr_json_array_free(json);
1018   fail_unless(res == 0, "Failed to free array: %s", strerror(errno));
1019 }
1020 END_TEST
1021 
START_TEST(json_array_from_text_test)1022 START_TEST(json_array_from_text_test) {
1023   pr_json_array_t *json;
1024   const char *text;
1025 
1026   mark_point();
1027   json = pr_json_array_from_text(NULL, NULL);
1028   fail_unless(json == NULL, "Failed to handle null pool");
1029   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1030     strerror(errno), errno);
1031 
1032   mark_point();
1033   json = pr_json_array_from_text(p, NULL);
1034   fail_unless(json == NULL, "Failed to handle null text");
1035   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1036     strerror(errno), errno);
1037 
1038   text = "foo bar";
1039 
1040   mark_point();
1041   json = pr_json_array_from_text(p, text);
1042   fail_unless(json == NULL, "Failed to handle invalid text '%s'", text);
1043   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1044     strerror(errno), errno);
1045 
1046   text = "{\"foo\":null,\"bar\":false}";
1047 
1048   mark_point();
1049   json = pr_json_array_from_text(p, text);
1050   fail_unless(json == NULL, "Failed to handle non-array text '%s'", text);
1051   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1052     strerror(errno), errno);
1053 
1054   text = "[\"foo\",\"bar\"]";
1055 
1056   mark_point();
1057   json = pr_json_array_from_text(p, text);
1058   fail_unless(json != NULL, "Failed to handle text '%s': %s", text,
1059     strerror(errno));
1060 
1061   (void) pr_json_array_free(json);
1062 }
1063 END_TEST
1064 
START_TEST(json_array_to_text_test)1065 START_TEST(json_array_to_text_test) {
1066   const char *text, *expected;
1067   pr_json_array_t *json;
1068 
1069   mark_point();
1070   text = pr_json_array_to_text(NULL, NULL, NULL);
1071   fail_unless(text == NULL, "Failed to handle null pool");
1072   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1073     strerror(errno), errno);
1074 
1075   mark_point();
1076   text = pr_json_array_to_text(p, NULL, NULL);
1077   fail_unless(text == NULL, "Failed to handle null json");
1078   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1079     strerror(errno), errno);
1080 
1081   json = pr_json_array_alloc(p);
1082 
1083   mark_point();
1084   text = pr_json_array_to_text(p, json, NULL);
1085   fail_unless(text == NULL, "Failed to handle null indent");
1086   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1087     strerror(errno), errno);
1088 
1089   expected = "[]";
1090 
1091   mark_point();
1092   text = pr_json_array_to_text(p, json, "");
1093   fail_unless(text != NULL, "Failed to get text for array: %s",
1094     strerror(errno));
1095   fail_unless(strcmp(text, expected) == 0, "Expected '%s', got '%s'", expected,
1096     text);
1097 
1098   (void) pr_json_array_free(json);
1099 }
1100 END_TEST
1101 
START_TEST(json_array_count_test)1102 START_TEST(json_array_count_test) {
1103   int res;
1104   pr_json_array_t *json;
1105   const char *text;
1106 
1107   mark_point();
1108   res = pr_json_array_count(NULL);
1109   fail_unless(res < 0, "Failed to handle null json");
1110   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1111     strerror(errno), errno);
1112 
1113   json = pr_json_array_alloc(p);
1114 
1115   mark_point();
1116   res = pr_json_array_count(json);
1117   fail_unless(res == 0, "Expected 0, got %d", res);
1118 
1119   (void) pr_json_array_free(json);
1120 
1121   text = "[\"foo\",true,\"bar\",false,\"baz\",1]";
1122   json = pr_json_array_from_text(p, text);
1123 
1124   mark_point();
1125   res = pr_json_array_count(json);
1126   fail_unless(res == 6, "Expected 6, got %d", res);
1127 
1128   (void) pr_json_array_free(json);
1129 }
1130 END_TEST
1131 
START_TEST(json_array_exists_test)1132 START_TEST(json_array_exists_test) {
1133   int res;
1134   pr_json_array_t *json;
1135   unsigned int idx;
1136   const char *text;
1137 
1138   mark_point();
1139   res = pr_json_array_exists(NULL, 0);
1140   fail_unless(res < 0, "Failed to handle null json");
1141   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1142     strerror(errno), errno);
1143 
1144   json = pr_json_array_alloc(p);
1145 
1146   mark_point();
1147   res = pr_json_array_exists(json, 0);
1148   fail_unless(res == FALSE, "Expected FALSE, got %d", res);
1149 
1150   (void) pr_json_array_free(json);
1151 
1152   text = "[\"foo\",true,\"bar\",false,\"baz\",1]";
1153   json = pr_json_array_from_text(p, text);
1154 
1155   idx = 3;
1156 
1157   mark_point();
1158   res = pr_json_array_exists(json, idx);
1159   fail_unless(res == TRUE, "Expected TRUE, got %d", res);
1160 
1161   (void) pr_json_array_free(json);
1162 }
1163 END_TEST
1164 
START_TEST(json_array_remove_test)1165 START_TEST(json_array_remove_test) {
1166   int res;
1167   pr_json_array_t *json;
1168   unsigned int idx;
1169   const char *text;
1170 
1171   mark_point();
1172   res = pr_json_array_remove(NULL, 0);
1173   fail_unless(res < 0, "Failed to handle null json");
1174   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1175     strerror(errno), errno);
1176 
1177   json = pr_json_array_alloc(p);
1178 
1179   idx = 2;
1180 
1181   mark_point();
1182   res = pr_json_array_remove(json, idx);
1183   fail_unless(res == 0, "Failed to remove nonexistent index %u: %s", idx,
1184     strerror(errno));
1185 
1186   res = pr_json_array_count(json);
1187   fail_unless(res == 0, "Expected count 0, got %d", res);
1188 
1189   (void) pr_json_array_free(json);
1190 
1191   text = "[\"foo\",true,\"bar\",false,\"baz\",1]";
1192   json = pr_json_array_from_text(p, text);
1193 
1194   mark_point();
1195   res = pr_json_array_remove(json, idx);
1196   fail_unless(res == 0, "Failed to remove existing index %u: %s", idx,
1197     strerror(errno));
1198 
1199   res = pr_json_array_count(json);
1200   fail_unless(res == 5, "Expected count 5, got %d", res);
1201 
1202   mark_point();
1203   res = pr_json_array_exists(json, idx);
1204   fail_unless(res == TRUE, "Expected TRUE, got %d", res);
1205 
1206   (void) pr_json_array_free(json);
1207 }
1208 END_TEST
1209 
START_TEST(json_array_get_bool_test)1210 START_TEST(json_array_get_bool_test) {
1211   int res, val;
1212   unsigned int idx;
1213   const char *text;
1214   pr_json_array_t *json;
1215 
1216   mark_point();
1217   res = pr_json_array_get_bool(NULL, NULL, 0, NULL);
1218   fail_unless(res < 0, "Failed to handle null pool");
1219   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1220     strerror(errno), errno);
1221 
1222   mark_point();
1223   res = pr_json_array_get_bool(p, NULL, 0, NULL);
1224   fail_unless(res < 0, "Failed to handle null json");
1225   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1226     strerror(errno), errno);
1227 
1228   json = pr_json_array_alloc(p);
1229 
1230   mark_point();
1231   res = pr_json_array_get_bool(p, json, 0, NULL);
1232   fail_unless(res < 0, "Failed to handle null val");
1233   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1234     strerror(errno), errno);
1235 
1236   idx = 0;
1237 
1238   mark_point();
1239   res = pr_json_array_get_bool(p, json, idx, &val);
1240   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1241   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1242     strerror(errno), errno);
1243 
1244   (void) pr_json_array_free(json);
1245 
1246   text = "[\"foo\",2,\"bar\",true]";
1247   json = pr_json_array_from_text(p, text);
1248 
1249   mark_point();
1250   res = pr_json_array_get_bool(p, json, idx, &val);
1251   fail_unless(res < 0, "Failed to handle non-boolean index %u", idx);
1252   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1253     strerror(errno), errno);
1254 
1255   idx = 3;
1256 
1257   mark_point();
1258   res = pr_json_array_get_bool(p, json, idx, &val);
1259   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1260     strerror(errno));
1261   fail_unless(val == TRUE, "Expected TRUE, got %d", val);
1262 
1263   (void) pr_json_array_free(json);
1264 }
1265 END_TEST
1266 
START_TEST(json_array_append_bool_test)1267 START_TEST(json_array_append_bool_test) {
1268   int res, val = TRUE;
1269   pr_json_array_t *json;
1270 
1271   mark_point();
1272   res = pr_json_array_append_bool(NULL, NULL, 0);
1273   fail_unless(res < 0, "Failed to handle null pool");
1274   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1275     strerror(errno), errno);
1276 
1277   mark_point();
1278   res = pr_json_array_append_bool(p, NULL, 0);
1279   fail_unless(res < 0, "Failed to handle null json");
1280   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1281     strerror(errno), errno);
1282 
1283   json = pr_json_array_alloc(p);
1284 
1285   mark_point();
1286   res = pr_json_array_append_bool(p, json, val);
1287   fail_unless(res == 0, "Failed to append val %d: %s", val, strerror(errno));
1288 
1289   val = FALSE;
1290 
1291   mark_point();
1292   res = pr_json_array_get_bool(p, json, 0, &val);
1293   fail_unless(res == 0, "Failed to handle existing index 0: %s",
1294     strerror(errno));
1295   fail_unless(val == TRUE, "Expected TRUE, got %d", val);
1296 
1297   (void) pr_json_array_free(json);
1298 }
1299 END_TEST
1300 
START_TEST(json_array_get_null_test)1301 START_TEST(json_array_get_null_test) {
1302   int res;
1303   unsigned int idx;
1304   const char *text;
1305   pr_json_array_t *json;
1306 
1307   mark_point();
1308   res = pr_json_array_get_null(NULL, NULL, 0);
1309   fail_unless(res < 0, "Failed to handle null pool");
1310   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1311     strerror(errno), errno);
1312 
1313   mark_point();
1314   res = pr_json_array_get_null(p, NULL, 0);
1315   fail_unless(res < 0, "Failed to handle null json");
1316   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1317     strerror(errno), errno);
1318 
1319   json = pr_json_array_alloc(p);
1320 
1321   idx = 1;
1322 
1323   mark_point();
1324   res = pr_json_array_get_null(p, json, idx);
1325   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1326   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1327     strerror(errno), errno);
1328 
1329   (void) pr_json_array_free(json);
1330 
1331   text = "[\"foo\",2,\"bar\",null]";
1332   json = pr_json_array_from_text(p, text);
1333 
1334   mark_point();
1335   res = pr_json_array_get_null(p, json, idx);
1336   fail_unless(res < 0, "Failed to handle non-null index %u", idx);
1337   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1338     strerror(errno), errno);
1339 
1340   idx = 3;
1341 
1342   mark_point();
1343   res = pr_json_array_get_null(p, json, idx);
1344   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1345     strerror(errno));
1346 
1347   (void) pr_json_array_free(json);
1348 }
1349 END_TEST
1350 
START_TEST(json_array_append_null_test)1351 START_TEST(json_array_append_null_test) {
1352   int res;
1353   pr_json_array_t *json;
1354 
1355   mark_point();
1356   res = pr_json_array_append_null(NULL, NULL);
1357   fail_unless(res < 0, "Failed to handle null pool");
1358   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1359     strerror(errno), errno);
1360 
1361   mark_point();
1362   res = pr_json_array_append_null(p, NULL);
1363   fail_unless(res < 0, "Failed to handle null json");
1364   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1365     strerror(errno), errno);
1366 
1367   json = pr_json_array_alloc(p);
1368 
1369   mark_point();
1370   res = pr_json_array_append_null(p, json);
1371   fail_unless(res == 0, "Failed to append null vall: %s", strerror(errno));
1372 
1373   mark_point();
1374   res = pr_json_array_get_null(p, json, 0);
1375   fail_unless(res == 0, "Failed to handle existing index 0: %s",
1376     strerror(errno));
1377 
1378   (void) pr_json_array_free(json);
1379 }
1380 END_TEST
1381 
START_TEST(json_array_get_number_test)1382 START_TEST(json_array_get_number_test) {
1383   int res;
1384   double val;
1385   unsigned int idx;
1386   const char *text;
1387   pr_json_array_t *json;
1388 
1389   mark_point();
1390   res = pr_json_array_get_number(NULL, NULL, 0, NULL);
1391   fail_unless(res < 0, "Failed to handle null pool");
1392   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1393     strerror(errno), errno);
1394 
1395   mark_point();
1396   res = pr_json_array_get_number(p, NULL, 0, NULL);
1397   fail_unless(res < 0, "Failed to handle null json");
1398   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1399     strerror(errno), errno);
1400 
1401   json = pr_json_array_alloc(p);
1402 
1403   mark_point();
1404   res = pr_json_array_get_number(p, json, 0, NULL);
1405   fail_unless(res < 0, "Failed to handle null val");
1406   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1407     strerror(errno), errno);
1408 
1409   idx = 3;
1410 
1411   mark_point();
1412   res = pr_json_array_get_number(p, json, idx, &val);
1413   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1414   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1415     strerror(errno), errno);
1416 
1417   (void) pr_json_array_free(json);
1418 
1419   text = "[\"foo\",2,\"bar\",true]";
1420   json = pr_json_array_from_text(p, text);
1421 
1422   mark_point();
1423   res = pr_json_array_get_number(p, json, idx, &val);
1424   fail_unless(res < 0, "Failed to handle non-number index %u", idx);
1425   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1426     strerror(errno), errno);
1427 
1428   idx = 1;
1429 
1430   mark_point();
1431   res = pr_json_array_get_number(p, json, idx, &val);
1432   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1433     strerror(errno));
1434   fail_unless(fabs(val) == fabs((double) 2.0), "Expected 2, got '%e'", val);
1435 
1436   (void) pr_json_array_free(json);
1437 }
1438 END_TEST
1439 
START_TEST(json_array_append_number_test)1440 START_TEST(json_array_append_number_test) {
1441   int res;
1442   double val = 7;
1443   pr_json_array_t *json;
1444 
1445   mark_point();
1446   res = pr_json_array_append_number(NULL, NULL, 0);
1447   fail_unless(res < 0, "Failed to handle null pool");
1448   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1449     strerror(errno), errno);
1450 
1451   mark_point();
1452   res = pr_json_array_append_number(p, NULL, 0);
1453   fail_unless(res < 0, "Failed to handle null json");
1454   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1455     strerror(errno), errno);
1456 
1457   json = pr_json_array_alloc(p);
1458 
1459   mark_point();
1460   res = pr_json_array_append_number(p, json, val);
1461   fail_unless(res == 0, "Failed to append val %e: %s", val, strerror(errno));
1462 
1463   val = 2;
1464 
1465   mark_point();
1466   res = pr_json_array_get_number(p, json, 0, &val);
1467   fail_unless(res == 0, "Failed to handle existing index 0: %s",
1468     strerror(errno));
1469   fail_unless(fabs(val) == fabs((double) 7.0), "Expected 7, got %e", val);
1470 
1471   (void) pr_json_array_free(json);
1472 }
1473 END_TEST
1474 
START_TEST(json_array_get_string_test)1475 START_TEST(json_array_get_string_test) {
1476   int res;
1477   unsigned int idx;
1478   const char *text, *val;
1479   pr_json_array_t *json;
1480 
1481   mark_point();
1482   res = pr_json_array_get_string(NULL, NULL, 0, NULL);
1483   fail_unless(res < 0, "Failed to handle null pool");
1484   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1485     strerror(errno), errno);
1486 
1487   mark_point();
1488   res = pr_json_array_get_string(p, NULL, 0, NULL);
1489   fail_unless(res < 0, "Failed to handle null json");
1490   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1491     strerror(errno), errno);
1492 
1493   json = pr_json_array_alloc(p);
1494 
1495   mark_point();
1496   res = pr_json_array_get_string(p, json, 0, NULL);
1497   fail_unless(res < 0, "Failed to handle null val");
1498   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1499     strerror(errno), errno);
1500 
1501   idx = 3;
1502 
1503   mark_point();
1504   res = pr_json_array_get_string(p, json, idx, (char **) &val);
1505   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1506   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1507     strerror(errno), errno);
1508 
1509   (void) pr_json_array_free(json);
1510 
1511   text = "[\"foo\",2,\"bar\",true]";
1512   json = pr_json_array_from_text(p, text);
1513 
1514   mark_point();
1515   res = pr_json_array_get_string(p, json, idx, (char **) &val);
1516   fail_unless(res < 0, "Failed to handle non-string index %u", idx);
1517   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1518     strerror(errno), errno);
1519 
1520   idx = 0;
1521 
1522   mark_point();
1523   res = pr_json_array_get_string(p, json, idx, (char **) &val);
1524   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1525     strerror(errno));
1526   fail_unless(strcmp(val, "foo") == 0, "Expected 'foo', got '%s'", val);
1527 
1528   (void) pr_json_array_free(json);
1529 }
1530 END_TEST
1531 
START_TEST(json_array_append_string_test)1532 START_TEST(json_array_append_string_test) {
1533   int res;
1534   const char *val;
1535   pr_json_array_t *json;
1536 
1537   mark_point();
1538   res = pr_json_array_append_string(NULL, NULL, NULL);
1539   fail_unless(res < 0, "Failed to handle null pool");
1540   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1541     strerror(errno), errno);
1542 
1543   mark_point();
1544   res = pr_json_array_append_string(p, NULL, NULL);
1545   fail_unless(res < 0, "Failed to handle null json");
1546   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1547     strerror(errno), errno);
1548 
1549   json = pr_json_array_alloc(p);
1550 
1551   mark_point();
1552   res = pr_json_array_append_string(p, json, NULL);
1553   fail_unless(res < 0, "Failed to handle null val");
1554   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1555     strerror(errno), errno);
1556 
1557   val = "foo!";
1558 
1559   mark_point();
1560   res = pr_json_array_append_string(p, json, val);
1561   fail_unless(res == 0, "Failed to append val '%s': %s", val, strerror(errno));
1562 
1563   val = NULL;
1564 
1565   mark_point();
1566   res = pr_json_array_get_string(p, json, 0, (char **) &val);
1567   fail_unless(res == 0, "Failed to handle existing index 0: %s",
1568     strerror(errno));
1569   fail_unless(strcmp(val, "foo!") == 0, "Expected 'foo!', got '%s'", val);
1570 
1571   (void) pr_json_array_free(json);
1572 }
1573 END_TEST
1574 
START_TEST(json_array_get_array_test)1575 START_TEST(json_array_get_array_test) {
1576   int res;
1577   unsigned int idx;
1578   const char *text;
1579   char *expected = NULL, *str = NULL;
1580   pr_json_array_t *json, *val = NULL;
1581 
1582   mark_point();
1583   res = pr_json_array_get_array(NULL, NULL, 0, NULL);
1584   fail_unless(res < 0, "Failed to handle null pool");
1585   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1586     strerror(errno), errno);
1587 
1588   mark_point();
1589   res = pr_json_array_get_array(p, NULL, 0, NULL);
1590   fail_unless(res < 0, "Failed to handle null json");
1591   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1592     strerror(errno), errno);
1593 
1594   json = pr_json_array_alloc(p);
1595 
1596   mark_point();
1597   res = pr_json_array_get_array(p, json, 0, NULL);
1598   fail_unless(res < 0, "Failed to handle null val");
1599   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1600     strerror(errno), errno);
1601 
1602   idx = 0;
1603 
1604   mark_point();
1605   res = pr_json_array_get_array(p, json, idx, &val);
1606   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1607   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1608     strerror(errno), errno);
1609 
1610   (void) pr_json_array_free(json);
1611 
1612   text = "[\"foo\",false,\"bar\",[\"baz\"]]";
1613   json = pr_json_array_from_text(p, text);
1614 
1615   mark_point();
1616   res = pr_json_array_get_array(p, json, idx, &val);
1617   fail_unless(res < 0, "Failed to handle non-array index %u", idx);
1618   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1619     strerror(errno), errno);
1620 
1621   idx = 3;
1622   val = NULL;
1623 
1624   mark_point();
1625   res = pr_json_array_get_array(p, json, idx, &val);
1626   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1627     strerror(errno));
1628   fail_unless(val != NULL, "Expected array, got null");
1629 
1630   expected = "[\"baz\"]";
1631   str = pr_json_array_to_text(p, val, "");
1632   fail_unless(strcmp(str, expected) == 0,
1633     "Expected '%s', got '%s'", expected, str);
1634 
1635   mark_point();
1636   (void) pr_json_array_free(val);
1637 
1638   mark_point();
1639   (void) pr_json_array_free(json);
1640 }
1641 END_TEST
1642 
START_TEST(json_array_append_array_test)1643 START_TEST(json_array_append_array_test) {
1644   int res;
1645   unsigned int idx;
1646   const char *text;
1647   pr_json_array_t *json, *val = NULL;
1648 
1649   mark_point();
1650   res = pr_json_array_append_array(NULL, NULL, NULL);
1651   fail_unless(res < 0, "Failed to handle null pool");
1652   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1653     strerror(errno), errno);
1654 
1655   mark_point();
1656   res = pr_json_array_append_array(p, NULL, NULL);
1657   fail_unless(res < 0, "Failed to handle null json");
1658   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1659     strerror(errno), errno);
1660 
1661   json = pr_json_array_alloc(p);
1662 
1663   mark_point();
1664   res = pr_json_array_append_array(p, json, NULL);
1665   fail_unless(res < 0, "Failed to handle null val");
1666   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1667     strerror(errno), errno);
1668 
1669   text = "[1, 1, 2, 3, 5, 8]";
1670   val = pr_json_array_from_text(p, text);
1671 
1672   mark_point();
1673   res = pr_json_array_append_array(p, json, val);
1674   fail_unless(res == 0, "Failed to append array: %s", strerror(errno));
1675 
1676   val = NULL;
1677   idx = 0;
1678 
1679   mark_point();
1680   res = pr_json_array_get_array(p, json, idx, &val);
1681   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1682     strerror(errno));
1683   fail_unless(val != NULL, "Expected array, got null");
1684 
1685   mark_point();
1686   (void) pr_json_array_free(val);
1687   (void) pr_json_array_free(json);
1688 }
1689 END_TEST
1690 
START_TEST(json_array_get_object_test)1691 START_TEST(json_array_get_object_test) {
1692   int res;
1693   unsigned int idx;
1694   const char *text;
1695   char *expected = NULL, *str = NULL;
1696   pr_json_object_t *val = NULL;
1697   pr_json_array_t *json;
1698 
1699   mark_point();
1700   res = pr_json_array_get_object(NULL, NULL, 0, NULL);
1701   fail_unless(res < 0, "Failed to handle null pool");
1702   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1703     strerror(errno), errno);
1704 
1705   mark_point();
1706   res = pr_json_array_get_object(p, NULL, 0, NULL);
1707   fail_unless(res < 0, "Failed to handle null json");
1708   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1709     strerror(errno), errno);
1710 
1711   json = pr_json_array_alloc(p);
1712 
1713   mark_point();
1714   res = pr_json_array_get_object(p, json, 0, NULL);
1715   fail_unless(res < 0, "Failed to handle null val");
1716   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1717     strerror(errno), errno);
1718 
1719   idx = 0;
1720 
1721   mark_point();
1722   res = pr_json_array_get_object(p, json, idx, &val);
1723   fail_unless(res < 0, "Failed to handle nonexistent index %u", idx);
1724   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1725     strerror(errno), errno);
1726 
1727   (void) pr_json_array_free(json);
1728 
1729   text = "[\"foo\",false,\"bar\",{}]";
1730   json = pr_json_array_from_text(p, text);
1731 
1732   mark_point();
1733   res = pr_json_array_get_object(p, json, idx, &val);
1734   fail_unless(res < 0, "Failed to handle non-object index %u", idx);
1735   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1736     strerror(errno), errno);
1737 
1738   idx = 3;
1739   val = NULL;
1740 
1741   mark_point();
1742   res = pr_json_array_get_object(p, json, idx, &val);
1743   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1744     strerror(errno));
1745   fail_unless(val != NULL, "Expected object, got null");
1746 
1747   expected = "{}";
1748   str = pr_json_object_to_text(p, val, "");
1749   fail_unless(strcmp(str, expected) == 0,
1750     "Expected '%s', got '%s'", expected, str);
1751 
1752   mark_point();
1753   (void) pr_json_object_free(val);
1754 
1755   mark_point();
1756   (void) pr_json_array_free(json);
1757 }
1758 END_TEST
1759 
START_TEST(json_array_append_object_test)1760 START_TEST(json_array_append_object_test) {
1761   int res;
1762   unsigned int idx;
1763   const char *text;
1764   pr_json_object_t *val = NULL;
1765   pr_json_array_t *json;
1766 
1767   mark_point();
1768   res = pr_json_array_append_object(NULL, NULL, NULL);
1769   fail_unless(res < 0, "Failed to handle null pool");
1770   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1771     strerror(errno), errno);
1772 
1773   mark_point();
1774   res = pr_json_array_append_object(p, NULL, NULL);
1775   fail_unless(res < 0, "Failed to handle null json");
1776   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1777     strerror(errno), errno);
1778 
1779   json = pr_json_array_alloc(p);
1780 
1781   mark_point();
1782   res = pr_json_array_append_object(p, json, NULL);
1783   fail_unless(res < 0, "Failed to handle null val");
1784   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1785     strerror(errno), errno);
1786 
1787   text = "{\"foo\":1,\"bar\":2}";
1788   val = pr_json_object_from_text(p, text);
1789 
1790   mark_point();
1791   res = pr_json_array_append_object(p, json, val);
1792   fail_unless(res == 0, "Failed to append object: %s", strerror(errno));
1793 
1794   val = NULL;
1795   idx = 0;
1796 
1797   mark_point();
1798   res = pr_json_array_get_object(p, json, idx, &val);
1799   fail_unless(res == 0, "Failed to handle existing index %u: %s", idx,
1800     strerror(errno));
1801   fail_unless(val != NULL, "Expected object, got null");
1802 
1803   mark_point();
1804   (void) pr_json_object_free(val);
1805   (void) pr_json_array_free(json);
1806 }
1807 END_TEST
1808 
START_TEST(json_text_validate_test)1809 START_TEST(json_text_validate_test) {
1810   int res;
1811   const char *text;
1812 
1813   mark_point();
1814   res = pr_json_text_validate(NULL, NULL);
1815   fail_unless(res < 0, "Failed to handle null pool");
1816   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1817     strerror(errno), errno);
1818 
1819   mark_point();
1820   res = pr_json_text_validate(p, NULL);
1821   fail_unless(res < 0, "Failed to handle null text");
1822   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1823     strerror(errno), errno);
1824 
1825   text = "foo bar";
1826 
1827   mark_point();
1828   res = pr_json_text_validate(p, text);
1829   fail_unless(res == FALSE, "Failed to handle invalid text '%s'", text);
1830 
1831   text = "[{}]";
1832 
1833   mark_point();
1834   res = pr_json_text_validate(p, text);
1835   fail_unless(res == TRUE, "Failed to handle valid text '%s'", text);
1836 }
1837 END_TEST
1838 
START_TEST(json_type_name_test)1839 START_TEST(json_type_name_test) {
1840   const char *res, *expected;
1841 
1842   res = pr_json_type_name(0);
1843   fail_unless(res == NULL, "Failed to handle invalid JSON type ID 0");
1844   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1845     strerror(errno), errno);
1846 
1847   expected = "boolean";
1848   res = pr_json_type_name(PR_JSON_TYPE_BOOL);
1849   fail_unless(res != NULL, "Failed to handle JSON_TYPE_BOOL: %s",
1850     strerror(errno));
1851   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1852     res);
1853 
1854   expected = "number";
1855   res = pr_json_type_name(PR_JSON_TYPE_NUMBER);
1856   fail_unless(res != NULL, "Failed to handle JSON_TYPE_NUMBER: %s",
1857     strerror(errno));
1858   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1859     res);
1860 
1861   expected = "null";
1862   res = pr_json_type_name(PR_JSON_TYPE_NULL);
1863   fail_unless(res != NULL, "Failed to handle JSON_TYPE_NULL: %s",
1864     strerror(errno));
1865   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1866     res);
1867 
1868   expected = "string";
1869   res = pr_json_type_name(PR_JSON_TYPE_STRING);
1870   fail_unless(res != NULL, "Failed to handle JSON_TYPE_STRING: %s",
1871     strerror(errno));
1872   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1873     res);
1874 
1875   expected = "array";
1876   res = pr_json_type_name(PR_JSON_TYPE_ARRAY);
1877   fail_unless(res != NULL, "Failed to handle JSON_TYPE_ARRAY: %s",
1878     strerror(errno));
1879   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1880     res);
1881 
1882   expected = "object";
1883   res = pr_json_type_name(PR_JSON_TYPE_OBJECT);
1884   fail_unless(res != NULL, "Failed to handle JSON_TYPE_OBJECT: %s",
1885     strerror(errno));
1886   fail_unless(strcmp(res, expected) == 0, "Expected '%s', got '%s'", expected,
1887     res);
1888 }
1889 END_TEST
1890 
tests_get_json_suite(void)1891 Suite *tests_get_json_suite(void) {
1892   Suite *suite;
1893   TCase *testcase;
1894 
1895   suite = suite_create("json");
1896   testcase = tcase_create("base");
1897 
1898   tcase_add_checked_fixture(testcase, set_up, tear_down);
1899 
1900   tcase_add_test(testcase, json_object_free_test);
1901   tcase_add_test(testcase, json_object_alloc_test);
1902   tcase_add_test(testcase, json_object_from_text_test);
1903   tcase_add_test(testcase, json_object_to_text_test);
1904   tcase_add_test(testcase, json_object_count_test);
1905   tcase_add_test(testcase, json_object_exists_test);
1906   tcase_add_test(testcase, json_object_remove_test);
1907   tcase_add_test(testcase, json_object_get_bool_test);
1908   tcase_add_test(testcase, json_object_set_bool_test);
1909   tcase_add_test(testcase, json_object_get_null_test);
1910   tcase_add_test(testcase, json_object_set_null_test);
1911   tcase_add_test(testcase, json_object_get_number_test);
1912   tcase_add_test(testcase, json_object_set_number_test);
1913   tcase_add_test(testcase, json_object_get_string_test);
1914   tcase_add_test(testcase, json_object_set_string_test);
1915   tcase_add_test(testcase, json_object_get_array_test);
1916   tcase_add_test(testcase, json_object_set_array_test);
1917   tcase_add_test(testcase, json_object_get_object_test);
1918   tcase_add_test(testcase, json_object_set_object_test);
1919 
1920   tcase_add_test(testcase, json_array_free_test);
1921   tcase_add_test(testcase, json_array_alloc_test);
1922   tcase_add_test(testcase, json_array_from_text_test);
1923   tcase_add_test(testcase, json_array_to_text_test);
1924   tcase_add_test(testcase, json_array_count_test);
1925   tcase_add_test(testcase, json_array_exists_test);
1926   tcase_add_test(testcase, json_array_remove_test);
1927   tcase_add_test(testcase, json_array_get_bool_test);
1928   tcase_add_test(testcase, json_array_append_bool_test);
1929   tcase_add_test(testcase, json_array_get_null_test);
1930   tcase_add_test(testcase, json_array_append_null_test);
1931   tcase_add_test(testcase, json_array_get_number_test);
1932   tcase_add_test(testcase, json_array_append_number_test);
1933   tcase_add_test(testcase, json_array_get_string_test);
1934   tcase_add_test(testcase, json_array_append_string_test);
1935   tcase_add_test(testcase, json_array_get_array_test);
1936   tcase_add_test(testcase, json_array_append_array_test);
1937   tcase_add_test(testcase, json_array_get_object_test);
1938   tcase_add_test(testcase, json_array_append_object_test);
1939 
1940   tcase_add_test(testcase, json_text_validate_test);
1941   tcase_add_test(testcase, json_type_name_test);
1942 
1943   suite_add_tcase(suite, testcase);
1944   return suite;
1945 }
1946