mcilspy/tests/test_models.py
Ryan Malloy 70c4a4a39a test: comprehensive test suite for mcilspy MCP server
Add complete test coverage for the mcilspy package:

- T7: Create TestAssembly.dll fixture with known types/members
- T1: Integration tests using real assembly (metadata reader + ILSpy wrapper)
- T2: MCP tool tests with mocked wrapper for each @mcp.tool()
- T3: Error path tests for regex, file not found, invalid assemblies
- T4: Concurrency tests with asyncio.gather() for parallel operations
- T5: Docstring coverage tests using AST introspection
- T6: Timeout behavior tests for 5-minute subprocess timeout

Test summary:
- 147 tests passing
- 14 skipped (ilspycmd-dependent integration tests)
- 73% code coverage
- All ruff linting checks pass
2026-02-08 11:40:57 -07:00

117 lines
4.1 KiB
Python

"""Tests for mcilspy.models module."""
import pytest
from mcilspy.models import (
DecompileRequest,
EntityType,
LanguageVersion,
ListTypesRequest,
TypeInfo,
)
class TestEntityType:
"""Tests for EntityType enum."""
def test_from_string_full_names(self):
"""Test parsing full entity type names."""
assert EntityType.from_string("class") == EntityType.CLASS
assert EntityType.from_string("interface") == EntityType.INTERFACE
assert EntityType.from_string("struct") == EntityType.STRUCT
assert EntityType.from_string("delegate") == EntityType.DELEGATE
assert EntityType.from_string("enum") == EntityType.ENUM
def test_from_string_short_names(self):
"""Test parsing short (single letter) entity type names."""
assert EntityType.from_string("c") == EntityType.CLASS
assert EntityType.from_string("i") == EntityType.INTERFACE
assert EntityType.from_string("s") == EntityType.STRUCT
assert EntityType.from_string("d") == EntityType.DELEGATE
assert EntityType.from_string("e") == EntityType.ENUM
def test_from_string_case_insensitive(self):
"""Test that parsing is case insensitive."""
assert EntityType.from_string("CLASS") == EntityType.CLASS
assert EntityType.from_string("Class") == EntityType.CLASS
assert EntityType.from_string("C") == EntityType.CLASS
def test_from_string_invalid(self):
"""Test that invalid strings raise ValueError."""
with pytest.raises(ValueError):
EntityType.from_string("invalid")
with pytest.raises(ValueError):
EntityType.from_string("x")
class TestLanguageVersion:
"""Tests for LanguageVersion enum."""
def test_common_versions(self):
"""Test common C# version values."""
assert LanguageVersion.LATEST.value == "Latest"
assert LanguageVersion.PREVIEW.value == "Preview"
assert LanguageVersion.CSHARP12_0.value == "CSharp12_0"
def test_version_count(self):
"""Ensure we have all expected versions."""
# Should have CSharp1 through CSharp12, plus Latest and Preview
assert len(LanguageVersion) >= 14
class TestDecompileRequest:
"""Tests for DecompileRequest model."""
def test_minimal_request(self):
"""Test creating request with only required fields."""
request = DecompileRequest(assembly_path="/path/to/assembly.dll")
assert request.assembly_path == "/path/to/assembly.dll"
assert request.language_version == LanguageVersion.LATEST
assert request.type_name is None
assert request.output_dir is None
def test_full_request(self):
"""Test creating request with all fields."""
request = DecompileRequest(
assembly_path="/path/to/assembly.dll",
language_version=LanguageVersion.CSHARP10_0,
type_name="MyNamespace.MyClass",
output_dir="/output",
create_project=True,
show_il_code=True,
)
assert request.language_version == LanguageVersion.CSHARP10_0
assert request.type_name == "MyNamespace.MyClass"
assert request.create_project is True
class TestListTypesRequest:
"""Tests for ListTypesRequest model."""
def test_default_entity_types(self):
"""Test that default entity types include common types."""
request = ListTypesRequest(assembly_path="/path/to/assembly.dll")
# Should have some default entity types
assert len(request.entity_types) > 0
assert EntityType.CLASS in request.entity_types
class TestTypeInfo:
"""Tests for TypeInfo model."""
def test_type_info_creation(self):
"""Test creating TypeInfo objects."""
info = TypeInfo(
name="MyClass",
full_name="MyNamespace.MyClass",
kind="Class",
namespace="MyNamespace",
)
assert info.name == "MyClass"
assert info.namespace == "MyNamespace"
def test_type_info_no_namespace(self):
"""Test TypeInfo with no namespace."""
info = TypeInfo(name="MyClass", full_name="MyClass", kind="Class")
assert info.namespace is None