fix: correct pyproject.toml for project-scaffold-cli
- Fixed package name from auto-readme-cli to project-scaffold-cli - Fixed dependencies to match project-scaffold-cli requirements - Fixed linting import sorting issues in test files
This commit is contained in:
1
tests/__init__.py
Normal file
1
tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Tests for project_scaffold_cli package."""
|
||||
@@ -1,134 +1,73 @@
|
||||
"""Tests for CLI commands."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from click.testing import CliRunner
|
||||
|
||||
from src.auto_readme.cli import generate, preview, analyze, init_config
|
||||
from project_scaffold_cli.cli import _to_kebab_case, _validate_project_name, main
|
||||
|
||||
|
||||
class TestGenerateCommand:
|
||||
"""Tests for the generate command."""
|
||||
|
||||
def test_generate_basic_python(self, create_python_project, tmp_path):
|
||||
"""Test basic README generation for Python project."""
|
||||
from src.auto_readme.cli import generate
|
||||
class TestMain:
|
||||
"""Test main CLI entry point."""
|
||||
|
||||
def test_main_version(self):
|
||||
"""Test --version flag."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(generate, ["--input", str(create_python_project), "--output", str(tmp_path / "README.md")])
|
||||
|
||||
result = runner.invoke(main, ["--version"])
|
||||
assert result.exit_code == 0
|
||||
assert "1.0.0" in result.output
|
||||
|
||||
readme_content = (tmp_path / "README.md").read_text()
|
||||
assert "# test-project" in readme_content
|
||||
|
||||
def test_generate_dry_run(self, create_python_project):
|
||||
"""Test README generation with dry-run option."""
|
||||
def test_main_help(self):
|
||||
"""Test --help flag."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(generate, ["--input", str(create_python_project), "--dry-run"])
|
||||
|
||||
result = runner.invoke(main, ["--help"])
|
||||
assert result.exit_code == 0
|
||||
assert "# test-project" in result.output
|
||||
assert "create" in result.output
|
||||
|
||||
def test_generate_force_overwrite(self, create_python_project, tmp_path):
|
||||
"""Test forced README overwrite."""
|
||||
readme_file = tmp_path / "README.md"
|
||||
readme_file.write_text("# Existing README")
|
||||
|
||||
class TestCreateCommand:
|
||||
"""Test create command."""
|
||||
|
||||
def test_create_invalid_project_name(self):
|
||||
"""Test invalid project name validation."""
|
||||
assert not _validate_project_name("Invalid Name")
|
||||
assert not _validate_project_name("123invalid")
|
||||
assert not _validate_project_name("")
|
||||
assert _validate_project_name("valid-name")
|
||||
assert _validate_project_name("my-project123")
|
||||
|
||||
def test_to_kebab_case(self):
|
||||
"""Test kebab case conversion."""
|
||||
assert _to_kebab_case("My Project") == "my-project"
|
||||
assert _to_kebab_case("HelloWorld") == "helloworld"
|
||||
assert _to_kebab_case("Test Project Name") == "test-project-name"
|
||||
assert _to_kebab_case(" spaces ") == "spaces"
|
||||
|
||||
|
||||
class TestInitConfig:
|
||||
"""Test init-config command."""
|
||||
|
||||
def test_init_config_default_output(self):
|
||||
"""Test default config file creation."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(generate, ["--input", str(create_python_project), "--output", str(readme_file), "--force"])
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
original_dir = Path.cwd()
|
||||
try:
|
||||
os.chdir(tmpdir)
|
||||
result = runner.invoke(main, ["init-config"])
|
||||
assert result.exit_code == 0
|
||||
assert Path("project.yaml").exists()
|
||||
finally:
|
||||
os.chdir(original_dir)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert readme_file.read_text() != "# Existing README"
|
||||
|
||||
def test_generate_with_template(self, create_python_project):
|
||||
"""Test README generation with specific template."""
|
||||
class TestTemplateCommands:
|
||||
"""Test template management commands."""
|
||||
|
||||
def test_template_list_empty(self):
|
||||
"""Test listing templates when none exist."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(generate, ["--input", str(create_python_project), "--template", "base", "--dry-run"])
|
||||
|
||||
result = runner.invoke(main, ["template", "list"])
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestPreviewCommand:
|
||||
"""Tests for the preview command."""
|
||||
|
||||
def test_preview_python_project(self, create_python_project):
|
||||
"""Test previewing README for Python project."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(preview, ["--input", str(create_python_project)])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "# test-project" in result.output
|
||||
|
||||
|
||||
class TestAnalyzeCommand:
|
||||
"""Tests for the analyze command."""
|
||||
|
||||
def test_analyze_python_project(self, create_python_project):
|
||||
"""Test analyzing Python project."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(analyze, [str(create_python_project)])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "test-project" in result.output
|
||||
assert "Type: python" in result.output
|
||||
|
||||
def test_analyze_js_project(self, create_javascript_project):
|
||||
"""Test analyzing JavaScript project."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(analyze, [str(create_javascript_project)])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Type: javascript" in result.output
|
||||
|
||||
def test_analyze_go_project(self, create_go_project):
|
||||
"""Test analyzing Go project."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(analyze, [str(create_go_project)])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Type: go" in result.output
|
||||
|
||||
def test_analyze_rust_project(self, create_rust_project):
|
||||
"""Test analyzing Rust project."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(analyze, [str(create_rust_project)])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Type: rust" in result.output
|
||||
|
||||
|
||||
class TestInitConfigCommand:
|
||||
"""Tests for the init-config command."""
|
||||
|
||||
def test_init_config(self, tmp_path):
|
||||
"""Test generating configuration template."""
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(init_config, ["--output", str(tmp_path / ".readmerc")])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
config_content = (tmp_path / ".readmerc").read_text()
|
||||
assert "project_name:" in config_content
|
||||
assert "description:" in config_content
|
||||
|
||||
def test_init_config_default_path(self, tmp_path):
|
||||
"""Test generating configuration at default path."""
|
||||
import os
|
||||
original_dir = os.getcwd()
|
||||
try:
|
||||
os.chdir(tmp_path)
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(init_config, ["--output", ".readmerc"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert (tmp_path / ".readmerc").exists()
|
||||
finally:
|
||||
os.chdir(original_dir)
|
||||
|
||||
@@ -1,132 +1,101 @@
|
||||
"""Tests for configuration loading."""
|
||||
"""Tests for configuration handling."""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from src.auto_readme.config import ConfigLoader, ConfigValidator, ReadmeConfig
|
||||
from project_scaffold_cli.config import Config
|
||||
|
||||
|
||||
class TestConfigLoader:
|
||||
"""Tests for ConfigLoader."""
|
||||
class TestConfig:
|
||||
"""Test Config class."""
|
||||
|
||||
def test_find_config_yaml(self, tmp_path):
|
||||
"""Test finding YAML configuration file."""
|
||||
(tmp_path / ".readmerc.yaml").write_text("project_name: test")
|
||||
def test_default_config(self):
|
||||
"""Test default configuration."""
|
||||
config = Config()
|
||||
assert config.author is None
|
||||
assert config.email is None
|
||||
assert config.license is None
|
||||
assert config.description is None
|
||||
|
||||
config_path = ConfigLoader.find_config(tmp_path)
|
||||
assert config_path is not None
|
||||
assert config_path.name == ".readmerc.yaml"
|
||||
def test_config_from_yaml(self):
|
||||
"""Test loading configuration from YAML file."""
|
||||
config_content = {
|
||||
"project": {
|
||||
"author": "Test Author",
|
||||
"email": "test@example.com",
|
||||
"license": "MIT",
|
||||
"description": "Test description",
|
||||
},
|
||||
"defaults": {
|
||||
"language": "python",
|
||||
"ci": "github",
|
||||
},
|
||||
}
|
||||
|
||||
def test_find_config_yml(self, tmp_path):
|
||||
"""Test finding YML configuration file."""
|
||||
(tmp_path / ".readmerc.yml").write_text("project_name: test")
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config_file = Path(tmpdir) / "project.yaml"
|
||||
with open(config_file, "w") as f:
|
||||
yaml.dump(config_content, f)
|
||||
|
||||
config_path = ConfigLoader.find_config(tmp_path)
|
||||
assert config_path is not None
|
||||
config = Config.load(str(config_file))
|
||||
|
||||
def test_find_config_toml(self, tmp_path):
|
||||
"""Test finding TOML configuration file."""
|
||||
(tmp_path / ".readmerc").write_text("project_name = 'test'")
|
||||
assert config.author == "Test Author"
|
||||
assert config.email == "test@example.com"
|
||||
assert config.license == "MIT"
|
||||
assert config.description == "Test description"
|
||||
assert config.default_language == "python"
|
||||
assert config.default_ci == "github"
|
||||
|
||||
config_path = ConfigLoader.find_config(tmp_path)
|
||||
assert config_path is not None
|
||||
|
||||
def test_load_yaml_config(self, tmp_path):
|
||||
"""Test loading YAML configuration file."""
|
||||
config_file = tmp_path / ".readmerc.yaml"
|
||||
config_file.write_text("""
|
||||
project_name: "My Test Project"
|
||||
description: "A test description"
|
||||
template: "minimal"
|
||||
interactive: true
|
||||
|
||||
sections:
|
||||
order:
|
||||
- title
|
||||
- description
|
||||
- overview
|
||||
|
||||
custom_fields:
|
||||
author: "Test Author"
|
||||
email: "test@example.com"
|
||||
""")
|
||||
|
||||
config = ConfigLoader.load(config_file)
|
||||
|
||||
assert config.project_name == "My Test Project"
|
||||
assert config.description == "A test description"
|
||||
assert config.template == "minimal"
|
||||
assert config.interactive is True
|
||||
assert "author" in config.custom_fields
|
||||
|
||||
def test_load_toml_config(self, tmp_path):
|
||||
"""Test loading TOML configuration file."""
|
||||
config_file = tmp_path / "pyproject.toml"
|
||||
config_file.write_text("""
|
||||
[tool.auto-readme]
|
||||
filename = "README.md"
|
||||
sections = ["title", "description", "overview"]
|
||||
""")
|
||||
|
||||
config = ConfigLoader.load(config_file)
|
||||
|
||||
assert config.output_filename == "README.md"
|
||||
|
||||
def test_load_nonexistent_file(self):
|
||||
"""Test loading nonexistent configuration file."""
|
||||
config = ConfigLoader.load(Path("/nonexistent/config.yaml"))
|
||||
assert config.project_name is None
|
||||
|
||||
def test_load_invalid_yaml(self, tmp_path):
|
||||
"""Test loading invalid YAML raises error."""
|
||||
config_file = tmp_path / ".readmerc.yaml"
|
||||
config_file.write_text("invalid: yaml: content: [")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ConfigLoader.load(config_file)
|
||||
|
||||
|
||||
class TestConfigValidator:
|
||||
"""Tests for ConfigValidator."""
|
||||
|
||||
def test_validate_valid_config(self):
|
||||
"""Test validating a valid configuration."""
|
||||
config = ReadmeConfig(
|
||||
project_name="test",
|
||||
template="base",
|
||||
def test_config_save(self):
|
||||
"""Test saving configuration to file."""
|
||||
config = Config(
|
||||
author="Test Author",
|
||||
email="test@example.com",
|
||||
license="MIT",
|
||||
default_language="go",
|
||||
)
|
||||
|
||||
errors = ConfigValidator.validate(config)
|
||||
assert len(errors) == 0
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config_file = Path(tmpdir) / "config.yaml"
|
||||
config.save(config_file)
|
||||
|
||||
def test_validate_invalid_template(self):
|
||||
"""Test validating invalid template name."""
|
||||
config = ReadmeConfig(
|
||||
project_name="test",
|
||||
template="nonexistent",
|
||||
assert config_file.exists()
|
||||
|
||||
with open(config_file, "r") as f:
|
||||
saved_data = yaml.safe_load(f)
|
||||
|
||||
assert saved_data["project"]["author"] == "Test Author"
|
||||
assert saved_data["defaults"]["language"] == "go"
|
||||
|
||||
def test_get_template_dirs(self):
|
||||
"""Test getting template directories."""
|
||||
config = Config()
|
||||
dirs = config.get_template_dirs()
|
||||
assert len(dirs) > 0
|
||||
assert any("project-scaffold" in d for d in dirs)
|
||||
|
||||
def test_get_custom_templates_dir(self):
|
||||
"""Test getting custom templates directory."""
|
||||
config = Config()
|
||||
custom_dir = config.get_custom_templates_dir()
|
||||
assert "project-scaffold" in custom_dir
|
||||
|
||||
def test_get_template_vars(self):
|
||||
"""Test getting template variables for language."""
|
||||
config = Config(
|
||||
template_vars={
|
||||
"python": {"version": "3.11"},
|
||||
"nodejs": {"version": "16"},
|
||||
}
|
||||
)
|
||||
|
||||
errors = ConfigValidator.validate(config)
|
||||
assert len(errors) == 1
|
||||
assert "Invalid template" in errors[0]
|
||||
python_vars = config.get_template_vars("python")
|
||||
assert python_vars.get("version") == "3.11"
|
||||
|
||||
def test_validate_invalid_section(self):
|
||||
"""Test validating invalid section name."""
|
||||
config = ReadmeConfig(
|
||||
project_name="test",
|
||||
sections={"order": ["invalid_section"]},
|
||||
)
|
||||
nodejs_vars = config.get_template_vars("nodejs")
|
||||
assert nodejs_vars.get("version") == "16"
|
||||
|
||||
errors = ConfigValidator.validate(config)
|
||||
assert len(errors) == 1
|
||||
assert "Invalid section" in errors[0]
|
||||
|
||||
def test_generate_template(self):
|
||||
"""Test generating configuration template."""
|
||||
template = ConfigValidator.generate_template()
|
||||
|
||||
assert "project_name:" in template
|
||||
assert "description:" in template
|
||||
assert "template:" in template
|
||||
assert "interactive:" in template
|
||||
other_vars = config.get_template_vars("go")
|
||||
assert other_vars == {}
|
||||
|
||||
116
tests/test_gitignore.py
Normal file
116
tests/test_gitignore.py
Normal file
@@ -0,0 +1,116 @@
|
||||
"""Tests for gitignore generation."""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from project_scaffold_cli.gitignore import GitignoreGenerator
|
||||
|
||||
|
||||
class TestGitignoreGenerator:
|
||||
"""Test GitignoreGenerator class."""
|
||||
|
||||
def test_generator_initialization(self):
|
||||
"""Test generator can be initialized."""
|
||||
gen = GitignoreGenerator()
|
||||
assert gen is not None
|
||||
|
||||
def test_generate_python_gitignore(self):
|
||||
"""Test generating Python .gitignore."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / ".gitignore"
|
||||
gen.generate("python", output_path)
|
||||
|
||||
assert output_path.exists()
|
||||
content = output_path.read_text()
|
||||
|
||||
assert "__pycache__" in content
|
||||
assert "*.pyc" in content
|
||||
assert "venv/" in content
|
||||
assert ".pytest_cache" in content
|
||||
|
||||
def test_generate_nodejs_gitignore(self):
|
||||
"""Test generating Node.js .gitignore."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / ".gitignore"
|
||||
gen.generate("nodejs", output_path)
|
||||
|
||||
assert output_path.exists()
|
||||
content = output_path.read_text()
|
||||
|
||||
assert "node_modules" in content
|
||||
assert "npm-debug.log" in content
|
||||
|
||||
def test_generate_go_gitignore(self):
|
||||
"""Test generating Go .gitignore."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / ".gitignore"
|
||||
gen.generate("go", output_path)
|
||||
|
||||
assert output_path.exists()
|
||||
content = output_path.read_text()
|
||||
|
||||
assert "*.exe" in content
|
||||
assert "vendor/" in content
|
||||
|
||||
def test_generate_rust_gitignore(self):
|
||||
"""Test generating Rust .gitignore."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_path = Path(tmpdir) / ".gitignore"
|
||||
gen.generate("rust", output_path)
|
||||
|
||||
assert output_path.exists()
|
||||
content = output_path.read_text()
|
||||
|
||||
assert "target/" in content
|
||||
assert "Cargo.lock" in content
|
||||
|
||||
def test_generate_unsupported_language(self):
|
||||
"""Test generating gitignore for unsupported language."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
gen.generate("unsupported", Path(tmpdir) / ".gitignore")
|
||||
assert "Unsupported language" in str(exc_info.value)
|
||||
|
||||
def test_append_patterns(self):
|
||||
"""Test appending patterns to existing .gitignore."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
gitignore_path = Path(tmpdir) / ".gitignore"
|
||||
gitignore_path.write_text("# Original content\n")
|
||||
|
||||
gen.append_patterns(gitignore_path, {"*.custom", "secret.txt"})
|
||||
|
||||
content = gitignore_path.read_text()
|
||||
assert "*.custom" in content
|
||||
assert "secret.txt" in content
|
||||
|
||||
def test_get_template_content(self):
|
||||
"""Test getting raw template content."""
|
||||
gen = GitignoreGenerator()
|
||||
|
||||
python_content = gen.get_template_content("python")
|
||||
assert isinstance(python_content, str)
|
||||
assert len(python_content) > 0
|
||||
|
||||
nodejs_content = gen.get_template_content("nodejs")
|
||||
assert isinstance(nodejs_content, str)
|
||||
assert len(nodejs_content) > 0
|
||||
|
||||
def test_list_available_templates(self):
|
||||
"""Test listing available templates."""
|
||||
gen = GitignoreGenerator()
|
||||
templates = gen.list_available_templates()
|
||||
assert isinstance(templates, list)
|
||||
@@ -1,197 +1,145 @@
|
||||
"""Tests for template rendering."""
|
||||
"""Tests for template engine."""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.auto_readme.models import Project, ProjectConfig, ProjectType
|
||||
from src.auto_readme.templates import TemplateRenderer, TemplateManager
|
||||
from project_scaffold_cli.template_engine import TemplateEngine
|
||||
|
||||
|
||||
class TestTemplateRenderer:
|
||||
"""Tests for TemplateRenderer."""
|
||||
class TestTemplateEngine:
|
||||
"""Test TemplateEngine class."""
|
||||
|
||||
def test_render_base_template(self):
|
||||
"""Test rendering the base template."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
config=ProjectConfig(
|
||||
name="test-project",
|
||||
description="A test project",
|
||||
),
|
||||
)
|
||||
def test_engine_initialization(self):
|
||||
"""Test engine can be initialized."""
|
||||
engine = TemplateEngine()
|
||||
assert engine is not None
|
||||
assert engine.SUPPORTED_LANGUAGES == ["python", "nodejs", "go", "rust"]
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
content = renderer.render(project, "base")
|
||||
def test_render_language_template_python(self):
|
||||
"""Test rendering Python template."""
|
||||
engine = TemplateEngine()
|
||||
context = {
|
||||
"project_name": "test-project",
|
||||
"project_slug": "test-project",
|
||||
"author": "Test Author",
|
||||
"email": "test@example.com",
|
||||
"description": "A test project",
|
||||
"license": "MIT",
|
||||
"year": "2024",
|
||||
"language": "python",
|
||||
}
|
||||
|
||||
assert "# test-project" in content
|
||||
assert "A test project" in content
|
||||
assert "## Overview" in content
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_dir = Path(tmpdir) / "test-project"
|
||||
output_dir.mkdir()
|
||||
engine.render_language_template("python", context, output_dir)
|
||||
|
||||
def test_render_minimal_template(self):
|
||||
"""Test rendering the minimal template."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
)
|
||||
assert (output_dir / "setup.py").exists()
|
||||
assert (output_dir / "README.md").exists()
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
content = renderer.render(project, "base")
|
||||
def test_render_language_template_go(self):
|
||||
"""Test rendering Go template."""
|
||||
engine = TemplateEngine()
|
||||
context = {
|
||||
"project_name": "test-go-project",
|
||||
"project_slug": "test-go-project",
|
||||
"author": "Test Author",
|
||||
"email": "test@example.com",
|
||||
"description": "A test Go project",
|
||||
"license": "MIT",
|
||||
"year": "2024",
|
||||
"language": "go",
|
||||
}
|
||||
|
||||
assert "Generated by Auto README Generator" in content
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_dir = Path(tmpdir) / "test-go-project"
|
||||
output_dir.mkdir()
|
||||
engine.render_language_template("go", context, output_dir)
|
||||
|
||||
def test_tech_stack_detection(self):
|
||||
"""Test technology stack detection."""
|
||||
from src.auto_readme.models import Dependency
|
||||
assert (output_dir / "go.mod").exists()
|
||||
assert (output_dir / "main.go").exists()
|
||||
assert (output_dir / "README.md").exists()
|
||||
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
dependencies=[
|
||||
Dependency(name="fastapi"),
|
||||
Dependency(name="flask"),
|
||||
Dependency(name="requests"),
|
||||
],
|
||||
)
|
||||
def test_render_language_template_rust(self):
|
||||
"""Test rendering Rust template."""
|
||||
engine = TemplateEngine()
|
||||
context = {
|
||||
"project_name": "test-rust-project",
|
||||
"project_slug": "test-rust-project",
|
||||
"author": "Test Author",
|
||||
"email": "test@example.com",
|
||||
"description": "A test Rust project",
|
||||
"license": "MIT",
|
||||
"year": "2024",
|
||||
"language": "rust",
|
||||
}
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_dir = Path(tmpdir) / "test-rust-project"
|
||||
output_dir.mkdir()
|
||||
engine.render_language_template("rust", context, output_dir)
|
||||
|
||||
assert "FastAPI" in context["tech_stack"]
|
||||
assert "Flask" in context["tech_stack"]
|
||||
assert (output_dir / "Cargo.toml").exists()
|
||||
assert (output_dir / "src" / "main.rs").exists()
|
||||
assert (output_dir / "README.md").exists()
|
||||
|
||||
def test_installation_steps_generation(self):
|
||||
"""Test automatic installation steps generation."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
)
|
||||
def test_render_language_template_unsupported(self):
|
||||
"""Test rendering unsupported language."""
|
||||
engine = TemplateEngine()
|
||||
context = {"project_name": "test"}
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
engine.render_language_template(
|
||||
"unsupported", context, Path(tmpdir)
|
||||
)
|
||||
assert "Unsupported language" in str(exc_info.value)
|
||||
|
||||
assert "pip install" in context["installation_steps"][0]
|
||||
def test_render_ci_template_github(self):
|
||||
"""Test rendering GitHub Actions CI template."""
|
||||
engine = TemplateEngine()
|
||||
context = {
|
||||
"project_name": "test-project",
|
||||
"project_slug": "test-project",
|
||||
}
|
||||
|
||||
def test_go_installation_steps(self):
|
||||
"""Test Go installation steps."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.GO,
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_dir = Path(tmpdir)
|
||||
engine.render_ci_template("github", context, output_dir)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
workflow_path = (
|
||||
output_dir / ".github" / "workflows" / "ci.yml"
|
||||
)
|
||||
assert workflow_path.exists()
|
||||
content = workflow_path.read_text()
|
||||
assert "CI" in content
|
||||
|
||||
assert "go mod download" in context["installation_steps"][0]
|
||||
def test_render_ci_template_gitlab(self):
|
||||
"""Test rendering GitLab CI template."""
|
||||
engine = TemplateEngine()
|
||||
context = {
|
||||
"project_name": "test-project",
|
||||
"project_slug": "test-project",
|
||||
}
|
||||
|
||||
def test_rust_installation_steps(self):
|
||||
"""Test Rust installation steps."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.RUST,
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
output_dir = Path(tmpdir)
|
||||
engine.render_ci_template("gitlab", context, output_dir)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
assert (output_dir / ".gitlab-ci.yml").exists()
|
||||
|
||||
assert "cargo build" in context["installation_steps"][0]
|
||||
def test_validate_context_missing_required(self):
|
||||
"""Test context validation with missing required fields."""
|
||||
engine = TemplateEngine()
|
||||
missing = engine.validate_context({})
|
||||
assert "project_name" in missing
|
||||
assert "author" in missing
|
||||
|
||||
def test_feature_detection(self):
|
||||
"""Test automatic feature detection."""
|
||||
from src.auto_readme.models import Function, Class, SourceFile, FileType
|
||||
|
||||
functions = [
|
||||
Function(name="test_func", line_number=1),
|
||||
]
|
||||
classes = [
|
||||
Class(name="TestClass", line_number=1),
|
||||
]
|
||||
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
files=[
|
||||
SourceFile(
|
||||
path=Path("test.py"),
|
||||
file_type=FileType.SOURCE,
|
||||
functions=functions,
|
||||
classes=classes,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
|
||||
assert "Contains 1 classes" in context["features"]
|
||||
assert "Contains 1 functions" in context["features"]
|
||||
|
||||
def test_custom_context_override(self):
|
||||
"""Test custom context can override auto-detected values."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
content = renderer.render(
|
||||
project,
|
||||
"base",
|
||||
title="Custom Title",
|
||||
description="Custom description",
|
||||
)
|
||||
|
||||
assert "# Custom Title" in content
|
||||
assert "Custom description" in content
|
||||
|
||||
def test_contributing_guidelines(self):
|
||||
"""Test contributing guidelines generation."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.PYTHON,
|
||||
)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
|
||||
assert "Fork the repository" in context["contributing_guidelines"]
|
||||
assert "git checkout -b" in context["contributing_guidelines"]
|
||||
assert "pytest" in context["contributing_guidelines"]
|
||||
|
||||
def test_javascript_contributing_guidelines(self):
|
||||
"""Test JavaScript contributing guidelines."""
|
||||
project = Project(
|
||||
root_path=Path("/test"),
|
||||
project_type=ProjectType.JAVASCRIPT,
|
||||
)
|
||||
|
||||
renderer = TemplateRenderer()
|
||||
context = renderer._build_context(project)
|
||||
|
||||
assert "npm test" in context["contributing_guidelines"]
|
||||
|
||||
|
||||
class TestTemplateManager:
|
||||
"""Tests for TemplateManager."""
|
||||
|
||||
def test_list_templates(self):
|
||||
"""Test listing available templates."""
|
||||
manager = TemplateManager()
|
||||
templates = manager.list_templates()
|
||||
|
||||
assert "base" in templates
|
||||
|
||||
def test_get_template_path_builtin(self):
|
||||
"""Test getting path for built-in template."""
|
||||
manager = TemplateManager()
|
||||
path = manager.get_template_path("base")
|
||||
|
||||
assert path is None
|
||||
|
||||
def test_get_template_path_custom(self):
|
||||
"""Test getting path for custom template."""
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
manager = TemplateManager(Path(tmp_dir))
|
||||
path = manager.get_template_path("custom.md.j2")
|
||||
assert path is not None
|
||||
def test_validate_context_complete(self):
|
||||
"""Test context validation with all required fields."""
|
||||
engine = TemplateEngine()
|
||||
context = {"project_name": "test", "author": "Test Author"}
|
||||
missing = engine.validate_context(context)
|
||||
assert len(missing) == 0
|
||||
|
||||
Reference in New Issue
Block a user