diff --git a/features/ALB015_Alignment-business-logic-zero-length-final-segment.feature b/features/ALB015_Alignment-business-logic-zero-length-final-segment.feature index 9c6895b1..99fd4123 100644 --- a/features/ALB015_Alignment-business-logic-zero-length-final-segment.feature +++ b/features/ALB015_Alignment-business-logic-zero-length-final-segment.feature @@ -11,7 +11,7 @@ Feature: ALB015 - Alignment business logic zero length final segment Given An IfcAlignmentHorizontal Given A relationship IfcRelNests from IfcAlignmentHorizontal to IfcAlignmentSegment and following that Given Its final element at depth 1 - Given Its attribute DesignParameters + Given Its attribute "DesignParameters" Then The SegmentLength of the IfcAlignmentHorizontalSegment must be 0 Scenario: Validating final segment of vertical alignment business logic @@ -19,7 +19,7 @@ Feature: ALB015 - Alignment business logic zero length final segment Given An IfcAlignmentVertical Given A relationship IfcRelNests from IfcAlignmentVertical to IfcAlignmentSegment and following that Given Its final element at depth 1 - Given Its attribute DesignParameters + Given Its attribute "DesignParameters" Then The HorizontalLength of the IfcAlignmentVerticalSegment must be 0 Scenario: Validating final segment of cant alignment business logic @@ -27,5 +27,5 @@ Feature: ALB015 - Alignment business logic zero length final segment Given An IfcAlignmentCant Given A relationship IfcRelNests from IfcAlignmentCant to IfcAlignmentSegment and following that Given Its final element at depth 1 - Given Its attribute DesignParameters + Given Its attribute "DesignParameters" Then The HorizontalLength of the IfcAlignmentCantSegment must be 0 \ No newline at end of file diff --git a/features/ALB023_Alignment-same-segment-types-in-business-logic-and-geometry.feature b/features/ALB023_Alignment-same-segment-types-in-business-logic-and-geometry.feature index 05390472..56100b82 100644 --- a/features/ALB023_Alignment-same-segment-types-in-business-logic-and-geometry.feature +++ b/features/ALB023_Alignment-same-segment-types-in-business-logic-and-geometry.feature @@ -11,37 +11,37 @@ Background: Validating schema version Scenario: Validating the same geometry types for representation of the alignment Given An IfcAlignment - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute Item + Given its attribute "Representation" + Given its attribute "Representations" + Given Its attribute "Item" Then Each segment must have the same geometry type as its corresponding segment in the applicable IfcAlignment layout Scenario: Validating the same geometry type for representation of the horizontal layout Given An IfcAlignmentHorizontal - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute Items + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" Then Each segment must have the same geometry type as its corresponding segment in the horizontal layout Scenario: Validating the same geometry type for representation of the vertical layout Given An IfcAlignmentVertical - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute Items + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" Then Each segment must have the same geometry type as its corresponding segment in the vertical layout Scenario: Validating the same geometry type for representation of the cant layout Given An IfcAlignmentCant - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute Items + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" Then Each segment must have the same geometry type as its corresponding segment in the cant layout Scenario: Validating the same geometry type for representation of the individual segments Given An IfcAlignmentSegment - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute Items + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" Then Each segment must have the same geometry type as its corresponding alignment segment diff --git a/features/ALS004_Alignment-segment-shape-representation.feature b/features/ALS004_Alignment-segment-shape-representation.feature index 8002fb47..55f1aecd 100644 --- a/features/ALS004_Alignment-segment-shape-representation.feature +++ b/features/ALS004_Alignment-segment-shape-representation.feature @@ -7,26 +7,26 @@ The rule verifies that each IfcAlignmentSegment uses correct representation. Background: Given A model with Schema "IFC4.3" Given An IfcAlignmentSegment - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" @E00020 Scenario: Agreement on each IfcAlignmentSegment using correct representation - Value - Given Its attribute RepresentationIdentifier + Given its attribute "RepresentationIdentifier" Then The value must be "Axis" @E00020 Scenario: Agreement on each IfcAlignmentSegment using correct representation - Type - Given Its attribute RepresentationType + Given its attribute "RepresentationType" Then The value must be "Segment" @E00010 Scenario: Agreement on each IfcAlignmentSegment using correct representation items - Type - Given Its attribute Items + Given its attribute "Items" Then The value must be "IfcCurveSegment" \ No newline at end of file diff --git a/features/ALS005_Alignment-shape-representation.feature b/features/ALS005_Alignment-shape-representation.feature index 605b10fa..07f23657 100644 --- a/features/ALS005_Alignment-shape-representation.feature +++ b/features/ALS005_Alignment-shape-representation.feature @@ -7,8 +7,8 @@ The rule verifies that each IfcAlignment uses correct representation. Background: Given A model with Schema "IFC4.3" Given An IfcAlignment - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" @E00020 diff --git a/features/ALS006_Alignment-horizontal-shape-representation.feature b/features/ALS006_Alignment-horizontal-shape-representation.feature index aabe11cc..5b696f2f 100644 --- a/features/ALS006_Alignment-horizontal-shape-representation.feature +++ b/features/ALS006_Alignment-horizontal-shape-representation.feature @@ -7,8 +7,8 @@ The rule verifies that IfcAlignmentHorizontal is represented correctly with repr Background: Given A model with Schema "IFC4.3" Given An IfcAlignmentHorizontal - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" @E00020 Scenario: Agreement on each IfcAlignmentHorizontal using correct representation - Value diff --git a/features/ALS007_Alignment-vertical-shape-representation.feature b/features/ALS007_Alignment-vertical-shape-representation.feature index 2c447a89..2d93806e 100644 --- a/features/ALS007_Alignment-vertical-shape-representation.feature +++ b/features/ALS007_Alignment-vertical-shape-representation.feature @@ -7,27 +7,27 @@ The rule verifies that IfcAlignmentVertical is represented correctly with repres Background: Given A model with Schema "IFC4.3" Given An IfcAlignmentVertical - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" @version3 @E00010 Scenario: Agreement on each IfcAlignmentVertical using correct representation - Type - Given its attribute Items + Given its attribute "Items" Then The type must be "IfcGradientCurve" @E00020 Scenario: Agreement on each IfcAlignmentVertical using correct representation - Value - Given its attribute RepresentationIdentifier + Given its attribute "RepresentationIdentifier" Then The value must be "Axis" @E00020 Scenario: Agreement on each IfcAlignmentVertical using correct representation - Type - Given its attribute RepresentationType + Given its attribute "RepresentationType" Then The value must be "Curve3D" diff --git a/features/ALS008_Alignment-cant-shape-representation.feature b/features/ALS008_Alignment-cant-shape-representation.feature index b8c6543c..d09a8704 100644 --- a/features/ALS008_Alignment-cant-shape-representation.feature +++ b/features/ALS008_Alignment-cant-shape-representation.feature @@ -7,25 +7,25 @@ The rule verifies that IfcAlignmentCant is represented correctly with representa Background: Given A model with Schema "IFC4.3" Given An IfcAlignmentCant - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" @E00020 Scenario: Agreement on each IfcAlignmentCant using correct representation - Value - Given its attribute RepresentationIdentifier + Given its attribute "RepresentationIdentifier" Then The value must be "Axis" @E00020 Scenario: Agreement on each IfcAlignmentCant using correct representation - Type - Given its attribute RepresentationType + Given its attribute "RepresentationType" Then The value must be "Curve3D" @E00010 Scenario: Agreement on each IfcAlignmentCant using correct representation items - Type - Given its attribute Items + Given its attribute "Items" Then The type must be "IfcSegmentedReferenceCurve" \ No newline at end of file diff --git a/features/ALS011_Alignment-segment-entity-type-consistency.feature b/features/ALS011_Alignment-segment-entity-type-consistency.feature index be484419..bc58445d 100644 --- a/features/ALS011_Alignment-segment-entity-type-consistency.feature +++ b/features/ALS011_Alignment-segment-entity-type-consistency.feature @@ -11,7 +11,7 @@ Feature: ALS011 - Alignment segment entity type consistency Scenario Outline: Consistent entity types used Given an - Given its attribute Segments + Given its attribute "Segments" Given its entity type Then The values must be identical at depth 1 @@ -26,7 +26,7 @@ Scenario Outline: Consistent entity types used Scenario Outline: IfcCurveSegment used for IfcSegmentedReferenceCurve and IfcGradientCurve Given an - Given its attribute Segments + Given its attribute "Segments" Given its entity type Then The value must be "IfcCurveSegment" diff --git a/features/ALS012_Alignment-segment-start-and-length-attribute-types.feature b/features/ALS012_Alignment-segment-start-and-length-attribute-types.feature index 47e32595..0cd6e423 100644 --- a/features/ALS012_Alignment-segment-start-and-length-attribute-types.feature +++ b/features/ALS012_Alignment-segment-start-and-length-attribute-types.feature @@ -12,11 +12,11 @@ Feature: ALS012 - Alignment segment start and length attribute types Scenario Outline: Correct entity type used for SegmentStart and Segment Length Given A model with Schema "IFC4.3" Given An IfcAlignment - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" Given All referenced instances Given Its Entity Type is '' - Given its attribute Segments + Given its attribute "Segments" Given Its Entity Type is 'IfcCurveSegment' Then The type of attribute must be IfcLengthMeasure diff --git a/features/ALS015_Alignment-representation-zero-length-final-segment.feature b/features/ALS015_Alignment-representation-zero-length-final-segment.feature index 8b357a33..bf69ea3a 100644 --- a/features/ALS015_Alignment-representation-zero-length-final-segment.feature +++ b/features/ALS015_Alignment-representation-zero-length-final-segment.feature @@ -10,15 +10,15 @@ ends with a discontinuous segment with length = 0. Background: Validating final segment of alignment geometry (representation). Given A model with Schema "IFC4.3" Given An IfcAlignment - Given Its attribute Representation - Given Its attribute Representations - Given its attribute Items - Given its attribute Segments + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" + Given its attribute "Segments" Given Its final element at depth 1 Scenario: Validating that the final alignment geometry segment is of length 0.0. Then The SegmentLength of the segment must be 0 Scenario: Validating that the final alignment geometry segment is discontinuous. - Given Its attribute Transition + Given Its attribute "Transition" Then The value must be "DISCONTINUOUS" diff --git a/features/ALS016_Alignment-horizontal-segment-geometric-continuity.feature b/features/ALS016_Alignment-horizontal-segment-geometric-continuity.feature index 7f81248a..7d17f657 100644 --- a/features/ALS016_Alignment-horizontal-segment-geometric-continuity.feature +++ b/features/ALS016_Alignment-horizontal-segment-geometric-continuity.feature @@ -15,12 +15,12 @@ Background: Given A model with Schema "IFC4.3" Given An IfcAlignment - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" Given RepresentationType = 'Curve2D' Given All referenced instances Given Its Entity Type is 'IfcCompositeCurve' - Given Its attribute Segments + Given its attribute "Segments" Given Its Entity Type is 'IfcCurveSegment' Given The values grouped pairwise at depth 1 diff --git a/features/ANN000_Annotations.feature b/features/ANN000_Annotations.feature index 0943e5ee..0bd8993f 100644 --- a/features/ANN000_Annotations.feature +++ b/features/ANN000_Annotations.feature @@ -10,8 +10,8 @@ Feature: ANN000 - Annotations Scenario: Check for activation Given an IfcAnnotation - Given its attribute Representation - Given its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" Given RepresentationIdentifier is 'Annotation' Then The IFC model contains information on the selected functional part diff --git a/features/ASM000_Composed-elements.feature b/features/ASM000_Composed-elements.feature index ba310d18..4c08f231 100644 --- a/features/ASM000_Composed-elements.feature +++ b/features/ASM000_Composed-elements.feature @@ -12,9 +12,9 @@ Feature: ASM000 - Composed elements Scenario: Check for activation Given an IfcElement - Given its attribute Decomposes + Given its attribute "Decomposes" Given its entity type is 'IfcRelAggregates' - Given its attribute RelatingObject + Given its attribute "RelatingObject" Given its entity type is 'IfcElement' including subtypes Then The IFC model contains information on the selected functional part diff --git a/features/BRP001_Polyhedral-IfcFace-boundary-no-self-intersections.feature b/features/BRP001_Polyhedral-IfcFace-boundary-no-self-intersections.feature index 488bcc0d..c61c1d8d 100644 --- a/features/BRP001_Polyhedral-IfcFace-boundary-no-self-intersections.feature +++ b/features/BRP001_Polyhedral-IfcFace-boundary-no-self-intersections.feature @@ -10,8 +10,8 @@ IfcFace with polygonal loops are used in IFC's Boundary Representation (BRep) me Scenario: Validating that polyhedral IfcFace instances do not have self-intersections in their boundaries Given An IfcFace - Given Its attribute Bounds - Given Its attribute Bound + Given Its attribute "Bounds" + Given Its attribute "Bound" Given Its Entity Type is 'IfcPolyLoop' Then There must be no self-intersections diff --git a/features/CLS000_Classification-association.feature b/features/CLS000_Classification-association.feature index 20556e4c..5a2edd64 100644 --- a/features/CLS000_Classification-association.feature +++ b/features/CLS000_Classification-association.feature @@ -12,9 +12,9 @@ Feature: CLS000 - Classification Association Scenario: Check for activation of Classification Association Given an IfcObjectDefinition - Given its attribute HasAssociations + Given its attribute "HasAssociations" Given its entity type is 'IfcRelAssociatesClassification' - Given its attribute RelatingClassification + Given its attribute "RelatingClassification" Given its entity type is 'IfcClassificationReference' Then The IFC model contains information on the selected functional part diff --git a/features/GEM003_Unique-representation-identifier.feature b/features/GEM003_Unique-representation-identifier.feature index 18715188..e5d46e4d 100644 --- a/features/GEM003_Unique-representation-identifier.feature +++ b/features/GEM003_Unique-representation-identifier.feature @@ -8,8 +8,8 @@ The rule verifies that Shape Representation identifier is unique within the prod Scenario: A Shape Representation identifier must not be used twice within the product representation of an IfcProduct element Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given its attribute RepresentationIdentifier + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationIdentifier" Then The values must be unique \ No newline at end of file diff --git a/features/GEM004_Constraints-on-representation-identifiers.feature b/features/GEM004_Constraints-on-representation-identifiers.feature index 5e92cdde..c72ccdbb 100644 --- a/features/GEM004_Constraints-on-representation-identifiers.feature +++ b/features/GEM004_Constraints-on-representation-identifiers.feature @@ -9,9 +9,9 @@ The rule verifies that shape representations adhere to the permissible values ou Given A model with Schema "IFC4.3" Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute RepresentationIdentifier + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationIdentifier" Then The values must be in 'valid_RepresentationIdentifier_IFC4.3.csv' @@ -19,9 +19,9 @@ The rule verifies that shape representations adhere to the permissible values ou Given A model with Schema "IFC4.3" Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute RepresentationType + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationType" Then The values must be in 'valid_RepresentationType_IFC4.3.csv' @@ -30,9 +30,9 @@ The rule verifies that shape representations adhere to the permissible values ou Given A model with Schema "IFC4" Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute RepresentationIdentifier + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationIdentifier" Then The values must be in 'valid_RepresentationIdentifier_IFC4.csv' @@ -40,18 +40,18 @@ The rule verifies that shape representations adhere to the permissible values ou Given A model with Schema "IFC4" Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute RepresentationType + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationType" Then The values must be in 'valid_RepresentationType_IFC4.csv' Scenario: Shape Representation Type must be valid - IFC2X3 Given A model with Schema "IFC2X3" Given An IfcProduct - Given Its attribute Representation - Given Its attribute Representations - Given Its attribute RepresentationType + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "RepresentationType" Then The values must be in 'valid_RepresentationType_IFC2X3.csv' diff --git a/features/GEM005_Building-shape-representation.feature b/features/GEM005_Building-shape-representation.feature index af51d06d..38362441 100644 --- a/features/GEM005_Building-shape-representation.feature +++ b/features/GEM005_Building-shape-representation.feature @@ -11,7 +11,7 @@ The rule verifies that an IfcBuilding has a correct representation Given An IfcBuilding Given ContainsElements = empty Given IsDecomposedBy = empty - Given Its attribute Representation - Given Its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" Then The value of attribute RepresentationIdentifier must be Body \ No newline at end of file diff --git a/features/GEM051_Presence-of-geometric-context.feature b/features/GEM051_Presence-of-geometric-context.feature index b008277d..4ec74eec 100644 --- a/features/GEM051_Presence-of-geometric-context.feature +++ b/features/GEM051_Presence-of-geometric-context.feature @@ -10,7 +10,7 @@ The rule verifies that a geometric context is present in the model, that its att Given A model with Schema "" Given An - Given Its attribute RepresentationContexts + Given its attribute "RepresentationContexts" Then Assert existence Then Its entity type is 'IfcGeometricRepresentationContext' including subtypes @@ -26,7 +26,7 @@ The rule verifies that a geometric context is present in the model, that its att Given A model with Schema "" Given An - Given Its attribute RepresentationContexts + Given its attribute "RepresentationContexts" Then ContextType = "Model" or "Plan" or "NotDefined" diff --git a/features/GEM052_Correct-geometric-subcontexts.feature b/features/GEM052_Correct-geometric-subcontexts.feature index 1ce9acba..619672da 100644 --- a/features/GEM052_Correct-geometric-subcontexts.feature +++ b/features/GEM052_Correct-geometric-subcontexts.feature @@ -18,7 +18,7 @@ Reference: https://github.com/buildingSMART/Sample-Test-Files/issues/137. Given a model with Schema "" Given An IfcGeometricRepresentationSubContext - Given Its attribute ContextIdentifier + Given Its attribute "ContextIdentifier" Then The values must be in '' diff --git a/features/GRF001_Identical-coordinate-operations.feature b/features/GRF001_Identical-coordinate-operations.feature index 259292c9..5a637ce0 100644 --- a/features/GRF001_Identical-coordinate-operations.feature +++ b/features/GRF001_Identical-coordinate-operations.feature @@ -12,7 +12,7 @@ Currently, for GRF001, this is only permitted if (1) there is a single context o Given A model with Schema "IFC4.3" Given All instances of IfcGeometricRepresentationContext without subtypes - Given Its Attribute HasCoordinateOperation + Given Its Attribute "HasCoordinateOperation" Given Its values excluding SourceCRS Then The values must be identical at depth 1 diff --git a/features/LAY000_Presentation-layer-assignment.feature b/features/LAY000_Presentation-layer-assignment.feature index 7c6c3173..29e7ad58 100644 --- a/features/LAY000_Presentation-layer-assignment.feature +++ b/features/LAY000_Presentation-layer-assignment.feature @@ -12,9 +12,9 @@ Feature: LAY000 - Presentation Layer Assignment Scenario: Layer assignment to representation Given an IfcProduct - Given its attribute Representation - Given its attribute Representations - Given its attribute LayerAssignments + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "LayerAssignments" Then The IFC model contains information on the selected functional part @@ -22,10 +22,10 @@ Feature: LAY000 - Presentation Layer Assignment Scenario: Layer assignment to representation items Given an IfcProduct - Given its attribute Representation - Given its attribute Representations - Given its attribute Items - Given its attribute LayerAssignment + Given its attribute "Representation" + Given its attribute "Representations" + Given its attribute "Items" + Given its attribute "LayerAssignment" Then The IFC model contains information on the selected functional part \ No newline at end of file diff --git a/features/MAT000_Materials.feature b/features/MAT000_Materials.feature index 6b05cd50..27a9487e 100644 --- a/features/MAT000_Materials.feature +++ b/features/MAT000_Materials.feature @@ -12,9 +12,9 @@ Feature: MAT000 - Materials Given A model with Schema "IFC4.3" or "IFC4" Given an IfcObjectDefinition - Given its attribute HasAssociations + Given its attribute "HasAssociations" Given its entity type is 'IfcRelAssociatesMaterial' - Given its attribute RelatingMaterial + Given its attribute "RelatingMaterial" Given its entity type is 'IfcMaterialDefinition' including subtypes Then The IFC model contains information on materials assigned to elements @@ -24,7 +24,7 @@ Feature: MAT000 - Materials Given A model with Schema "IFC2X3" Given an IfcObjectDefinition - Given its attribute HasAssociations + Given its attribute "HasAssociations" Given its entity type is 'IfcRelAssociatesMaterial' Then The IFC model contains information on materials assigned to elements diff --git a/features/PJS003_Globally-Unique-Identifiers.feature b/features/PJS003_Globally-Unique-Identifiers.feature index 6296a094..fe8cd8a0 100644 --- a/features/PJS003_Globally-Unique-Identifiers.feature +++ b/features/PJS003_Globally-Unique-Identifiers.feature @@ -14,7 +14,7 @@ Feature: PJS003 - Globally Unique Identifiers Scenario Outline: Valid globally unique identifiers Given An IfcRoot - Given Its attribute GlobalId + Given Its attribute "GlobalId" Then diff --git a/features/POR000_Port-connectivity-and-nesting.feature b/features/POR000_Port-connectivity-and-nesting.feature index d300f6ba..f7f7414d 100644 --- a/features/POR000_Port-connectivity-and-nesting.feature +++ b/features/POR000_Port-connectivity-and-nesting.feature @@ -11,9 +11,9 @@ Feature: POR000 - Port Connectivity and Nesting Scenario: Check for activation Given an IfcDistributionPort - Given its attribute ConnectedFrom + Given its attribute "ConnectedFrom" Given its entity type is 'IfcRelConnectsPorts' - Given its attribute RelatingPort + Given its attribute "RelatingPort" Given its entity type is 'IfcDistributionPort' Then The IFC model contains information on port connectivity and nesting diff --git a/features/QTY000_Quantities-for-objects.feature b/features/QTY000_Quantities-for-objects.feature index 3a959132..4d419912 100644 --- a/features/QTY000_Quantities-for-objects.feature +++ b/features/QTY000_Quantities-for-objects.feature @@ -11,9 +11,9 @@ Feature: QTY000 - Quantities for Objects Scenario: Check for activation Given an IfcObject - Given its attribute IsDefinedBy + Given its attribute "IsDefinedBy" Given its entity type is 'IfcRelDefinesByProperties' - Given its attribute RelatingPropertyDefinition + Given its attribute "RelatingPropertyDefinition" Given its entity type is 'IfcElementQuantity' Then The IFC model contains information on quantities of elements diff --git a/features/SWE001_Arbitrary-profile-boundary-no-self-intersections.feature b/features/SWE001_Arbitrary-profile-boundary-no-self-intersections.feature index 322687de..1a8ee7f4 100644 --- a/features/SWE001_Arbitrary-profile-boundary-no-self-intersections.feature +++ b/features/SWE001_Arbitrary-profile-boundary-no-self-intersections.feature @@ -11,13 +11,13 @@ geometrical sweeps such as extrusions. Scenario: Validating that IfcArbitraryClosedProfileDef instances do not have self-intersections in their boundaries Given An IfcArbitraryClosedProfileDef - Given Its attribute OuterCurve + Given Its attribute "OuterCurve" Then There must be no self-intersections Scenario: Validating that IfcArbitraryProfileDefWithVoids instances do not have self-intersections in their inner boundaries Given An IfcArbitraryClosedProfileDef - Given Its attribute InnerCurves + Given Its attribute "InnerCurves" Then There must be no self-intersections diff --git a/features/SYS001_Cable-signal-flow.feature b/features/SYS001_Cable-signal-flow.feature index 1a08f705..07e0122c 100644 --- a/features/SYS001_Cable-signal-flow.feature +++ b/features/SYS001_Cable-signal-flow.feature @@ -19,6 +19,6 @@ The rule verifies that IfcCableSegment must define 2 distribution ports, 1 as a Scenario: Agreement on port directions Given There exists a relationship IfcRelNests from IfcAlignment to IfcDistributionPort and following that - Given Its attribute FlowDirection + Given Its attribute "FlowDirection" Then at least "1" value must be "SOURCE" Then at least "1" value must be "SINK" \ No newline at end of file diff --git a/features/TAS001_Polygonal-face-boundary-no-self-intersections.feature b/features/TAS001_Polygonal-face-boundary-no-self-intersections.feature index edc15f3b..615a737c 100644 --- a/features/TAS001_Polygonal-face-boundary-no-self-intersections.feature +++ b/features/TAS001_Polygonal-face-boundary-no-self-intersections.feature @@ -9,14 +9,14 @@ IfcFace with polygonal loops are used in IFC's Boundary Representation (BRep) me Scenario: Validating that tessellated face instances do not have self-intersections in their boundaries Given An IfcPolygonalFaceSet - Given Its attribute Faces + Given Its attribute "Faces" Then There must be no self-intersections for attribute CoordIndex Scenario: Validating that tessellated face instances with voids do not have self-intersections in their inner boundaries Given An IfcPolygonalFaceSet - Given Its attribute Faces + Given Its attribute "Faces" Given Its Entity Type is 'IfcIndexedPolygonalFaceWithVoids' Then There must be no self-intersections for attribute InnerCoordIndices diff --git a/features/VER000_Versioning-and-revision-control.feature b/features/VER000_Versioning-and-revision-control.feature index 952ba90a..7775eddc 100644 --- a/features/VER000_Versioning-and-revision-control.feature +++ b/features/VER000_Versioning-and-revision-control.feature @@ -8,24 +8,11 @@ Feature: VER000 - Versioning and revision control https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/concepts/Object_Attributes/Revision_Control/content.html - Scenario Outline: Check for activation + Scenario: Check for activation Given an IfcRoot - Given its attribute OwnerHistory - Given its attribute - - Then The IFC model contains information on the selected functional part - - Examples: - | attribute | - | LastModifiedDate | - | LastModifyingUser | - | LastModifyingApplication | - - - Scenario: Check for activation - ChangeAction - - Given an IfcOwnerHistory + Given its attribute "OwnerHistory" + Given its attribute "LastModifiedDate" and "LastModifyingUser" and "LastModifyingApplication" exists Given ChangeAction is not "NOTDEFINED" Then The IFC model contains information on the selected functional part diff --git a/features/steps/RULE_AUTHORING.md b/features/steps/RULE_AUTHORING.md index 199fed49..ae330e7b 100644 --- a/features/steps/RULE_AUTHORING.md +++ b/features/steps/RULE_AUTHORING.md @@ -82,8 +82,8 @@ Feature: ALS005 - Alignment shape representation Background: Given a model with Schema "IFC4.3" Given an IfcAlignment - Given Its attribute Representation - Given its attribute Representations + Given its attribute "Representation" + Given its attribute "Representations" Scenario: Agreement on each IfcAlignment using correct representation - Value diff --git a/features/steps/givens/attributes.py b/features/steps/givens/attributes.py index cf6acc85..8d421064 100644 --- a/features/steps/givens/attributes.py +++ b/features/steps/givens/attributes.py @@ -1,5 +1,4 @@ import ast -import itertools import operator import ifcopenshell @@ -8,6 +7,8 @@ from parse_type import TypeBuilder from validation_handling import gherkin_ifc, register_enum_type from . import ValidationOutcome, OutcomeSeverity +from functools import reduce +from pyparsing import quotedString, Word, alphas, oneOf, infixNotation, opAssoc from enum import Enum, auto @@ -31,7 +32,7 @@ class SubTypeHandling (Enum): class PrefixCondition(Enum): STARTS = "starts" DOES_NOT_START = "does not start" - + register_type(include_or_exclude_subtypes=TypeBuilder.make_enum({"including subtypes": SubTypeHandling.INCLUDE, "excluding subtypes": SubTypeHandling.EXCLUDE })) register_type(first_or_final=TypeBuilder.make_enum({"first": FirstOrFinal.FIRST, "final": FirstOrFinal.FINAL })) @@ -148,10 +149,43 @@ def step_impl(context, file_or_model, field, values): context.applicable = getattr(context, 'applicable', True) and applicable +operator_mapping = { + 'and': operator.and_, + 'or': operator.or_ +} # should we do this in some central place? + +def parse_attributes_and_operators(text): -@gherkin_ifc.step('Its attribute {attribute}') -def step_impl(context, inst, attribute, tail="single"): - yield ValidationOutcome(instance_id=getattr(inst, attribute, None), severity=OutcomeSeverity.PASSED) + attribute = quotedString | Word(alphas) + operators = oneOf("and or") + + parsed_result = infixNotation(attribute, [ + (operators, 2, opAssoc.LEFT), + ]).parseString(text.replace('"', ''), parseAll=True) + + for item in parsed_result.asList(): + if isinstance(item, list): + attributes = item[0::2] + operators = set(operator_mapping[i] for i in item[1::2]) + assert len(operators) == 1, 'only one operator [and/or] allowed in expression' + op = list(operators)[0] + else: # if there is only a single attribute, both operators work + attributes, operator = [item], operator.and_ + + return attributes, op + + +@gherkin_ifc.step('Its attribute "{attribute}"') +@gherkin_ifc.step('Its attribute "{attribute}" exists') +def step_impl(context, inst, attribute): + if 'exists' in context.step.name: + attributes, op = parse_attributes_and_operators(attribute) + if reduce(op, (bool(getattr(inst, attr, False)) for attr in attributes)): + yield ValidationOutcome(instance_id = inst, severity=OutcomeSeverity.PASSED) + else: + yield ValidationOutcome(instance_id = inst, expected=attributes, observed='not all required attributes are present', severity=OutcomeSeverity.ERROR) + else: + yield ValidationOutcome(instance_id=getattr(inst, attribute, None), severity=OutcomeSeverity.PASSED) @gherkin_ifc.step("Its {attribute} attribute {prefix_condition:PrefixCondition} with {prefix}") diff --git a/test/files/ver000/generate.py b/test/files/ver000/generate.py index c13df3bd..e8ad8d17 100644 --- a/test/files/ver000/generate.py +++ b/test/files/ver000/generate.py @@ -1,17 +1,29 @@ import ifcopenshell import ifcopenshell.template import uuid +from importlib.metadata import version create_guid = lambda: ifcopenshell.guid.compress(uuid.uuid1().hex) f = ifcopenshell.template.create(schema_identifier="IFC4X3_ADD2") owner = f.by_type("IfcOwnerHistory")[0] +user = f.by_type("IfcPersonAndOrganization")[0] +organization = f.by_type("IfcOrganization")[0] +person = f.by_type("IfcPerson") +application = f.by_type("IfcApplication")[0] + +organization.Name = 'Validation Service Team' f.write('na-ver000-owner_without_versioning.ifc') -f.write('pass-ver000-owner_with_change_action.ifc') +f.write('na-ver000-owner_with_change_action.ifc') f = ifcopenshell.template.create(schema_identifier="IFC4X3_ADD2") -f.by_type("IfcOwnerHistory")[0].LastModifiedDate = 1320688800 +owner.LastModifiedDate = 1320688800 + +f.write('na-ver000-owner_with_last_modify_date.ifc') + +owner.LastModifyingUser = user +owner.LastModifyingApplication = application -f.write('pass-ver000-owner_with_last_modify_date.ifc') \ No newline at end of file +f.write('pass-ver000-versioning_attributes_present.ifc') \ No newline at end of file diff --git a/test/files/ver000/pass-ver000-owner_with_change_action.ifc b/test/files/ver000/na-ver000-owner_with_last_modify_date.ifc similarity index 83% rename from test/files/ver000/pass-ver000-owner_with_change_action.ifc rename to test/files/ver000/na-ver000-owner_with_last_modify_date.ifc index 6452aa0f..1d31c679 100644 --- a/test/files/ver000/pass-ver000-owner_with_change_action.ifc +++ b/test/files/ver000/na-ver000-owner_with_last_modify_date.ifc @@ -1,7 +1,7 @@ ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); -FILE_NAME('','2024-10-23T15:47:21',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); +FILE_NAME('','2024-11-03T20:21:45',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); FILE_SCHEMA(('IFC4X3_ADD2')); ENDSEC; DATA; @@ -9,7 +9,7 @@ DATA; #2=IFCORGANIZATION($,'',$,$,$); #3=IFCPERSONANDORGANIZATION(#1,#2,$); #4=IFCAPPLICATION(#2,'0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); -#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,1320688800,#3,#4,1729698441); +#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,#3,#4,1730665305); #6=IFCDIRECTION((1.,0.,0.)); #7=IFCDIRECTION((0.,0.,1.)); #8=IFCCARTESIANPOINT((0.,0.,0.)); @@ -24,6 +24,6 @@ DATA; #17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16); #18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17); #19=IFCUNITASSIGNMENT((#13,#14,#15,#18)); -#20=IFCPROJECT('3cKqXUVprAK96oukheoJqJ',#5,'',$,$,$,$,(#11),#19); +#20=IFCPROJECT('2E3LRVubTBHOM7zf4qZDFp',#5,'',$,$,$,$,(#11),#19); ENDSEC; END-ISO-10303-21; diff --git a/test/files/ver000/na-ver000-owner_without_versioning.ifc b/test/files/ver000/na-ver000-owner_without_versioning.ifc index 08e0e8ea..af23f881 100644 --- a/test/files/ver000/na-ver000-owner_without_versioning.ifc +++ b/test/files/ver000/na-ver000-owner_without_versioning.ifc @@ -1,15 +1,15 @@ ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); -FILE_NAME('','2024-10-23T15:47:21',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); +FILE_NAME('','2024-11-03T20:21:45',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); FILE_SCHEMA(('IFC4X3_ADD2')); ENDSEC; DATA; #1=IFCPERSON($,$,'',$,$,$,$,$); -#2=IFCORGANIZATION($,'',$,$,$); +#2=IFCORGANIZATION($,'Validation Service Team',$,$,$); #3=IFCPERSONANDORGANIZATION(#1,#2,$); #4=IFCAPPLICATION(#2,'0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); -#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,$,$,1729698441); +#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,#3,#4,1730665305); #6=IFCDIRECTION((1.,0.,0.)); #7=IFCDIRECTION((0.,0.,1.)); #8=IFCCARTESIANPOINT((0.,0.,0.)); @@ -24,6 +24,6 @@ DATA; #17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16); #18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17); #19=IFCUNITASSIGNMENT((#13,#14,#15,#18)); -#20=IFCPROJECT('3cKqXUVprAK96oukheoJqJ',#5,'',$,$,$,$,(#11),#19); +#20=IFCPROJECT('2C0_5FU_vCLOZjbb7Ve_lz',#5,'',$,$,$,$,(#11),#19); ENDSEC; END-ISO-10303-21; diff --git a/test/files/ver000/na-ver000-owner_wrong_change_action.ifc b/test/files/ver000/na-ver000-owner_wrong_change_action.ifc new file mode 100644 index 00000000..af23f881 --- /dev/null +++ b/test/files/ver000/na-ver000-owner_wrong_change_action.ifc @@ -0,0 +1,29 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('','2024-11-03T20:21:45',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); +FILE_SCHEMA(('IFC4X3_ADD2')); +ENDSEC; +DATA; +#1=IFCPERSON($,$,'',$,$,$,$,$); +#2=IFCORGANIZATION($,'Validation Service Team',$,$,$); +#3=IFCPERSONANDORGANIZATION(#1,#2,$); +#4=IFCAPPLICATION(#2,'0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); +#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,$,#3,#4,1730665305); +#6=IFCDIRECTION((1.,0.,0.)); +#7=IFCDIRECTION((0.,0.,1.)); +#8=IFCCARTESIANPOINT((0.,0.,0.)); +#9=IFCAXIS2PLACEMENT3D(#8,#7,#6); +#10=IFCDIRECTION((0.,1.)); +#11=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.E-05,#9,#10); +#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0); +#13=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.); +#14=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.); +#15=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.); +#16=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.); +#17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16); +#18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17); +#19=IFCUNITASSIGNMENT((#13,#14,#15,#18)); +#20=IFCPROJECT('2C0_5FU_vCLOZjbb7Ve_lz',#5,'',$,$,$,$,(#11),#19); +ENDSEC; +END-ISO-10303-21; diff --git a/test/files/ver000/pass-ver000-owner_with_last_modify_date.ifc b/test/files/ver000/pass-ver000-versioning_attributes_present.ifc similarity index 83% rename from test/files/ver000/pass-ver000-owner_with_last_modify_date.ifc rename to test/files/ver000/pass-ver000-versioning_attributes_present.ifc index 8917da21..488424ed 100644 --- a/test/files/ver000/pass-ver000-owner_with_last_modify_date.ifc +++ b/test/files/ver000/pass-ver000-versioning_attributes_present.ifc @@ -1,7 +1,7 @@ ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); -FILE_NAME('','2024-10-23T15:47:21',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); +FILE_NAME('','2024-11-03T20:21:45',(''),(''),'IfcOpenShell-0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); FILE_SCHEMA(('IFC4X3_ADD2')); ENDSEC; DATA; @@ -9,7 +9,7 @@ DATA; #2=IFCORGANIZATION($,'',$,$,$); #3=IFCPERSONANDORGANIZATION(#1,#2,$); #4=IFCAPPLICATION(#2,'0.7.11-d51fa2c5f','IfcOpenShell-0.7.11-d51fa2c5f',''); -#5=IFCOWNERHISTORY(#3,#4,$,.NOTDEFINED.,1320688800,#3,#4,1729698441); +#5=IFCOWNERHISTORY(#3,#4,$,.MODIFIED.,1320688800,#3,#4,1730665305); #6=IFCDIRECTION((1.,0.,0.)); #7=IFCDIRECTION((0.,0.,1.)); #8=IFCCARTESIANPOINT((0.,0.,0.)); @@ -24,6 +24,6 @@ DATA; #17=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.017453292519943295),#16); #18=IFCCONVERSIONBASEDUNIT(#12,.PLANEANGLEUNIT.,'DEGREE',#17); #19=IFCUNITASSIGNMENT((#13,#14,#15,#18)); -#20=IFCPROJECT('3IEQwpQZz0LxMGrEzeCjsz',#5,'',$,$,$,$,(#11),#19); +#20=IFCPROJECT('2E3LRVubTBHOM7zf4qZDFp',#5,'',$,$,$,$,(#11),#19); ENDSEC; END-ISO-10303-21;