"""Tests for devx.tools.check_doc_versions.""" from __future__ import annotations from pathlib import Path from click.testing import CliRunner import devx.tools.check_doc_versions as cdv class TestDetectPackageName: def test_finds_package(self, tmp_path: Path) -> None: src = tmp_path / "src" / "myproj" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "1.0.0"\n') assert cdv.detect_package_name(tmp_path) == "myproj" def test_no_src_dir(self, tmp_path: Path) -> None: assert cdv.detect_package_name(tmp_path) is None def test_no_init_py(self, tmp_path: Path) -> None: src = tmp_path / "src" / "myproj" src.mkdir(parents=True) assert cdv.detect_package_name(tmp_path) is None class TestReadVersion: def test_reads_version(self, tmp_path: Path) -> None: src = tmp_path / "src" / "myproj" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "2.3.4"\n') assert cdv.read_version(tmp_path, "myproj") == "2.3.4" def test_no_version(self, tmp_path: Path) -> None: src = tmp_path / "src" / "myproj" src.mkdir(parents=True) (src / "__init__.py").write_text("# no version here\n") assert cdv.read_version(tmp_path, "myproj") is None def test_no_init_file(self, tmp_path: Path) -> None: assert cdv.read_version(tmp_path, "nonexistent") is None class TestFindVersionRefs: def test_finds_gte_ref(self) -> None: content = ' "devx>=0.27.0",\n' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 1 _, full, op, ver, _ = refs[0] assert op == ">=" assert ver == "0.27.0" def test_finds_eq_ref(self) -> None: content = '"devx==0.33.4"' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 1 _, _, op, ver, _ = refs[0] assert op == "==" assert ver == "0.33.4" def test_finds_extras_ref(self) -> None: content = '"devx[dev]>=0.27.0"' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 1 _, _, op, ver, _ = refs[0] assert op == ">=" assert ver == "0.27.0" def test_finds_upper_bound(self) -> None: content = '"devx>=0.27.0,<0.28"' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 1 _, _, _, _, rest = refs[0] assert "<0.28" in rest def test_ignores_other_packages(self) -> None: content = '"other-pkg>=1.0.0"' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 0 def test_multiple_refs(self) -> None: content = '"devx>=0.27.0"\n"devx==0.33.4"\n' refs = cdv.find_version_refs(content, "devx") assert len(refs) == 2 class TestFixVersionRefs: def test_fixes_stale_version(self) -> None: content = '"devx>=0.27.0"' new, fixes = cdv.fix_version_refs(content, "devx", "0.33.4") assert fixes == 1 assert "0.33.4" in new assert "0.27.0" not in new def test_no_fix_needed(self) -> None: content = '"devx>=0.33.4"' new, fixes = cdv.fix_version_refs(content, "devx", "0.33.4") assert fixes == 0 assert new == content def test_fixes_upper_bound(self) -> None: content = '"devx>=0.27.0,<0.28"' new, fixes = cdv.fix_version_refs(content, "devx", "0.33.4") assert fixes == 1 assert "0.33.4" in new assert "<0.34" in new assert "<0.28" not in new def test_ignores_other_packages(self) -> None: content = '"other>=1.0.0"' new, fixes = cdv.fix_version_refs(content, "devx", "0.33.4") assert fixes == 0 assert new == content class TestMain: def test_pass_when_current(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.33.4"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 0 assert "PASS" in result.output def test_fail_when_stale(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.27.0"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 1 assert "stale" in result.output def test_fix_updates_files(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.27.0"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path), "--fix"]) assert result.exit_code == 0 assert "0.33.4" in readme.read_text() def test_no_package_skips(self, tmp_path: Path) -> None: runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 0 assert "skipping" in result.output def test_no_version_skips(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text("# no version\n") runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 0 assert "Cannot read" in result.output def test_docs_only_skips_readme(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.27.0"\n') docs = tmp_path / "docs" docs.mkdir() (docs / "index.md").write_text('"devx>=0.33.4"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path), "--docs-only"]) assert result.exit_code == 0 assert "PASS" in result.output def test_fix_no_stale(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.33.4"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path), "--fix"]) assert result.exit_code == 0 assert "No stale" in result.output def test_checks_docs_dir(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') docs = tmp_path / "docs" docs.mkdir() (docs / "index.md").write_text('"devx>=0.27.0"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 1 assert "docs/index.md" in result.output def test_detect_package_with_non_dir_entry(self, tmp_path: Path) -> None: src = tmp_path / "src" src.mkdir(parents=True) # `aaa_file.py` sorts before `devx/` so the non-dir branch is hit (src / "aaa_file.py").touch() pkg_dir = src / "devx" pkg_dir.mkdir() (pkg_dir / "__init__.py").write_text('__version__ = "1.0.0"\n') assert cdv.detect_package_name(tmp_path) == "devx" def test_read_version_auto_detect(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "3.2.1"\n') assert cdv.read_version(tmp_path) == "3.2.1" def test_read_version_no_package(self, tmp_path: Path) -> None: assert cdv.read_version(tmp_path) is None def test_main_with_file_without_refs(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') docs = tmp_path / "docs" docs.mkdir() (docs / "index.md").write_text("# No version refs here\n") (docs / "other.md").write_text('"devx>=0.27.0"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path)]) assert result.exit_code == 1 assert "other.md" in result.output def test_fix_with_file_without_refs(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text("# No refs\n") runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path), "--fix"]) assert result.exit_code == 0 assert "No stale" in result.output def test_fix_with_current_refs(self, tmp_path: Path) -> None: src = tmp_path / "src" / "devx" src.mkdir(parents=True) (src / "__init__.py").write_text('__version__ = "0.33.4"\n') readme = tmp_path / "README.md" readme.write_text('"devx>=0.33.4"\n') runner = CliRunner() result = runner.invoke(cdv.main, ["--root", str(tmp_path), "--fix"]) assert result.exit_code == 0 assert "No stale" in result.output