Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(expect): accept array index as number in toHaveProperty #2808

Merged
merged 8 commits into from
Feb 11, 2023
6 changes: 5 additions & 1 deletion docs/api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ type Awaitable<T> = T | PromiseLike<T>
expect(invoice).toHaveProperty('items[0].type', 'apples')
expect(invoice).toHaveProperty('items.0.type', 'apples') // dot notation also works

// Deep referencing using an array containing the keyPath
expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples')
expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples') // string notation also works

// Wrap your key in an array to avoid the key from being parsed as a deep reference
expect(invoice).toHaveProperty(['P.O'], '12345')
})
Expand Down Expand Up @@ -1270,4 +1274,4 @@ type Awaitable<T> = T | PromiseLike<T>

:::tip
If you want to know more, checkout [guide on extending matchers](/guide/extending-matchers).
:::
:::
4 changes: 2 additions & 2 deletions packages/expect/src/jest-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => {
return this.have.length(length)
})
// destructuring, because it checks `arguments` inside, and value is passing as `undefined`
def('toHaveProperty', function (...args: [property: string | string[], value?: any]) {
def('toHaveProperty', function (...args: [property: string | (string | number)[], value?: any]) {
if (Array.isArray(args[0]))
args[0] = args[0].map(key => key.replace(/([.[\]])/g, '\\$1')).join('.')
args[0] = args[0].map(key => String(key).replace(/([.[\]])/g, '\\$1')).join('.')

const actual = this._obj
const [propertyName, expected] = args
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/types/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ declare global {
toBeInstanceOf<E>(expected: E): void
toBeCalledTimes(times: number): void
toHaveLength(length: number): void
toHaveProperty<E>(property: string | string[], value?: E): void
toHaveProperty<E>(property: string | (string | number)[], value?: E): void
toBeCloseTo(number: number, numDigits?: number): void
toHaveBeenCalledTimes(times: number): void
toHaveBeenCalledOnce(): void
Expand Down
13 changes: 12 additions & 1 deletion test/core/test/jest-expect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ describe('jest-expect', () => {

const foo = {}
const complex = {
'0': 'zero',
'foo': 1,
'foo.bar[0]': 'baz',
'a-b': true,
Expand All @@ -227,12 +228,22 @@ describe('jest-expect', () => {

expect(complex).toHaveProperty('a-b')
expect(complex).toHaveProperty('a-b-1.0.0')
expect(complex).toHaveProperty('0')
expect(complex).toHaveProperty('0', 'zero')
expect(complex).toHaveProperty(['0'])
expect(complex).toHaveProperty(['0'], 'zero')
expect(complex).toHaveProperty([0])
expect(complex).toHaveProperty([0], 'zero')
expect(complex).toHaveProperty('foo')
expect(complex).toHaveProperty('foo', 1)
expect(complex).toHaveProperty('bar.foo', 'foo')
expect(complex).toHaveProperty('bar.arr[0]')
expect(complex).toHaveProperty('bar.arr[1].zoo', 'monkey')
expect(complex).toHaveProperty('bar.arr.0')
expect(complex).toHaveProperty(['bar', 'arr', '0'])
expect(complex).toHaveProperty(['bar', 'arr', '0'], 'first')
expect(complex).toHaveProperty(['bar', 'arr', 0])
expect(complex).toHaveProperty(['bar', 'arr', 0], 'first')
expect(complex).toHaveProperty('bar.arr.1.zoo', 'monkey')
expect(complex).toHaveProperty(['bar', 'arr', '1', 'zoo'], 'monkey')
expect(complex).toHaveProperty(['foo.bar[0]'], 'baz')
Expand All @@ -248,7 +259,7 @@ describe('jest-expect', () => {

expect(() => {
expect(complex).toHaveProperty('a-b', false)
}).toThrowErrorMatchingInlineSnapshot('"expected { foo: 1, \'foo.bar[0]\': \'baz\', …(3) } to have property \\"a-b\\" with value false"')
}).toThrowErrorMatchingInlineSnapshot('"expected { \'0\': \'zero\', foo: 1, …(4) } to have property \\"a-b\\" with value false"')
})

it('assertions', () => {
Expand Down