|
15 | 15 | import hypothesis.strategies as st |
16 | 16 | from hypothesis import HealthCheck, assume, example, given, settings |
17 | 17 | from hypothesis.internal.conjecture import utils as cu |
18 | | -from hypothesis.internal.conjecture.data import ConjectureData |
19 | | -from hypothesis.internal.conjecture.floats import float_to_lex |
| 18 | +from hypothesis.internal.conjecture.data import ConjectureData, ir_value_equal |
20 | 19 | from hypothesis.internal.floats import SIGNALING_NAN, SMALLEST_SUBNORMAL |
21 | 20 |
|
22 | | -from tests.conjecture.common import ( |
23 | | - boolean_kwargs, |
24 | | - bytes_kwargs, |
25 | | - float_kwargs, |
26 | | - fresh_data, |
27 | | - integer_kwargs, |
28 | | - string_kwargs, |
29 | | -) |
| 21 | +from tests.conjecture.common import fresh_data, ir_types_and_kwargs |
30 | 22 |
|
31 | 23 |
|
32 | 24 | @given(st.data()) |
@@ -67,105 +59,48 @@ def test_forced_many(data): |
67 | 59 | assert not many.more() |
68 | 60 |
|
69 | 61 |
|
70 | | -@example({"p": 1e-19, "forced": True}) # 64 bit p |
71 | | -@example({"p": 3e-19, "forced": True}) # 62 bit p |
72 | | -@given(boolean_kwargs(use_forced=True)) |
73 | | -def test_forced_boolean(kwargs): |
74 | | - forced = kwargs["forced"] |
75 | | - |
76 | | - data = fresh_data() |
77 | | - assert data.draw_boolean(**kwargs) == forced |
78 | | - |
79 | | - # now make sure the written buffer reproduces the forced value, even without |
80 | | - # specifying forced=. |
81 | | - del kwargs["forced"] |
82 | | - data = ConjectureData.for_buffer(data.buffer) |
83 | | - assert data.draw_boolean(**kwargs) == forced |
84 | | - |
85 | | - |
86 | | -@settings(derandomize=True) |
87 | | -@given(integer_kwargs(use_forced=True)) |
88 | | -def test_forced_integer(kwargs): |
89 | | - forced = kwargs["forced"] |
90 | | - |
91 | | - data = fresh_data() |
92 | | - assert data.draw_integer(**kwargs) == forced |
93 | | - |
94 | | - del kwargs["forced"] |
95 | | - data = ConjectureData.for_buffer(data.buffer) |
96 | | - assert data.draw_integer(**kwargs) == forced |
97 | | - |
98 | | - |
99 | | -@pytest.mark.parametrize("use_min_size", [True, False]) |
100 | | -@pytest.mark.parametrize("use_max_size", [True, False]) |
101 | | -def test_forced_string(use_min_size, use_max_size): |
102 | | - @given( |
103 | | - string_kwargs( |
104 | | - use_min_size=use_min_size, use_max_size=use_max_size, use_forced=True |
105 | | - ) |
| 62 | +@example(("boolean", {"p": 1e-19, "forced": True})) # 64 bit p |
| 63 | +@example(("boolean", {"p": 3e-19, "forced": True})) # 62 bit p |
| 64 | +@example(("float", {"forced": 0.0})) |
| 65 | +@example(("float", {"forced": -0.0})) |
| 66 | +@example(("float", {"forced": 1.0})) |
| 67 | +@example(("float", {"forced": 1.2345})) |
| 68 | +@example(("float", {"forced": SMALLEST_SUBNORMAL})) |
| 69 | +@example(("float", {"forced": -SMALLEST_SUBNORMAL})) |
| 70 | +@example(("float", {"forced": 100 * SMALLEST_SUBNORMAL})) |
| 71 | +@example(("float", {"forced": math.nan})) |
| 72 | +@example(("float", {"forced": -math.nan})) |
| 73 | +@example(("float", {"forced": SIGNALING_NAN})) |
| 74 | +@example(("float", {"forced": -SIGNALING_NAN})) |
| 75 | +@example(("float", {"forced": 1e999})) |
| 76 | +@example(("float", {"forced": -1e999})) |
| 77 | +# previously errored on our {pos, neg}_clamper logic not considering nans. |
| 78 | +@example( |
| 79 | + ( |
| 80 | + "float", |
| 81 | + {"min_value": -1 * math.inf, "max_value": -1 * math.inf, "forced": math.nan}, |
106 | 82 | ) |
107 | | - def test(kwargs): |
108 | | - forced = kwargs["forced"] |
109 | | - |
110 | | - data = fresh_data() |
111 | | - assert data.draw_string(**kwargs) == forced |
112 | | - |
113 | | - del kwargs["forced"] |
114 | | - data = ConjectureData.for_buffer(data.buffer) |
115 | | - assert data.draw_string(**kwargs) == forced |
116 | | - |
117 | | - test() |
118 | | - |
119 | | - |
120 | | -@given(st.data()) |
121 | | -def test_forced_bytes(data): |
122 | | - kwargs = data.draw(bytes_kwargs(use_forced=True)) |
123 | | - forced = kwargs["forced"] |
| 83 | +) |
| 84 | +@given(ir_types_and_kwargs(use_forced=True)) |
| 85 | +def test_forced_values(ir_type_and_kwargs): |
| 86 | + (ir_type, kwargs) = ir_type_and_kwargs |
124 | 87 |
|
125 | | - data = fresh_data() |
126 | | - assert data.draw_bytes(**kwargs) == forced |
127 | | - |
128 | | - del kwargs["forced"] |
129 | | - data = ConjectureData.for_buffer(data.buffer) |
130 | | - assert data.draw_bytes(**kwargs) == forced |
131 | | - |
132 | | - |
133 | | -@example({"forced": 0.0}) |
134 | | -@example({"forced": -0.0}) |
135 | | -@example({"forced": 1.0}) |
136 | | -@example({"forced": 1.2345}) |
137 | | -@example({"forced": SMALLEST_SUBNORMAL}) |
138 | | -@example({"forced": -SMALLEST_SUBNORMAL}) |
139 | | -@example({"forced": 100 * SMALLEST_SUBNORMAL}) |
140 | | -@example({"forced": math.nan}) |
141 | | -@example({"forced": -math.nan}) |
142 | | -@example({"forced": SIGNALING_NAN}) |
143 | | -@example({"forced": -SIGNALING_NAN}) |
144 | | -@example({"forced": 1e999}) |
145 | | -@example({"forced": -1e999}) |
146 | | -# previously errored on our {pos, neg}_clamper logic not considering nans. |
147 | | -@example({"min_value": -1 * math.inf, "max_value": -1 * math.inf, "forced": math.nan}) |
148 | | -@given(float_kwargs(use_forced=True)) |
149 | | -def test_forced_floats(kwargs): |
150 | | - # TODO intentionally avoid triggering a bug with forcing nan values |
151 | | - # while both min and max value have the opposite sign. |
152 | | - # Once we fix the aforementioned bug we can remove this intentional |
153 | | - # weakening of the test. |
154 | | - assume(not math.isnan(kwargs["forced"])) |
| 88 | + if ir_type == "float": |
| 89 | + # TODO intentionally avoid triggering a bug with forcing nan values |
| 90 | + # while both min and max value have the opposite sign. |
| 91 | + # Once we fix the aforementioned bug we can remove this intentional |
| 92 | + # weakening of the test. |
| 93 | + assume(not math.isnan(kwargs["forced"])) |
155 | 94 |
|
156 | 95 | forced = kwargs["forced"] |
157 | | - |
158 | 96 | data = fresh_data() |
159 | | - drawn = data.draw_float(**kwargs) |
160 | | - # Bitwise equality check to handle nan, snan, -nan, +0, -0, etc. |
161 | | - assert math.copysign(1, drawn) == math.copysign(1, forced) |
162 | | - assert float_to_lex(abs(drawn)) == float_to_lex(abs(forced)) |
| 97 | + assert ir_value_equal(ir_type, getattr(data, f"draw_{ir_type}")(**kwargs), forced) |
163 | 98 |
|
| 99 | + # now make sure the written buffer reproduces the forced value, even without |
| 100 | + # specifying forced=. |
164 | 101 | del kwargs["forced"] |
165 | 102 | data = ConjectureData.for_buffer(data.buffer) |
166 | | - drawn = data.draw_float(**kwargs) |
167 | | - assert math.copysign(1, drawn) == math.copysign(1, forced) |
168 | | - assert float_to_lex(abs(drawn)) == float_to_lex(abs(forced)) |
| 103 | + assert ir_value_equal(ir_type, getattr(data, f"draw_{ir_type}")(**kwargs), forced) |
169 | 104 |
|
170 | 105 |
|
171 | 106 | @pytest.mark.parametrize("sign", [1, -1]) |
|
0 commit comments