from pathlib import Path from types import SimpleNamespace from unittest import TestCase from unittest.mock import Mock import tempfile import numpy as np from pipeline import MeasurementPipeline class CombinedContourRetentionTest(TestCase): def make_pipeline(self, root: Path) -> MeasurementPipeline: mesh = root / "mesh.ply" pointcloud = root / "points.ply" mesh.touch() pointcloud.touch() pipeline = MeasurementPipeline.__new__(MeasurementPipeline) pipeline._resolve_contour_task_inputs = Mock(return_value=[{ "task_id": "1", "sample_id": "sample", "cad_path": None, "mesh_path": mesh, "pointcloud_path": pointcloud, }]) pipeline._contour_task_save_path = Mock(return_value=root / "sample_contour.ply") pipeline.run_contour = Mock(return_value={ "distance_stats": SimpleNamespace(max=0.5), "distances": np.array([0.1, 0.2]), "pointcloud": object(), }) pipeline._contour_combined_save_path = Mock(return_value=root / "combined_contour.ply") pipeline._save_contour_combined_pointcloud_stream = Mock() pipeline._should_visualize = Mock(return_value=False) return pipeline def test_skips_combined_file_when_disabled(self) -> None: with tempfile.TemporaryDirectory() as temp: pipeline = self.make_pipeline(Path(temp)) result = pipeline.run_contour_batch( all_tasks=True, save_path=temp, save_combined_visualization=False, no_visualize=True, ) self.assertIsNone(result["combined_visualization_output"]) pipeline._save_contour_combined_pointcloud_stream.assert_not_called() def test_keeps_backward_compatible_combined_file_when_enabled(self) -> None: with tempfile.TemporaryDirectory() as temp: pipeline = self.make_pipeline(Path(temp)) result = pipeline.run_contour_batch( all_tasks=True, save_path=temp, save_combined_visualization=True, no_visualize=True, ) self.assertEqual(result["combined_visualization_output"], Path(temp) / "combined_contour.ply") pipeline._save_contour_combined_pointcloud_stream.assert_called_once()