Skip to content

Propose applicability test cases for non-Entity facets (#181) - #453

Open
BIMvoice wants to merge 2 commits into
buildingSMART:developmentfrom
BIMvoice:propose/ids-181-applicability-testcases
Open

Propose applicability test cases for non-Entity facets (#181)#453
BIMvoice wants to merge 2 commits into
buildingSMART:developmentfrom
BIMvoice:propose/ids-181-applicability-testcases

Conversation

@BIMvoice

@BIMvoice BIMvoice commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This issue is assigned to @CBenghi, so this is offered as a starting point to take, change or discard, not a claim on the work.

The measured gap

Parsing all 318 .ids files in TestCases/: every single <applicability> block uses only the Entity facet. None uses Classification, Attribute, Property, Material or PartOf in applicability, and none carries minOccurs or maxOccurs on an applicability facet.

Cross-checked against Schema/ids.xsd: applicabilityType's facets use the bare types with no cardinality attribute, only requirementsType's extensions add it. So per-facet Prohibited or Optional at the applicability level genuinely does not exist in 1.0; only whole-specification cardinality does, and that is already covered.

What these cases implement

Driven by the concrete asks in the thread rather than by the label. @berlotti established the semantics in the first reply, "there is symmetry in applicability and requirements" and "union. So multiple facets should be interpreted as AND". @CBenghi later enumerated the missing cases.

Three pass and fail pairs, each pair sharing the same specification so a pass alone cannot be mistaken for not-checked-at-all:

  • a Classification facet used in applicability
  • an Attribute facet used in applicability, implementing the "bedrooms need a minimum floor area" worked example from specifications.md verbatim
  • a Property facet used in applicability, implementing the "external load bearing walls need a fire rating" worked example verbatim

How these were built

Correction: I originally wrote that CreateTestCases could not be run. That was wrong. The build needs the .NET 8 runtime specifically, because Nuke uses BinaryFormatter, which .NET 9 removed. With that installed it runs in about a second. These .ids files are still hand-authored; I am happy to regenerate them through the official build on request. Validation, unchanged: all six are XSD-valid against Schema/ids.xsd (checked with a deliberately broken control file to confirm the validator actually rejects invalid input), and all six give the expected pass or fail verdict against IfcOpenShell's IfcTester.

Separate observation, not addressed here

Sweeping the existing suite with current IfcTester, 18 shipped pass- cases return FAIL, sharing one cause: the Attribute facet does not check cardinality == "optional" before failing on a null value with a value constraint. That is a defect on our side rather than in these cases, and we have a fix in review at IfcOpenShell#9205 that adds exactly that check. Mentioned only so the number is not mistaken for a problem with this suite.

@CBenghi @berlotti

This PR was created with the assistance of an AI coding tool.

Every applicability block in the shipped test suite used only the
Entity facet. Add three pass/fail pairs proving Classification,
Property (AND-combined with Entity) and Attribute facets also work
in applicability, per berlotti's confirmation on buildingSMART#181 and the
worked examples in specifications.md.

Hand authored since the CreateTestCases .NET build does not run in
this environment. Validated against Schema/ids.xsd (xmlschema) and
functionally against ifctester on both current v0.8.0 IfcOpenShell
and the local ifctester source.

AI-assisted contribution, human reviewed before submission.
@andyward

andyward commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Copying over from another PR #458 where you regenerated the TestCases:

RepositoryAutomation/SchemaProject/DocAutomation/IdsScript.cs, PopulateApplicability handles only case EntityPrefix: with default: break;, whereas PopulateRequirements just below handles Entity, Attribute, Classification, Material, PartOf and Property. So the generator cannot represent non-Entity applicability facets, and running it stripped the extra applicability facet out of all three pass/fail pairs, which is the exact behaviour those cases exist to demonstrate for #181. The DSL in scripts.md is already correct, it is the generator that cannot read it back.

So it should be relatively simple to update the SchemaProject Tooling to handle all the facets on Applicability. The Make<facet> methods need implementing - use the existing MakeReq<Facet> methods as a example but use the Applicability IDS Types. Then just update the PopulateApplicability switch statement

Separately, and my fault rather than the tooling's, #453 current fixtures fail with Error 305: Invalid value 'TRUE' for base type 'XsBoolean'. XSD booleans are lowercase. Happy to fix that one whenever the queue question is settled.

I would update this - no point having an invalid test in the PR.

Implement Make<Facet> for Attribute, Classification, Material,
PartOf and Property in the Applicability IDS types, and wire them
into PopulateApplicability so the generator no longer silently
drops these facets. Cardinality is dropped since it is a
requirements-only concept per the schema.

Also fix Error 305 by lowercasing TRUE to true in the fire rating
fixtures and their scripts.md source, per XSD boolean rules.

@andyward andyward left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you remove this section from all the new Make<Facet> methods:

 if (parts.Count > 0 && parts[0] is ConditionalCardinality)
  {
      // cardinality is a requirements-only concept, not available on applicability facets
      parts.RemoveAt(0);
  }

Comment thread RepositoryAutomation/SchemaProject/DocAutomation/IdsScript.cs
@BIMvoice

BIMvoice commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Both done, pushed as 0d8e392.

The five Make* methods are in, mirroring the MakeReq* ones but returning the applicability types. Worth noting for anyone doing the same: ApplicabilityType.Entity is a single property but Attribute, Classification, Material, PartOf and Property are all Collection<T>, so the switch assigns Entity and calls .Add() for the other five.

I left cardinality out. In ids.xsd the cardinality attribute comes from requirementsType's extension of each facet, so the base types used by applicabilityType have no such property. The methods still consume a leading cardinality token if the DSL supplies one, and discard it.

Proved it works rather than assuming: reverted IdsScript.cs, regenerated, confirmed the <attribute> facet was silently stripped from the bedrooms fixture, then restored and regenerated. All three pairs now keep their second applicability facet. Regenerating all 324 scripts touched only the 6 files we intended.

AuditDocTestCases: 324 files processed. Completed with status: Ok. Zero errors, so the TRUE to true fix is in as well, in both the fixtures and the scripts.md source so regeneration keeps it correct.

One thing I did not touch: GetFacets(ApplicabilityType) still returns Entity only. It is only used by the IdsScript(Ids.Ids sourceIds) round-trip constructor rather than CreateTestCases, so it did not affect this, but it is the same gap in a second place if you want it closed.

@andyward

andyward commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Both done, pushed as 0d8e392.

Great

The five Make* methods are in, mirroring the MakeReq* ones but returning the applicability types. Worth noting for anyone doing the same: ApplicabilityType.Entity is a single property but Attribute, Classification, Material, PartOf and Property are all Collection, so the switch assigns Entity and calls .Add() for the other five.

That's because there can be only one Entity facet per applicability. It doesn't make sense that multiple be supplied, whereas other facets can be combined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants