Skip to content

test(core): JSON Canvas spec conformance suite (#16, slice 1) - #67

Merged
LeslieOA merged 1 commit into
developfrom
test/spec-conformance
Jun 3, 2026
Merged

test(core): JSON Canvas spec conformance suite (#16, slice 1)#67
LeslieOA merged 1 commit into
developfrom
test/spec-conformance

Conversation

@LeslieOA

@LeslieOA LeslieOA commented Jun 1, 2026

Copy link
Copy Markdown
Member

Summary

First slice of #16 — spec conformance for the core parse/serialize gate. 33 new tests in conformance.test.ts, complementing the sample-fixture coverage already in serialization.test.ts.

Covers the spec checklist:

  • All four node types in one document + type-specific required fields
  • Full edge matrixfromSide×toSide×fromEnd×toEnd (64 combos) parsed and round-trip-preserved
  • Colour preservation — preset codes 16 and hex values verbatim
  • Minimal docs{}, {"nodes":[]}, {"nodes":[],"edges":[]}
  • Malformed-input rejection (18 cases) — bad JSON, non-object roots, non-array nodes/edges, missing/empty id, bad type tag, non-numeric coords, missing type-specific fields, bad edge side/end enums
  • Round-trip property parse(serialize(parse(x))) ≡ parse(x) + unknown-field preservation (doc/node/edge) + tab indentation

Plus a bundled all-node-types.canvas fixture (text/file/link/group + a fully-specified edge — the sample lacked a file node).

Why pure-TS

No unified/remark/hast imports, so it runs under the existing ts-jest config with zero mocking. Precondition for the Rust port (#6): these fixtures will validate the Rust parser accepts/rejects exactly what the TS one does.

Scope (sliced deliberately)

  • This PR — core spec conformance.
  • Slice 2 (next) — Canvas Candy cssclasses enrichment: class→prop mapping, frontmatter forms, displayText stripping, zero-overhead path. Also pure-TS (js-yaml only).
  • Deferred — callouts parseCallouts conformance: pulls in the unified/remark ESM chain that breaks under ts-jest. Belongs with a one-time jest-ESM solution, not per-test mocking (we learned that lesson on the parse-cache PR). hasCallouts (pure regex) will be covered in slice 2.

Test plan

  • 81 tests pass (33 new), typecheck + lint clean
  • No device/native needed — pure logic

Part of #16.

🤖 Generated with Claude Code

Adds src/core/__tests__/conformance.test.ts (33 tests) targeting the spec
contract directly, complementing the sample-fixture coverage in
serialization.test.ts:

  - all four node types in one document + type-specific required fields
  - full edge matrix: fromSide×toSide×fromEnd×toEnd (64 combinations) parsed
    and preserved through a round-trip
  - colour preservation: preset codes 1–6 and hex values verbatim
  - minimal docs: {}, {"nodes":[]}, {"nodes":[],"edges":[]}
  - malformed-input rejection matrix (18 cases): bad JSON, non-object roots,
    nodes/edges not arrays, missing/empty id, bad type tag, non-numeric coords,
    missing type-specific fields, bad edge side/end enums
  - round-trip property parse(serialize(parse(x))) ≡ parse(x), plus
    unknown-field preservation at document / node / edge level, tab indentation

Plus a bundled spec fixture (all-node-types.canvas) exercising text/file/link/
group + a fully-specified edge.

Pure-TS / no ESM deps, so it runs under the existing ts-jest config with no
mocking. Precondition for the Rust port (#6): the same fixtures will validate
the Rust parser accepts/rejects exactly what the TS one does.

Scope: this is slice 1 (core spec). Canvas Candy cssclasses enrichment is
slice 2 (also pure-TS via js-yaml); callouts conformance is deferred — it
pulls in the unified/remark ESM chain that needs the jest-ESM problem solved
once, properly, rather than per-test mocking.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@LeslieOA
LeslieOA merged commit 82384e1 into develop Jun 3, 2026
1 check passed
@LeslieOA
LeslieOA deleted the test/spec-conformance branch June 3, 2026 15:51
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