Skip to content

Commit

Permalink
Merge pull request #90 from timofurrer/feature/pypy-support
Browse files Browse the repository at this point in the history
Add pypy support
  • Loading branch information
timofurrer committed Jun 5, 2016
2 parents ff4b104 + c59d18d commit 1508a1b
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 31 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ language: python
sudo: false
python:
- "2.7"
- "pypy"
- "3.4"
- "3.5"

Expand Down
9 changes: 5 additions & 4 deletions sure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,13 +435,13 @@ def __getattr__(self, name):


class AssertionBuilder(object):
def __init__(self, name=None, negative=False, obj=None):
def __init__(self, name=None, negative=False, obj=None, callable_args=None, callable_kw=None):
self._name = name
self.negative = negative

self.obj = obj
self._callable_args = []
self._callable_kw = {}
self._callable_args = callable_args or []
self._callable_kw = callable_kw or {}
self._that = AssertionHelper(self.obj)

def __call__(self, obj):
Expand All @@ -463,7 +463,8 @@ def __getattr__(self, attr):
negative = attr in NEGATIVES

if special_case:
return AssertionBuilder(attr, negative=negative, obj=self.obj)
return AssertionBuilder(attr, negative=negative, obj=self.obj,
callable_args=self._callable_args, callable_kw=self._callable_kw)

return super(AssertionBuilder, self).__getattribute__(attr)

Expand Down
10 changes: 5 additions & 5 deletions tests/test_assertion_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,11 @@ def wrong_should():
def wrong_should_not():
return this(d2).should_not.be(d1)

wrong_should_not.when.called.should.throw(
expect(wrong_should_not).when.called.should.throw(
AssertionError,
'{} should not be the same object as {}, but it is',
)
wrong_should.when.called.should.throw(
expect(wrong_should).when.called.should.throw(
AssertionError,
'{} should be the same object as {}, but it is not',
)
Expand Down Expand Up @@ -713,7 +713,7 @@ def test_equals_handles_mock_call_list():
# Then I see I can compare the call list without manually
# converting anything

callback.call_args_list.should.equal([
expect(callback.call_args_list).should.equal([
mock.call(a=1, b=2),
mock.call(a=3, b=4),
])
Expand Down Expand Up @@ -751,5 +751,5 @@ def test_equals_dictionaries_with_tuple_keys():
("0.0.0.0", 400): "chuck norris",
}

X.should_not.equal(Y)
Y.should_not.equal(X)
expect(X).should_not.equal(Y)
expect(Y).should_not.equal(X)
25 changes: 13 additions & 12 deletions tests/test_cpython_patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@

import sure
from sure import expect
from sure.magic import is_cpython

if is_cpython:
if sure.allows_new_syntax:
def test_it_works_with_objects():
("anything that inherits from object should be patched")

if sure.allows_new_syntax:
def test_it_works_with_objects():
("anything that inherits from object should be patched")
(4).should.equal(2 + 2)
"foo".should.equal("f" + ("o" * 2))
{}.should.be.empty

(4).should.equal(2 + 2)
"foo".should.equal("f" + ("o" * 2))
{}.should.be.empty

def test_dir_conceals_sure_specific_attributes():
("dir(obj) should conceal names of methods that were grafted by sure")

def test_dir_conceals_sure_specific_attributes():
("dir(obj) should conceal names of methods that were grafted by sure")
x = 123

x = 123

expect(set(dir(x)).intersection(set(sure.POSITIVES))).to.be.empty
expect(set(dir(x)).intersection(set(sure.NEGATIVES))).to.be.empty
expect(set(dir(x)).intersection(set(sure.POSITIVES))).to.be.empty
expect(set(dir(x)).intersection(set(sure.NEGATIVES))).to.be.empty


# TODO
Expand Down
4 changes: 2 additions & 2 deletions tests/test_issue_48.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sure
from sure import expect

def raise_err(foobar):
raise ValueError()

def test_issue_48():
raise_err.when.called_with('asdf').should.throw(ValueError)
expect(raise_err).when.called_with('asdf').should.throw(ValueError)
16 changes: 10 additions & 6 deletions tests/test_old_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import sure
from sure.deprecated import that
from sure.magic import is_cpython
from sure import VariablesBag, expect
from nose.tools import assert_equals, assert_raises
from sure.compat import compat_repr, safe_repr, text_type_name
Expand Down Expand Up @@ -57,7 +58,7 @@ def it_crashes():

assert that(it_crashes).raises(
TypeError, (
"the function it_crashes defined at test_old_api.py line 55, is being "
"the function it_crashes defined at test_old_api.py line 56, is being "
"decorated by either @that_with_context or @scenario, so it should "
"take at least 1 parameter, which is the test context"),
)
Expand Down Expand Up @@ -524,9 +525,11 @@ def assertions():
# We can't use unicode in Py2, otherwise it will try to coerce
assert that('foobar' if PY3 else b'foobar').contains(None)

error_msg = "'in <string>' requires string as left operand, not NoneType" if is_cpython else "'NoneType' does not have the buffer interface"

assert that(assertions).raises(
TypeError,
"'in <string>' requires string as left operand, not NoneType",
error_msg
)


Expand All @@ -537,9 +540,10 @@ def test_that_none_contains_string():
assert that(None).contains('bungalow')
assert False, 'should not reach here'
except Exception as e:
error_msg = "argument of type 'NoneType' is not iterable" if is_cpython else "'NoneType' object is not iterable"
assert_equals(
text_type(e),
"argument of type 'NoneType' is not iterable",
error_msg
)


Expand Down Expand Up @@ -891,7 +895,7 @@ def test_depends_on_failing_due_nothing_found():
from sure import action_for, scenario

fullpath = os.path.abspath(__file__).replace('.pyc', '.py')
error = 'the action "lonely_action" defined at %s:900 ' \
error = 'the action "lonely_action" defined at %s:904 ' \
'depends on the attribute "something" to be available in the' \
' context. It turns out that there are no actions providing ' \
'that. Please double-check the implementation' % fullpath
Expand All @@ -917,10 +921,10 @@ def test_depends_on_failing_due_not_calling_a_previous_action():
from sure import action_for, scenario

fullpath = os.path.abspath(__file__).replace('.pyc', '.py')
error = 'the action "my_action" defined at {0}:930 ' \
error = 'the action "my_action" defined at {0}:934 ' \
'depends on the attribute "some_attr" to be available in the context.'\
' You need to call one of the following actions beforehand:\n' \
' -> dependency_action at {0}:926'.replace('{0}', fullpath)
' -> dependency_action at {0}:930'.replace('{0}', fullpath)

def with_setup(context):
@action_for(context, provides=['some_attr'])
Expand Down
3 changes: 1 addition & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
# and then run "tox" from this directory.

[tox]
envlist = py27, py34, py35
envlist = py27, pypy, py34, py35

[testenv]
commands = nosetests
deps =
steadymark
nose

0 comments on commit 1508a1b

Please sign in to comment.