Skip to main content
Glama
test_xsd_compliance.py5.04 kB
"""XSD Compliance tests for IDS validation. Tests that IDS files validate against the official IDS 1.0 XSD schema. """ import pytest from pathlib import Path from ifctester import ids # Get fixtures directory FIXTURES_DIR = Path(__file__).parent / "fixtures" VALID_IDS_DIR = FIXTURES_DIR / "valid_ids_files" INVALID_IDS_DIR = FIXTURES_DIR / "invalid_ids_files" @pytest.mark.asyncio async def test_valid_ids_files_pass_xsd_validation(): """Test that valid IDS fixture files pass XSD validation. Note: Due to IfcTester 0.8.3 namespace bug, files with restrictions cannot be validated with XSD. Those files are tested without XSD validation. """ valid_files = list(VALID_IDS_DIR.glob("*.ids")) assert len(valid_files) > 0, "No valid IDS fixture files found" for ids_file in valid_files: # Load and validate with IfcTester ids_obj = ids.open(str(ids_file)) # Export to XML xml_string = ids_obj.to_string() # Check if file has restrictions (these fail XSD validation due to IfcTester bug) has_restrictions = "<xs:restriction" in xml_string if not has_restrictions: # Can safely do XSD validation for files without restrictions validated_ids = ids.from_string(xml_string, validate=True) assert validated_ids is not None, f"File {ids_file.name} failed XSD validation" else: # Skip XSD validation for files with restrictions (known IfcTester bug) # Just verify we can reload without validation validated_ids = ids.from_string(xml_string, validate=False) assert validated_ids is not None, f"File {ids_file.name} failed to reload" assert validated_ids.info.get("title"), f"File {ids_file.name} has no title" @pytest.mark.asyncio async def test_simple_wall_requirement_structure(): """Test the structure of simple_wall_requirement.ids fixture.""" ids_file = VALID_IDS_DIR / "simple_wall_requirement.ids" ids_obj = ids.open(str(ids_file)) # Verify structure assert ids_obj.info.get("title") == "Simple Wall Requirement" assert len(ids_obj.specifications) == 1 spec = ids_obj.specifications[0] assert spec.name == "Wall Existence" assert len(spec.applicability) == 1 assert len(spec.requirements) == 1 # Verify applicability is entity assert isinstance(spec.applicability[0], ids.Entity) # Verify requirement is attribute assert isinstance(spec.requirements[0], ids.Attribute) # NOTE: Restriction tests moved to test_restriction_tools.py # due to IfcTester 0.8.3 XSD namespace bug preventing fixture file validation # NOTE: Invalid IDS tests removed - IfcTester's strict XSD validation # prevents loading these files at all, which is actually correct behavior. # Our validation logic is tested in test_validation_tools.py instead. @pytest.mark.asyncio async def test_round_trip_validation(): """Test that valid IDS can be loaded, exported, and re-validated. Uses simple_wall_requirement.ids (no restrictions) to avoid IfcTester bug. """ ids_file = VALID_IDS_DIR / "simple_wall_requirement.ids" # Load ids_obj = ids.open(str(ids_file)) # Export xml_string = ids_obj.to_string() # Re-load and validate (safe because no restrictions) reloaded_ids = ids.from_string(xml_string, validate=True) # Should match original structure assert len(reloaded_ids.specifications) == len(ids_obj.specifications) assert reloaded_ids.info.get("title") == ids_obj.info.get("title") # Export again xml_string_2 = reloaded_ids.to_string() # Should be able to load again reloaded_ids_2 = ids.from_string(xml_string_2, validate=True) assert reloaded_ids_2 is not None @pytest.mark.asyncio async def test_all_valid_fixtures_round_trip(): """Test round-trip (load -> export -> load) for all valid fixtures. Note: XSD validation skipped for files with restrictions due to IfcTester bug. """ valid_files = list(VALID_IDS_DIR.glob("*.ids")) assert len(valid_files) > 0, "No valid IDS fixture files found" for ids_file in valid_files: # Load (may fail XSD validation for files with restrictions) import xml.etree.ElementTree as ET tree = ET.parse(str(ids_file)) xml_string_initial = ET.tostring(tree.getroot(), encoding='unicode') ids_obj = ids.from_string(xml_string_initial, validate=False) # Export xml_string = ids_obj.to_string() # Check if has restrictions has_restrictions = "<xs:restriction" in xml_string # Re-load (with or without validation based on restrictions) reloaded_ids = ids.from_string(xml_string, validate=not has_restrictions) # Basic structure checks assert reloaded_ids is not None, f"{ids_file.name}: Failed round-trip" assert len(reloaded_ids.specifications) == len(ids_obj.specifications), \ f"{ids_file.name}: Specification count mismatch after round-trip"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vinnividivicci/ifc-ids-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server