From dba02f075698c071aefc443b30a91f61622c92d8 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 05:37:20 +0000 Subject: [PATCH] Initial upload: ScaffoldForge CLI tool with full codebase, tests, and CI/CD --- tests/unit/test_generators.py | 185 ++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 tests/unit/test_generators.py diff --git a/tests/unit/test_generators.py b/tests/unit/test_generators.py new file mode 100644 index 0000000..06f67e4 --- /dev/null +++ b/tests/unit/test_generators.py @@ -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