Fix mockLocale for vitest 4.x spyOn breaking change (#5303)
This commit is contained in:
@@ -12,11 +12,31 @@ import { vi } from "vitest";
|
||||
* Defaults to `en-GB`
|
||||
*/
|
||||
export const mockLocale = (defaultLocale = "en-GB"): void => {
|
||||
const { DateTimeFormat } = Intl;
|
||||
const OriginalDateTimeFormat = Intl.DateTimeFormat;
|
||||
|
||||
// Vitest 4.x requires function/class implementations for spyOn mocks when
|
||||
// mocking constructors. For built-in constructors like Intl.DateTimeFormat
|
||||
// that have internal slots, we use a function that returns a new instance.
|
||||
// This is valid JavaScript - when a constructor returns an object, that
|
||||
// object becomes the instance (instead of `this`).
|
||||
function MockDateTimeFormat(
|
||||
this: unknown,
|
||||
locales?: Intl.LocalesArgument,
|
||||
options?: Intl.DateTimeFormatOptions,
|
||||
): Intl.DateTimeFormat {
|
||||
// Apply default locale when no locale is specified
|
||||
return new OriginalDateTimeFormat(locales || defaultLocale, options);
|
||||
}
|
||||
|
||||
// Inherit static methods from the original DateTimeFormat
|
||||
Object.setPrototypeOf(MockDateTimeFormat, OriginalDateTimeFormat);
|
||||
// Set up prototype chain so instanceof checks work correctly
|
||||
Object.setPrototypeOf(
|
||||
MockDateTimeFormat.prototype,
|
||||
OriginalDateTimeFormat.prototype,
|
||||
);
|
||||
|
||||
vi.spyOn(Intl, "DateTimeFormat").mockImplementation(
|
||||
(
|
||||
locales?: Intl.LocalesArgument,
|
||||
options?: Intl.DateTimeFormatOptions | undefined,
|
||||
) => new DateTimeFormat(locales || defaultLocale, options),
|
||||
MockDateTimeFormat as typeof Intl.DateTimeFormat,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user