Skip to content

Commit

Permalink
Merge pull request #216 from cdent/read-full-json
Browse files Browse the repository at this point in the history
Read full json
  • Loading branch information
cdent committed Jul 7, 2017
2 parents 87f3896 + 92377f8 commit b7e767e
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 5 deletions.
15 changes: 15 additions & 0 deletions docs/source/jsonpath.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,23 @@ lead to difficult to read tests and it also indicates that your
gabbi tests are being used to test your serializers and data models,
not just your API interactions.

It is also possible to read raw JSON from disk for either all or
some of a JSON response::

response_json_paths:
$: @<data.json

or::

response_json_paths:
$.pets: <@pets.json
$.pets[0]: <@cat.json

Examples like this can be found in one of gabbi's `own tests`_.

There are more JSONPath examples in :doc:`example` and in the
`jsonpath_rw`_ and `jsonpath_rw_ext`_ documentation.

.. _jsonpath_rw: http://jsonpath-rw.readthedocs.io/en/latest/
.. _jsonpath_rw_ext: https://python-jsonpath-rw-ext.readthedocs.io/en/latest/
.. _own tests: https://github.com/cdent/gabbi/blob/master/gabbi/tests/gabbits_intercept/data.yaml
6 changes: 5 additions & 1 deletion gabbi/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ def replace_template(self, message):

return message

def load_data_file(self, filename):
"""Read a file from the current test directory."""
return self._load_data_file(filename)

def _assert_response(self):
"""Compare the response with expected data."""
self._test_status(self.test_data['status'], self.response['status'])
Expand Down Expand Up @@ -505,7 +509,7 @@ def _test_data_to_string(self, data, content_type):
"""
if isinstance(data, str):
if data.startswith('<@'):
info = self._load_data_file(data.replace('<@', '', 1))
info = self.load_data_file(data.replace('<@', '', 1))
if utils.not_binary(content_type):
data = six.text_type(info, 'UTF-8')
else:
Expand Down
9 changes: 9 additions & 0 deletions gabbi/handlers/jsonhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import json

import six

from gabbi.handlers import base
from gabbi import json_parser

Expand Down Expand Up @@ -86,6 +88,13 @@ def action(self, test, path, value=None):
except ValueError:
raise AssertionError('json path %s cannot match %s' %
(path, test.response_data))

# read data from disk if the value starts with '<@'
if isinstance(value, str) and value.startswith('<@'):
info = test.load_data_file(value.replace('<@', '', 1))
info = six.text_type(info, 'UTF-8')
value = self.loads(info)

expected = test.replace_template(value)
# If expected is a string, check to see if it is a regex.
if (hasattr(expected, 'startswith') and expected.startswith('/')
Expand Down
4 changes: 4 additions & 0 deletions gabbi/tests/gabbits_intercept/cat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "cat",
"sound": "meow"
}
23 changes: 23 additions & 0 deletions gabbi/tests/gabbits_intercept/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,26 @@ tests:
request_headers:
content-type: text/plain
data: <@utf8.txt

- name: json value from disk
POST: /
request_headers:
content-type: application/json
data: <@data.json
response_json_paths:
foo['bár']: 1
$: <@data.json

- name: partial json from disk
POST: /
request_headers:
content-type: application/json
data:
pets:
- type: cat
sound: meow
- type: dog
sound: woof
response_json_paths:
$.pets: <@pets.json
$.pets[0]: <@cat.json
10 changes: 10 additions & 0 deletions gabbi/tests/gabbits_intercept/pets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"type": "cat",
"sound": "meow"
},
{
"type": "dog",
"sound": "woof"
}
]
8 changes: 4 additions & 4 deletions gabbi/tests/test_load_data_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def setUp(self):

def _assert_content_read(self, filepath):
self.assertEqual(
'dummy content', self.http_case._load_data_file(filepath))
'dummy content', self.http_case.load_data_file(filepath))

def test_load_file(self, m_open):
self.http_case.test_directory = '.'
Expand All @@ -52,15 +52,15 @@ def test_load_file_in_root(self, m_open):
filepath = '/top-level.private'

with self.assertRaises(ValueError):
self.http_case._load_data_file(filepath)
self.http_case.load_data_file(filepath)
self.assertFalse(m_open.called)

def test_load_file_in_parent_dir(self, m_open):
self.http_case.test_directory = '.'
filepath = '../file-in-parent-dir.txt'

with self.assertRaises(ValueError):
self.http_case._load_data_file(filepath)
self.http_case.load_data_file(filepath)
self.assertFalse(m_open.called)

def test_load_file_within_test_directory(self, m_open):
Expand All @@ -73,5 +73,5 @@ def test_load_file_not_within_test_directory(self, m_open):
self.http_case.test_directory = '/a/b/c'
filepath = '../../b/E/file-in-test-dir.txt'
with self.assertRaises(ValueError):
self.http_case._load_data_file(filepath)
self.http_case.load_data_file(filepath)
self.assertFalse(m_open.called)

0 comments on commit b7e767e

Please sign in to comment.