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