166 lines
4.6 KiB
Python
166 lines
4.6 KiB
Python
import pytest
|
|
from rest_framework.exceptions import ValidationError
|
|
|
|
from toolbox.engine import calculate, parse_expression
|
|
|
|
|
|
def test_calculate_精确计算与微积分():
|
|
exact = calculate({"operation": "calculate", "expression": "sqrt(2) + 1/3"})
|
|
derivative = calculate(
|
|
{"operation": "derivative", "expression": "sin(x) + x^3", "variable": "x"}
|
|
)
|
|
integral = calculate(
|
|
{
|
|
"operation": "integral",
|
|
"expression": "x^2",
|
|
"variable": "x",
|
|
"lower": "0",
|
|
"upper": "3",
|
|
}
|
|
)
|
|
|
|
assert exact["result"]["exact"] == "1/3 + sqrt(2)"
|
|
assert derivative["result"]["exact"] == "3*x**2 + cos(x)"
|
|
assert integral["result"]["exact"] == "9"
|
|
|
|
|
|
def test_calculate_方程矩阵统计与进制():
|
|
solved = calculate({"operation": "solve", "expression": "x^2 - 5*x + 6 = 0"})
|
|
determinant = calculate({"operation": "matrix_det", "expression": "1,2;3,4"})
|
|
statistics = calculate({"operation": "statistics", "expression": "1,2,3,4"})
|
|
converted = calculate(
|
|
{"operation": "base", "expression": "FF", "from_base": 16, "to_base": 2}
|
|
)
|
|
units = calculate(
|
|
{
|
|
"operation": "unit",
|
|
"expression": "1.75",
|
|
"from_unit": "m",
|
|
"to_unit": "cm",
|
|
}
|
|
)
|
|
combinations = calculate({"operation": "calculate", "expression": "binomial(10, 3)"})
|
|
|
|
assert [item["exact"] for item in solved["result"]] == ["2", "3"]
|
|
assert determinant["result"]["exact"] == "-2"
|
|
assert statistics["result"]["mean"] == 2.5
|
|
assert converted["result"]["exact"] == "11111111"
|
|
assert units["result"]["exact"] == "175 cm"
|
|
assert combinations["result"]["exact"] == "120"
|
|
|
|
|
|
def test_calculate_高级微积分与多元分析():
|
|
series = calculate(
|
|
{
|
|
"operation": "series",
|
|
"expression": "exp(x)",
|
|
"variable": "x",
|
|
"point": "0",
|
|
"order": 5,
|
|
}
|
|
)
|
|
gradient = calculate(
|
|
{
|
|
"operation": "gradient",
|
|
"expression": "x^2*y + sin(y)",
|
|
"variables": "x,y",
|
|
}
|
|
)
|
|
hessian = calculate(
|
|
{
|
|
"operation": "hessian",
|
|
"expression": "x^2 + x*y + y^2",
|
|
"variables": "x,y",
|
|
}
|
|
)
|
|
roots = calculate(
|
|
{
|
|
"operation": "polynomial_roots",
|
|
"expression": "x^3 - 1 = 0",
|
|
"variable": "x",
|
|
}
|
|
)
|
|
|
|
assert "x**4/24" in series["result"]["exact"]
|
|
assert gradient["result"]["exact"] == "[[2*x*y], [x**2 + cos(y)]]"
|
|
assert hessian["result"]["exact"] == "[[2, 1], [1, 2]]"
|
|
assert len(roots["result"]) == 3
|
|
|
|
|
|
def test_calculate_线性代数与方程组():
|
|
system = calculate(
|
|
{
|
|
"operation": "solve_system",
|
|
"expression": "x + y = 5; x - y = 1",
|
|
"variables": "x,y",
|
|
}
|
|
)
|
|
rank = calculate(
|
|
{"operation": "matrix_rank", "expression": "1,2,3;2,4,6"}
|
|
)
|
|
nullspace = calculate(
|
|
{"operation": "matrix_nullspace", "expression": "1,2;2,4"}
|
|
)
|
|
eigenvalues = calculate(
|
|
{"operation": "matrix_eigenvalues", "expression": "2,0;0,3"}
|
|
)
|
|
|
|
assert system["result"][0]["x"]["exact"] == "3"
|
|
assert system["result"][0]["y"]["exact"] == "2"
|
|
assert rank["result"]["exact"] == "1"
|
|
assert nullspace["result"][0]["exact"] == "[[-2], [1]]"
|
|
assert set(eigenvalues["result"]) == {"2", "3"}
|
|
|
|
|
|
def test_calculate_统计包含四分位数与极差():
|
|
result = calculate(
|
|
{"operation": "statistics", "expression": "1,2,3,4,5"}
|
|
)["result"]
|
|
|
|
assert result["sum"] == 15
|
|
assert result["q1"] == 2
|
|
assert result["q3"] == 4
|
|
assert result["range"] == 4
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("payload", "field"),
|
|
[
|
|
(
|
|
{
|
|
"operation": "series",
|
|
"expression": "exp(x)",
|
|
"order": "not-an-integer",
|
|
},
|
|
"order",
|
|
),
|
|
(
|
|
{
|
|
"operation": "polynomial_roots",
|
|
"expression": "x + y",
|
|
"variable": "x",
|
|
},
|
|
"expression",
|
|
),
|
|
],
|
|
)
|
|
def test_calculate_高级操作返回可读校验错误(payload, field):
|
|
with pytest.raises(ValidationError) as exc_info:
|
|
calculate(payload)
|
|
|
|
assert field in exc_info.value.detail
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"source",
|
|
[
|
|
"__import__('os').system('id')",
|
|
"open('/etc/passwd')",
|
|
"x.__class__",
|
|
"[x for x in range(10)]",
|
|
],
|
|
)
|
|
def test_parse_expression_拒绝非数学语法(source):
|
|
with pytest.raises(ValidationError):
|
|
parse_expression(source)
|