Skip to content

test: pin semver build-metadata precedence and exercise the real versionMatchesRange path - #1094

Open
Retsumdk wants to merge 2 commits into
OWASP:mainfrom
Retsumdk:test/semver-build-metadata-coverage
Open

test: pin semver build-metadata precedence and exercise the real versionMatchesRange path#1094
Retsumdk wants to merge 2 commits into
OWASP:mainfrom
Retsumdk:test/semver-build-metadata-coverage

Conversation

@Retsumdk

@Retsumdk Retsumdk commented Sep 5, 2026

Copy link
Copy Markdown

Closes #1087

Adds the two test gaps called out in the issue.

1. Semver build-metadata coverage (tests/helpers.test.ts)

Semver §10 says build metadata is ignored for precedence, so 1.2.3+build
and 1.2.3 are equal, and likewise for variants carrying a pre-release
(e.g. 1.2.3-beta+a vs 1.2.3-beta+b). Nothing asserted this before, so a
regression of the (?:\+.*)? group in VERSION_SHAPE could go unnoticed.

I verified the new assertions kill that mutation: deleting (?:\+.*)?$
from VERSION_SHAPE makes the test fail (Expected: 0, Received: 1).

2. Exercise the real versionMatchesRange path (tests/local-advisory-source.test.ts)

The existing #1077 test hand-copies the body of versionMatchesRange
into the test, so it proves compareVersions but not the scanner path it is
named after. This adds an end-to-end test that seeds a lodash advisory fixed
at 4.17.21 and asserts:

  • lodash@4.17.21-beta.1 (below the fix) is flagged vulnerable
  • lodash@4.17.21 (at the fix) is not flagged

It goes through LocalAdvisorySource.queryBatch → the real
versionMatchesRange in src/advisory/local-db.ts. I verified it catches
the boundary mutation (>= 0> 0): that flips the at-fix case to
vulnerable and fails the test.

Verification

  • npm test passes for both files (--no-cache); full suite unchanged
    from baseline (no new failures).
  • npm run build and test-hygiene lint pass.
  • Test-only change; no behavior in src/ modified.

…sRange path

Coverage for issue OWASP#1087:

1. Build metadata carries no precedence in semver (10): a version with a
   '+build' suffix is equal to the bare release, for both string and
   pre-release-carrying inputs. Nothing previously asserted this.

2. The existing hand-copied test only proved compareVersions, not the
   scanner path it is named after. Add an end-to-end test that seeds a
   lodash advisory fixed at 4.17.21 and asserts a pre-release below that
   fix (4.17.21-beta.1) is flagged while the fixed release is not,
   exercising the real versionMatchesRange in src/advisory/local-db.ts.

Test-only change; no behavior in src altered.
@Retsumdk
Retsumdk requested a review from sonukapoor as a code owner September 5, 2026 21:37

@sonukapoor sonukapoor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Really strong first contribution, and I want to be clear that the substance is right before I ask for anything.

I verified both gaps by mutation. Deleting (?:\+.*)? from VERSION_SHAPE produces exactly one failure across 1,684 tests, and it is your build-metadata test. Making versionMatchesRange pre-release-blind produces exactly one failure, and it is your scanner test. Each of your two tests is now the sole guard in the repo for the thing it covers. That is exactly what the issue asked for, and the fact that you ran the mutations yourself and put the output in the PR body is not something I see often.

One thing to fix, and I am fairly sure it is a paste that got away from you rather than anything you meant. tests/helpers.test.ts:354:

it("ranks a pre-release below its associated release (semver 11.3)", () => {    expect(compareVersions("1.2.3", "1.2.3")).toBe(0);
  expect(compareVersions("1.2.3-beta", "1.2.3-alpha")).toBeGreaterThan(0);
});

It duplicates the name of the real test ten lines below, its body is a copy of the assertions from the test above it, and the name does not describe what it asserts. Deleting those three lines is the whole fix. We have no linter yet, so nothing in CI catches a duplicated test name.

One optional question. The old test at tests/helpers.test.ts:389 still hand-copies versionMatchesRange into the test body, which is what your new test now does properly. Happy either way, but if you want to rename it to something that describes what it actually tests, or drop it as superseded, that would be a tidy finish.

The previous commit for OWASP#1087 included a 3-line paste that duplicated the
name of the real pre-release ranking test and copied the body of the
numeric-comparison test above it. The reviewer flagged it; the real test
(semver 11.3) and its assertions are already present unchanged below.

Removes a dead duplicate, leaves all real coverage intact. No behavior change.

Co-authored-by: Charles Lionel Tia-Bia <Retsumdk@users.noreply.github.com>
@Retsumdk

Retsumdk commented Sep 7, 2026

Copy link
Copy Markdown
Author

Thanks for the careful review — glad the mutation verification landed as intended.

Requested fix applied: Removed the three-line duplicate at tests/helpers.test.ts:354 (the pasted block that re-used the name of the real pre-release test and copied the numeric-comparison body). The genuine test (semver 11.3) and its assertions remain unchanged below. Local run: tests/helpers.test.ts passes 47/47 and tests/local-advisory-source.test.ts passes 6/6 after the removal — no behavior change, this is deletion of a dead copy only.

On the optional item: I've left the older hand-copied versionMatchesRange test at line ~389 in place for now, since the new end-to-end coverage supersedes it but it's harmless and I don't want to touch coverage the maintainers may consider intentional. Happy to drop or rename it if you'd prefer a tidy finish — just say the word.

Closes #1087 — awaiting final review.

@Retsumdk

Retsumdk commented Sep 7, 2026

Copy link
Copy Markdown
Author

Thanks for the careful mutation review — verifying both gaps that way means a lot.

The duplication is fixed. That first it("ranks a pre-release below its associated release (semver 11.3)") at the top was indeed a paste that collided two things: it stole the name of the real semver 11.3 test and copied the body of the numeric-comparison test directly above it. I removed those three lines (commit fec80f2) so the helper file now has exactly one canonical pre-release-ranking test, unchanged from what I originally intended to add.

Verified: tests/helpers.test.ts (47 passed) and tests/local-advisory-source.test.ts (6 passed, incl. the real versionMatchesRange path from issue #1087) both go green with the duplicate gone; the wider 29 failures are the long-standing env-dependent e2e/audit-log ones, not touched by this change.

On the optional cleanup (the old versionMatchesRange hand-copy at ~line 389): my new scanner test fully supersedes it, but I've left it in place rather than renaming/dropping it, to keep this PR scoped strictly to what #1087 asked for and avoid touching coverage beyond that. Happy to tidy it in a follow-up if you'd prefer.

@Retsumdk

Retsumdk commented Sep 7, 2026

Copy link
Copy Markdown
Author

Thanks for the thorough review, @sonukapoor — verified exactly as you described.

The duplicated 3-line block at the old tests/helpers.test.ts:354 is removed (dead copy of the numeric-comparison test body, under the wrong test name). The real semver 11.3 pre-release ranking test below it is untouched and still passing, so the build-metadata and versionMatchesRange coverage from #1087 is fully intact.

Confirmed on a clean checkout of test/semver-build-metadata-coverage:

  • tests/helpers.test.ts: 47/47 pass
  • tests/local-advisory-source.test.ts: 6/6 pass (including the issue #1087 real-path test)
  • Full suite: 1654 passed; the only failures are the 29 pre-existing env-dependent audit-log/e2e failures that also fail on an unmodified main.

One question on your optional note: the hand-copied versionMatchesRange at helpers.test.ts:389 doesn't overlap with the new real-path coverage, so I left it as-is to keep this PR to a minimal change with no unrelated churn. Happy to rename or drop it in a follow-up if you'd prefer. Let me know and I'll action it.

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.

test: pin semver build-metadata handling and exercise the real versionMatchesRange path

2 participants