219 lines
7.3 KiB
Python
219 lines
7.3 KiB
Python
"""Unit tests for generators."""
|
|
|
|
import pytest
|
|
from code_doc_cli.generators.markdown_generator import MarkdownGenerator
|
|
from code_doc_cli.generators.templates import DocumentationTemplate, SyntaxHighlighter
|
|
from code_doc_cli.parsers.base import DocElement, ElementType, Parameter
|
|
|
|
|
|
class TestMarkdownGenerator:
|
|
"""Tests for Markdown generator."""
|
|
|
|
@pytest.fixture
|
|
def sample_elements(self):
|
|
"""Create sample documentation elements."""
|
|
elements = []
|
|
|
|
module_elem = DocElement(
|
|
name="sample_module",
|
|
element_type=ElementType.MODULE,
|
|
description="This is a sample module for testing.",
|
|
full_docstring="This is a sample module for testing.",
|
|
source_file="sample.py",
|
|
line_number=1,
|
|
)
|
|
elements.append(module_elem)
|
|
|
|
func_elem = DocElement(
|
|
name="add",
|
|
element_type=ElementType.FUNCTION,
|
|
description="Add two numbers together.",
|
|
full_docstring="Add two numbers together.\n\nArgs:\n a: First number\n b: Second number",
|
|
parameters=[
|
|
Parameter(name="a", type_hint="int", description="First number"),
|
|
Parameter(name="b", type_hint="int", description="Second number"),
|
|
],
|
|
return_type="int",
|
|
return_description="The sum of a and b",
|
|
source_file="sample.py",
|
|
line_number=10,
|
|
visibility="public",
|
|
)
|
|
elements.append(func_elem)
|
|
|
|
class_elem = DocElement(
|
|
name="Calculator",
|
|
element_type=ElementType.CLASS,
|
|
description="A simple calculator class.",
|
|
full_docstring="A simple calculator class.",
|
|
attributes=[
|
|
("memory", "int", "Current stored value in memory"),
|
|
],
|
|
source_file="sample.py",
|
|
line_number=20,
|
|
visibility="public",
|
|
decorators=["@dataclass"],
|
|
)
|
|
elements.append(class_elem)
|
|
|
|
return elements
|
|
|
|
def test_generate_markdown(self, sample_elements):
|
|
"""Test Markdown generation."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=sample_elements)
|
|
|
|
assert "# API Documentation" in output
|
|
assert "sample_module" in output
|
|
assert "add" in output
|
|
assert "Calculator" in output
|
|
|
|
def test_generate_function_markdown(self, sample_elements):
|
|
"""Test function documentation in Markdown."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=sample_elements)
|
|
|
|
assert "### add" in output
|
|
assert "int" in output
|
|
assert "First number" in output
|
|
|
|
def test_generate_class_markdown(self, sample_elements):
|
|
"""Test class documentation in Markdown."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=sample_elements)
|
|
|
|
assert "## Calculator" in output
|
|
assert "memory" in output
|
|
|
|
def test_generate_json(self, sample_elements):
|
|
"""Test JSON generation."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate_json(elements=sample_elements)
|
|
|
|
assert '"name": "add"' in output
|
|
assert '"type": "function"' in output
|
|
assert '"parameters"' in output
|
|
|
|
def test_generate_json_structure(self, sample_elements):
|
|
"""Test JSON output structure."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate_json(elements=sample_elements)
|
|
|
|
import json
|
|
data = json.loads(output)
|
|
|
|
assert "generated_at" in data
|
|
assert "elements" in data
|
|
assert len(data["elements"]) == 3
|
|
|
|
def test_custom_title(self, sample_elements):
|
|
"""Test custom documentation title."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=sample_elements, title="Custom Title")
|
|
|
|
assert "# Custom Title" in output
|
|
|
|
def test_no_metadata(self, sample_elements):
|
|
"""Test generation without metadata."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=sample_elements, include_metadata=False)
|
|
|
|
assert "Generated on" not in output
|
|
|
|
def test_empty_elements(self):
|
|
"""Test generation with no elements."""
|
|
generator = MarkdownGenerator()
|
|
output = generator.generate(elements=[])
|
|
|
|
assert "# API Documentation" in output
|
|
|
|
|
|
class TestDocumentationTemplate:
|
|
"""Tests for documentation template."""
|
|
|
|
def test_format_function(self):
|
|
"""Test function template formatting."""
|
|
template = DocumentationTemplate()
|
|
params = [("a", "int", None, "First number"), ("b", "int", None, "Second number")]
|
|
output = template.format_function(
|
|
name="add",
|
|
description="Add two numbers.",
|
|
parameters=params,
|
|
return_type="int",
|
|
return_description="The sum",
|
|
raises=[("ValueError", "If inputs are invalid")],
|
|
examples=["add(1, 2) # Returns 3"],
|
|
source_file="test.py",
|
|
line_number=10,
|
|
decorators=[],
|
|
)
|
|
|
|
assert "### add" in output
|
|
assert "Add two numbers" in output
|
|
assert "| a |" in output
|
|
assert "| b |" in output
|
|
assert "Returns:" in output
|
|
assert "Raises:" in output
|
|
|
|
def test_format_class(self):
|
|
"""Test class template formatting."""
|
|
template = DocumentationTemplate()
|
|
output = template.format_class(
|
|
name="Calculator",
|
|
description="A calculator class.",
|
|
attributes=[("value", "int", "Stored value")],
|
|
methods=["add", "subtract"],
|
|
parameters=[("BaseClass", "Some description")],
|
|
decorators=["@dataclass"],
|
|
source_file="test.py",
|
|
line_number=5,
|
|
)
|
|
|
|
assert "## Calculator" in output
|
|
assert "A calculator class" in output
|
|
assert "Attributes:" in output
|
|
assert "value" in output
|
|
assert "Methods:" in output
|
|
|
|
def test_format_module(self):
|
|
"""Test module template formatting."""
|
|
template = DocumentationTemplate()
|
|
output = template.format_module(
|
|
name="my_module",
|
|
description="This is my module.",
|
|
imports=["os", "sys"],
|
|
elements_count={"functions": 5, "classes": 2, "constants": 3},
|
|
)
|
|
|
|
assert "# my_module" in output
|
|
assert "This is my module" in output
|
|
assert "os" in output
|
|
assert "functions" in output
|
|
|
|
|
|
class TestSyntaxHighlighter:
|
|
"""Tests for syntax highlighter."""
|
|
|
|
def test_highlight_python(self):
|
|
"""Test Python syntax highlighting."""
|
|
highlighter = SyntaxHighlighter()
|
|
code = "def hello():\n print('world')"
|
|
output = highlighter.highlight(code, "python")
|
|
|
|
assert output
|
|
assert "<pre>" in output or "code" in output.lower()
|
|
|
|
def test_highlight_with_theme(self):
|
|
"""Test different themes."""
|
|
for theme in ["default", "dark", "light"]:
|
|
highlighter = SyntaxHighlighter(theme=theme)
|
|
assert highlighter.theme is not None
|
|
|
|
def test_get_css(self):
|
|
"""Test CSS generation."""
|
|
highlighter = SyntaxHighlighter()
|
|
css = highlighter.get_css()
|
|
|
|
assert css
|
|
assert "pre" in css or "code" in css
|