"""Unit tests for the generators module.""" import tempfile from unittest.mock import Mock, patch from scaffoldforge.generators import CodeGenerator, StructureGenerator from scaffoldforge.generators.structure import FileSpec from scaffoldforge.parsers import ChecklistItem, IssueData 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