initial
diff --git a/simplejson/tests/.___init__.py b/simplejson/tests/.___init__.py
new file mode 100644
index 0000000..457e8bf
--- /dev/null
+++ b/simplejson/tests/.___init__.py
Binary files differ
diff --git a/simplejson/tests/._test_decimal.py b/simplejson/tests/._test_decimal.py
new file mode 100644
index 0000000..5c62656
--- /dev/null
+++ b/simplejson/tests/._test_decimal.py
Binary files differ
diff --git a/simplejson/tests/._test_decode.py b/simplejson/tests/._test_decode.py
new file mode 100644
index 0000000..cce2c80
--- /dev/null
+++ b/simplejson/tests/._test_decode.py
Binary files differ
diff --git a/simplejson/tests/._test_default.py b/simplejson/tests/._test_default.py
new file mode 100644
index 0000000..3ce0189
--- /dev/null
+++ b/simplejson/tests/._test_default.py
Binary files differ
diff --git a/simplejson/tests/._test_dump.py b/simplejson/tests/._test_dump.py
new file mode 100644
index 0000000..cc0e9d9
--- /dev/null
+++ b/simplejson/tests/._test_dump.py
Binary files differ
diff --git a/simplejson/tests/._test_encode_basestring_ascii.py b/simplejson/tests/._test_encode_basestring_ascii.py
new file mode 100644
index 0000000..e253291
--- /dev/null
+++ b/simplejson/tests/._test_encode_basestring_ascii.py
Binary files differ
diff --git a/simplejson/tests/._test_float.py b/simplejson/tests/._test_float.py
new file mode 100644
index 0000000..3f84ded
--- /dev/null
+++ b/simplejson/tests/._test_float.py
Binary files differ
diff --git a/simplejson/tests/._test_separators.py b/simplejson/tests/._test_separators.py
new file mode 100644
index 0000000..39f8ed2
--- /dev/null
+++ b/simplejson/tests/._test_separators.py
Binary files differ
diff --git a/simplejson/tests/._test_unicode.py b/simplejson/tests/._test_unicode.py
new file mode 100644
index 0000000..7f83797
--- /dev/null
+++ b/simplejson/tests/._test_unicode.py
Binary files differ
diff --git a/simplejson/tests/__init__.py b/simplejson/tests/__init__.py
new file mode 100644
index 0000000..22d8465
--- /dev/null
+++ b/simplejson/tests/__init__.py
@@ -0,0 +1,63 @@
+import unittest
+import doctest
+
+
+class OptionalExtensionTestSuite(unittest.TestSuite):
+    def run(self, result):
+        import simplejson
+        run = unittest.TestSuite.run
+        run(self, result)
+        simplejson._toggle_speedups(False)
+        run(self, result)
+        simplejson._toggle_speedups(True)
+        return result
+
+
+def additional_tests(suite=None):
+    import simplejson
+    import simplejson.encoder
+    import simplejson.decoder
+    if suite is None:
+        suite = unittest.TestSuite()
+    for mod in (simplejson, simplejson.encoder, simplejson.decoder):
+        suite.addTest(doctest.DocTestSuite(mod))
+    suite.addTest(doctest.DocFileSuite('../../index.rst'))
+    return suite
+
+
+def all_tests_suite():
+    suite = unittest.TestLoader().loadTestsFromNames([
+        'simplejson.tests.test_check_circular',
+        'simplejson.tests.test_decode',
+        'simplejson.tests.test_default',
+        'simplejson.tests.test_dump',
+        'simplejson.tests.test_encode_basestring_ascii',
+        'simplejson.tests.test_encode_for_html',
+        'simplejson.tests.test_fail',
+        'simplejson.tests.test_float',
+        'simplejson.tests.test_indent',
+        'simplejson.tests.test_pass1',
+        'simplejson.tests.test_pass2',
+        'simplejson.tests.test_pass3',
+        'simplejson.tests.test_recursion',
+        'simplejson.tests.test_scanstring',
+        'simplejson.tests.test_separators',
+        'simplejson.tests.test_speedups',
+        'simplejson.tests.test_unicode',
+        'simplejson.tests.test_decimal',
+    ])
+    suite = additional_tests(suite)
+    return OptionalExtensionTestSuite([suite])
+
+
+def main():
+    runner = unittest.TextTestRunner()
+    suite = all_tests_suite()
+    runner.run(suite)
+
+
+if __name__ == '__main__':
+    import os
+    import sys
+    sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+    main()
diff --git a/simplejson/tests/test_check_circular.py b/simplejson/tests/test_check_circular.py
new file mode 100644
index 0000000..af6463d
--- /dev/null
+++ b/simplejson/tests/test_check_circular.py
@@ -0,0 +1,30 @@
+from unittest import TestCase
+import simplejson as json
+
+def default_iterable(obj):
+    return list(obj)
+
+class TestCheckCircular(TestCase):
+    def test_circular_dict(self):
+        dct = {}
+        dct['a'] = dct
+        self.assertRaises(ValueError, json.dumps, dct)
+
+    def test_circular_list(self):
+        lst = []
+        lst.append(lst)
+        self.assertRaises(ValueError, json.dumps, lst)
+
+    def test_circular_composite(self):
+        dct2 = {}
+        dct2['a'] = []
+        dct2['a'].append(dct2)
+        self.assertRaises(ValueError, json.dumps, dct2)
+
+    def test_circular_default(self):
+        json.dumps([set()], default=default_iterable)
+        self.assertRaises(TypeError, json.dumps, [set()])
+
+    def test_circular_off_default(self):
+        json.dumps([set()], default=default_iterable, check_circular=False)
+        self.assertRaises(TypeError, json.dumps, [set()], check_circular=False)
diff --git a/simplejson/tests/test_decimal.py b/simplejson/tests/test_decimal.py
new file mode 100644
index 0000000..a694c7e
--- /dev/null
+++ b/simplejson/tests/test_decimal.py
@@ -0,0 +1,33 @@
+from decimal import Decimal
+from unittest import TestCase
+
+import simplejson as json
+
+class TestDecimal(TestCase):
+    NUMS = "1.0", "10.00", "1.1", "1234567890.1234567890", "500"
+    def test_decimal_encode(self):
+        for d in map(Decimal, self.NUMS):
+            self.assertEquals(json.dumps(d, use_decimal=True), str(d))
+    
+    def test_decimal_decode(self):
+        for s in self.NUMS:
+            self.assertEquals(json.loads(s, parse_float=Decimal), Decimal(s))
+    
+    def test_decimal_roundtrip(self):
+        for d in map(Decimal, self.NUMS):
+            # The type might not be the same (int and Decimal) but they
+            # should still compare equal.
+            self.assertEquals(
+                json.loads(
+                    json.dumps(d, use_decimal=True), parse_float=Decimal),
+                d)
+            self.assertEquals(
+                json.loads(
+                    json.dumps([d], use_decimal=True), parse_float=Decimal),
+                [d])
+
+    def test_decimal_defaults(self):
+        d = Decimal(1)
+        # use_decimal=False is the default
+        self.assertRaises(TypeError, json.dumps, d, use_decimal=False)
+        self.assertRaises(TypeError, json.dumps, d)
\ No newline at end of file
diff --git a/simplejson/tests/test_decode.py b/simplejson/tests/test_decode.py
new file mode 100644
index 0000000..a5a1c48
--- /dev/null
+++ b/simplejson/tests/test_decode.py
@@ -0,0 +1,73 @@
+import decimal
+from unittest import TestCase
+from StringIO import StringIO
+
+import simplejson as json
+from simplejson import OrderedDict
+
+class TestDecode(TestCase):
+    if not hasattr(TestCase, 'assertIs'):
+        def assertIs(self, a, b):
+            self.assertTrue(a is b, '%r is %r' % (a, b))
+
+    def test_decimal(self):
+        rval = json.loads('1.1', parse_float=decimal.Decimal)
+        self.assertTrue(isinstance(rval, decimal.Decimal))
+        self.assertEquals(rval, decimal.Decimal('1.1'))
+
+    def test_float(self):
+        rval = json.loads('1', parse_int=float)
+        self.assertTrue(isinstance(rval, float))
+        self.assertEquals(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 = json.loads('{   "key"    :    "value"    ,  "k":"v"    }')
+        self.assertEquals(rval, {"key":"value", "k":"v"})
+
+    def test_empty_objects(self):
+        s = '{}'
+        self.assertEqual(json.loads(s), eval(s))
+        s = '[]'
+        self.assertEqual(json.loads(s), eval(s))
+        s = '""'
+        self.assertEqual(json.loads(s), eval(s))
+
+    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(json.loads(s), eval(s))
+        self.assertEqual(json.loads(s, object_pairs_hook=lambda x: x), p)
+        self.assertEqual(json.load(StringIO(s),
+                                   object_pairs_hook=lambda x: x), p)
+        od = json.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(json.loads(s,
+                                    object_pairs_hook=OrderedDict,
+                                    object_hook=lambda x: None),
+                         OrderedDict(p))
+
+    def check_keys_reuse(self, source, loads):
+        rval = loads(source)
+        (a, b), (c, d) = sorted(rval[0]), sorted(rval[1])
+        self.assertIs(a, c)
+        self.assertIs(b, d)
+
+    def test_keys_reuse_str(self):
+        s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'.encode('utf8')
+        self.check_keys_reuse(s, json.loads)
+
+    def test_keys_reuse_unicode(self):
+        s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'
+        self.check_keys_reuse(s, json.loads)
+
+    def test_empty_strings(self):
+        self.assertEqual(json.loads('""'), "")
+        self.assertEqual(json.loads(u'""'), u"")
+        self.assertEqual(json.loads('[""]'), [""])
+        self.assertEqual(json.loads(u'[""]'), [u""])
diff --git a/simplejson/tests/test_default.py b/simplejson/tests/test_default.py
new file mode 100644
index 0000000..139e42b
--- /dev/null
+++ b/simplejson/tests/test_default.py
@@ -0,0 +1,9 @@
+from unittest import TestCase
+
+import simplejson as json
+
+class TestDefault(TestCase):
+    def test_default(self):
+        self.assertEquals(
+            json.dumps(type, default=repr),
+            json.dumps(repr(type)))
diff --git a/simplejson/tests/test_dump.py b/simplejson/tests/test_dump.py
new file mode 100644
index 0000000..8b34004
--- /dev/null
+++ b/simplejson/tests/test_dump.py
@@ -0,0 +1,27 @@
+from unittest import TestCase
+from cStringIO import StringIO
+
+import simplejson as json
+
+class TestDump(TestCase):
+    def test_dump(self):
+        sio = StringIO()
+        json.dump({}, sio)
+        self.assertEquals(sio.getvalue(), '{}')
+
+    def test_dumps(self):
+        self.assertEquals(json.dumps({}), '{}')
+
+    def test_encode_truefalse(self):
+        self.assertEquals(json.dumps(
+                 {True: False, False: True}, sort_keys=True),
+                 '{"false": true, "true": false}')
+        self.assertEquals(json.dumps(
+                {2: 3.0, 4.0: 5L, False: 1, 6L: True, "7": 0}, sort_keys=True),
+                '{"false": 1, "2": 3.0, "4.0": 5, "6": true, "7": 0}')
+
+    def test_ordered_dict(self):
+        # http://bugs.python.org/issue6105
+        items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
+        s = json.dumps(json.OrderedDict(items))
+        self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}')
\ No newline at end of file
diff --git a/simplejson/tests/test_encode_basestring_ascii.py b/simplejson/tests/test_encode_basestring_ascii.py
new file mode 100644
index 0000000..b19631a
--- /dev/null
+++ b/simplejson/tests/test_encode_basestring_ascii.py
@@ -0,0 +1,41 @@
+from unittest import TestCase
+
+import simplejson.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~!@#$%^&*()_+-=[]{}|;:\',./<>?"'),
+    (u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
+    (u'controls', '"controls"'),
+    (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
+    (u'{"object with 1 member":["array with 1 element"]}', '"{\\"object with 1 member\\":[\\"array with 1 element\\"]}"'),
+    (u' s p a c e d ', '" s p a c e d "'),
+    (u'\U0001d120', '"\\ud834\\udd20"'),
+    (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
+    ('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
+    (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
+    ('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
+    (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
+    (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
+    (u"`1~!@#$%^&*()_+-={':[,]}|;.</>?", '"`1~!@#$%^&*()_+-={\':[,]}|;.</>?"'),
+    (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
+    (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(simplejson.encoder.py_encode_basestring_ascii)
+
+    def test_c_encode_basestring_ascii(self):
+        if not simplejson.encoder.c_encode_basestring_ascii:
+            return
+        self._test_encode_basestring_ascii(simplejson.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:
+            result = encode_basestring_ascii(input_string)
+            #self.assertEquals(result, expect,
+            #    '{0!r} != {1!r} for {2}({3!r})'.format(
+            #        result, expect, fname, input_string))
+            self.assertEquals(result, expect,
+                '%r != %r for %s(%r)' % (result, expect, fname, input_string))
diff --git a/simplejson/tests/test_encode_for_html.py b/simplejson/tests/test_encode_for_html.py
new file mode 100644
index 0000000..c2d5f80
--- /dev/null
+++ b/simplejson/tests/test_encode_for_html.py
@@ -0,0 +1,32 @@
+import unittest
+
+import simplejson.decoder
+import simplejson.encoder
+
+
+class TestEncodeForHTML(unittest.TestCase):
+
+    def setUp(self):
+        self.decoder = simplejson.decoder.JSONDecoder()
+        self.encoder = simplejson.encoder.JSONEncoderForHTML()
+
+    def test_basic_encode(self):
+        self.assertEqual(r'"\u0026"', self.encoder.encode('&'))
+        self.assertEqual(r'"\u003c"', self.encoder.encode('<'))
+        self.assertEqual(r'"\u003e"', self.encoder.encode('>'))
+
+    def test_basic_roundtrip(self):
+        for char in '&<>':
+            self.assertEqual(
+                char, self.decoder.decode(
+                    self.encoder.encode(char)))
+
+    def test_prevent_script_breakout(self):
+        bad_string = '</script><script>alert("gotcha")</script>'
+        self.assertEqual(
+            r'"\u003c/script\u003e\u003cscript\u003e'
+            r'alert(\"gotcha\")\u003c/script\u003e"',
+            self.encoder.encode(bad_string))
+        self.assertEqual(
+            bad_string, self.decoder.decode(
+                self.encoder.encode(bad_string)))
diff --git a/simplejson/tests/test_fail.py b/simplejson/tests/test_fail.py
new file mode 100644
index 0000000..646c0f4
--- /dev/null
+++ b/simplejson/tests/test_fail.py
@@ -0,0 +1,91 @@
+from unittest import TestCase
+
+import simplejson as json
+
+# Fri Dec 30 18:57:26 2005
+JSONDOCS = [
+    # http://json.org/JSON_checker/test/fail1.json
+    '"A JSON payload should be an object or array, not a string."',
+    # http://json.org/JSON_checker/test/fail2.json
+    '["Unclosed array"',
+    # http://json.org/JSON_checker/test/fail3.json
+    '{unquoted_key: "keys must be quoted}',
+    # http://json.org/JSON_checker/test/fail4.json
+    '["extra comma",]',
+    # http://json.org/JSON_checker/test/fail5.json
+    '["double extra comma",,]',
+    # http://json.org/JSON_checker/test/fail6.json
+    '[   , "<-- missing value"]',
+    # http://json.org/JSON_checker/test/fail7.json
+    '["Comma after the close"],',
+    # http://json.org/JSON_checker/test/fail8.json
+    '["Extra close"]]',
+    # http://json.org/JSON_checker/test/fail9.json
+    '{"Extra comma": true,}',
+    # http://json.org/JSON_checker/test/fail10.json
+    '{"Extra value after close": true} "misplaced quoted value"',
+    # http://json.org/JSON_checker/test/fail11.json
+    '{"Illegal expression": 1 + 2}',
+    # http://json.org/JSON_checker/test/fail12.json
+    '{"Illegal invocation": alert()}',
+    # http://json.org/JSON_checker/test/fail13.json
+    '{"Numbers cannot have leading zeroes": 013}',
+    # http://json.org/JSON_checker/test/fail14.json
+    '{"Numbers cannot be hex": 0x14}',
+    # http://json.org/JSON_checker/test/fail15.json
+    '["Illegal backslash escape: \\x15"]',
+    # http://json.org/JSON_checker/test/fail16.json
+    '["Illegal backslash escape: \\\'"]',
+    # http://json.org/JSON_checker/test/fail17.json
+    '["Illegal backslash escape: \\017"]',
+    # http://json.org/JSON_checker/test/fail18.json
+    '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
+    # http://json.org/JSON_checker/test/fail19.json
+    '{"Missing colon" null}',
+    # http://json.org/JSON_checker/test/fail20.json
+    '{"Double colon":: null}',
+    # http://json.org/JSON_checker/test/fail21.json
+    '{"Comma instead of colon", null}',
+    # http://json.org/JSON_checker/test/fail22.json
+    '["Colon instead of comma": false]',
+    # http://json.org/JSON_checker/test/fail23.json
+    '["Bad value", truth]',
+    # http://json.org/JSON_checker/test/fail24.json
+    "['single quote']",
+    # http://code.google.com/p/simplejson/issues/detail?id=3
+    u'["A\u001FZ control characters in string"]',
+]
+
+SKIPS = {
+    1: "why not have a string payload?",
+    18: "spec doesn't specify any nesting limitations",
+}
+
+class TestFail(TestCase):
+    def test_failures(self):
+        for idx, doc in enumerate(JSONDOCS):
+            idx = idx + 1
+            if idx in SKIPS:
+                json.loads(doc)
+                continue
+            try:
+                json.loads(doc)
+            except json.JSONDecodeError:
+                pass
+            else:
+                #self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
+                self.fail("Expected failure for fail%d.json: %r" % (idx, doc))
+
+    def test_array_decoder_issue46(self):
+        # http://code.google.com/p/simplejson/issues/detail?id=46
+        for doc in [u'[,]', '[,]']:
+            try:
+                json.loads(doc)
+            except json.JSONDecodeError, e:
+                self.assertEquals(e.pos, 1)
+                self.assertEquals(e.lineno, 1)
+                self.assertEquals(e.colno, 1)
+            except Exception, e:
+                self.fail("Unexpected exception raised %r %s" % (e, e))
+            else:
+                self.fail("Unexpected success parsing '[,]'")
\ No newline at end of file
diff --git a/simplejson/tests/test_float.py b/simplejson/tests/test_float.py
new file mode 100644
index 0000000..94502c6
--- /dev/null
+++ b/simplejson/tests/test_float.py
@@ -0,0 +1,19 @@
+import math
+from unittest import TestCase
+
+import simplejson as json
+
+class TestFloat(TestCase):
+    def test_floats(self):
+        for num in [1617161771.7650001, math.pi, math.pi**100,
+                    math.pi**-100, 3.1]:
+            self.assertEquals(float(json.dumps(num)), num)
+            self.assertEquals(json.loads(json.dumps(num)), num)
+            self.assertEquals(json.loads(unicode(json.dumps(num))), num)
+
+    def test_ints(self):
+        for num in [1, 1L, 1<<32, 1<<64]:
+            self.assertEquals(json.dumps(num), str(num))
+            self.assertEquals(int(json.dumps(num)), num)
+            self.assertEquals(json.loads(json.dumps(num)), num)
+            self.assertEquals(json.loads(unicode(json.dumps(num))), num)
diff --git a/simplejson/tests/test_indent.py b/simplejson/tests/test_indent.py
new file mode 100644
index 0000000..985831b
--- /dev/null
+++ b/simplejson/tests/test_indent.py
@@ -0,0 +1,53 @@
+from unittest import TestCase
+
+import simplejson as json
+import textwrap
+
+class TestIndent(TestCase):
+    def test_indent(self):
+        h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh',
+             'i-vhbjkhnth',
+             {'nifty': 87}, {'field': 'yes', 'morefield': False} ]
+
+        expect = textwrap.dedent("""\
+        [
+        \t[
+        \t\t"blorpie"
+        \t],
+        \t[
+        \t\t"whoops"
+        \t],
+        \t[],
+        \t"d-shtaeou",
+        \t"d-nthiouh",
+        \t"i-vhbjkhnth",
+        \t{
+        \t\t"nifty": 87
+        \t},
+        \t{
+        \t\t"field": "yes",
+        \t\t"morefield": false
+        \t}
+        ]""")
+
+
+        d1 = json.dumps(h)
+        d2 = json.dumps(h, indent='\t', sort_keys=True, separators=(',', ': '))
+        d3 = json.dumps(h, indent='  ', sort_keys=True, separators=(',', ': '))
+        d4 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
+
+        h1 = json.loads(d1)
+        h2 = json.loads(d2)
+        h3 = json.loads(d3)
+        h4 = json.loads(d4)
+
+        self.assertEquals(h1, h)
+        self.assertEquals(h2, h)
+        self.assertEquals(h3, h)
+        self.assertEquals(h4, h)
+        self.assertEquals(d3, expect.replace('\t', '  '))
+        self.assertEquals(d4, expect.replace('\t', '  '))
+        # NOTE: Python 2.4 textwrap.dedent converts tabs to spaces,
+        #       so the following is expected to fail. Python 2.4 is not a
+        #       supported platform in simplejson 2.1.0+.
+        self.assertEquals(d2, expect)
diff --git a/simplejson/tests/test_pass1.py b/simplejson/tests/test_pass1.py
new file mode 100644
index 0000000..c3d6302
--- /dev/null
+++ b/simplejson/tests/test_pass1.py
@@ -0,0 +1,76 @@
+from unittest import TestCase
+
+import simplejson as json
+
+# from http://json.org/JSON_checker/test/pass1.json
+JSON = r'''
+[
+    "JSON Test Pattern pass1",
+    {"object with 1 member":["array with 1 element"]},
+    {},
+    [],
+    -42,
+    true,
+    false,
+    null,
+    {
+        "integer": 1234567890,
+        "real": -9876.543210,
+        "e": 0.123456789e-12,
+        "E": 1.234567890E+34,
+        "":  23456789012E666,
+        "zero": 0,
+        "one": 1,
+        "space": " ",
+        "quote": "\"",
+        "backslash": "\\",
+        "controls": "\b\f\n\r\t",
+        "slash": "/ & \/",
+        "alpha": "abcdefghijklmnopqrstuvwyz",
+        "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+        "digit": "0123456789",
+        "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+        "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+        "true": true,
+        "false": false,
+        "null": null,
+        "array":[  ],
+        "object":{  },
+        "address": "50 St. James Street",
+        "url": "http://www.JSON.org/",
+        "comment": "// /* <!-- --",
+        "# -- --> */": " ",
+        " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5        ,          6           ,7        ],
+        "compact": [1,2,3,4,5,6,7],
+        "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+        "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+        "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+    },
+    0.5 ,98.6
+,
+99.44
+,
+
+1066
+
+
+,"rosebud"]
+'''
+
+class TestPass1(TestCase):
+    def test_parse(self):
+        # test in/out equivalence and parsing
+        res = json.loads(JSON)
+        out = json.dumps(res)
+        self.assertEquals(res, json.loads(out))
+        try:
+            json.dumps(res, allow_nan=False)
+        except ValueError:
+            pass
+        else:
+            self.fail("23456789012E666 should be out of range")
diff --git a/simplejson/tests/test_pass2.py b/simplejson/tests/test_pass2.py
new file mode 100644
index 0000000..de4ee00
--- /dev/null
+++ b/simplejson/tests/test_pass2.py
@@ -0,0 +1,14 @@
+from unittest import TestCase
+import simplejson as json
+
+# from http://json.org/JSON_checker/test/pass2.json
+JSON = r'''
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
+'''
+
+class TestPass2(TestCase):
+    def test_parse(self):
+        # test in/out equivalence and parsing
+        res = json.loads(JSON)
+        out = json.dumps(res)
+        self.assertEquals(res, json.loads(out))
diff --git a/simplejson/tests/test_pass3.py b/simplejson/tests/test_pass3.py
new file mode 100644
index 0000000..f591aba
--- /dev/null
+++ b/simplejson/tests/test_pass3.py
@@ -0,0 +1,20 @@
+from unittest import TestCase
+
+import simplejson as json
+
+# from http://json.org/JSON_checker/test/pass3.json
+JSON = r'''
+{
+    "JSON Test Pattern pass3": {
+        "The outermost value": "must be an object or array.",
+        "In this test": "It is an object."
+    }
+}
+'''
+
+class TestPass3(TestCase):
+    def test_parse(self):
+        # test in/out equivalence and parsing
+        res = json.loads(JSON)
+        out = json.dumps(res)
+        self.assertEquals(res, json.loads(out))
diff --git a/simplejson/tests/test_recursion.py b/simplejson/tests/test_recursion.py
new file mode 100644
index 0000000..97422a6
--- /dev/null
+++ b/simplejson/tests/test_recursion.py
@@ -0,0 +1,67 @@
+from unittest import TestCase
+
+import simplejson as 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):
+    def test_listrecursion(self):
+        x = []
+        x.append(x)
+        try:
+            json.dumps(x)
+        except ValueError:
+            pass
+        else:
+            self.fail("didn't raise ValueError on list recursion")
+        x = []
+        y = [x]
+        x.append(y)
+        try:
+            json.dumps(x)
+        except ValueError:
+            pass
+        else:
+            self.fail("didn't raise ValueError on alternating list recursion")
+        y = []
+        x = [y, y]
+        # ensure that the marker is cleared
+        json.dumps(x)
+
+    def test_dictrecursion(self):
+        x = {}
+        x["test"] = x
+        try:
+            json.dumps(x)
+        except ValueError:
+            pass
+        else:
+            self.fail("didn't raise ValueError on dict recursion")
+        x = {}
+        y = {"a": x, "b": x}
+        # ensure that the marker is cleared
+        json.dumps(x)
+
+    def test_defaultrecursion(self):
+        enc = RecursiveJSONEncoder()
+        self.assertEquals(enc.encode(JSONTestObject), '"JSONTestObject"')
+        enc.recurse = True
+        try:
+            enc.encode(JSONTestObject)
+        except ValueError:
+            pass
+        else:
+            self.fail("didn't raise ValueError on default recursion")
diff --git a/simplejson/tests/test_scanstring.py b/simplejson/tests/test_scanstring.py
new file mode 100644
index 0000000..a7fcd46
--- /dev/null
+++ b/simplejson/tests/test_scanstring.py
@@ -0,0 +1,117 @@
+import sys
+from unittest import TestCase
+
+import simplejson as json
+import simplejson.decoder
+
+class TestScanString(TestCase):
+    def test_py_scanstring(self):
+        self._test_scanstring(simplejson.decoder.py_scanstring)
+
+    def test_c_scanstring(self):
+        if not simplejson.decoder.c_scanstring:
+            return
+        self._test_scanstring(simplejson.decoder.c_scanstring)
+
+    def _test_scanstring(self, scanstring):
+        self.assertEquals(
+            scanstring('"z\\ud834\\udd20x"', 1, None, True),
+            (u'z\U0001d120x', 16))
+
+        if sys.maxunicode == 65535:
+            self.assertEquals(
+                scanstring(u'"z\U0001d120x"', 1, None, True),
+                (u'z\U0001d120x', 6))
+        else:
+            self.assertEquals(
+                scanstring(u'"z\U0001d120x"', 1, None, True),
+                (u'z\U0001d120x', 5))
+
+        self.assertEquals(
+            scanstring('"\\u007b"', 1, None, True),
+            (u'{', 8))
+
+        self.assertEquals(
+            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(
+            scanstring('["Unclosed array"', 2, None, True),
+            (u'Unclosed array', 17))
+
+        self.assertEquals(
+            scanstring('["extra comma",]', 2, None, True),
+            (u'extra comma', 14))
+
+        self.assertEquals(
+            scanstring('["double extra comma",,]', 2, None, True),
+            (u'double extra comma', 21))
+
+        self.assertEquals(
+            scanstring('["Comma after the close"],', 2, None, True),
+            (u'Comma after the close', 24))
+
+        self.assertEquals(
+            scanstring('["Extra close"]]', 2, None, True),
+            (u'Extra close', 14))
+
+        self.assertEquals(
+            scanstring('{"Extra comma": true,}', 2, None, True),
+            (u'Extra comma', 14))
+
+        self.assertEquals(
+            scanstring('{"Extra value after close": true} "misplaced quoted value"', 2, None, True),
+            (u'Extra value after close', 26))
+
+        self.assertEquals(
+            scanstring('{"Illegal expression": 1 + 2}', 2, None, True),
+            (u'Illegal expression', 21))
+
+        self.assertEquals(
+            scanstring('{"Illegal invocation": alert()}', 2, None, True),
+            (u'Illegal invocation', 21))
+
+        self.assertEquals(
+            scanstring('{"Numbers cannot have leading zeroes": 013}', 2, None, True),
+            (u'Numbers cannot have leading zeroes', 37))
+
+        self.assertEquals(
+            scanstring('{"Numbers cannot be hex": 0x14}', 2, None, True),
+            (u'Numbers cannot be hex', 24))
+
+        self.assertEquals(
+            scanstring('[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', 21, None, True),
+            (u'Too deep', 30))
+
+        self.assertEquals(
+            scanstring('{"Missing colon" null}', 2, None, True),
+            (u'Missing colon', 16))
+
+        self.assertEquals(
+            scanstring('{"Double colon":: null}', 2, None, True),
+            (u'Double colon', 15))
+
+        self.assertEquals(
+            scanstring('{"Comma instead of colon", null}', 2, None, True),
+            (u'Comma instead of colon', 25))
+
+        self.assertEquals(
+            scanstring('["Colon instead of comma": false]', 2, None, True),
+            (u'Colon instead of comma', 25))
+
+        self.assertEquals(
+            scanstring('["Bad value", truth]', 2, None, True),
+            (u'Bad value', 12))
+
+    def test_issue3623(self):
+        self.assertRaises(ValueError, json.decoder.scanstring, "xxx", 1,
+                          "xxx")
+        self.assertRaises(UnicodeDecodeError,
+                          json.encoder.encode_basestring_ascii, "xx\xff")
+
+    def test_overflow(self):
+        # Python 2.5 does not have maxsize
+        maxsize = getattr(sys, 'maxsize', sys.maxint)
+        self.assertRaises(OverflowError, json.decoder.scanstring, "xxx",
+                          maxsize + 1)
+
diff --git a/simplejson/tests/test_separators.py b/simplejson/tests/test_separators.py
new file mode 100644
index 0000000..cbda93c
--- /dev/null
+++ b/simplejson/tests/test_separators.py
@@ -0,0 +1,42 @@
+import textwrap
+from unittest import TestCase
+
+import simplejson as json
+
+
+class TestSeparators(TestCase):
+    def test_separators(self):
+        h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth',
+             {'nifty': 87}, {'field': 'yes', 'morefield': False} ]
+
+        expect = textwrap.dedent("""\
+        [
+          [
+            "blorpie"
+          ] ,
+          [
+            "whoops"
+          ] ,
+          [] ,
+          "d-shtaeou" ,
+          "d-nthiouh" ,
+          "i-vhbjkhnth" ,
+          {
+            "nifty" : 87
+          } ,
+          {
+            "field" : "yes" ,
+            "morefield" : false
+          }
+        ]""")
+
+
+        d1 = json.dumps(h)
+        d2 = json.dumps(h, indent='  ', sort_keys=True, separators=(' ,', ' : '))
+
+        h1 = json.loads(d1)
+        h2 = json.loads(d2)
+
+        self.assertEquals(h1, h)
+        self.assertEquals(h2, h)
+        self.assertEquals(d2, expect)
diff --git a/simplejson/tests/test_speedups.py b/simplejson/tests/test_speedups.py
new file mode 100644
index 0000000..4bf0875
--- /dev/null
+++ b/simplejson/tests/test_speedups.py
@@ -0,0 +1,21 @@
+import decimal
+from unittest import TestCase
+
+from simplejson import decoder, encoder, scanner
+
+def has_speedups():
+    return encoder.c_make_encoder is not None
+
+class TestDecode(TestCase):
+    def test_make_scanner(self):
+        if not has_speedups():
+            return
+        self.assertRaises(AttributeError, scanner.c_make_scanner, 1)
+
+    def test_make_encoder(self):
+        if not has_speedups():
+            return
+        self.assertRaises(TypeError, 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/simplejson/tests/test_unicode.py b/simplejson/tests/test_unicode.py
new file mode 100644
index 0000000..f73e5bf
--- /dev/null
+++ b/simplejson/tests/test_unicode.py
@@ -0,0 +1,99 @@
+from unittest import TestCase
+
+import simplejson as json
+
+class TestUnicode(TestCase):
+    def test_encoding1(self):
+        encoder = 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)
+
+    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)
+
+    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"')
+
+    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"]')
+
+    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'"' + u + 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'["' + u + 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"')
+
+    def test_big_unicode_decode(self):
+        u = u'z\U0001d120x'
+        self.assertEquals(json.loads('"' + u + '"'), u)
+        self.assertEquals(json.loads('"z\\ud834\\udd20x"'), u)
+
+    def test_unicode_decode(self):
+        for i in range(0, 0xd7ff):
+            u = unichr(i)
+            #s = '"\\u{0:04x}"'.format(i)
+            s = '"\\u%04x"' % (i,)
+            self.assertEquals(json.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(json.loads(s), eval(s))
+        self.assertEqual(json.loads(s, object_pairs_hook=lambda x: x), p)
+        od = json.loads(s, object_pairs_hook=json.OrderedDict)
+        self.assertEqual(od, json.OrderedDict(p))
+        self.assertEqual(type(od), json.OrderedDict)
+        # the object_pairs_hook takes priority over the object_hook
+        self.assertEqual(json.loads(s,
+                                    object_pairs_hook=json.OrderedDict,
+                                    object_hook=lambda x: None),
+                         json.OrderedDict(p))
+
+
+    def test_default_encoding(self):
+        self.assertEquals(json.loads(u'{"a": "\xe9"}'.encode('utf-8')),
+            {'a': u'\xe9'})
+
+    def test_unicode_preservation(self):
+        self.assertEquals(type(json.loads(u'""')), unicode)
+        self.assertEquals(type(json.loads(u'"a"')), unicode)
+        self.assertEquals(type(json.loads(u'["a"]')[0]), unicode)
+
+    def test_ensure_ascii_false_returns_unicode(self):
+        # http://code.google.com/p/simplejson/issues/detail?id=48
+        self.assertEquals(type(json.dumps([], ensure_ascii=False)), unicode)
+        self.assertEquals(type(json.dumps(0, ensure_ascii=False)), unicode)
+        self.assertEquals(type(json.dumps({}, ensure_ascii=False)), unicode)
+        self.assertEquals(type(json.dumps("", ensure_ascii=False)), unicode)
+
+    def test_ensure_ascii_false_bytestring_encoding(self):
+        # http://code.google.com/p/simplejson/issues/detail?id=48
+        doc1 = {u'quux': 'Arr\xc3\xaat sur images'}
+        doc2 = {u'quux': u'Arr\xeat sur images'}
+        doc_ascii = '{"quux": "Arr\\u00eat sur images"}'
+        doc_unicode = u'{"quux": "Arr\xeat sur images"}'
+        self.assertEquals(json.dumps(doc1), doc_ascii)
+        self.assertEquals(json.dumps(doc2), doc_ascii)
+        self.assertEquals(json.dumps(doc1, ensure_ascii=False), doc_unicode)
+        self.assertEquals(json.dumps(doc2, ensure_ascii=False), doc_unicode)