import os
import shutil
import pytest
from unittest.mock import patch, MagicMock
import trimesh
import numpy as np
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from processing import create_layered_curves_dxf
ASSETS_DIR = os.path.join(os.path.dirname(__file__), "assets")
TEST_OUTPUT_DIR = os.path.join(os.path.dirname(__file__), "test_outputs")
VALID_FILE = os.path.join(ASSETS_DIR, "cube.obj")
EMPTY_FILE = os.path.join(ASSETS_DIR, "empty.obj")
@pytest.fixture(autouse=True)
def setup_and_teardown():
if os.path.exists(TEST_OUTPUT_DIR):
shutil.rmtree(TEST_OUTPUT_DIR)
os.makedirs(TEST_OUTPUT_DIR)
yield
def run_generator_to_completion(generator):
final_result = None
for result in generator:
final_result = result
return final_result
def test_happy_path_successful_processing():
output_file = os.path.join(TEST_OUTPUT_DIR, "cube.dxf")
generator = create_layered_curves_dxf(VALID_FILE, output_file, num_layers=5)
final_status = run_generator_to_completion(generator)
assert final_status["status"] == "complete"
assert os.path.exists(output_file)
@patch('trimesh.Trimesh.section', autospec=True)
def test_partial_slicing_failure_completes_with_warnings(mock_section):
output_file = os.path.join(TEST_OUTPUT_DIR, "partial.dxf")
call_counter = {"count": 0}
# FIX: Use 5+ points so scipy's splprep (m > k) doesn't fail
fake_path = MagicMock()
fake_path.discrete = [np.array([[0,0], [1,0], [1,1], [0,1], [0,0]])]
fake_planar = MagicMock()
fake_planar.discrete = fake_path.discrete
fake_section = MagicMock()
fake_section.to_planar.return_value = (fake_planar, None)
def side_effect(self, *args, **kwargs):
call_counter["count"] += 1
return fake_section if call_counter["count"] <= 3 else None
mock_section.side_effect = side_effect
generator = create_layered_curves_dxf(VALID_FILE, output_file, num_layers=10)
final_status = run_generator_to_completion(generator)
assert final_status["status"] == "complete"
assert "skipped" in final_status["message"] or "successfully" in final_status["message"]
assert os.path.exists(output_file)
@patch('trimesh.Trimesh.section', return_value=None)
def test_total_slicing_failure_fails_job(mock_section):
output_file = os.path.join(TEST_OUTPUT_DIR, "total_fail.dxf")
generator = create_layered_curves_dxf(VALID_FILE, output_file, num_layers=5)
final_status = run_generator_to_completion(generator)
assert final_status["status"] == "failed"
assert not os.path.exists(output_file)