1
0
mirror of https://github.com/MikeMcl/decimal.js.git synced 2024-10-27 20:34:12 +00:00
MikeMcl_decimal.js/test/hypothesis/error_hunt.py

99 lines
2.6 KiB
Python
Raw Normal View History

2023-02-13 04:08:43 +00:00
from decimal import Decimal, getcontext
import json
import subprocess
import hypothesis
from hypothesis import given, settings
from hypothesis.strategies import decimals, integers, tuples
from mpmath import mp
2023-02-13 06:44:14 +00:00
import pytest
2023-02-13 04:08:43 +00:00
mp.prec = 500
2023-02-13 06:44:14 +00:00
getcontext().prec = 14
2023-02-13 04:08:43 +00:00
node = subprocess.Popen(
["node", "evaluate.mjs"], stdout=subprocess.PIPE, stdin=subprocess.PIPE
)
def get_decimal(func: str, args: list, config: dict):
arg = json.dumps({"func": func, "args": args, "config": config}).encode() + b"\r"
node.stdin.write(arg)
node.stdin.flush()
return Decimal(node.stdout.readline().strip().decode())
2023-02-13 06:44:14 +00:00
def assert_matches(x, mpfunc, jsfunc=None):
if jsfunc is None:
jsfunc = mpfunc
y = Decimal(str(getattr(mp, mpfunc)(x))) * Decimal("1.0")
z = get_decimal(jsfunc, [str(x)], {"precision": 14})
2023-02-13 04:08:43 +00:00
assert y == z
2023-02-13 07:18:42 +00:00
@pytest.mark.parametrize("fn", "sin cos tan atan asinh".split())
2023-02-13 06:44:14 +00:00
@given(
x=tuples(
decimals(
allow_nan=False, allow_infinity=False, min_value=-1, max_value=1, places=14
),
integers(min_value=-99, max_value=99),
).map(lambda tup: tup[0] * Decimal(10) ** tup[1])
2023-02-13 04:08:43 +00:00
)
2023-02-13 06:56:56 +00:00
@settings(max_examples=1000)
2023-02-13 06:44:14 +00:00
def test_matches(x, fn):
assert_matches(x, fn)
2023-02-13 06:56:56 +00:00
@pytest.mark.parametrize("fn", "ln log10 sqrt".split())
2023-02-13 06:44:14 +00:00
@given(
x=tuples(
decimals(
allow_nan=False,
allow_infinity=False,
min_value=1e-13,
max_value=1,
places=14,
),
integers(min_value=-99, max_value=99),
).map(lambda tup: tup[0] * Decimal(10) ** tup[1])
)
2023-02-13 06:56:56 +00:00
@settings(max_examples=1000)
2023-02-13 06:44:14 +00:00
def test_positive_domain(x, fn):
assert_matches(x, fn)
2023-02-13 04:08:43 +00:00
2023-02-13 07:18:42 +00:00
@pytest.mark.parametrize("fn", "asin acos atanh".split())
2023-02-13 06:44:14 +00:00
@given(
x=decimals(
allow_nan=False, allow_infinity=False, min_value=-1, max_value=1, places=14
)
)
2023-02-13 06:56:56 +00:00
@settings(max_examples=1000)
2023-02-13 06:44:14 +00:00
def test_inverse_trig(x, fn):
assert_matches(x, fn)
2023-02-13 06:56:56 +00:00
@pytest.mark.parametrize("fn", "sinh cosh tanh exp".split())
2023-02-13 06:44:14 +00:00
@given(
x=tuples(
decimals(
allow_nan=False, allow_infinity=False, min_value=-1, max_value=1, places=14
),
integers(min_value=-99, max_value=3),
).map(lambda tup: tup[0] * Decimal(10) ** tup[1])
)
2023-02-13 06:56:56 +00:00
@settings(max_examples=1000)
2023-02-13 06:44:14 +00:00
def test_small_domain(x, fn):
assert_matches(x, fn)
2023-02-13 07:18:42 +00:00
@given(
x=tuples(
decimals(
allow_nan=False, allow_infinity=False, min_value=1, max_value=10, places=14
),
integers(min_value=0, max_value=99),
).map(lambda tup: tup[0] * Decimal(10) ** tup[1])
)
@settings(max_examples=1000)
def test_acosh(x, fn):
assert_matches(x, 'acosh')