Skip to content

refactor(validation): extract shared info-object validation - #92

Merged
TheAsda merged 3 commits into
masterfrom
refactor/90-shared-info-validation
Oct 15, 2026
Merged

TheAsda merged 3 commits into
masterfrom
refactor/90-shared-info-validation

Conversation

@TheAsda

@TheAsda TheAsda commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Summary

Extracts the byte-identical Info Object validation from both dialect validators into one shared module, following the validate-security.ts precedent (issue #90).

 src/parser/version/
 ├── validate-security.ts        # existing shared-rule sibling
+├── validate-info.ts            # NEW: shared info-object checks
 ├── v3.0/validator.ts
-│   └── inline info checks
+│   └── validateInfo(s, '3.0', errors)
 ├── v3.1/validator.ts
-│   └── inline info checks
+│   └── validateInfo(s, '3.1', errors)

Same signature contract as validateSecurity(spec, version, errors); calls specViolation(version, key, message) internally so each dialect keeps its own spec links. Messages, check order, and post-#88 semantics (empty-string title/version valid; non-object info reports only info-object) are byte-identical.

Scope deliberately limited to the info block — the document-root, openapi-field, and components.schemas duplication stays for a later, separate decision.

Also ships:

  • the CONTEXT.md Shared rule entry (it names the new module)
  • tests/unit/version/validate-info.test.ts pinning the exact message + link per dialect × key — the v3.0.4 / v3.1.1 URLs are hardcoded on purpose; the follow-up on Extract shared info-object validation from the per-dialect validators #90 documents why the pre-existing expectViolation regex was too loose to catch version/key mix-ups.

Closes #90.

Evidence

TDD red→green on the new module, then the full suite.

Before (test written first, module absent):

npx vitest run tests/unit/version/validate-info.test.ts
Test Files  1 failed (1)

After (module + both validators wired):

Test Files  69 passed (69)
     Tests  1647 passed (1647)

npm run check clean · npm run format:check clean · oxlint clean on touched files.

Two-axis review of the branch (standards + spec sub-agents) found no hard violations; the spec axis verified all binding requirements with line-level evidence.

Merge Danger

Door: two-way — pure internal refactor, no behavior change, trivially revertible.

Blast radius: tiny. Nothing exported from the package root changes; generated-client output is unchanged (snapshot-backed suites cover it).

The Info Object checks were byte-identical in the 3.0 and 3.1 validators
and every change to them landed as lockstep edits. Move them to
validate-info.ts beside validate-security.ts, taking the dialect as a
parameter and rendering its own spec links. Closes #90.
@TheAsda

TheAsda commented Oct 15, 2026

Copy link
Copy Markdown
Owner Author

This PR extracts the byte-identical Info Object validation (object presence + title/version string checks) from src/parser/version/v3.0/validator.ts and v3.1/validator.ts into a new shared module src/parser/version/validate-info.ts, mirroring the existing validate-security.ts precedent: same (spec, version, errors) signature, specViolation(version, key, message) called directly so each dialect cites its own spec page. It also adds a "Shared rule" glossary entry to CONTEXT.md and a unit test pinning the exact message + link per dialect × key, closing #90.

Findings

  • [minor] tests/unit/version/validate-info.test.ts:10 — the hardcoded page URLs duplicate SPEC_PAGE from src/parser/version/spec-links.ts:12. The PR description explains this is deliberate (so a version/key mix-up or silent SPEC_PAGE change fails loudly), and I agree the pinning value is real — but note the maintenance cost runs the other way too: every future SPEC_PAGE patch bump (v3.0.4 → v3.0.5) must now also touch this test. Worth a one-line comment in the test saying the duplication is intentional, so a future contributor doesn't "fix" it into importing SPEC_PAGE and lose the pin.
  • [nit] tests/unit/version/validate-info.test.ts:7 — run()'s default version: '3.0' is dead code; every call site passes the version explicitly. Drop the default or remove the parameter's fallback.

Otherwise this is a clean, faithful extraction. I verified the removed inline blocks and the new module are equivalent in messages, check order, and control flow (the else branch correctly became an early return, preserving the "non-object info reports only info-object" semantics from #88). Both call sites sit at the same position in their validators' check sequence as before, and each passes its own dialect literal. The refactor stays behind the version-module boundary and doesn't touch the analyzer/generator seam. Regression coverage is two-sided: the new test pins the shared module directly, while the existing v3.0-validator/v3.1-validator/spec-links unit tests still exercise info validation through the public entry points. I confirmed on the PR head: full suite 69 files / 1647 tests green (after npm run build — the 36 failures without it are the documented build-before-test requirement, not the PR), tsc --noEmit clean, oxlint and oxfmt --check clean on the touched files. Keeping document-root/openapi-field/components.schemas out of scope is the right call for this PR's size.

Verdict

✅ Approve — a faithful, well-tested extraction with no behavioral change, matching the established shared-rule pattern; the two nits are non-blocking polish.


🤖 automatic review · T3 thread mcp:04ee55ce-97a0-45ff-b02d-091c201d9432 · model zai/glm-5.3 · triggered by PR opened event

Review notes on #92: label the hardcoded spec-page URLs as a deliberate
pin (a SPEC_PAGE bump must update them in the same commit) so nobody
imports SPEC_PAGE and silently loses the exactness guarantee; and remove
run()'s unused '3.0' fallback.
@TheAsda
TheAsda merged commit f9d920f into master Oct 15, 2026
5 checks passed
@TheAsda
TheAsda deleted the refactor/90-shared-info-validation branch October 15, 2026 16:42
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.

Extract shared info-object validation from the per-dialect validators

1 participant