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#define	TST(name)				\
24	printf("\ntst |%s|\n", name)
25#define	IN2(vala, valb)				\
26	in = strjoin(vala, valb);		\
27	printf("in  |%s|\n", in)
28#define	IN(val)					\
29	in = val;				\
30	printf("in  |%s|\n", in)
31#define	SEL(ss)					\
32	out = json(in, ss);			\
33	printf("sel |%s|\nout |%s|\n", ss,	\
34	    out != NULL ? out : "<NULL>")
35
36BEGIN
37{
38	TST("empty array");
39	IN("[]");
40	SEL("0");
41
42	TST("one-element array: integer");
43	IN("[1]");
44	SEL("0");
45	SEL("1");
46	SEL("100");
47	SEL("-1");
48
49	TST("one-element array: hex integer (not in spec, not supported)");
50	IN("[0x1000]");
51	SEL("0");
52
53	TST("one-element array: float");
54	IN("[1.5001]");
55	SEL("0");
56
57	TST("one-element array: float + exponent");
58	IN("[16.3e10]");
59	SEL("0");
60
61	TST("one-element array: integer + whitespace");
62	IN("[ \t   5\t]");
63	SEL("0");
64
65	TST("one-element array: integer + exponent + whitespace");
66	IN("[ \t    \t 16E10  \t ]");
67	SEL("0");
68
69	TST("one-element array: string");
70	IN("[\"alpha\"]");
71	SEL("0");
72
73	TST("alternative first-element indexing");
74	IN("[1,5,10,15,20]");
75	SEL("[0]");
76	SEL("[3]");
77	SEL("[4]");
78	SEL("[5]");
79
80	TST("one-element array: object");
81	IN("[ { \"first\": true, \"second\": false }]");
82	SEL("0.first");
83	SEL("0.second");
84	SEL("0.third");
85
86	TST("many-element array: integers");
87	IN("[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]");
88	SEL("10"); /* F(10) = 55 */
89	SEL("14"); /* F(14) = 377 */
90	SEL("19");
91
92	TST("many-element array: multiple types");
93	IN2("[\"string\",32,true,{\"a\":9,\"b\":false},100.3e10,false,200.5,",
94	    "{\"key\":\"val\"},null]");
95	SEL("0");
96	SEL("0.notobject");
97	SEL("1");
98	SEL("2");
99	SEL("3");
100	SEL("3.a");
101	SEL("3.b");
102	SEL("3.c");
103	SEL("4");
104	SEL("5");
105	SEL("6");
106	SEL("7");
107	SEL("7.key");
108	SEL("7.key.notobject");
109	SEL("7.nonexist");
110	SEL("8");
111	SEL("9");
112
113	TST("many-element array: multiple types + whitespace");
114	IN2("\n[\t\"string\" ,\t32 , true\t,\t {\"a\":  9,\t\"b\": false},\t\t",
115	    "100.3e10, false, 200.5,{\"key\" \t:\n \"val\"},\t\t null ]\t\t");
116	SEL("0");
117	SEL("0.notobject");
118	SEL("1");
119	SEL("2");
120	SEL("3");
121	SEL("3.a");
122	SEL("3.b");
123	SEL("3.c");
124	SEL("4");
125	SEL("5");
126	SEL("6");
127	SEL("7");
128	SEL("7.key");
129	SEL("7.key.notobject");
130	SEL("7.nonexist");
131	SEL("8");
132	SEL("9");
133
134	TST("two-element array: various string escape codes");
135	IN2("[\"abcd \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u0000 \\uf00F \", ",
136	    "\"final\"]");
137	SEL("0");
138	SEL("1");
139
140	TST("three-element array: broken escape code");
141	IN("[\"fine here\", \"dodgey \\u00AZ\", \"wont get here\"]");
142	SEL("0");
143	SEL("1");
144	SEL("2");
145
146	TST("nested objects");
147	IN2("{ \"top\": { \"mid\"  : { \"legs\": \"feet\" }, \"number\": 9, ",
148	    "\"array\":[0,1,{\"a\":true,\"bb\":[1,2,false,{\"x\":\"yz\"}]}]}}");
149	SEL("top");
150	SEL("fargo");
151	SEL("top.mid");
152	SEL("top.centre");
153	SEL("top.mid.legs");
154	SEL("top.mid.number");
155	SEL("top.mid.array");
156	SEL("top.number");
157	SEL("top.array");
158	SEL("top.array[0]");
159	SEL("top.array[1]");
160	SEL("top.array[2]");
161	SEL("top.array[2].a");
162	SEL("top.array[2].b");
163	SEL("top.array[2].bb");
164	SEL("top.array[2].bb[0]");
165	SEL("top.array[2].bb[1]");
166	SEL("top.array[2].bb[2]");
167	SEL("top.array[2].bb[3]");
168	SEL("top.array[2].bb[3].x");
169	SEL("top.array[2].bb[3].x.nofurther");
170	SEL("top.array[2].bb[4]");
171	SEL("top.array[3]");
172
173	exit(0);
174}
175
176ERROR
177{
178	exit(1);
179}
180