test_namedtuple.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. from __future__ import absolute_import
  2. import unittest
  3. import simplejson as json
  4. from simplejson.compat import StringIO
  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. def _asdict(self):
  12. return {'value': self[0]}
  13. class Point(tuple):
  14. def __new__(cls, *args):
  15. return tuple.__new__(cls, args)
  16. def _asdict(self):
  17. return {'x': self[0], 'y': self[1]}
  18. else:
  19. Value = namedtuple('Value', ['value'])
  20. Point = namedtuple('Point', ['x', 'y'])
  21. class DuckValue(object):
  22. def __init__(self, *args):
  23. self.value = Value(*args)
  24. def _asdict(self):
  25. return self.value._asdict()
  26. class DuckPoint(object):
  27. def __init__(self, *args):
  28. self.point = Point(*args)
  29. def _asdict(self):
  30. return self.point._asdict()
  31. class DeadDuck(object):
  32. _asdict = None
  33. class DeadDict(dict):
  34. _asdict = None
  35. CONSTRUCTORS = [
  36. lambda v: v,
  37. lambda v: [v],
  38. lambda v: [{'key': v}],
  39. ]
  40. class TestNamedTuple(unittest.TestCase):
  41. def test_namedtuple_dumps(self):
  42. for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
  43. d = v._asdict()
  44. self.assertEqual(d, json.loads(json.dumps(v)))
  45. self.assertEqual(
  46. d,
  47. json.loads(json.dumps(v, namedtuple_as_object=True)))
  48. self.assertEqual(d, json.loads(json.dumps(v, tuple_as_array=False)))
  49. self.assertEqual(
  50. d,
  51. json.loads(json.dumps(v, namedtuple_as_object=True,
  52. tuple_as_array=False)))
  53. def test_namedtuple_dumps_false(self):
  54. for v in [Value(1), Point(1, 2)]:
  55. l = list(v)
  56. self.assertEqual(
  57. l,
  58. json.loads(json.dumps(v, namedtuple_as_object=False)))
  59. self.assertRaises(TypeError, json.dumps, v,
  60. tuple_as_array=False, namedtuple_as_object=False)
  61. def test_namedtuple_dump(self):
  62. for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]:
  63. d = v._asdict()
  64. sio = StringIO()
  65. json.dump(v, sio)
  66. self.assertEqual(d, json.loads(sio.getvalue()))
  67. sio = StringIO()
  68. json.dump(v, sio, namedtuple_as_object=True)
  69. self.assertEqual(
  70. d,
  71. json.loads(sio.getvalue()))
  72. sio = StringIO()
  73. json.dump(v, sio, tuple_as_array=False)
  74. self.assertEqual(d, json.loads(sio.getvalue()))
  75. sio = StringIO()
  76. json.dump(v, sio, namedtuple_as_object=True,
  77. tuple_as_array=False)
  78. self.assertEqual(
  79. d,
  80. json.loads(sio.getvalue()))
  81. def test_namedtuple_dump_false(self):
  82. for v in [Value(1), Point(1, 2)]:
  83. l = list(v)
  84. sio = StringIO()
  85. json.dump(v, sio, namedtuple_as_object=False)
  86. self.assertEqual(
  87. l,
  88. json.loads(sio.getvalue()))
  89. self.assertRaises(TypeError, json.dump, v, StringIO(),
  90. tuple_as_array=False, namedtuple_as_object=False)
  91. def test_asdict_not_callable_dump(self):
  92. for f in CONSTRUCTORS:
  93. self.assertRaises(TypeError,
  94. json.dump, f(DeadDuck()), StringIO(), namedtuple_as_object=True)
  95. sio = StringIO()
  96. json.dump(f(DeadDict()), sio, namedtuple_as_object=True)
  97. self.assertEqual(
  98. json.dumps(f({})),
  99. sio.getvalue())
  100. def test_asdict_not_callable_dumps(self):
  101. for f in CONSTRUCTORS:
  102. self.assertRaises(TypeError,
  103. json.dumps, f(DeadDuck()), namedtuple_as_object=True)
  104. self.assertEqual(
  105. json.dumps(f({})),
  106. json.dumps(f(DeadDict()), namedtuple_as_object=True))