#!/usr/bin/env python3
"""Tests for scitex_writer.writer.Writer."""
from unittest.mock import MagicMock, patch
import pytest
from scitex_writer.writer import Writer
@pytest.fixture
def valid_project_structure(tmp_path):
"""Create a valid writer project structure."""
(tmp_path / "00_shared").mkdir()
(tmp_path / "01_manuscript").mkdir()
(tmp_path / "02_supplementary").mkdir()
(tmp_path / "03_revision").mkdir()
(tmp_path / "scripts").mkdir()
return tmp_path
class TestWriterInitialization:
"""Tests for Writer initialization with existing project."""
def test_initializes_with_existing_project(self, valid_project_structure):
"""Verify Writer initializes with existing project."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
assert writer.project_dir == valid_project_structure
assert writer.project_name == valid_project_structure.name
def test_sets_project_name_from_directory(self, valid_project_structure):
"""Verify project_name defaults to directory name."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
assert writer.project_name == valid_project_structure.name
def test_uses_custom_project_name(self, valid_project_structure):
"""Verify custom project name is used."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure, name="custom_name")
assert writer.project_name == "custom_name"
def test_initializes_document_trees(self, valid_project_structure):
"""Verify document trees are initialized."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
assert writer.manuscript is not None
assert writer.supplementary is not None
assert writer.revision is not None
assert writer.scripts is not None
assert writer.shared is not None
class TestWriterProjectVerification:
"""Tests for Writer project structure verification."""
def test_raises_when_manuscript_missing(self, tmp_path):
"""Verify raises RuntimeError when manuscript directory is missing."""
(tmp_path / "00_shared").mkdir()
(tmp_path / "02_supplementary").mkdir()
(tmp_path / "03_revision").mkdir()
(tmp_path / "scripts").mkdir()
with patch("scitex_writer.writer._find_git_root", return_value=None):
with pytest.raises(RuntimeError, match="01_manuscript"):
Writer(tmp_path)
def test_raises_when_supplementary_missing(self, tmp_path):
"""Verify raises RuntimeError when supplementary directory is missing."""
(tmp_path / "00_shared").mkdir()
(tmp_path / "01_manuscript").mkdir()
(tmp_path / "03_revision").mkdir()
(tmp_path / "scripts").mkdir()
with patch("scitex_writer.writer._find_git_root", return_value=None):
with pytest.raises(RuntimeError, match="02_supplementary"):
Writer(tmp_path)
def test_raises_when_revision_missing(self, tmp_path):
"""Verify raises RuntimeError when revision directory is missing."""
(tmp_path / "00_shared").mkdir()
(tmp_path / "01_manuscript").mkdir()
(tmp_path / "02_supplementary").mkdir()
(tmp_path / "scripts").mkdir()
with patch("scitex_writer.writer._find_git_root", return_value=None):
with pytest.raises(RuntimeError, match="03_revision"):
Writer(tmp_path)
class TestWriterGetPdf:
"""Tests for Writer.get_pdf method."""
def test_returns_none_when_pdf_missing(self, valid_project_structure):
"""Verify returns None when PDF doesn't exist."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
assert writer.get_pdf("manuscript") is None
def test_returns_path_when_pdf_exists(self, valid_project_structure):
"""Verify returns Path when PDF exists."""
pdf_path = valid_project_structure / "01_manuscript" / "manuscript.pdf"
pdf_path.write_bytes(b"%PDF-1.4")
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
result = writer.get_pdf("manuscript")
assert result == pdf_path
def test_returns_supplementary_pdf(self, valid_project_structure):
"""Verify returns supplementary PDF path."""
pdf_path = valid_project_structure / "02_supplementary" / "supplementary.pdf"
pdf_path.write_bytes(b"%PDF-1.4")
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
result = writer.get_pdf("supplementary")
assert result == pdf_path
class TestWriterDelete:
"""Tests for Writer.delete method."""
def test_deletes_project_directory(self, valid_project_structure):
"""Verify delete removes project directory."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
result = writer.delete()
assert result is True
assert not valid_project_structure.exists()
def test_delete_returns_false_on_error(self, valid_project_structure):
"""Verify delete returns False on error."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
with patch("shutil.rmtree", side_effect=PermissionError("Access denied")):
result = writer.delete()
assert result is False
class TestWriterCompileMethods:
"""Tests for Writer compilation methods."""
def test_compile_manuscript_calls_function(self, valid_project_structure):
"""Verify compile_manuscript calls the compile function."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
Writer(valid_project_structure) # Verify initialization works
mock_result = MagicMock()
with patch(
"scitex_writer.writer.compile_manuscript",
return_value=mock_result,
) as mock_compile:
result = mock_compile(
valid_project_structure,
timeout=300,
log_callback=None,
progress_callback=None,
)
assert result == mock_result
def test_compile_supplementary_calls_function(self, valid_project_structure):
"""Verify compile_supplementary calls the compile function."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
Writer(valid_project_structure) # Verify initialization works
mock_result = MagicMock()
with patch(
"scitex_writer.writer.compile_supplementary",
return_value=mock_result,
) as mock_compile:
result = mock_compile(
valid_project_structure,
timeout=300,
log_callback=None,
progress_callback=None,
)
assert result == mock_result
def test_compile_revision_calls_function(self, valid_project_structure):
"""Verify compile_revision calls the compile function."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
Writer(valid_project_structure) # Verify initialization works
mock_result = MagicMock()
with patch(
"scitex_writer.writer.compile_revision",
return_value=mock_result,
) as mock_compile:
result = mock_compile(
valid_project_structure,
track_changes=False,
timeout=300,
log_callback=None,
progress_callback=None,
)
assert result == mock_result
class TestWriterWatch:
"""Tests for Writer.watch method."""
def test_watch_calls_watch_manuscript(self, valid_project_structure):
"""Verify watch calls watch_manuscript function."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
callback = MagicMock()
with patch("scitex_writer.writer.watch_manuscript") as mock_watch:
writer.watch(on_compile=callback)
mock_watch.assert_called_once_with(
valid_project_structure, on_compile=callback
)
class TestWriterGitStrategy:
"""Tests for Writer git_strategy parameter."""
def test_default_git_strategy_is_child(self, valid_project_structure):
"""Verify default git_strategy is 'child'."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure)
assert writer.git_strategy == "child"
def test_custom_git_strategy(self, valid_project_structure):
"""Verify custom git_strategy is set."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure, git_strategy="parent")
assert writer.git_strategy == "parent"
def test_git_strategy_none(self, valid_project_structure):
"""Verify git_strategy=None is allowed."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure, git_strategy=None)
assert writer.git_strategy is None
class TestWriterBranchTag:
"""Tests for Writer branch and tag parameters."""
def test_branch_parameter(self, valid_project_structure):
"""Verify branch parameter is stored."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure, branch="develop")
assert writer.branch == "develop"
def test_tag_parameter(self, valid_project_structure):
"""Verify tag parameter is stored."""
with patch("scitex_writer.writer._find_git_root", return_value=None):
writer = Writer(valid_project_structure, tag="v1.0.0")
assert writer.tag == "v1.0.0"
if __name__ == "__main__":
import os
import pytest
pytest.main([os.path.abspath(__file__)])