Skip to content

Commit

Permalink
Merge pull request #1 from vxgmichel/hypothesis-443
Browse files Browse the repository at this point in the history
 Update to hypothesis 4.4.3
  • Loading branch information
Zac-HD authored Feb 10, 2019
2 parents bb769ef + d2561e1 commit 5c020ed
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 167 deletions.
19 changes: 5 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
language: python
python:
- 3.5.0
- 3.5.2
- 3.5-dev
- 3.5
- pypy3.5
- 3.6
- 3.6-dev
- 3.7-dev
- 3.7
- 3.8-dev
sudo: false
dist: trusty
dist: xenial
matrix:
include:
- os: linux
language: generic
env: USE_PYPY_RELEASE_VERSION=5.9-beta
# Python3.5 on MacOS doesn't currently support TLSv1.2 needed to use pip :(
# http://pyfound.blogspot.fr/2017/01/time-to-upgrade-your-python-tls-v12.html
# - os: osx
# language: generic
# env: MACPYTHON=3.5.4
- os: osx
language: generic
env: MACPYTHON=3.6.3
Expand Down
122 changes: 66 additions & 56 deletions hypothesis_trio/_tests/test_async_stateful.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,11 @@
from trio.abc import Instrument
from trio.testing import MockClock

from hypothesis_trio.stateful import TrioGenericStateMachine, TrioRuleBasedStateMachine
from hypothesis.stateful import initialize, rule, invariant, run_state_machine_as_test
from hypothesis.strategies import just, integers, lists, tuples


def test_triggers():
class LogEventsStateMachine(TrioGenericStateMachine):
events = []

async def teardown(self):
await trio.sleep(0)
self.events.append('teardown')

def steps(self):
return just(42)

async def execute_step(self, step):
await trio.sleep(0)
assert step is 42
self.events.append('execute_step')

async def check_invariants(self):
await trio.sleep(0)
self.events.append('check_invariants')

run_state_machine_as_test(LogEventsStateMachine)

per_run_events = []
current_run_events = []
for event in LogEventsStateMachine.events:
current_run_events.append(event)
if event == 'teardown':
per_run_events.append(current_run_events)
current_run_events = []

for run_events in per_run_events:
expected_events = ['check_invariants']
expected_events += ['execute_step', 'check_invariants'
] * ((len(run_events) - 2) // 2)
expected_events.append('teardown')
assert run_events == expected_events
import hypothesis
from hypothesis import Verbosity
from hypothesis_trio.stateful import TrioRuleBasedStateMachine
from hypothesis.stateful import Bundle, initialize, rule, invariant, run_state_machine_as_test
from hypothesis.strategies import integers, lists, tuples


def test_rule_based():
Expand Down Expand Up @@ -150,46 +114,92 @@ async def teardown(self):


def test_trio_style():
async def _consumer(
in_queue, out_queue, *, task_status=trio.TASK_STATUS_IGNORED
async def consumer(
receive_job, send_result, *, task_status=trio.TASK_STATUS_IGNORED
):
with trio.open_cancel_scope() as cancel_scope:
task_status.started(cancel_scope)
while True:
x, y = await in_queue.get()
async for x, y in receive_job:
await trio.sleep(0)
result = x + y
await out_queue.put('%s + %s = %s' % (x, y, result))
await send_result.send('%s + %s = %s' % (x, y, result))

class TrioStyleStateMachine(TrioRuleBasedStateMachine):
@initialize()
async def initialize(self):
self.job_queue = trio.Queue(100)
self.result_queue = trio.Queue(100)
self.consumer_cancel_scope = await self.get_root_nursery().start(
_consumer, self.job_queue, self.result_queue
)
self.send_job, receive_job = trio.open_memory_channel(100)
send_result, self.receive_result = trio.open_memory_channel(100)
self.consumer_args = consumer, receive_job, send_result
self.consumer_cancel_scope = await self.get_root_nursery(
).start(*self.consumer_args)

@rule(work=lists(tuples(integers(), integers())))
async def generate_work(self, work):
await trio.sleep(0)
for x, y in work:
await self.job_queue.put((x, y))
await self.send_job.send((x, y))

@rule()
async def restart_consumer(self):
self.consumer_cancel_scope.cancel()
self.consumer_cancel_scope = await self.get_root_nursery().start(
_consumer, self.job_queue, self.result_queue
)
self.consumer_cancel_scope = await self.get_root_nursery(
).start(*self.consumer_args)

@invariant()
async def check_results(self):
while True:
try:
job = self.result_queue.get_nowait()
job = self.receive_result.receive_nowait()
assert isinstance(job, str)
except (trio.WouldBlock, AttributeError):
break

run_state_machine_as_test(TrioStyleStateMachine)


def test_trio_style_failing(capsys):

# Failing state machine

class TrioStyleStateMachine(TrioRuleBasedStateMachine):
Values = Bundle('value')

@initialize(target=Values)
async def initialize(self):
return 1

@rule(value=Values)
async def do_work(self, value):
assert value == 2

# Check failure

settings = hypothesis.settings(max_examples=10, verbosity=Verbosity.debug)
with pytest.raises(AssertionError) as record:
run_state_machine_as_test(TrioStyleStateMachine, settings=settings)
captured = capsys.readouterr()
assert 'assert 1 == 2' in str(record.value)

# Check steps

with pytest.raises(AssertionError) as record:
state = TrioStyleStateMachine()

async def steps():
v1 = await state.initialize()
await state.do_work(value=v1)
await state.teardown()

state.trio_run(steps)
assert 'assert 1 == 2' in str(record.value)

# Check steps printout

assert """\
state = TrioStyleStateMachine()
async def steps():
v1 = await state.initialize()
await state.do_work(value=v1)
await state.teardown()
state.trio_run(steps)
""" in captured.out
2 changes: 1 addition & 1 deletion hypothesis_trio/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# This file is imported from __init__.py and exec'd from setup.py

__version__ = "0.2.2"
__version__ = "0.3.0"
Loading

0 comments on commit 5c020ed

Please sign in to comment.