Skip to content

test(downgrader): cover the cut-$ref reset, writeOnly and $ref tags, and repeated keywords beside properties - #330

Merged
dinwwwh merged 1 commit into
mainfrom
claude/project-thread-rixcs1
Nov 2, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/project-thread-rixcs1

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Nov 2, 2026

Copy link
Copy Markdown
Member

Requested by dinwwwh · project thread

What

Test-only. Stryker on main (94c60c7) leaves 77 of 2,511 mutants alive, where 0.5.0 left 70. Of the 10 new survivors, 8 are untested branches added by #313, #314 and #318 (the other 2, the converting: [] initial value and isOneWay's final return false, are equivalent):

Mutant that survived New test
cutHolders.clear() removed (#313) A $ref object cut at recursion in one call still told no oneOf branch apart in the next call.
follow's check for a $ref into a target being inlined removed (#313's surroundings) A $ref to a component whose own $ref into that target is cut only after the component's other keywords convert. Without the check, the oneOf stays although its branch { allOf: [{}] } now overlaps the other one, so 3.0 rejects { tag: "u" }, which 3.1 accepts.
isOneWay ignoring writeOnly (2 mutants), or not following a $ref (#318) A oneOf tagged only by writeOnly tags, and one tagged by $refs to readOnly consts, both become anyOf.
repeats()'s additionalProperties clause (3 mutants, #314) A repeated additionalProperties beside the same (no) properties merges, and a repeated description beside different properties merges too.
mayRepeatUnseen counting null as an object A oneOf of literals where one enum holds null merges.

I checked each mutant by hand: each now fails a test, and the unmutated code passes.

Checks

pnpm run check and pnpm test (303 tests) pass. No source change, so coverage stays at 100%.


Generated by Claude Code

…and repeated keywords beside properties

Stryker on 94c60c7 leaves 77 mutants alive where 0.5.0 left 70. Seven of
the new ones are untested branches from #313, #314 and #318:

- cutHolders.clear() removed: a $ref object cut in one call still tells no
  oneOf branch apart in the next.
- follow's check for a $ref into a target being inlined removed: a $ref to
  a component whose own $ref into that target is cut only later keeps a
  oneOf whose branches now overlap.
- isOneWay ignoring writeOnly, or not following a $ref to the tag.
- repeats(): a repeated additionalProperties beside the same properties,
  and another keyword beside different properties.
- mayRepeatUnseen counting null as an object.

Each of these mutants now fails a test. No source change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VVaw7RYWCsn8myBE4Rncuq
@dinwwwh dinwwwh self-assigned this Nov 2, 2026
@codecov

codecov Bot commented Nov 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Nov 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

1 warning

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 29 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing claude/project-thread-rixcs1 (c848f6e) with main (f5bf5c9)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes — test-only PR adding coverage in packages/downgrader/tests/v3.1-to-v3.0.test.ts for ten mutants Stryker leaves alive on main (eight from #313/#314/#318 plus the two equivalent ones). No src/ change.

  • cutHolders.clear() reset — a $ref object cut at recursion in one downgradeSchemaV31ToV30 call must not suppress branch-telling in the next call.
  • follow's inlining cut — a $ref to a component whose own $ref back into the target is cut only after its other keywords convert still forces the oneOf to anyOf.
  • isOneWay writeOnly / $ref follow — a oneOf tagged only by writeOnly, and one tagged via $refs to readOnly consts, each become anyOf; a $ref loop holds neither keyword.
  • repeats() additionalProperties clause — a repeated additionalProperties beside the same (no) properties merges; a repeated description beside differing properties merges too.
  • mayRepeatUnseen null handling — a oneOf of literals whose enum holds null merges.

I verified the coverage claim independently: applying each of nine targeted mutations to src/v3.1-to-v3.0.ts and re-running the corresponding test kills all nine (source restored byte-identical). Full suite (362 tests) and uncheck (oxlint/oxfmt/tsc) pass on the tree.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit 78d0dc7 into main Nov 2, 2026
9 checks passed
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