Implement JSON parsing and serialization.
[sliver-openvswitch.git] / tests / json.at
1 m4_define([JSON_CHECK_POSITIVE], 
2   [AT_SETUP([$1])
3    AT_KEYWORDS([json positive])
4    AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
5    OVS_CHECK_LCOV([test-json $4 input], [0], [$3
6 ], [])
7    AT_CLEANUP])
8
9 m4_define([JSON_CHECK_NEGATIVE], 
10   [AT_SETUP([$1])
11    AT_KEYWORDS([json negative])
12    AT_CHECK([printf %s "AS_ESCAPE([$2])" > input])
13    OVS_CHECK_LCOV([test-json $4 input], [1], [$3
14 ])
15    AT_CLEANUP])
16
17 AT_BANNER([JSON -- arrays])
18
19 JSON_CHECK_POSITIVE([empty array], [[ [   ] ]], [[[]]])
20 JSON_CHECK_POSITIVE([single-element array], [[ [ 1 ] ]], [[[1]]])
21 JSON_CHECK_POSITIVE([2-element array], [[ [ 1, 2 ] ]], [[[1,2]]])
22 JSON_CHECK_POSITIVE([many-element array],
23                     [[ [ 1, 2, 3, 4, 5 ] ]],
24                     [[[1,2,3,4,5]]])
25 JSON_CHECK_NEGATIVE([missing comma], [[ [ 1, 2, 3 4, 5 ] ]],
26                     [error: syntax error expecting '@:>@' or ','])
27 JSON_CHECK_NEGATIVE([trailing comma not allowed], 
28                     [[[1,2,]]], [error: syntax error expecting value])
29 JSON_CHECK_NEGATIVE([doubled comma not allowed], 
30                     [[[1,,2]]], [error: syntax error expecting value])
31
32 AT_BANNER([JSON -- strings])
33
34 JSON_CHECK_POSITIVE([empty string], [[[ "" ]]], [[[""]]])
35 JSON_CHECK_POSITIVE([1-character strings], 
36                     [[[ "a", "b", "c" ]]],
37                     [[["a","b","c"]]])
38 JSON_CHECK_POSITIVE([escape sequences], 
39   [[[ " \" \\ \/ \b \f \n \r \t" ]]],
40   [[[" \" \\ / \b \f \n \r \t"]]])
41 JSON_CHECK_POSITIVE([Unicode escape sequences], 
42   [[[ " \u0022 \u005c \u002F \u0008 \u000c \u000A \u000d \u0009" ]]],
43   [[[" \" \\ / \b \f \n \r \t"]]])
44 JSON_CHECK_POSITIVE([surrogate pairs],
45   [[["\ud834\udd1e"]]],
46   [[["𝄞"]]])
47 JSON_CHECK_NEGATIVE([a string by itself is not valid JSON], ["xxx"],
48                     [error: syntax error at beginning of input])
49 JSON_CHECK_NEGATIVE([end of line in quoted string],
50                     [[["xxx
51 "]]],
52                     [error: U+000A must be escaped in quoted string])
53 JSON_CHECK_NEGATIVE([formfeed in quoted string],
54                     [[["xxx\f"]]],
55                     [error: U+000C must be escaped in quoted string])
56 JSON_CHECK_NEGATIVE([bad escape in quoted string],
57                     [[["\x12"]]],
58                     [error: bad escape \x])
59 JSON_CHECK_NEGATIVE([\u must be followed by 4 hex digits],
60                     [[["\u1x"]]],
61                     [error: malformed \u escape])
62 JSON_CHECK_NEGATIVE([isolated leading surrogate not allowed],
63                     [[["\ud834xxx"]]],
64                     [error: malformed escaped surrogate pair])
65 JSON_CHECK_NEGATIVE([surrogatess must paired properly],
66                     [[["\ud834\u1234"]]],
67                     [error: second half of escaped surrogate pair is not trailing surrogate])
68 JSON_CHECK_NEGATIVE([null bytes not allowed], 
69                     [[["\u0000"]]], 
70                     [error: null bytes not supported in quoted strings])
71
72 AT_SETUP([end of input in quoted string])
73 AT_KEYWORDS([json negative])
74 AT_CHECK([printf '\"xxx' | test-json -], [1],
75   [error: unexpected end of input in quoted string
76 ])
77 AT_CLEANUP
78
79 AT_BANNER([JSON -- objects])
80
81 JSON_CHECK_POSITIVE([empty object], [[{ }]], [[{}]])
82 JSON_CHECK_POSITIVE([simple object],
83                     [[{"b": 2, "a": 1, "c": 3}]],
84                     [[{"a":1,"b":2,"c":3}]])
85 JSON_CHECK_NEGATIVE([bad value], [[{"a": }, "b": 2]], 
86                     [error: syntax error expecting value])
87 JSON_CHECK_NEGATIVE([missing colon], [[{"b": 2, "a" 1, "c": 3}]],
88                     [error: syntax error parsing object expecting ':'])
89 JSON_CHECK_NEGATIVE([missing comma], [[{"b": 2 "a" 1, "c": 3}]],
90                     [error: syntax error expecting '}' or ','])
91 JSON_CHECK_NEGATIVE([trailing comma not allowed],
92                     [[{"b": 2, "a": 1, "c": 3, }]],
93                     [[error: syntax error parsing object expecting string]])
94 JSON_CHECK_NEGATIVE([doubled comma not allowed],
95                     [[{"b": 2, "a": 1,, "c": 3}]],
96                     [[error: syntax error parsing object expecting string]])
97 JSON_CHECK_NEGATIVE([names must be strings],
98                     [[{1: 2}]],
99                     [[error: syntax error parsing object expecting string]])
100
101 AT_BANNER([JSON -- literal names])
102
103 JSON_CHECK_POSITIVE([null], [[[ null ]]], [[[null]]])
104 JSON_CHECK_POSITIVE([false], [[[ false ]]], [[[false]]])
105 JSON_CHECK_POSITIVE([true], [[[ true ]]], [[[true]]])
106 JSON_CHECK_NEGATIVE([a literal by itself is not valid JSON], [null],
107                     [error: syntax error at beginning of input])
108 JSON_CHECK_NEGATIVE([nullify is invalid], [[[ nullify ]]], 
109                     [error: invalid keyword 'nullify'])
110 JSON_CHECK_NEGATIVE([nubs is invalid], [[[ nubs ]]],
111                     [error: invalid keyword 'nubs'])
112 JSON_CHECK_NEGATIVE([xxx is invalid], [[[ xxx ]]], 
113                     [error: invalid keyword 'xxx'])
114
115 AT_BANNER([JSON -- numbers])
116
117 JSON_CHECK_POSITIVE(
118   [integers expressed as reals],
119   [[[1.0000000000,
120      2.00000000000000000000000000000000000,
121      2e5,
122      2.1234e4,
123      2.1230e3,
124      0e-10000,
125      0e10000]]],
126   [[[1,2,200000,21234,2123,0,0]]])
127 JSON_CHECK_POSITIVE(
128   [large integers], 
129   [[[9223372036854775807, -9223372036854775808]]],
130   [[[9223372036854775807,-9223372036854775808]]])
131 JSON_CHECK_POSITIVE(
132   [large integers expressed as reals], 
133   [[[9223372036854775807.0, -9223372036854775808.0,
134      92233720.36854775807e11, -9.223372036854775808e18]]],
135   [[[9223372036854775807,-9223372036854775808,9223372036854775807,-9223372036854775808]]])
136 # It seems likely that the following test will fail on some system that
137 # rounds slightly differently in arithmetic or in printf, but I'd like
138 # to keep it this way until we run into such a system.
139 JSON_CHECK_POSITIVE(
140   [large integers that overflow to reals], 
141   [[[9223372036854775807000, -92233720368547758080000]]],
142   [[[9.22337203685478e+21,-9.22337203685478e+22]]])
143
144 JSON_CHECK_POSITIVE(
145   [negative zero],
146   [[[-0, -0.0, 1e-9999, -1e-9999]]],
147   [[[0,0,0,0]]])
148
149 JSON_CHECK_POSITIVE(
150   [reals], 
151   [[[0.0, 1.0, 2.0, 3.0, 3.5, 81.250]]],
152   [[[0,1,2,3,3.5,81.25]]])
153 JSON_CHECK_POSITIVE(
154   [scientific notation],
155   [[[1e3, 1E3, 2.5E2, 1e+3, 125e-3, 3.125e-2, 3125e-05, 1.525878906e-5]]],
156   [[[1000,1000,250,1000,0.125,0.03125,0.03125,1.525878906e-05]]])
157 JSON_CHECK_POSITIVE(
158   [negative reals], 
159   [[[-0, -1.0, -2.0, -3.0, -3.5, -8.1250]]],
160   [[[0,-1,-2,-3,-3.5,-8.125]]])
161 JSON_CHECK_POSITIVE(
162   [negative scientific notation],
163   [[[-1e3, -1E3, -2.5E2, -1e+3, -125e-3, -3.125e-2, -3125e-05, -1.525878906e-5]]],
164   [[[-1000,-1000,-250,-1000,-0.125,-0.03125,-0.03125,-1.525878906e-05]]])
165 JSON_CHECK_POSITIVE(
166   [1e-9999 underflows to 0],
167   [[[1e-9999]]],
168   [[[0]]])
169 JSON_CHECK_NEGATIVE([a number by itself is not valid JSON], [1],
170                     [error: syntax error at beginning of input])
171 JSON_CHECK_NEGATIVE(
172   [leading zeros not allowed],
173   [[[0123]]],
174   [error: leading zeros not allowed])
175 JSON_CHECK_NEGATIVE(
176   [1e9999 is too big],
177   [[[1e9999]]],
178   [error: number outside valid range])
179 JSON_CHECK_NEGATIVE(
180   [exponent bigger than INT_MAX],
181   [[[1e9999999999999999999]]],
182   [error: exponent outside valid range])
183 JSON_CHECK_NEGATIVE(
184   [decimal point must be followed by digit],
185   [[[1.]]],
186   [error: decimal point must be followed by digit])
187 JSON_CHECK_NEGATIVE(
188   [exponent must contain at least one digit (1)],
189   [[[1e]]],
190   [error: exponent must contain at least one digit])
191 JSON_CHECK_NEGATIVE(
192   [exponent must contain at least one digit (2)],
193   [[[1e+]]],
194   [error: exponent must contain at least one digit])
195 JSON_CHECK_NEGATIVE(
196   [exponent must contain at least one digit (3)],
197   [[[1e-]]],
198   [error: exponent must contain at least one digit])
199
200 AT_BANNER([JSON -- RFC 4627 examples])
201
202 JSON_CHECK_POSITIVE([RFC 4267 object example],
203 [[{
204    "Image": {
205        "Width":  800,
206        "Height": 600,
207        "Title":  "View from 15th Floor",
208        "Thumbnail": {
209            "Url":    "http://www.example.com/image/481989943",
210            "Height": 125,
211            "Width":  "100"
212        },
213        "IDs": [116, 943, 234, 38793]
214      }
215 }]],
216 [[{"Image":{"Height":600,"IDs":[116,943,234,38793],"Thumbnail":{"Height":125,"Url":"http://www.example.com/image/481989943","Width":"100"},"Title":"View from 15th Floor","Width":800}}]])
217
218 JSON_CHECK_POSITIVE([RFC 4267 array example],
219 [[[
220    {
221       "precision": "zip",
222       "Latitude":  37.7668,
223       "Longitude": -122.3959,
224       "Address":   "",
225       "City":      "SAN FRANCISCO",
226       "State":     "CA",
227       "Zip":       "94107",
228       "Country":   "US"
229    },
230    {
231       "precision": "zip",
232       "Latitude":  37.371991,
233       "Longitude": -122.026020,
234       "Address":   "",
235       "City":      "SUNNYVALE",
236       "State":     "CA",
237       "Zip":       "94085",
238       "Country":   "US"
239    }
240 ]]],
241 [[[{"Address":"","City":"SAN FRANCISCO","Country":"US","Latitude":37.7668,"Longitude":-122.3959,"State":"CA","Zip":"94107","precision":"zip"},{"Address":"","City":"SUNNYVALE","Country":"US","Latitude":37.371991,"Longitude":-122.02602,"State":"CA","Zip":"94085","precision":"zip"}]]])
242
243 AT_BANNER([JSON -- pathological cases])
244
245 JSON_CHECK_NEGATIVE([trailing garbage], [[[1]null]],
246                     [error: trailing garbage at end of input])
247 JSON_CHECK_NEGATIVE([formfeeds are not valid white space],
248                     [[[\f]]], [error: invalid character U+000c])
249 JSON_CHECK_NEGATIVE([';' is not a valid token],
250                     [;], [error: invalid character ';'])
251 JSON_CHECK_NEGATIVE([arrays nesting too deep],
252                     [m4_for([i], [0], [1002], [1], [@<:@])dnl
253                      m4_for([i], [0], [1002], [1], [@:>@])],
254                     [error: input exceeds maximum nesting depth 1000])
255 JSON_CHECK_NEGATIVE([objects nesting too deep],
256                     [m4_for([i], [0], [1002], [1], [{"x":])dnl
257                      m4_for([i], [0], [1002], [1], [}])],
258                     [error: input exceeds maximum nesting depth 1000])
259
260 AT_SETUP([input may not be empty])
261 AT_KEYWORDS([json negative])
262 AT_CHECK([test-json /dev/null], [1], [error: empty input stream
263 ])
264 AT_CLEANUP
265
266 AT_BANNER([JSON -- multiple inputs])
267
268 JSON_CHECK_POSITIVE([multiple adjacent objects], [[{}{}{}]], [[{}
269 {}
270 {}]],
271   [--multiple])
272
273 JSON_CHECK_POSITIVE([multiple space-separated objects], [[{}  {}  {}]], [[{}
274 {}
275 {}]],
276   [--multiple])
277
278 JSON_CHECK_POSITIVE([multiple objects on separate lines], [[{}
279 {}
280 {}]], [[{}
281 {}
282 {}]],
283   [--multiple])
284
285 JSON_CHECK_POSITIVE([multiple objects and arrays], [[{}[]{}[]]], [[{}
286 []
287 {}
288 []]],
289   [--multiple])
290
291 JSON_CHECK_NEGATIVE([garbage between multiple objects], [[{}x{}]], [[{}
292 error: invalid keyword 'x'
293 {}]], [--multiple])
294
295 JSON_CHECK_NEGATIVE([garbage after multiple objects], [[{}{}x]], [[{}
296 {}
297 error: invalid keyword 'x']], [--multiple])