test_jsonutil.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # coding: utf-8
  2. """Test suite for our JSON utilities."""
  3. # Copyright (c) IPython Development Team.
  4. # Distributed under the terms of the Modified BSD License.
  5. from binascii import a2b_base64
  6. import json
  7. from datetime import datetime
  8. import numbers
  9. import nose.tools as nt
  10. from .. import jsonutil
  11. from ..jsonutil import json_clean, encode_images
  12. from ipython_genutils.py3compat import unicode_to_str
  13. class MyInt(object):
  14. def __int__(self):
  15. return 389
  16. numbers.Integral.register(MyInt)
  17. class MyFloat(object):
  18. def __float__(self):
  19. return 3.14
  20. numbers.Real.register(MyFloat)
  21. def test():
  22. # list of input/expected output. Use None for the expected output if it
  23. # can be the same as the input.
  24. pairs = [(1, None), # start with scalars
  25. (1.0, None),
  26. ('a', None),
  27. (True, None),
  28. (False, None),
  29. (None, None),
  30. # Containers
  31. ([1, 2], None),
  32. ((1, 2), [1, 2]),
  33. (set([1, 2]), [1, 2]),
  34. (dict(x=1), None),
  35. ({'x': 1, 'y':[1,2,3], '1':'int'}, None),
  36. # More exotic objects
  37. ((x for x in range(3)), [0, 1, 2]),
  38. (iter([1, 2]), [1, 2]),
  39. (datetime(1991, 7, 3, 12, 00), "1991-07-03T12:00:00.000000"),
  40. (MyFloat(), 3.14),
  41. (MyInt(), 389)
  42. ]
  43. for val, jval in pairs:
  44. if jval is None:
  45. jval = val
  46. out = json_clean(val)
  47. # validate our cleanup
  48. assert out == jval
  49. # and ensure that what we return, indeed encodes cleanly
  50. json.loads(json.dumps(out))
  51. def test_encode_images():
  52. # invalid data, but the header and footer are from real files
  53. pngdata = b'\x89PNG\r\n\x1a\nblahblahnotactuallyvalidIEND\xaeB`\x82'
  54. jpegdata = b'\xff\xd8\xff\xe0\x00\x10JFIFblahblahjpeg(\xa0\x0f\xff\xd9'
  55. pdfdata = b'%PDF-1.\ntrailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>'
  56. bindata = b'\xff\xff\xff\xff'
  57. fmt = {
  58. 'image/png' : pngdata,
  59. 'image/jpeg' : jpegdata,
  60. 'application/pdf' : pdfdata,
  61. 'application/unrecognized': bindata,
  62. }
  63. encoded = json_clean(encode_images(fmt))
  64. for key, value in fmt.items():
  65. # encoded has unicode, want bytes
  66. decoded = a2b_base64(encoded[key])
  67. assert decoded == value
  68. encoded2 = json_clean(encode_images(encoded))
  69. assert encoded == encoded2
  70. # test that we don't double-encode base64 str
  71. b64_str = {}
  72. for key, encoded in encoded.items():
  73. b64_str[key] = unicode_to_str(encoded)
  74. encoded3 = json_clean(encode_images(b64_str))
  75. assert encoded3 == b64_str
  76. for key, value in fmt.items():
  77. decoded = a2b_base64(encoded3[key])
  78. assert decoded == value
  79. def test_lambda():
  80. with nt.assert_raises(ValueError):
  81. json_clean(lambda : 1)
  82. def test_exception():
  83. bad_dicts = [{1:'number', '1':'string'},
  84. {True:'bool', 'True':'string'},
  85. ]
  86. for d in bad_dicts:
  87. nt.assert_raises(ValueError, json_clean, d)
  88. def test_unicode_dict():
  89. data = {u'üniço∂e': u'üniço∂e'}
  90. clean = jsonutil.json_clean(data)
  91. assert data == clean