Add lots of tests for pack/unpack code, fix bugs found
[jansson.git] / test / suites / api / test_pack.c
1 /*
2  * Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
3  * Copyright (c) 2010-2011 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
4  *
5  * Jansson is free software; you can redistribute it and/or modify
6  * it under the terms of the MIT license. See LICENSE for details.
7  */
8
9 #include <string.h>
10 #include <jansson.h>
11 #include <stdio.h>
12 #include "util.h"
13
14 int main()
15 {
16     json_t *value;
17     int i;
18     json_error_t error;
19
20     /*
21      * Simple, valid json_pack cases
22      */
23
24     /* true */
25     value = json_pack("b", 1);
26     if(!json_is_true(value))
27         fail("json_pack boolean failed");
28     if(value->refcount != (ssize_t)-1)
29         fail("json_pack boolean refcount failed");
30     json_decref(value);
31
32     /* false */
33     value = json_pack("b", 0);
34     if(!json_is_false(value))
35         fail("json_pack boolean failed");
36     if(value->refcount != (ssize_t)-1)
37         fail("json_pack boolean refcount failed");
38     json_decref(value);
39
40     /* null */
41     value = json_pack("n");
42     if(!json_is_null(value))
43         fail("json_pack null failed");
44     if(value->refcount != (ssize_t)-1)
45         fail("json_pack null refcount failed");
46     json_decref(value);
47
48     /* integer */
49     value = json_pack("i", 1);
50     if(!json_is_integer(value) || json_integer_value(value) != 1)
51         fail("json_pack integer failed");
52     if(value->refcount != (ssize_t)1)
53         fail("json_pack integer refcount failed");
54     json_decref(value);
55
56     /* integer from json_int_t */
57     value = json_pack("I", (json_int_t)555555);
58     if(!json_is_integer(value) || json_integer_value(value) != 555555)
59         fail("json_pack json_int_t failed");
60     if(value->refcount != (ssize_t)1)
61         fail("json_pack integer refcount failed");
62     json_decref(value);
63
64     /* real */
65     value = json_pack("f", 1.0);
66     if(!json_is_real(value) || json_real_value(value) != 1.0)
67         fail("json_pack real failed");
68     if(value->refcount != (ssize_t)1)
69         fail("json_pack real refcount failed");
70     json_decref(value);
71
72     /* string */
73     value = json_pack("s", "test");
74     if(!json_is_string(value) || strcmp("test", json_string_value(value)))
75         fail("json_pack string failed");
76     if(value->refcount != (ssize_t)1)
77         fail("json_pack string refcount failed");
78     json_decref(value);
79
80     /* empty object */
81     value = json_pack("{}", 1.0);
82     if(!json_is_object(value) || json_object_size(value) != 0)
83         fail("json_pack empty object failed");
84     if(value->refcount != (ssize_t)1)
85         fail("json_pack empty object refcount failed");
86     json_decref(value);
87
88     /* empty list */
89     value = json_pack("[]", 1.0);
90     if(!json_is_array(value) || json_array_size(value) != 0)
91         fail("json_pack empty list failed");
92     if(value->refcount != (ssize_t)1)
93         fail("json_pack empty list failed");
94     json_decref(value);
95
96     /* non-incref'd object */
97     value = json_pack("o", json_integer(1));
98     if(!json_is_integer(value) || json_integer_value(value) != 1)
99         fail("json_pack object failed");
100     if(value->refcount != (ssize_t)1)
101         fail("json_pack integer refcount failed");
102     json_decref(value);
103
104     /* incref'd object */
105     value = json_pack("O", json_integer(1));
106     if(!json_is_integer(value) || json_integer_value(value) != 1)
107         fail("json_pack object failed");
108     if(value->refcount != (ssize_t)2)
109         fail("json_pack integer refcount failed");
110     json_decref(value);
111     json_decref(value);
112
113     /* simple object */
114     value = json_pack("{s:[]}", "foo");
115     if(!json_is_object(value) || json_object_size(value) != 1)
116         fail("json_pack array failed");
117     if(!json_is_array(json_object_get(value, "foo")))
118         fail("json_pack array failed");
119     if(json_object_get(value, "foo")->refcount != (ssize_t)1)
120         fail("json_pack object refcount failed");
121     json_decref(value);
122
123     /* simple array */
124     value = json_pack("[i,i,i]", 0, 1, 2);
125     if(!json_is_array(value) || json_array_size(value) != 3)
126         fail("json_pack object failed");
127     for(i=0; i<3; i++)
128     {
129         if(!json_is_integer(json_array_get(value, i)) ||
130            json_integer_value(json_array_get(value, i)) != i)
131
132             fail("json_pack integer array failed");
133     }
134     json_decref(value);
135
136     /* Whitespace; regular string */
137     value = json_pack(" s ", "test");
138     if(!json_is_string(value) || strcmp("test", json_string_value(value)))
139         fail("json_pack string (with whitespace) failed");
140     json_decref(value);
141
142     /* Whitespace; empty array */
143     value = json_pack("[ ]");
144     if(!json_is_array(value) || json_array_size(value) != 0)
145         fail("json_pack empty array (with whitespace) failed");
146     json_decref(value);
147
148     /* Whitespace; array */
149     value = json_pack("[ i , i,  i ] ", 1, 2, 3);
150     if(!json_is_array(value) || json_array_size(value) != 3)
151         fail("json_pack array (with whitespace) failed");
152     json_decref(value);
153
154     /*
155      * Invalid cases
156      */
157
158     /* newline in format string */
159     if(json_pack_ex(&error, 0, "{\n\n1"))
160         fail("json_pack failed to catch invalid format '1'");
161     check_error("Expected format 's', got '1'", "<format>", 3, 1, 4);
162
163     /* mismatched open/close array/object */
164     if(json_pack_ex(&error, 0, "[}"))
165         fail("json_pack failed to catch mismatched '}'");
166     check_error("Unexpected format character '}'", "<format>", 1, 2, 2);
167
168     if(json_pack_ex(&error, 0, "{]"))
169         fail("json_pack failed to catch mismatched ']'");
170     check_error("Expected format 's', got ']'", "<format>", 1, 2, 2);
171
172     /* missing close array */
173     if(json_pack_ex(&error, 0, "["))
174         fail("json_pack failed to catch missing ']'");
175     check_error("Unexpected end of format string", "<format>", 1, 2, 2);
176
177     /* missing close object */
178     if(json_pack_ex(&error, 0, "{"))
179         fail("json_pack failed to catch missing '}'");
180     check_error("Unexpected end of format string", "<format>", 1, 2, 2);
181
182     /* garbage after format string */
183     if(json_pack_ex(&error, 0, "[i]a", 42))
184         fail("json_pack failed to catch garbage after format string");
185     check_error("Garbage after format string", "<format>", 1, 4, 4);
186
187     if(json_pack_ex(&error, 0, "ia", 42))
188         fail("json_pack failed to catch garbage after format string");
189     check_error("Garbage after format string", "<format>", 1, 2, 2);
190
191     /* NULL string */
192     if(json_pack_ex(&error, 0, "s", NULL))
193         fail("json_pack failed to catch null argument string");
194     check_error("NULL string argument", "<args>", 1, 1, 1);
195
196     /* NULL format */
197     if(json_pack_ex(&error, 0, NULL))
198         fail("json_pack failed to catch NULL format string");
199     check_error("NULL or empty format string", "<format>", -1, -1, 0);
200
201     /* NULL key */
202     if(json_pack_ex(&error, 0, "{s:i}", NULL, 1))
203         fail("json_pack failed to catch NULL key");
204     check_error("NULL object key", "<args>", 1, 2, 2);
205
206     /* More complicated checks for row/columns */
207     if(json_pack_ex(&error, 0, "{ {}: s }", "foo"))
208         fail("json_pack failed to catch object as key");
209     check_error("Expected format 's', got '{'", "<format>", 1, 3, 3);
210
211
212     if(json_pack_ex(&error, 0, "{ s: {},  s:[ii{} }", "foo", "bar", 12, 13))
213         fail("json_pack failed to catch missing ]");
214     check_error("Unexpected format character '}'", "<format>", 1, 19, 19);
215
216     if(json_pack_ex(&error, 0, "[[[[[   [[[[[  [[[[ }]]]] ]]]] ]]]]]"))
217         fail("json_pack failed to catch extra }");
218     check_error("Unexpected format character '}'", "<format>", 1, 21, 21);
219
220     return 0;
221 }