go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/starlark/testdata/json.star (about) 1 # Tests of json module. 2 3 load("assert.star", "assert") 4 load("json.star", "json") 5 6 assert.eq(dir(json), ["decode", "encode", "indent"]) 7 8 # Some of these cases were inspired by github.com/nst/JSONTestSuite. 9 10 ## json.encode 11 12 assert.eq(json.encode(None), "null") 13 assert.eq(json.encode(True), "true") 14 assert.eq(json.encode(False), "false") 15 assert.eq(json.encode(-123), "-123") 16 assert.eq(json.encode(12345*12345*12345*12345*12345*12345), "3539537889086624823140625") 17 assert.eq(json.encode(float(12345*12345*12345*12345*12345*12345)), "3.539537889086625e+24") 18 assert.eq(json.encode(12.345e67), "1.2345e+68") 19 assert.eq(json.encode("hello"), '"hello"') 20 assert.eq(json.encode([1, 2, 3]), "[1,2,3]") 21 assert.eq(json.encode((1, 2, 3)), "[1,2,3]") 22 assert.eq(json.encode(range(3)), "[0,1,2]") # a built-in iterable 23 assert.eq(json.encode(dict(x = 1, y = "two")), '{"x":1,"y":"two"}') 24 assert.eq(json.encode(dict(y = "two", x = 1)), '{"x":1,"y":"two"}') # key, not insertion, order 25 assert.eq(json.encode(struct(x = 1, y = "two")), '{"x":1,"y":"two"}') # a user-defined HasAttrs 26 assert.eq(json.encode("πΉ"[:1]), '"\\ufffd"') # invalid UTF-8 -> replacement char 27 28 def encode_error(expr, error): 29 assert.fails(lambda: json.encode(expr), error) 30 31 encode_error(float("NaN"), "json.encode: cannot encode non-finite float nan") 32 encode_error({1: "two"}, "dict has int key, want string") 33 encode_error(len, "cannot encode builtin_function_or_method as JSON") 34 encode_error(struct(x=[1, {"x": len}]), # nested failure 35 'in field .x: at list index 1: in dict key "x": cannot encode...') 36 encode_error(struct(x=[1, {"x": len}]), # nested failure 37 'in field .x: at list index 1: in dict key "x": cannot encode...') 38 encode_error({1: 2}, 'dict has int key, want string') 39 40 recursive_map = {} 41 recursive_map["r"] = recursive_map 42 encode_error(recursive_map, 'json.encode: in dict key "r": cycle in JSON structure') 43 44 recursive_list = [] 45 recursive_list.append(recursive_list) 46 encode_error(recursive_list, 'json.encode: at list index 0: cycle in JSON structure') 47 48 recursive_tuple = (1, 2, []) 49 recursive_tuple[2].append(recursive_tuple) 50 encode_error(recursive_tuple, 'json.encode: at tuple index 2: at list index 0: cycle in JSON structure') 51 52 ## json.decode 53 54 assert.eq(json.decode("null"), None) 55 assert.eq(json.decode("true"), True) 56 assert.eq(json.decode("false"), False) 57 assert.eq(json.decode("-123"), -123) 58 assert.eq(json.decode("-0"), -0) 59 assert.eq(json.decode("3539537889086624823140625"), 3539537889086624823140625) 60 assert.eq(json.decode("3539537889086624823140625.0"), float(3539537889086624823140625)) 61 assert.eq(json.decode("3.539537889086625e+24"), 3.539537889086625e+24) 62 assert.eq(json.decode("0e+1"), 0) 63 assert.eq(json.decode("-0.0"), -0.0) 64 assert.eq(json.decode( 65 "-0.000000000000000000000000000000000000000000000000000000000000000000000000000001"), 66 -0.000000000000000000000000000000000000000000000000000000000000000000000000000001) 67 assert.eq(json.decode('[]'), []) 68 assert.eq(json.decode('[1]'), [1]) 69 assert.eq(json.decode('[1,2,3]'), [1, 2, 3]) 70 assert.eq(json.decode('{"one": 1, "two": 2}'), dict(one=1, two=2)) 71 assert.eq(json.decode('{"foo\\u0000bar": 42}'), {"foo\x00bar": 42}) 72 assert.eq(json.decode('"\\ud83d\\ude39\\ud83d\\udc8d"'), "πΉπ") 73 assert.eq(json.decode('"\\u0123"'), 'Δ£') 74 assert.eq(json.decode('"\x7f"'), "\x7f") 75 76 def decode_error(expr, error): 77 assert.fails(lambda: json.decode(expr), error) 78 79 decode_error('truefalse', 80 "json.decode: at offset 4, unexpected character 'f' after value") 81 82 decode_error('"abc', "unclosed string literal") 83 decode_error('"ab\\gc"', "invalid character 'g' in string escape code") 84 decode_error("'abc'", "unexpected character '\\\\''") 85 86 decode_error("1.2.3", "invalid number: 1.2.3") 87 decode_error("+1", "unexpected character '\\+'") 88 decode_error("-abc", "invalid number: -") 89 decode_error("-", "invalid number: -") 90 decode_error("-00", "invalid number: -00") 91 decode_error("00", "invalid number: 00") 92 decode_error("--1", "invalid number: --1") 93 decode_error("-+1", "invalid number: -\\+1") 94 decode_error("1e1e1", "invalid number: 1e1e1") 95 decode_error("0123", "invalid number: 0123") 96 decode_error("000.123", "invalid number: 000.123") 97 decode_error("-0123", "invalid number: -0123") 98 decode_error("-000.123", "invalid number: -000.123") 99 decode_error("0x123", "unexpected character 'x' after value") 100 101 decode_error('[1, 2 ', "unexpected end of file") 102 decode_error('[1, 2, ', "unexpected end of file") 103 decode_error('[1, 2, ]', "unexpected character ']'") 104 decode_error('[1, 2, }', "unexpected character '}'") 105 decode_error('[1, 2}', "got '}', want ',' or ']'") 106 107 decode_error('{"one": 1', "unexpected end of file") 108 decode_error('{"one" 1', "after object key, got '1', want ':'") 109 decode_error('{"one": 1 "two": 2', "in object, got '\"', want ',' or '}'") 110 decode_error('{"one": 1,', "unexpected end of file") 111 decode_error('{"one": 1, }', "unexpected character '}'") 112 decode_error('{"one": 1]', "in object, got ']', want ',' or '}'") 113 114 ## json.decode with default specified 115 116 assert.eq(json.decode('{"valid": "json"}', default = "default value"), {"valid": "json"}) 117 assert.eq(json.decode('{"valid": "json"}', "default value"), {"valid": "json"}) 118 assert.eq(json.decode('{"invalid": "json"', default = "default value"), "default value") 119 assert.eq(json.decode('{"invalid": "json"', "default value"), "default value") 120 assert.eq(json.decode('{"invalid": "json"', default = None), None) 121 assert.eq(json.decode('{"invalid": "json"', None), None) 122 123 assert.fails( 124 lambda: json.decode(x = '{"invalid": "json"', default = "default value"), 125 "unexpected keyword argument x" 126 ) 127 128 def codec(x): 129 return json.decode(json.encode(x)) 130 131 # string round-tripping 132 strings = [ 133 "πΏ", # U+1F63F CRYING_CAT_FACE 134 "π±βπ€", # CAT FACE + ZERO WIDTH JOINER + BUST IN SILHOUETTE 135 ] 136 assert.eq(codec(strings), strings) 137 138 # codepoints is a string with every 16-bit code point. 139 codepoints = ''.join(['%c' % c for c in range(65536)]) 140 assert.eq(codec(codepoints), codepoints) 141 142 # number round-tripping 143 numbers = [ 144 0, 1, -1, +1, 1.23e45, -1.23e-45, 145 3539537889086624823140625, 146 float(3539537889086624823140625), 147 ] 148 assert.eq(codec(numbers), numbers) 149 150 ## json.indent 151 152 s = json.encode(dict(x = 1, y = ["one", "two"])) 153 154 assert.eq(json.indent(s), '''{ 155 "x": 1, 156 "y": [ 157 "one", 158 "two" 159 ] 160 }''') 161 162 assert.eq(json.decode(json.indent(s)), {"x": 1, "y": ["one", "two"]}) 163 164 assert.eq(json.indent(s, prefix='ΒΆ', indent='βββ'), '''{ 165 ΒΆβββ"x": 1, 166 ΒΆβββ"y": [ 167 ΒΆββββββ"one", 168 ΒΆββββββ"two" 169 ΒΆβββ] 170 ΒΆ}''') 171 172 assert.fails(lambda: json.indent("!@#$%^& this is not json"), 'invalid character') 173 ---