forked from HypothesisWorks/hypothesis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_subnormal_floats.py
97 lines (84 loc) · 3.26 KB
/
test_subnormal_floats.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# This file is part of Hypothesis, which may be found at
# https://github.com/HypothesisWorks/hypothesis/
#
# Copyright the Hypothesis Authors.
# Individual contributors are listed in AUTHORS.rst and the git log.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
from sys import float_info
import pytest
from hypothesis.errors import InvalidArgument
from hypothesis.internal.floats import next_down, next_up
from hypothesis.strategies import floats
from hypothesis.strategies._internal.numbers import next_down_normal, next_up_normal
from tests.common.debug import assert_no_examples, find_any
from tests.common.utils import PYTHON_FTZ
pytestmark = [pytest.mark.skipif(PYTHON_FTZ, reason="broken by unsafe compiler flags")]
def kw(marks=(), **kwargs):
id_ = ", ".join(f"{k}={v!r}" for k, v in kwargs.items())
return pytest.param(kwargs, id=id_, marks=marks)
@pytest.mark.parametrize(
"kwargs",
[
kw(min_value=1),
kw(min_value=1),
kw(max_value=-1),
kw(min_value=float_info.min),
kw(min_value=next_down(float_info.min), exclude_min=True),
kw(max_value=-float_info.min),
kw(min_value=next_up(-float_info.min), exclude_max=True),
],
)
def test_subnormal_validation(kwargs):
strat = floats(**kwargs, allow_subnormal=True)
with pytest.raises(InvalidArgument):
strat.example()
@pytest.mark.parametrize(
"kwargs",
[
# min value
kw(allow_subnormal=False, min_value=1),
kw(allow_subnormal=False, min_value=float_info.min),
kw(allow_subnormal=True, min_value=-1),
kw(allow_subnormal=True, min_value=next_down(float_info.min)),
# max value
kw(allow_subnormal=False, max_value=-1),
kw(allow_subnormal=False, max_value=-float_info.min),
kw(allow_subnormal=True, max_value=1),
kw(allow_subnormal=True, max_value=next_up(-float_info.min)),
# min/max values
kw(allow_subnormal=True, min_value=-1, max_value=1),
kw(
allow_subnormal=True,
min_value=next_down(float_info.min),
max_value=float_info.min,
),
kw(
allow_subnormal=True,
min_value=-float_info.min,
max_value=next_up(-float_info.min),
),
kw(allow_subnormal=False, min_value=-1, max_value=-float_info.min),
kw(allow_subnormal=False, min_value=float_info.min, max_value=1),
],
)
def test_allow_subnormal_defaults_correctly(kwargs):
allow_subnormal = kwargs.pop("allow_subnormal")
strat = floats(**kwargs).filter(lambda x: x != 0)
if allow_subnormal:
find_any(strat, lambda x: -float_info.min < x < float_info.min)
else:
assert_no_examples(strat, lambda x: -float_info.min < x < float_info.min)
@pytest.mark.parametrize(
"func, val, expected",
[
(next_up_normal, -float_info.min, -0.0),
(next_up_normal, +0.0, float_info.min),
(next_down_normal, float_info.min, +0.0),
(next_down_normal, -0.0, -float_info.min),
],
)
def test_next_float_normal(func, val, expected):
assert func(value=val, width=64, allow_subnormal=False) == expected