Matchers¶
Classes for defining request and response data that is variable.
Attributes¶
SomethingLike = Like
module-attribute
¶
Classes¶
EachLike(matcher, minimum=1)
¶
Bases: Matcher
Expect the data to be a list of similar objects.
Example:
from pact import Consumer, Provider pact = Consumer('consumer').has_pact_with(Provider('provider')) (pact.given('there are three comments') ... .upon_receiving('a request for the most recent 2 comments') ... .with_request('get', '/comment', query={'limit': 2}) ... .will_respond_with(200, body={ ... 'comments': EachLike( ... {'name': SomethingLike('bob'), ... 'text': SomethingLike('Hello!')}, ... minimum=2) ... })) Would expect the response to be a JSON object, with a comments list. In that list should be at least 2 items, and each item should be a
dict
with the keysname
andtext
,
:param matcher: The expected value that each item in a list should look like, this can be other matchers. :type matcher: None, list, dict, int, float, str, unicode, Matcher :param minimum: The minimum number of items expected. Must be greater than or equal to 1. :type minimum: int
Source code in src/pact/matchers.py
Attributes¶
matcher = matcher
instance-attribute
¶
minimum = minimum
instance-attribute
¶
Functions¶
generate()
¶
Generate the value the mock service will return.
:return: A dict containing the information about the contents of the list and the provided minimum number of items for that list. :rtype: dict
Source code in src/pact/matchers.py
Format()
¶
Class of regular expressions for common formats.
Example:
from pact import Consumer, Provider from pact.matchers import Format pact = Consumer('consumer').has_pact_with(Provider('provider')) (pact.given('the current user is logged in as
tester
') ... .upon_receiving('a request for the user profile') ... .with_request('get', '/profile') ... .will_respond_with(200, body={ ... 'id': Format().identifier, ... 'lastUpdated': Format().time ... }))
Would expect id
to be any valid int and lastUpdated
to be a valid time.
When the consumer runs this contract, the value of that will be returned
is the second value passed to Term in the given function, for the time
example it would be datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time()
Source code in src/pact/matchers.py
Attributes¶
identifier = self.integer_or_identifier()
instance-attribute
¶
integer = self.integer_or_identifier()
instance-attribute
¶
iso_datetime = self.iso_8601_datetime()
instance-attribute
¶
iso_datetime_ms = self.iso_8601_datetime(with_ms=True)
instance-attribute
¶
Classes¶
Regexes
¶
Bases: Enum
Regex Enum for common formats.
Attributes¶
date = '^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))?)'
class-attribute
instance-attribute
¶hexadecimal = '[0-9a-fA-F]+'
class-attribute
instance-attribute
¶ip_address = '(\\d{1,3}\\.)+\\d{1,3}'
class-attribute
instance-attribute
¶ipv6_address = '(\\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\\Z)|(\\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\\Z)|(\\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\\Z)|(\\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\\Z)|(\\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\\Z)|(\\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\\Z)|(\\A(([0-9a-f]{1,4}:){1,7}|:):\\Z)|(\\A:(:[0-9a-f]{1,4}){1,7}\\Z)|(\\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})\\Z)|(\\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})\\Z)|(\\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)|(\\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\Z)'
class-attribute
instance-attribute
¶iso_8601_datetime = '^\\d{4}-[01]\\d-[0-3]\\d\\x54[0-2]\\d:[0-6]\\d:[0-6]\\d(?:\\.\\d+)?(?:(?:[+-]\\d\\d:?\\d\\d)|\\x5A)?$'
class-attribute
instance-attribute
¶iso_8601_datetime_ms = '^\\d{4}-[01]\\d-[0-3]\\d\\x54[0-2]\\d:[0-6]\\d:[0-6]\\d\\.\\d+(?:(?:[+-]\\d\\d:?\\d\\d)|\\x5A)?$'
class-attribute
instance-attribute
¶time_regex = '^(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?$'
class-attribute
instance-attribute
¶timestamp = '^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$'
class-attribute
instance-attribute
¶uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
class-attribute
instance-attribute
¶Functions¶
date()
¶
Match any date.
:return: a Term object with a date regex. :rtype: Term
decimal()
¶
hexadecimal()
¶
Match any hexadecimal.
:return: a Term object with a hexadecimal regex. :rtype: Term
integer_or_identifier()
¶
ip_address()
¶
Match any ip address.
:return: a Term object with an ip address regex. :rtype: Term
ipv6_address()
¶
Match any ipv6 address.
:return: a Term object with an ipv6 address regex. :rtype: Term
iso_8601_datetime(with_ms=False)
¶
Match a string for a full ISO 8601 Date.
Does not do any sort of date validation, only checks if the string is according to the ISO 8601 spec.
This method differs from :func:~pact.Format.timestamp
,
:func:~pact.Format.date
and :func:~pact.Format.time
implementations
in that it is more stringent and tests the string for exact match to
the ISO 8601 dates format.
Without with_ms
will match string containing ISO 8601 formatted dates
as stated bellow:
- 2016-12-15T20:16:01
- 2010-05-01T01:14:31.876
- 2016-05-24T15:54:14.00000Z
- 1994-11-05T08:15:30-05:00
- 2002-01-31T23:00:00.1234-02:00
- 1991-02-20T06:35:26.079043+00:00
Otherwise, ONLY dates with milliseconds will match the pattern:
- 2010-05-01T01:14:31.876
- 2016-05-24T15:54:14.00000Z
- 2002-01-31T23:00:00.1234-02:00
- 1991-02-20T06:35:26.079043+00:00
:param with_ms: Enforcing millisecond precision. :type with_ms: bool :return: a Term object with a date regex. :rtype: Term
Source code in src/pact/matchers.py
time()
¶
Match any time.
:return: a Term object with a time regex. :rtype: Term
timestamp()
¶
Match any timestamp.
:return: a Term object with a timestamp regex. :rtype: Term
uuid()
¶
Match any uuid.
:return: a Term object with a uuid regex. :rtype: Term
Like(matcher)
¶
Bases: Matcher
Expect the type of the value to be the same as matcher.
Example:
from pact import Consumer, Provider pact = Consumer('consumer').has_pact_with(Provider('provider')) (pact ... .given('there is a random number generator') ... .upon_receiving('a request for a random number') ... .with_request('get', '/generate-number') ... .will_respond_with(200, body={ ... 'number': Like(1111222233334444) ... }))
Would expect the response body to be a JSON object, containing the key
number
, which would contain an integer. When the consumer runs this
contract, the value 1111222233334444
will be returned by the mock
service, instead of a randomly generated value.
:param matcher: The object that should be expected. The mock service will return this value. When verified against the provider, the type of this value will be asserted, while the value will be ignored. :type matcher: None, list, dict, int, float, str, unicode, Matcher
Source code in src/pact/matchers.py
Term(matcher, generate)
¶
Bases: Matcher
Expect the response to match a specified regular expression.
Example:
from pact import Consumer, Provider pact = Consumer('consumer').has_pact_with(Provider('provider')) (pact.given('the current user is logged in as
tester
') ... .upon_receiving('a request for the user profile') ... .with_request('get', '/profile') ... .will_respond_with(200, body={ ... 'name': 'tester', ... 'theme': Term('light|dark|legacy', 'dark') ... }))
Would expect the response body to be a JSON object, containing the key
name
, which will contain the value tester
, and theme
which must be
one of the values: light, dark, or legacy. When the consumer runs this
contract, the value dark
will be returned by the mock service.
:param matcher: A regular expression to find. :type matcher: basestring :param generate: A value to be returned by the mock service when generating the response to the consumer. :type generate: basestring
Source code in src/pact/matchers.py
Attributes¶
matcher = matcher
instance-attribute
¶
Functions¶
generate()
¶
Return the value that should be used in the request/response.
:return: A dict containing the information about what the contents of the response should be, and what should match for the requests. :rtype: dict
Source code in src/pact/matchers.py
Functions¶
from_term(term)
¶
Parse the provided term into the JSON for the mock service.
:param term: The term to be parsed. :type term: None, list, dict, int, float, str, bytes, unicode, Matcher :return: The JSON representation for this term. :rtype: dict, list, str
Source code in src/pact/matchers.py
get_generated_values(input)
¶
Resolve (nested) Matchers to their generated values for assertion.
:param input: The input to be resolved to its generated values. :type input: None, list, dict, int, float, bool, str, unicode, Matcher :return: The input resolved to its generated value(s) :rtype: None, list, dict, int, float, bool, str, unicode, Matcher