1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2012, Joyent, Inc.  All rights reserved.
14  */
15 
16 /*
17  * General functional tests of JSON parser for json().
18  */
19 
20 #pragma D option quiet
21 #pragma D option strsize=1k
22 
23 /*
24  * The hard tabs here are deliberate to assure constant behavior across
25  * the various cpp variants we might run against (and their various bugs).
26  * See illumos/cpp#2 for details.
27  */
28 #define	TST(name)				\
29 	printf("\ntst\t|%s|\n", name)
30 #define	IN2(vala, valb)				\
31 	in = strjoin(vala, valb);		\
32 	printf("in\t|%s|\n", in)
33 #define	IN(val)					\
34 	in = val;				\
35 	printf("in\t|%s|\n", in)
36 #define	SEL(ss)					\
37 	out = json(in, ss);			\
38 	printf("sel\t|%s|\nout\t|%s|\n", ss,	\
39 	    out != NULL ? out : "<NULL>")
40 
41 BEGIN
42 {
43 	TST("empty array");
44 	IN("[]");
45 	SEL("0");
46 
47 	TST("one-element array: integer");
48 	IN("[1]");
49 	SEL("0");
50 	SEL("1");
51 	SEL("100");
52 	SEL("-1");
53 
54 	TST("one-element array: hex integer (not in spec, not supported)");
55 	IN("[0x1000]");
56 	SEL("0");
57 
58 	TST("one-element array: float");
59 	IN("[1.5001]");
60 	SEL("0");
61 
62 	TST("one-element array: float + exponent");
63 	IN("[16.3e10]");
64 	SEL("0");
65 
66 	TST("one-element array: integer + whitespace");
67 	IN("[ \t   5\t]");
68 	SEL("0");
69 
70 	TST("one-element array: integer + exponent + whitespace");
71 	IN("[ \t    \t 16E10  \t ]");
72 	SEL("0");
73 
74 	TST("one-element array: string");
75 	IN("[\"alpha\"]");
76 	SEL("0");
77 
78 	TST("alternative first-element indexing");
79 	IN("[1,5,10,15,20]");
80 	SEL("[0]");
81 	SEL("[3]");
82 	SEL("[4]");
83 	SEL("[5]");
84 
85 	TST("one-element array: object");
86 	IN("[ { \"first\": true, \"second\": false }]");
87 	SEL("0.first");
88 	SEL("0.second");
89 	SEL("0.third");
90 
91 	TST("many-element array: integers");
92 	IN("[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]");
93 	SEL("10"); /* F(10) = 55 */
94 	SEL("14"); /* F(14) = 377 */
95 	SEL("19");
96 
97 	TST("many-element array: multiple types");
98 	IN2("[\"string\",32,true,{\"a\":9,\"b\":false},100.3e10,false,200.5,",
99 	    "{\"key\":\"val\"},null]");
100 	SEL("0");
101 	SEL("0.notobject");
102 	SEL("1");
103 	SEL("2");
104 	SEL("3");
105 	SEL("3.a");
106 	SEL("3.b");
107 	SEL("3.c");
108 	SEL("4");
109 	SEL("5");
110 	SEL("6");
111 	SEL("7");
112 	SEL("7.key");
113 	SEL("7.key.notobject");
114 	SEL("7.nonexist");
115 	SEL("8");
116 	SEL("9");
117 
118 	TST("many-element array: multiple types + whitespace");
119 	IN2("\n[\t\"string\" ,\t32 , true\t,\t {\"a\":  9,\t\"b\": false},\t\t",
120 	    "100.3e10, false, 200.5,{\"key\" \t:\n \"val\"},\t\t null ]\t\t");
121 	SEL("0");
122 	SEL("0.notobject");
123 	SEL("1");
124 	SEL("2");
125 	SEL("3");
126 	SEL("3.a");
127 	SEL("3.b");
128 	SEL("3.c");
129 	SEL("4");
130 	SEL("5");
131 	SEL("6");
132 	SEL("7");
133 	SEL("7.key");
134 	SEL("7.key.notobject");
135 	SEL("7.nonexist");
136 	SEL("8");
137 	SEL("9");
138 
139 	TST("two-element array: various string escape codes");
140 	IN2("[\"abcd \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u0000 \\uf00F \", ",
141 	    "\"final\"]");
142 	SEL("0");
143 	SEL("1");
144 
145 	TST("three-element array: broken escape code");
146 	IN("[\"fine here\", \"dodgey \\u00AZ\", \"wont get here\"]");
147 	SEL("0");
148 	SEL("1");
149 	SEL("2");
150 
151 	TST("nested objects");
152 	IN2("{ \"top\": { \"mid\"  : { \"legs\": \"feet\" }, \"number\": 9, ",
153 	    "\"array\":[0,1,{\"a\":true,\"bb\":[1,2,false,{\"x\":\"yz\"}]}]}}");
154 	SEL("top");
155 	SEL("fargo");
156 	SEL("top.mid");
157 	SEL("top.centre");
158 	SEL("top.mid.legs");
159 	SEL("top.mid.number");
160 	SEL("top.mid.array");
161 	SEL("top.number");
162 	SEL("top.array");
163 	SEL("top.array[0]");
164 	SEL("top.array[1]");
165 	SEL("top.array[2]");
166 	SEL("top.array[2].a");
167 	SEL("top.array[2].b");
168 	SEL("top.array[2].bb");
169 	SEL("top.array[2].bb[0]");
170 	SEL("top.array[2].bb[1]");
171 	SEL("top.array[2].bb[2]");
172 	SEL("top.array[2].bb[3]");
173 	SEL("top.array[2].bb[3].x");
174 	SEL("top.array[2].bb[3].x.nofurther");
175 	SEL("top.array[2].bb[4]");
176 	SEL("top.array[3]");
177 
178 	exit(0);
179 }
180 
181 ERROR
182 {
183 	exit(1);
184 }
185