Skip to content

Commit

Permalink
Merge pull request #910 from fischman/test-examples
Browse files Browse the repository at this point in the history
Add a new TestCase that asserts that examples exit successfully.
  • Loading branch information
gumyr authored Feb 22, 2025
2 parents aeb6b32 + 80097a9 commit 8aeee30
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
6 changes: 5 additions & 1 deletion examples/loft.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@
top_bottom = art.faces().filter_by(GeomType.PLANE)
offset(openings=top_bottom, amount=0.5)

assert abs(art.part.volume - 1306.3405290344635) < 1e-3
want = 1306.3405290344635
got = art.part.volume
delta = abs(got - want)
tolerance = want * 1e-5
assert delta < tolerance, f"{delta=} is greater than {tolerance=}; {got=}, {want=}"

show(art, names=["art"])
# [End]
5 changes: 4 additions & 1 deletion examples/packed_boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import random
import build123d as bd

GEN_DOCS = False

random.seed(123456)
test_boxes = [bd.Box(random.randint(1, 20), random.randint(1, 20), random.randint(1, 5))
for _ in range(50)]
Expand All @@ -28,7 +30,8 @@ def export_svg(parts, name):
exporter.add_layer("Hidden", line_color=(99, 99, 99), line_type=bd.LineType.ISO_DOT)
exporter.add_shape(visible, layer="Visible")
exporter.add_shape(hidden, layer="Hidden")
exporter.write(f"../docs/assets/{name}.svg")
if GEN_DOCS:
exporter.write(f"../docs/assets/{name}.svg")

export_svg(test_boxes, "packed_boxes_input")
export_svg(packed, "packed_boxes_output")
86 changes: 86 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
build123d Example tests
name: test_examples.py
by: fischman
date: February 21 2025
desc: Unit tests for the build123d examples, ensuring they don't raise.
"""

from pathlib import Path

import os
import subprocess
import sys
import tempfile
import unittest


_examples_dir = Path(os.path.abspath(os.path.dirname(__file__))).parent / "examples"

_MOCK_OCP_VSCODE_CONTENTS = """
from pathlib import Path
import re
import sys
from unittest.mock import Mock
mock_module = Mock()
mock_module.show = Mock()
mock_module.show_object = Mock()
mock_module.show_all = Mock()
sys.modules["ocp_vscode"] = mock_module
"""


def generate_example_test(path: Path):
"""Generate and return a function to test the example at `path`."""
name = path.name

def assert_example_does_not_raise(self):
with tempfile.TemporaryDirectory(
prefix=f"build123d_test_examples_{name}"
) as tmpdir:
# More examples emit output files than read input files,
# so default to running with a temporary directory to
# avoid cluttering the git working directory. For
# examples that want to read assets from the examples
# directory, use that. If an example is added in the
# future that wants to both read assets from the examples
# directory and write output files, deal with it then.
cwd = tmpdir if 'benchy' not in path.name else _examples_dir
mock_ocp_vscode = Path(tmpdir) / "_mock_ocp_vscode.py"
with open(mock_ocp_vscode, "w", encoding="utf-8") as f:
f.write(_MOCK_OCP_VSCODE_CONTENTS)
got = subprocess.run(
[
sys.executable,
"-c",
f"exec(open(r'{mock_ocp_vscode}').read()); exec(open(r'{path}').read())",
],
capture_output=True,
cwd=cwd,
check=False,
)
self.assertEqual(
0, got.returncode, f"stdout/stderr: {got.stdout} / {got.stderr}"
)

return assert_example_does_not_raise


class TestExamples(unittest.TestCase):
"""Tests build123d examples."""


for example in sorted(_examples_dir.iterdir()):
if example.name.startswith("_") or not example.name.endswith(".py"):
continue
setattr(
TestExamples,
f"test_{example.name.replace('.', '_')}",
generate_example_test(example),
)

if __name__ == "__main__":
unittest.main()

0 comments on commit 8aeee30

Please sign in to comment.