test(byte-codec): cross-transport byte-faithfulness contract — (xxj.3)#64
Merged
Conversation
…ehavior-not-structure] (xxj.3)
Adds 8 contract tests asserting ∀ byte b in probe payload, every transport's
onData delivers a string where charCodeAt(i) === b.
Node file covers websocketTransport (ArrayBuffer, Uint8Array, sub-array view
with non-zero byteOffset) and the spawn transport's setEncoding('latin1') path
via a PassThrough stream. Browser file runs the same websocketTransport
assertions in happy-dom, guarding against future TextDecoder('latin1')
regression (windows-1252 remaps 0x80-0x9F in browsers).
Canonical probe payload in _helpers/probe-bytes.ts: windows-1252 landmine
bytes 0x80/0x81/0x8D/0x8F/0x9D/0x9F, emoji U+1F600 (F0 9F 98 80), CJK
U+4E2D (E4 B8 AD), ASCII baseline.
[LAW:single-enforcer] probe payload defined once in probe-bytes.ts
[LAW:behavior-not-structure] tests assert the per-byte contract, not decode impl
There was a problem hiding this comment.
Pull request overview
This PR adds cross-transport “byte-faithfulness” contract tests to ensure the transport→parser boundary always preserves raw bytes 1:1 inside the library’s latin1-container string representation (i.e., charCodeAt(i) === originalByte). This strengthens long-term correctness for pane output handling across WebSocket and spawn-style transports, including “landmine” bytes and multibyte UTF-8 sequences.
Changes:
- Added Node-environment contract tests covering
websocketTransportforArrayBuffer,Uint8Array, and non-zero-byteOffsetviews. - Added Node-only contract tests validating the spawn transport’s
setEncoding("latin1")decode mechanism via aPassThrough. - Added a happy-dom browser-environment contract test suite for
websocketTransport, including explicit coverage for the 0x80–0x9F remapping hazard.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/unit/byte-faithful-contract.test.ts | Adds Node-side contract tests for WebSocket frame decoding and stream setEncoding("latin1") byte-faithfulness. |
| tests/unit/byte-faithful-contract.browser.test.ts | Adds happy-dom “browser-like” contract tests to prevent browser-specific byte remapping regressions. |
| tests/unit/_helpers/probe-bytes.ts | Introduces a single canonical probe byte payload (landmine bytes + multibyte UTF-8 sequences + ASCII baseline) shared by both test suites. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ReadonlyArray<T> → readonly T[], type → interface for PaneMeta, remove unused PaneBytesEnvelope import in electron/main.ts. None of these were introduced by this PR; all existed on master.
…ment
- send()/close() now match BrowserWebSocketLike parameter signatures
- Comment corrected: TextDecoder('latin1') is windows-1252 everywhere per
the WHATWG Encoding Standard, not just in browsers; only String.fromCharCode
(bytesToLatin1) is byte-faithful in all runtimes
…mments
TextDecoder('latin1') is windows-1252 in ALL WHATWG runtimes (not just
browsers). Node stream setEncoding('latin1') is byte-faithful but Node-only.
String.fromCharCode (bytesToLatin1) is the portable cross-runtime path.
These files had pre-existing prettier violations that caused format:check to fail in CI. No logic changes — formatting only.
…terals PaneBytesEnvelope = PaneOutputMessage requires type: "output" since PR #63 aligned the wire envelope with the protocol type. The satisfies checks in the renderer-side tests were missing the discriminant field.
… shared helper [LAW:single-enforcer] The two contract test files defined identical assertByteFaithful and FakeWebSocket. Extracting to _helpers/websocket-fake.ts ensures a single change point if BrowserWebSocketLike evolves.
brandon-fryslie
added a commit
that referenced
this pull request
May 27, 2026
#64) * test(byte-codec): cross-transport byte-faithfulness contract — [LAW:behavior-not-structure] (xxj.3) Adds 8 contract tests asserting ∀ byte b in probe payload, every transport's onData delivers a string where charCodeAt(i) === b. Node file covers websocketTransport (ArrayBuffer, Uint8Array, sub-array view with non-zero byteOffset) and the spawn transport's setEncoding('latin1') path via a PassThrough stream. Browser file runs the same websocketTransport assertions in happy-dom, guarding against future TextDecoder('latin1') regression (windows-1252 remaps 0x80-0x9F in browsers). Canonical probe payload in _helpers/probe-bytes.ts: windows-1252 landmine bytes 0x80/0x81/0x8D/0x8F/0x9D/0x9F, emoji U+1F600 (F0 9F 98 80), CJK U+4E2D (E4 B8 AD), ASCII baseline. [LAW:single-enforcer] probe payload defined once in probe-bytes.ts [LAW:behavior-not-structure] tests assert the per-byte contract, not decode impl * fix(lint): pre-existing ESLint errors blocking CI ReadonlyArray<T> → readonly T[], type → interface for PaneMeta, remove unused PaneBytesEnvelope import in electron/main.ts. None of these were introduced by this PR; all existed on master. * fix(test): align FakeWebSocket signatures and correct TextDecoder comment - send()/close() now match BrowserWebSocketLike parameter signatures - Comment corrected: TextDecoder('latin1') is windows-1252 everywhere per the WHATWG Encoding Standard, not just in browsers; only String.fromCharCode (bytesToLatin1) is byte-faithful in all runtimes * fix(test): clarify TextDecoder vs Node stream latin1 in spawn test comments TextDecoder('latin1') is windows-1252 in ALL WHATWG runtimes (not just browsers). Node stream setEncoding('latin1') is byte-faithful but Node-only. String.fromCharCode (bytesToLatin1) is the portable cross-runtime path. * fix(format): apply prettier to pre-existing formatting issues These files had pre-existing prettier violations that caused format:check to fail in CI. No logic changes — formatting only. * fix(typecheck): add missing type discriminant to PaneBytesEnvelope literals PaneBytesEnvelope = PaneOutputMessage requires type: "output" since PR #63 aligned the wire envelope with the protocol type. The satisfies checks in the renderer-side tests were missing the discriminant field. * refactor(test-helpers): extract assertByteFaithful + FakeWebSocket to shared helper [LAW:single-enforcer] The two contract test files defined identical assertByteFaithful and FakeWebSocket. Extracting to _helpers/websocket-fake.ts ensures a single change point if BrowserWebSocketLike evolves.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
∀ byte b in probe payload, transport.onData delivers string where charCodeAt(i) === btests/unit/_helpers/probe-bytes.ts): windows-1252 landmine bytes 0x80/0x81/0x8D/0x8F/0x9D/0x9F, emoji U+1F600 (F0 9F 98 80), CJK U+4E2D (E4 B8 AD), ASCII baselinebyte-faithful-contract.test.ts): websocketTransport (ArrayBuffer, Uint8Array, sub-array view with non-zero byteOffset) + spawn transport decode via PassThrough/setEncodingbyte-faithful-contract.browser.test.ts,@vitest-environment happy-dom): websocketTransport with landmine bytes — catches futureTextDecoder('latin1')regression that would silently corrupt 0x80-0x9F in browsersTest plan
pnpm run test:allpasses (573 tests)pnpm run typecheck— no new errors in new filesString.fromCharCodeis byte-faithful vsTextDecoder('latin1')(windows-1252 in browsers)