Home | History | Annotate | Download | only in test
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <stdarg.h>
      5 
      6 #include "test.h"
      7 #include "testutil.h"
      8 
      9 int test_empty(void) {
     10 	check(parse("{}", 1, 1,
     11 				JSMN_OBJECT, 0, 2, 0));
     12 	check(parse("[]", 1, 1,
     13 				JSMN_ARRAY, 0, 2, 0));
     14 	check(parse("[{},{}]", 3, 3,
     15 				JSMN_ARRAY, 0, 7, 2,
     16 				JSMN_OBJECT, 1, 3, 0,
     17 				JSMN_OBJECT, 4, 6, 0));
     18 	return 0;
     19 }
     20 
     21 int test_object(void) {
     22 	check(parse("{\"a\":0}", 3, 3,
     23 				JSMN_OBJECT, 0, 7, 1,
     24 				JSMN_STRING, "a", 1,
     25 				JSMN_PRIMITIVE, "0"));
     26 	check(parse("{\"a\":[]}", 3, 3,
     27 				JSMN_OBJECT, 0, 8, 1,
     28 				JSMN_STRING, "a", 1,
     29 				JSMN_ARRAY, 5, 7, 0));
     30 	check(parse("{\"a\":{},\"b\":{}}", 5, 5,
     31 				JSMN_OBJECT, -1, -1, 2,
     32 				JSMN_STRING, "a", 1,
     33 				JSMN_OBJECT, -1, -1, 0,
     34 				JSMN_STRING, "b", 1,
     35 				JSMN_OBJECT, -1, -1, 0));
     36 	check(parse("{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }", 7, 7,
     37 				JSMN_OBJECT, -1, -1, 3,
     38 				JSMN_STRING, "Day", 1,
     39 				JSMN_PRIMITIVE, "26",
     40 				JSMN_STRING, "Month", 1,
     41 				JSMN_PRIMITIVE, "9",
     42 				JSMN_STRING, "Year", 1,
     43 				JSMN_PRIMITIVE, "12"));
     44 	check(parse("{\"a\": 0, \"b\": \"c\"}", 5, 5,
     45 				JSMN_OBJECT, -1, -1, 2,
     46 				JSMN_STRING, "a", 1,
     47 				JSMN_PRIMITIVE, "0",
     48 				JSMN_STRING, "b", 1,
     49 				JSMN_STRING, "c", 0));
     50 
     51 #ifdef JSMN_STRICT
     52 	check(parse("{\"a\"\n0}", JSMN_ERROR_INVAL, 3));
     53 	check(parse("{\"a\", 0}", JSMN_ERROR_INVAL, 3));
     54 	check(parse("{\"a\": {2}}", JSMN_ERROR_INVAL, 3));
     55 	check(parse("{\"a\": {2: 3}}", JSMN_ERROR_INVAL, 3));
     56 	check(parse("{\"a\": {\"a\": 2 3}}", JSMN_ERROR_INVAL, 5));
     57 	/* FIXME */
     58 	/*check(parse("{\"a\"}", JSMN_ERROR_INVAL, 2));*/
     59 	/*check(parse("{\"a\": 1, \"b\"}", JSMN_ERROR_INVAL, 4));*/
     60 	/*check(parse("{\"a\",\"b\":1}", JSMN_ERROR_INVAL, 4));*/
     61 	/*check(parse("{\"a\":1,}", JSMN_ERROR_INVAL, 4));*/
     62 	/*check(parse("{\"a\":\"b\":\"c\"}", JSMN_ERROR_INVAL, 4));*/
     63 	/*check(parse("{,}", JSMN_ERROR_INVAL, 4));*/
     64 #endif
     65 	return 0;
     66 }
     67 
     68 int test_array(void) {
     69 	/* FIXME */
     70 	/*check(parse("[10}", JSMN_ERROR_INVAL, 3));*/
     71 	/*check(parse("[1,,3]", JSMN_ERROR_INVAL, 3)*/
     72 	check(parse("[10]", 2, 2,
     73 				JSMN_ARRAY, -1, -1, 1,
     74 				JSMN_PRIMITIVE, "10"));
     75 	check(parse("{\"a\": 1]", JSMN_ERROR_INVAL, 3));
     76 	/* FIXME */
     77 	/*check(parse("[\"a\": 1]", JSMN_ERROR_INVAL, 3));*/
     78 	return 0;
     79 }
     80 
     81 int test_primitive(void) {
     82 	check(parse("{\"boolVar\" : true }", 3, 3,
     83 				JSMN_OBJECT, -1, -1, 1,
     84 				JSMN_STRING, "boolVar", 1,
     85 				JSMN_PRIMITIVE, "true"));
     86 	check(parse("{\"boolVar\" : false }", 3, 3,
     87 				JSMN_OBJECT, -1, -1, 1,
     88 				JSMN_STRING, "boolVar", 1,
     89 				JSMN_PRIMITIVE, "false"));
     90 	check(parse("{\"nullVar\" : null }", 3, 3,
     91 				JSMN_OBJECT, -1, -1, 1,
     92 				JSMN_STRING, "nullVar", 1,
     93 				JSMN_PRIMITIVE, "null"));
     94 	check(parse("{\"intVar\" : 12}", 3, 3,
     95 				JSMN_OBJECT, -1, -1, 1,
     96 				JSMN_STRING, "intVar", 1,
     97 				JSMN_PRIMITIVE, "12"));
     98 	check(parse("{\"floatVar\" : 12.345}", 3, 3,
     99 				JSMN_OBJECT, -1, -1, 1,
    100 				JSMN_STRING, "floatVar", 1,
    101 				JSMN_PRIMITIVE, "12.345"));
    102 	return 0;
    103 }
    104 
    105 int test_string(void) {
    106 	check(parse("{\"strVar\" : \"hello world\"}", 3, 3,
    107 				JSMN_OBJECT, -1, -1, 1,
    108 				JSMN_STRING, "strVar", 1,
    109 				JSMN_STRING, "hello world", 0));
    110 	check(parse("{\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"}", 3, 3,
    111 				JSMN_OBJECT, -1, -1, 1,
    112 				JSMN_STRING, "strVar", 1,
    113 				JSMN_STRING, "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\", 0));
    114 	check(parse("{\"strVar\": \"\"}", 3, 3,
    115 				JSMN_OBJECT, -1, -1, 1,
    116 				JSMN_STRING, "strVar", 1,
    117 				JSMN_STRING, "", 0));
    118 	check(parse("{\"a\":\"\\uAbcD\"}", 3, 3,
    119 				JSMN_OBJECT, -1, -1, 1,
    120 				JSMN_STRING, "a", 1,
    121 				JSMN_STRING, "\\uAbcD", 0));
    122 	check(parse("{\"a\":\"str\\u0000\"}", 3, 3,
    123 				JSMN_OBJECT, -1, -1, 1,
    124 				JSMN_STRING, "a", 1,
    125 				JSMN_STRING, "str\\u0000", 0));
    126 	check(parse("{\"a\":\"\\uFFFFstr\"}", 3, 3,
    127 				JSMN_OBJECT, -1, -1, 1,
    128 				JSMN_STRING, "a", 1,
    129 				JSMN_STRING, "\\uFFFFstr", 0));
    130 	check(parse("{\"a\":[\"\\u0280\"]}", 4, 4,
    131 				JSMN_OBJECT, -1, -1, 1,
    132 				JSMN_STRING, "a", 1,
    133 				JSMN_ARRAY, -1, -1, 1,
    134 				JSMN_STRING, "\\u0280", 0));
    135 
    136 	check(parse("{\"a\":\"str\\uFFGFstr\"}", JSMN_ERROR_INVAL, 3));
    137 	check(parse("{\"a\":\"str\\u@FfF\"}", JSMN_ERROR_INVAL, 3));
    138 	check(parse("{{\"a\":[\"\\u028\"]}", JSMN_ERROR_INVAL, 4));
    139 	return 0;
    140 }
    141 
    142 int test_partial_string(void) {
    143 	int i;
    144 	int r;
    145 	jsmn_parser p;
    146 	jsmntok_t tok[5];
    147 	const char *js = "{\"x\": \"va\\\\ue\", \"y\": \"value y\"}";
    148 
    149 	jsmn_init(&p);
    150 	for (i = 1; i <= strlen(js); i++) {
    151 		r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0]));
    152 		if (i == strlen(js)) {
    153 			check(r == 5);
    154 			check(tokeq(js, tok, 5,
    155 					JSMN_OBJECT, -1, -1, 2,
    156 					JSMN_STRING, "x", 1,
    157 					JSMN_STRING, "va\\\\ue", 0,
    158 					JSMN_STRING, "y", 1,
    159 					JSMN_STRING, "value y", 0));
    160 		} else {
    161 			check(r == JSMN_ERROR_PART);
    162 		}
    163 	}
    164 	return 0;
    165 }
    166 
    167 int test_partial_array(void) {
    168 #ifdef JSMN_STRICT
    169 	int r;
    170 	int i;
    171 	jsmn_parser p;
    172 	jsmntok_t tok[10];
    173 	const char *js = "[ 1, true, [123, \"hello\"]]";
    174 
    175 	jsmn_init(&p);
    176 	for (i = 1; i <= strlen(js); i++) {
    177 		r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0]));
    178 		if (i == strlen(js)) {
    179 			check(r == 6);
    180 			check(tokeq(js, tok, 6,
    181 					JSMN_ARRAY, -1, -1, 3,
    182 					JSMN_PRIMITIVE, "1",
    183 					JSMN_PRIMITIVE, "true",
    184 					JSMN_ARRAY, -1, -1, 2,
    185 					JSMN_PRIMITIVE, "123",
    186 					JSMN_STRING, "hello", 0));
    187 		} else {
    188 			check(r == JSMN_ERROR_PART);
    189 		}
    190 	}
    191 #endif
    192 	return 0;
    193 }
    194 
    195 int test_array_nomem(void) {
    196 	int i;
    197 	int r;
    198 	jsmn_parser p;
    199 	jsmntok_t toksmall[10], toklarge[10];
    200 	const char *js;
    201 
    202 	js = "  [ 1, true, [123, \"hello\"]]";
    203 
    204 	for (i = 0; i < 6; i++) {
    205 		jsmn_init(&p);
    206 		memset(toksmall, 0, sizeof(toksmall));
    207 		memset(toklarge, 0, sizeof(toklarge));
    208 		r = jsmn_parse(&p, js, strlen(js), toksmall, i);
    209 		check(r == JSMN_ERROR_NOMEM);
    210 
    211 		memcpy(toklarge, toksmall, sizeof(toksmall));
    212 
    213 		r = jsmn_parse(&p, js, strlen(js), toklarge, 10);
    214 		check(r >= 0);
    215 		check(tokeq(js, toklarge, 4,
    216 					JSMN_ARRAY, -1, -1, 3,
    217 					JSMN_PRIMITIVE, "1",
    218 					JSMN_PRIMITIVE, "true",
    219 					JSMN_ARRAY, -1, -1, 2,
    220 					JSMN_PRIMITIVE, "123",
    221 					JSMN_STRING, "hello", 0));
    222 	}
    223 	return 0;
    224 }
    225 
    226 int test_unquoted_keys(void) {
    227 #ifndef JSMN_STRICT
    228 	int r;
    229 	jsmn_parser p;
    230 	jsmntok_t tok[10];
    231 	const char *js;
    232 
    233 	jsmn_init(&p);
    234 	js = "key1: \"value\"\nkey2 : 123";
    235 
    236 	r = jsmn_parse(&p, js, strlen(js), tok, 10);
    237 	check(r >= 0);
    238 	check(tokeq(js, tok, 4,
    239 				JSMN_PRIMITIVE, "key1",
    240 				JSMN_STRING, "value", 0,
    241 				JSMN_PRIMITIVE, "key2",
    242 				JSMN_PRIMITIVE, "123"));
    243 #endif
    244 	return 0;
    245 }
    246 
    247 int test_issue_22(void) {
    248 	int r;
    249 	jsmn_parser p;
    250 	jsmntok_t tokens[128];
    251 	const char *js;
    252 
    253 	js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, "
    254 		"\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", "
    255 		"\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], "
    256 		"\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, "
    257 		"\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", "
    258 		"\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", "
    259 		"\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], "
    260 		"\"tilewidth\":32, \"version\":1, \"width\":10 }";
    261 	jsmn_init(&p);
    262 	r = jsmn_parse(&p, js, strlen(js), tokens, 128);
    263 	check(r >= 0);
    264 	return 0;
    265 }
    266 
    267 int test_issue_27(void) {
    268 	const char *js =
    269 		"{ \"name\" : \"Jack\", \"age\" : 27 } { \"name\" : \"Anna\", ";
    270 	check(parse(js, JSMN_ERROR_PART, 8));
    271 	return 0;
    272 }
    273 
    274 int test_input_length(void) {
    275 	const char *js;
    276 	int r;
    277 	jsmn_parser p;
    278 	jsmntok_t tokens[10];
    279 
    280 	js = "{\"a\": 0}garbage";
    281 
    282 	jsmn_init(&p);
    283 	r = jsmn_parse(&p, js, 8, tokens, 10);
    284 	check(r == 3);
    285 	check(tokeq(js, tokens, 3,
    286 				JSMN_OBJECT, -1, -1, 1,
    287 				JSMN_STRING, "a", 1,
    288 				JSMN_PRIMITIVE, "0"));
    289 	return 0;
    290 }
    291 
    292 int test_count(void) {
    293 	jsmn_parser p;
    294 	const char *js;
    295 
    296 	js = "{}";
    297 	jsmn_init(&p);
    298 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
    299 
    300 	js = "[]";
    301 	jsmn_init(&p);
    302 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
    303 
    304 	js = "[[]]";
    305 	jsmn_init(&p);
    306 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2);
    307 
    308 	js = "[[], []]";
    309 	jsmn_init(&p);
    310 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
    311 
    312 	js = "[[], []]";
    313 	jsmn_init(&p);
    314 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
    315 
    316 	js = "[[], [[]], [[], []]]";
    317 	jsmn_init(&p);
    318 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
    319 
    320 	js = "[\"a\", [[], []]]";
    321 	jsmn_init(&p);
    322 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
    323 
    324 	js = "[[], \"[], [[]]\", [[]]]";
    325 	jsmn_init(&p);
    326 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
    327 
    328 	js = "[1, 2, 3]";
    329 	jsmn_init(&p);
    330 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4);
    331 
    332 	js = "[1, 2, [3, \"a\"], null]";
    333 	jsmn_init(&p);
    334 	check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
    335 
    336 	return 0;
    337 }
    338 
    339 
    340 int test_nonstrict(void) {
    341 #ifndef JSMN_STRICT
    342 	const char *js;
    343 	js = "a: 0garbage";
    344 	check(parse(js, 2, 2,
    345 				JSMN_PRIMITIVE, "a",
    346 				JSMN_PRIMITIVE, "0garbage"));
    347 
    348 	js = "Day : 26\nMonth : Sep\n\nYear: 12";
    349 	check(parse(js, 6, 6,
    350 				JSMN_PRIMITIVE, "Day",
    351 				JSMN_PRIMITIVE, "26",
    352 				JSMN_PRIMITIVE, "Month",
    353 				JSMN_PRIMITIVE, "Sep",
    354 				JSMN_PRIMITIVE, "Year",
    355 				JSMN_PRIMITIVE, "12"));
    356 
    357 	//nested {s don't cause a parse error.
    358 	js = "\"key {1\": 1234";
    359 	check(parse(js, 2, 2,
    360 		              JSMN_STRING, "key {1", 1,
    361 		              JSMN_PRIMITIVE, "1234"));
    362 
    363 
    364 #endif
    365 	return 0;
    366 }
    367 
    368 int test_unmatched_brackets(void) {
    369 	const char *js;
    370 	js = "\"key 1\": 1234}";
    371 	check(parse(js, JSMN_ERROR_INVAL, 2));
    372 	js = "{\"key 1\": 1234";
    373 	check(parse(js, JSMN_ERROR_PART, 3));
    374 	js = "{\"key 1\": 1234}}";
    375 	check(parse(js, JSMN_ERROR_INVAL, 3));
    376 	js = "\"key 1\"}: 1234";
    377 	check(parse(js, JSMN_ERROR_INVAL, 3));
    378 	js = "{\"key {1\": 1234}";
    379 	check(parse(js, 3, 3,
    380 				JSMN_OBJECT, 0, 16, 1,
    381 				JSMN_STRING, "key {1", 1,
    382 				JSMN_PRIMITIVE, "1234"));
    383 	js = "{{\"key 1\": 1234}";
    384 	check(parse(js, JSMN_ERROR_PART, 4));
    385 	return 0;
    386 }
    387 
    388 int main(void) {
    389 	test(test_empty, "test for a empty JSON objects/arrays");
    390 	test(test_object, "test for a JSON objects");
    391 	test(test_array, "test for a JSON arrays");
    392 	test(test_primitive, "test primitive JSON data types");
    393 	test(test_string, "test string JSON data types");
    394 
    395 	test(test_partial_string, "test partial JSON string parsing");
    396 	test(test_partial_array, "test partial array reading");
    397 	test(test_array_nomem, "test array reading with a smaller number of tokens");
    398 	test(test_unquoted_keys, "test unquoted keys (like in JavaScript)");
    399 	test(test_input_length, "test strings that are not null-terminated");
    400 	test(test_issue_22, "test issue #22");
    401 	test(test_issue_27, "test issue #27");
    402 	test(test_count, "test tokens count estimation");
    403 	test(test_nonstrict, "test for non-strict mode");
    404 	test(test_unmatched_brackets, "test for unmatched brackets");
    405 	printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed);
    406 	return (test_failed > 0);
    407 }
    408