summaryrefslogtreecommitdiff
path: root/Lib/json/tests
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/json/tests')
-rw-r--r--Lib/json/tests/__init__.py46
-rw-r--r--Lib/json/tests/test_check_circular.py34
-rw-r--r--Lib/json/tests/test_decode.py53
-rw-r--r--Lib/json/tests/test_default.py15
-rw-r--r--Lib/json/tests/test_dump.py22
-rw-r--r--Lib/json/tests/test_encode_basestring_ascii.py30
-rw-r--r--Lib/json/tests/test_fail.py25
-rw-r--r--Lib/json/tests/test_float.py23
-rw-r--r--Lib/json/tests/test_indent.py41
-rw-r--r--Lib/json/tests/test_pass1.py17
-rw-r--r--Lib/json/tests/test_pass2.py16
-rw-r--r--Lib/json/tests/test_pass3.py16
-rw-r--r--Lib/json/tests/test_recursion.py81
-rw-r--r--Lib/json/tests/test_scanstring.py72
-rw-r--r--Lib/json/tests/test_separators.py24
-rw-r--r--Lib/json/tests/test_speedups.py28
-rw-r--r--Lib/json/tests/test_unicode.py74
17 files changed, 439 insertions, 178 deletions
diff --git a/Lib/json/tests/__init__.py b/Lib/json/tests/__init__.py
index 1a1e3e6d5a..90cb2b7ad6 100644
--- a/Lib/json/tests/__init__.py
+++ b/Lib/json/tests/__init__.py
@@ -1,7 +1,46 @@
import os
import sys
-import unittest
+import json
import doctest
+import unittest
+
+from test import test_support
+
+# import json with and without accelerations
+cjson = test_support.import_fresh_module('json', fresh=['_json'])
+pyjson = test_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__)
@@ -17,12 +56,11 @@ def test_suite():
return suite
def additional_tests():
- import json
- import json.encoder
- import json.decoder
suite = unittest.TestSuite()
for mod in (json, json.encoder, json.decoder):
suite.addTest(doctest.DocTestSuite(mod))
+ suite.addTest(TestPyTest('test_pyjson'))
+ suite.addTest(TestCTest('test_cjson'))
return suite
def main():
diff --git a/Lib/json/tests/test_check_circular.py b/Lib/json/tests/test_check_circular.py
new file mode 100644
index 0000000000..3ad3d24196
--- /dev/null
+++ b/Lib/json/tests/test_check_circular.py
@@ -0,0 +1,34 @@
+from json.tests import PyTest, CTest
+
+
+def default_iterable(obj):
+ return list(obj)
+
+class TestCheckCircular(object):
+ def test_circular_dict(self):
+ dct = {}
+ dct['a'] = dct
+ self.assertRaises(ValueError, self.dumps, dct)
+
+ def test_circular_list(self):
+ lst = []
+ lst.append(lst)
+ self.assertRaises(ValueError, self.dumps, lst)
+
+ def test_circular_composite(self):
+ dct2 = {}
+ dct2['a'] = []
+ dct2['a'].append(dct2)
+ self.assertRaises(ValueError, self.dumps, dct2)
+
+ def test_circular_default(self):
+ self.dumps([set()], default=default_iterable)
+ self.assertRaises(TypeError, self.dumps, [set()])
+
+ def test_circular_off_default(self):
+ self.dumps([set()], default=default_iterable, check_circular=False)
+ self.assertRaises(TypeError, self.dumps, [set()], check_circular=False)
+
+
+class TestPyCheckCircular(TestCheckCircular, PyTest): pass
+class TestCCheckCircular(TestCheckCircular, CTest): pass
diff --git a/Lib/json/tests/test_decode.py b/Lib/json/tests/test_decode.py
index 609f62288c..aa8bbe9b54 100644
--- a/Lib/json/tests/test_decode.py
+++ b/Lib/json/tests/test_decode.py
@@ -1,15 +1,50 @@
import decimal
-from unittest import TestCase
+from StringIO import StringIO
+from collections import OrderedDict
+from json.tests import PyTest, CTest
-import json
-class TestDecode(TestCase):
+class TestDecode(object):
def test_decimal(self):
- rval = json.loads('1.1', parse_float=decimal.Decimal)
- self.assert_(isinstance(rval, decimal.Decimal))
- self.assertEquals(rval, decimal.Decimal('1.1'))
+ rval = self.loads('1.1', parse_float=decimal.Decimal)
+ self.assertTrue(isinstance(rval, decimal.Decimal))
+ self.assertEqual(rval, decimal.Decimal('1.1'))
def test_float(self):
- rval = json.loads('1', parse_int=float)
- self.assert_(isinstance(rval, float))
- self.assertEquals(rval, 1.0)
+ rval = self.loads('1', parse_int=float)
+ self.assertTrue(isinstance(rval, float))
+ self.assertEqual(rval, 1.0)
+
+ def test_decoder_optimizations(self):
+ # Several optimizations were made that skip over calls to
+ # the whitespace regex, so this test is designed to try and
+ # exercise the uncommon cases. The array cases are already covered.
+ rval = self.loads('{ "key" : "value" , "k":"v" }')
+ self.assertEqual(rval, {"key":"value", "k":"v"})
+
+ def test_empty_objects(self):
+ self.assertEqual(self.loads('{}'), {})
+ self.assertEqual(self.loads('[]'), [])
+ self.assertEqual(self.loads('""'), u"")
+ self.assertIsInstance(self.loads('""'), unicode)
+
+ def test_object_pairs_hook(self):
+ s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}'
+ p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4),
+ ("qrt", 5), ("pad", 6), ("hoy", 7)]
+ self.assertEqual(self.loads(s), eval(s))
+ self.assertEqual(self.loads(s, object_pairs_hook=lambda x: x), p)
+ self.assertEqual(self.json.load(StringIO(s),
+ object_pairs_hook=lambda x: x), p)
+ od = self.loads(s, object_pairs_hook=OrderedDict)
+ self.assertEqual(od, OrderedDict(p))
+ self.assertEqual(type(od), OrderedDict)
+ # the object_pairs_hook takes priority over the object_hook
+ self.assertEqual(self.loads(s,
+ object_pairs_hook=OrderedDict,
+ object_hook=lambda x: None),
+ OrderedDict(p))
+
+
+class TestPyDecode(TestDecode, PyTest): pass
+class TestCDecode(TestDecode, CTest): pass
diff --git a/Lib/json/tests/test_default.py b/Lib/json/tests/test_default.py
index 49f05ad660..c2a07f605e 100644
--- a/Lib/json/tests/test_default.py
+++ b/Lib/json/tests/test_default.py
@@ -1,9 +1,12 @@
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
-class TestDefault(TestCase):
+class TestDefault(object):
def test_default(self):
- self.assertEquals(
- json.dumps(type, default=repr),
- json.dumps(repr(type)))
+ self.assertEqual(
+ self.dumps(type, default=repr),
+ self.dumps(repr(type)))
+
+
+class TestPyDefault(TestDefault, PyTest): pass
+class TestCDefault(TestDefault, CTest): pass
diff --git a/Lib/json/tests/test_dump.py b/Lib/json/tests/test_dump.py
index d288c0d293..9a7c8ccdd0 100644
--- a/Lib/json/tests/test_dump.py
+++ b/Lib/json/tests/test_dump.py
@@ -1,13 +1,23 @@
-from unittest import TestCase
from cStringIO import StringIO
+from json.tests import PyTest, CTest
-import json
-class TestDump(TestCase):
+class TestDump(object):
def test_dump(self):
sio = StringIO()
- json.dump({}, sio)
- self.assertEquals(sio.getvalue(), '{}')
+ self.json.dump({}, sio)
+ self.assertEqual(sio.getvalue(), '{}')
def test_dumps(self):
- self.assertEquals(json.dumps({}), '{}')
+ self.assertEqual(self.dumps({}), '{}')
+
+ def test_encode_truefalse(self):
+ self.assertEqual(self.dumps(
+ {True: False, False: True}, sort_keys=True),
+ '{"false": true, "true": false}')
+ self.assertEqual(self.dumps(
+ {2: 3.0, 4.0: 5L, False: 1, 6L: True}, sort_keys=True),
+ '{"false": 1, "2": 3.0, "4.0": 5, "6": true}')
+
+class TestPyDump(TestDump, PyTest): pass
+class TestCDump(TestDump, CTest): pass
diff --git a/Lib/json/tests/test_encode_basestring_ascii.py b/Lib/json/tests/test_encode_basestring_ascii.py
index 352423ec6b..9f9d5a5deb 100644
--- a/Lib/json/tests/test_encode_basestring_ascii.py
+++ b/Lib/json/tests/test_encode_basestring_ascii.py
@@ -1,6 +1,6 @@
-from unittest import TestCase
+from collections import OrderedDict
+from json.tests import PyTest, CTest
-import json.encoder
CASES = [
(u'/\\"\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,15 +21,21 @@ CASES = [
(u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
]
-class TestEncodeBaseStringAscii(TestCase):
- def test_py_encode_basestring_ascii(self):
- self._test_encode_basestring_ascii(json.encoder.py_encode_basestring_ascii)
+class TestEncodeBasestringAscii(object):
+ def test_encode_basestring_ascii(self):
+ fname = self.json.encoder.encode_basestring_ascii.__name__
+ for input_string, expect in CASES:
+ result = self.json.encoder.encode_basestring_ascii(input_string)
+ self.assertEqual(result, expect,
+ '{0!r} != {1!r} for {2}({3!r})'.format(
+ result, expect, fname, input_string))
- def test_c_encode_basestring_ascii(self):
- self._test_encode_basestring_ascii(json.encoder.c_encode_basestring_ascii)
+ def test_ordered_dict(self):
+ # See issue 6105
+ items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
+ s = self.dumps(OrderedDict(items))
+ self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}')
- def _test_encode_basestring_ascii(self, encode_basestring_ascii):
- fname = encode_basestring_ascii.__name__
- for input_string, expect in CASES:
- result = encode_basestring_ascii(input_string)
- self.assertEquals(result, expect)
+
+class TestPyEncodeBasestringAscii(TestEncodeBasestringAscii, PyTest): pass
+class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest): pass
diff --git a/Lib/json/tests/test_fail.py b/Lib/json/tests/test_fail.py
index ee31bfa980..ae962c88a4 100644
--- a/Lib/json/tests/test_fail.py
+++ b/Lib/json/tests/test_fail.py
@@ -1,6 +1,4 @@
-from unittest import TestCase
-
-import json
+from json.tests import PyTest, CTest
# Fri Dec 30 18:57:26 2005
JSONDOCS = [
@@ -61,16 +59,29 @@ SKIPS = {
18: "spec doesn't specify any nesting limitations",
}
-class TestFail(TestCase):
+class TestFail(object):
def test_failures(self):
for idx, doc in enumerate(JSONDOCS):
idx = idx + 1
if idx in SKIPS:
- json.loads(doc)
+ self.loads(doc)
continue
try:
- json.loads(doc)
+ self.loads(doc)
except ValueError:
pass
else:
- self.fail("Expected failure for fail%d.json: %r" % (idx, doc))
+ self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
+
+ def test_non_string_keys_dict(self):
+ data = {'a' : 1, (1, 2) : 2}
+
+ #This is for c encoder
+ self.assertRaises(TypeError, self.dumps, data)
+
+ #This is for python encoder
+ self.assertRaises(TypeError, self.dumps, data, indent=True)
+
+
+class TestPyFail(TestFail, PyTest): pass
+class TestCFail(TestFail, CTest): pass
diff --git a/Lib/json/tests/test_float.py b/Lib/json/tests/test_float.py
index 9df6d1ee7a..12d35074c9 100644
--- a/Lib/json/tests/test_float.py
+++ b/Lib/json/tests/test_float.py
@@ -1,9 +1,22 @@
import math
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
-class TestFloat(TestCase):
+class TestFloat(object):
def test_floats(self):
- for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100]:
- self.assertEquals(float(json.dumps(num)), num)
+ for num in [1617161771.7650001, math.pi, math.pi**100,
+ math.pi**-100, 3.1]:
+ self.assertEqual(float(self.dumps(num)), num)
+ self.assertEqual(self.loads(self.dumps(num)), num)
+ self.assertEqual(self.loads(unicode(self.dumps(num))), num)
+
+ def test_ints(self):
+ for num in [1, 1L, 1<<32, 1<<64]:
+ self.assertEqual(self.dumps(num), str(num))
+ self.assertEqual(int(self.dumps(num)), num)
+ self.assertEqual(self.loads(self.dumps(num)), num)
+ self.assertEqual(self.loads(unicode(self.dumps(num))), num)
+
+
+class TestPyFloat(TestFloat, PyTest): pass
+class TestCFloat(TestFloat, CTest): pass
diff --git a/Lib/json/tests/test_indent.py b/Lib/json/tests/test_indent.py
index 605516230f..9b1876123a 100644
--- a/Lib/json/tests/test_indent.py
+++ b/Lib/json/tests/test_indent.py
@@ -1,9 +1,9 @@
-from unittest import TestCase
-
-import json
import textwrap
+from StringIO import StringIO
+from json.tests import PyTest, CTest
+
-class TestIndent(TestCase):
+class TestIndent(object):
def test_indent(self):
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
{'nifty': 87}, {'field': 'yes', 'morefield': False} ]
@@ -30,12 +30,31 @@ class TestIndent(TestCase):
]""")
- d1 = json.dumps(h)
- d2 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
+ d1 = self.dumps(h)
+ d2 = self.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
+
+ h1 = self.loads(d1)
+ h2 = self.loads(d2)
+
+ self.assertEqual(h1, h)
+ self.assertEqual(h2, h)
+ self.assertEqual(d2, expect)
+
+ def test_indent0(self):
+ h = {3: 1}
+ def check(indent, expected):
+ d1 = self.dumps(h, indent=indent)
+ self.assertEqual(d1, expected)
+
+ sio = StringIO()
+ self.json.dump(h, sio, indent=indent)
+ self.assertEqual(sio.getvalue(), expected)
+
+ # indent=0 should emit newlines
+ check(0, '{\n"3": 1\n}')
+ # indent=None is more compact
+ check(None, '{"3": 1}')
- h1 = json.loads(d1)
- h2 = json.loads(d2)
- self.assertEquals(h1, h)
- self.assertEquals(h2, h)
- self.assertEquals(d2, expect)
+class TestPyIndent(TestIndent, PyTest): pass
+class TestCIndent(TestIndent, CTest): pass
diff --git a/Lib/json/tests/test_pass1.py b/Lib/json/tests/test_pass1.py
index 216e2528de..82d71543ba 100644
--- a/Lib/json/tests/test_pass1.py
+++ b/Lib/json/tests/test_pass1.py
@@ -1,6 +1,5 @@
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
# from http://json.org/JSON_checker/test/pass1.json
JSON = r'''
@@ -62,15 +61,19 @@ JSON = r'''
,"rosebud"]
'''
-class TestPass1(TestCase):
+class TestPass1(object):
def test_parse(self):
# test in/out equivalence and parsing
- res = json.loads(JSON)
- out = json.dumps(res)
- self.assertEquals(res, json.loads(out))
+ res = self.loads(JSON)
+ out = self.dumps(res)
+ self.assertEqual(res, self.loads(out))
try:
- json.dumps(res, allow_nan=False)
+ self.dumps(res, allow_nan=False)
except ValueError:
pass
else:
self.fail("23456789012E666 should be out of range")
+
+
+class TestPyPass1(TestPass1, PyTest): pass
+class TestCPass1(TestPass1, CTest): pass
diff --git a/Lib/json/tests/test_pass2.py b/Lib/json/tests/test_pass2.py
index 80d8433091..a2bb6d7211 100644
--- a/Lib/json/tests/test_pass2.py
+++ b/Lib/json/tests/test_pass2.py
@@ -1,14 +1,18 @@
-from unittest import TestCase
-import json
+from json.tests import PyTest, CTest
+
# from http://json.org/JSON_checker/test/pass2.json
JSON = r'''
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
'''
-class TestPass2(TestCase):
+class TestPass2(object):
def test_parse(self):
# test in/out equivalence and parsing
- res = json.loads(JSON)
- out = json.dumps(res)
- self.assertEquals(res, json.loads(out))
+ res = self.loads(JSON)
+ out = self.dumps(res)
+ self.assertEqual(res, self.loads(out))
+
+
+class TestPyPass2(TestPass2, PyTest): pass
+class TestCPass2(TestPass2, CTest): pass
diff --git a/Lib/json/tests/test_pass3.py b/Lib/json/tests/test_pass3.py
index 77d87b2aa5..221f9a0c3d 100644
--- a/Lib/json/tests/test_pass3.py
+++ b/Lib/json/tests/test_pass3.py
@@ -1,6 +1,5 @@
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
# from http://json.org/JSON_checker/test/pass3.json
JSON = r'''
@@ -12,9 +11,14 @@ JSON = r'''
}
'''
-class TestPass3(TestCase):
+
+class TestPass3(object):
def test_parse(self):
# test in/out equivalence and parsing
- res = json.loads(JSON)
- out = json.dumps(res)
- self.assertEquals(res, json.loads(out))
+ res = self.loads(JSON)
+ out = self.dumps(res)
+ self.assertEqual(res, self.loads(out))
+
+
+class TestPyPass3(TestPass3, PyTest): pass
+class TestCPass3(TestPass3, CTest): pass
diff --git a/Lib/json/tests/test_recursion.py b/Lib/json/tests/test_recursion.py
index 073d3c1bad..b5221e5d16 100644
--- a/Lib/json/tests/test_recursion.py
+++ b/Lib/json/tests/test_recursion.py
@@ -1,28 +1,16 @@
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
class JSONTestObject:
pass
-class RecursiveJSONEncoder(json.JSONEncoder):
- recurse = False
- def default(self, o):
- if o is JSONTestObject:
- if self.recurse:
- return [JSONTestObject]
- else:
- return 'JSONTestObject'
- return json.JSONEncoder.default(o)
-
-
-class TestRecursion(TestCase):
+class TestRecursion(object):
def test_listrecursion(self):
x = []
x.append(x)
try:
- json.dumps(x)
+ self.dumps(x)
except ValueError:
pass
else:
@@ -31,7 +19,7 @@ class TestRecursion(TestCase):
y = [x]
x.append(y)
try:
- json.dumps(x)
+ self.dumps(x)
except ValueError:
pass
else:
@@ -39,13 +27,13 @@ class TestRecursion(TestCase):
y = []
x = [y, y]
# ensure that the marker is cleared
- json.dumps(x)
+ self.dumps(x)
def test_dictrecursion(self):
x = {}
x["test"] = x
try:
- json.dumps(x)
+ self.dumps(x)
except ValueError:
pass
else:
@@ -53,11 +41,21 @@ class TestRecursion(TestCase):
x = {}
y = {"a": x, "b": x}
# ensure that the marker is cleared
- json.dumps(x)
+ self.dumps(x)
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()
- self.assertEquals(enc.encode(JSONTestObject), '"JSONTestObject"')
+ self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"')
enc.recurse = True
try:
enc.encode(JSONTestObject)
@@ -65,3 +63,46 @@ class TestRecursion(TestCase):
pass
else:
self.fail("didn't raise ValueError on default recursion")
+
+
+ def test_highly_nested_objects_decoding(self):
+ # test that loading highly-nested objects doesn't segfault when C
+ # accelerations are used. See #12017
+ # str
+ with self.assertRaises(RuntimeError):
+ self.loads('{"a":' * 100000 + '1' + '}' * 100000)
+ with self.assertRaises(RuntimeError):
+ self.loads('{"a":' * 100000 + '[1]' + '}' * 100000)
+ with self.assertRaises(RuntimeError):
+ self.loads('[' * 100000 + '1' + ']' * 100000)
+ # unicode
+ with self.assertRaises(RuntimeError):
+ self.loads(u'{"a":' * 100000 + u'1' + u'}' * 100000)
+ with self.assertRaises(RuntimeError):
+ self.loads(u'{"a":' * 100000 + u'[1]' + u'}' * 100000)
+ with self.assertRaises(RuntimeError):
+ self.loads(u'[' * 100000 + u'1' + u']' * 100000)
+
+ def test_highly_nested_objects_encoding(self):
+ # See #12051
+ l, d = [], {}
+ for x in xrange(100000):
+ l, d = [l], {'k':d}
+ with self.assertRaises(RuntimeError):
+ self.dumps(l)
+ with self.assertRaises(RuntimeError):
+ self.dumps(d)
+
+ def test_endless_recursion(self):
+ # 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):
+ EndlessJSONEncoder(check_circular=False).encode(5j)
+
+
+class TestPyRecursion(TestRecursion, PyTest): pass
+class TestCRecursion(TestRecursion, CTest): pass
diff --git a/Lib/json/tests/test_scanstring.py b/Lib/json/tests/test_scanstring.py
index 6b600dbe16..4fef8cbabf 100644
--- a/Lib/json/tests/test_scanstring.py
+++ b/Lib/json/tests/test_scanstring.py
@@ -1,109 +1,109 @@
import sys
-import decimal
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
-import json.decoder
-class TestScanString(TestCase):
- def test_py_scanstring(self):
- self._test_scanstring(json.decoder.py_scanstring)
-
- def test_c_scanstring(self):
- self._test_scanstring(json.decoder.c_scanstring)
-
- def _test_scanstring(self, scanstring):
- self.assertEquals(
+class TestScanstring(object):
+ def test_scanstring(self):
+ scanstring = self.json.decoder.scanstring
+ self.assertEqual(
scanstring('"z\\ud834\\udd20x"', 1, None, True),
(u'z\U0001d120x', 16))
if sys.maxunicode == 65535:
- self.assertEquals(
+ self.assertEqual(
scanstring(u'"z\U0001d120x"', 1, None, True),
(u'z\U0001d120x', 6))
else:
- self.assertEquals(
+ self.assertEqual(
scanstring(u'"z\U0001d120x"', 1, None, True),
(u'z\U0001d120x', 5))
- self.assertEquals(
+ self.assertEqual(
scanstring('"\\u007b"', 1, None, True),
(u'{', 8))
- self.assertEquals(
+ self.assertEqual(
scanstring('"A JSON payload should be an object or array, not a string."', 1, None, True),
(u'A JSON payload should be an object or array, not a string.', 60))
- self.assertEquals(
+ self.assertEqual(
scanstring('["Unclosed array"', 2, None, True),
(u'Unclosed array', 17))
- self.assertEquals(
+ self.assertEqual(
scanstring('["extra comma",]', 2, None, True),
(u'extra comma', 14))
- self.assertEquals(
+ self.assertEqual(
scanstring('["double extra comma",,]', 2, None, True),
(u'double extra comma', 21))
- self.assertEquals(
+ self.assertEqual(
scanstring('["Comma after the close"],', 2, None, True),
(u'Comma after the close', 24))
- self.assertEquals(
+ self.assertEqual(
scanstring('["Extra close"]]', 2, None, True),
(u'Extra close', 14))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Extra comma": true,}', 2, None, True),
(u'Extra comma', 14))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Extra value after close": true} "misplaced quoted value"', 2, None, True),
(u'Extra value after close', 26))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Illegal expression": 1 + 2}', 2, None, True),
(u'Illegal expression', 21))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Illegal invocation": alert()}', 2, None, True),
(u'Illegal invocation', 21))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Numbers cannot have leading zeroes": 013}', 2, None, True),
(u'Numbers cannot have leading zeroes', 37))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Numbers cannot be hex": 0x14}', 2, None, True),
(u'Numbers cannot be hex', 24))
- self.assertEquals(
+ self.assertEqual(
scanstring('[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', 21, None, True),
(u'Too deep', 30))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Missing colon" null}', 2, None, True),
(u'Missing colon', 16))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Double colon":: null}', 2, None, True),
(u'Double colon', 15))
- self.assertEquals(
+ self.assertEqual(
scanstring('{"Comma instead of colon", null}', 2, None, True),
(u'Comma instead of colon', 25))
- self.assertEquals(
+ self.assertEqual(
scanstring('["Colon instead of comma": false]', 2, None, True),
(u'Colon instead of comma', 25))
- self.assertEquals(
+ self.assertEqual(
scanstring('["Bad value", truth]', 2, None, True),
(u'Bad value', 12))
def test_issue3623(self):
- self.assertRaises(ValueError, json.decoder.scanstring, b"xxx", 1,
+ self.assertRaises(ValueError, self.json.decoder.scanstring, b"xxx", 1,
"xxx")
self.assertRaises(UnicodeDecodeError,
- json.encoder.encode_basestring_ascii, b"xx\xff")
+ self.json.encoder.encode_basestring_ascii, b"xx\xff")
+
+ def test_overflow(self):
+ with self.assertRaises(OverflowError):
+ self.json.decoder.scanstring(b"xxx", sys.maxsize+1)
+
+
+class TestPyScanstring(TestScanstring, PyTest): pass
+class TestCScanstring(TestScanstring, CTest): pass
diff --git a/Lib/json/tests/test_separators.py b/Lib/json/tests/test_separators.py
index 32db341929..a4246e1f2d 100644
--- a/Lib/json/tests/test_separators.py
+++ b/Lib/json/tests/test_separators.py
@@ -1,10 +1,8 @@
import textwrap
-from unittest import TestCase
+from json.tests import PyTest, CTest
-import json
-
-class TestSeparators(TestCase):
+class TestSeparators(object):
def test_separators(self):
h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
{'nifty': 87}, {'field': 'yes', 'morefield': False} ]
@@ -31,12 +29,16 @@ class TestSeparators(TestCase):
]""")
- d1 = json.dumps(h)
- d2 = json.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : '))
+ d1 = self.dumps(h)
+ d2 = self.dumps(h, indent=2, sort_keys=True, separators=(' ,', ' : '))
+
+ h1 = self.loads(d1)
+ h2 = self.loads(d2)
+
+ self.assertEqual(h1, h)
+ self.assertEqual(h2, h)
+ self.assertEqual(d2, expect)
- h1 = json.loads(d1)
- h2 = json.loads(d2)
- self.assertEquals(h1, h)
- self.assertEquals(h2, h)
- self.assertEquals(d2, expect)
+class TestPySeparators(TestSeparators, PyTest): pass
+class TestCSeparators(TestSeparators, CTest): pass
diff --git a/Lib/json/tests/test_speedups.py b/Lib/json/tests/test_speedups.py
index 8ff9a3812f..7186a40932 100644
--- a/Lib/json/tests/test_speedups.py
+++ b/Lib/json/tests/test_speedups.py
@@ -1,15 +1,23 @@
-import decimal
-from unittest import TestCase
+from json.tests import CTest
-from json import decoder
-from json import encoder
-class TestSpeedups(TestCase):
+class TestSpeedups(CTest):
def test_scanstring(self):
- self.assertEquals(decoder.scanstring.__module__, "_json")
- self.assert_(decoder.scanstring is decoder.c_scanstring)
+ self.assertEqual(self.json.decoder.scanstring.__module__, "_json")
+ self.assertIs(self.json.decoder.scanstring, self.json.decoder.c_scanstring)
def test_encode_basestring_ascii(self):
- self.assertEquals(encoder.encode_basestring_ascii.__module__, "_json")
- self.assert_(encoder.encode_basestring_ascii is
- encoder.c_encode_basestring_ascii)
+ self.assertEqual(self.json.encoder.encode_basestring_ascii.__module__,
+ "_json")
+ self.assertIs(self.json.encoder.encode_basestring_ascii,
+ self.json.encoder.c_encode_basestring_ascii)
+
+class TestDecode(CTest):
+ def test_make_scanner(self):
+ self.assertRaises(AttributeError, self.json.scanner.c_make_scanner, 1)
+
+ def test_make_encoder(self):
+ self.assertRaises(TypeError, self.json.encoder.c_make_encoder,
+ None,
+ "\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
+ None)
diff --git a/Lib/json/tests/test_unicode.py b/Lib/json/tests/test_unicode.py
index 3ac4541b6c..31cf38925c 100644
--- a/Lib/json/tests/test_unicode.py
+++ b/Lib/json/tests/test_unicode.py
@@ -1,55 +1,85 @@
-from unittest import TestCase
+from collections import OrderedDict
+from json.tests import PyTest, CTest
-import json
-class TestUnicode(TestCase):
+class TestUnicode(object):
def test_encoding1(self):
- encoder = json.JSONEncoder(encoding='utf-8')
+ encoder = self.json.JSONEncoder(encoding='utf-8')
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
s = u.encode('utf-8')
ju = encoder.encode(u)
js = encoder.encode(s)
- self.assertEquals(ju, js)
+ self.assertEqual(ju, js)
def test_encoding2(self):
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
s = u.encode('utf-8')
- ju = json.dumps(u, encoding='utf-8')
- js = json.dumps(s, encoding='utf-8')
- self.assertEquals(ju, js)
+ ju = self.dumps(u, encoding='utf-8')
+ js = self.dumps(s, encoding='utf-8')
+ self.assertEqual(ju, js)
def test_encoding3(self):
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
- j = json.dumps(u)
- self.assertEquals(j, '"\\u03b1\\u03a9"')
+ j = self.dumps(u)
+ self.assertEqual(j, '"\\u03b1\\u03a9"')
def test_encoding4(self):
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
- j = json.dumps([u])
- self.assertEquals(j, '["\\u03b1\\u03a9"]')
+ j = self.dumps([u])
+ self.assertEqual(j, '["\\u03b1\\u03a9"]')
def test_encoding5(self):
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
- j = json.dumps(u, ensure_ascii=False)
- self.assertEquals(j, u'"{0}"'.format(u))
+ j = self.dumps(u, ensure_ascii=False)
+ self.assertEqual(j, u'"{0}"'.format(u))
def test_encoding6(self):
u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
- j = json.dumps([u], ensure_ascii=False)
- self.assertEquals(j, u'["{0}"]'.format(u))
+ j = self.dumps([u], ensure_ascii=False)
+ self.assertEqual(j, u'["{0}"]'.format(u))
def test_big_unicode_encode(self):
u = u'\U0001d120'
- self.assertEquals(json.dumps(u), '"\\ud834\\udd20"')
- self.assertEquals(json.dumps(u, ensure_ascii=False), u'"\U0001d120"')
+ self.assertEqual(self.dumps(u), '"\\ud834\\udd20"')
+ self.assertEqual(self.dumps(u, ensure_ascii=False), u'"\U0001d120"')
def test_big_unicode_decode(self):
u = u'z\U0001d120x'
- self.assertEquals(json.loads('"' + u + '"'), u)
- self.assertEquals(json.loads('"z\\ud834\\udd20x"'), u)
+ self.assertEqual(self.loads('"' + u + '"'), u)
+ self.assertEqual(self.loads('"z\\ud834\\udd20x"'), u)
def test_unicode_decode(self):
for i in range(0, 0xd7ff):
u = unichr(i)
- js = '"\\u{0:04x}"'.format(i)
- self.assertEquals(json.loads(js), u)
+ s = '"\\u{0:04x}"'.format(i)
+ self.assertEqual(self.loads(s), u)
+
+ def test_object_pairs_hook_with_unicode(self):
+ s = u'{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}'
+ p = [(u"xkd", 1), (u"kcw", 2), (u"art", 3), (u"hxm", 4),
+ (u"qrt", 5), (u"pad", 6), (u"hoy", 7)]
+ self.assertEqual(self.loads(s), eval(s))
+ self.assertEqual(self.loads(s, object_pairs_hook = lambda x: x), p)
+ od = self.loads(s, object_pairs_hook = OrderedDict)
+ self.assertEqual(od, OrderedDict(p))
+ self.assertEqual(type(od), OrderedDict)
+ # the object_pairs_hook takes priority over the object_hook
+ self.assertEqual(self.loads(s,
+ object_pairs_hook = OrderedDict,
+ object_hook = lambda x: None),
+ OrderedDict(p))
+
+ def test_default_encoding(self):
+ self.assertEqual(self.loads(u'{"a": "\xe9"}'.encode('utf-8')),
+ {'a': u'\xe9'})
+
+ def test_unicode_preservation(self):
+ self.assertEqual(type(self.loads(u'""')), unicode)
+ self.assertEqual(type(self.loads(u'"a"')), unicode)
+ self.assertEqual(type(self.loads(u'["a"]')[0]), unicode)
+ # Issue 10038.
+ self.assertEqual(type(self.loads('"foo"')), unicode)
+
+
+class TestPyUnicode(TestUnicode, PyTest): pass
+class TestCUnicode(TestUnicode, CTest): pass