- 包声明 type:module 时 .js 产物被 Node 按 ESM 解析:Node 16/18 下 require 报 ERR_REQUIRE_ESM,Node 20+ 拿到 namespace 对象(success/version 等属性 undefined) - dist/metona-toast.cjs.js → .cjs,dist/react.cjs.js → .cjs - 主包 CJS footer 将 default 提升为 module.exports:require() 直接返回 MeToast(兼容 .default / .MeToast / .Met / .Toast / .VERSION 所有用法) - 版本 0.5.1(0.5.0 已发布带问题产物) - 真实消费者验证:CJS/ESM/React 子包四路加载全部正常
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
/**
|
||
* 环境隔离测试 — 需要切换 document/window/localStorage 环境并调用 jest.resetModules()。
|
||
* 独立成文件:resetModules 会清空模块缓存,若与其他测试同文件会导致
|
||
* 后续 require 拿到新模块实例、与 import 时绑定的实例状态分裂。
|
||
* 注:jsdom 以 getter 暴露 document/window,普通赋值无效,须用 defineProperty 覆盖。
|
||
* @module tests
|
||
* @version 0.5.1
|
||
*/
|
||
|
||
/** 临时移除全局对象,返回恢复函数 */
|
||
const hideGlobal = (key: string): (() => void) => {
|
||
const desc = Object.getOwnPropertyDescriptor(global, key);
|
||
Object.defineProperty(global, key, { value: undefined, configurable: true, writable: true });
|
||
return () => {
|
||
if (desc) Object.defineProperty(global, key, desc);
|
||
else delete (global as Record<string, unknown>)[key];
|
||
};
|
||
};
|
||
|
||
describe('环境隔离(SSR / localStorage 异常路径)', () => {
|
||
test('escapeHTML SSR 路径(无 document)', () => {
|
||
const restore = hideGlobal('document');
|
||
jest.resetModules();
|
||
const { escapeHTML } = require('../src/utils.js');
|
||
const result = escapeHTML('<script>alert("xss")</script>');
|
||
expect(result).not.toContain('<script>');
|
||
expect(result).toContain('<script>');
|
||
restore();
|
||
});
|
||
|
||
test('prefersDark 无 window 时返回 false', () => {
|
||
const restore = hideGlobal('window');
|
||
jest.resetModules();
|
||
const { prefersDark } = require('../src/utils.js');
|
||
expect(prefersDark()).toBe(false);
|
||
restore();
|
||
});
|
||
|
||
test('saveTheme localStorage 异常被捕获', () => {
|
||
const orig = (global as Record<string, unknown>).localStorage;
|
||
(global as Record<string, unknown>).localStorage = undefined;
|
||
jest.resetModules();
|
||
const { saveTheme } = require('../src/themes.js');
|
||
expect(() => saveTheme('dark')).not.toThrow();
|
||
(global as Record<string, unknown>).localStorage = orig;
|
||
});
|
||
|
||
test('loadLocale localStorage 异常返回 default', () => {
|
||
const orig = (global as Record<string, unknown>).localStorage;
|
||
(global as Record<string, unknown>).localStorage = {
|
||
getItem: () => { throw new Error('quota'); },
|
||
};
|
||
jest.resetModules();
|
||
const { loadLocale } = require('../src/i18n.js');
|
||
expect(typeof loadLocale()).toBe('string');
|
||
(global as Record<string, unknown>).localStorage = orig;
|
||
});
|
||
});
|