- Use importlib.metadata for dynamic version (single source in pyproject.toml) - Clean up duplicate `import re` statements across modules - Add missing type hints to all public methods - Fix PATH auto-discovery for ilspycmd (~/.dotnet/tools) - Add pytest test suite with 35 tests covering models, metadata reader, wrapper - Bump version to 0.2.0, add CHANGELOG.md
113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
"""Tests for mcilspy.metadata_reader module."""
|
|
|
|
import pytest
|
|
|
|
from mcilspy.metadata_reader import MetadataReader
|
|
|
|
|
|
class TestMetadataReader:
|
|
"""Tests for MetadataReader class."""
|
|
|
|
def test_init_with_nonexistent_file(self, nonexistent_path):
|
|
"""Test that initializing with nonexistent file raises error."""
|
|
with pytest.raises(FileNotFoundError):
|
|
MetadataReader(nonexistent_path)
|
|
|
|
def test_context_manager(self, sample_assembly_path):
|
|
"""Test using MetadataReader as context manager."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
assert reader is not None
|
|
# Should be able to read metadata
|
|
meta = reader.get_assembly_metadata()
|
|
assert meta.name is not None
|
|
|
|
def test_get_assembly_metadata(self, sample_assembly_path):
|
|
"""Test reading assembly metadata."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
meta = reader.get_assembly_metadata()
|
|
|
|
# Basic fields should be populated
|
|
assert meta.name is not None
|
|
assert len(meta.name) > 0
|
|
assert meta.version is not None
|
|
assert meta.type_count >= 0
|
|
assert meta.method_count >= 0
|
|
|
|
def test_list_methods(self, sample_assembly_path):
|
|
"""Test listing methods from assembly."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
methods = reader.list_methods()
|
|
|
|
# Should find some methods
|
|
assert len(methods) > 0
|
|
|
|
# Each method should have required fields
|
|
for method in methods[:5]: # Check first 5
|
|
assert method.name is not None
|
|
assert method.declaring_type is not None
|
|
|
|
def test_list_methods_with_filter(self, sample_assembly_path):
|
|
"""Test listing methods with type filter."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
# First get unfiltered list
|
|
all_methods = reader.list_methods()
|
|
|
|
if len(all_methods) > 0:
|
|
# Get a type name from the first method
|
|
declaring_type = all_methods[0].declaring_type
|
|
|
|
# Filter by that type
|
|
filtered = reader.list_methods(type_filter=declaring_type)
|
|
|
|
# Filtered should be subset
|
|
assert len(filtered) <= len(all_methods)
|
|
# All filtered methods should contain the type name
|
|
for method in filtered:
|
|
assert declaring_type.lower() in method.declaring_type.lower()
|
|
|
|
def test_list_fields(self, sample_assembly_path):
|
|
"""Test listing fields from assembly."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
fields = reader.list_fields()
|
|
# Fields list may be empty for some assemblies
|
|
assert isinstance(fields, list)
|
|
|
|
def test_list_properties(self, sample_assembly_path):
|
|
"""Test listing properties from assembly."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
props = reader.list_properties()
|
|
assert isinstance(props, list)
|
|
|
|
def test_list_events(self, sample_assembly_path):
|
|
"""Test listing events from assembly."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
events = reader.list_events()
|
|
assert isinstance(events, list)
|
|
|
|
def test_list_resources(self, sample_assembly_path):
|
|
"""Test listing embedded resources from assembly."""
|
|
with MetadataReader(sample_assembly_path) as reader:
|
|
resources = reader.list_resources()
|
|
assert isinstance(resources, list)
|
|
|
|
|
|
class TestMetadataReaderHelpers:
|
|
"""Tests for MetadataReader helper methods."""
|
|
|
|
def test_split_type_name_simple(self):
|
|
"""Test splitting simple type names."""
|
|
# Import the wrapper to access the static method
|
|
from mcilspy.ilspy_wrapper import ILSpyWrapper
|
|
|
|
assert ILSpyWrapper._split_type_name("MyClass") == ("MyClass", None)
|
|
assert ILSpyWrapper._split_type_name("NS.MyClass") == ("MyClass", "NS")
|
|
assert ILSpyWrapper._split_type_name("Deep.NS.MyClass") == ("MyClass", "Deep.NS")
|
|
|
|
def test_split_type_name_nested(self):
|
|
"""Test splitting nested type names."""
|
|
from mcilspy.ilspy_wrapper import ILSpyWrapper
|
|
|
|
assert ILSpyWrapper._split_type_name("NS.Outer+Nested") == ("Outer+Nested", "NS")
|
|
assert ILSpyWrapper._split_type_name("Outer+Nested") == ("Outer+Nested", None)
|
|
assert ILSpyWrapper._split_type_name("NS.A+B+C") == ("A+B+C", "NS")
|