Skip to content

Commit 5831543

Browse files
committed
Add test for correct structure in output of Plot3D
1 parent c6e5d28 commit 5831543

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

mathics/core/util.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,23 @@ def subranges(
113113
items[start : start + length],
114114
(items[:start], items[start + length :]),
115115
)
116+
117+
118+
def print_expr_tree(expr, indent=1):
119+
"""Print a Mathics Expression as an indented tree"""
120+
if not hasattr(expr, "elements"):
121+
print(" " * indent + str(expr))
122+
else:
123+
print(" " * indent + str(expr.head))
124+
for elt in expr.elements:
125+
print_expr_tree(elt, indent + 1)
126+
127+
128+
def print_sympy_tree(expr, indent=""):
129+
"""Print a SymPy Expression as an indented tree"""
130+
if expr.args:
131+
print(f"{indent}{expr.func.__name__}")
132+
for i, arg in enumerate(expr.args):
133+
print_sympy_tree(arg, indent + " ")
134+
else:
135+
print(f"{indent}{expr.func.__name__}({str(expr)})")

test/builtin/drawing/test_plot.py

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
Unit tests from mathics.builtin.drawing.plot
44
"""
55

6-
from test.helper import check_evaluation
6+
from mathics.core.util import print_expr_tree
7+
from test.helper import check_evaluation, session
78

89
import pytest
910

@@ -201,3 +202,102 @@ def test_plot(str_expr, msgs, str_expected, fail_msg):
201202
failure_message=fail_msg,
202203
expected_messages=msgs,
203204
)
205+
206+
#
207+
# Call plotting functions and examine the structure of the output
208+
# TODO: check_structure is a little fragile and a little hard to debug. Imrovements:
209+
# some indication of where in the structure the error is occurring - e.g. tree coordinates?
210+
#
211+
#
212+
213+
214+
def check_structure(result, expected):
215+
"""Check that expected is a prefix of result at every node"""
216+
#print_expr_tree(result)
217+
#print_expr_tree(expected)
218+
assert result.get_head() == expected.get_head(), "heads must match"
219+
assert hasattr(result, "elements") == hasattr(expected, "elements"), "either both or none must have elements"
220+
if hasattr(expected, "elements"):
221+
for i, e in enumerate(expected.elements):
222+
assert len(result.elements) > i, f"expected at least {i} elements, found only {len(result.elements)}"
223+
check_structure(result.elements[i], e)
224+
else:
225+
assert str(result) == str(expected), f"leaves don't match"
226+
227+
228+
@pytest.mark.parametrize(
229+
("str_expr", "str_expected"),
230+
[
231+
# Plot3D, all default options
232+
(
233+
"""
234+
Plot3D[
235+
x+y,
236+
{x,0,1}, {y,0,1},
237+
PlotPoints->{2,2},
238+
MaxRecursion->0
239+
]
240+
""", """
241+
Graphics3D[
242+
{
243+
Polygon[{{0.0,0.0,0.0}, {0.0,0.5,0.5}, {0.5,0.0,0.5}}],
244+
Polygon[{{}}]
245+
},
246+
AspectRatio -> 1,
247+
Axes -> True,
248+
AxesStyle -> {},
249+
Background -> Automatic,
250+
BoxRatios -> {1, 1, 0.4},
251+
ImageSize -> Automatic,
252+
LabelStyle -> {},
253+
PlotRange -> Automatic,
254+
PlotRangePadding -> Automatic,
255+
TicksStyle -> {}
256+
]
257+
"""
258+
),
259+
# Plot3D, all non-default options
260+
(
261+
"""
262+
Plot3D[
263+
x+y,
264+
{x,0,1}, {y,0,1},
265+
PlotPoints->{2,2},
266+
MaxRecursion->0
267+
AspectRatio -> 0.5,
268+
Axes -> False,
269+
AxesStyle -> {Red,Blue},
270+
Background -> Green,
271+
BoxRatios -> {10, 10, 1},
272+
ImageSize -> {200,200},
273+
LabelStyle -> Red,
274+
PlotRange -> {0,1},
275+
PlotRangePadding -> {1,2},
276+
TicksStyle -> {Purple,White}
277+
]
278+
""", """
279+
Graphics3D[
280+
{
281+
Polygon[{{0.0,0.0,0.0}, {0.0,0.5,0.5}, {0.5,0.0,0.5}}],
282+
Polygon[{{}}]
283+
},
284+
AspectRatio -> 1, (* TODO: is not passed through apparently - or is my misunderstanding? *)
285+
Axes -> False,
286+
AxesStyle -> {RGBColor[1,0,0],RGBColor[0,0,1]},
287+
Background -> RGBColor[0,1,0],
288+
BoxRatios -> {10, 10, 1},
289+
ImageSize -> {200,200},
290+
LabelStyle -> RGBColor[1,0,0],
291+
PlotRange -> {0,1},
292+
PlotRangePadding -> {1,2},
293+
TicksStyle -> {RGBColor[0.5,0,0.5],GrayLevel[1]}
294+
]
295+
"""
296+
),
297+
]
298+
)
299+
def test_plot_structure(str_expr, str_expected):
300+
expr = session.parse(str_expr)
301+
result = expr.evaluate(session.evaluation)
302+
expected = session.parse(str_expected)
303+
check_structure(result, expected)

0 commit comments

Comments
 (0)