3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
11 # This file implements tests for the JSON5 enhancements to the
12 # JSON SQL functions extension to the SQLite library.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set testprefix json501
19 # From https://spec.json5.org/#introduction
21 #-----------------------------------------------------------------------------
24 # The following ECMAScript 5.1 features, which are not supported in JSON, have
25 # been extended to JSON5.
29 # 1) Object keys may be an ECMAScript 5.1 IdentifierName.
30 # 2) Objects may have a single trailing comma.
34 # 3) Arrays may have a single trailing comma.
38 # 4) Strings may be single quoted.
39 # 5) Strings may span multiple lines by escaping new line characters.
40 # 6) Strings may include character escapes.
44 # 7) Numbers may be hexadecimal.
45 # 8) Numbers may have a leading or trailing decimal point.
46 # 9) Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
47 # 10) Numbers may begin with an explicit plus sign.
51 # 11) Single and multi-line comments are allowed.
55 # 12) Additional white space characters are allowed.
56 #-----------------------------------------------------------------------------
58 # Test number in this file are of the form X.Y where X is one of the item
59 # numbers in the feature list above and Y is the test sequence number.
62 ###############################################################################
63 # 1) Object keys may be an ECMAScript 5.1 IdentifierName.
65 WITH c(x) AS (VALUES('{a:5,b:6}'))
66 SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
67 } {5 {{"a":5,"b":6}} 0 1}
69 SELECT '[7,null,{a:5,b:6},[8,9]]'->>'$[2].b';
72 SELECT '{ $123 : 789 }'->>'$."$123"';
75 SELECT '{ _123$xyz : 789 }'->>'$."_123$xyz"';
78 SELECT '{ MNO_123$xyz : 789 }'->>'$."MNO_123$xyz"';
82 SELECT json('{ MNO_123$xyz : 789 }');
83 } [list {{"MNO_123$xyz":789}}]
85 do_catchsql_test 1.10 {
86 SELECT json('{ MNO_123/xyz : 789 }');
87 } {1 {malformed JSON}}
89 do_execsql_test 1.11 {
90 SELECT '{ MNO_123æxyz : 789 }'->>'MNO_123æxyz';
93 ###############################################################################
94 # 2) Objects may have a single trailing comma.
97 WITH c(x) AS (VALUES('{"a":5, "b":6, }'))
98 SELECT x->>'b', json(x), json_valid(x), NOT json_error_position(x) FROM c;
99 } {6 {{"a":5,"b":6}} 0 1}
100 do_execsql_test 2.2 {
101 SELECT '{a:5, b:6 , }'->>'b';
103 do_catchsql_test 2.3 {
104 SELECT '{a:5, b:6 ,, }'->>'b';
105 } {1 {malformed JSON}}
106 do_catchsql_test 2.4 {
107 SELECT '{a:5, b:6, ,}'->>'b';
108 } {1 {malformed JSON}}
110 ###############################################################################
111 # 3) Arrays may have a single trailing comma.
113 do_execsql_test 3.1 {
114 WITH c(x) AS (VALUES('[5, 6,]'))
115 SELECT x->>1, json(x), json_valid(x), NOT json_error_position(x) FROM c;
117 do_execsql_test 3.2 {
118 SELECT '[5, 6 , ]'->>1;
120 do_catchsql_test 3.3 {
121 SELECT '[5, 6,,]'->>1;
122 } {1 {malformed JSON}}
123 do_catchsql_test 3.4 {
124 SELECT '[5, 6 , , ]'->>1;
125 } {1 {malformed JSON}}
127 ###############################################################################
128 # 4) Strings may be single quoted.
130 do_execsql_test 4.1 {
131 WITH c(x) AS (VALUES('{"a": ''abcd''}'))
132 SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
133 } {abcd {{"a":"abcd"}} 0 1}
134 do_execsql_test 4.2 {
135 SELECT '{b: 123, ''a'': ''ab\''cd''}'->>'a';
138 ###############################################################################
139 # 5) Strings may span multiple lines by escaping new line characters.
141 do_execsql_test 5.1 {
142 WITH c(x) AS (VALUES('{a: "abc'||char(0x5c,0x0a)||'xyz"}'))
143 SELECT x->>'a', json(x), json_valid(x), NOT json_error_position(x) FROM c;
144 } {abcxyz {{"a":"abcxyz"}} 0 1}
145 do_execsql_test 5.2 {
146 SELECT ('{a: "abc'||char(0x5c,0x0d)||'xyz"}')->>'a';
148 do_execsql_test 5.3 {
149 SELECT ('{a: "abc'||char(0x5c,0x0d,0x0a)||'xyz"}')->>'a';
151 do_execsql_test 5.4 {
152 SELECT ('{a: "abc'||char(0x5c,0x2028)||'xyz"}')->>'a';
154 do_execsql_test 5.5 {
155 SELECT ('{a: "abc'||char(0x5c,0x2029)||'xyz"}')->>'a';
159 ###############################################################################
160 # 6) Strings may include character escapes.
162 do_execsql_test 6.1 {
163 SELECT ('{a: "abc'||char(0x5c,0x27)||'xyz"}')->>'a';
165 do_execsql_test 6.2 {
166 SELECT ('{a: "abc'||char(0x5c,0x22)||'xyz"}')->>'a';
168 do_execsql_test 6.3 {
169 SELECT ('{a: "abc'||char(0x5c,0x5c)||'xyz"}')->>'a';
171 do_execsql_test 6.4 {
172 SELECT hex(('{a: "abc\bxyz"}')->>'a');
174 do_execsql_test 6.5 {
175 SELECT hex(('{a: "abc\f\n\r\t\vxyz"}')->>'a');
176 } {6162630C0A0D090B78797A}
177 do_execsql_test 6.6 {
178 SELECT hex(('{a: "abc\0xyz"}')->>'a');
180 do_execsql_test 6.7 {
181 SELECT '{a: "abc\x35\x4f\x6Exyz"}'->>'a';
183 do_execsql_test 6.8 {
184 SELECT '{a: "\x6a\x6A\x6b\x6B\x6c\x6C\x6d\x6D\x6e\x6E\x6f\x6F"}'->>'a';
187 ###############################################################################
188 # 7) Numbers may be hexadecimal.
190 do_execsql_test 7.1 {
191 SELECT '{a: 0x0}'->>'a';
193 do_execsql_test 7.2 {
194 SELECT '{a: -0x0}'->>'a';
196 do_execsql_test 7.3 {
197 SELECT '{a: +0x0}'->>'a';
199 do_execsql_test 7.4 {
200 SELECT '{a: 0xabcdef}'->>'a';
202 do_execsql_test 7.5 {
203 SELECT '{a: -0xaBcDeF}'->>'a';
205 do_execsql_test 7.6 {
206 SELECT '{a: +0xABCDEF}'->>'a';
209 ###############################################################################
210 # 8) Numbers may have a leading or trailing decimal point.
212 do_execsql_test 8.1 {
213 WITH c(x) AS (VALUES('{x: 4.}')) SELECT x->>'x', json(x) FROM c;
215 do_execsql_test 8.2 {
216 WITH c(x) AS (VALUES('{x: +4.}')) SELECT x->>'x', json(x) FROM c;
218 do_execsql_test 8.3 {
219 WITH c(x) AS (VALUES('{x: -4.}')) SELECT x->>'x', json(x) FROM c;
220 } {-4.0 {{"x":-4.0}}}
221 do_execsql_test 8.3 {
222 WITH c(x) AS (VALUES('{x: .5}')) SELECT x->>'x', json(x) FROM c;
224 do_execsql_test 8.4 {
225 WITH c(x) AS (VALUES('{x: -.5}')) SELECT x->>'x', json(x) FROM c;
226 } {-0.5 {{"x":-0.5}}}
227 do_execsql_test 8.5 {
228 WITH c(x) AS (VALUES('{x: +.5}')) SELECT x->>'x', json(x) FROM c;
230 do_execsql_test 8.6 {
231 WITH c(x) AS (VALUES('{x: 4.e0}')) SELECT x->>'x', json(x) FROM c;
232 } {4.0 {{"x":4.0e0}}}
233 do_execsql_test 8.7 {
234 WITH c(x) AS (VALUES('{x: +4.e1}')) SELECT x->>'x', json(x) FROM c;
235 } {40.0 {{"x":4.0e1}}}
236 do_execsql_test 8.8 {
237 WITH c(x) AS (VALUES('{x: -4.e2}')) SELECT x->>'x', json(x) FROM c;
238 } {-400.0 {{"x":-4.0e2}}}
239 do_execsql_test 8.9 {
240 WITH c(x) AS (VALUES('{x: .5e3}')) SELECT x->>'x', json(x) FROM c;
241 } {500.0 {{"x":0.5e3}}}
242 do_execsql_test 8.10 {
243 WITH c(x) AS (VALUES('{x: -.5e-1}')) SELECT x->>'x', json(x) FROM c;
244 } {-0.05 {{"x":-0.5e-1}}}
245 do_execsql_test 8.11 {
246 WITH c(x) AS (VALUES('{x: +.5e-2}')) SELECT x->>'x', json(x) FROM c;
247 } {0.005 {{"x":0.5e-2}}}
250 ###############################################################################
251 # 9) Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
253 do_execsql_test 9.1 {
254 WITH c(x) AS (VALUES('{x: +Infinity}')) SELECT x->>'x', json(x) FROM c;
255 } {Inf {{"x":9.0e999}}}
256 do_execsql_test 9.2 {
257 WITH c(x) AS (VALUES('{x: -Infinity}')) SELECT x->>'x', json(x) FROM c;
258 } {-Inf {{"x":-9.0e999}}}
259 do_execsql_test 9.3 {
260 WITH c(x) AS (VALUES('{x: Infinity}')) SELECT x->>'x', json(x) FROM c;
261 } {Inf {{"x":9.0e999}}}
262 do_execsql_test 9.4 {
263 WITH c(x) AS (VALUES('{x: NaN}')) SELECT x->>'x', json(x) FROM c;
266 ###############################################################################
267 # 10) Numbers may begin with an explicit plus sign.
269 do_execsql_test 10.1 {
270 SELECT '{a: +123}'->'a';
273 ###############################################################################
274 # 11) Single and multi-line comments are allowed.
276 do_execsql_test 11.1 {
277 SELECT ' /* abc */ { /*def*/ aaa /* xyz */ : // to the end of line
278 123 /* xyz */ , /* 123 */ }'->>'aaa';
281 ###############################################################################
282 # 12) Additional white space characters are allowed.
284 do_execsql_test 12.1 {
285 SELECT (char(0x09,0x0a,0x0b,0x0c,0x0d,0x20,0xa0,0x2028,0x2029)
286 || '{a: "xyz"}')->>'a';
288 do_execsql_test 12.2 {
289 SELECT ('{a:' || char(0x09,0x0a,0x0b,0x0c,0x0d,0x20,0xa0,0x2028,0x2029)
292 do_execsql_test 12.3 {
293 SELECT (char(0x1680,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,
294 0x2006,0x2007,0x2008,0x2009,0x200a,0x3000,0xfeff)
295 || '{a: "xyz"}')->>'a';
297 do_execsql_test 12.4 {
298 SELECT ('{a: ' ||char(0x1680,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,
299 0x2006,0x2007,0x2008,0x2009,0x200a,0x3000,0xfeff)