import copy import tempfile import unittest from pathlib import Path from unittest.mock import patch import svg2gcode from optimise import get_total_distance class OptimisationTests(unittest.TestCase): def test_distance_does_not_remove_shapes(self): shapes = [[(0, 0), (1, 0)], [(4, 0), (5, 0)], [(5, 4)]] original = copy.deepcopy(shapes) self.assertEqual(get_total_distance(shapes), 7) self.assertEqual(get_total_distance(shapes), 7) self.assertEqual(shapes, original) def test_empty_and_single_shape_distance(self): self.assertEqual(get_total_distance([]), 0) self.assertEqual(get_total_distance([[(0, 0), (1, 1)]]), 0) def test_single_shape_conversion_retains_all_moves(self): with tempfile.TemporaryDirectory() as directory: output = Path(directory) / "drawing.gcode" shapes = [[(10, 20), (11, 21), (12, 22)]] with patch.object(svg2gcode, "get_shapes", return_value=shapes), \ patch.object(svg2gcode, "optimise", True): svg2gcode.main("drawing.svg", output) text = output.read_text() for x, y in ((10, 20), (11, 21), (12, 22)): self.assertIn(f"G1 X{x:.3f} Y{y:.3f}", text) self.assertTrue(text.endswith("G0 Z2\nG0 X0 Y0\n")) def test_no_shapes_is_an_explicit_error_without_output(self): with tempfile.TemporaryDirectory() as directory: output = Path(directory) / "drawing.gcode" with patch.object(svg2gcode, "get_shapes", return_value=[]): with self.assertRaisesRegex(ValueError, "no drawable SVG shapes"): svg2gcode.main("empty.svg", output) self.assertFalse(output.exists()) if __name__ == "__main__": unittest.main()