test_build.py•5.29 kB
"""
Unit tests for the build.py script module.
"""
import os
import sys
import pytest
from unittest.mock import patch, MagicMock, call, ANY
from pathlib import Path
import subprocess
import shutil
from chroma_mcp.dev_scripts.build import run_command, main, get_project_root
class TestBuildScript:
"""Test cases for the build.py script module."""
@patch("subprocess.run")
def test_run_command(self, mock_subprocess_run):
"""Test the run_command helper function."""
mock_subprocess_run.return_value = MagicMock(returncode=0)
# Call the function
result = run_command(["echo", "test"])
# Check the result
assert result == 0
mock_subprocess_run.assert_called_once_with(["echo", "test"], cwd=None)
@patch("subprocess.run")
@patch("chroma_mcp.dev_scripts.build.run_command")
@patch("chroma_mcp.dev_scripts.build.shutil.rmtree")
@patch("pathlib.Path.exists")
@patch("chroma_mcp.dev_scripts.build.get_project_root")
def test_build_success(
self, mock_get_project_root, mock_exists, mock_rmtree, mock_run_command, mock_subprocess_run
):
"""Test successful build execution."""
# Set up mocks
mock_project_root = MagicMock(spec=Path)
mock_get_project_root.return_value = mock_project_root
# Mock Path.exists to return True for cleanup paths
mock_exists.return_value = True
# Mock subprocess.run for hatch check
mock_subprocess_run.return_value = MagicMock(returncode=0)
# Mock run_command to succeed for all commands
mock_run_command.return_value = 0
# Call the main function
result = main()
# Check the result
assert result == 0
# Check that cleanup was called for dist and build directories
assert mock_rmtree.call_count >= 1
# Verify that hatch build was called
assert any(
"hatch" in str(call_args) and "build" in str(call_args) for call_args in mock_run_command.call_args_list
)
# Verify that black formatting was called
assert any("black" in str(call_args) for call_args in mock_run_command.call_args_list)
@patch("subprocess.run")
@patch("chroma_mcp.dev_scripts.build.run_command")
@patch("chroma_mcp.dev_scripts.build.shutil.rmtree")
@patch("pathlib.Path.exists")
@patch("chroma_mcp.dev_scripts.build.get_project_root")
@patch("sys.executable", "/path/to/python")
def test_build_hatch_not_installed(
self, mock_get_project_root, mock_exists, mock_rmtree, mock_run_command, mock_subprocess_run
):
"""Test build when hatch is not installed."""
# Set up mocks
mock_project_root = MagicMock(spec=Path)
mock_get_project_root.return_value = mock_project_root
# Mock Path.exists to return True for cleanup paths
mock_exists.return_value = True
# Mock subprocess.run to raise FileNotFoundError for hatch check
mock_subprocess_run.side_effect = FileNotFoundError("No such file or directory: 'hatch'")
# Mock run_command to succeed for pip install but fail for hatch build
def run_command_side_effect(cmd, cwd=None):
if cmd[0] == "/path/to/python" and "-m" in cmd and "pip" in cmd and "install" in cmd:
return 0 # Success for pip install
else:
return 1 # Failure for other commands
mock_run_command.side_effect = run_command_side_effect
# Call the main function
result = main()
# Check the result - should be failure since hatch build failed
assert result == 1
# Print the actual calls to debug
for i, args in enumerate(mock_run_command.call_args_list):
cmd, kwargs = args
print(f"Call {i+1}: {cmd}, {kwargs}")
# Just test that run_command was called at all
assert mock_run_command.call_count > 0
@patch("subprocess.run")
@patch("chroma_mcp.dev_scripts.build.run_command")
@patch("chroma_mcp.dev_scripts.build.shutil.rmtree")
@patch("pathlib.Path.exists")
@patch("chroma_mcp.dev_scripts.build.get_project_root")
def test_build_command_failure(
self, mock_get_project_root, mock_exists, mock_rmtree, mock_run_command, mock_subprocess_run
):
"""Test build when a command fails."""
# Set up mocks
mock_project_root = MagicMock(spec=Path)
mock_get_project_root.return_value = mock_project_root
# Mock Path.exists to return True for cleanup paths
mock_exists.return_value = True
# Mock subprocess.run for hatch check
mock_subprocess_run.return_value = MagicMock(returncode=0)
# Mock run_command to succeed for black but fail for hatch build
def run_command_side_effect(cmd, cwd=None):
if "black" in cmd:
return 0 # Success for black
elif "hatch" in cmd and "build" in cmd:
return 1 # Failure for hatch build
return 0
mock_run_command.side_effect = run_command_side_effect
# Call the main function
result = main()
# Check the result - should be failure since hatch build failed
assert result == 1