RA.Aid/tests/test_project_state.py

151 lines
4.5 KiB
Python

"""Tests for project state detection functionality."""
import os
import pytest
from ra_aid.project_state import (
DirectoryAccessError,
DirectoryNotFoundError,
ProjectStateError,
is_new_project,
)
@pytest.fixture
def empty_dir(tmp_path):
"""Create an empty temporary directory."""
return tmp_path
@pytest.fixture
def git_only_dir(tmp_path):
"""Create a directory with only git files."""
git_dir = tmp_path / ".git"
git_dir.mkdir(exist_ok=True)
gitignore = tmp_path / ".gitignore"
gitignore.write_text("*.pyc\n")
return tmp_path
@pytest.fixture
def ra_aid_only_dir(tmp_path):
"""Create a directory with only a .ra-aid directory."""
ra_aid_dir = tmp_path / ".ra-aid"
ra_aid_dir.mkdir(exist_ok=True)
return tmp_path
@pytest.fixture
def mixed_allowed_dir(tmp_path):
"""Create a directory with all allowed items (.git, .gitignore, and .ra-aid)."""
git_dir = tmp_path / ".git"
git_dir.mkdir(exist_ok=True)
gitignore = tmp_path / ".gitignore"
gitignore.write_text("*.pyc\n")
ra_aid_dir = tmp_path / ".ra-aid"
ra_aid_dir.mkdir(exist_ok=True)
return tmp_path
@pytest.fixture
def project_dir(tmp_path):
"""Create a directory with some project files."""
(tmp_path / "src").mkdir()
(tmp_path / "README.md").write_text("# Test Project")
return tmp_path
def test_empty_directory(empty_dir):
"""Test that an empty directory is considered a new project."""
assert is_new_project(str(empty_dir)) is True
def test_git_only_directory(git_only_dir):
"""Test that a directory with only git files is considered a new project."""
assert is_new_project(str(git_only_dir)) is True
def test_ra_aid_only_directory(ra_aid_only_dir):
"""Test that a directory with only a .ra-aid directory is considered a new project."""
assert is_new_project(str(ra_aid_only_dir)) is True
def test_mixed_allowed_directory(mixed_allowed_dir):
"""Test that a directory with all allowed items is considered a new project."""
assert is_new_project(str(mixed_allowed_dir)) is True
@pytest.fixture
def git_dir_with_contents(tmp_path):
"""Create a directory with .git containing files and .gitignore."""
git_dir = tmp_path / ".git"
git_dir.mkdir()
# Add some files inside .git
(git_dir / "HEAD").write_text("ref: refs/heads/main")
(git_dir / "config").write_text("[core]\n\trepositoryformatversion = 0")
(git_dir / "refs").mkdir()
# Add .gitignore
gitignore = tmp_path / ".gitignore"
gitignore.write_text("*.pyc\n")
return tmp_path
def test_git_directory_with_contents(git_dir_with_contents):
"""Test that a directory is considered new even with files inside .git."""
assert is_new_project(str(git_dir_with_contents)) is True
def test_existing_project_directory(project_dir):
"""Test that a directory with project files is not considered new."""
assert is_new_project(str(project_dir)) is False
def test_nonexistent_directory():
"""Test that a non-existent directory raises appropriate error."""
with pytest.raises(DirectoryNotFoundError):
is_new_project("/nonexistent/path/123456")
def test_file_as_directory(tmp_path):
"""Test that passing a file instead of directory raises error."""
test_file = tmp_path / "test.txt"
test_file.write_text("test")
with pytest.raises(ProjectStateError):
is_new_project(str(test_file))
@pytest.mark.skipif(os.name == "nt", reason="Permission tests unreliable on Windows")
def test_permission_error(tmp_path):
"""Test handling of permission errors."""
try:
# Make directory unreadable
os.chmod(tmp_path, 0o000)
with pytest.raises(DirectoryAccessError):
is_new_project(str(tmp_path))
finally:
# Restore permissions to allow cleanup
os.chmod(tmp_path, 0o755)
def test_verify_fix(tmp_path):
"""
Verify fix: a project with only .ra-aid directory is considered new,
but adding other files makes it recognized as an existing project.
"""
# Create a .ra-aid directory inside the temporary directory
ra_aid_dir = tmp_path / ".ra-aid"
ra_aid_dir.mkdir(exist_ok=True)
# Check that is_new_project() returns True (only .ra-aid directory)
assert is_new_project(str(tmp_path)) is True
# Add a README.md file to the directory
readme_file = tmp_path / "README.md"
readme_file.write_text("# Test Project")
# Check that is_new_project() now returns False (has actual content)
assert is_new_project(str(tmp_path)) is False