Skip to content

test(downgrader): keep the anyOf of a nullable $ref to a nullable anyOf beside a not - #210

Merged
dinwwwh merged 1 commit into
mainfrom
claude/project-thread-8grn3t
Oct 29, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/project-thread-8grn3t

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 29, 2026

Copy link
Copy Markdown
Member

Requested by dinwwwh · project thread

Test-only. admitsNull lets a nullable $ref pair collapse to the bare $ref only when the target holds annotations and an anyOf with a null branch. No test gave the target another keyword, so two Stryker mutants survived:

  • name === 'anyOf' -> true
  • (name === 'anyOf' && Array.isArray(schema.anyOf)) -> ||

The new expectation, anyOf [$ref Pet, null] where Pet is { anyOf: [pet, null], not: { type: 'null' } }, stays { anyOf: [ref, onlyNull] }, since the not can reject null. Applying each mutant by hand fails this test, and both pass without it. Stryker survivors go from 71 to 69, all equivalent (mergeNullable's ref !== undefined -> true, tagsOf's getRef(value) !== undefined -> true).

pnpm run check and pnpm test (367 tests) pass.


Generated by Claude Code

…Of beside a `not`

A `not` beside a nullable anyOf target can reject null too, so the
pair stays an anyOf. No test covered a target with a keyword other
than `anyOf` and annotations, so Stryker's `name === 'anyOf'` -> true
and `name === 'anyOf' && Array.isArray(...)` -> `||` mutants in
admitsNull survived.

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

codecov Bot commented Oct 29, 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 Oct 29, 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-8grn3t (7c407a9) with main (22ade18)

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

  • New regression expectation in the nullable-$ref pair suite — owner({ anyOf: [pet, { type: 'null' }], not: { type: 'null' } }) now asserts the pair stays { anyOf: [ref, onlyNull] }. The not makes the $ref target reject null, so admitsNull is false and mergeNullable must keep the explicit null branch rather than collapse to the bare $ref. The expectation is semantically correct.

I verified the mutation coverage claim empirically: both admitsNull mutants (name === 'anyOf' → true, and the && → || guard at packages/downgrader/src/v3.1-to-v3.0.ts:818) make this new assertion fail, and the file passes 122/122 unmutated.

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

@dinwwwh
dinwwwh merged commit e324f29 into main Oct 29, 2026
11 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