import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { installArrayAtPolyfill, installObjectHasOwnPolyfill, installPromiseWithResolversPolyfill, installStringAtPolyfill, installStructuredClonePolyfill, installUrlCanParsePolyfill, } from './polyfills'; const descriptors = new Map< string, [object, PropertyKey, PropertyDescriptor | undefined] >(); function remember(key: string, target: object, property: PropertyKey) { descriptors.set(key, [ target, property, Object.getOwnPropertyDescriptor(target, property), ]); } function remove(target: object, property: PropertyKey) { Reflect.deleteProperty(target, property); } beforeEach(() => { remember('arrayAt', Array.prototype, 'at'); remember('stringAt', String.prototype, 'at'); remember('hasOwn', Object, 'hasOwn'); remember('withResolvers', Promise, 'withResolvers'); remember('structuredClone', globalThis, 'structuredClone'); remember('canParse', URL, 'canParse'); }); afterEach(() => { for (const [target, property, descriptor] of descriptors.values()) { if (descriptor) Object.defineProperty(target, property, descriptor); else remove(target, property); } descriptors.clear(); }); describe('chrome 90 browser polyfills', () => { it('restores missing collection and object APIs', () => { remove(Array.prototype, 'at'); remove(String.prototype, 'at'); remove(Object, 'hasOwn'); installArrayAtPolyfill(); installStringAtPolyfill(); installObjectHasOwnPolyfill(); expect(['first', 'last'].at(-1)).toBe('last'); expect('EasyFlow'.at(-1)).toBe('w'); expect(Object.hasOwn({ ready: true }, 'ready')).toBe(true); }); it('restores missing async, clone and URL APIs', async () => { remove(Promise, 'withResolvers'); remove(globalThis, 'structuredClone'); remove(URL, 'canParse'); installPromiseWithResolversPolyfill(); installStructuredClonePolyfill(); installUrlCanParsePolyfill(); // eslint-disable-next-line n/no-unsupported-features/es-syntax -- 测试目标就是验证该 API 的兼容实现。 const { promise, resolve } = Promise.withResolvers(); resolve('ready'); await expect(promise).resolves.toBe('ready'); const source: { map: Map; self?: unknown } = { map: new Map([['answer', 2026]]), }; source.self = source; const clone = structuredClone(source); expect(clone.self).toBe(clone); expect(clone.map.get('answer')).toBe(2026); expect(URL.canParse('/chat', 'https://easyflow.example')).toBe(true); }); });