Initial upload: ScaffoldForge CLI tool with full codebase, tests, and CI/CD
This commit is contained in:
185
tests/unit/test_generators.py
Normal file
185
tests/unit/test_generators.py
Normal file
@@ -0,0 +1,185 @@
|
||||
"""Unit tests for the generators module."""
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
|
||||
from scaffoldforge.generators import StructureGenerator, CodeGenerator
|
||||
from scaffoldforge.generators.structure import FileSpec
|
||||
from scaffoldforge.parsers import IssueData, ChecklistItem
|
||||
from scaffoldforge.templates import TemplateEngine
|
||||
|
||||
|
||||
class TestFileSpec:
|
||||
"""Tests for FileSpec dataclass."""
|
||||
|
||||
def test_file_spec_creation(self):
|
||||
"""Test creating a file specification."""
|
||||
spec = FileSpec(
|
||||
path="src/main.py",
|
||||
content="# Hello World"
|
||||
)
|
||||
assert spec.path == "src/main.py"
|
||||
assert spec.content == "# Hello World"
|
||||
assert spec.encoding == "utf-8"
|
||||
assert spec.executable is False
|
||||
|
||||
def test_file_spec_executable(self):
|
||||
"""Test executable file specification."""
|
||||
spec = FileSpec(
|
||||
path="script.sh",
|
||||
content="#!/bin/bash",
|
||||
executable=True
|
||||
)
|
||||
assert spec.executable is True
|
||||
|
||||
|
||||
class TestStructureGenerator:
|
||||
"""Tests for StructureGenerator class."""
|
||||
|
||||
def test_generator_initialization(self):
|
||||
"""Test generator initialization."""
|
||||
gen = StructureGenerator()
|
||||
assert gen.output_dir == "./generated"
|
||||
assert gen.preview is False
|
||||
|
||||
def test_generator_initialization_with_custom_dir(self):
|
||||
"""Test generator with custom output directory."""
|
||||
gen = StructureGenerator(output_dir="/tmp/myproject", preview=True)
|
||||
assert gen.output_dir == "/tmp/myproject"
|
||||
assert gen.preview is True
|
||||
|
||||
def test_sanitize_name(self):
|
||||
"""Test name sanitization."""
|
||||
gen = StructureGenerator()
|
||||
assert gen._sanitize_name("Hello World!") == "hello-world"
|
||||
assert gen._sanitize_name("Test/Project") == "testproject"
|
||||
assert gen._sanitize_name(" Spaces ") == "spaces"
|
||||
result = gen._sanitize_name("Very long name " * 10)
|
||||
assert len(result) <= 50
|
||||
|
||||
def test_sanitize_name_empty(self):
|
||||
"""Test sanitizing empty name."""
|
||||
gen = StructureGenerator()
|
||||
result = gen._sanitize_name("!!!")
|
||||
assert result == "project"
|
||||
|
||||
@patch('scaffoldforge.generators.code.TemplateEngine')
|
||||
def test_generate_creates_files(self, mock_template_engine):
|
||||
"""Test that generate creates files in preview mode."""
|
||||
issue_data = IssueData(
|
||||
number=1, title="Test Issue", body="", body_html="",
|
||||
labels=["python"], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at="",
|
||||
checklist=[ChecklistItem(text="Task 1", completed=False)]
|
||||
)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
gen = StructureGenerator(output_dir=tmpdir, preview=True)
|
||||
|
||||
mock_engine = Mock(spec=TemplateEngine)
|
||||
mock_engine.get_template_context.return_value = {
|
||||
"project_name": "test-project"
|
||||
}
|
||||
code_gen = Mock(spec=CodeGenerator)
|
||||
code_gen.generate_all_files.return_value = [
|
||||
FileSpec(path="main.py", content="print('hello')")
|
||||
]
|
||||
|
||||
gen.generate("python", issue_data, code_gen)
|
||||
|
||||
def test_get_created_files(self):
|
||||
"""Test getting list of created files."""
|
||||
gen = StructureGenerator()
|
||||
gen.created_files = ["file1.py", "file2.py"]
|
||||
files = gen.get_created_files()
|
||||
assert len(files) == 2
|
||||
assert "file1.py" in files
|
||||
|
||||
def test_get_created_directories(self):
|
||||
"""Test getting list of created directories."""
|
||||
gen = StructureGenerator()
|
||||
gen.created_dirs = ["src", "tests"]
|
||||
dirs = gen.get_created_directories()
|
||||
assert len(dirs) == 2
|
||||
|
||||
|
||||
class TestCodeGenerator:
|
||||
"""Tests for CodeGenerator class."""
|
||||
|
||||
def test_code_generator_initialization(self):
|
||||
"""Test code generator initialization."""
|
||||
issue_data = IssueData(
|
||||
number=1, title="Test", body="", body_html="",
|
||||
labels=[], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at=""
|
||||
)
|
||||
engine = TemplateEngine()
|
||||
gen = CodeGenerator(engine, issue_data)
|
||||
assert gen.issue_data == issue_data
|
||||
assert gen.template_engine == engine
|
||||
|
||||
def test_get_extension(self):
|
||||
"""Test file extension detection."""
|
||||
issue_data = IssueData(
|
||||
number=1, title="Test", body="", body_html="",
|
||||
labels=[], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at=""
|
||||
)
|
||||
engine = TemplateEngine()
|
||||
gen = CodeGenerator(engine, issue_data)
|
||||
|
||||
assert gen._get_extension("python") == ".py"
|
||||
assert gen._get_extension("javascript") == ".js"
|
||||
assert gen._get_extension("go") == ".go"
|
||||
assert gen._get_extension("rust") == ".rs"
|
||||
assert gen._get_extension("unknown") == ".txt"
|
||||
|
||||
def test_get_source_path(self):
|
||||
"""Test source path generation."""
|
||||
issue_data = IssueData(
|
||||
number=1, title="Test", body="", body_html="",
|
||||
labels=[], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at=""
|
||||
)
|
||||
engine = TemplateEngine()
|
||||
gen = CodeGenerator(engine, issue_data)
|
||||
|
||||
assert gen._get_source_path("main", "python") == "main.py"
|
||||
assert gen._get_source_path("utils", "python") == "src/utils.py"
|
||||
assert gen._get_source_path("lib", "rust") == "src/lib.rs"
|
||||
|
||||
def test_generate_todo_content_python(self):
|
||||
"""Test TODO content generation for Python."""
|
||||
issue_data = IssueData(
|
||||
number=42, title="Test", body="", body_html="",
|
||||
labels=[], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at="",
|
||||
checklist=[
|
||||
ChecklistItem(text="Implement feature", completed=False),
|
||||
ChecklistItem(text="Add tests", completed=False),
|
||||
]
|
||||
)
|
||||
engine = TemplateEngine()
|
||||
gen = CodeGenerator(engine, issue_data)
|
||||
|
||||
content = gen._generate_todo_content("python", "main", ["Task 1", "Task 2"])
|
||||
assert '"""' in content
|
||||
assert "# TODO: Task 1" in content
|
||||
|
||||
def test_generate_todo_content_go(self):
|
||||
"""Test TODO content generation for Go."""
|
||||
issue_data = IssueData(
|
||||
number=1, title="Test", body="", body_html="",
|
||||
labels=[], state="open", url="", repository="",
|
||||
author="", created_at="", updated_at="",
|
||||
checklist=[ChecklistItem(text="Task 1", completed=False)]
|
||||
)
|
||||
engine = TemplateEngine()
|
||||
gen = CodeGenerator(engine, issue_data)
|
||||
|
||||
content = gen._generate_todo_content("go", "main", ["Task 1"])
|
||||
assert "// main" in content
|
||||
assert "# TODO: Task 1" in content
|
||||
Reference in New Issue
Block a user