Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALS003_Alignment-cant-shape-representation #63

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8ee3a67
add functionality to test only for specific rules
Ghesselink Feb 13, 2023
64adb32
test rules from command line
Ghesselink Feb 16, 2023
93327fa
Initial commit of RI14
JTurbakiewicz Mar 14, 2023
d2bdc79
MR comments - unified step
JTurbakiewicz Mar 19, 2023
cdd6b8e
MR comments - unified step
JTurbakiewicz Mar 19, 2023
377f4e6
re match on rule folders
Ghesselink Mar 27, 2023
3d1850e
Unifications
JTurbakiewicz Apr 23, 2023
46d5bc3
MR comments
JTurbakiewicz Apr 26, 2023
11b7275
MR comments
JTurbakiewicz Apr 26, 2023
f083d2c
include pytest -sv scenario, allow for single file test
Ghesselink May 27, 2023
6a89f11
Merge branch 'main' into ri-14-agreement-on-ifcalignmentcant-represen…
aothms Sep 18, 2023
bd56ba0
Update test/test_main.py
aothms Sep 18, 2023
c1dd5e6
Apply suggestions
aothms Sep 18, 2023
95ff46b
Merge branch 'limit-rules-tested'
aothms Sep 18, 2023
a62b750
Merge branch 'main' into ri-14-agreement-on-ifcalignmentcant-represen…
aothms Sep 18, 2023
7a82986
Small textual change for consistency
aothms Sep 18, 2023
c87d2db
Rename attribute to `inst` so that it gets treated in json
aothms Sep 18, 2023
c48cc45
Use map_state to handle multiple representations (still incorrect in …
aothms Sep 18, 2023
17d05c3
What is this?
aothms Sep 18, 2023
f7116ca
Some defensiveness (mostly for the passed rules which seem to not alw…
aothms Sep 18, 2023
7425c2e
Try to make test file a little bit less invalid
aothms Sep 18, 2023
4305b08
Always filter rule disabled/passed in tests?
aothms Sep 18, 2023
16ad7b7
ALB001 fail files should pass due to disabled rule
aothms Sep 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions features/ALB002_Alignment-layout.feature
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ This rule verifies that (a) alignment has a nesting relationship with its layout
Given an IfcAlignmentSegment
And The element nests an IfcAlignmentHorizontal

Then The type of attribute DesignParameters should be IfcAlignmentHorizontalSegment
Then The type of attribute DesignParameters must be IfcAlignmentHorizontalSegment

Scenario: Agreement of the segments of the vertical alignment

Given an IfcAlignmentSegment
And The element nests an IfcAlignmentVertical

Then The type of attribute DesignParameters should be IfcAlignmentVerticalSegment
Then The type of attribute DesignParameters must be IfcAlignmentVerticalSegment

Scenario: Agreement of the segments of the cant alignment

Given an IfcAlignmentSegment
And The element nests an IfcAlignmentCant

Then The type of attribute DesignParameters should be IfcAlignmentCantSegment
Then The type of attribute DesignParameters must be IfcAlignmentCantSegment
14 changes: 14 additions & 0 deletions features/ALS003_Alignment-cant-shape-representation.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@implementer-agreement
@ALS
Feature: ALS003 - Alignment cant shape representation
The rule verifies that each IfcAlignmentCant uses correct representation.

Scenario: Agreement on each IfcAlignmentCant using correct representation

Given A file with Schema Identifier "IFC4X3_TC1" or "IFC4X3_ADD1" or "IFC4X3"
And An IfcAlignmentCant
And Its attribute Representation
And Its attribute Representations
Then The value of attribute RepresentationIdentifier must be Axis
And The value of attribute RepresentationType must be Curve3D
And The type of attribute Items must be IfcSegmentedReferenceCurve
6 changes: 3 additions & 3 deletions features/steps/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __str__(self):
if len(self.related):
return f"The instance {self.inst} expected type '{self.expected_entity_type}' for the attribute {self.attribute}, but found {misc.fmt(self.related)} "
else:
return f"This instance {self.inst} has no value for attribute {self.attribute}"
return f"The instance {self.inst} has no value for attribute {self.attribute}"


@dataclass
Expand Down Expand Up @@ -129,12 +129,12 @@ def __str__(self):

@dataclass
class InvalidValueError(RuleState):
related: ifcopenshell.entity_instance
inst: ifcopenshell.entity_instance
attribute: str
value: str

def __str__(self):
return f"On instance {misc.fmt(self.related)} the following invalid value for {self.attribute} has been found: {self.value}"
return f"On instance {misc.fmt(self.inst)} the following invalid value for {self.attribute} has been found: {self.value}"


@dataclass
Expand Down
27 changes: 23 additions & 4 deletions features/steps/thens/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,36 @@ def step_impl(context, entity, other_entity):
misc.handle_errors(context, errors)


@then('The type of attribute {attribute} should be {expected_entity_type}')
@then('The type of attribute {attribute} must be {expected_entity_type}')
def step_impl(context, attribute, expected_entity_type):

def _():
for inst in context.instances:
related_entity = getattr(inst, attribute, [])
if not related_entity.is_a(expected_entity_type):
yield err.AttributeTypeError(False, inst, [related_entity], attribute, expected_entity_type)
related_entity = misc.map_state(inst, lambda i: getattr(i, attribute, None))
errors = []
def accumulate_errors(i):
if not i.is_a(expected_entity_type):
misc.map_state(inst, lambda x: errors.append(err.AttributeTypeError(False, x, [i], attribute, expected_entity_type)))
misc.map_state(related_entity, accumulate_errors)
if errors:
yield from errors
elif context.error_on_passed_rule:
yield err.RuleSuccessInst(True, related_entity)

misc.handle_errors(context, list(_()))


@then('The value of attribute {attribute} must be {value}')
def step_impl(context, attribute, value):
if getattr(context, 'applicable', True):
errors = []
for inst in context.instances:
if isinstance(inst, (tuple, list)):
inst = inst[0]
attribute_value = getattr(inst, attribute, 'Attribute not found')
if attribute_value != value:
errors.append(err.InvalidValueError(False, inst, attribute, attribute_value))
elif context.error_on_passed_rule:
errors.append(err.RuleSuccessInst(True, inst))

misc.handle_errors(context, errors)
1 change: 0 additions & 1 deletion features/steps/thens/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

@then('Each {entity} {condition} be {directness} contained in {other_entity}')
def step_impl(context, entity, condition, directness, other_entity):
context.run_via_pytest
stmt_to_op = ['must', 'must not']
assert condition in stmt_to_op

Expand Down
12 changes: 9 additions & 3 deletions features/steps/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ def do_try(fn, default=None):

def get_inst_attributes(dc):
if hasattr(dc, 'inst'):
yield 'inst_guid', getattr(dc.inst, 'GlobalId', None)
yield 'inst_type', dc.inst.is_a()
yield 'inst_id', dc.inst.id()
if isinstance(dc.inst, ifcopenshell.entity_instance):
yield 'inst_guid', getattr(dc.inst, 'GlobalId', None)
yield 'inst_type', dc.inst.is_a()
yield 'inst_id', dc.inst.id()
else:
# apparently mostly for the rule passed logs...
# @todo fix this
yield 'inst_guid', None
yield 'inst_type', type(dc.inst).__name__


def fmt(x):
Expand Down
6 changes: 6 additions & 0 deletions test/files/als003/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| File name | Expected result | Error log | Description |
|-------------------------------------------------------------|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
| pass-als003-alignment-cant-shape-representation | success | n.a. | |
| fail-als003-scenario01-wrong-representationidentifier-value | fail | On instance (#518=IfcShapeRepresentat...383)),) the following invalid value for RepresentationIdentifier has been found: Profile | The expected RepresentationIdentifier value was Axis. |
| fail-als003-scenario01-wrong-representationtype-value | fail | On instance (#518=IfcShapeRepresentat...383)),) the following invalid value for RepresentationType has been found: Curve2D | The expected RepresentationType value was Curve3D. |
| fail-als003-scenario01-wrong-items-type | fail | The instance #518=IfcShapeRepresentation(#17,'Axis','Curve3D',(#383)) expected type 'IfcSegmentedReferenceCurve' for the attribute Items, but found [#383=IfcPolyline((#384,#...#496))] | The expected type of Items was IfcSegmentedReferenceCurve |
Loading