import glob import pytest try: from .__init__ import ( parse, open, _ValidationError, CollectedValidationErrors, DuplicateNameError, HeaderFieldError, ) except: from __init__ import ( parse, open, _ValidationError, CollectedValidationErrors, DuplicateNameError, HeaderFieldError, ) from contextlib import nullcontext def create_context(fn): if "fail_" in fn: return pytest.raises(_ValidationError) else: return nullcontext() @pytest.mark.parametrize("file", glob.glob("fixtures/*.ifc")) def test_file_with_tree(file): with create_context(file): parse(filename=file, with_tree=True) @pytest.mark.parametrize("file", glob.glob("fixtures/*.ifc")) def test_file_without_tree(file): if any( sub in file for sub in [ "fail_too_many_header_entity_fields.ifc", "fail_multiple_wrong_header_fields", ] ): pytest.skip( "This file relies on header field validation using the parsed AST, " "but with_tree=False uses a NullTransformer that discards the AST, " "so validating the header field names is not possible in this mode." ) with create_context(file): parse(filename=file, with_tree=False) def test_parse_features(): f = open("fixtures/pass_1.ifc") assert f.by_id(1).id == 1 assert f.by_id(1).type == "IFCPERSON" assert f.data_[1][0].type == "IFCPERSON" assert f.by_type("ifcperson")[0].id == 1 assert f[1][0] is None assert f.header.file_description[0][0] == "ViewDefinition [CoordinationView]" assert f.header_.get("FILE_DESCRIPTION")[0][0] assert f.by_type("ifcapplication")[1][2] == "Nested ' quotes" def test_parse_valid_header(): f = open("fixtures/passing_header.ifc") expected_description = { "description": ("ViewDefinition [Alignment-basedView]",), "implementation_level": "2;1", } expected_name = { "name": "Header example2.ifc", "time_stamp": "2022-09-16T10:35:07", "author": ("Evandro Alfieri",), "organization": ("buildingSMART Int.",), "preprocessor_version": "IFC Motor 1.0", "originating_system": "Company - Application - 26.0.0.0", "authorization": "none", } expected_schema = { "schema_identifiers": ("IFC4X3_ADD2",), } for key, val in expected_description.items(): assert getattr(f.header.file_description, key) == val, f"{key} mismatch" for key, val in expected_name.items(): assert getattr(f.header.file_name, key) == val, f"{key} mismatch" for key, val in expected_schema.items(): assert getattr(f.header.file_schema, key) == val, f"{key} mismatch" def test_header_only_api(): f = open("fixtures/passing_header.ifc", only_header=True) expected_description = { "description": ("ViewDefinition [Alignment-basedView]",), "implementation_level": "2;1", } expected_name = { "name": "Header example2.ifc", "time_stamp": "2022-09-16T10:35:07", "author": ("Evandro Alfieri",), "organization": ("buildingSMART Int.",), "preprocessor_version": "IFC Motor 1.0", "originating_system": "Company - Application - 26.0.0.0", "authorization": "none", } expected_schema = { "schema_identifiers": ("IFC4X3_ADD2",), } for key, val in expected_description.items(): assert getattr(f.header.file_description, key) == val, f"{key} mismatch" for key, val in expected_name.items(): assert getattr(f.header.file_name, key) == val, f"{key} mismatch" for key, val in expected_schema.items(): assert getattr(f.header.file_schema, key) == val, f"{key} mismatch" def test_file_mvd_attr(): f = open("fixtures/extended_mvd.ifc", only_header=True) assert "ReferenceView_V1.2" in f.mvd.view_definitions assert all( i in f.mvd.keywords for i in ["exchange_requirements", "view_definitions", "remark", "comments"] ) assert "Ramp" in f.mvd.options["ExcludedObjects"] assert f.mvd.Remark["SomeKey"] == "SomeValue" assert len(f.mvd.comments) == 2 assert all( v in vars(f.header).keys() for v in ["file_description", "file_name", "file_schema"] ) assert len(f.header.file_name) == 7 @pytest.mark.parametrize( "filename", [ "fixtures/fail_invalid_header_entity.ifc", "fixtures/fail_no_header.ifc", ], ) def test_invalid_headers_(filename): # error in header with pytest.raises(_ValidationError): parse(filename=filename, with_tree=False, only_header=True) @pytest.mark.parametrize( "filename", [ "fixtures/fail_duplicate_id.ifc", "fixtures/fail_double_comma.ifc", "fixtures/fail_double_semi.ifc", ], ) def test_valid_headers(filename): # error in body with nullcontext(): parse(filename=filename, with_tree=False, only_header=True) def test_header_entity_fields(): with pytest.raises(_ValidationError): parse( filename="fixtures/fail_too_many_header_entity_fields.ifc", only_header=True ) def test_header_entity_fields_whole_file(): with pytest.raises(_ValidationError): parse(filename="fixtures/fail_too_many_header_entity_fields.ifc") def test_header_entity_fields_whole_file(): with pytest.raises(CollectedValidationErrors) as exc_info: parse(filename="fixtures/fail_multiple_duplicate_ids.ifc") errors = exc_info.value.errors assert len(errors) == 2 assert all(isinstance(e, DuplicateNameError) for e in errors) def test_multiple_wrong_header_fields(): with pytest.raises(CollectedValidationErrors) as exc_info: parse(filename="fixtures/fail_multiple_wrong_header_fields.ifc") errors = exc_info.value.errors assert len(errors) == 2 assert all(isinstance(e, HeaderFieldError) for e in errors)