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

RI007_Stationing-property #64

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
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
39 changes: 39 additions & 0 deletions features/RI007_Stationing-property.feature
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All scenarios should not have the same name.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@implementer-agreement
@RI
Feature: RI007 - Stationing property
The rule verifies, that station information can be exported in IFC using Pset_Stationing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The rule verifies, that station information can be exported in IFC using Pset_Stationing.
The rule verifies that station information is present in IFC using Pset_Stationing.


Scenario: Agreement on alignment stationing

Given A file with Schema Identifier "IFC4X3_TC1" or "IFC4X3_ADD1" or "IFC4X3"
And An IfcReferent
And Its attribute Name
Then The value must exist

Scenario: Agreement on alignment stationing

Given A file with Schema Identifier "IFC4X3_TC1" or "IFC4X3_ADD1" or "IFC4X3"
And An IfcReferent
And Its attribute IsDefinedBy
And Its attribute RelatingPropertyDefinition
And Its attribute Name
Comment on lines +18 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would allow a IfcQuantitySet to pass as well. We need to reconsider this.

Then The value must exist

Scenario: Agreement on alignment stationing

Given A file with Schema Identifier "IFC4X3_TC1" or "IFC4X3_ADD1" or "IFC4X3"
And An IfcReferent
And Its attribute IsDefinedBy
And Its attribute RelatingPropertyDefinition
And Its attribute HasProperties
Then The value of attribute Name must be Station

Scenario: Agreement on alignment stationing

Given A file with Schema Identifier "IFC4X3_TC1" or "IFC4X3_ADD1" or "IFC4X3"
And An IfcReferent
And Its attribute IsDefinedBy
And Its attribute RelatingPropertyDefinition
And Its attribute HasProperties
And Its attribute NominalValue
Then The value must exist
Comment on lines +22 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not agree with splitting this up in independent scenarios.

For example, any attached property with NominalValue non empty would pass the bottom test. The requirement was that the property named Station would have a non empty value.

7 changes: 7 additions & 0 deletions features/steps/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ class InvalidValueError:
def __str__(self):
return f"On instance {misc.fmt(self.related)} the following invalid value for {self.attribute} has been found: {self.value}"

@dataclass
class MissingValueError:
related: ifcopenshell.entity_instance

def __str__(self):
return f"On instance {misc.fmt(self.related)} the value doesn't exist"
Comment on lines +121 to +126
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value of what?



@dataclass
class PolyobjectDuplicatePointsError:
Expand Down
20 changes: 18 additions & 2 deletions features/steps/thens/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,31 @@ 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:
if isinstance(inst, tuple):
inst = inst[0]
related_entity = getattr(inst, attribute, [])
if not related_entity.is_a(expected_entity_type):
if isinstance(related_entity, tuple):
related_entity = related_entity[0]
if isinstance(related_entity, list) or (not related_entity.is_a(expected_entity_type)):
yield err.AttributeTypeError(inst, [related_entity], attribute, expected_entity_type)

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 instance in context.instances:
while isinstance(instance, tuple):
instance = instance[0]
attribute_value = getattr(instance, attribute, 'Attribute not found')
if attribute_value != value:
errors.append(err.InvalidValueError(instance, attribute, attribute_value))

misc.handle_errors(context, errors)
10 changes: 8 additions & 2 deletions features/steps/thens/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def step_impl(context, constraint, num=None):
stack_tree = list(
filter(None, list(map(lambda layer: layer.get('instances'), context._stack))))
instances = [context.instances] if within_model else context.instances

if constraint in ('identical', 'unique'):
for i, values in enumerate(instances):
if not values:
Expand Down Expand Up @@ -62,5 +61,12 @@ def step_impl(context, constraint, num=None):
for iv, value in enumerate(values):
if not value in valid_values:
errors.append(err.InvalidValueError([t[i] for t in stack_tree][1][iv], attribute, value))

if constraint in ('exist',):
for inst, related_instance in zip(instances, stack_tree[1]):
while isinstance(inst, tuple):
inst = inst[0]
if isinstance(inst, tuple) and not any(inst):
errors.append(err.MissingValueError(related_instance))
elif not inst:
errors.append(err.MissingValueError(related_instance))
misc.handle_errors(context, errors)
10 changes: 10 additions & 0 deletions test/files/ri007/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
| File name | Expected result | Error log | Description |
|-----------------------------------------------------------------------------------|-----------------|-----------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| pass-ri007-stationing-property | success | n.a. | |
| fail-ri007-scenario01-no-name-attribute-of-ifcreferent-default | fail | On instance #532=IfcReferent('13nJTlK...ATION.) the value doesn't exist | A value was expected for Name attribute of #532=IfcReferent(), but $ was found |
| fail-ri007-scenario01-no-name-attribute-of-ifcreferent-empty | fail | On instance #532=IfcReferent('13nJTlK...ION.,$) the value doesn't exist | A value was expected for Name attribute of #532=IfcReferent(), but '' was found |
| fail-ri007-scenario02-no-name-attribute-of-ifcpropertyset-default | fail | On instance (#536=IfcPropertySet('0oZ...537)),) the value doesn't exist | A value was expected for Name attribute of #536=IfcPropertySet(), but $ was found |
| fail-ri007-scenario02-no-name-attribute-of-ifcpropertyset-empty | fail | On instance (#536=IfcPropertySet('0oZ...537)),) the value doesn't exist | A value was expected for Name attribute of #536=IfcPropertySet(), but '' was found |
| fail-ri007-scenario03-wrong-name-value | fail | On instance #537=IfcPropertySingleVal...3.1),$) the following invalid value for Name has been found: Body | The expected IfcPropertySingleValue value was Station. |
| fail-ri007-scenario04-no-nominalvalue-attribute-of-ifcpropertysinglevalue-default | fail | On instance ((#537=IfcPropertySingleV...,$),),) the value doesn't exist | A value was expected for NominalValue attribute of #537=IFCPROPERTYSINGLEVALUE(), but $ was found |
| fail-ri007-scenario04-no-nominalvalue-attribute-of-ifcpropertysinglevalue-empty | fail | On instance ((#537=IfcPropertySingleV...,$),),) the value doesn't exist | A value was expected for NominalValue attribute of #537=IFCPROPERTYSINGLEVALUE(), but '' was found |