Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide possibility to extend sure. Refs #31 #117

Merged
merged 3 commits into from
Jun 29, 2016

Conversation

timofurrer
Copy link
Collaborator

@timofurrer timofurrer commented Jun 16, 2016

Note: work in progress

This PR contains the following features:

  • Add decorator to extend sure with a custom assertion method
  • Add decorator to extend sure with a chain method
  • Add decorator to extend sure with a chain property

Other Todos:

  • Enforce beauty of assertion error message. How? Provide specific Exception: class Assertion(AssertionError): pass which takes expected and given arguments? Is it just best practice?
  • Enforce negative check. How? Is it just best practice?
  • Documentation / Tutorial

Custom assertion example

from sure import assertion


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


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

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

@gabrielfalcao please provide feedback regarding API. See first test for entire example usage.

Refs: #31

@timofurrer
Copy link
Collaborator Author

@gabrielfalcao Would you prefer to pass important values to the assertion function directly?

The interface would then look like:

@assertion
def return_code(self, what, is_negative, return_code):
    pass

This would have the benefit that the user does not need to know the AssertionBuilder class that well. The user would get an impression what's important for the assertion from the methods interface.

However, with that the user is kinda limited to those values - even worse would be if the user would not need the passed values but instead needs to access something from self: every linter would complain about unused arguments.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe don't use setattr but registration of assertion into a dict and then use __getattr__ ...?

return self.obj.headers[header_name]


# FIXME(TF): 'must' does not sound right in this method chain.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gabrielfalcao what do you think about adding a which or having to the list of POSITIVES for the monkey patched PyObject properties?

@timofurrer timofurrer changed the title [WIP] Provide possibility to extend sure. Refs #31 Provide possibility to extend sure. Refs #31 Jun 21, 2016
@timofurrer timofurrer modified the milestone: 1.4.0 Jun 21, 2016
@timofurrer timofurrer merged commit cfec013 into gabrielfalcao:master Jun 29, 2016
@gabrielfalcao
Copy link
Owner

This developer experience is fantastic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants