Commit 3c0d8a1c authored by Ezio Melotti's avatar Ezio Melotti

#5723: Improve json tests to be executed with and without accelerations.

parent fec3ad10
...@@ -5,7 +5,7 @@ import re ...@@ -5,7 +5,7 @@ import re
import sys import sys
import struct import struct
from json.scanner import make_scanner from json import scanner
try: try:
from _json import scanstring as c_scanstring from _json import scanstring as c_scanstring
except ImportError: except ImportError:
...@@ -334,7 +334,7 @@ class JSONDecoder(object): ...@@ -334,7 +334,7 @@ class JSONDecoder(object):
self.parse_object = JSONObject self.parse_object = JSONObject
self.parse_array = JSONArray self.parse_array = JSONArray
self.parse_string = scanstring self.parse_string = scanstring
self.scan_once = make_scanner(self) self.scan_once = scanner.make_scanner(self)
def decode(self, s, _w=WHITESPACE.match): def decode(self, s, _w=WHITESPACE.match):
......
import os import os
import sys import sys
import unittest import json
import doctest import doctest
import unittest
from test import support
# import json with and without accelerations
cjson = support.import_fresh_module('json', fresh=['_json'])
pyjson = support.import_fresh_module('json', blocked=['_json'])
# create two base classes that will be used by the other tests
class PyTest(unittest.TestCase):
json = pyjson
loads = staticmethod(pyjson.loads)
dumps = staticmethod(pyjson.dumps)
@unittest.skipUnless(cjson, 'requires _json')
class CTest(unittest.TestCase):
if cjson is not None:
json = cjson
loads = staticmethod(cjson.loads)
dumps = staticmethod(cjson.dumps)
# test PyTest and CTest checking if the functions come from the right module
class TestPyTest(PyTest):
def test_pyjson(self):
self.assertEqual(self.json.scanner.make_scanner.__module__,
'json.scanner')
self.assertEqual(self.json.decoder.scanstring.__module__,
'json.decoder')
self.assertEqual(self.json.encoder.encode_basestring_ascii.__module__,
'json.encoder')
class TestCTest(CTest):
def test_cjson(self):
self.assertEqual(self.json.scanner.make_scanner.__module__, '_json')
self.assertEqual(self.json.decoder.scanstring.__module__, '_json')
self.assertEqual(self.json.encoder.c_make_encoder.__module__, '_json')
self.assertEqual(self.json.encoder.encode_basestring_ascii.__module__,
'_json')
here = os.path.dirname(__file__) here = os.path.dirname(__file__)
...@@ -17,12 +56,11 @@ def test_suite(): ...@@ -17,12 +56,11 @@ def test_suite():
return suite return suite
def additional_tests(): def additional_tests():
import json
import json.encoder
import json.decoder
suite = unittest.TestSuite() suite = unittest.TestSuite()
for mod in (json, json.encoder, json.decoder): for mod in (json, json.encoder, json.decoder):
suite.addTest(doctest.DocTestSuite(mod)) suite.addTest(doctest.DocTestSuite(mod))
suite.addTest(TestPyTest('test_pyjson'))
suite.addTest(TestCTest('test_cjson'))
return suite return suite
def main(): def main():
......
import decimal import decimal
from unittest import TestCase
from io import StringIO from io import StringIO
import json
from collections import OrderedDict from collections import OrderedDict
from json.tests import PyTest, CTest
class TestDecode(TestCase): class TestDecode:
def test_decimal(self): def test_decimal(self):
rval = json.loads('1.1', parse_float=decimal.Decimal) rval = self.loads('1.1', parse_float=decimal.Decimal)
self.assertTrue(isinstance(rval, decimal.Decimal)) self.assertTrue(isinstance(rval, decimal.Decimal))
self.assertEqual(rval, decimal.Decimal('1.1')) self.assertEqual(rval, decimal.Decimal('1.1'))
def test_float(self): def test_float(self):
rval = json.loads('1', parse_int=float) rval = self.loads('1', parse_int=float)
self.assertTrue(isinstance(rval, float)) self.assertTrue(isinstance(rval, float))
self.assertEqual(rval, 1.0) self.assertEqual(rval, 1.0)
def test_empty_objects(self): def test_empty_objects(self):
self.assertEqual(json.loads('{}'), {}) self.assertEqual(self.loads('{}'), {})
self.assertEqual(json.loads('[]'), []) self.assertEqual(self.loads('[]'), [])
self.assertEqual(json.loads('""'), "") self.assertEqual(self.loads('""'), "")
def test_object_pairs_hook(self): def test_object_pairs_hook(self):
s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}'
p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4), p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4),
("qrt", 5), ("pad", 6), ("hoy", 7)] ("qrt", 5), ("pad", 6), ("hoy", 7)]
self.assertEqual(json.loads(s), eval(s)) self.assertEqual(self.loads(s), eval(s))
self.assertEqual(json.loads(s, object_pairs_hook = lambda x: x), p) self.assertEqual(self.loads(s, object_pairs_hook = lambda x: x), p)
self.assertEqual(json.load(StringIO(s), self.assertEqual(self.json.load(StringIO(s),
object_pairs_hook=lambda x: x), p) object_pairs_hook=lambda x: x), p)
od = json.loads(s, object_pairs_hook = OrderedDict) od = self.loads(s, object_pairs_hook = OrderedDict)
self.assertEqual(od, OrderedDict(p)) self.assertEqual(od, OrderedDict(p))
self.assertEqual(type(od), OrderedDict) self.assertEqual(type(od), OrderedDict)
# the object_pairs_hook takes priority over the object_hook # the object_pairs_hook takes priority over the object_hook
self.assertEqual(json.loads(s, self.assertEqual(self.loads(s,
object_pairs_hook = OrderedDict, object_pairs_hook = OrderedDict,
object_hook = lambda x: None), object_hook = lambda x: None),
OrderedDict(p)) OrderedDict(p))
...@@ -42,5 +41,9 @@ class TestDecode(TestCase): ...@@ -42,5 +41,9 @@ class TestDecode(TestCase):
# Several optimizations were made that skip over calls to # Several optimizations were made that skip over calls to
# the whitespace regex, so this test is designed to try and # the whitespace regex, so this test is designed to try and
# exercise the uncommon cases. The array cases are already covered. # exercise the uncommon cases. The array cases are already covered.
rval = json.loads('{ "key" : "value" , "k":"v" }') rval = self.loads('{ "key" : "value" , "k":"v" }')
self.assertEqual(rval, {"key":"value", "k":"v"}) self.assertEqual(rval, {"key":"value", "k":"v"})
class TestPyDecode(TestDecode, PyTest): pass
class TestCDecode(TestDecode, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
class TestDefault(TestCase): class TestDefault:
def test_default(self): def test_default(self):
self.assertEqual( self.assertEqual(
json.dumps(type, default=repr), self.dumps(type, default=repr),
json.dumps(repr(type))) self.dumps(repr(type)))
class TestPyDefault(TestDefault, PyTest): pass
class TestCDefault(TestDefault, CTest): pass
from unittest import TestCase
from io import StringIO from io import StringIO
from json.tests import PyTest, CTest
import json
class TestDump(TestCase): class TestDump:
def test_dump(self): def test_dump(self):
sio = StringIO() sio = StringIO()
json.dump({}, sio) self.json.dump({}, sio)
self.assertEqual(sio.getvalue(), '{}') self.assertEqual(sio.getvalue(), '{}')
def test_dumps(self): def test_dumps(self):
self.assertEqual(json.dumps({}), '{}') self.assertEqual(self.dumps({}), '{}')
def test_encode_truefalse(self): def test_encode_truefalse(self):
self.assertEqual(json.dumps( self.assertEqual(self.dumps(
{True: False, False: True}, sort_keys=True), {True: False, False: True}, sort_keys=True),
'{"false": true, "true": false}') '{"false": true, "true": false}')
self.assertEqual(json.dumps( self.assertEqual(self.dumps(
{2: 3.0, 4.0: 5, False: 1, 6: True}, sort_keys=True), {2: 3.0, 4.0: 5, False: 1, 6: True}, sort_keys=True),
'{"false": 1, "2": 3.0, "4.0": 5, "6": true}') '{"false": 1, "2": 3.0, "4.0": 5, "6": true}')
class TestPyDump(TestDump, PyTest): pass
class TestCDump(TestDump, CTest): pass
from unittest import TestCase
import json.encoder
from json import dumps
from collections import OrderedDict from collections import OrderedDict
from json.tests import PyTest, CTest
CASES = [ CASES = [
('/\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\x08\x0c\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?', '"/\\\\\\"\\ucafe\\ubabe\\uab98\\ufcde\\ubcda\\uef4a\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?"'), ('/\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\x08\x0c\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?', '"/\\\\\\"\\ucafe\\ubabe\\uab98\\ufcde\\ubcda\\uef4a\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?"'),
...@@ -21,19 +19,11 @@ CASES = [ ...@@ -21,19 +19,11 @@ CASES = [
('\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'), ('\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
] ]
class TestEncodeBaseStringAscii(TestCase): class TestEncodeBasestringAscii:
def test_py_encode_basestring_ascii(self): def test_encode_basestring_ascii(self):
self._test_encode_basestring_ascii(json.encoder.py_encode_basestring_ascii) fname = self.json.encoder.encode_basestring_ascii.__name__
def test_c_encode_basestring_ascii(self):
if not json.encoder.c_encode_basestring_ascii:
return
self._test_encode_basestring_ascii(json.encoder.c_encode_basestring_ascii)
def _test_encode_basestring_ascii(self, encode_basestring_ascii):
fname = encode_basestring_ascii.__name__
for input_string, expect in CASES: for input_string, expect in CASES:
result = encode_basestring_ascii(input_string) result = self.json.encoder.encode_basestring_ascii(input_string)
self.assertEqual(result, expect, self.assertEqual(result, expect,
'{0!r} != {1!r} for {2}({3!r})'.format( '{0!r} != {1!r} for {2}({3!r})'.format(
result, expect, fname, input_string)) result, expect, fname, input_string))
...@@ -41,10 +31,14 @@ class TestEncodeBaseStringAscii(TestCase): ...@@ -41,10 +31,14 @@ class TestEncodeBaseStringAscii(TestCase):
def test_ordered_dict(self): def test_ordered_dict(self):
# See issue 6105 # See issue 6105
items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)] items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
s = json.dumps(OrderedDict(items)) s = self.dumps(OrderedDict(items))
self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}') self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}')
def test_sorted_dict(self): def test_sorted_dict(self):
items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)] items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
s = json.dumps(dict(items), sort_keys=True) s = self.dumps(dict(items), sort_keys=True)
self.assertEqual(s, '{"five": 5, "four": 4, "one": 1, "three": 3, "two": 2}') self.assertEqual(s, '{"five": 5, "four": 4, "one": 1, "three": 3, "two": 2}')
class TestPyEncodeBasestringAscii(TestEncodeBasestringAscii, PyTest): pass
class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
# Fri Dec 30 18:57:26 2005 # Fri Dec 30 18:57:26 2005
JSONDOCS = [ JSONDOCS = [
...@@ -61,15 +59,15 @@ SKIPS = { ...@@ -61,15 +59,15 @@ SKIPS = {
18: "spec doesn't specify any nesting limitations", 18: "spec doesn't specify any nesting limitations",
} }
class TestFail(TestCase): class TestFail:
def test_failures(self): def test_failures(self):
for idx, doc in enumerate(JSONDOCS): for idx, doc in enumerate(JSONDOCS):
idx = idx + 1 idx = idx + 1
if idx in SKIPS: if idx in SKIPS:
json.loads(doc) self.loads(doc)
continue continue
try: try:
json.loads(doc) self.loads(doc)
except ValueError: except ValueError:
pass pass
else: else:
...@@ -79,7 +77,11 @@ class TestFail(TestCase): ...@@ -79,7 +77,11 @@ class TestFail(TestCase):
data = {'a' : 1, (1, 2) : 2} data = {'a' : 1, (1, 2) : 2}
#This is for c encoder #This is for c encoder
self.assertRaises(TypeError, json.dumps, data) self.assertRaises(TypeError, self.dumps, data)
#This is for python encoder #This is for python encoder
self.assertRaises(TypeError, json.dumps, data, indent=True) self.assertRaises(TypeError, self.dumps, data, indent=True)
class TestPyFail(TestFail, PyTest): pass
class TestCFail(TestFail, CTest): pass
import math import math
from unittest import TestCase from json.tests import PyTest, CTest
import json
class TestFloat(TestCase): class TestFloat:
def test_floats(self): def test_floats(self):
for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100, 3.1]: for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100, 3.1]:
self.assertEqual(float(json.dumps(num)), num) self.assertEqual(float(self.dumps(num)), num)
self.assertEqual(json.loads(json.dumps(num)), num) self.assertEqual(self.loads(self.dumps(num)), num)
def test_ints(self): def test_ints(self):
for num in [1, 1<<32, 1<<64]: for num in [1, 1<<32, 1<<64]:
self.assertEqual(json.dumps(num), str(num)) self.assertEqual(self.dumps(num), str(num))
self.assertEqual(int(json.dumps(num)), num) self.assertEqual(int(self.dumps(num)), num)
class TestPyFloat(TestFloat, PyTest): pass
class TestCFloat(TestFloat, CTest): pass
from unittest import TestCase
import json
import textwrap import textwrap
from io import StringIO from io import StringIO
from json.tests import PyTest, CTest
class TestIndent(TestCase): class TestIndent:
def test_indent(self): def test_indent(self):
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
{'nifty': 87}, {'field': 'yes', 'morefield': False} ] {'nifty': 87}, {'field': 'yes', 'morefield': False} ]
...@@ -31,11 +30,11 @@ class TestIndent(TestCase): ...@@ -31,11 +30,11 @@ class TestIndent(TestCase):
]""") ]""")
d1 = json.dumps(h) d1 = self.dumps(h)
d2 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': ')) d2 = self.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
h1 = json.loads(d1) h1 = self.loads(d1)
h2 = json.loads(d2) h2 = self.loads(d2)
self.assertEqual(h1, h) self.assertEqual(h1, h)
self.assertEqual(h2, h) self.assertEqual(h2, h)
...@@ -44,14 +43,18 @@ class TestIndent(TestCase): ...@@ -44,14 +43,18 @@ class TestIndent(TestCase):
def test_indent0(self): def test_indent0(self):
h = {3: 1} h = {3: 1}
def check(indent, expected): def check(indent, expected):
d1 = json.dumps(h, indent=indent) d1 = self.dumps(h, indent=indent)
self.assertEqual(d1, expected) self.assertEqual(d1, expected)
sio = StringIO() sio = StringIO()
json.dump(h, sio, indent=indent) self.json.dump(h, sio, indent=indent)
self.assertEqual(sio.getvalue(), expected) self.assertEqual(sio.getvalue(), expected)
# indent=0 should emit newlines # indent=0 should emit newlines
check(0, '{\n"3": 1\n}') check(0, '{\n"3": 1\n}')
# indent=None is more compact # indent=None is more compact
check(None, '{"3": 1}') check(None, '{"3": 1}')
class TestPyIndent(TestIndent, PyTest): pass
class TestCIndent(TestIndent, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
# from http://json.org/JSON_checker/test/pass1.json # from http://json.org/JSON_checker/test/pass1.json
JSON = r''' JSON = r'''
...@@ -62,15 +61,19 @@ JSON = r''' ...@@ -62,15 +61,19 @@ JSON = r'''
,"rosebud"] ,"rosebud"]
''' '''
class TestPass1(TestCase): class TestPass1:
def test_parse(self): def test_parse(self):
# test in/out equivalence and parsing # test in/out equivalence and parsing
res = json.loads(JSON) res = self.loads(JSON)
out = json.dumps(res) out = self.dumps(res)
self.assertEqual(res, json.loads(out)) self.assertEqual(res, self.loads(out))
try: try:
json.dumps(res, allow_nan=False) self.dumps(res, allow_nan=False)
except ValueError: except ValueError:
pass pass
else: else:
self.fail("23456789012E666 should be out of range") self.fail("23456789012E666 should be out of range")
class TestPyPass1(TestPass1, PyTest): pass
class TestCPass1(TestPass1, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
# from http://json.org/JSON_checker/test/pass2.json # from http://json.org/JSON_checker/test/pass2.json
JSON = r''' JSON = r'''
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
''' '''
class TestPass2(TestCase): class TestPass2:
def test_parse(self): def test_parse(self):
# test in/out equivalence and parsing # test in/out equivalence and parsing
res = json.loads(JSON) res = self.loads(JSON)
out = json.dumps(res) out = self.dumps(res)
self.assertEqual(res, json.loads(out)) self.assertEqual(res, self.loads(out))
class TestPyPass2(TestPass2, PyTest): pass
class TestCPass2(TestPass2, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
# from http://json.org/JSON_checker/test/pass3.json # from http://json.org/JSON_checker/test/pass3.json
JSON = r''' JSON = r'''
...@@ -12,9 +11,14 @@ JSON = r''' ...@@ -12,9 +11,14 @@ JSON = r'''
} }
''' '''
class TestPass3(TestCase):
class TestPass3:
def test_parse(self): def test_parse(self):
# test in/out equivalence and parsing # test in/out equivalence and parsing
res = json.loads(JSON) res = self.loads(JSON)
out = json.dumps(res) out = self.dumps(res)
self.assertEqual(res, json.loads(out)) self.assertEqual(res, self.loads(out))
class TestPyPass3(TestPass3, PyTest): pass
class TestCPass3(TestPass3, CTest): pass
from unittest import TestCase from json.tests import PyTest, CTest
import json
class JSONTestObject: class JSONTestObject:
pass pass
class RecursiveJSONEncoder(json.JSONEncoder): class TestRecursion:
recurse = False
def default(self, o):
if o is JSONTestObject:
if self.recurse:
return [JSONTestObject]
else:
return 'JSONTestObject'
return json.JSONEncoder.default(o)
class EndlessJSONEncoder(json.JSONEncoder):
def default(self, o):
"""If check_circular is False, this will keep adding another list."""
return [o]
class TestRecursion(TestCase):
def test_listrecursion(self): def test_listrecursion(self):
x = [] x = []
x.append(x) x.append(x)
try: try:
json.dumps(x) self.dumps(x)
except ValueError: except ValueError:
pass pass
else: else:
...@@ -36,7 +19,7 @@ class TestRecursion(TestCase): ...@@ -36,7 +19,7 @@ class TestRecursion(TestCase):
y = [x] y = [x]
x.append(y) x.append(y)
try: try:
json.dumps(x) self.dumps(x)
except ValueError: except ValueError:
pass pass
else: else:
...@@ -44,13 +27,13 @@ class TestRecursion(TestCase): ...@@ -44,13 +27,13 @@ class TestRecursion(TestCase):
y = [] y = []
x = [y, y] x = [y, y]
# ensure that the marker is cleared # ensure that the marker is cleared
json.dumps(x) self.dumps(x)
def test_dictrecursion(self): def test_dictrecursion(self):
x = {} x = {}
x["test"] = x x["test"] = x
try: try:
json.dumps(x) self.dumps(x)
except ValueError: except ValueError:
pass pass
else: else:
...@@ -58,9 +41,19 @@ class TestRecursion(TestCase): ...@@ -58,9 +41,19 @@ class TestRecursion(TestCase):
x = {} x = {}
y = {"a": x, "b": x} y = {"a": x, "b": x}
# ensure that the marker is cleared # ensure that the marker is cleared
json.dumps(x) self.dumps(x)
def test_defaultrecursion(self): def test_defaultrecursion(self):
class RecursiveJSONEncoder(self.json.JSONEncoder):
recurse = False
def default(self, o):
if o is JSONTestObject:
if self.recurse:
return [JSONTestObject]
else:
return 'JSONTestObject'
return pyjson.JSONEncoder.default(o)
enc = RecursiveJSONEncoder() enc = RecursiveJSONEncoder()
self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"') self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"')
enc.recurse = True enc.recurse = True
...@@ -76,11 +69,11 @@ class TestRecursion(TestCase): ...@@ -76,11 +69,11 @@ class TestRecursion(TestCase):
# test that loading highly-nested objects doesn't segfault when C # test that loading highly-nested objects doesn't segfault when C
# accelerations are used. See #12017 # accelerations are used. See #12017
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
json.loads('{"a":' * 100000 + '1' + '}' * 100000) self.loads('{"a":' * 100000 + '1' + '}' * 100000)
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
json.loads('{"a":' * 100000 + '[1]' + '}' * 100000) self.loads('{"a":' * 100000 + '[1]' + '}' * 100000)
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
json.loads('[' * 100000 + '1' + ']' * 100000) self.loads('[' * 100000 + '1' + ']' * 100000)
def test_highly_nested_objects_encoding(self): def test_highly_nested_objects_encoding(self):
# See #12051 # See #12051
...@@ -88,11 +81,20 @@ class TestRecursion(TestCase): ...@@ -88,11 +81,20 @@ class TestRecursion(TestCase):
for x in range(100000): for x in range(100000):
l, d = [l], {'k':d} l, d = [l], {'k':d}
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
json.dumps(l) self.dumps(l)
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
json.dumps(d) self.dumps(d)
def test_endless_recursion(self): def test_endless_recursion(self):
# See #12051 # See #12051
class EndlessJSONEncoder(self.json.JSONEncoder):
def default(self, o):
"""If check_circular is False, this will keep adding another list."""
return [o]
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
EndlessJSONEncoder(check_circular=False).encode(5j) EndlessJSONEncoder(check_circular=False).encode(5j)
class TestPyRecursion(TestRecursion, PyTest): pass
class TestCRecursion(TestRecursion, CTest): pass
import sys import sys
from unittest import TestCase, skipUnless from json.tests import PyTest, CTest
import json
import json.decoder
try: class TestScanstring:
import _json def test_scanstring(self):
except ImportError: scanstring = self.json.decoder.scanstring
_json = None
class TestScanString(TestCase):
def test_py_scanstring(self):
self._test_scanstring(json.decoder.py_scanstring)
@skipUnless(_json, 'test requires the _json module')
def test_c_scanstring(self):
if json.decoder.c_scanstring is not None:
self._test_scanstring(json.decoder.c_scanstring)
def _test_scanstring(self, scanstring):
self.assertEqual( self.assertEqual(
scanstring('"z\\ud834\\udd20x"', 1, True), scanstring('"z\\ud834\\udd20x"', 1, True),
('z\U0001d120x', 16)) ('z\U0001d120x', 16))
...@@ -109,4 +95,9 @@ class TestScanString(TestCase): ...@@ -109,4 +95,9 @@ class TestScanString(TestCase):
('Bad value', 12)) ('Bad value', 12))
def test_overflow(self): def test_overflow(self):
self.assertRaises(OverflowError, json.decoder.scanstring, b"xxx", sys.maxsize+1) with self.assertRaises(OverflowError):
self.json.decoder.scanstring(b"xxx", sys.maxsize+1)
class TestPyScanstring(TestScanstring, PyTest): pass
class TestCScanstring(TestScanstring, CTest): pass
import textwrap import textwrap
from unittest import TestCase from json.tests import PyTest, CTest
import json
class TestSeparators:
class TestSeparators(TestCase):
def test_separators(self): def test_separators(self):
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
{'nifty': 87}, {'field': 'yes', 'morefield': False} ] {'nifty': 87}, {'field': 'yes', 'morefield': False} ]
...@@ -31,12 +29,16 @@ class TestSeparators(TestCase): ...@@ -31,12 +29,16 @@ class TestSeparators(TestCase):
]""") ]""")
d1 = json.dumps(h) d1 = self.dumps(h)
d2 = json.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : ')) d2 = self.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : '))
h1 = json.loads(d1) h1 = self.loads(d1)
h2 = json.loads(d2) h2 = self.loads(d2)
self.assertEqual(h1, h) self.assertEqual(h1, h)
self.assertEqual(h2, h) self.assertEqual(h2, h)
self.assertEqual(d2, expect) self.assertEqual(d2, expect)
class TestPySeparators(TestSeparators, PyTest): pass
class TestCSeparators(TestSeparators, CTest): pass
from unittest import TestCase, skipUnless from json.tests import CTest
from json import decoder, encoder, scanner
try: class TestSpeedups(CTest):
import _json
except ImportError:
_json = None
@skipUnless(_json, 'test requires the _json module')
class TestSpeedups(TestCase):
def test_scanstring(self): def test_scanstring(self):
self.assertEqual(decoder.scanstring.__module__, "_json") self.assertEqual(self.json.decoder.scanstring.__module__, "_json")
self.assertIs(decoder.scanstring, decoder.c_scanstring) self.assertIs(self.json.decoder.scanstring, self.json.decoder.c_scanstring)
def test_encode_basestring_ascii(self): def test_encode_basestring_ascii(self):
self.assertEqual(encoder.encode_basestring_ascii.__module__, "_json") self.assertEqual(self.json.encoder.encode_basestring_ascii.__module__,
self.assertIs(encoder.encode_basestring_ascii, "_json")
encoder.c_encode_basestring_ascii) self.assertIs(self.json.encoder.encode_basestring_ascii,
self.json.encoder.c_encode_basestring_ascii)
class TestDecode(TestCase): class TestDecode(CTest):
def test_make_scanner(self): def test_make_scanner(self):
self.assertRaises(AttributeError, scanner.c_make_scanner, 1) self.assertRaises(AttributeError, self.json.scanner.c_make_scanner, 1)
def test_make_encoder(self): def test_make_encoder(self):
self.assertRaises(TypeError, encoder.c_make_encoder, self.assertRaises(TypeError, self.json.encoder.c_make_encoder,
(True, False), (True, False),
b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
None) None)
from unittest import TestCase
import json
from collections import OrderedDict from collections import OrderedDict
from json.tests import PyTest, CTest
class TestUnicode(TestCase): class TestUnicode:
# test_encoding1 and test_encoding2 from 2.x are irrelevant (only str # test_encoding1 and test_encoding2 from 2.x are irrelevant (only str
# is supported as input, not bytes). # is supported as input, not bytes).
def test_encoding3(self): def test_encoding3(self):
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
j = json.dumps(u) j = self.dumps(u)
self.assertEqual(j, '"\\u03b1\\u03a9"') self.assertEqual(j, '"\\u03b1\\u03a9"')
def test_encoding4(self): def test_encoding4(self):
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
j = json.dumps([u]) j = self.dumps([u])
self.assertEqual(j, '["\\u03b1\\u03a9"]') self.assertEqual(j, '["\\u03b1\\u03a9"]')
def test_encoding5(self): def test_encoding5(self):
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
j = json.dumps(u, ensure_ascii=False) j = self.dumps(u, ensure_ascii=False)
self.assertEqual(j, '"{0}"'.format(u)) self.assertEqual(j, '"{0}"'.format(u))
def test_encoding6(self): def test_encoding6(self):
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
j = json.dumps([u], ensure_ascii=False) j = self.dumps([u], ensure_ascii=False)
self.assertEqual(j, '["{0}"]'.format(u)) self.assertEqual(j, '["{0}"]'.format(u))
def test_big_unicode_encode(self): def test_big_unicode_encode(self):
u = '\U0001d120' u = '\U0001d120'
self.assertEqual(json.dumps(u), '"\\ud834\\udd20"') self.assertEqual(self.dumps(u), '"\\ud834\\udd20"')
self.assertEqual(json.dumps(u, ensure_ascii=False), '"\U0001d120"') self.assertEqual(self.dumps(u, ensure_ascii=False), '"\U0001d120"')
def test_big_unicode_decode(self): def test_big_unicode_decode(self):
u = 'z\U0001d120x' u = 'z\U0001d120x'
self.assertEqual(json.loads('"' + u + '"'), u) self.assertEqual(self.loads('"' + u + '"'), u)
self.assertEqual(json.loads('"z\\ud834\\udd20x"'), u) self.assertEqual(self.loads('"z\\ud834\\udd20x"'), u)
def test_unicode_decode(self): def test_unicode_decode(self):
for i in range(0, 0xd7ff): for i in range(0, 0xd7ff):
u = chr(i) u = chr(i)
s = '"\\u{0:04x}"'.format(i) s = '"\\u{0:04x}"'.format(i)
self.assertEqual(json.loads(s), u) self.assertEqual(self.loads(s), u)
def test_unicode_preservation(self): def test_unicode_preservation(self):
self.assertEqual(type(json.loads('""')), str) self.assertEqual(type(self.loads('""')), str)
self.assertEqual(type(json.loads('"a"')), str) self.assertEqual(type(self.loads('"a"')), str)
self.assertEqual(type(json.loads('["a"]')[0]), str) self.assertEqual(type(self.loads('["a"]')[0]), str)
def test_bytes_encode(self): def test_bytes_encode(self):
self.assertRaises(TypeError, json.dumps, b"hi") self.assertRaises(TypeError, self.dumps, b"hi")
self.assertRaises(TypeError, json.dumps, [b"hi"]) self.assertRaises(TypeError, self.dumps, [b"hi"])
def test_bytes_decode(self): def test_bytes_decode(self):
self.assertRaises(TypeError, json.loads, b'"hi"') self.assertRaises(TypeError, self.loads, b'"hi"')
self.assertRaises(TypeError, json.loads, b'["hi"]') self.assertRaises(TypeError, self.loads, b'["hi"]')
def test_object_pairs_hook_with_unicode(self): def test_object_pairs_hook_with_unicode(self):
s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}'
p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4), p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4),
("qrt", 5), ("pad", 6), ("hoy", 7)] ("qrt", 5), ("pad", 6), ("hoy", 7)]
self.assertEqual(json.loads(s), eval(s)) self.assertEqual(self.loads(s), eval(s))
self.assertEqual(json.loads(s, object_pairs_hook = lambda x: x), p) self.assertEqual(self.loads(s, object_pairs_hook = lambda x: x), p)
od = json.loads(s, object_pairs_hook = OrderedDict) od = self.loads(s, object_pairs_hook = OrderedDict)
self.assertEqual(od, OrderedDict(p)) self.assertEqual(od, OrderedDict(p))
self.assertEqual(type(od), OrderedDict) self.assertEqual(type(od), OrderedDict)
# the object_pairs_hook takes priority over the object_hook # the object_pairs_hook takes priority over the object_hook
self.assertEqual(json.loads(s, self.assertEqual(self.loads(s, object_pairs_hook = OrderedDict,
object_pairs_hook = OrderedDict,
object_hook = lambda x: None), object_hook = lambda x: None),
OrderedDict(p)) OrderedDict(p))
class TestPyUnicode(TestUnicode, PyTest): pass
class TestCUnicode(TestUnicode, CTest): pass
...@@ -116,8 +116,8 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): ...@@ -116,8 +116,8 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False):
If deprecated is True, any module or package deprecation messages If deprecated is True, any module or package deprecation messages
will be suppressed.""" will be suppressed."""
# NOTE: test_heapq and test_warnings include extra sanity checks to make # NOTE: test_heapq, test_json and test_warnings include extra sanity checks
# sure that this utility function is working as expected # to make sure that this utility function is working as expected
with _ignore_deprecated_imports(deprecated): with _ignore_deprecated_imports(deprecated):
# Keep track of modules saved for later restoration as well # Keep track of modules saved for later restoration as well
# as those which just need a blocking entry removed # as those which just need a blocking entry removed
......
...@@ -376,6 +376,8 @@ Build ...@@ -376,6 +376,8 @@ Build
Tests Tests
----- -----
- Issue #5723: Improve json tests to be executed with and without accelerations.
- Issue #11910: Fix test_heapq to skip the C tests when _heapq is missing. - Issue #11910: Fix test_heapq to skip the C tests when _heapq is missing.
- Fix test_startfile to wait for child process to terminate before finishing. - Fix test_startfile to wait for child process to terminate before finishing.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment