@becrafter/prompt-manager 0.1.12 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/desktop/assets/app.1.png +0 -0
- package/app/desktop/assets/app.png +0 -0
- package/app/desktop/assets/icons/icon.icns +0 -0
- package/app/desktop/assets/icons/icon.ico +0 -0
- package/app/desktop/assets/icons/icon.png +0 -0
- package/app/desktop/assets/icons/tray.png +0 -0
- package/app/desktop/assets/templates/about.html +147 -0
- package/app/desktop/assets/tray.1.png +0 -0
- package/app/desktop/assets/tray.png +0 -0
- package/app/desktop/docs/ASSETS_PLANNING.md +351 -0
- package/app/desktop/docs/REFACTORING_SUMMARY.md +205 -0
- package/app/desktop/main.js +340 -0
- package/app/desktop/package-lock.json +6912 -0
- package/app/desktop/package.json +119 -0
- package/app/desktop/preload.js +7 -0
- package/app/desktop/src/core/error-handler.js +108 -0
- package/app/desktop/src/core/event-emitter.js +84 -0
- package/app/desktop/src/core/logger.js +130 -0
- package/app/desktop/src/core/state-manager.js +125 -0
- package/app/desktop/src/services/module-loader.js +330 -0
- package/app/desktop/src/services/runtime-manager.js +398 -0
- package/app/desktop/src/services/service-manager.js +210 -0
- package/app/desktop/src/services/update-manager.js +267 -0
- package/app/desktop/src/ui/about-dialog-manager.js +208 -0
- package/app/desktop/src/ui/admin-window-manager.js +757 -0
- package/app/desktop/src/ui/splash-manager.js +253 -0
- package/app/desktop/src/ui/tray-manager.js +186 -0
- package/app/desktop/src/utils/icon-manager.js +133 -0
- package/app/desktop/src/utils/path-utils.js +58 -0
- package/app/desktop/src/utils/resource-paths.js +49 -0
- package/app/desktop/src/utils/resource-sync.js +260 -0
- package/app/desktop/src/utils/runtime-sync.js +241 -0
- package/app/desktop/src/utils/self-check.js +288 -0
- package/app/desktop/src/utils/template-renderer.js +284 -0
- package/app/desktop/src/utils/version-utils.js +59 -0
- package/env.example +1 -1
- package/examples/prompts/developer/code-review.yaml +32 -0
- package/examples/prompts/developer/code_refactoring.yaml +31 -0
- package/examples/prompts/developer/doc-generator.yaml +36 -0
- package/examples/prompts/developer/error-code-fixer.yaml +35 -0
- package/examples/prompts/engineer/engineer-professional.yaml +92 -0
- package/examples/prompts/engineer/laowang-engineer.yaml +132 -0
- package/examples/prompts/engineer/nekomata-engineer.yaml +123 -0
- package/examples/prompts/engineer/ojousama-engineer.yaml +124 -0
- package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +117 -0
- package/examples/prompts/generator/gen_3d_webpage_html.yaml +75 -0
- package/examples/prompts/generator/gen_bento_grid_html.yaml +112 -0
- package/examples/prompts/generator/gen_html_web_page.yaml +88 -0
- package/examples/prompts/generator/gen_knowledge_card_html.yaml +83 -0
- package/examples/prompts/generator/gen_magazine_card_html.yaml +82 -0
- package/examples/prompts/generator/gen_mimeng_headline_title.yaml +71 -0
- package/examples/prompts/generator/gen_podcast_script.yaml +69 -0
- package/examples/prompts/generator/gen_prd_prototype_html.yaml +175 -0
- package/examples/prompts/generator/gen_summarize.yaml +157 -0
- package/examples/prompts/generator/gen_title.yaml +119 -0
- package/examples/prompts/generator/others/api_documentation.yaml +32 -0
- package/examples/prompts/generator/others/build_mcp_server.yaml +26 -0
- package/examples/prompts/generator/others/project_architecture.yaml +31 -0
- package/examples/prompts/generator/others/test_case_generator.yaml +30 -0
- package/examples/prompts/generator/others/writing_assistant.yaml +72 -0
- package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +105 -0
- package/examples/prompts/workflow/sixstep-workflow.yaml +192 -0
- package/package.json +13 -1
- package/packages/server/.eslintrc.js +70 -0
- package/packages/server/.husky/pre-commit +8 -0
- package/packages/server/.husky/pre-push +8 -0
- package/packages/server/.prettierrc +14 -0
- package/packages/server/dev-server.js +90 -0
- package/packages/server/jsdoc.conf.json +39 -0
- package/packages/server/playwright.config.js +62 -0
- package/packages/server/scripts/generate-docs.js +300 -0
- package/packages/server/server.js +1 -0
- package/packages/server/services/TerminalService.js +84 -11
- package/packages/server/tests/e2e/terminal-e2e.test.js +315 -0
- package/packages/server/tests/integration/terminal-websocket.test.js +372 -0
- package/packages/server/tests/integration/tools.test.js +264 -0
- package/packages/server/tests/setup.js +45 -0
- package/packages/server/tests/unit/TerminalService.test.js +410 -0
- package/packages/server/tests/unit/WebSocketService.test.js +403 -0
- package/packages/server/tests/unit/core.test.js +94 -0
- package/packages/server/typedoc.json +52 -0
- package/packages/server/utils/config.js +1 -1
- package/packages/server/utils/util.js +59 -5
- package/packages/server/vitest.config.js +74 -0
- package/packages/web/0.d1c5a72339dfc32ad86a.js +1 -0
- package/packages/web/112.8807b976372b2b0541a8.js +1 -0
- package/packages/web/130.584c7e365da413f5d9be.js +1 -0
- package/packages/web/142.72c985bc29720f975cca.js +1 -0
- package/packages/web/165.a05fc53bf84d18db36b8.js +2 -0
- package/packages/web/165.a05fc53bf84d18db36b8.js.LICENSE.txt +9 -0
- package/packages/web/203.724ab9f717b80554c397.js +1 -0
- package/packages/web/241.bf941d4f02866795f64a.js +1 -0
- package/packages/web/249.54cfb224af63f5f5ec55.js +1 -0
- package/packages/web/291.6df35042f8f296fca7cd.js +1 -0
- package/packages/web/319.2fab900a31b29873f666.js +1 -0
- package/packages/web/32.c78d866281995ec33a7b.js +1 -0
- package/packages/web/325.9ca297d0f73f38468ce9.js +1 -0
- package/packages/web/366.2f9b48fdbf8eee039e57.js +1 -0
- package/packages/web/378.6be08c612cd5a3ef97dc.js +1 -0
- package/packages/web/393.7a2f817515c5e90623d7.js +1 -0
- package/packages/web/412.062df5f732d5ba203415.js +1 -0
- package/packages/web/426.08656fef4918b3fb19ad.js +1 -0
- package/packages/web/465.2be8018327130a3bd798.js +1 -0
- package/packages/web/48.8ca96fc93667a715e67a.js +1 -0
- package/packages/web/480.44c1f1a2927486ac3d4f.js +1 -0
- package/packages/web/489.e041a8d0db15dc96d607.js +1 -0
- package/packages/web/490.9ffb26c907de020d671b.js +1 -0
- package/packages/web/492.58781369e348d91fc06a.js +1 -0
- package/packages/web/495.ed63e99791a87167c6b3.js +1 -0
- package/packages/web/510.4cc07ab7d30d5c1cd17f.js +1 -0
- package/packages/web/543.3af155ed4fa237664308.js +1 -0
- package/packages/web/567.f04ab60f8e2c2fb0745a.js +1 -0
- package/packages/web/592.f3ad085fa9c1849daa06.js +1 -0
- package/packages/web/616.b03fb801b3433b17750f.js +1 -0
- package/packages/web/617.d88def54921d2c4dc44c.js +1 -0
- package/packages/web/641.d30787d674f548928261.js +1 -0
- package/packages/web/672.5269c8399fa42a5af95d.js +1 -0
- package/packages/web/731.97cab92b71811c502bda.js +1 -0
- package/packages/web/746.3947c6f0235407e420fb.js +1 -0
- package/packages/web/756.a53233b3f3913900d5ac.js +1 -0
- package/packages/web/77.68801af593a28a631fbf.js +1 -0
- package/packages/web/802.53b2bff3cf2a69f7b80c.js +1 -0
- package/packages/web/815.b6dfab82265f56c7e046.js +1 -0
- package/packages/web/821.f5a13e5c735aac244eb9.js +1 -0
- package/packages/web/846.b9bf97d5f559270675ce.js +1 -0
- package/packages/web/869.7c10403f500e6201407f.js +1 -0
- package/packages/web/885.135050364f99e6924fb5.js +1 -0
- package/packages/web/901.fd5aeb9df630609a2b43.js +1 -0
- package/packages/web/928.f67e590de3caa4daa3ae.js +1 -0
- package/packages/web/955.d833403521ba4dd567ee.js +1 -0
- package/packages/web/981.a45cb745cf424044c8c8.js +1 -0
- package/packages/web/992.645320b60c74c8787482.js +1 -0
- package/packages/web/996.ed9a963dc9e7439eca9a.js +1 -0
- package/packages/web/css/codemirror-theme_xq-light.css +43 -0
- package/packages/web/css/codemirror.css +344 -0
- package/packages/web/css/main.3b61356b384d2f11f47f.css +7268 -0
- package/packages/web/index.html +3 -0
- package/packages/web/main.77c2c4b553ca3fac223b.js +2 -0
- package/packages/web/main.77c2c4b553ca3fac223b.js.LICENSE.txt +3 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具系统测试文件
|
|
3
|
+
*
|
|
4
|
+
* 用于验证工具加载、工具管理等功能是否正常工作
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { toolLoaderService } from './tool-loader.service.js';
|
|
8
|
+
import { handleToolM } from './tool-manager.handler.js';
|
|
9
|
+
import { logger } from '../utils/logger.js';
|
|
10
|
+
|
|
11
|
+
// 测试工具加载服务
|
|
12
|
+
async function testToolLoader() {
|
|
13
|
+
console.log('\n========== 测试工具加载服务 ==========\n');
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
// 初始化工具加载器
|
|
17
|
+
console.log('1. 初始化工具加载器...');
|
|
18
|
+
await toolLoaderService.initialize();
|
|
19
|
+
console.log('✓ 工具加载器初始化成功');
|
|
20
|
+
|
|
21
|
+
// 获取所有工具列表
|
|
22
|
+
console.log('\n2. 获取所有工具列表...');
|
|
23
|
+
const tools = toolLoaderService.getAllTools();
|
|
24
|
+
console.log(`✓ 共加载 ${tools.length} 个工具:`);
|
|
25
|
+
tools.forEach(tool => {
|
|
26
|
+
console.log(` - ${tool.name}: ${tool.metadata.description || '无描述'}`);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// 检查 filesystem 工具是否存在
|
|
30
|
+
console.log('\n3. 检查 filesystem 工具是否存在...');
|
|
31
|
+
const hasFilesystem = toolLoaderService.hasTool('filesystem');
|
|
32
|
+
if (hasFilesystem) {
|
|
33
|
+
console.log('✓ filesystem 工具已加载');
|
|
34
|
+
|
|
35
|
+
// 获取 filesystem 工具详情
|
|
36
|
+
const filesystemTool = toolLoaderService.getTool('filesystem');
|
|
37
|
+
console.log(` - 元数据:`, filesystemTool.metadata);
|
|
38
|
+
} else {
|
|
39
|
+
console.log('✗ filesystem 工具未找到');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('✗ 测试失败:', error.message);
|
|
45
|
+
console.error(error.stack);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 测试手册模式
|
|
51
|
+
async function testManualMode() {
|
|
52
|
+
console.log('\n========== 测试手册模式 (manual) ==========\n');
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const yamlInput = `tool: tool://filesystem
|
|
56
|
+
mode: manual`;
|
|
57
|
+
|
|
58
|
+
console.log('YAML 输入:');
|
|
59
|
+
console.log(yamlInput);
|
|
60
|
+
console.log('\n执行 handleToolM...');
|
|
61
|
+
|
|
62
|
+
const result = await handleToolM({ yaml: yamlInput });
|
|
63
|
+
|
|
64
|
+
console.log('\n✓ 手册模式执行成功');
|
|
65
|
+
console.log('返回结果类型:', result.content[0].type);
|
|
66
|
+
console.log('手册内容长度:', result.content[0].text.length, '字符');
|
|
67
|
+
console.log('\n手册内容预览(前 500 字符):');
|
|
68
|
+
console.log(result.content[0].text.substring(0, 500));
|
|
69
|
+
console.log('...\n');
|
|
70
|
+
|
|
71
|
+
return true;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('✗ 测试失败:', error.message);
|
|
74
|
+
console.error(error.stack);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 测试执行模式
|
|
80
|
+
async function testExecuteMode() {
|
|
81
|
+
console.log('\n========== 测试执行模式 (execute) ==========\n');
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const yamlInput = `tool: tool://filesystem
|
|
85
|
+
mode: execute
|
|
86
|
+
parameters:
|
|
87
|
+
method: list_allowed_directories`;
|
|
88
|
+
|
|
89
|
+
console.log('YAML 输入:');
|
|
90
|
+
console.log(yamlInput);
|
|
91
|
+
console.log('\n执行 handleToolM...');
|
|
92
|
+
|
|
93
|
+
const result = await handleToolM({ yaml: yamlInput });
|
|
94
|
+
|
|
95
|
+
console.log('\n✓ 执行模式测试成功');
|
|
96
|
+
console.log('返回结果:');
|
|
97
|
+
console.log(result.content[0].text);
|
|
98
|
+
|
|
99
|
+
return true;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('✗ 测试失败:', error.message);
|
|
102
|
+
console.error(error.stack);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 测试配置模式
|
|
108
|
+
async function testConfigureMode() {
|
|
109
|
+
console.log('\n========== 测试配置模式 (configure) ==========\n');
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const yamlInput = `tool: tool://filesystem
|
|
113
|
+
mode: configure
|
|
114
|
+
parameters:
|
|
115
|
+
ALLOWED_DIRECTORIES: '["~/.prompt-manager", "/tmp"]'`;
|
|
116
|
+
|
|
117
|
+
console.log('YAML 输入:');
|
|
118
|
+
console.log(yamlInput);
|
|
119
|
+
console.log('\n执行 handleToolM...');
|
|
120
|
+
|
|
121
|
+
const result = await handleToolM({ yaml: yamlInput });
|
|
122
|
+
|
|
123
|
+
console.log('\n✓ 配置模式测试成功');
|
|
124
|
+
console.log('返回结果:');
|
|
125
|
+
console.log(result.content[0].text);
|
|
126
|
+
|
|
127
|
+
return true;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('✗ 测试失败:', error.message);
|
|
130
|
+
console.error(error.stack);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 测试日志模式
|
|
136
|
+
async function testLogMode() {
|
|
137
|
+
console.log('\n========== 测试日志模式 (log) ==========\n');
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const yamlInput = `tool: tool://filesystem
|
|
141
|
+
mode: log
|
|
142
|
+
parameters:
|
|
143
|
+
action: tail
|
|
144
|
+
lines: 50`;
|
|
145
|
+
|
|
146
|
+
console.log('YAML 输入:');
|
|
147
|
+
console.log(yamlInput);
|
|
148
|
+
console.log('\n执行 handleToolM...');
|
|
149
|
+
|
|
150
|
+
const result = await handleToolM({ yaml: yamlInput });
|
|
151
|
+
|
|
152
|
+
console.log('\n✓ 日志模式测试成功');
|
|
153
|
+
console.log('返回结果:');
|
|
154
|
+
console.log(result.content[0].text);
|
|
155
|
+
|
|
156
|
+
return true;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error('✗ 测试失败:', error.message);
|
|
159
|
+
console.error(error.stack);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 测试错误处理
|
|
165
|
+
async function testErrorHandling() {
|
|
166
|
+
console.log('\n========== 测试错误处理 ==========\n');
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
console.log('1. 测试不存在的工具...');
|
|
170
|
+
try {
|
|
171
|
+
const yamlInput = `tool: tool://nonexistent
|
|
172
|
+
mode: execute`;
|
|
173
|
+
await handleToolM({ yaml: yamlInput });
|
|
174
|
+
console.log('✗ 应该抛出错误但没有');
|
|
175
|
+
return false;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.log('✓ 正确抛出错误:', error.message.split('\n')[0]);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
console.log('\n2. 测试缺少必需参数...');
|
|
181
|
+
try {
|
|
182
|
+
await handleToolM({});
|
|
183
|
+
console.log('✗ 应该抛出错误但没有');
|
|
184
|
+
return false;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.log('✓ 正确抛出错误:', error.message);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
console.log('\n3. 测试无效的工具格式...');
|
|
190
|
+
try {
|
|
191
|
+
const yamlInput = `tool: filesystem
|
|
192
|
+
mode: execute`;
|
|
193
|
+
await handleToolM({ yaml: yamlInput });
|
|
194
|
+
console.log('✗ 应该抛出错误但没有');
|
|
195
|
+
return false;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.log('✓ 正确抛出错误:', error.message.split('\n')[0]);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return true;
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.error('✗ 测试失败:', error.message);
|
|
203
|
+
console.error(error.stack);
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// 主测试函数
|
|
209
|
+
async function runAllTests() {
|
|
210
|
+
console.log('\n');
|
|
211
|
+
console.log('╔════════════════════════════════════════════════╗');
|
|
212
|
+
console.log('║ Prompt Manager 工具系统测试套件 ║');
|
|
213
|
+
console.log('╚════════════════════════════════════════════════╝');
|
|
214
|
+
|
|
215
|
+
const results = [];
|
|
216
|
+
|
|
217
|
+
// 运行所有测试
|
|
218
|
+
results.push({ name: '工具加载服务', passed: await testToolLoader() });
|
|
219
|
+
results.push({ name: '手册模式', passed: await testManualMode() });
|
|
220
|
+
results.push({ name: '执行模式', passed: await testExecuteMode() });
|
|
221
|
+
results.push({ name: '配置模式', passed: await testConfigureMode() });
|
|
222
|
+
results.push({ name: '日志模式', passed: await testLogMode() });
|
|
223
|
+
results.push({ name: '错误处理', passed: await testErrorHandling() });
|
|
224
|
+
|
|
225
|
+
// 输出测试总结
|
|
226
|
+
console.log('\n');
|
|
227
|
+
console.log('╔════════════════════════════════════════════════╗');
|
|
228
|
+
console.log('║ 测试结果总结 ║');
|
|
229
|
+
console.log('╚════════════════════════════════════════════════╝');
|
|
230
|
+
console.log('\n');
|
|
231
|
+
|
|
232
|
+
const passed = results.filter(r => r.passed).length;
|
|
233
|
+
const failed = results.filter(r => !r.passed).length;
|
|
234
|
+
|
|
235
|
+
results.forEach(result => {
|
|
236
|
+
const status = result.passed ? '✓ PASS' : '✗ FAIL';
|
|
237
|
+
console.log(`${status} - ${result.name}`);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
console.log('\n');
|
|
241
|
+
console.log(`总计: ${results.length} 个测试`);
|
|
242
|
+
console.log(`通过: ${passed} 个`);
|
|
243
|
+
console.log(`失败: ${failed} 个`);
|
|
244
|
+
console.log('\n');
|
|
245
|
+
|
|
246
|
+
if (failed === 0) {
|
|
247
|
+
console.log('🎉 所有测试通过!工具系统运行正常。');
|
|
248
|
+
} else {
|
|
249
|
+
console.log('⚠️ 部分测试失败,请检查错误信息。');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return failed === 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// 运行测试
|
|
256
|
+
runAllTests()
|
|
257
|
+
.then(success => {
|
|
258
|
+
process.exit(success ? 0 : 1);
|
|
259
|
+
})
|
|
260
|
+
.catch(error => {
|
|
261
|
+
console.error('测试运行失败:', error);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
});
|
|
264
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest 测试设置文件
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { vi } from 'vitest';
|
|
6
|
+
|
|
7
|
+
// Mock node-pty 模块
|
|
8
|
+
vi.mock('node-pty', () => {
|
|
9
|
+
const mockPty = {
|
|
10
|
+
on: vi.fn(),
|
|
11
|
+
write: vi.fn(),
|
|
12
|
+
resize: vi.fn(),
|
|
13
|
+
kill: vi.fn(),
|
|
14
|
+
pid: 12345,
|
|
15
|
+
cols: 80,
|
|
16
|
+
rows: 24
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
default: {
|
|
21
|
+
spawn: vi.fn(() => mockPty)
|
|
22
|
+
},
|
|
23
|
+
spawn: vi.fn(() => mockPty)
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Mock fs-extra 的某些方法(如果需要)
|
|
28
|
+
vi.mock('fs-extra', async () => {
|
|
29
|
+
const actual = await vi.importActual('fs-extra');
|
|
30
|
+
return {
|
|
31
|
+
...actual,
|
|
32
|
+
// 可以在这里添加特定的mock
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// 全局测试设置
|
|
37
|
+
global.console = {
|
|
38
|
+
...console,
|
|
39
|
+
// 在测试中减少日志输出
|
|
40
|
+
log: vi.fn(),
|
|
41
|
+
debug: vi.fn(),
|
|
42
|
+
info: vi.fn(),
|
|
43
|
+
warn: vi.fn(),
|
|
44
|
+
error: vi.fn(),
|
|
45
|
+
};
|