pygments.rb 0.2.13 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/.gitignore +1 -0
  2. data/README.md +45 -19
  3. data/Rakefile +21 -11
  4. data/bench.rb +15 -48
  5. data/cache-lexers.rb +8 -0
  6. data/lexers +0 -0
  7. data/lib/pygments.rb +3 -6
  8. data/lib/pygments/mentos.py +343 -0
  9. data/lib/pygments/popen.rb +383 -0
  10. data/lib/pygments/version.rb +1 -1
  11. data/pygments.rb.gemspec +5 -4
  12. data/test/test_data.c +2581 -0
  13. data/test/test_data.py +514 -0
  14. data/test/test_data_generated +2582 -0
  15. data/test/test_pygments.rb +208 -84
  16. data/vendor/pygments-main/pygments/lexers/_mapping.py +1 -1
  17. data/vendor/pygments-main/pygments/lexers/shell.py +1 -1
  18. data/vendor/simplejson/.gitignore +10 -0
  19. data/vendor/simplejson/.travis.yml +5 -0
  20. data/vendor/simplejson/CHANGES.txt +291 -0
  21. data/vendor/simplejson/LICENSE.txt +19 -0
  22. data/vendor/simplejson/MANIFEST.in +5 -0
  23. data/vendor/simplejson/README.rst +19 -0
  24. data/vendor/simplejson/conf.py +179 -0
  25. data/vendor/simplejson/index.rst +628 -0
  26. data/vendor/simplejson/scripts/make_docs.py +18 -0
  27. data/vendor/simplejson/setup.py +104 -0
  28. data/vendor/simplejson/simplejson/__init__.py +510 -0
  29. data/vendor/simplejson/simplejson/_speedups.c +2745 -0
  30. data/vendor/simplejson/simplejson/decoder.py +425 -0
  31. data/vendor/simplejson/simplejson/encoder.py +567 -0
  32. data/vendor/simplejson/simplejson/ordered_dict.py +119 -0
  33. data/vendor/simplejson/simplejson/scanner.py +77 -0
  34. data/vendor/simplejson/simplejson/tests/__init__.py +67 -0
  35. data/vendor/simplejson/simplejson/tests/test_bigint_as_string.py +55 -0
  36. data/vendor/simplejson/simplejson/tests/test_check_circular.py +30 -0
  37. data/vendor/simplejson/simplejson/tests/test_decimal.py +66 -0
  38. data/vendor/simplejson/simplejson/tests/test_decode.py +83 -0
  39. data/vendor/simplejson/simplejson/tests/test_default.py +9 -0
  40. data/vendor/simplejson/simplejson/tests/test_dump.py +67 -0
  41. data/vendor/simplejson/simplejson/tests/test_encode_basestring_ascii.py +46 -0
  42. data/vendor/simplejson/simplejson/tests/test_encode_for_html.py +32 -0
  43. data/vendor/simplejson/simplejson/tests/test_errors.py +34 -0
  44. data/vendor/simplejson/simplejson/tests/test_fail.py +91 -0
  45. data/vendor/simplejson/simplejson/tests/test_float.py +19 -0
  46. data/vendor/simplejson/simplejson/tests/test_indent.py +86 -0
  47. data/vendor/simplejson/simplejson/tests/test_item_sort_key.py +20 -0
  48. data/vendor/simplejson/simplejson/tests/test_namedtuple.py +121 -0
  49. data/vendor/simplejson/simplejson/tests/test_pass1.py +76 -0
  50. data/vendor/simplejson/simplejson/tests/test_pass2.py +14 -0
  51. data/vendor/simplejson/simplejson/tests/test_pass3.py +20 -0
  52. data/vendor/simplejson/simplejson/tests/test_recursion.py +67 -0
  53. data/vendor/simplejson/simplejson/tests/test_scanstring.py +117 -0
  54. data/vendor/simplejson/simplejson/tests/test_separators.py +42 -0
  55. data/vendor/simplejson/simplejson/tests/test_speedups.py +20 -0
  56. data/vendor/simplejson/simplejson/tests/test_tuple.py +49 -0
  57. data/vendor/simplejson/simplejson/tests/test_unicode.py +109 -0
  58. data/vendor/simplejson/simplejson/tool.py +39 -0
  59. metadata +80 -22
  60. data/ext/extconf.rb +0 -14
  61. data/ext/pygments.c +0 -466
  62. data/lib/pygments/c.rb +0 -54
  63. data/lib/pygments/ffi.rb +0 -155
  64. data/vendor/.gitignore +0 -1
@@ -0,0 +1,9 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson as json
4
+
5
+ class TestDefault(TestCase):
6
+ def test_default(self):
7
+ self.assertEquals(
8
+ json.dumps(type, default=repr),
9
+ json.dumps(repr(type)))
@@ -0,0 +1,67 @@
1
+ from unittest import TestCase
2
+ from cStringIO import StringIO
3
+
4
+ import simplejson as json
5
+
6
+ class TestDump(TestCase):
7
+ def test_dump(self):
8
+ sio = StringIO()
9
+ json.dump({}, sio)
10
+ self.assertEquals(sio.getvalue(), '{}')
11
+
12
+ def test_dumps(self):
13
+ self.assertEquals(json.dumps({}), '{}')
14
+
15
+ def test_encode_truefalse(self):
16
+ self.assertEquals(json.dumps(
17
+ {True: False, False: True}, sort_keys=True),
18
+ '{"false": true, "true": false}')
19
+ self.assertEquals(json.dumps(
20
+ {2: 3.0, 4.0: 5L, False: 1, 6L: True, "7": 0}, sort_keys=True),
21
+ '{"false": 1, "2": 3.0, "4.0": 5, "6": true, "7": 0}')
22
+
23
+ def test_ordered_dict(self):
24
+ # http://bugs.python.org/issue6105
25
+ items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
26
+ s = json.dumps(json.OrderedDict(items))
27
+ self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}')
28
+
29
+ def test_indent_unknown_type_acceptance(self):
30
+ """
31
+ A test against the regression mentioned at `github issue 29`_.
32
+
33
+ The indent parameter should accept any type which pretends to be
34
+ an instance of int or long when it comes to being multiplied by
35
+ strings, even if it is not actually an int or long, for
36
+ backwards compatibility.
37
+
38
+ .. _github issue 29:
39
+ http://github.com/simplejson/simplejson/issue/29
40
+ """
41
+
42
+ class AwesomeInt(object):
43
+ """An awesome reimplementation of integers"""
44
+
45
+ def __init__(self, *args, **kwargs):
46
+ if len(args) > 0:
47
+ # [construct from literals, objects, etc.]
48
+ # ...
49
+
50
+ # Finally, if args[0] is an integer, store it
51
+ if isinstance(args[0], int):
52
+ self._int = args[0]
53
+
54
+ # [various methods]
55
+
56
+ def __mul__(self, other):
57
+ # [various ways to multiply AwesomeInt objects]
58
+ # ... finally, if the right-hand operand is not awesome enough,
59
+ # try to do a normal integer multiplication
60
+ if hasattr(self, '_int'):
61
+ return self._int * other
62
+ else:
63
+ raise NotImplementedError("To do non-awesome things with"
64
+ " this object, please construct it from an integer!")
65
+
66
+ s = json.dumps(range(3), indent=AwesomeInt(3))
67
+ self.assertEqual(s, '[\n 0,\n 1,\n 2\n]')
@@ -0,0 +1,46 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson.encoder
4
+
5
+ CASES = [
6
+ (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~!@#$%^&*()_+-=[]{}|;:\',./<>?"'),
7
+ (u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
8
+ (u'controls', '"controls"'),
9
+ (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
10
+ (u'{"object with 1 member":["array with 1 element"]}', '"{\\"object with 1 member\\":[\\"array with 1 element\\"]}"'),
11
+ (u' s p a c e d ', '" s p a c e d "'),
12
+ (u'\U0001d120', '"\\ud834\\udd20"'),
13
+ (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
14
+ ('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
15
+ (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
16
+ ('\xce\xb1\xce\xa9', '"\\u03b1\\u03a9"'),
17
+ (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
18
+ (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'),
19
+ (u"`1~!@#$%^&*()_+-={':[,]}|;.</>?", '"`1~!@#$%^&*()_+-={\':[,]}|;.</>?"'),
20
+ (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'),
21
+ (u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'),
22
+ ]
23
+
24
+ class TestEncodeBaseStringAscii(TestCase):
25
+ def test_py_encode_basestring_ascii(self):
26
+ self._test_encode_basestring_ascii(simplejson.encoder.py_encode_basestring_ascii)
27
+
28
+ def test_c_encode_basestring_ascii(self):
29
+ if not simplejson.encoder.c_encode_basestring_ascii:
30
+ return
31
+ self._test_encode_basestring_ascii(simplejson.encoder.c_encode_basestring_ascii)
32
+
33
+ def _test_encode_basestring_ascii(self, encode_basestring_ascii):
34
+ fname = encode_basestring_ascii.__name__
35
+ for input_string, expect in CASES:
36
+ result = encode_basestring_ascii(input_string)
37
+ #self.assertEquals(result, expect,
38
+ # '{0!r} != {1!r} for {2}({3!r})'.format(
39
+ # result, expect, fname, input_string))
40
+ self.assertEquals(result, expect,
41
+ '%r != %r for %s(%r)' % (result, expect, fname, input_string))
42
+
43
+ def test_sorted_dict(self):
44
+ items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
45
+ s = simplejson.dumps(dict(items), sort_keys=True)
46
+ self.assertEqual(s, '{"five": 5, "four": 4, "one": 1, "three": 3, "two": 2}')
@@ -0,0 +1,32 @@
1
+ import unittest
2
+
3
+ import simplejson.decoder
4
+ import simplejson.encoder
5
+
6
+
7
+ class TestEncodeForHTML(unittest.TestCase):
8
+
9
+ def setUp(self):
10
+ self.decoder = simplejson.decoder.JSONDecoder()
11
+ self.encoder = simplejson.encoder.JSONEncoderForHTML()
12
+
13
+ def test_basic_encode(self):
14
+ self.assertEqual(r'"\u0026"', self.encoder.encode('&'))
15
+ self.assertEqual(r'"\u003c"', self.encoder.encode('<'))
16
+ self.assertEqual(r'"\u003e"', self.encoder.encode('>'))
17
+
18
+ def test_basic_roundtrip(self):
19
+ for char in '&<>':
20
+ self.assertEqual(
21
+ char, self.decoder.decode(
22
+ self.encoder.encode(char)))
23
+
24
+ def test_prevent_script_breakout(self):
25
+ bad_string = '</script><script>alert("gotcha")</script>'
26
+ self.assertEqual(
27
+ r'"\u003c/script\u003e\u003cscript\u003e'
28
+ r'alert(\"gotcha\")\u003c/script\u003e"',
29
+ self.encoder.encode(bad_string))
30
+ self.assertEqual(
31
+ bad_string, self.decoder.decode(
32
+ self.encoder.encode(bad_string)))
@@ -0,0 +1,34 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson as json
4
+
5
+ class TestErrors(TestCase):
6
+ def test_string_keys_error(self):
7
+ data = [{'a': 'A', 'b': (2, 4), 'c': 3.0, ('d',): 'D tuple'}]
8
+ self.assertRaises(TypeError, json.dumps, data)
9
+
10
+ def test_decode_error(self):
11
+ err = None
12
+ try:
13
+ json.loads('{}\na\nb')
14
+ except json.JSONDecodeError, e:
15
+ err = e
16
+ else:
17
+ self.fail('Expected JSONDecodeError')
18
+ self.assertEquals(err.lineno, 2)
19
+ self.assertEquals(err.colno, 1)
20
+ self.assertEquals(err.endlineno, 3)
21
+ self.assertEquals(err.endcolno, 2)
22
+
23
+ def test_scan_error(self):
24
+ err = None
25
+ for t in (str, unicode):
26
+ try:
27
+ json.loads(t('{"asdf": "'))
28
+ except json.JSONDecodeError, e:
29
+ err = e
30
+ else:
31
+ self.fail('Expected JSONDecodeError')
32
+ self.assertEquals(err.lineno, 1)
33
+ self.assertEquals(err.colno, 9)
34
+
@@ -0,0 +1,91 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson as json
4
+
5
+ # Fri Dec 30 18:57:26 2005
6
+ JSONDOCS = [
7
+ # http://json.org/JSON_checker/test/fail1.json
8
+ '"A JSON payload should be an object or array, not a string."',
9
+ # http://json.org/JSON_checker/test/fail2.json
10
+ '["Unclosed array"',
11
+ # http://json.org/JSON_checker/test/fail3.json
12
+ '{unquoted_key: "keys must be quoted}',
13
+ # http://json.org/JSON_checker/test/fail4.json
14
+ '["extra comma",]',
15
+ # http://json.org/JSON_checker/test/fail5.json
16
+ '["double extra comma",,]',
17
+ # http://json.org/JSON_checker/test/fail6.json
18
+ '[ , "<-- missing value"]',
19
+ # http://json.org/JSON_checker/test/fail7.json
20
+ '["Comma after the close"],',
21
+ # http://json.org/JSON_checker/test/fail8.json
22
+ '["Extra close"]]',
23
+ # http://json.org/JSON_checker/test/fail9.json
24
+ '{"Extra comma": true,}',
25
+ # http://json.org/JSON_checker/test/fail10.json
26
+ '{"Extra value after close": true} "misplaced quoted value"',
27
+ # http://json.org/JSON_checker/test/fail11.json
28
+ '{"Illegal expression": 1 + 2}',
29
+ # http://json.org/JSON_checker/test/fail12.json
30
+ '{"Illegal invocation": alert()}',
31
+ # http://json.org/JSON_checker/test/fail13.json
32
+ '{"Numbers cannot have leading zeroes": 013}',
33
+ # http://json.org/JSON_checker/test/fail14.json
34
+ '{"Numbers cannot be hex": 0x14}',
35
+ # http://json.org/JSON_checker/test/fail15.json
36
+ '["Illegal backslash escape: \\x15"]',
37
+ # http://json.org/JSON_checker/test/fail16.json
38
+ '["Illegal backslash escape: \\\'"]',
39
+ # http://json.org/JSON_checker/test/fail17.json
40
+ '["Illegal backslash escape: \\017"]',
41
+ # http://json.org/JSON_checker/test/fail18.json
42
+ '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
43
+ # http://json.org/JSON_checker/test/fail19.json
44
+ '{"Missing colon" null}',
45
+ # http://json.org/JSON_checker/test/fail20.json
46
+ '{"Double colon":: null}',
47
+ # http://json.org/JSON_checker/test/fail21.json
48
+ '{"Comma instead of colon", null}',
49
+ # http://json.org/JSON_checker/test/fail22.json
50
+ '["Colon instead of comma": false]',
51
+ # http://json.org/JSON_checker/test/fail23.json
52
+ '["Bad value", truth]',
53
+ # http://json.org/JSON_checker/test/fail24.json
54
+ "['single quote']",
55
+ # http://code.google.com/p/simplejson/issues/detail?id=3
56
+ u'["A\u001FZ control characters in string"]',
57
+ ]
58
+
59
+ SKIPS = {
60
+ 1: "why not have a string payload?",
61
+ 18: "spec doesn't specify any nesting limitations",
62
+ }
63
+
64
+ class TestFail(TestCase):
65
+ def test_failures(self):
66
+ for idx, doc in enumerate(JSONDOCS):
67
+ idx = idx + 1
68
+ if idx in SKIPS:
69
+ json.loads(doc)
70
+ continue
71
+ try:
72
+ json.loads(doc)
73
+ except json.JSONDecodeError:
74
+ pass
75
+ else:
76
+ #self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
77
+ self.fail("Expected failure for fail%d.json: %r" % (idx, doc))
78
+
79
+ def test_array_decoder_issue46(self):
80
+ # http://code.google.com/p/simplejson/issues/detail?id=46
81
+ for doc in [u'[,]', '[,]']:
82
+ try:
83
+ json.loads(doc)
84
+ except json.JSONDecodeError, e:
85
+ self.assertEquals(e.pos, 1)
86
+ self.assertEquals(e.lineno, 1)
87
+ self.assertEquals(e.colno, 1)
88
+ except Exception, e:
89
+ self.fail("Unexpected exception raised %r %s" % (e, e))
90
+ else:
91
+ self.fail("Unexpected success parsing '[,]'")
@@ -0,0 +1,19 @@
1
+ import math
2
+ from unittest import TestCase
3
+
4
+ import simplejson as json
5
+
6
+ class TestFloat(TestCase):
7
+ def test_floats(self):
8
+ for num in [1617161771.7650001, math.pi, math.pi**100,
9
+ math.pi**-100, 3.1]:
10
+ self.assertEquals(float(json.dumps(num)), num)
11
+ self.assertEquals(json.loads(json.dumps(num)), num)
12
+ self.assertEquals(json.loads(unicode(json.dumps(num))), num)
13
+
14
+ def test_ints(self):
15
+ for num in [1, 1L, 1<<32, 1<<64]:
16
+ self.assertEquals(json.dumps(num), str(num))
17
+ self.assertEquals(int(json.dumps(num)), num)
18
+ self.assertEquals(json.loads(json.dumps(num)), num)
19
+ self.assertEquals(json.loads(unicode(json.dumps(num))), num)
@@ -0,0 +1,86 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson as json
4
+ import textwrap
5
+ from StringIO import StringIO
6
+
7
+ class TestIndent(TestCase):
8
+ def test_indent(self):
9
+ h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh',
10
+ 'i-vhbjkhnth',
11
+ {'nifty': 87}, {'field': 'yes', 'morefield': False} ]
12
+
13
+ expect = textwrap.dedent("""\
14
+ [
15
+ \t[
16
+ \t\t"blorpie"
17
+ \t],
18
+ \t[
19
+ \t\t"whoops"
20
+ \t],
21
+ \t[],
22
+ \t"d-shtaeou",
23
+ \t"d-nthiouh",
24
+ \t"i-vhbjkhnth",
25
+ \t{
26
+ \t\t"nifty": 87
27
+ \t},
28
+ \t{
29
+ \t\t"field": "yes",
30
+ \t\t"morefield": false
31
+ \t}
32
+ ]""")
33
+
34
+
35
+ d1 = json.dumps(h)
36
+ d2 = json.dumps(h, indent='\t', sort_keys=True, separators=(',', ': '))
37
+ d3 = json.dumps(h, indent=' ', sort_keys=True, separators=(',', ': '))
38
+ d4 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
39
+
40
+ h1 = json.loads(d1)
41
+ h2 = json.loads(d2)
42
+ h3 = json.loads(d3)
43
+ h4 = json.loads(d4)
44
+
45
+ self.assertEquals(h1, h)
46
+ self.assertEquals(h2, h)
47
+ self.assertEquals(h3, h)
48
+ self.assertEquals(h4, h)
49
+ self.assertEquals(d3, expect.replace('\t', ' '))
50
+ self.assertEquals(d4, expect.replace('\t', ' '))
51
+ # NOTE: Python 2.4 textwrap.dedent converts tabs to spaces,
52
+ # so the following is expected to fail. Python 2.4 is not a
53
+ # supported platform in simplejson 2.1.0+.
54
+ self.assertEquals(d2, expect)
55
+
56
+ def test_indent0(self):
57
+ h = {3: 1}
58
+ def check(indent, expected):
59
+ d1 = json.dumps(h, indent=indent)
60
+ self.assertEquals(d1, expected)
61
+
62
+ sio = StringIO()
63
+ json.dump(h, sio, indent=indent)
64
+ self.assertEquals(sio.getvalue(), expected)
65
+
66
+ # indent=0 should emit newlines
67
+ check(0, '{\n"3": 1\n}')
68
+ # indent=None is more compact
69
+ check(None, '{"3": 1}')
70
+
71
+ def test_separators(self):
72
+ lst = [1,2,3,4]
73
+ expect = '[\n1,\n2,\n3,\n4\n]'
74
+ expect_spaces = '[\n1, \n2, \n3, \n4\n]'
75
+ # Ensure that separators still works
76
+ self.assertEquals(
77
+ expect_spaces,
78
+ json.dumps(lst, indent=0, separators=(', ', ': ')))
79
+ # Force the new defaults
80
+ self.assertEquals(
81
+ expect,
82
+ json.dumps(lst, indent=0, separators=(',', ': ')))
83
+ # Added in 2.1.4
84
+ self.assertEquals(
85
+ expect,
86
+ json.dumps(lst, indent=0))
@@ -0,0 +1,20 @@
1
+ from unittest import TestCase
2
+
3
+ import simplejson as json
4
+ from operator import itemgetter
5
+
6
+ class TestItemSortKey(TestCase):
7
+ def test_simple_first(self):
8
+ a = {'a': 1, 'c': 5, 'jack': 'jill', 'pick': 'axe', 'array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
9
+ self.assertEquals(
10
+ '{"a": 1, "c": 5, "crate": "dog", "jack": "jill", "pick": "axe", "zeak": "oh", "array": [1, 5, 6, 9], "tuple": [83, 12, 3]}',
11
+ json.dumps(a, item_sort_key=json.simple_first))
12
+
13
+ def test_case(self):
14
+ a = {'a': 1, 'c': 5, 'Jack': 'jill', 'pick': 'axe', 'Array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
15
+ self.assertEquals(
16
+ '{"Array": [1, 5, 6, 9], "Jack": "jill", "a": 1, "c": 5, "crate": "dog", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
17
+ json.dumps(a, item_sort_key=itemgetter(0)))
18
+ self.assertEquals(
19
+ '{"a": 1, "Array": [1, 5, 6, 9], "c": 5, "crate": "dog", "Jack": "jill", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
20
+ json.dumps(a, item_sort_key=lambda kv: kv[0].lower()))
@@ -0,0 +1,121 @@
1
+ import unittest
2
+ import simplejson as json
3
+ from StringIO import StringIO
4
+
5
+ try:
6
+ from collections import namedtuple
7
+ except ImportError:
8
+ class Value(tuple):
9
+ def __new__(cls, *args):
10
+ return tuple.__new__(cls, args)
11
+
12
+ def _asdict(self):
13
+ return {'value': self[0]}
14
+ class Point(tuple):
15
+ def __new__(cls, *args):
16
+ return tuple.__new__(cls, args)
17
+
18
+ def _asdict(self):
19
+ return {'x': self[0], 'y': self[1]}
20
+ else:
21
+ Value = namedtuple('Value', ['value'])
22
+ Point = namedtuple('Point', ['x', 'y'])
23
+
24
+ class DuckValue(object):
25
+ def __init__(self, *args):
26
+ self.value = Value(*args)
27
+
28
+ def _asdict(self):
29
+ return self.value._asdict()
30
+
31
+ class DuckPoint(object):
32
+ def __init__(self, *args):
33
+ self.point = Point(*args)
34
+
35
+ def _asdict(self):
36
+ return self.point._asdict()
37
+
38
+ class DeadDuck(object):
39
+ _asdict = None
40
+
41
+ class DeadDict(dict):
42
+ _asdict = None
43
+
44
+ CONSTRUCTORS = [
45
+ lambda v: v,
46
+ lambda v: [v],
47
+ lambda v: [{'key': v}],
48
+ ]
49
+
50
+ class TestNamedTuple(unittest.TestCase):
51
+ def test_namedtuple_dumps(self):
52
+ for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
53
+ d = v._asdict()
54
+ self.assertEqual(d, json.loads(json.dumps(v)))
55
+ self.assertEqual(
56
+ d,
57
+ json.loads(json.dumps(v, namedtuple_as_object=True)))
58
+ self.assertEqual(d, json.loads(json.dumps(v, tuple_as_array=False)))
59
+ self.assertEqual(
60
+ d,
61
+ json.loads(json.dumps(v, namedtuple_as_object=True,
62
+ tuple_as_array=False)))
63
+
64
+ def test_namedtuple_dumps_false(self):
65
+ for v in [Value(1), Point(1, 2)]:
66
+ l = list(v)
67
+ self.assertEqual(
68
+ l,
69
+ json.loads(json.dumps(v, namedtuple_as_object=False)))
70
+ self.assertRaises(TypeError, json.dumps, v,
71
+ tuple_as_array=False, namedtuple_as_object=False)
72
+
73
+ def test_namedtuple_dump(self):
74
+ for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
75
+ d = v._asdict()
76
+ sio = StringIO()
77
+ json.dump(v, sio)
78
+ self.assertEqual(d, json.loads(sio.getvalue()))
79
+ sio = StringIO()
80
+ json.dump(v, sio, namedtuple_as_object=True)
81
+ self.assertEqual(
82
+ d,
83
+ json.loads(sio.getvalue()))
84
+ sio = StringIO()
85
+ json.dump(v, sio, tuple_as_array=False)
86
+ self.assertEqual(d, json.loads(sio.getvalue()))
87
+ sio = StringIO()
88
+ json.dump(v, sio, namedtuple_as_object=True,
89
+ tuple_as_array=False)
90
+ self.assertEqual(
91
+ d,
92
+ json.loads(sio.getvalue()))
93
+
94
+ def test_namedtuple_dump_false(self):
95
+ for v in [Value(1), Point(1, 2)]:
96
+ l = list(v)
97
+ sio = StringIO()
98
+ json.dump(v, sio, namedtuple_as_object=False)
99
+ self.assertEqual(
100
+ l,
101
+ json.loads(sio.getvalue()))
102
+ self.assertRaises(TypeError, json.dump, v, StringIO(),
103
+ tuple_as_array=False, namedtuple_as_object=False)
104
+
105
+ def test_asdict_not_callable_dump(self):
106
+ for f in CONSTRUCTORS:
107
+ self.assertRaises(TypeError,
108
+ json.dump, f(DeadDuck()), StringIO(), namedtuple_as_object=True)
109
+ sio = StringIO()
110
+ json.dump(f(DeadDict()), sio, namedtuple_as_object=True)
111
+ self.assertEqual(
112
+ json.dumps(f({})),
113
+ sio.getvalue())
114
+
115
+ def test_asdict_not_callable_dumps(self):
116
+ for f in CONSTRUCTORS:
117
+ self.assertRaises(TypeError,
118
+ json.dumps, f(DeadDuck()), namedtuple_as_object=True)
119
+ self.assertEqual(
120
+ json.dumps(f({})),
121
+ json.dumps(f(DeadDict()), namedtuple_as_object=True))