Created
April 13, 2015 18:23
-
-
Save offbyone/79f8597d763054bf4492 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Goals: | |
1. Easy matcher definitions from methods, without the class plumbing. | |
>>> from hamcrest.decorators import matcher | |
>>> @matcher() | |
... def checks_out(item): | |
... return item.checks_out() | |
... | |
>>> assert_that(value, checks_out()) | |
2. Easy adapting of existing methods to matchers | |
>>> import my_lib | |
>>> from hamcrest.decorators import matcher | |
>>> checks_out = matcher()(my_lib.checks_out) | |
>>> assert_that(value, checks_out()) | |
3. transparent adaptive wrapping of boolean/assertion methods in | |
assertions | |
>>> import my_lib | |
>>> assert_that(value, my_lib.checks_out()) | |
4. Flexible customization of matchers: | |
>>> import my_lib # has a checks_out_this(thing, item) -- item will be used as the hamcrest arg, thing must be provided. | |
>>> from hamcrest.decorators import matcher | |
>>> checks_out_this = matcher()(my_lib.checks_out_this) | |
>>> assert_that(value, checks_out_this(thing)) | |
5. Descriptions should be simple -- first line of the docstring becomes describe_to | |
6. describe_mismatch can be added via a new decorator or via assert in the method. | |
7. Matcher methods with multiple arguments should be curried by the decorator | |
>>> @matcher(versus=3) | |
... def this_vs_that(versus, item): | |
... pass | |
8. Matcher methods can allow selecting a different value argument if needed | |
>>> @matcher(_value_arg="value", versus=3) | |
... def this_vs_that(versus, value): | |
... pass | |
... should one detect this on decoration? | |
""" | |
"""An example of a method-based matcher that does not provide its own | |
describe_mismatch support. | |
A method decorated with @matcher can be used in any role that a | |
matcher would fit. | |
""" | |
from hamcrest.decorators import matcher | |
@matcher() | |
def greater_than_three(value): | |
return value > 3 | |
assert_that(4, greater_than_three()) | |
"""if the matcher doesn't take customizations, it's okay to skip the | |
call.""" | |
assert_that(4, greater_than_three) # ---> false | |
"""TypeErrors and ValueErrors in the matchers are considered False""" | |
assert_that('alpha', greater_than_three()) # ---> false | |
"""Alternately you can provide an assertion matcher""" | |
from hamcrest.decorators import assert_matcher | |
@assert_matcher() | |
def greater_than_three(value): | |
assert value > 3 | |
"""An example of a method-based matcher that takes initialization | |
parameters, and matches one value. | |
By default, all parameters other than the one named 'value' will need | |
to be provided to the matcher instance | |
""" | |
@matcher() | |
def greater_than(base, value): | |
return value > base | |
assert_that(4, greater_than(2)) # true | |
"""method based matchers can also be adapted to different methods -- so | |
you can create them from non-hamcrest methods.""" | |
@matcher(_value_arg='left_side') | |
def right_of(right_side, left_side): | |
return left_side.startswith(right_side) | |
assert_that('kneejerk', right_of('knee')) # don't ask me what these mean. | |
"""describing a matcher uses the docstring of the matcher method, | |
where the args of the method will be substituted into the string. | |
""" | |
@matcher() | |
def greater_than(base, value): | |
"""a value greater than {base}""" | |
greater_than(3).describe_to(description) --> "a value greater than 3" | |
"""Describing a mismatch is a bit trickier. Two methods are supported; | |
one is by decorating a second mismatch describer. This works using | |
either a 1-arg or 2-arg method; the 1-arg takes just the item, and | |
returns a string -- this is the least Hamcrest-ian method, and should | |
be accessible to anything. | |
The 2-arg method takes (item, description) and the description is a | |
Hamcrest description builder. | |
""" | |
@matcher() | |
def greater_than(base, value): | |
return value > base | |
@greater_than.describe_mismatch | |
def gt_mismatch(item): | |
return "was {}".format(item) | |
@greater_than.describe_mismatch | |
def gt_mismatch_desc(item, description): | |
description.append_text('was ').append_description_of(item) | |
"""Alternately, you can implement your matcher using the assert/None model""" | |
@assert_matcher() | |
def greater_than(base, value): | |
"""a value greater than {base}""" | |
assert value > base, "was {}".format(value) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment