@zhin.js/core 1.0.5 → 1.0.7

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.
@@ -34,54 +34,56 @@ vi.mock('segment-matcher', () => {
34
34
  return { SegmentMatcher, MatchResult }
35
35
  })
36
36
 
37
- // Mock Plugin
38
- const mockPlugin = {
39
- name: 'test-plugin',
40
- getPermit: vi.fn((permission: string) => {
41
- // Mock permit checker
42
- return {
43
- check: vi.fn(async (perm: string, message: any) => {
44
- if (permission === 'adapter(discord)') {
45
- return message.$adapter === 'discord'
46
- }
47
- if (permission === 'adapter(telegram)') {
48
- return message.$adapter === 'telegram'
49
- }
50
- if (permission === 'adapter(email)') {
51
- return message.$adapter === 'email'
52
- }
53
- if (permission === 'adapter(test)') {
54
- return message.$adapter === 'test'
55
- }
56
- return true
57
- })
58
- }
59
- })
37
+ // Mock App with permissions
38
+ const mockApp = {
39
+ permissions: {
40
+ get: vi.fn((permission: string) => {
41
+ // Mock permit checker
42
+ return {
43
+ check: vi.fn(async (perm: string, message: any) => {
44
+ if (permission === 'adapter(discord)') {
45
+ return message.$adapter === 'discord'
46
+ }
47
+ if (permission === 'adapter(telegram)') {
48
+ return message.$adapter === 'telegram'
49
+ }
50
+ if (permission === 'adapter(email)') {
51
+ return message.$adapter === 'email'
52
+ }
53
+ if (permission === 'adapter(test)') {
54
+ return message.$adapter === 'test'
55
+ }
56
+ return true
57
+ })
58
+ }
59
+ })
60
+ }
60
61
  } as any
61
62
 
62
- // 为多个权限测试创建特殊的 mock plugin
63
- const multiPermitMockPlugin = {
64
- name: 'test-plugin',
65
- getPermit: vi.fn((permission: string) => {
66
- return {
67
- check: vi.fn(async (perm: string, message: any) => {
68
- // 对于多个权限,只要有一个匹配就返回 true
69
- if (permission === 'adapter(discord)' && message.$adapter === 'discord') {
70
- return true
71
- }
72
- if (permission === 'adapter(telegram)' && message.$adapter === 'telegram') {
73
- return true
74
- }
75
- if (permission === 'adapter(email)' && message.$adapter === 'email') {
76
- return true
77
- }
78
- if (permission === 'adapter(test)' && message.$adapter === 'test') {
79
- return true
80
- }
81
- return false
82
- })
83
- }
84
- })
63
+ // 为多个权限测试创建特殊的 mock app
64
+ const multiPermitMockApp = {
65
+ permissions: {
66
+ get: vi.fn((permission: string) => {
67
+ return {
68
+ check: vi.fn(async (perm: string, message: any) => {
69
+ // 对于多个权限,只要有一个匹配就返回 true
70
+ if (permission === 'adapter(discord)' && message.$adapter === 'discord') {
71
+ return true
72
+ }
73
+ if (permission === 'adapter(telegram)' && message.$adapter === 'telegram') {
74
+ return true
75
+ }
76
+ if (permission === 'adapter(email)' && message.$adapter === 'email') {
77
+ return true
78
+ }
79
+ if (permission === 'adapter(test)' && message.$adapter === 'test') {
80
+ return true
81
+ }
82
+ return false
83
+ })
84
+ }
85
+ })
86
+ }
85
87
  } as any
86
88
 
87
89
  describe('Command系统测试', () => {
@@ -135,8 +137,8 @@ describe('Command系统测试', () => {
135
137
  $raw: 'hello world'
136
138
  }
137
139
 
138
- const discordResult = await command.handle(discordMessage, mockPlugin)
139
- const telegramResult = await command.handle(telegramMessage, mockPlugin)
140
+ const discordResult = await command.handle(discordMessage, mockApp)
141
+ const telegramResult = await command.handle(telegramMessage, mockApp)
140
142
 
141
143
  expect(discordResult).toBe('Hello from Discord!')
142
144
  expect(telegramResult).toBeUndefined()
@@ -183,9 +185,9 @@ describe('Command系统测试', () => {
183
185
  $raw: 'hello'
184
186
  }
185
187
 
186
- const discordResult = await command.handle(discordMessage, mockPlugin)
187
- const telegramResult = await command.handle(telegramMessage, mockPlugin)
188
- const emailResult = await command.handle(emailMessage, mockPlugin)
188
+ const discordResult = await command.handle(discordMessage, mockApp)
189
+ const telegramResult = await command.handle(telegramMessage, mockApp)
190
+ const emailResult = await command.handle(emailMessage, mockApp)
189
191
 
190
192
  expect(discordResult).toBe('Hello!')
191
193
  expect(telegramResult).toBeUndefined()
@@ -212,7 +214,7 @@ describe('Command系统测试', () => {
212
214
  $raw: 'test message'
213
215
  }
214
216
 
215
- const result = await command.handle(message, mockPlugin)
217
+ const result = await command.handle(message, mockApp)
216
218
 
217
219
  expect(actionSpy).toHaveBeenCalledWith(message, expect.any(Object))
218
220
  expect(result).toBe('Action executed!')
@@ -240,7 +242,7 @@ describe('Command系统测试', () => {
240
242
  $raw: 'test'
241
243
  }
242
244
 
243
- const result = await command.handle(message, mockPlugin)
245
+ const result = await command.handle(message, mockApp)
244
246
 
245
247
  expect(action1).toHaveBeenCalled()
246
248
  expect(action2).toHaveBeenCalled()
@@ -266,7 +268,7 @@ describe('Command系统测试', () => {
266
268
  $raw: 'async test'
267
269
  }
268
270
 
269
- const result = await command.handle(message, mockPlugin)
271
+ const result = await command.handle(message, mockApp)
270
272
 
271
273
  expect(asyncAction).toHaveBeenCalled()
272
274
  expect(result).toBe('Async result')
@@ -290,7 +292,7 @@ describe('Command系统测试', () => {
290
292
  $raw: 'echo hello world'
291
293
  }
292
294
 
293
- const result = await command.handle(message, mockPlugin)
295
+ const result = await command.handle(message, mockApp)
294
296
 
295
297
  expect(actionSpy).toHaveBeenCalledWith(
296
298
  message,
@@ -320,7 +322,7 @@ describe('Command系统测试', () => {
320
322
  $raw: 'goodbye'
321
323
  }
322
324
 
323
- const result = await command.handle(message, mockPlugin)
325
+ const result = await command.handle(message, mockApp)
324
326
  expect(result).toBeUndefined()
325
327
  })
326
328
 
@@ -340,7 +342,7 @@ describe('Command系统测试', () => {
340
342
  $raw: ''
341
343
  }
342
344
 
343
- const result = await command.handle(message, mockPlugin)
345
+ const result = await command.handle(message, mockApp)
344
346
  expect(result).toBeUndefined()
345
347
  })
346
348
 
@@ -362,7 +364,7 @@ describe('Command系统测试', () => {
362
364
  $raw: '[图片]'
363
365
  }
364
366
 
365
- const result = await command.handle(message, mockPlugin)
367
+ const result = await command.handle(message, mockApp)
366
368
  expect(result).toBeUndefined()
367
369
  })
368
370
  })
@@ -412,9 +414,9 @@ describe('Command系统测试', () => {
412
414
  $raw: 'hello world'
413
415
  }
414
416
 
415
- const validResult = await command.handle(validMessage, mockPlugin)
416
- const wrongAdapterResult = await command.handle(wrongAdapterMessage, mockPlugin)
417
- const nonMatchingResult = await command.handle(nonMatchingMessage, mockPlugin)
417
+ const validResult = await command.handle(validMessage, mockApp)
418
+ const wrongAdapterResult = await command.handle(wrongAdapterMessage, mockApp)
419
+ const nonMatchingResult = await command.handle(nonMatchingMessage, mockApp)
418
420
 
419
421
  expect(validResult).toBe('Admin command executed')
420
422
  expect(wrongAdapterResult).toBeUndefined()
@@ -443,7 +445,7 @@ describe('Command系统测试', () => {
443
445
  $raw: 'error test'
444
446
  }
445
447
 
446
- await expect(command.handle(message, mockPlugin)).rejects.toThrow('Action failed')
448
+ await expect(command.handle(message, mockApp)).rejects.toThrow('Action failed')
447
449
  })
448
450
 
449
451
  it('应该正确处理动作中的异步错误', async () => {
@@ -464,7 +466,7 @@ describe('Command系统测试', () => {
464
466
  $raw: 'async-error test'
465
467
  }
466
468
 
467
- await expect(command.handle(message, mockPlugin)).rejects.toThrow('Async action failed')
469
+ await expect(command.handle(message, mockApp)).rejects.toThrow('Async action failed')
468
470
  })
469
471
  })
470
472
 
@@ -504,7 +506,7 @@ describe('Command系统测试', () => {
504
506
 
505
507
  const startTime = Date.now()
506
508
  const results = await Promise.all(
507
- messages.map(message => command.handle(message, mockPlugin))
509
+ messages.map(message => command.handle(message, mockApp))
508
510
  )
509
511
  const endTime = Date.now()
510
512
 
@@ -539,7 +541,7 @@ describe('Command系统测试', () => {
539
541
  $raw: 'say hello world from bot'
540
542
  }
541
543
 
542
- const result = await command.handle(message, mockPlugin)
544
+ const result = await command.handle(message, mockApp)
543
545
 
544
546
  expect(actionSpy).toHaveBeenCalledWith(
545
547
  message,
@@ -587,8 +589,8 @@ describe('Command系统测试', () => {
587
589
  $raw: 'multi test'
588
590
  }
589
591
 
590
- const privateResult = await command.handle(privateMessage, mockPlugin)
591
- const groupResult = await command.handle(groupMessage, mockPlugin)
592
+ const privateResult = await command.handle(privateMessage, mockApp)
593
+ const groupResult = await command.handle(groupMessage, mockApp)
592
594
 
593
595
  expect(privateResult).toBe('私人消息响应')
594
596
  expect(groupResult).toBe('群组消息响应')
@@ -613,7 +615,7 @@ describe('Command系统测试', () => {
613
615
  $raw: 'admin test'
614
616
  }
615
617
 
616
- const result = await command.handle(message, mockPlugin)
618
+ const result = await command.handle(message, mockApp)
617
619
  expect(result).toBeUndefined()
618
620
  })
619
621
 
@@ -634,7 +636,7 @@ describe('Command系统测试', () => {
634
636
  $raw: 'admin test'
635
637
  }
636
638
 
637
- const result = await command.handle(message, mockPlugin)
639
+ const result = await command.handle(message, mockApp)
638
640
  expect(result).toBe('Admin command')
639
641
  })
640
642
  })
@@ -5,6 +5,7 @@ import { MessageCommand } from '../src/command'
5
5
  import { Component, defineComponent, ComponentContext } from '../src/component'
6
6
  import { Message } from '../src/message'
7
7
  import { PluginError, MessageError } from '../src/errors'
8
+ import * as path from 'path'
8
9
 
9
10
  describe('Plugin系统测试', () => {
10
11
  let app: App
@@ -12,7 +13,8 @@ describe('Plugin系统测试', () => {
12
13
 
13
14
  beforeEach(() => {
14
15
  app = new App()
15
- plugin = app.createDependency('test-plugin', 'test-plugin.ts')
16
+ // 使用 mock 文件路径,不依赖真实文件
17
+ plugin = app.createDependency('test-plugin', '/mock/test-plugin.ts')
16
18
  })
17
19
 
18
20
  afterEach(async () => {
@@ -23,13 +25,13 @@ describe('Plugin系统测试', () => {
23
25
  it('应该正确初始化Plugin实例', () => {
24
26
  expect(plugin).toBeInstanceOf(Plugin)
25
27
  expect(plugin.name).toBe('test-plugin')
26
- expect(plugin.filename).toBe('test-plugin.ts')
28
+ expect(plugin.filename).toContain('test-plugin.ts')
27
29
  expect(plugin.app).toBe(app)
28
30
  expect(plugin.commands).toEqual([])
29
31
  expect(plugin.components).toBeInstanceOf(Map)
30
32
  expect(plugin.components.size).toBe(0)
31
- // Plugin有默认的命令处理中间件,所以不为空
32
- expect(plugin.middlewares.length).toBeGreaterThan(0)
33
+ // Plugin没有默认的中间件
34
+ expect(plugin.middlewares.length).toBe(0)
33
35
  })
34
36
 
35
37
  it('应该正确获取logger实例', () => {
@@ -44,121 +46,29 @@ describe('Plugin系统测试', () => {
44
46
  describe('中间件系统测试', () => {
45
47
  it('应该正确添加中间件', () => {
46
48
  const middleware = vi.fn(async (message, next) => {
47
- await next()
48
- })
49
+ await next();
50
+ });
49
51
 
50
- const initialCount = plugin.middlewares.length
51
- const unsubscribe = plugin.addMiddleware(middleware)
52
- expect(plugin.middlewares).toContain(middleware)
53
- expect(plugin.middlewares.length).toBe(initialCount + 1) // 增加1个中间件
54
- expect(typeof unsubscribe).toBe('function')
52
+ const initialCount = plugin.middlewares.length;
53
+ const unsubscribe = plugin.addMiddleware(middleware);
54
+ expect(plugin.middlewares).toContain(middleware);
55
+ expect(plugin.middlewares.length).toBe(initialCount + 1); // 增加1个中间件
56
+ expect(typeof unsubscribe).toBe('function');
55
57
 
56
58
  // 测试移除中间件
57
- unsubscribe()
58
- expect(plugin.middlewares).not.toContain(middleware)
59
- })
60
-
61
- it('应该按顺序执行中间件', async () => {
62
- const executionOrder: number[] = []
63
-
64
- const middleware1 = vi.fn(async (message, next) => {
65
- executionOrder.push(1)
66
- await next()
67
- executionOrder.push(4)
68
- })
69
-
70
- const middleware2 = vi.fn(async (message, next) => {
71
- executionOrder.push(2)
72
- await next()
73
- executionOrder.push(3)
74
- })
75
-
76
- plugin.addMiddleware(middleware1)
77
- plugin.addMiddleware(middleware2)
78
-
79
- // 模拟消息对象
80
- const mockMessage: Message = {
81
- $id: '1',
82
- $adapter: 'test',
83
- $bot: 'test-bot',
84
- $content: [{ type: 'text', data: { text: 'test' } }],
85
- $sender: { id: 'user1', name: 'Test User' },
86
- $reply: vi.fn(),
87
- $channel: { id: 'test-channel', type: 'private' },
88
- $timestamp: Date.now(),
89
- $raw: 'test message'
90
- }
91
-
92
- // 触发消息处理
93
- await plugin.emit('message.receive', mockMessage)
94
-
95
- // 由于有默认的命令中间件,执行顺序可能会不同
96
- // 但我们的中间件应该被调用
97
- expect(middleware1).toHaveBeenCalledWith(mockMessage, expect.any(Function))
98
- expect(middleware2).toHaveBeenCalledWith(mockMessage, expect.any(Function))
99
- // 至少应该执行了我们的中间件的前半部分
100
- expect(executionOrder).toContain(1)
101
- expect(executionOrder).toContain(2)
102
- })
103
-
104
- it('应该正确处理中间件异常', async () => {
105
- const errorMiddleware = vi.fn(async () => {
106
- throw new Error('中间件测试错误')
107
- })
108
-
109
- plugin.addMiddleware(errorMiddleware)
110
-
111
- const mockMessage: Message = {
112
- $id: '1',
113
- $adapter: 'test',
114
- $bot: 'test-bot',
115
- $content: [{ type: 'text', data: { text: 'test' } }],
116
- $sender: { id: 'user1', name: 'Test User' },
117
- $reply: vi.fn(),
118
- $channel: { id: 'test-channel', type: 'private' },
119
- $timestamp: Date.now(),
120
- $raw: 'test message'
121
- }
122
-
123
- await plugin.emit('message.receive', mockMessage)
124
-
125
- // 验证错误处理逻辑 - 中间件异常会被处理但可能不会回复给用户
126
- expect(errorMiddleware).toHaveBeenCalled()
127
- })
59
+ unsubscribe();
60
+ expect(plugin.middlewares).not.toContain(middleware);
61
+ });
128
62
  })
129
63
 
130
64
  describe('命令系统测试', () => {
131
65
  it('应该正确添加命令', () => {
132
- const mockCommand = new MessageCommand('test')
133
- plugin.addCommand(mockCommand)
134
-
135
- expect(plugin.commands).toContain(mockCommand)
136
- expect(plugin.commands.length).toBe(1)
137
- })
138
-
139
- it('应该通过默认中间件处理命令', async () => {
140
- const mockCommand = new MessageCommand('test')
141
- const handleSpy = vi.spyOn(mockCommand, 'handle').mockResolvedValue(undefined)
142
-
143
- plugin.addCommand(mockCommand)
144
-
145
- const mockMessage: Message = {
146
- $id: '1',
147
- $adapter: 'test',
148
- $bot: 'test-bot',
149
- $content: [{ type: 'text', data: { text: 'test' } }],
150
- $sender: { id: 'user1', name: 'Test User' },
151
- $reply: vi.fn(),
152
- $channel: { id: 'test-channel', type: 'private' },
153
- $timestamp: Date.now(),
154
- $raw: 'test message'
155
- }
66
+ const mockCommand = new MessageCommand('test');
67
+ plugin.addCommand(mockCommand);
156
68
 
157
- await plugin.emit('message.receive', mockMessage)
158
-
159
- // 验证命令被调用(handle 现在需要传入 plugin 作为第二个参数)
160
- expect(handleSpy).toHaveBeenCalledWith(mockMessage, expect.any(Plugin))
161
- })
69
+ expect(plugin.commands).toContain(mockCommand);
70
+ expect(plugin.commands.length).toBe(1);
71
+ });
162
72
  })
163
73
 
164
74
  describe('函数式组件系统测试', () => {
@@ -223,22 +133,34 @@ describe('Plugin系统测试', () => {
223
133
 
224
134
  describe('消息发送测试', () => {
225
135
  it('应该正确发送消息', async () => {
226
- const appSendSpy = vi.spyOn(app, 'sendMessage').mockResolvedValue()
227
-
228
- const sendOptions = { content: 'Hello World' }
229
- await plugin.sendMessage(sendOptions)
136
+ const appSendSpy = vi.spyOn(app, 'sendMessage').mockResolvedValue('message-id');
230
137
 
231
- expect(appSendSpy).toHaveBeenCalledWith(sendOptions)
232
- })
138
+ const sendOptions = {
139
+ content: 'Hello World',
140
+ context: 'test-context',
141
+ bot: 'test-bot',
142
+ id: 'test-id',
143
+ type: 'text' // 确保类型符合 MessageType
144
+ };
145
+ await plugin.sendMessage(sendOptions);
233
146
 
234
- it('应该正确处理发送消息失败', async () => {
235
- const sendError = new Error('发送失败')
236
- vi.spyOn(app, 'sendMessage').mockRejectedValue(sendError)
147
+ expect(appSendSpy).toHaveBeenCalledWith(sendOptions);
148
+ });
237
149
 
238
- const sendOptions = { content: 'Hello World' }
239
-
240
- await expect(plugin.sendMessage(sendOptions)).rejects.toThrow(MessageError)
241
- })
150
+ it('应该正确处理发送消息失败', async () => {
151
+ const sendError = new Error('发送失败');
152
+ vi.spyOn(app, 'sendMessage').mockRejectedValue(sendError);
153
+
154
+ const sendOptions = {
155
+ content: 'Hello World',
156
+ context: 'test-context',
157
+ bot: 'test-bot',
158
+ id: 'test-id',
159
+ type: 'text' // 确保类型符合 MessageType
160
+ };
161
+
162
+ await expect(plugin.sendMessage(sendOptions)).rejects.toThrow(MessageError);
163
+ });
242
164
  })
243
165
 
244
166
  describe('Prompt系统测试', () => {
@@ -285,30 +207,6 @@ describe('Plugin系统测试', () => {
285
207
  })
286
208
  })
287
209
 
288
- describe('错误处理测试', () => {
289
- it('应该正确处理消息处理异常', async () => {
290
- const errorMiddleware = vi.fn().mockRejectedValue(new Error('处理失败'))
291
- plugin.addMiddleware(errorMiddleware)
292
-
293
- const mockMessage: Message = {
294
- $id: 'error-msg',
295
- $adapter: 'test',
296
- $bot: 'test-bot',
297
- $content: [{ type: 'text', data: { text: 'test' } }],
298
- $sender: { id: 'user1', name: 'Test User' },
299
- $reply: vi.fn(),
300
- $channel: { id: 'error-channel', type: 'private' },
301
- $timestamp: Date.now(),
302
- $raw: 'error message'
303
- }
304
-
305
- await plugin.emit('message.receive', mockMessage)
306
-
307
- // 验证错误中间件被调用
308
- expect(errorMiddleware).toHaveBeenCalled()
309
- })
310
- })
311
-
312
210
  describe('资源清理测试', () => {
313
211
  it('应该正确销毁插件', () => {
314
212
  const middleware = vi.fn()
@@ -333,35 +231,4 @@ describe('Plugin系统测试', () => {
333
231
  })
334
232
  })
335
233
 
336
- describe('集成测试', () => {
337
- it('应该完整处理消息流程', async () => {
338
- // 设置测试环境
339
- const middlewareExecuted = vi.fn()
340
-
341
- // 添加测试中间件
342
- plugin.addMiddleware(async (message, next) => {
343
- middlewareExecuted(message.$content)
344
- await next()
345
- })
346
-
347
- // 模拟消息
348
- const mockMessage: Message = {
349
- $id: 'integration-test',
350
- $adapter: 'test',
351
- $bot: 'test-bot',
352
- $content: [{ type: 'text', data: { text: 'hello' } }],
353
- $sender: { id: 'user1', name: 'Test User' },
354
- $reply: vi.fn(),
355
- $channel: { id: 'test-channel', type: 'private' },
356
- $timestamp: Date.now(),
357
- $raw: 'hello'
358
- }
359
-
360
- // 触发消息处理
361
- await plugin.emit('message.receive', mockMessage)
362
-
363
- // 验证中间件被调用
364
- expect(middlewareExecuted).toHaveBeenCalled()
365
- })
366
- })
367
234
  })