Refactored the subprocess wrapper to only split the command part (first element) if it contains spaces, while preserving spaces in subsequent arguments (like file paths). Added unit tests for various scenarios including command overrides and error handling.
55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
import unittest
|
|
import os
|
|
import subprocess
|
|
from unittest.mock import patch, MagicMock
|
|
from geodata_pipeline.buildings import _run
|
|
|
|
class TestBuildingsSubprocess(unittest.TestCase):
|
|
@patch("subprocess.run")
|
|
def test_run_with_spaces_in_args(self, mock_run):
|
|
mock_run.return_value = MagicMock(returncode=0)
|
|
|
|
# This simulates a path with spaces
|
|
cmd = ["ls", "folder with space/file.txt"]
|
|
_run(cmd, "test command")
|
|
|
|
# Should stay as one argument for the path
|
|
expected_argv = ["ls", "folder with space/file.txt"]
|
|
actual_argv = mock_run.call_args[0][0]
|
|
self.assertEqual(actual_argv, expected_argv)
|
|
|
|
@patch("subprocess.run")
|
|
@patch("os.path.exists")
|
|
def test_run_with_spaces_in_command_override(self, mock_exists, mock_run):
|
|
mock_run.return_value = MagicMock(returncode=0)
|
|
mock_exists.return_value = False # Simulate "uv run cjio" is not a file
|
|
|
|
cmd = ["uv run cjio", "arg1", "path with space"]
|
|
_run(cmd, "test command")
|
|
|
|
# The command part should be split, but not the arguments
|
|
expected_argv = ["uv", "run", "cjio", "arg1", "path with space"]
|
|
actual_argv = mock_run.call_args[0][0]
|
|
self.assertEqual(actual_argv, expected_argv)
|
|
|
|
@patch("subprocess.run")
|
|
def test_run_file_not_found(self, mock_run):
|
|
mock_run.side_effect = FileNotFoundError()
|
|
|
|
cmd = ["nonexistent_tool", "arg1"]
|
|
result = _run(cmd, "test command")
|
|
|
|
self.assertFalse(result)
|
|
|
|
@patch("subprocess.run")
|
|
def test_run_failed_exit_code(self, mock_run):
|
|
mock_run.return_value = MagicMock(returncode=1)
|
|
|
|
cmd = ["ls", "nonexistent_file"]
|
|
result = _run(cmd, "test command")
|
|
|
|
self.assertFalse(result)
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|