File size: 2,974 Bytes
ef30000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Tests for core/validator.py — CNC manufacturability validation.

These tests require CadQuery to be installed.
"""

import pytest
from core.executor import execute_cadquery
from core.validator import validate_for_cnc, CNCValidationResult, CNCIssue

pytestmark = pytest.mark.requires_cadquery


def _make_solid(code: str):
    """Helper to create a CadQuery Workplane from code."""
    result = execute_cadquery(code)
    assert result.success, f"Code failed: {result.error}"
    return result.result


class TestValidateForCnc:
    def test_simple_box_is_machinable(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid, "test_box")
        assert val.machinable is True
        assert val.error_count == 0

    def test_result_has_part_name(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid, "my_part")
        assert val.part_name == "my_part"

    def test_axis_recommendation_default_3axis(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid)
        assert "3-axis" in val.axis_recommendation or "3" in val.axis_recommendation

    def test_complex_part_gets_higher_axis(self):
        code = '''
result = cq.Workplane('XY').box(50, 50, 50)
for i in range(5):
    result = result.faces('>Z').workplane().pushPoints([(i*8-16, 0)]).hole(3)
for i in range(5):
    result = result.faces('>X').workplane().pushPoints([(i*8-16, 0)]).hole(3)
'''
        solid = _make_solid(code)
        val = validate_for_cnc(solid)
        assert val.part_name is not None

    def test_oversized_part_flagged(self):
        solid = _make_solid("result = cq.Workplane('XY').box(600, 600, 600)")
        val = validate_for_cnc(solid, config={"max_part_size_mm": 500.0})
        assert any(i.category == "Size" for i in val.issues)

    def test_tiny_part_flagged(self):
        solid = _make_solid("result = cq.Workplane('XY').box(0.5, 0.5, 0.5)")
        val = validate_for_cnc(solid, config={"min_part_size_mm": 1.0})
        assert any(i.category == "Size" for i in val.issues)

    def test_summary_format(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid, "test")
        summary = val.summary()
        assert isinstance(summary, str)
        assert "test" in summary

    def test_custom_config(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid, config={"min_wall_thickness_mm": 0.5})
        assert isinstance(val, CNCValidationResult)

    def test_error_and_warning_counts(self):
        solid = _make_solid("result = cq.Workplane('XY').box(50, 30, 10)")
        val = validate_for_cnc(solid)
        assert val.error_count >= 0
        assert val.warning_count >= 0
        assert val.error_count + val.warning_count <= len(val.issues)