|
3 | 3 | Unit tests from mathics.builtin.drawing.plot |
4 | 4 | """ |
5 | 5 |
|
6 | | -from test.helper import check_evaluation |
| 6 | +from test.helper import check_evaluation, session |
7 | 7 |
|
8 | 8 | import pytest |
9 | 9 |
|
| 10 | +from mathics.core.util import print_expression_tree |
| 11 | + |
10 | 12 |
|
11 | 13 | def test__listplot(): |
12 | 14 | """tests for module builtin.drawing.plot._ListPlot""" |
@@ -201,3 +203,125 @@ def test_plot(str_expr, msgs, str_expected, fail_msg): |
201 | 203 | failure_message=fail_msg, |
202 | 204 | expected_messages=msgs, |
203 | 205 | ) |
| 206 | + |
| 207 | + |
| 208 | +# |
| 209 | +# Call plotting functions and examine the structure of the output |
| 210 | +# In case of error trees are printed with an embedded >>> marker showing location of error |
| 211 | +# |
| 212 | + |
| 213 | + |
| 214 | +def print_expression_tree_with_marker(expr): |
| 215 | + print_expression_tree(expr, marker=lambda expr: getattr(expr, "_marker", "")) |
| 216 | + |
| 217 | + |
| 218 | +def check_structure(result, expected): |
| 219 | + """Check that expected is a prefix of result at every node""" |
| 220 | + |
| 221 | + def error(msg): |
| 222 | + result._marker = "RESULT >>> " |
| 223 | + expected._marker = "EXPECTED >>> " |
| 224 | + raise AssertionError(msg) |
| 225 | + |
| 226 | + # do the heads match? |
| 227 | + if result.get_head() != expected.get_head(): |
| 228 | + error("heads don't match") |
| 229 | + |
| 230 | + # does the structure match? |
| 231 | + if hasattr(expected, "elements"): |
| 232 | + if not hasattr(result, "elements"): |
| 233 | + error("expected elements but result has none") |
| 234 | + for i, e in enumerate(expected.elements): |
| 235 | + if len(result.elements) <= i: |
| 236 | + error("result has too few elements") |
| 237 | + check_structure(result.elements[i], e) |
| 238 | + else: |
| 239 | + if str(result) != str(expected): |
| 240 | + error("leaves don't match") |
| 241 | + |
| 242 | + |
| 243 | +def eval_and_check_structure(str_expr, str_expected): |
| 244 | + expr = session.parse(str_expr) |
| 245 | + result = expr.evaluate(session.evaluation) |
| 246 | + expected = session.parse(str_expected) |
| 247 | + try: |
| 248 | + check_structure(result, expected) |
| 249 | + except AssertionError as oops: |
| 250 | + print(f"\nERROR: {oops} (error is marked with >>> below)") |
| 251 | + print("=== result:") |
| 252 | + print_expression_tree_with_marker(result) |
| 253 | + print("=== expected:") |
| 254 | + print_expression_tree_with_marker(expected) |
| 255 | + raise |
| 256 | + |
| 257 | + |
| 258 | +def test_plot3d_default(): |
| 259 | + eval_and_check_structure( |
| 260 | + """ |
| 261 | + Plot3D[ |
| 262 | + x+y, |
| 263 | + {x,0,1}, {y,0,1}, |
| 264 | + PlotPoints->{2,2}, |
| 265 | + MaxRecursion->0 |
| 266 | + ] |
| 267 | + """, |
| 268 | + """ |
| 269 | + Graphics3D[ |
| 270 | + { |
| 271 | + Polygon[{{0.0,0.0,0.0}, {0.0,0.5,0.5}, {0.5,0.0,0.5}}], |
| 272 | + Polygon[{{}}] |
| 273 | + }, |
| 274 | + AspectRatio -> 1, |
| 275 | + Axes -> True, |
| 276 | + AxesStyle -> {}, |
| 277 | + Background -> Automatic, |
| 278 | + BoxRatios -> {1, 1, 0.4}, |
| 279 | + ImageSize -> Automatic, |
| 280 | + LabelStyle -> {}, |
| 281 | + PlotRange -> Automatic, |
| 282 | + PlotRangePadding -> Automatic, |
| 283 | + TicksStyle -> {} |
| 284 | + ] |
| 285 | + """, |
| 286 | + ) |
| 287 | + |
| 288 | + |
| 289 | +def test_plot3d_nondefault(): |
| 290 | + eval_and_check_structure( |
| 291 | + """ |
| 292 | + Plot3D[ |
| 293 | + x+y, |
| 294 | + {x,0,1}, {y,0,1}, |
| 295 | + PlotPoints->{2,2}, |
| 296 | + MaxRecursion->0 |
| 297 | + AspectRatio -> 0.5, |
| 298 | + Axes -> False, |
| 299 | + AxesStyle -> {Red,Blue}, |
| 300 | + Background -> Green, |
| 301 | + BoxRatios -> {10, 10, 1}, |
| 302 | + ImageSize -> {200,200}, |
| 303 | + LabelStyle -> Red, |
| 304 | + PlotRange -> {0,1}, |
| 305 | + PlotRangePadding -> {1,2}, |
| 306 | + TicksStyle -> {Purple,White} |
| 307 | + ] |
| 308 | + """, |
| 309 | + """ |
| 310 | + Graphics3D[ |
| 311 | + { |
| 312 | + Polygon[{{0.0,0.0,0.0}, {0.0,0.5,0.5}, {0.5,0.0,0.5}}], |
| 313 | + Polygon[{{}}] |
| 314 | + }, |
| 315 | + AspectRatio -> 1, (* TODO: is not passed through apparently - or is my misunderstanding? *) |
| 316 | + Axes -> False, |
| 317 | + AxesStyle -> {RGBColor[1,0,0],RGBColor[0,0,1]}, |
| 318 | + Background -> RGBColor[0,1,0], |
| 319 | + BoxRatios -> {10, 10, 1}, |
| 320 | + ImageSize -> {200,200}, |
| 321 | + LabelStyle -> RGBColor[1,0,0], |
| 322 | + PlotRange -> {0,1}, |
| 323 | + PlotRangePadding -> {1,2}, |
| 324 | + TicksStyle -> {RGBColor[0.5,0,0.5],GrayLevel[1]} |
| 325 | + ] |
| 326 | + """, |
| 327 | + ) |
0 commit comments