File size: 3,887 Bytes
fe0c99f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from __future__ import annotations

from core.extractor import ExpressionExtractor


def test_extract_fraction_derivative_and_order():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\frac{d^5}{dx^5} x^3")
    assert inner == "x^3"
    assert params["variable"] == "x"
    assert params["order"] == 5


def test_extract_plain_derivative_notation():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract("d^2/dx^2 sin(x)")
    assert inner == "sin(x)"
    assert params["variable"] == "x"
    assert params["order"] == 2


def test_extract_definite_integral_and_bounds():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\int_{0}^{1} x^2 dx")
    assert inner == "x^2"
    assert params["lower"] == 0
    assert params["upper"] == 1
    assert params["variable"] == "x"


def test_extract_limit_plain_text_arrow_unicode():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract("lim_(x → ∞) (1+(1)/(x))^x")
    assert inner == "(1+(1)/(x))^x"
    assert params["variable"] == "x"
    assert params["point"] == "∞"


def test_extract_returns_original_when_no_wrapper_found():
    extractor = ExpressionExtractor()
    latex = "x^2 + 3x + 2"
    inner, params = extractor.extract(latex, params={"variable": "x"})
    assert inner == latex
    assert params["variable"] == "x"


def test_parse_bound_infinity_tokens():
    assert ExpressionExtractor._parse_bound(r"\infty") == "oo"
    assert ExpressionExtractor._parse_bound(r"-\infty") == "-oo"
    assert ExpressionExtractor._parse_bound("2.5") == 2.5


def test_extract_partial_derivative_branch():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\frac{\partial^2}{\partial x^2} (x^2 y)")
    assert inner == "(x^2 y)"
    assert params["variable"] == "x"
    assert params["order"] == 2


def test_extract_prime_notation_branch():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract("y''(t)")
    assert inner == "y''(t)"
    assert params["variable"] == "t"
    assert params["order"] == 2


def test_extract_definite_integral_non_braced_pattern():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\int_0^1 x^2 dx")
    assert inner == "x^2"
    assert params["lower"] == 0
    assert params["upper"] == 1
    assert params["variable"] == "x"


def test_extract_plain_integral_patterns():
    extractor = ExpressionExtractor()
    inner1, p1 = extractor.extract("int_0^2 x dx")
    assert inner1 == "x"
    assert p1["lower"] == 0 and p1["upper"] == 2 and p1["variable"] == "x"

    inner2, p2 = extractor.extract("∫ x^2 dx")
    assert inner2 == "x^2"
    assert p2["variable"] == "x"


def test_extract_limit_latex_and_plain_variants():
    extractor = ExpressionExtractor()
    inner1, p1 = extractor.extract(r"\lim_{x \to 0} \frac{\sin x}{x}")
    assert p1["variable"] == "x" and p1["point"] == "0"
    assert inner1 == r"\frac{\sin x}{x}"

    inner2, p2 = extractor.extract("lim x->0 sin(x)/x")
    assert p2["variable"] == "x" and p2["point"] == "0"
    assert inner2 == "sin(x)/x"

    inner3, p3 = extractor.extract("lim x to 0 sin(x)/x")
    assert p3["variable"] == "x" and p3["point"] == "0"
    assert inner3 == "sin(x)/x"


def test_extract_sum_branch():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\sum_{n=1}^{10} n^2")
    assert "n^2" in inner
    assert params["variable"] == "n"
    assert params["lower"] == 1
    # Current extractor regex does not capture upper bound robustly for this form.
    # Keep this as a branch-coverage regression guard.
    assert "upper" in params


def test_extract_indefinite_integral_latex_branch():
    extractor = ExpressionExtractor()
    inner, params = extractor.extract(r"\int x^3 dx")
    assert inner == "x^3"
    assert params["variable"] == "x"