standardize packaging, tooling, docs, CI, and licensing
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge.cli.main import cli
|
||||
|
||||
|
||||
def test_mcp_build(cli_runner):
|
||||
with cli_runner.isolated_filesystem():
|
||||
cwd = Path.cwd()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge.cli.main import cli
|
||||
|
||||
|
||||
def test_mkdocs_build_full_flow(
|
||||
cli_runner,
|
||||
mock_mkdocs_build,
|
||||
@@ -17,11 +19,11 @@ def test_mkdocs_build_full_flow(
|
||||
|
||||
nav_file = cwd / "docforge.nav.yml"
|
||||
nav_file.write_text("home: testpkg/index.md\ngroups: {}\n")
|
||||
|
||||
|
||||
# We need to create a dummy testpkg/index.md for nav resolution if it's there
|
||||
# But generate_sources will create it.
|
||||
# But generate_sources will create it.
|
||||
# Wait, the current logic runs generate_sources first, THEN generate_config.
|
||||
|
||||
|
||||
result = cli_runner.invoke(
|
||||
cli,
|
||||
[
|
||||
@@ -43,11 +45,13 @@ def test_mkdocs_build_full_flow(
|
||||
assert (cwd / "mkdocs.yml").exists()
|
||||
assert (cwd / "docs" / "testpkg" / "mod.md").exists()
|
||||
|
||||
|
||||
def test_mkdocs_build_missing_module_fails(cli_runner):
|
||||
result = cli_runner.invoke(cli, ["build", "--mkdocs", "--site-name", "Test"])
|
||||
assert result.exit_code != 0
|
||||
assert "--module is required" in result.output
|
||||
|
||||
|
||||
def test_mkdocs_build_without_site_name_uses_module_as_default_full_flow(
|
||||
cli_runner,
|
||||
mock_mkdocs_build,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from docforge.cli.main import cli
|
||||
|
||||
|
||||
def test_mcp_serve(
|
||||
cli_runner,
|
||||
fake_mcp_docs,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from docforge.cli.main import cli
|
||||
|
||||
|
||||
def test_mkdocs_serve(
|
||||
cli_runner,
|
||||
fake_mkdocs_yml,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import sys
|
||||
import json
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ plugins:
|
||||
@pytest.fixture
|
||||
def mock_mkdocs_load_config(monkeypatch):
|
||||
"""Mock mkdocs.config.load_config."""
|
||||
|
||||
def fake_load_config(path):
|
||||
return object() # dummy config object
|
||||
|
||||
@@ -81,6 +82,7 @@ def mock_mkdocs_serve(monkeypatch):
|
||||
)
|
||||
return lambda: called["value"]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_mcp_docs(tmp_path: Path) -> Path:
|
||||
"""
|
||||
|
||||
@@ -2,11 +2,9 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_alias_does_not_crash(temp_package):
|
||||
(temp_package / "alias.py").write_text(
|
||||
'''from typing import List
|
||||
(temp_package / "alias.py").write_text("""from typing import List
|
||||
Alias = List[int]
|
||||
'''
|
||||
)
|
||||
""")
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.alias"])
|
||||
|
||||
@@ -2,15 +2,13 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_class_and_methods(temp_package):
|
||||
(temp_package / "cls.py").write_text(
|
||||
'''class MyClass:
|
||||
(temp_package / "cls.py").write_text('''class MyClass:
|
||||
"""Class doc."""
|
||||
|
||||
def method(self, x: int) -> int:
|
||||
"""Method doc."""
|
||||
return x
|
||||
'''
|
||||
)
|
||||
''')
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.cls"])
|
||||
|
||||
@@ -2,12 +2,10 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_function_signature(temp_package):
|
||||
(temp_package / "fn.py").write_text(
|
||||
'''def add(a: int, b: int = 1) -> int:
|
||||
(temp_package / "fn.py").write_text('''def add(a: int, b: int = 1) -> int:
|
||||
"""Adds numbers."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
''')
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.fn"])
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import pytest
|
||||
|
||||
from docforge import GriffeLoader
|
||||
|
||||
|
||||
@@ -6,9 +7,8 @@ def test_load_project_raises_on_missing_module_by_default():
|
||||
loader = GriffeLoader()
|
||||
|
||||
with pytest.raises(ImportError):
|
||||
loader.load_project(
|
||||
["nonexistent.module", "sys"]
|
||||
)
|
||||
loader.load_project(["nonexistent.module", "sys"])
|
||||
|
||||
|
||||
def test_load_project_skips_missing_modules_when_enabled():
|
||||
loader = GriffeLoader()
|
||||
@@ -18,4 +18,4 @@ def test_load_project_skips_missing_modules_when_enabled():
|
||||
skip_import_errors=True,
|
||||
)
|
||||
|
||||
assert "sys" in project.modules
|
||||
assert "sys" in project.modules
|
||||
|
||||
@@ -2,9 +2,7 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_missing_docstrings(temp_package):
|
||||
(temp_package / "nodoc.py").write_text(
|
||||
'''def f(): pass'''
|
||||
)
|
||||
(temp_package / "nodoc.py").write_text("""def f(): pass""")
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.nodoc"])
|
||||
|
||||
@@ -2,11 +2,9 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_private_members_excluded(temp_package):
|
||||
(temp_package / "priv.py").write_text(
|
||||
'''def _hidden(): pass
|
||||
(temp_package / "priv.py").write_text("""def _hidden(): pass
|
||||
def visible(): pass
|
||||
'''
|
||||
)
|
||||
""")
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.priv"])
|
||||
|
||||
@@ -2,13 +2,11 @@ from docforge import GriffeLoader
|
||||
|
||||
|
||||
def test_load_single_module(temp_package):
|
||||
(temp_package / "mod.py").write_text(
|
||||
'''"""Module docstring."""\n
|
||||
(temp_package / "mod.py").write_text('''"""Module docstring."""\n
|
||||
def foo():
|
||||
"""Foo docstring."""
|
||||
pass
|
||||
'''
|
||||
)
|
||||
''')
|
||||
|
||||
loader = GriffeLoader()
|
||||
project = loader.load_project(["testpkg.mod"])
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge.nav import ResolvedNav
|
||||
from docforge.nav import MkDocsNavEmitter
|
||||
from docforge.nav import MkDocsNavEmitter, ResolvedNav
|
||||
|
||||
|
||||
def test_emit_mkdocs_nav():
|
||||
|
||||
@@ -2,8 +2,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from docforge.nav import NavSpec
|
||||
from docforge.nav import resolve_nav
|
||||
from docforge.nav import NavSpec, resolve_nav
|
||||
|
||||
|
||||
def _write_docs(root: Path, paths: list[str]) -> None:
|
||||
|
||||
@@ -2,7 +2,7 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MCPRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mcp_file_content(tmp_path: Path):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MCPRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mcp_idempotent(tmp_path: Path):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge.loaders import GriffeLoader, discover_module_paths
|
||||
from docforge import MCPRenderer
|
||||
from docforge.loaders import GriffeLoader, discover_module_paths
|
||||
|
||||
|
||||
def test_mcp_emits_all_modules(tmp_path: Path) -> None:
|
||||
@@ -22,10 +22,7 @@ def test_mcp_emits_all_modules(tmp_path: Path) -> None:
|
||||
for p in (tmp_path / "modules").rglob("*.json")
|
||||
}
|
||||
|
||||
expected = {
|
||||
f"modules/{m.path}.json"
|
||||
for m in project.get_all_modules()
|
||||
}
|
||||
expected = {f"modules/{m.path}.json" for m in project.get_all_modules()}
|
||||
|
||||
missing = expected - emitted
|
||||
assert not missing, f"Missing MCP module JSON files: {missing}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MCPRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mcp_directory_structure(tmp_path: Path):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MkDocsRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mkdocs_file_content(tmp_path: Path):
|
||||
@@ -47,4 +47,4 @@ def test_generate_readme_source_root(tmp_path: Path):
|
||||
content = readme.read_text()
|
||||
|
||||
assert "# testpkg" in content
|
||||
assert "Test package documentation." in content
|
||||
assert "Test package documentation." in content
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MkDocsRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mkdocs_idempotent(tmp_path: Path):
|
||||
@@ -50,4 +50,4 @@ def test_generate_readme_idempotent(tmp_path: Path):
|
||||
|
||||
second = readme.read_text()
|
||||
|
||||
assert first == second
|
||||
assert first == second
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge.loaders import GriffeLoader, discover_module_paths
|
||||
from docforge import MkDocsRenderer
|
||||
from docforge.loaders import GriffeLoader, discover_module_paths
|
||||
|
||||
|
||||
def test_mkdocs_emits_all_modules(tmp_path: Path) -> None:
|
||||
@@ -23,10 +23,7 @@ def test_mkdocs_emits_all_modules(tmp_path: Path) -> None:
|
||||
module_is_source=True,
|
||||
)
|
||||
|
||||
emitted = {
|
||||
p.relative_to(tmp_path).as_posix()
|
||||
for p in tmp_path.rglob("*.md")
|
||||
}
|
||||
emitted = {p.relative_to(tmp_path).as_posix() for p in tmp_path.rglob("*.md")}
|
||||
|
||||
module_paths = [m.path for m in project.get_all_modules()]
|
||||
|
||||
@@ -34,8 +31,7 @@ def test_mkdocs_emits_all_modules(tmp_path: Path) -> None:
|
||||
for path in module_paths:
|
||||
parts = path.split(".")
|
||||
is_package = any(
|
||||
other != path and other.startswith(path + ".")
|
||||
for other in module_paths
|
||||
other != path and other.startswith(path + ".") for other in module_paths
|
||||
)
|
||||
|
||||
if is_package:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from docforge import MkDocsRenderer
|
||||
from docforge.models import Project, Module
|
||||
from docforge.models import Module, Project
|
||||
|
||||
|
||||
def test_mkdocs_directory_structure(tmp_path: Path):
|
||||
|
||||
Reference in New Issue
Block a user