Skip to content

fix: clarify spy-only assertion errors - #2773

Open
LeulTew wants to merge 1 commit into
sinonjs:mainfrom
LeulTew:leultew-spy-only-assertion-diagnostics
Open

LeulTew wants to merge 1 commit into
sinonjs:mainfrom
LeulTew:leultew-spy-only-assertion-diagnostics

Conversation

@LeulTew

@LeulTew LeulTew commented Sep 16, 2026

Copy link
Copy Markdown

Purpose (TL;DR) - mandatory

Reject individual spy calls in calledOnce and calledOnceWithExactly with a clear diagnostic rather than a misleading assertion failure. Correct the documentation to require a whole spy and direct individual-call checks to calledWithExactly.

Fixes #2277.

Validation limits: The unchanged Rollup configuration fails on Windows before producing artifacts, so the configured Node suite, distribution contracts, browser/WebWorker tests, and documentation tests remain unverified. Full Prettier checking reports 85 unchanged files with CRLF-only differences; all three changed files pass.

Implementation and validation

This follows the historical maintainer direction to correct the documentation and reject calls, not implement the original request to accept them. It does not imply new maintainer approval.

The shared fake and assertion-arity checks still run first. Only the two spy-only assertions then require a function and report failures through the existing failAssertion helper. This preserves custom and exposed failure handlers, avoids falsely rejecting spies with a proxy property, and leaves supported individual-call assertions unchanged. No exports, overloads, source-layout changes, dependencies, or public API manifest changes are introduced.

Validation used Windows, Node 26.3.0, and npm 11.16.0:

  • The new real-source diagnostics produced 10 failures before the fix, with 6 supported controls passing.
  • The complete assertion file passes all 203 tests. The source-only Node suite passes 1513 tests, with 10 existing pending tests. These are not results for npm run test-node, which stops in its build prerequisite.
  • Regression coverage includes first and later calls, spies/stubs/fakes, ordinary and Sinon-branded proxy properties, default/custom/nonthrowing/exposed failure handlers, and valid calledWithExactly call-level behavior. Existing argument-diff tests continue to pass.
  • Full npm run lint passes with a per-command PowerShell script-shell override; the default Windows command shell passes literal quotes in the ESLint glob. The changed JavaScript files also pass direct ESLint.
  • Targeted Prettier checking passes for all three changed files, explicitly including the documentation excluded by the root ignore file. Every one of the 85 full-check warnings was compared with the base commit and disappears after in-memory CRLF normalization; no unrelated files were rewritten.
  • The build fails with Entry module "src\create-sinon-api.js" cannot be external. The build script, Rollup configuration, dependency manifests, and public API manifest have identical Git blobs to the base commit. A direct control confirms that the unchanged configuration classifies its own first Windows entry as external.
  • No artifact or browser results are claimed, and no tests were run against stale distributions.

How to verify - mandatory

  1. Check out this branch.
  2. Set HUSKY=0 and HUSKY_SKIP_INSTALL=1 in the command environment, then install locked dependencies with npm ci.
  3. Run npm run test-node, npm run lint, npm run prettier:check, and npm run test-contract on a host where the existing build prerequisites work.

Checklist for author

  • npm run lint passes
  • References to standard library functions are cached.

No new standard-library method references are introduced in production code.

Reject individual spy calls in calledOnce and calledOnceWithExactly with a clear assertion error while preserving calledWithExactly support for individual calls. Correct the documentation to describe the whole-spy contract.

Fixes sinonjs#2277.

This branch has not been deployed

No deployments
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.

sinon.assert.calledOnceWithExactly() does not accept a single spy call

1 participant