#!/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__)])