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

Add initial hypothesis #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
coverage
pytest
hypothesis
ipdb
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ def find_meta(meta):
zip_safe=False,
classifiers=CLASSIFIERS,
install_requires=INSTALL_REQUIRES,
tests_require=["hypothesis"]
)
99 changes: 66 additions & 33 deletions tests/test_requires.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
import pytest

from required import Requires, R, RequirementError
from hypothesis import given
from hypothesis.strategies import (
data, integers, one_of, booleans,
floats, complex_numbers, tuples,
none, lists, sets, fixed_dictionaries,
characters, text, binary,
)

all_types = (
integers(), none(),
floats(), complex_numbers(), tuples(),
characters(), text(), binary(), booleans(),
)


class TestRequires(object):

def test_value_no_dependency_does_not_raise_error(self):
requires = Requires("x", "y")
data = {"x": 1}
requires._validate("y", data)
@given(data())
def test_value_no_dependency_does_not_raise_error(self, draw):
requires = Requires("x", R("x") < R("y"))

x = draw.draw(integers())
y = draw.draw(integers(min_value=x+1))

data = {"x": x, "y": y}
requires.validate(data)

def test_exists_dependency_raises_requirements_error(self):
@given(one_of(*all_types))
def test_exists_dependency_raises_requirements_error(self, item):
requires = Requires("x", "y")
data = {"x": 1}
data = {"x": item}
with pytest.raises(RequirementError):
requires._validate("x", data)

def test_triple_dependency_raises_correct_error(self):
@given(one_of(*all_types))
def test_triple_dependency_raises_correct_error(self, item):
requires = Requires("x", "y") + Requires("y", "z")
data = {"x": 1}
data = {"x": item}

with pytest.raises(RequirementError):
requires._validate("x", data)
Expand All @@ -28,71 +48,80 @@ def test_triple_dependency_raises_correct_error(self):

requires._validate("z", data)

def test_multiple_dependencies_requires_all(self):
@given(one_of(*all_types), one_of(*all_types), one_of(*all_types))
def test_multiple_dependencies_requires_all(self, x, y, z):
requires = Requires("x", "y") + Requires("x", "z")
data = {"x": 1, "y": 2}
data = {"x": x, "y": y}

with pytest.raises(RequirementError):
requires._validate("x", data)

data = {"x": 1, "z": 2}
data = {"x": x, "z": z}
with pytest.raises(RequirementError):
requires._validate("x", data)

data = {"x": 1, "z": 2, "y": 2}
data = {"x": x, "z": y, "y": z}
requires._validate("x", data)

def test_circular_dependency_requires_both(self):
@given(one_of(*all_types), one_of(*all_types))
def test_circular_dependency_requires_both(self, x, y):
requires = Requires("x", "y") + Requires("y", "x")

data = {"x": 1}
data = {"x": x}
with pytest.raises(RequirementError):
requires._validate("x", data)

data = {"y": 1}
data = {"y": y}
with pytest.raises(RequirementError):
requires._validate("y", data)

data = {"x": 1, "y": 2}
data = {"x": x, "y": y}
requires._validate("y", data)
requires._validate("x", data)

def test_simple_expression_dependency_equal(self):
requires = Requires("x", R("y") == 1)
data = {"x": 1, "y": 2}
@given(one_of(*all_types), integers())
def test_simple_expression_dependency_equal(self, x, y):
requires = Requires("x", R("y") == y)
data = {"x": x, "y": y + 1}
with pytest.raises(RequirementError):
requires._validate("x", data)

data = {"x": 1, "y": 1}
data = {"x": x, "y": y}
requires._validate("x", data)

def test_simple_expression_dependency_greater_or_equal(self):
@given(data())
def test_simple_expression_dependency_greater_or_equal(self, draw):
requires = Requires("x", R("y") >= 1)
data = {"x": 1, "y": 0}

x = draw.draw(integers())
y = draw.draw(integers(max_value=0))

data = {"x": x, "y": y}
with pytest.raises(RequirementError):
requires._validate("x", data)

data = {"x": 1, "y": 1}
requires._validate("x", data)
x = draw.draw(integers())
y = draw.draw(integers(min_value=1))

data = {"x": 1, "y": 2}
data = {"x": x, "y": y}
requires._validate("x", data)

data = {"y": 2}
data = {"y": x}
requires._validate("y", data)

def test_multi_expression_dependency_correctly_validates(self):
requires = Requires("x", R("y") >= 1) + Requires("z", R("y") <= 1)
@given(integers(), integers(), integers(), integers())
def test_multi_expression_dependency_correctly_validates(self, x, y, z, gte):
requires = Requires("x", R("y") >= gte) + Requires("z", R("y") <= gte)

data = {"x": 1, "y": 2, "z": 1}
data = {"x": x, "y": gte + 1, "z": z}

with pytest.raises(RequirementError):
requires._validate("z", data)

requires._validate("x", data)
requires._validate("y", data)

data = {"x": 1, "y": 1, "z": 1}
data = {"x": gte, "y": gte, "z": gte}
requires._validate("z", data)

def test_multi_r_in_expression_correctly_validates(self):
Expand Down Expand Up @@ -277,13 +306,17 @@ def test_multi_partial_dependency_simple_all_satisifed(self):
data = {"x": 2, "z": "hello"}
requires.validate(data)

def test_simple_self_dependency(self):
@given(data())
def test_simple_self_dependency(self, draw):
requires = Requires("x", R("x") > 1)
data = {"x": 1}

x = draw.draw(integers(max_value=1))
data = {"x": x}
with pytest.raises(RequirementError):
requires.validate(data)

data = {"x": 2}
x = draw.draw(integers(min_value=2))
data = {"x": x}
requires.validate(data)

def test_simple_length_equals(self):
Expand Down