Skip to content

The corpus round-trip guard cannot see an escape that was wrongly dropped #264

Description

@Azganoth

Summary

corpusRoundTrip.test.tsx asserts that a second serialization equals the first. That guard is structurally blind to under-escaping: a document holding literal *a* saved as *a* reparses as emphasis and re-serializes to identical bytes, so the run converges while the document has changed. #252 made escape emission conditional on an analysis of the text around each character, which is the first change whose failure mode this guard cannot detect. Comparing documents rather than bytes closes it.

Affected areas

  • src/features/editor/tests/corpusRoundTrip.test.tsx
  • corpus/commonmark/, corpus/gfm/, corpus/isolated/end-of-file/

Intended outcome

The corpus guard asserts that the ProseMirror document after a save and reopen equals the document before it, for every scoped file that can hold that property today, alongside the existing convergence assertion. Convergence stays: the two assertions fail on different defects.

Related context

Done when

  • The corpus guard compares documents across a save for the eleven scoped files that hold document identity today.
  • The five that do not — commonmark/blocks.md, commonmark/html.md, commonmark/lists-and-blockquotes.md, gfm/tables.md, and gfm/task-lists.md — are excluded by name, each naming the issue that owns its drift, so the list shrinks as those land rather than hiding new drift.
  • An excluded file that starts holding document identity fails the guard, so the list cannot outlive its reasons.

Notes

Measured on bug/precise-serializer-escaping by mounting each corpus file, taking view.state.doc.toJSON(), serializing, mounting the result, and comparing the two documents: eleven of the sixteen scoped files preserve the document, and the five that do not are exactly the five #252 recorded as pre-existing and not escape-caused.

The blindness is not hypothetical for the class of change #252 opened. Under-escaping produces text that reparses into a different document and then serializes to the same bytes on every pass after the first, which is precisely the shape convergence treats as success.

Out of scope

Metadata

Metadata

Assignees

Labels

MaintenanceChore, refactor, dependency, or test work without user-facing change

Projects

Status
In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions