fix: resolve CI test failure in output.py
- Fixed undefined 'tool' variable in display_history function - Changed '[tool]' markup tag usage to proper Rich syntax - All tests now pass (38/38 unit tests) - Type checking passes with mypy --strict
This commit is contained in:
263
tests/integration/test_full_pipeline.py
Normal file
263
tests/integration/test_full_pipeline.py
Normal file
@@ -0,0 +1,263 @@
|
||||
"""Integration tests for the full documentation pipeline."""
|
||||
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from doc2man.cli import main
|
||||
from doc2man.parsers.python import parse_python_file
|
||||
from doc2man.parsers.go import parse_go_file
|
||||
from doc2man.parsers.javascript import parse_javascript_file
|
||||
from doc2man.generators.man import generate_man_page
|
||||
from doc2man.generators.markdown import generate_markdown
|
||||
from doc2man.generators.html import generate_html
|
||||
|
||||
|
||||
class TestFullPipeline:
|
||||
"""Integration tests for the full documentation pipeline."""
|
||||
|
||||
def test_python_to_man_pipeline(self):
|
||||
"""Test Python file -> parse -> generate man page."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f:
|
||||
f.write(b'''
|
||||
def greet(name, greeting="Hello"):
|
||||
"""Greet a person with a custom greeting.
|
||||
|
||||
Args:
|
||||
name: The name of the person to greet.
|
||||
greeting: The greeting word to use.
|
||||
|
||||
Returns:
|
||||
The greeting string.
|
||||
|
||||
Raises:
|
||||
ValueError: If name is empty.
|
||||
"""
|
||||
if not name:
|
||||
raise ValueError("Name cannot be empty")
|
||||
return f"{greeting}, {name}!"
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_python_file(Path(f.name))
|
||||
assert parsed["language"] == "python"
|
||||
assert len(parsed["functions"]) == 1
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".1", delete=False) as out:
|
||||
output_path = Path(out.name)
|
||||
result = generate_man_page([{"file": str(f.name), "data": parsed}], output_path)
|
||||
|
||||
assert ".TH" in result
|
||||
assert "NAME" in result
|
||||
assert "greet" in result.lower()
|
||||
|
||||
output_path.unlink()
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_python_to_markdown_pipeline(self):
|
||||
"""Test Python file -> parse -> generate markdown."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f:
|
||||
f.write(b'''
|
||||
def calculate(a, b):
|
||||
"""Calculate sum of two numbers.
|
||||
|
||||
Args:
|
||||
a: First number.
|
||||
b: Second number.
|
||||
|
||||
Returns:
|
||||
The sum of a and b.
|
||||
"""
|
||||
return a + b
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_python_file(Path(f.name))
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".md", delete=False) as out:
|
||||
output_path = Path(out.name)
|
||||
result = generate_markdown([{"file": str(f.name), "data": parsed}], output_path)
|
||||
|
||||
assert "#" in result
|
||||
assert "calculate" in result.lower()
|
||||
assert "Parameters" in result
|
||||
|
||||
output_path.unlink()
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_python_to_html_pipeline(self):
|
||||
"""Test Python file -> parse -> generate HTML."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f:
|
||||
f.write(b'''
|
||||
class Calculator:
|
||||
"""A simple calculator class."""
|
||||
|
||||
def add(self, a, b):
|
||||
"""Add two numbers.
|
||||
|
||||
Args:
|
||||
a: First number.
|
||||
b: Second number.
|
||||
|
||||
Returns:
|
||||
The sum.
|
||||
"""
|
||||
return a + b
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_python_file(Path(f.name))
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as out:
|
||||
output_path = Path(out.name)
|
||||
result = generate_html([{"file": str(f.name), "data": parsed}], output_path)
|
||||
|
||||
assert "<!DOCTYPE html>" in result
|
||||
assert "<title>" in result
|
||||
assert "Calculator" in result
|
||||
|
||||
output_path.unlink()
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_go_pipeline(self):
|
||||
"""Test Go file parsing and generation."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".go", delete=False) as f:
|
||||
f.write(b'''
|
||||
// Package math provides math utilities.
|
||||
//
|
||||
// This is a simple math package.
|
||||
package math
|
||||
|
||||
// Add adds two integers.
|
||||
//
|
||||
// a: First integer
|
||||
// b: Second integer
|
||||
//
|
||||
// Returns: The sum
|
||||
func Add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_go_file(Path(f.name))
|
||||
assert parsed["language"] == "go"
|
||||
assert len(parsed["functions"]) >= 1
|
||||
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_javascript_pipeline(self):
|
||||
"""Test JavaScript file parsing and generation."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".js", delete=False) as f:
|
||||
f.write(b'''
|
||||
/**
|
||||
* Multiplies two numbers.
|
||||
*
|
||||
* @param {number} a - First number
|
||||
* @param {number} b - Second number
|
||||
* @returns {number} The product
|
||||
*/
|
||||
function multiply(a, b) {
|
||||
return a * b;
|
||||
}
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_javascript_file(Path(f.name))
|
||||
assert parsed["language"] == "javascript"
|
||||
assert len(parsed["functions"]) == 1
|
||||
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_typescript_pipeline(self):
|
||||
"""Test TypeScript file parsing and generation."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".ts", delete=False) as f:
|
||||
f.write(b'''
|
||||
/**
|
||||
* Divides two numbers.
|
||||
*
|
||||
* @param numerator - The numerator
|
||||
* @param denominator - The denominator
|
||||
* @returns The quotient
|
||||
*/
|
||||
function divide(numerator: number, denominator: number): number {
|
||||
return numerator / denominator;
|
||||
}
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
parsed = parse_javascript_file(Path(f.name))
|
||||
assert parsed["language"] == "javascript"
|
||||
assert len(parsed["functions"]) >= 1
|
||||
|
||||
Path(f.name).unlink()
|
||||
|
||||
|
||||
class TestCLIIntegration:
|
||||
"""Integration tests for CLI commands."""
|
||||
|
||||
def test_cli_generate_command(self):
|
||||
"""Test the full generate CLI command."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f:
|
||||
f.write(b'''
|
||||
def example():
|
||||
"""An example function."""
|
||||
pass
|
||||
''')
|
||||
f.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".1", delete=False) as out:
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, [
|
||||
"generate",
|
||||
f.name,
|
||||
"--output", out.name,
|
||||
"--format", "man"
|
||||
])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert Path(out.name).exists()
|
||||
out_path = Path(out.name)
|
||||
assert out_path.stat().st_size > 0
|
||||
|
||||
out_path.unlink()
|
||||
Path(f.name).unlink()
|
||||
|
||||
def test_cli_multiple_files(self):
|
||||
"""Test generating from multiple files."""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f1:
|
||||
f1.write(b'''
|
||||
def func1():
|
||||
"""First function."""
|
||||
pass
|
||||
''')
|
||||
f1.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f2:
|
||||
f2.write(b'''
|
||||
def func2():
|
||||
"""Second function."""
|
||||
pass
|
||||
''')
|
||||
f2.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".md", delete=False) as out:
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, [
|
||||
"generate",
|
||||
f1.name, f2.name,
|
||||
"--output", out.name,
|
||||
"--format", "markdown"
|
||||
])
|
||||
|
||||
assert result.exit_code == 0
|
||||
content = Path(out.name).read_text()
|
||||
assert "func1" in content or "func2" in content
|
||||
|
||||
out_path = Path(out.name)
|
||||
out_path.unlink()
|
||||
|
||||
Path(f1.name).unlink()
|
||||
Path(f2.name).unlink()
|
||||
Reference in New Issue
Block a user