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  ---