feat(extend): custom asymmetric matchers
This commit is contained in:
parent
c9f3eb158e
commit
052e8fea2f
9
packages/playwright/types/test.d.ts
vendored
9
packages/playwright/types/test.d.ts
vendored
|
|
@ -6573,6 +6573,11 @@ type PollMatchers<R, T, ExtendedMatchers> = {
|
||||||
not: PollMatchers<R, T, ExtendedMatchers>;
|
not: PollMatchers<R, T, ExtendedMatchers>;
|
||||||
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
||||||
|
|
||||||
|
type ExtendedAsymmetricMatchers<M = {}> = {
|
||||||
|
[K in keyof M]: M[K] extends (this: ExpectMatcherState, received: any, ...args: infer P) => any ? (...args: P) => AsymmetricMatcher
|
||||||
|
: never
|
||||||
|
}
|
||||||
|
|
||||||
export type Expect<ExtendedMatchers = {}> = {
|
export type Expect<ExtendedMatchers = {}> = {
|
||||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
||||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
||||||
|
|
@ -6584,8 +6589,8 @@ export type Expect<ExtendedMatchers = {}> = {
|
||||||
soft?: boolean,
|
soft?: boolean,
|
||||||
}) => Expect<ExtendedMatchers>;
|
}) => Expect<ExtendedMatchers>;
|
||||||
getState(): unknown;
|
getState(): unknown;
|
||||||
not: Omit<AsymmetricMatchers, 'any' | 'anything'>;
|
not: Omit<AsymmetricMatchers & ExtendedAsymmetricMatchers<ExtendedMatchers>, 'any' | 'anything'>;
|
||||||
} & AsymmetricMatchers;
|
} & AsymmetricMatchers & ExtendedAsymmetricMatchers<ExtendedMatchers>;
|
||||||
|
|
||||||
// --- BEGINGLOBAL ---
|
// --- BEGINGLOBAL ---
|
||||||
declare global {
|
declare global {
|
||||||
|
|
|
||||||
|
|
@ -910,12 +910,21 @@ test('should support mergeExpects (TSC)', async ({ runTSC }) => {
|
||||||
const expect1 = baseExpect.extend({
|
const expect1 = baseExpect.extend({
|
||||||
async toBeAGoodPage(page: Page, x: number) {
|
async toBeAGoodPage(page: Page, x: number) {
|
||||||
return { pass: true, message: () => '' };
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
matchFoo(received: unknown, expected: string) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
toBeFoo(received: unknown) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const expect2 = baseExpect.extend({
|
const expect2 = baseExpect.extend({
|
||||||
async toBeABadPage(page: Page, y: string) {
|
async toBeABadPage(page: Page, y: string) {
|
||||||
return { pass: true, message: () => '' };
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
matchBar(received: unknown, expected: string) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -924,12 +933,19 @@ test('should support mergeExpects (TSC)', async ({ runTSC }) => {
|
||||||
test('custom matchers', async ({ page }) => {
|
test('custom matchers', async ({ page }) => {
|
||||||
await expect(page).toBeAGoodPage(123);
|
await expect(page).toBeAGoodPage(123);
|
||||||
await expect(page).toBeABadPage('123');
|
await expect(page).toBeABadPage('123');
|
||||||
|
await expect('foo').toEqual(expect.matchFoo('123'));
|
||||||
|
await expect('bar').not.toEqual(expect.not.matchBar('123'));
|
||||||
|
await expect({ name: 'Foo' }).toMatchObject({ name: expect.toBeFoo() });
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
await expect(page).toBeAMediocrePage();
|
await expect(page).toBeAMediocrePage();
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
await expect(page).toBeABadPage(123);
|
await expect(page).toBeABadPage(123);
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
await expect(page).toBeAGoodPage('123');
|
await expect(page).toBeAGoodPage('123');
|
||||||
|
// @ts-expect-error
|
||||||
|
expect('foo').toEqual(expect.matchFoo(123));
|
||||||
|
// @ts-expect-error
|
||||||
|
expect('bar').not.toEqual(expect.not.matchBar(123));
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
|
@ -945,12 +961,21 @@ test('should support mergeExpects', async ({ runInlineTest }) => {
|
||||||
const expect1 = baseExpect.extend({
|
const expect1 = baseExpect.extend({
|
||||||
async toBeAGoodPage(page: Page, x: number) {
|
async toBeAGoodPage(page: Page, x: number) {
|
||||||
return { pass: true, message: () => '' };
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
matchFoo(received: unknown, expected: string) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
toBeFoo(received: unknown) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const expect2 = baseExpect.extend({
|
const expect2 = baseExpect.extend({
|
||||||
async toBeABadPage(page: Page, y: string) {
|
async toBeABadPage(page: Page, y: string) {
|
||||||
return { pass: true, message: () => '' };
|
return { pass: true, message: () => '' };
|
||||||
|
},
|
||||||
|
matchBar(received: unknown, expected: string) {
|
||||||
|
return { pass: true, message: () => '' };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -959,6 +984,9 @@ test('should support mergeExpects', async ({ runInlineTest }) => {
|
||||||
test('custom matchers', async ({ page }) => {
|
test('custom matchers', async ({ page }) => {
|
||||||
await expect(page).toBeAGoodPage(123);
|
await expect(page).toBeAGoodPage(123);
|
||||||
await expect(page).toBeABadPage('123');
|
await expect(page).toBeABadPage('123');
|
||||||
|
await expect('foo').toEqual(expect.matchFoo('123'));
|
||||||
|
await expect('bar').not.toEqual(expect.not.matchBar('123'));
|
||||||
|
await expect({ name: 'Foo' }).toMatchObject({ name: expect.toBeFoo() });
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
}, { workers: 1 });
|
}, { workers: 1 });
|
||||||
|
|
|
||||||
9
utils/generate_types/overrides-test.d.ts
vendored
9
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -411,6 +411,11 @@ type PollMatchers<R, T, ExtendedMatchers> = {
|
||||||
not: PollMatchers<R, T, ExtendedMatchers>;
|
not: PollMatchers<R, T, ExtendedMatchers>;
|
||||||
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
} & BaseMatchers<R, T> & ToUserMatcherObject<ExtendedMatchers, T>;
|
||||||
|
|
||||||
|
type ExtendedAsymmetricMatchers<M = {}> = {
|
||||||
|
[K in keyof M]: M[K] extends (this: ExpectMatcherState, received: any, ...args: infer P) => any ? (...args: P) => AsymmetricMatcher
|
||||||
|
: never
|
||||||
|
}
|
||||||
|
|
||||||
export type Expect<ExtendedMatchers = {}> = {
|
export type Expect<ExtendedMatchers = {}> = {
|
||||||
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
<T = unknown>(actual: T, messageOrOptions?: string | { message?: string }): MakeMatchers<void, T, ExtendedMatchers>;
|
||||||
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
soft: <T = unknown>(actual: T, messageOrOptions?: string | { message?: string }) => MakeMatchers<void, T, ExtendedMatchers>;
|
||||||
|
|
@ -422,8 +427,8 @@ export type Expect<ExtendedMatchers = {}> = {
|
||||||
soft?: boolean,
|
soft?: boolean,
|
||||||
}) => Expect<ExtendedMatchers>;
|
}) => Expect<ExtendedMatchers>;
|
||||||
getState(): unknown;
|
getState(): unknown;
|
||||||
not: Omit<AsymmetricMatchers, 'any' | 'anything'>;
|
not: Omit<AsymmetricMatchers & ExtendedAsymmetricMatchers<ExtendedMatchers>, 'any' | 'anything'>;
|
||||||
} & AsymmetricMatchers;
|
} & AsymmetricMatchers & ExtendedAsymmetricMatchers<ExtendedMatchers>;
|
||||||
|
|
||||||
// --- BEGINGLOBAL ---
|
// --- BEGINGLOBAL ---
|
||||||
declare global {
|
declare global {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue