Skip to content

Commit

Permalink
Merge pull request #117 from timofurrer/feature/extend-sure
Browse files Browse the repository at this point in the history
Provide possibility to extend sure. Refs #31
  • Loading branch information
timofurrer committed Jun 29, 2016
2 parents 8e5472b + 7dcba5a commit cfec013
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
19 changes: 19 additions & 0 deletions sure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,25 @@ def match(self, regex, *args):
expect = AssertionBuilder('expect')


def assertion(func):
"""Extend sure with a custom assertion method."""
func = assertionmethod(func)
setattr(AssertionBuilder, func.__name__, func)
return func


def chain(func):
"""Extend sure with a custom chaining method."""
setattr(AssertionBuilder, func.__name__, func)
return func

def chainproperty(func):
"""Extend sure with a custom chain property."""
func = assertionproperty(func)
setattr(AssertionBuilder, func.fget.__name__, func)
return func


allows_new_syntax = not os.getenv('SURE_DISABLE_NEW_SYNTAX')


Expand Down
88 changes: 88 additions & 0 deletions tests/test_custom_assertions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-

"""
Test custom assertions.
"""

from sure import expect, assertion, chain, chainproperty
from sure.magic import is_cpython


def test_custom_assertion():
"test extending sure with a custom assertion."

class Response(object):
def __init__(self, return_code):
self.return_code = return_code


@assertion
def return_code(self, return_code):
if self.negative:
assert return_code != self.obj.return_code, "Expected was a return code different from {0}.".format(return_code)
else:
assert return_code == self.obj.return_code, "Expected return code is: {0}\nGiven return code was: {1}".format(
return_code, self.obj.return_code)

return True


expect(Response(200)).should.have.return_code(200)
expect(Response(200)).shouldnt.have.return_code(201)


def test_custom_chain_method():
"test extending sure with a custom chain method."

class Response(object):
def __init__(self, headers, return_code):
self.headers = headers
self.return_code = return_code


@chain
def header(self, header_name):
expect(self.obj.headers).should.have.key(header_name)
return self.obj.headers[header_name]


# FIXME(TF): 'must' does not sound right in this method chain.
# it should rather be ...header("foo").which.equals("bar")
# however, which is an assertionproperty in AssertionBuilder
# and is not a monkey patched property.
if is_cpython:
Response({"foo": "bar", "bar": "foo"}, 200).should.have.header("foo").must.be.equal("bar")
else:
expect(expect(Response({"foo": "bar", "bar": "foo"}, 200)).should.have.header("foo")).must.be.equal("bar")


def test_custom_chain_property():
"test extending sure with a custom chain property."

class Response(object):
magic = 41

@chainproperty
def having(self):
return self

@chainproperty
def implement(self):
return self


@assertion
def attribute(self, name):
has_it = hasattr(self.obj, name)
if self.negative:
assert not has_it, "Expected was that object {0} does not have attribute {1}".format(
self.obj, name)
else:
assert has_it, "Expected was that object {0} has attribute {1}".format(
self.obj, name)

return True


expect(Response).having.attribute("magic")
expect(Response).doesnt.implement.attribute("nomagic")

0 comments on commit cfec013

Please sign in to comment.