[Python-modules-commits] [python-hypothesis] 01/03: Import python-hypothesis_3.4.0.orig.tar.gz
Tristan Seligmann
mithrandi at moszumanska.debian.org
Sat Jun 25 01:01:41 UTC 2016
This is an automated email from the git hooks/post-receive script.
mithrandi pushed a commit to branch master
in repository python-hypothesis.
commit 3f1e2cddf7ec412a29d70c93174f2dab92238f3e
Author: Tristan Seligmann <mithrandi at debian.org>
Date: Sat Jun 25 02:00:35 2016 +0200
Import python-hypothesis_3.4.0.orig.tar.gz
---
.coveragerc | 4 +-
.gitattributes | 1 +
.gitignore | 2 +
CITATION | 4 +-
Makefile | 7 +-
Vagrantfile | 33 ++++++++
docs/changes.rst | 37 ++++++++-
docs/details.rst | 2 +-
docs/development.rst | 8 +-
docs/endorsements.rst | 2 +-
docs/extras.rst | 14 ----
docs/index.rst | 2 +-
docs/packaging.rst | 2 +-
docs/support.rst | 2 +-
hypothesislegacysupport/setup.py | 2 +-
.../src/hypothesislegacysupport/version.py | 2 +-
scripts/install.sh | 2 +-
setup.py | 2 +-
src/hypothesis/core.py | 45 +++-------
src/hypothesis/extra/django/models.py | 74 ++++++++++++++---
src/hypothesis/version.py | 2 +-
tests/cover/test_health_checks.py | 96 ++++++++++------------
tests/cover/test_random_module.py | 30 +++++++
tests/cover/test_testdecorators.py | 3 +-
tests/django/toystore/models.py | 29 ++++++-
tests/django/toystore/test_given_models.py | 21 ++++-
tox.ini | 2 +
27 files changed, 291 insertions(+), 139 deletions(-)
diff --git a/.coveragerc b/.coveragerc
index 0c4a163..5e67a9f 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,8 +1,8 @@
[run]
branch = True
include =
- .tox/*/lib/*/site-packages/hypothesis/*.py
- .tox/*/lib/*/site-packages/hypothesis/**/*.py
+ **/.tox/*/lib/*/site-packages/hypothesis/*.py
+ **/.tox/*/lib/*/site-packages/hypothesis/**/*.py
omit =
**/_settings.py
**/pytestplugin.py
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..70a9d75
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index cf521b1..b3fc281 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ _build
.tox
.coverage
.runtimes
+.idea
+.vagrant
diff --git a/CITATION b/CITATION
index 6ac50a5..6c0364b 100644
--- a/CITATION
+++ b/CITATION
@@ -4,7 +4,7 @@ x.y) from this installation
Text:
[Hypothesis] Hypothesis x.y, 2016
-David R. MacIver, https://github.com/DRMacIver/hypothesis
+David R. MacIver, https://github.com/HypothesisWorks/hypothesis-python
BibTeX:
@@ -12,7 +12,7 @@ BibTeX:
title = {{H}ypothesis x.y},
author = {David R. MacIver},
year = {2016},
- howpublished = {\href{https://github.com/DRMacIver/hypothesis}{\texttt{https://github.com/DRMacIver/hypothesis}}},
+ howpublished = {\href{https://github.com/HypothesisWorks/hypothesis-python}{\texttt{https://github.com/HypothesisWorks/hypothesis-python}}},
}
If you are unsure about which version of hypothesis you are using run: `pip show
diff --git a/Makefile b/Makefile
index e3da186..ef1f921 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,9 @@ SPHINXBUILD = $(DEV_PYTHON) -m sphinx
SPHINX_BUILDDIR = docs/_build
ALLSPHINXOPTS = -d $(SPHINX_BUILDDIR)/doctrees docs -W
-BUILD_RUNTIMES?=$(PWD)/.runtimes
+export BUILD_RUNTIMES?=$(HOME)/.cache/hypothesis-build-runtimes
+export TOX_WORK_DIR=$(BUILD_RUNTIMES)/.tox
+export COVERAGE_FILE=$(BUILD_RUNTIMES)/.coverage
PY26=$(BUILD_RUNTIMES)/snakepit/python2.6
PY27=$(BUILD_RUNTIMES)/snakepit/python2.7
@@ -62,6 +64,8 @@ $(TOOL_VIRTUALENV): $(PY34)
$(TOOLS): $(TOOL_VIRTUALENV)
+install-tools: $(TOOLS)
+
$(ISORT_VIRTUALENV): $(PY34)
$(PY34) -m virtualenv $(ISORT_VIRTUALENV)
@@ -160,7 +164,6 @@ check-fast: lint $(PY26) $(PY35) $(PYPY) $(TOX)
$(TOX): $(PY35) tox.ini $(TOOLS)
rm -f $(TOX)
$(TOOL_INSTALL) tox
- rm -rf .tox
ln -sf $(TOOL_VIRTUALENV)/bin/tox $(TOX)
touch $(TOOL_VIRTUALENV)/bin/tox $(TOX)
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000..99be1c6
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,33 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# This is a trivial Vagrantfile designed to simplify development of Hypothesis on Windows,
+# where the normal make based build system doesn't work, or anywhere else where you would
+# prefer a clean environment for Hypothesis development. It doesn't do anything more than spin
+# up a suitable local VM for use with vagrant ssh. You should then use the Makefile from within
+# that VM.
+
+PROVISION = <<PROVISION
+
+sudo apt-get install -y git libreadline-dev libssl-dev zlib1g-dev build-essential libbz2-dev libsqlite3-dev
+
+if [ ! $(grep -q 'cd /vagrant' $HOME/.bashrc) ]; then
+ echo 'cd /vagrant' >> $HOME/.bashrc
+fi
+
+cd /vagrant/
+
+make install-tools
+
+PROVISION
+
+Vagrant.configure(2) do |config|
+
+ config.vm.provider "virtualbox" do |v|
+ v.memory = 1024
+ end
+
+ config.vm.box = "ubuntu/trusty64"
+
+ config.vm.provision "shell", inline: PROVISION, privileged: false
+end
diff --git a/docs/changes.rst b/docs/changes.rst
index 1e38e06..cb9adfd 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -22,6 +22,41 @@ You should generally assume that an API is internal unless you have specific
information to the contrary.
------------------
+3.4.0 - 2016-05-27
+------------------
+
+This release is entirely provided by `Lucas Wiman <https://github.com/lucaswiman>`_:
+
+models() strategies from hypothesis.extra.django will now respect much more of
+Django's validations out of the box. Wherever possible full_clean() should
+succeed.
+
+In particular:
+
+* The max_length, blank and choices kwargs are now respected.
+* Add support for DecimalField.
+* If a field includes validators, the list of validators are used to filter the field strategy.
+
+------------------
+3.3.0 - 2016-05-27
+------------------
+
+This release went wrong and is functionally equivalent to 3.2.0. Ignore it.
+
+------------------
+3.2.0 - 2016-05-19
+------------------
+
+This is a small single-feature release:
+
+* All tests using @given now fix the global random seed. This removes the health
+ check for that. If a non-zero seed is required for the final falsifying
+ example, it will be reported. Otherwise Hypothesis will assume randomization
+ was not a significant factor for the test and be silent on the subject. If you
+ use the random_module() strategy this will continue to work and will always
+ display the seed.
+
+------------------
3.1.3 - 2016-05-01
------------------
@@ -548,7 +583,7 @@ Bug fixes:
instead of its contexts. This is obviously silly. It now works with any sequence
of things convertible to unicode strings.
* @given will now work on methods whose definitions contains no explicit positional
- arguments, only varargs (`bug #118 <https://github.com/DRMacIver/hypothesis/issues/118>`_).
+ arguments, only varargs (`bug #118 <https://github.com/HypothesisWorks/hypothesis-python/issues/118>`_).
This may have some knock on effects because it means that @given no longer changes the
argspec of functions other than by adding defaults.
* Introduction of new @composite feature for more natural definition of strategies you'd
diff --git a/docs/details.rst b/docs/details.rst
index a987497..c516d61 100644
--- a/docs/details.rst
+++ b/docs/details.rst
@@ -418,7 +418,7 @@ example to a condition that is always false it will raise an error:
>>> find(booleans(), lambda x: False)
Traceback (most recent call last):
...
- hypothesis.errors.DefinitelyNoSuchExample: No examples of condition lambda x: <unknown> (all 2 considered)
+ hypothesis.errors.NoSuchExample: No examples of condition lambda x: <unknown>
diff --git a/docs/development.rst b/docs/development.rst
index 361ca81..387a2f9 100644
--- a/docs/development.rst
+++ b/docs/development.rst
@@ -16,13 +16,13 @@ I am the primary author of Hypothesis.
So all new features must either be sponsored or implemented by someone else. That being said, I take a fairly active
role in shepherding pull requests and helping people write a new feature (see `the
-contributing guidelines <https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst>`_ for
+contributing guidelines <https://github.com/HypothesisWorks/hypothesis-python/blob/master/CONTRIBUTING.rst>`_ for
details and `this pull request
-<https://github.com/DRMacIver/hypothesis/pull/154>`_ for an example of how the process goes). This isn't
+<https://github.com/HypothesisWorks/hypothesis-python/pull/154>`_ for an example of how the process goes). This isn't
"patches welcome", it's "I will help you write a patch".
-All enhancement tickets on GitHub are tagged with either `help-wanted <https://github.com/DRMacIver/hypothesis/labels/help-wanted>`_
-if I think they're viable for someone else to pick up or `for-a-modest-fee <https://github.com/DRMacIver/hypothesis/labels/for-a-modest-fee>`_ if
+All enhancement tickets on GitHub are tagged with either `help-wanted <https://github.com/HypothesisWorks/hypothesis-python/labels/help-wanted>`_
+if I think they're viable for someone else to pick up or `for-a-modest-fee <https://github.com/HypothesisWorks/hypothesis-python/labels/for-a-modest-fee>`_ if
I think they are not and that if you want them you should probably talk to me about paid development.
You are of course entirely welcome to ask for paid development on something that is marked help-wanted,
diff --git a/docs/endorsements.rst b/docs/endorsements.rst
index 91b3895..0989d94 100644
--- a/docs/endorsements.rst
+++ b/docs/endorsements.rst
@@ -4,7 +4,7 @@ Who is using Hypothesis?
This is a page for listing people who are using Hypothesis and how excited they
are about that. If that's you and your name is not on the list, `this file is in
-Git <https://github.com/DRMacIver/hypothesis/blob/master/docs/endorsements.rst>`_
+Git <https://github.com/HypothesisWorks/hypothesis-python/blob/master/docs/endorsements.rst>`_
and I'd love it if you sent me a pull request to fix that.
diff --git a/docs/extras.rst b/docs/extras.rst
index dcc0aa2..a58806a 100644
--- a/docs/extras.rst
+++ b/docs/extras.rst
@@ -184,20 +184,6 @@ against 1.8.
It's large enough that it is :doc:`documented elsewhere <django>`.
------------------
-hypothesis-pytest
------------------
-
-hypothesis-pytest is actually available as a separate package that is installed as
-hypothesis-pytest rather than hypothesis[pytest]. This may change in future but the
-package will remain for compatibility reasons if it does.
-
-hypothesis-pytest is the world's most basic pytest plugin. Install it to get
-slightly better integrated example reporting when using @given and running
-under pytest.
-
-It can also load :ref:`settings Profiles <settings_profiles>`.
-
------------------
hypothesis[numpy]
------------------
diff --git a/docs/index.rst b/docs/index.rst
index 1f0e3fd..7d08ab9 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,7 +2,7 @@
Welcome to Hypothesis!
======================
-`Hypothesis <https://github.com/DRMacIver/hypothesis>`_ is a Python library for
+`Hypothesis <http://hypothesis.works>`_ is a Python library for
creating unit tests which are simpler to write and more powerful when run,
finding edge cases in your code you wouldn't have thought to look for. It is
stable, powerful and easy to add to any existing test suite.
diff --git a/docs/packaging.rst b/docs/packaging.rst
index 6d7696a..39e6cdc 100644
--- a/docs/packaging.rst
+++ b/docs/packaging.rst
@@ -21,7 +21,7 @@ some information you might find useful.
Release tarballs
----------------
-These are available from `the GitHub releases page <https://github.com/DRMacIver/hypothesis/releases>`_. The
+These are available from `the GitHub releases page <https://github.com/HypothesisWorks/hypothesis-python/releases>`_. The
tarballs on pypi are intended for installation from a Python tool such as pip or easy_install and should not
be considered complete releases. Requests to include additional files in them will not be granted. Their absence
is not a bug.
diff --git a/docs/support.rst b/docs/support.rst
index e700508..9b579dc 100644
--- a/docs/support.rst
+++ b/docs/support.rst
@@ -7,7 +7,7 @@ friendly place where I or others will be more than happy to help you out. You're
ask questions on Stack Overflow. If you do, please tag them with 'python-hypothesis' so someone
sees them.
-For bugs and enhancements, please file an issue on the `GitHub issue tracker <https://github.com/DRMacIver/hypothesis/issues>`_.
+For bugs and enhancements, please file an issue on the `GitHub issue tracker <https://github.com/HypothesisWorks/hypothesis-python/issues>`_.
Note that as per the :doc:`development policy <development>`, enhancements will probably not get
implemented unless you're willing to pay for development or implement them yourself (with assistance from me). Bugs
will tend to get fixed reasonably promptly, though it is of course on a best effort basis.
diff --git a/hypothesislegacysupport/setup.py b/hypothesislegacysupport/setup.py
index 607dd7b..bbbfa26 100644
--- a/hypothesislegacysupport/setup.py
+++ b/hypothesislegacysupport/setup.py
@@ -37,7 +37,7 @@ setup(
author_email='david at drmaciver.com',
packages=find_packages(SOURCE),
package_dir={'': SOURCE},
- url='https://github.com/DRMacIver/hypothesis',
+ url='https://github.com/HypothesisWorks/hypothesis-python',
license='AGPL',
install_requires=install_requires,
extras_require={
diff --git a/hypothesislegacysupport/src/hypothesislegacysupport/version.py b/hypothesislegacysupport/src/hypothesislegacysupport/version.py
index d3ede55..9a5c67e 100644
--- a/hypothesislegacysupport/src/hypothesislegacysupport/version.py
+++ b/hypothesislegacysupport/src/hypothesislegacysupport/version.py
@@ -20,5 +20,5 @@
from __future__ import division, print_function, absolute_import
-__version_info__ = (3, 1, 3)
+__version_info__ = (3, 4, 0)
__version__ = '.'.join(map(str, __version_info__))
diff --git a/scripts/install.sh b/scripts/install.sh
index 95c0d04..f29fdf4 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -26,7 +26,7 @@ env | grep UTF
# ever not being acquired.
BASE=${BUILD_RUNTIMES-$PWD/.runtimes}
-echo $BASE
+
mkdir -p $BASE
LOCKFILE="$BASE/.install-lockfile"
diff --git a/setup.py b/setup.py
index c35a1ad..26cc83c 100644
--- a/setup.py
+++ b/setup.py
@@ -63,7 +63,7 @@ setup(
author_email='david at drmaciver.com',
packages=find_packages(SOURCE),
package_dir={"": SOURCE},
- url='https://github.com/DRMacIver/hypothesis',
+ url='https://github.com/HypothesisWorks/hypothesis-python',
license='MPL v2',
description='A library for property based testing',
zip_safe=False,
diff --git a/src/hypothesis/core.py b/src/hypothesis/core.py
index 821ccd1..1f889d8 100644
--- a/src/hypothesis/core.py
+++ b/src/hypothesis/core.py
@@ -24,7 +24,6 @@ import time
import inspect
import functools
import traceback
-from random import getstate as getglobalrandomstate
from random import Random
from collections import namedtuple
@@ -89,8 +88,15 @@ def reify_and_execute(
print_example=False,
is_final=False,
):
+ from hypothesis.strategies import random_module
+
def run(data):
+ from hypothesis.control import note
+
with BuildContext(is_final=is_final):
+ seed = data.draw(random_module()).seed
+ if seed != 0:
+ note('random.seed(%d)' % (seed,))
args, kwargs = data.draw(search_strategy)
if print_example:
@@ -314,7 +320,6 @@ def given(*generator_arguments, **generator_kwargs):
return
if perform_health_check:
- initial_state = getglobalrandomstate()
health_check_random = Random(random.getrandbits(128))
# We "pre warm" the health check with one draw to give it some
# time to calculate any cached data. This prevents the case
@@ -364,6 +369,11 @@ def given(*generator_arguments, **generator_kwargs):
except InvalidArgument:
raise
except Exception:
+ if (
+ HealthCheck.exception_in_generation in
+ settings.suppress_health_check
+ ):
+ raise
report(traceback.format_exc())
if test_runner is default_new_style_executor:
fail_health_check(
@@ -424,27 +434,10 @@ def given(*generator_arguments, **generator_kwargs):
) % (count, runtime, filtered_draws, overruns),
HealthCheck.too_slow,
)
- if getglobalrandomstate() != initial_state:
- fail_health_check(
- 'Data generation depends on global random module. '
- 'This makes results impossible to replay, which '
- 'prevents Hypothesis from working correctly. '
- 'If you want to use methods from random, use '
- 'randoms() from hypothesis.strategies to get an '
- 'instance of Random you can use. Alternatively, you '
- 'can use the random_module() strategy to explicitly '
- 'seed the random module.', HealthCheck.random_module,
- )
last_exception = [None]
repr_for_last_exception = [None]
- performed_random_check = [False]
def evaluate_test_data(data):
- if perform_health_check and not performed_random_check[0]:
- initial_state = getglobalrandomstate()
- performed_random_check[0] = True
- else:
- initial_state = None
try:
result = test_runner(data, reify_and_execute(
search_strategy, test,
@@ -466,20 +459,6 @@ def given(*generator_arguments, **generator_kwargs):
last_exception[0] = traceback.format_exc()
verbose_report(last_exception[0])
data.mark_interesting()
- finally:
- if (
- initial_state is not None and
- getglobalrandomstate() != initial_state
- ):
- fail_health_check(
- 'Your test used the global random module. '
- 'This is unlikely to work correctly. You should '
- 'consider using the randoms() strategy from '
- 'hypothesis.strategies instead. Alternatively, '
- 'you can use the random_module() strategy to '
- 'explicitly seed the random module.',
- HealthCheck.random_module,
- )
from hypothesis.internal.conjecture.engine import TestRunner
diff --git a/src/hypothesis/extra/django/models.py b/src/hypothesis/extra/django/models.py
index ad3d68b..b8267e4 100644
--- a/src/hypothesis/extra/django/models.py
+++ b/src/hypothesis/extra/django/models.py
@@ -17,8 +17,11 @@
from __future__ import division, print_function, absolute_import
+from decimal import Decimal
+
import django.db.models as dm
from django.db import IntegrityError
+from django.core.exceptions import ValidationError
import hypothesis.strategies as st
import hypothesis.extra.fakefactory as ff
@@ -60,10 +63,7 @@ def field_mappings():
dm.PositiveSmallIntegerField: st.integers(0, 32767),
dm.BinaryField: st.binary(),
dm.BooleanField: st.booleans(),
- dm.CharField: st.text(),
- dm.TextField: st.text(),
dm.DateTimeField: datetimes(allow_naive=False),
- dm.EmailField: ff.fake_factory(u'email'),
dm.FloatField: st.floats(),
dm.NullBooleanField: st.one_of(st.none(), st.booleans()),
}
@@ -77,22 +77,70 @@ def add_default_field_mapping(field_type, strategy):
default_value = UniqueIdentifier(u'default_value')
+class UnmappedFieldError(Exception):
+ pass
+
+
+def validator_to_filter(f):
+ """Converts the field run_validators method to something suitable for use
+ in filter."""
+
+ def validate(value):
+ try:
+ f.run_validators(value)
+ return True
+ except ValidationError:
+ return False
+
+ return validate
+
+
+def _get_strategy_for_field(f):
+ if isinstance(f, dm.AutoField):
+ return default_value
+ elif f.choices:
+ choices = [value for (value, name) in f.choices]
+ if isinstance(f, (dm.CharField, dm.TextField)) and f.blank:
+ choices.append(u'')
+ strategy = st.sampled_from(choices)
+ elif isinstance(f, dm.EmailField):
+ return ff.fake_factory(u'email')
+ elif type(f) in (dm.TextField, dm.CharField):
+ strategy = st.text(min_size=(None if f.blank else 1),
+ max_size=f.max_length)
+ elif type(f) == dm.DecimalField:
+ m = 10 ** f.max_digits - 1
+ div = 10 ** f.decimal_places
+ q = Decimal('1.' + ('0' * f.decimal_places))
+ strategy = (
+ st.integers(min_value=-m, max_value=m)
+ .map(lambda n: (Decimal(n) / div).quantize(q)))
+ else:
+ try:
+ strategy = field_mappings()[type(f)]
+ except KeyError:
+ if f.null:
+ return None
+ else:
+ raise UnmappedFieldError(f)
+ if f.validators:
+ strategy = strategy.filter(validator_to_filter(f))
+ if f.null:
+ strategy = st.one_of(st.none(), strategy)
+ return strategy
+
+
def models(model, **extra):
result = {}
- mappings = field_mappings()
mandatory = set()
for f in model._meta.concrete_fields:
- if isinstance(f, dm.AutoField):
- continue
try:
- mapped = mappings[type(f)]
- except KeyError:
- if not f.null:
- mandatory.add(f.name)
+ strategy = _get_strategy_for_field(f)
+ except UnmappedFieldError:
+ mandatory.add(f.name)
continue
- if f.null:
- mapped = st.one_of(st.none(), mapped)
- result[f.name] = mapped
+ if strategy is not None:
+ result[f.name] = strategy
missed = {x for x in mandatory if x not in extra}
if missed:
raise InvalidArgument((
diff --git a/src/hypothesis/version.py b/src/hypothesis/version.py
index 41be08a..1b68ae6 100644
--- a/src/hypothesis/version.py
+++ b/src/hypothesis/version.py
@@ -17,5 +17,5 @@
from __future__ import division, print_function, absolute_import
-__version_info__ = (3, 1, 3)
+__version_info__ = (3, 4, 0)
__version__ = '.'.join(map(str, __version_info__))
diff --git a/tests/cover/test_health_checks.py b/tests/cover/test_health_checks.py
index e74f67c..dce5a06 100644
--- a/tests/cover/test_health_checks.py
+++ b/tests/cover/test_health_checks.py
@@ -26,6 +26,7 @@ import hypothesis.strategies as st
from hypothesis import given, settings, HealthCheck
from hypothesis.errors import FailedHealthCheck
from hypothesis.control import assume
+from tests.common.utils import capture_out
from hypothesis.internal.compat import int_from_bytes
from hypothesis.searchstrategy.strategies import SearchStrategy
@@ -39,28 +40,6 @@ def test_slow_generation_fails_a_health_check():
test()
-def test_global_random_in_strategy_fails_a_health_check():
- import random
-
- @given(st.lists(st.integers(), min_size=1).map(random.choice))
- def test(x):
- pass
-
- with raises(FailedHealthCheck):
- test()
-
-
-def test_global_random_in_test_fails_a_health_check():
- import random
-
- @given(st.lists(st.integers(), min_size=1))
- def test(x):
- random.choice(x)
-
- with raises(FailedHealthCheck):
- test()
-
-
def test_default_health_check_can_weaken_specific():
import random
@@ -86,6 +65,48 @@ def test_error_in_strategy_produces_health_check_error():
assert 'executor' not in e.value.args[0]
+def test_suppressing_error_in_value_generation():
+ def boom(x):
+ raise ValueError()
+
+ @settings(suppress_health_check=[HealthCheck.exception_in_generation])
+ @given(st.integers().map(boom))
+ def test(x):
+ pass
+
+ with capture_out() as out:
+ with reporting.with_reporter(reporting.default):
+ with raises(ValueError):
+ test()
+ assert 'ValueError' not in out.getvalue()
+
+
+def test_suppressing_filtering_health_check():
+ count = [0]
+
+ def too_soon(x):
+ count[0] += 1
+ return count[0] >= 200
+
+ @given(st.integers().filter(too_soon))
+ def test1(x):
+ raise ValueError()
+
+ with raises(FailedHealthCheck):
+ test1()
+
+ count[0] = 0
+
+ @settings(suppress_health_check=[
+ HealthCheck.filter_too_much, HealthCheck.too_slow])
+ @given(st.integers().filter(too_soon))
+ def test2(x):
+ raise ValueError()
+
+ with raises(ValueError):
+ test2()
+
+
def test_error_in_strategy_with_custom_executor():
def boom(x):
raise ValueError()
@@ -147,18 +168,6 @@ def test_large_data_will_fail_a_health_check():
assert 'allowable size' in e.value.args[0]
-def test_nesting_without_control_fails_health_check():
- @given(st.integers())
- def test_blah(x):
- @given(st.integers())
- def test_nest(y):
- assert y < x
- with raises(AssertionError):
- test_nest()
- with raises(FailedHealthCheck):
- test_blah()
-
-
def test_returning_non_none_is_forbidden():
@given(st.integers())
def a(x):
@@ -175,22 +184,3 @@ def test_returning_non_none_does_not_fail_if_health_check_disabled():
return 1
a()
-
-
- at given(st.integers())
- at settings(suppress_health_check=[HealthCheck.random_module])
-def test_can_suppress_a_single_health_check(i):
- import random
- random.seed(i)
-
-
-def test_suppressing_health_check_does_not_suppress_others():
- import random
-
- @given(st.integers().filter(lambda x: random.randint(0, 1) and False))
- @settings(suppress_health_check=[HealthCheck.random_module])
- def test(i):
- pass
-
- with raises(FailedHealthCheck):
- test()
diff --git a/tests/cover/test_random_module.py b/tests/cover/test_random_module.py
index 6a95a96..7da8098 100644
--- a/tests/cover/test_random_module.py
+++ b/tests/cover/test_random_module.py
@@ -17,6 +17,8 @@
from __future__ import division, print_function, absolute_import
+import random
+
import pytest
import hypothesis.strategies as st
@@ -44,3 +46,31 @@ def test_seed_random_twice(r, r2):
def test_does_not_fail_health_check_if_randomness_is_used(r):
import random
random.getrandbits(128)
+
+
+def test_reports_non_zero_seed():
+ random.seed(0)
+ zero_value = random.randint(0, 10)
+
+ with capture_out() as out:
+ with reporting.with_reporter(reporting.default):
+ with pytest.raises(AssertionError):
+ @given(st.integers())
+ def test(r):
+ assert random.randint(0, 10) == zero_value
+ test()
+ assert 'random.seed' in out.getvalue()
+
+
+def test_does_not_report_zero_seed():
+ random.seed(0)
+ zero_value = random.randint(0, 3)
+
+ with capture_out() as out:
+ with reporting.with_reporter(reporting.default):
+ with pytest.raises(AssertionError):
+ @given(st.integers())
+ def test(r):
+ assert random.randint(0, 3) != zero_value
+ test()
+ assert 'random.seed' not in out.getvalue()
diff --git a/tests/cover/test_testdecorators.py b/tests/cover/test_testdecorators.py
index b2519f1..41bbd25 100644
--- a/tests/cover/test_testdecorators.py
+++ b/tests/cover/test_testdecorators.py
@@ -454,7 +454,8 @@ def test_can_run_with_database_in_thread():
@given(integers())
def test_can_call_an_argument_f(f):
- # See issue https://github.com/DRMacIver/hypothesis/issues/38 for details
+ # See issue https://github.com/HypothesisWorks/hypothesis-python/issues/38
+ # for details
pass
diff --git a/tests/django/toystore/models.py b/tests/django/toystore/models.py
index 2b70347..050e76f 100644
--- a/tests/django/toystore/models.py
+++ b/tests/django/toystore/models.py
@@ -18,6 +18,7 @@
from __future__ import division, print_function, absolute_import
from django.db import models
+from django.core.exceptions import ValidationError
class Company(models.Model):
@@ -73,7 +74,7 @@ class LoopB(models.Model):
a = models.ForeignKey(u'LoopA', null=True)
-class ManyInts(models.Model):
+class ManyNumerics(models.Model):
i1 = models.IntegerField()
i2 = models.SmallIntegerField()
i3 = models.BigIntegerField()
@@ -81,6 +82,8 @@ class ManyInts(models.Model):
p1 = models.PositiveIntegerField()
p2 = models.PositiveSmallIntegerField()
+ d = models.DecimalField(decimal_places=2, max_digits=5)
+
class CustomishDefault(models.Model):
customish = CustomishField(default=u'b')
@@ -96,3 +99,27 @@ class MandatoryComputed(models.Model):
cname = kw[u'name'] + u'_company'
kw[u'company'] = Company.objects.create(name=cname)
super(MandatoryComputed, self).__init__(**kw)
+
+
+def validate_even(value):
+ if value % 2 != 0:
+ raise ValidationError('')
+
+
+class RestrictedFields(models.Model):
+ text_field_4 = models.TextField(max_length=4, blank=True)
+ char_field_4 = models.CharField(max_length=4, blank=True)
+ choice_field_text = models.TextField(
+ choices=(('foo', 'Foo'), ('bar', 'Bar'))
+ )
+ choice_field_int = models.IntegerField(
+ choices=((1, 'First'), (2, 'Second'))
+ )
+ null_choice_field_int = models.IntegerField(
+ choices=((1, 'First'), (2, 'Second')),
+ null=True, blank=True
+ )
+ even_number_field = models.IntegerField(
+ validators=[validate_even]
+ )
+ non_blank_text_field = models.TextField(blank=False)
diff --git a/tests/django/toystore/test_given_models.py b/tests/django/toystore/test_given_models.py
index 6dd0f0a..2273550 100644
--- a/tests/django/toystore/test_given_models.py
+++ b/tests/django/toystore/test_given_models.py
@@ -22,8 +22,8 @@ from hypothesis.errors import InvalidArgument
from hypothesis.strategies import just, lists
from hypothesis.extra.django import TestCase, TransactionTestCase
from tests.django.toystore.models import Store, Company, Customer, \
- ManyInts, SelfLoop, Customish, CustomishField, CouldBeCharming, \
- CustomishDefault, MandatoryComputed
+ SelfLoop, Customish, ManyNumerics, CustomishField, CouldBeCharming, \
+ CustomishDefault, RestrictedFields, MandatoryComputed
from hypothesis.extra.django.models import models, default_value, \
add_default_field_mapping
@@ -66,7 +66,7 @@ class TestGetsBasicModels(TestCase):
def test_sl(self, sl):
self.assertIsNone(sl.me)
- @given(lists(models(ManyInts)))
+ @given(lists(models(ManyNumerics)))
def test_no_overflow_in_integer(self, manyints):
pass
@@ -102,3 +102,18 @@ class TestsNeedingRollback(TransactionTestCase):
def test_can_get_examples(self):
for _ in range(200):
models(Company).example()
+
+
+class TestRestrictedFields(TestCase):
+
+ @given(models(RestrictedFields))
+ def test_constructs_valid_instance(self, instance):
+ self.assertTrue(isinstance(instance, RestrictedFields))
+ instance.full_clean()
+ self.assertLessEqual(len(instance.text_field_4), 4)
+ self.assertLessEqual(len(instance.char_field_4), 4)
+ self.assertIn(instance.choice_field_text, ('foo', 'bar'))
+ self.assertIn(instance.choice_field_int, (1, 2))
+ self.assertIn(instance.null_choice_field_int, (1, 2, None))
+ self.assertEqual(instance.even_number_field % 2, 0)
+ self.assertTrue(instance.non_blank_text_field)
diff --git a/tox.ini b/tox.ini
index 1452d2d..9810c17 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,11 @@
[tox]
envlist = py{26,27,33,34,35,py}-{brief,prettyquick,full,custom,benchmark}
+toxworkdir={env:TOX_WORK_DIR:.tox}
passenv=
HOME
LC_ALL
+ COVERAGE_FILE
[testenv]
deps =
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-hypothesis.git
More information about the Python-modules-commits
mailing list