Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into antdv-next

This commit is contained in:
dap
2026-03-16 20:33:39 +08:00
358 changed files with 3665 additions and 2339 deletions

View File

@@ -1,10 +1,7 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { loadScript } from '../resources';
const testJsPath =
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js';
describe('loadScript', () => {
beforeEach(() => {
// 每个测试前清空 head保证环境干净
@@ -12,18 +9,14 @@ describe('loadScript', () => {
});
it('should resolve when the script loads successfully', async () => {
const promise = loadScript(testJsPath);
// happy-dom v20+ auto-fires 'load' via handleDisabledFileLoadingAsSuccess
const promise = loadScript('/test-script.js');
// 此时脚本元素已被创建并插入
const script = document.querySelector(
`script[src="${testJsPath}"]`,
'script[src="/test-script.js"]',
) as HTMLScriptElement;
expect(script).toBeTruthy();
// 模拟加载成功
script.dispatchEvent(new Event('load'));
// 等待 promise resolve
await expect(promise).resolves.toBeUndefined();
});
@@ -45,37 +38,44 @@ describe('loadScript', () => {
});
it('should reject when the script fails to load', async () => {
let capturedScript: HTMLScriptElement | null = null;
// 拦截 append捕获 script 元素但不插入 DOM
// 防止 happy-dom v20+ 自动触发 load 事件
const appendSpy = vi
.spyOn(document.head, 'append')
.mockImplementation((...nodes) => {
for (const node of nodes) {
if (node instanceof HTMLScriptElement) {
capturedScript = node;
}
}
});
const promise = loadScript('error.js');
const script = document.querySelector(
'script[src="error.js"]',
) as HTMLScriptElement;
expect(script).toBeTruthy();
appendSpy.mockRestore();
// 模拟加载失败
script.dispatchEvent(new Event('error'));
expect(capturedScript).toBeTruthy();
if (!capturedScript) {
throw new Error('Expected the captured script element to exist');
}
capturedScript.dispatchEvent(new Event('error'));
await expect(promise).rejects.toThrow('Failed to load script: error.js');
});
it('should handle multiple concurrent calls and only insert one script tag', async () => {
const p1 = loadScript(testJsPath);
const p2 = loadScript(testJsPath);
const script = document.querySelector(
`script[src="${testJsPath}"]`,
) as HTMLScriptElement;
expect(script).toBeTruthy();
// 触发一次 load两个 promise 都应该 resolve
script.dispatchEvent(new Event('load'));
const p1 = loadScript('/test-script.js');
const p2 = loadScript('/test-script.js');
// happy-dom v20+ auto-fires 'load',两个 promise 都应该 resolve
await expect(p1).resolves.toBeUndefined();
await expect(p2).resolves.toBeUndefined();
// 只插入一次
const scripts = document.head.querySelectorAll(
`script[src="${testJsPath}"]`,
'script[src="/test-script.js"]',
);
expect(scripts).toHaveLength(1);
});

View File

@@ -1,4 +1,3 @@
// eslint-disable-next-line vue/prefer-import-from-vue
import { isFunction, isObject, isString } from '@vue/shared';
/**