Skip to content

chore: assert resolved values instead of using t.resolves - #10185

Open
oBusk wants to merge 3 commits into
npm:latestfrom
oBusk:fix/tests-resolves-checks-value
Open

oBusk wants to merge 3 commits into
npm:latestfrom
oBusk:fix/tests-resolves-checks-value

Conversation

@oBusk

@oBusk oBusk commented Oct 28, 2026

Copy link
Copy Markdown

While working on #10184, I noticed that some tests were misusing tap's t.resolves(). They seem to assume that t.resolves(promise, 'value') checks that the promise resolves to 'value', but the second parameter is actually the assertion message (its label). t.resolves() only checks that the promise resolves, not what it resolves to. I checked whether tap has ever worked the way these tests assume, but I couldn't see that it ever has.

I fixed the tests that affected #10184, but figured there might be other examples, so I looked through the project and found the same issue in two places:

  • the npm access command tests (test/lib/commands/access.js)
  • the libnpmaccess workspace tests (workspaces/libnpmaccess/test/index.js)

This PR replaces those uses of t.resolves() with t.strictSame(), which deep-compares the arrays and objects the promises resolve to. The libnpmaccess tests passed without changing any expected values.

In the npm access completion test, two expectations turned out to be wrong once the values were actually compared:

  • One expected the top-level completions in a different order than the function returns them. The function works as intended, so I updated the expected order in the test. It never failed before because of the incorrect use of t.resolves().
  • The other expected an empty array when a subcommand was already typed, but completion() returned undefined. npm completion (wrap() in lib/commands/completion.js) then throws on undefined.length, inside a try/catch that swallows the error. So users saw no difference, but the test makes the intended behaviour clear. I updated completion() to return [], which matches the test and shouldn't change anything for users.

oBusk added 3 commits October 28, 2026 22:52
t.resolves(promise, message) only checks that the promise resolves; its
second argument is the assertion message, not an expected value. These
tests passed an expected value there, so the results were never
compared:

- test/lib/commands/access.js: all completion expectations
- workspaces/libnpmaccess/test/index.js: getCollaborators, getPackages
  and getVisibility

Await the result and compare it with t.strictSame instead.
The top-level `npm access` completion test expected
['list', 'get', 'set', 'grant', 'revoke'], but the command has always
returned its subcommands alphabetically. This went unnoticed because
the test used t.resolves, which never compared the value.
Once a subcommand was already typed (e.g. `npm access grant <TAB>`),
completion() fell through without a return value and resolved to
undefined. `npm completion` then threw on `undefined.length` and
swallowed the error, so the empty result only worked by accident.

Return [] so completion always resolves to an array, as the completion
contract expects and as the existing test already assumed.
@oBusk
oBusk requested a review from a team as a code owner October 28, 2026 22:25
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