Skip to content

test(mock): judge plain data through the owner - #521

Merged
Vivswan merged 1 commit into
mainfrom
test/tidy-copies-and-long-lines
Oct 7, 2026
Merged

Vivswan merged 1 commit into
mainfrom
test/tidy-copies-and-long-lines

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

What this changes

test/e2e/mock/state.ts         private isPlainObject(value): value is Json             -> import { isPlainObject, own, put } from src/plain-data
test/e2e/mock/request-body.ts  private isPlainObject(value): value is Json             -> the same import
test/e2e/mock/support.ts       asObject: body && typeof body === "object" && ...        -> isPlainObject(body) ? body : {}
test/e2e/mock/chaos.ts         if (body && typeof body === "object" && ...)             -> if (isPlainObject(body))
test/e2e/mock/routes.ts        typeof variables !== "object" || === null || isArray(..) -> !isPlainObject(body.variables)
deepMerge, protectionFromPut, the missing_envelope arm   out[key] = ...                -> put(out, key, ...): a __proto__ key stays an own data key

How

  • Every plainness judgment in the mock (object, not null, not a list) is the engine's isPlainObject; its predicate type is the mock's Json alias, no wrapper or cast.
  • The owner refuses a foreign prototype, so a YAML-tagged seed (!!timestamp, !!set, !!binary) now replaces like a scalar, as the engine does, where the old checks spread it into the state.
  • Arbitrary-key copies write through the owner's put, so a key spelled __proto__ stays data: deepMerge keeps the seeded owner reslugged, and the missing_envelope reply keeps the key.

Proof

  • Census: grep -rc Array.isArray test/e2e/mock sums to 21 before, 16 after; the five gone were plainness checks; the rest judge lists.
  • Tests: state.test.ts 52 and chaos.test.ts 1, each red when its copy writes out[key] again; the other mock tests green, 96 across six files.
  • Gates: typecheck, biome, knip green.
Technical details
  • Library: none. The owner is src/plain-data.ts, the repository's one plain-mapping judgment; the npm is-plain-object package would be a second judgment beside it.
  • Narrowing: Json in test/e2e/mock/support.ts and in state.ts is an alias of Record<string, unknown>, the owner's predicate type, so every caller typechecks unchanged and routes.ts drops its as Json cast.
  • Corpus: no scenario under test/sections/*/scenarios or test/e2e seeds a YAML tag or a __proto__ key; both reach live_state through z.unknown(), and the change takes the owner's semantics for them.
  • Seeded values reach asObject and the chaos arm too: an actions_retention: !!binary seed is a Uint8Array there, replaced whole under the owner where the old check spread its indices into the state.
  • protectionFromPut's put is census-proved: its input is the branch-protection PUT body the action builds from a closed schema.
  • Object checks that are not plainness checks, unchanged: routes.ts value && typeof value === "object" after a list branch in the node-id walk, support.ts typeof rule === "object" && rule !== null in the rule-type read, server.ts on the bound address.
  • Arbitrary-key writes unchanged, same class: state.ts the URL rewrite loop, the stored-twins loops, the extras loop; support.ts stored[key] = payload[key]; server.ts query parsing.
  • Files: test/e2e/mock/{state.ts,request-body.ts,support.ts,chaos.ts,routes.ts} (+15 -20), test/e2e/mock/{state.test.ts,chaos.test.ts} (+43).

Copilot AI balanced review requested due to automatic review settings October 6, 2026 22:12

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.

Copilot review overview

🟢 Approval recommended

The focused mock changes match the shared helpers' contracts and include regression coverage, with no blocking issues identified.

Review effort: Balanced
Findings: None

What changed in this PR

Aligns the end-to-end mocks with the engine's shared plain-data handling.

Changes:

  • Replaces duplicate plain-object checks with the shared helper.
  • Uses safe property reads and writes when merging seed data.
  • Adds regression coverage for __proto__ keys and owner reslugging.
File Description
test/​e2e/​mock/​state.ts Uses shared helpers for plain-object checks and safe seed merging.
test/​e2e/​mock/​state.test.ts Verifies __proto__ remains data and the owner is reslugged.
test/​e2e/​mock/​request-body.ts Uses the shared plain-object check and removes an unused import.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Vivswan
Vivswan force-pushed the test/tidy-copies-and-long-lines branch from 931b294 to 80fcdc9 Compare October 6, 2026 22:42
Copilot AI balanced review requested due to automatic review settings October 6, 2026 22:42

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.

Copilot review overview

🟢 Approval recommended

The focused mock changes reuse established helpers and include regression coverage, with no unresolved defects identified.

Review effort: Balanced
Findings: None

The mock judged plainness five ways beside the engine's owner in src/plain-data.ts: two private isPlainObject copies (state.ts, request-body.ts), two inline checks (support.ts asObject, the chaos stripped arm), and the GraphQL variables guard in routes.ts, all accepting any non-null, non-array object, where the owner also refuses a foreign prototype. All five now use the owner; its predicate type is the type the mock's Json alias names, so no wrapper or cast is needed, and routes.ts drops its cast.

A live_state seed can carry a foreign prototype after all: the yaml parser turns !!timestamp into a Date, !!set into a Set, and !!binary into a Uint8Array, and the schema passes them through as unknown. Under the owner such a seed replaces like a scalar, as the engine treats the same tag in a settings file, where the old checks spread it into the state.

Three arbitrary-key copies assigned out[key], so a key spelled __proto__ set the output's prototype: deepMerge (under the stricter predicate reslugRepo then skipped the seeded owner), the chaos missing_envelope arm (the seeded key vanished from the reply), and protectionFromPut. All three write through the owner's put, and deepMerge reads through own; a test each pins deepMerge and the chaos arm with a parsed seed.
Copilot AI balanced review requested due to automatic review settings October 6, 2026 22:58
@Vivswan
Vivswan force-pushed the test/tidy-copies-and-long-lines branch from 80fcdc9 to aa61a56 Compare October 6, 2026 22:58

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.

Copilot review overview

🟢 Approval recommended

The focused mock changes reuse established helpers, include regression coverage, and have no identified blocking defects.

Review effort: Balanced
Findings: None

@Vivswan Vivswan added the merge-when-green Owner approved: merge once every gate is green label Oct 6, 2026
@Vivswan
Vivswan marked this pull request as ready for review October 6, 2026 23:04
@Vivswan
Vivswan merged commit 061fed7 into main Oct 7, 2026
32 checks passed
@Vivswan
Vivswan deleted the test/tidy-copies-and-long-lines branch October 7, 2026 02:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-when-green Owner approved: merge once every gate is green

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants