Skip to content

test(byte-codec): cross-transport byte-faithfulness contract — (xxj.3)#64

Merged
brandon-fryslie merged 7 commits into
masterfrom
tmux-byte-codec-xxj.3
May 27, 2026
Merged

test(byte-codec): cross-transport byte-faithfulness contract — (xxj.3)#64
brandon-fryslie merged 7 commits into
masterfrom
tmux-byte-codec-xxj.3

Conversation

@brandon-fryslie

Copy link
Copy Markdown
Contributor

Summary

  • Adds 8 contract tests asserting ∀ byte b in probe payload, transport.onData delivers string where charCodeAt(i) === b
  • Canonical probe payload (tests/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 baseline
  • Node environment (byte-faithful-contract.test.ts): websocketTransport (ArrayBuffer, Uint8Array, sub-array view with non-zero byteOffset) + spawn transport decode via PassThrough/setEncoding
  • Browser environment (byte-faithful-contract.browser.test.ts, @vitest-environment happy-dom): websocketTransport with landmine bytes — catches future TextDecoder('latin1') regression that would silently corrupt 0x80-0x9F in browsers

Test plan

  • pnpm run test:all passes (573 tests)
  • pnpm run typecheck — no new errors in new files
  • Browser environment test verifies String.fromCharCode is byte-faithful vs TextDecoder('latin1') (windows-1252 in browsers)

…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
Copilot AI review requested due to automatic review settings May 27, 2026 20:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 websocketTransport for ArrayBuffer, Uint8Array, and non-zero-byteOffset views.
  • Added Node-only contract tests validating the spawn transport’s setEncoding("latin1") decode mechanism via a PassThrough.
  • 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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment thread tests/unit/byte-faithful-contract.browser.test.ts Outdated
Comment thread tests/unit/byte-faithful-contract.test.ts Outdated
Comment thread tests/unit/byte-faithful-contract.browser.test.ts Outdated
…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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread tests/unit/byte-faithful-contract.test.ts Outdated
Comment thread tests/unit/byte-faithful-contract.browser.test.ts Outdated
…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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

These files had pre-existing prettier violations that caused format:check
to fail in CI. No logic changes — formatting only.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

…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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread tests/unit/byte-faithful-contract.test.ts Outdated
Comment thread tests/unit/byte-faithful-contract.browser.test.ts Outdated
… 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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

@brandon-fryslie brandon-fryslie merged commit 2ddfac0 into master May 27, 2026
2 checks passed
@brandon-fryslie brandon-fryslie deleted the tmux-byte-codec-xxj.3 branch May 27, 2026 20:39
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.
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.

2 participants