vitest
vitest copied to clipboard
`expect` `toThrow` does not match empty string
Describe the bug
The toThrow
method on the JestAssertion
interface does not match the empty string when using a regular expression matcher (e.g., /^$/
). Instead, it gives the following output:
AssertionError: expected [Function] to throw an error
- Expected:
null
+ Received:
""
Reproduction
https://stackblitz.com/edit/vitest-dev-vitest-otkry8?file=test%2Fbasic.test.ts
import { expect, test } from 'vitest';
test('should throw empty string', () => {
expect(() => { throw '' }).toThrow(/^$/);
});
System Info
System:
OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 5.31 GB / 7.60 GB
Container: Yes
Shell: 5.1.16 - /bin/bash
Binaries:
Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm
bun: 1.0.25 - ~/.bun/bin/bun
npmPackages:
vitest: ^1.3.0 => 1.3.0
Used Package Manager
npm
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
I think this behavior is directly coming from chai:
https://github.com/vitest-dev/vitest/blob/7d9b1fb02338beef048487ef07f6083aa5559106/packages/expect/src/jest-expect.ts#L530-L532
Here is a reproduction: https://stackblitz.com/edit/vitest-dev-vitest-8a9pvm?file=repro-chai.mjs
Show code
import * as chai from 'chai';
try {
chai
.expect(() => {
throw '';
})
.throws(/^$/);
} catch (e) {
console.error(e);
}
// AssertionError: expected [Function] to throw an error
// at eval (/home/projects/vitest-dev-vitest-8a9pvm/repro-chai.mjs:21:6)
// at _0xba6ba0.run (https://vitestdevvitest8a9pvm-zty5.w-credentialless.staticblitz.com/blitz.a9c8a5a3.js:352:372622)
// at _0x3775c6._evaluate (https://vitestdevvitest8a9pvm-zty5.w-credentialless.staticblitz.com/blitz.a9c8a5a3.js:352:378123)
// at async ModuleJob.run (node:internal/modules/esm/module_job:181:2372) {
// actual: '',
// expected: null,
// showDiff: true,
// operator: 'strictEqual'
// }
try {
chai
.expect(() => {
throw 'hello';
})
.throws(/^$/);
} catch (e) {
console.error(e);
}
// AssertionError: expected [Function] to throw error matching /^$/ but got 'hello'
// at eval (/home/projects/vitest-dev-vitest-8a9pvm/repro-chai.mjs:31:6)
// at _0xba6ba0.run (https://vitestdevvitest8a9pvm-zty5.w-credentialless.staticblitz.com/blitz.a9c8a5a3.js:352:372622)
// at _0x3775c6._evaluate (https://vitestdevvitest8a9pvm-zty5.w-credentialless.staticblitz.com/blitz.a9c8a5a3.js:352:378123)
// at async ModuleJob.run (node:internal/modules/esm/module_job:181:2372) {
// actual: 'hello',
// expected: /^$/,
// showDiff: true,
// operator: 'strictEqual'
// }
This'll probably be fixed in chaijs/chai#1609
@43081j what if I want to throw undefined
?
Just kidding 😄
Seriously though, couldn't the initial value be a dummy object? Like this:
const noError = {};
var caughtErr = noError;
// ...
caughtErr !== noError
we could support undefined
(via a flag rather than a dummy obj most likely) but i just figured nobody should really be doing that in the first place 🤔 tbh, all thrown errors these days should be Error
instances
i feel like supporting that will only lead to confusion further down the line ("expected x not to throw but it threw undefined
" etc)
we released chai 5.1.1 recently which fixes this, and renovatebot already bumped the version here in vitest. this issue can be closed i think