Skip to content

Examine every IdfObject.update entry before applying any - #81

Merged
samuelduchesne merged 3 commits into
fix-extensible-accessor-validationfrom
015-object-multi-field-update
Oct 21, 2026
Merged

samuelduchesne merged 3 commits into
fix-extensible-accessor-validationfrom
015-object-multi-field-update

Conversation

@samuelduchesne

Copy link
Copy Markdown
Contributor

Summary

IdfObject.update applied entries in order and threw at the first unknown field, so entries before it were already written. It now examines every entry before applying any, and follows the contract shared with the Python IDFObject.update (idfkit/idfkit#235, feature 015).

Stacked on #80. This pull request targets fix-extensible-accessor-validation; review #80 first. Once #80 merges, this pull request is retargeted to main.

Behaviour

An entry is refused when:

  1. its name is not a field of the type;
  2. it is name, in any letter case (assign the name property instead, which also updates the objects that refer to this one);
  3. it gives the extensible key a value the accessor rejects (Validate the value written to the extensible key in its accessor #80), checked with the accessor's own extensibleValueProblem.

If any entry is refused, nothing is written and a plain Error lists every refused entry, under the heading the Python library uses:

Update of object type 'Zone' refused; no field was changed:
  - bogus: unknown (not a field of Zone)

Otherwise every entry is applied in order through the accessor, so reference tracking and change notification are those of consecutive set calls. The signature and the returned object (this) are unchanged; null or undefined still clears a field, including the extensible list.

Changes

  • packages/core/src/object.ts: update examines, then applies.
  • packages/core/tests/document.test.ts and packages/core/tests/regressions.test.ts: refusal per reason with the object unchanged, a mixed group listing every entry, equivalence with set including change notifications, [null] refused with the reference graph intact, null clearing, Name refused, and the exact heading.
  • packages/core/package.json: governance level raised to governance-2026.30, the naming-register tag that records update as an aligned concept, with the return value as the one stated divergence.
  • CHANGELOG.md: entry under Unreleased, Changed.

Conformance

The shared cases (update-*) are in the idfkit-conformance branch 015-update-operation and are not yet in a tag. Run against this branch, all update assertions pass, including a case for a malformed extensible list. The conformance pin is raised to conformance-2026.17 in a follow-up commit on this pull request once that tag exists; until then, CI runs the corpus at the current pin.

Verification

  • npm run typecheck: passes.
  • npm run format:check: passes.
  • npm test: 920 of 920 tests pass across 35 files.

IdfObject.update applied entries in order through set and threw at the
first unknown field, so a group with a misspelled name left the entries
before it applied. It now examines the whole group first. An unknown
field, name, or a non-array value for the extensible key refuses the
group, nothing is written, and one Error lists every refused entry, one
per line. An accepted group is applied through set as before, and the
object is still returned.

This is the shared contract of the Python IDFObject.update
(idfkit/idfkit#235), registered as "apply several fields to an object"
in the naming register.
The tag carries the register entry for "apply several fields to an
object", which IdfObject.update now satisfies. The naming and parity
gates pass against it.
update checked that the value for the extensible key was an array but not
what it held, so [null] passed examination and reached the accessor after
earlier entries had been written. Examination now asks
extensibleValueProblem, the accessor's own validator, so a malformed list
is refused with nothing written and the reference graph intact, and null
still clears the list.

update also refuses name in any letter case, opens its message with the
heading the Python library uses, and writes through the accessor without
checking each field name a second time. The changelog and TSDoc describe
the behaviour rather than citing conformance cases that no tag contains yet.
@samuelduchesne
samuelduchesne requested review from a team as code owners October 21, 2026 15:25
@samuelduchesne
samuelduchesne added this pull request to stack #82 October 21, 2026 16:10
@samuelduchesne
samuelduchesne merged commit c5f976c into main Oct 21, 2026
39 checks passed
samuelduchesne added a commit that referenced this pull request Oct 21, 2026
The level adds the five update cases, the update operation and the post-operation-epjson assertion, and removes the six typescript divergence entries for those cases, which #80 and #81 close. conformance.ts and the EPW sentinel table are regenerated from the new tag; only their recorded level changes. The publication gate's attested level moves with the pin, with the evidence taken at the tag in both languages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant