-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_hypothesis.py
71 lines (53 loc) · 2.02 KB
/
test_hypothesis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from calculator import Calculator
import pytest
from hypothesis import given
from hypothesis import strategies as st
from hypothesis.stateful import Bundle, RuleBasedStateMachine, rule
import math
@given(st.tuples(st.one_of(st.integers(), st.floats()),
st.one_of(st.integers(), st.floats()),
st.sampled_from(('+', '-', '*', '/'))).filter(
lambda x: not (x[1] == 0 and x[2] == '/')
))
def test_binary_operation(args):
a, b, op = args
calculator = Calculator()
calculator.push(a)
calculator.push(b)
calculator.push(op)
result = calculator.pop()
eval_result = eval("{} {} {}".format(a, op, b),
{}, {"inf": float("inf"),
"nan": float("nan")})
if math.isnan(eval_result):
assert math.isnan(result)
else:
assert eval_result == result
class CalculatorStateMachine(RuleBasedStateMachine):
def __init__(self):
super().__init__()
self.calculator = Calculator()
@rule(n=st.one_of(st.integers(), st.floats()))
def push_number(self, n):
self.calculator.push(n)
@rule(op=st.sampled_from(('+', '-', '*', '/')))
def push_operation(self, op):
stack_size = len(self.calculator.stack)
if stack_size >= 2 and self.calculator.stack[-1] == 0 and op == '/':
with pytest.raises(ZeroDivisionError):
self.calculator.push(op)
else:
result = self.calculator.push(op)
assert result is (stack_size >= 2)
if result:
assert len(self.calculator.stack) == stack_size - 1
@rule()
def pop_result(self):
stack_size = len(self.calculator.stack)
result = self.calculator.pop()
if stack_size == 0:
assert result is False
else:
assert result is not False
assert len(self.calculator.stack) == stack_size - 1
TestCalculatorStateMachine = CalculatorStateMachine.TestCase