301 lines
9.0 KiB
Python
301 lines
9.0 KiB
Python
"""Unit tests for parsers."""
|
|
|
|
import pytest
|
|
import os
|
|
from code_doc_cli.parsers.python_parser import PythonParser
|
|
from code_doc_cli.parsers.typescript_parser import TypeScriptParser
|
|
from code_doc_cli.parsers.go_parser import GoParser
|
|
from code_doc_cli.parsers.registry import ParserRegistry
|
|
from code_doc_cli.parsers.base import ElementType
|
|
import tempfile
|
|
|
|
|
|
class TestPythonParser:
|
|
"""Tests for Python parser."""
|
|
|
|
def test_parse_function(self):
|
|
"""Test parsing a Python function."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
f.write('''
|
|
def add(a: int, b: int) -> int:
|
|
"""Add two numbers together.
|
|
|
|
Args:
|
|
a: First number
|
|
b: Second number
|
|
|
|
Returns:
|
|
The sum of a and b
|
|
"""
|
|
return a + b
|
|
''')
|
|
f.flush()
|
|
|
|
parser = PythonParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
assert len(elements) > 0
|
|
|
|
func_names = [e.name for e in elements]
|
|
assert "add" in func_names
|
|
|
|
add_elem = next(e for e in elements if e.name == "add")
|
|
assert add_elem.element_type == ElementType.FUNCTION
|
|
assert len(add_elem.parameters) == 2
|
|
|
|
def test_parse_class(self):
|
|
"""Test parsing a Python class."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
f.write('''
|
|
class Calculator:
|
|
"""A simple calculator class."""
|
|
|
|
def __init__(self, initial: int = 0):
|
|
"""Initialize calculator."""
|
|
self.memory = initial
|
|
|
|
def multiply(self, x: int, y: int) -> int:
|
|
"""Multiply two numbers."""
|
|
return x * y
|
|
''')
|
|
f.flush()
|
|
|
|
parser = PythonParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
class_names = [e.name for e in elements]
|
|
assert "Calculator" in class_names
|
|
|
|
calc_elem = next(e for e in elements if e.name == "Calculator")
|
|
assert calc_elem.element_type == ElementType.CLASS
|
|
|
|
def test_parse_module(self):
|
|
"""Test parsing module docstring."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
f.write('''"""This is a test module."""
|
|
|
|
def test_func():
|
|
pass
|
|
''')
|
|
f.flush()
|
|
|
|
parser = PythonParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
module_elems = [e for e in elements if e.element_type == ElementType.MODULE]
|
|
assert len(module_elems) == 1
|
|
assert "test module" in module_elems[0].description.lower()
|
|
|
|
def test_language_name(self):
|
|
"""Test language name detection."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
f.write("x = 1\n")
|
|
f.flush()
|
|
|
|
parser = PythonParser(f.name)
|
|
os.unlink(f.name)
|
|
|
|
assert parser.get_language_name() == "python"
|
|
|
|
def test_supports_file(self):
|
|
"""Test file extension support."""
|
|
assert PythonParser.supports_file("test.py")
|
|
assert PythonParser.supports_file("test.pyw")
|
|
assert not PythonParser.supports_file("test.ts")
|
|
assert not PythonParser.supports_file("test.go")
|
|
|
|
|
|
class TestTypeScriptParser:
|
|
"""Tests for TypeScript parser."""
|
|
|
|
def test_parse_function(self):
|
|
"""Test parsing a TypeScript function."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".ts", delete=False) as f:
|
|
f.write('''
|
|
export function add(a: number, b: number): number {
|
|
return a + b;
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = TypeScriptParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
func_names = [e.name for e in elements if e.element_type == ElementType.FUNCTION]
|
|
assert "add" in func_names
|
|
|
|
def test_parse_interface(self):
|
|
"""Test parsing a TypeScript interface."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".ts", delete=False) as f:
|
|
f.write('''
|
|
export interface User {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = TypeScriptParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
interface_names = [e.name for e in elements if e.element_type == ElementType.INTERFACE]
|
|
assert "User" in interface_names
|
|
|
|
def test_parse_class(self):
|
|
"""Test parsing a TypeScript class."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".ts", delete=False) as f:
|
|
f.write('''
|
|
export class Calculator {
|
|
private memory: number;
|
|
|
|
constructor(initial: number = 0) {
|
|
this.memory = initial;
|
|
}
|
|
|
|
public multiply(x: number, y: number): number {
|
|
return x * y;
|
|
}
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = TypeScriptParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
class_names = [e.name for e in elements if e.element_type == ElementType.CLASS]
|
|
assert "Calculator" in class_names
|
|
|
|
def test_language_name(self):
|
|
"""Test language name detection."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".ts", delete=False) as f:
|
|
f.write("const x = 1;\n")
|
|
f.flush()
|
|
|
|
parser = TypeScriptParser(f.name)
|
|
os.unlink(f.name)
|
|
|
|
assert parser.get_language_name() == "typescript"
|
|
|
|
def test_supports_file(self):
|
|
"""Test file extension support."""
|
|
assert TypeScriptParser.supports_file("test.ts")
|
|
assert TypeScriptParser.supports_file("test.tsx")
|
|
assert not TypeScriptParser.supports_file("test.py")
|
|
|
|
|
|
class TestGoParser:
|
|
"""Tests for Go parser."""
|
|
|
|
def test_parse_function(self):
|
|
"""Test parsing a Go function."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".go", delete=False) as f:
|
|
f.write('''
|
|
package main
|
|
|
|
func Add(a, b int) int {
|
|
return a + b
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = GoParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
func_names = [e.name for e in elements if e.element_type == ElementType.FUNCTION]
|
|
assert "Add" in func_names
|
|
|
|
def test_parse_struct(self):
|
|
"""Test parsing a Go struct."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".go", delete=False) as f:
|
|
f.write('''
|
|
package main
|
|
|
|
type Calculator struct {
|
|
memory int
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = GoParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
struct_names = [e.name for e in elements if e.element_type == ElementType.STRUCT]
|
|
assert "Calculator" in struct_names
|
|
|
|
def test_parse_package(self):
|
|
"""Test parsing package docstring."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".go", delete=False) as f:
|
|
f.write('''// Package main provides math functions.
|
|
package main
|
|
|
|
func Add(a, b int) int {
|
|
return a + b
|
|
}
|
|
''')
|
|
f.flush()
|
|
|
|
parser = GoParser(f.name)
|
|
elements = parser.parse()
|
|
|
|
os.unlink(f.name)
|
|
|
|
module_elems = [e for e in elements if e.element_type == ElementType.MODULE]
|
|
assert len(module_elems) >= 1
|
|
|
|
def test_language_name(self):
|
|
"""Test language name detection."""
|
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".go", delete=False) as f:
|
|
f.write("package main\n")
|
|
f.flush()
|
|
|
|
parser = GoParser(f.name)
|
|
os.unlink(f.name)
|
|
|
|
assert parser.get_language_name() == "go"
|
|
|
|
def test_supports_file(self):
|
|
"""Test file extension support."""
|
|
assert GoParser.supports_file("test.go")
|
|
assert not GoParser.supports_file("test.py")
|
|
|
|
|
|
class TestParserRegistry:
|
|
"""Tests for parser registry."""
|
|
|
|
def test_get_parser_class(self):
|
|
"""Test getting parser class by language."""
|
|
assert ParserRegistry.get_parser_class("python") == PythonParser
|
|
assert ParserRegistry.get_parser_class("py") == PythonParser
|
|
assert ParserRegistry.get_parser_class("typescript") == TypeScriptParser
|
|
assert ParserRegistry.get_parser_class("ts") == TypeScriptParser
|
|
assert ParserRegistry.get_parser_class("go") == GoParser
|
|
|
|
def test_get_language_from_extension(self):
|
|
"""Test language detection from extension."""
|
|
assert ParserRegistry.get_language_from_extension("test.py") == "python"
|
|
assert ParserRegistry.get_language_from_extension("test.ts") == "typescript"
|
|
assert ParserRegistry.get_language_from_extension("test.go") == "go"
|
|
|
|
def test_get_supported_languages(self):
|
|
"""Test getting supported languages."""
|
|
languages = ParserRegistry.get_supported_languages()
|
|
assert "python" in languages
|
|
assert "typescript" in languages
|
|
assert "go" in languages
|