1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Base classes for response and content handlers."""
from gabbi.exception import GabbiFormatError
class ResponseHandler:
"""Add functionality for making assertions about an HTTP response.
A subclass may implement two methods: ``action`` and ``preprocess``.
``preprocess`` takes one argument, the ``TestCase``. It is called exactly
once for each test before looping across the assertions. It is used,
rarely, to copy the ``test.output`` into a useful form (such as a parsed
DOM).
``action`` takes two or three arguments. If ``test_key_value`` is a list
``action`` is called with the test case and a single list item. If
``test_key_value`` is a dict then ``action`` is called with the test case
and a key and value pair.
"""
test_key_suffix = ''
test_key_value = []
def __init__(self):
self._register()
def __call__(self, test):
if test.test_data[self._key]:
self.preprocess(test)
if not isinstance(
test.test_data[self._key], type(self.test_key_value)):
raise GabbiFormatError(
"%s in '%s' has incorrect type, must be %s"
% (self._key, test.test_data['name'],
type(self.test_key_value)))
for item in test.test_data[self._key]:
try:
value = test.test_data[self._key][item]
except (TypeError, KeyError):
value = None
self.action(test, item, value=value)
def preprocess(self, test):
"""Do any pre-single-test preprocessing."""
pass
def action(self, test, item, value=None):
"""Test an individual entry for this response handler.
If the entry is a key value pair the key is in item and the
value in value. Otherwise the entry is considered a single item
from a list.
"""
pass
def is_regex(self, value):
"""Check if the value is formatted to looks like a regular expression.
Meaning it starts and ends with "/".
"""
return (
value.startswith('/') and value.endswith('/') and len(value) > 1
)
def _register(self):
"""Register this handler on the provided test class."""
self.response_handler = None
self.content_handler = None
if self.test_key_suffix:
self._key = 'response_%s' % self.test_key_suffix
self.test_base = {self._key: self.test_key_value}
self.response_handler = self
if hasattr(self, 'accepts'):
self.content_handler = self
def __eq__(self, other):
if isinstance(other, ResponseHandler):
return self.__class__ == other.__class__
return False
def __ne__(self, other):
return not self.__eq__(other)
class ContentHandler(ResponseHandler):
"""A subclass of ResponseHandlers that adds content handling."""
@staticmethod
def accepts(content_type):
"""Return True if this handler can handler this type."""
return False
@classmethod
def replacer(cls, response_data, path):
"""Return the string that is replacing RESPONSE."""
return path
@staticmethod
def dumps(data, pretty=False, test=None):
"""Return structured data as a string.
If pretty is true, prettify.
"""
return data
@staticmethod
def loads(data):
"""Create structured (Python) data from a stream.
If there is a failure decoding then the handler should
repackage the error as a gabbi.exception.GabbiDataLoadError.
"""
return data
@staticmethod
def load_data_file(test, file_path):
"""Return the string content of the file specified by the file_path."""
return test.load_data_file(file_path)
|