123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- # -*- coding: utf-8 -*-
- """
- Tests for salt.utils.json
- """
- # Import Python libs
- from __future__ import absolute_import, print_function, unicode_literals
- import textwrap
- # Import Salt libs
- import salt.utils.files
- import salt.utils.json
- import salt.utils.platform
- import salt.utils.stringutils
- from salt.ext import six
- # Import Salt Testing libs
- from tests.support.helpers import with_tempfile
- from tests.support.mock import MagicMock, patch
- from tests.support.unit import LOREM_IPSUM, TestCase, skipIf
- class JSONTestCase(TestCase):
- data = {
- "спам": "яйца",
- "list": [1, 2, "three"],
- "dict": {"subdict": {"спам": "яйца"}},
- "True": False,
- "float": 1.5,
- "None": None,
- }
- serialized = salt.utils.stringutils.to_str(
- '{"None": null, "True": false, "dict": {"subdict": {"спам": "яйца"}}, "float": 1.5, "list": [1, 2, "three"], "спам": "яйца"}'
- )
- serialized_indent4 = salt.utils.stringutils.to_str(
- textwrap.dedent(
- """\
- {
- "None": null,
- "True": false,
- "dict": {
- "subdict": {
- "спам": "яйца"
- }
- },
- "float": 1.5,
- "list": [
- 1,
- 2,
- "three"
- ],
- "спам": "яйца"
- }"""
- )
- )
- def test_find_json(self):
- test_sample_json = """
- {
- "glossary": {
- "title": "example glossary",
- "GlossDiv": {
- "title": "S",
- "GlossList": {
- "GlossEntry": {
- "ID": "SGML",
- "SortAs": "SGML",
- "GlossTerm": "Standard Generalized Markup Language",
- "Acronym": "SGML",
- "Abbrev": "ISO 8879:1986",
- "GlossDef": {
- "para": "A meta-markup language, used to create markup languages such as DocBook.",
- "GlossSeeAlso": ["GML", "XML"]
- },
- "GlossSee": "markup"
- }
- }
- }
- }
- }
- """
- expected_ret = {
- "glossary": {
- "GlossDiv": {
- "GlossList": {
- "GlossEntry": {
- "GlossDef": {
- "GlossSeeAlso": ["GML", "XML"],
- "para": "A meta-markup language, used to create markup languages such as DocBook.",
- },
- "GlossSee": "markup",
- "Acronym": "SGML",
- "GlossTerm": "Standard Generalized Markup Language",
- "SortAs": "SGML",
- "Abbrev": "ISO 8879:1986",
- "ID": "SGML",
- }
- },
- "title": "S",
- },
- "title": "example glossary",
- }
- }
- # First test the valid JSON
- ret = salt.utils.json.find_json(test_sample_json)
- self.assertDictEqual(ret, expected_ret)
- # Now pre-pend some garbage and re-test
- garbage_prepend_json = "{0}{1}".format(LOREM_IPSUM, test_sample_json)
- ret = salt.utils.json.find_json(garbage_prepend_json)
- self.assertDictEqual(ret, expected_ret)
- # Test to see if a ValueError is raised if no JSON is passed in
- self.assertRaises(ValueError, salt.utils.json.find_json, LOREM_IPSUM)
- @skipIf(
- salt.utils.platform.is_windows(),
- "skip until we figure out what to do about decoding unicode on windows",
- )
- @skipIf(not six.PY2, "Test only needed on Python 2")
- def test_find_json_unicode_splitlines(self):
- """
- Tests a case in salt-ssh where a unicode string is split into a list of
- str types by .splitlines().
- """
- raw = '{"foo": "öäü"}'
- mock_split = MagicMock(return_value=[raw.encode("utf8")])
- with patch.object(salt.utils.json, "__split", mock_split):
- ret = salt.utils.json.find_json(raw)
- self.assertEqual(ret, {"foo": "öäü"})
- def test_dumps_loads(self):
- """
- Test dumping to and loading from a string
- """
- # Dump with no indentation
- ret = salt.utils.json.dumps(self.data, sort_keys=True)
- # Make sure the result is as expected
- self.assertEqual(ret, self.serialized)
- # Loading it should be equal to the original data
- self.assertEqual(salt.utils.json.loads(ret), self.data)
- # Dump with 4 spaces of indentation
- ret = salt.utils.json.dumps(self.data, sort_keys=True, indent=4)
- # Make sure the result is as expected. Note that in Python 2, dumping
- # results in trailing whitespace on lines ending in a comma. So, for a
- # proper comparison, we will have to run rstrip on each line of the
- # return and then stitch it back together.
- ret = str("\n").join(
- [x.rstrip() for x in ret.splitlines()]
- ) # future lint: disable=blacklisted-function
- self.assertEqual(ret, self.serialized_indent4)
- # Loading it should be equal to the original data
- self.assertEqual(salt.utils.json.loads(ret), self.data)
- @with_tempfile()
- def test_dump_load(self, json_out):
- """
- Test dumping to and loading from a file handle
- """
- with salt.utils.files.fopen(json_out, "wb") as fp_:
- fp_.write(salt.utils.stringutils.to_bytes(salt.utils.json.dumps(self.data)))
- with salt.utils.files.fopen(json_out, "rb") as fp_:
- ret = salt.utils.json.loads(salt.utils.stringutils.to_unicode(fp_.read()))
- # Loading should be equal to the original data
- self.assertEqual(ret, self.data)
|