Skip to content

Commit 547de50

Browse files
committed
increase test coverage + fix for IMPLEMENTATION_LEVEL
1 parent 9400d24 commit 547de50

5 files changed

Lines changed: 104 additions & 10 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
ISO-10303-21;
2+
HEADER;
3+
FILE_DESCRIPTION(('ViewDefinition [ReferenceView_V1.2]', 'ExchangeRequirement [Any]')); /* missing implementation level */
4+
FILE_NAME('Header example2.ifc', '2022-09-16T10:35:07', ('Evandro Alfieri'), ('buildingSMART Int.'), 'IFC Motor 1.0', 'Company - Application - 26.0.0.0', 'none');
5+
FILE_SCHEMA(('IFC4'));
6+
ENDSEC;
7+
DATA;
8+
#1=IFCPERSON($,$,'',$,$,$,$,$);
9+
#2=IFCORGANIZATION($,'',$,$,$);
10+
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
11+
#4=IFCAPPLICATION(#2,'v0.7.0-6c9e130ca','IfcOpenShell-v0.7.0-6c9e130ca','');
12+
#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,#3,#4,1700419055);
13+
#6=IFCDIRECTION((1.,0.,0.));
14+
#7=IFCDIRECTION((0.,0.,1.));
15+
#8=IFCCARTESIANPOINT((0.,0.,0.));
16+
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
17+
#10=IFCDIRECTION((0.,1.));
18+
#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10);
19+
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
20+
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
21+
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
22+
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
23+
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
24+
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
25+
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
26+
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
27+
#20=IFCPROJECT('0iDmeiiLP3AOllitM2Favn',#5,'',$,$,$,$,(#11),#19);
28+
#21=IFCSITE('3rg2jGkIH10RFhrQsGZKRk',#5,$,$,$,$,$,$,$,$,$,$,$,$);
29+
ENDSEC;
30+
END-ISO-10303-21;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
ISO-10303-21;
2+
HEADER;
3+
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'4;5'); /* should be '2;1' */
4+
FILE_NAME('Header example2.ifc', '2022-09-16T10:35:07', ('Evandro Alfieri'), ('buildingSMART Int.'), 'IFC Motor 1.0', 'Company - Application - 26.0.0.0', 'none');
5+
FILE_SCHEMA(('IFC4'));
6+
ENDSEC;
7+
DATA;
8+
#1=IFCPERSON($,$,'',$,$,$,$,$);
9+
#2=IFCORGANIZATION($,'',$,$,$);
10+
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
11+
#4=IFCAPPLICATION(#2,'v0.7.0-6c9e130ca','IfcOpenShell-v0.7.0-6c9e130ca','');
12+
#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,#3,#4,1700419055);
13+
#6=IFCDIRECTION((1.,0.,0.));
14+
#7=IFCDIRECTION((0.,0.,1.));
15+
#8=IFCCARTESIANPOINT((0.,0.,0.));
16+
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
17+
#10=IFCDIRECTION((0.,1.));
18+
#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10);
19+
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
20+
#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
21+
#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
22+
#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
23+
#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
24+
#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16);
25+
#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17);
26+
#19=IFCUNITASSIGNMENT((#13,#14,#15,#18));
27+
#20=IFCPROJECT('0iDmeiiLP3AOllitM2Favn',#5,'',$,$,$,$,(#11),#19);
28+
#21=IFCSITE('3rg2jGkIH10RFhrQsGZKRk',#5,$,$,$,$,$,$,$,$,$,$,$,$);
29+
ENDSEC;
30+
END-ISO-10303-21;

parser/parse.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424

2525
def validate_header_fields(header, error_collector, only_header=False):
26+
27+
# all required fields present
2628
for field in HEADER_FIELDS.keys():
2729
observed = header.get(field.upper(), [])
2830
expected = HEADER_FIELDS.get(field)._fields
@@ -33,6 +35,16 @@ def validate_header_fields(header, error_collector, only_header=False):
3335
if only_header:
3436
error_collector.raise_if_any()
3537

38+
# implementation level should be present and equal to "2;1"
39+
file_description = header.get('FILE_DESCRIPTION')
40+
implementation_level = None if len(file_description) < 2 else file_description[1]
41+
if implementation_level != "2;1":
42+
error_collector.add(
43+
HeaderFieldError("IMPLEMENTATION_LEVEL", implementation_level, "2;1")
44+
)
45+
if only_header:
46+
error_collector.raise_if_any()
47+
3648

3749
@dataclass
3850
class ParseResult:

test_parser.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def test_file_without_tree(file):
4646
for sub in [
4747
"fail_too_many_header_entity_fields.ifc",
4848
"fail_multiple_wrong_header_fields",
49+
"fail_missing_implementation_level.ifc",
50+
"fail_wrong_implementation_level.ifc"
4951
]
5052
):
5153
pytest.skip(
@@ -66,11 +68,12 @@ def test_parse_features():
6668
assert f[1][0] is None
6769
assert f.header.file_description[0][0] == "ViewDefinition [CoordinationView]"
6870
assert f.header_.get("FILE_DESCRIPTION")[0][0]
71+
assert f.header_.get("FILE_DESCRIPTION")[1] == "2;1"
6972
assert f.by_type("ifcapplication")[1][2] == "Nested ' quotes"
7073

7174

7275
def test_parse_valid_header():
73-
f = open("fixtures/passing_header.ifc")
76+
f = open("fixtures/pass_header.ifc")
7477

7578
expected_description = {
7679
"description": ("ViewDefinition [Alignment-basedView]",),
@@ -102,7 +105,7 @@ def test_parse_valid_header():
102105

103106

104107
def test_header_only_api():
105-
f = open("fixtures/passing_header.ifc", only_header=True)
108+
f = open("fixtures/pass_header.ifc", only_header=True)
106109
expected_description = {
107110
"description": ("ViewDefinition [Alignment-basedView]",),
108111
"implementation_level": "2;1",
@@ -155,7 +158,9 @@ def test_file_mvd_attr():
155158
[
156159
"fixtures/fail_invalid_header_entity.ifc",
157160
"fixtures/fail_no_header.ifc",
158-
],
161+
"fixtures/fail_missing_implementation_level.ifc",
162+
"fixtures/fail_wrong_implementation_level.ifc",
163+
]
159164
)
160165
def test_invalid_headers_(filename):
161166
# error in header
@@ -205,7 +210,7 @@ def test_multiple_wrong_header_fields():
205210

206211
errors = exc_info.value.errors
207212

208-
assert len(errors) == 2
213+
assert len(errors) == 3
209214
assert all(isinstance(e, HeaderFieldError) for e in errors)
210215

211216

@@ -216,27 +221,44 @@ def test_multiple_wrong_header_fields():
216221

217222
def run_cli(*args):
218223
return subprocess.run(
219-
["python", "-m", MODULE_NAME, *args],
224+
["python3", "-m", MODULE_NAME, *args],
220225
capture_output=True,
221226
text=True,
222227
cwd=PARENT_DIR,
223228
)
224229

225230

226-
def test_cli_valid_file():
227-
result = run_cli("step-file-parser/fixtures/passing_header.ifc")
231+
@pytest.mark.parametrize("filename", glob.glob("fixtures/pass*.ifc"))
232+
@pytest.mark.parametrize("only_header", [False, True])
233+
def test_cli_valid_file(filename, only_header):
234+
args = []
235+
if only_header: args.append('--only-header')
236+
result = run_cli(f'step-file-parser/{filename}', *args)
228237
assert result.returncode == 0
229238
assert "Valid" in result.stderr
230239

231240

232-
def test_cli_invalid_file():
241+
@pytest.mark.parametrize("filename", glob.glob("fixtures/pass*.ifc"))
242+
@pytest.mark.parametrize("only_header", [False, True])
243+
def test_cli_valid_file_json_output(filename, only_header):
244+
args = ['--json']
245+
if only_header: args.append('--only-header')
246+
result = run_cli(f'step-file-parser/{filename}', *args)
247+
assert result.returncode == 0
248+
assert result.stderr.strip() == ""
249+
assert result.stdout.strip() == ""
250+
251+
252+
def test_cli_fail_no_header():
233253
result = run_cli("step-file-parser/fixtures/fail_no_header.ifc")
234254
assert result.returncode == 1
255+
assert result.stderr.strip() != ""
235256

236257

237-
def test_cli_json_output():
238-
result = run_cli("--json", "step-file-parser/fixtures/fail_no_header.ifc")
258+
def test_cli_fail_no_header_json_output():
259+
result = run_cli("step-file-parser/fixtures/fail_no_header.ifc", "--json")
239260
assert result.returncode == 1
261+
assert result.stdout.strip() != ""
240262
errors = json.loads(result.stdout)
241263
assert isinstance(errors, list)
242264
assert len(errors) > 0

0 commit comments

Comments
 (0)