Files
scaffoldforge/tests/integration/test_full_workflow.py
7000pctAUTO 4de73353a4
Some checks failed
CI / test (push) Has been cancelled
fix: resolve CI linting and type checking errors
2026-02-04 05:58:29 +00:00

295 lines
10 KiB
Python

"""Integration tests for ScaffoldForge."""
import tempfile
from pathlib import Path
from unittest.mock import Mock, patch
from click.testing import CliRunner
from scaffoldforge.cli import cli
from scaffoldforge.generators import CodeGenerator, StructureGenerator
from scaffoldforge.parsers import ChecklistItem, IssueData
from scaffoldforge.templates import TemplateEngine
class TestFullWorkflow:
"""Integration tests for the full workflow."""
@patch('scaffoldforge.cli.commands.IssueParser')
@patch('scaffoldforge.cli.commands.TemplateEngine')
@patch('scaffoldforge.cli.commands.StructureGenerator')
@patch('scaffoldforge.cli.commands.CodeGenerator')
def test_full_generate_workflow(
self, mock_code_gen, mock_struct_gen, mock_tpl_engine, mock_parser
):
"""Test complete generate workflow."""
runner = CliRunner()
mock_issue_data = Mock()
mock_issue_data.number = 42
mock_issue_data.title = "Implement User Authentication"
mock_issue_data.body = "Add user login and registration"
mock_issue_data.labels = ["python", "security"]
mock_issue_data.checklist = [
ChecklistItem(text="Create login form", completed=False),
ChecklistItem(text="Add password hashing", completed=False),
]
mock_issue_data.get_todo_items.return_value = [
"Create login form",
"Add password hashing"
]
mock_issue_data.requirements = ["Must be secure", "Must be fast"]
mock_issue_data.acceptance_criteria = []
mock_issue_data.suggested_files = []
mock_issue_data.suggested_directories = []
mock_issue_data.repository = "user/repo"
mock_issue_data.author = "testuser"
mock_issue_data.created_at = "2024-01-01T00:00:00"
mock_parser_instance = Mock()
mock_parser_instance.parse_issue.return_value = mock_issue_data
mock_parser_instance.detect_language.return_value = "python"
mock_parser.return_value = mock_parser_instance
mock_engine = Mock()
mock_engine.load_templates.return_value = {
"main.py": "# content",
"utils.py": "# utils"
}
mock_engine.get_template_context.return_value = {
"project_name": "implement-user-authentication",
"issue_number": 42
}
mock_tpl_engine.return_value = mock_engine
mock_code_gen_instance = Mock()
mock_code_gen_instance.generate_all_files.return_value = []
mock_code_gen.return_value = mock_code_gen_instance
mock_struct_gen_instance = Mock()
mock_struct_gen.return_value = mock_struct_gen_instance
with runner.isolated_filesystem():
result = runner.invoke(
cli,
[
"generate",
"https://github.com/user/repo/issues/42",
"--language", "python",
"--output", "./test-project"
]
)
assert result.exit_code == 0
def test_template_engine_with_real_templates(self):
"""Test TemplateEngine with real built-in templates."""
engine = TemplateEngine()
languages = engine.list_available_languages()
assert "python" in languages
assert "javascript" in languages
assert "go" in languages
assert "rust" in languages
python_templates = engine.list_available_templates("python")
assert "default" in python_templates
def test_issue_data_integration(self):
"""Test IssueData with real checklist items."""
checklist = [
ChecklistItem(text="First task", completed=False),
ChecklistItem(text="Second task", completed=True),
ChecklistItem(text="Third task", completed=False),
]
issue_data = IssueData(
number=100,
title="Integration Test Issue",
body="Test body for integration",
body_html="<p>Test body</p>",
labels=["test"],
state="open",
url="https://github.com/test/repo/issues/100",
repository="test/repo",
author="testuser",
created_at="2024-01-01T00:00:00",
updated_at="2024-01-02T00:00:00",
checklist=checklist
)
todos = issue_data.get_todo_items()
completed = issue_data.get_completed_items()
assert len(todos) == 2
assert len(completed) == 1
assert "First task" in todos
assert "Second task" in completed
def test_generator_with_real_templates(self):
"""Test code generation with real templates."""
issue_data = IssueData(
number=1,
title="Test Python Project",
body="",
body_html="",
labels=["python"],
state="open",
url="",
repository="",
author="",
created_at="",
updated_at="",
checklist=[
ChecklistItem(text="Task 1", completed=False),
ChecklistItem(text="Task 2", completed=False),
]
)
engine = TemplateEngine()
gen = CodeGenerator(engine, issue_data)
files = gen.generate_all_files("python", issue_data)
assert len(files) > 0
for f in files:
assert f.path is not None
assert f.content is not None
def test_structure_generator_preview_mode(self):
"""Test structure generator in preview mode."""
issue_data = IssueData(
number=1,
title="Preview Test",
body="",
body_html="",
labels=["python"],
state="open",
url="",
repository="",
author="",
created_at="",
updated_at="",
checklist=[]
)
engine = TemplateEngine()
code_gen = CodeGenerator(engine, issue_data)
with tempfile.TemporaryDirectory() as tmpdir:
gen = StructureGenerator(output_dir=tmpdir, preview=True)
gen.generate("python", issue_data, code_gen)
assert len(gen.created_files) == 0
assert len(gen.created_dirs) == 0
def test_multiple_language_templates(self):
"""Test that all language templates can be loaded."""
engine = TemplateEngine()
for lang in ["python", "javascript", "go", "rust"]:
templates = engine.list_available_templates(lang)
assert len(templates) >= 1
context = engine.get_template_context(
IssueData(
number=1, title="Test", body="", body_html="",
labels=[lang], state="open", url="", repository="",
author="", created_at="", updated_at=""
)
)
assert context is not None
def test_cli_with_preview_flag(self):
"""Test CLI with preview flag doesn't create files."""
runner = CliRunner()
with patch('scaffoldforge.cli.commands.IssueParser') as mock_parser, \
patch('scaffoldforge.cli.commands.TemplateEngine') as _mock_tpl_engine, \
patch('scaffoldforge.cli.commands.StructureGenerator') as _mock_struct_gen, \
patch('scaffoldforge.cli.commands.CodeGenerator') as _mock_code_gen:
mock_issue_data = Mock()
mock_issue_data.number = 1
mock_issue_data.title = "Test"
mock_issue_data.labels = ["python"]
mock_issue_data.checklist = []
mock_issue_data.get_todo_items.return_value = []
mock_issue_data.requirements = []
mock_issue_data.body = ""
mock_issue_data.repository = ""
mock_issue_data.author = ""
mock_issue_data.created_at = ""
mock_parser.return_value.parse_issue.return_value = mock_issue_data
mock_parser.return_value.detect_language.return_value = "python"
with runner.isolated_filesystem():
result = runner.invoke(
cli,
["generate", "https://github.com/test/repo/issues/1", "--preview"]
)
assert result.exit_code == 0
def test_readme_generation(self):
"""Test README generation in structure generator."""
issue_data = IssueData(
number=123,
title="Test Project",
body="This is a test project body",
body_html="",
labels=["python"],
state="open",
url="https://github.com/user/repo/issues/123",
repository="user/repo",
author="testuser",
created_at="2024-01-01T00:00:00",
updated_at="2024-01-02T00:00:00",
checklist=[
ChecklistItem(text="Task 1", completed=False),
ChecklistItem(text="Task 2", completed=True),
]
)
engine = TemplateEngine()
code_gen = CodeGenerator(engine, issue_data)
with tempfile.TemporaryDirectory() as tmpdir:
gen = StructureGenerator(output_dir=tmpdir, preview=False)
gen.generate("python", issue_data, code_gen)
readme_path = Path(tmpdir) / "test-project" / "README.md"
if readme_path.exists():
content = readme_path.read_text()
assert "Test Project" in content
assert "123" in content
class TestRepositoryIntegration:
"""Tests for repository integration features."""
def test_gitignore_content_by_language(self):
"""Test that gitignore content varies by language."""
issue_data = IssueData(
number=1, title="Test", body="", body_html="",
labels=[], state="open", url="", repository="",
author="", created_at="", updated_at=""
)
engine = TemplateEngine()
code_gen = CodeGenerator(engine, issue_data)
for lang in ["python", "javascript", "go", "rust"]:
files = code_gen.generate_all_files(lang, issue_data)
file_names = [f.path for f in files]
if lang == "python":
assert any("requirements" in f or "pyproject" in f for f in file_names)
elif lang == "javascript":
assert any("package.json" in f for f in file_names)
elif lang == "go":
assert any("go.mod" in f for f in file_names)
elif lang == "rust":
assert any("Cargo.toml" in f for f in file_names)