diff --git a/packages/koishi-core/tests/help.spec.ts b/packages/koishi-core/tests/help.spec.ts index c00562a88f..41b2356b0b 100644 --- a/packages/koishi-core/tests/help.spec.ts +++ b/packages/koishi-core/tests/help.spec.ts @@ -8,7 +8,7 @@ import { install } from '@sinonjs/fake-timers' Message.GLOBAL_HELP_EPILOG = 'EPILOG' const app = new App().plugin(memory) -const session = app.createSession('user', 123) +const session = app.session(123) const now = Date.now() before(async () => { @@ -23,13 +23,13 @@ let message: string describe('Help Command', () => { it('basic support', async () => { - await session.shouldHaveReply('help', [ + await session.shouldReply('help', [ '当前可用的指令有:', ' help 显示帮助信息', 'EPILOG', ].join('\n')) - await session.shouldHaveReply('help help', message = [ + await session.shouldReply('help help', message = [ 'help [command]', '显示帮助信息', '可用的选项有:', @@ -37,9 +37,9 @@ describe('Help Command', () => { ' -H, --show-hidden 查看隐藏的选项和指令', ].join('\n')) - await session.shouldHaveReply('help heip', '指令未找到。你要找的是不是“help”?发送空行或句号以调用推测的指令。') - await session.shouldHaveReply('.', message) - await session.shouldHaveReply('help -h', message) + await session.shouldReply('help heip', '指令未找到。你要找的是不是“help”?发送空行或句号以调用推测的指令。') + await session.shouldReply('.', message) + await session.shouldReply('help -h', message) }) it('command attributes', async () => { @@ -55,15 +55,15 @@ describe('Help Command', () => { const clock = install({ now }) - await session.shouldHaveReply('help foo1', 'foo1\nDESCRIPTION\n别名:foo。') - await session.shouldHaveReply('help foo2', 'foo2\nDESCRIPTION\n最低权限:2 级。') - await session.shouldHaveReply('help foo3', 'foo3\nDESCRIPTION(指令已禁用)') - await session.shouldHaveReply('help foo4', 'foo4\nDESCRIPTION\nUSAGE TEXT') - await session.shouldHaveReply('help foo5', 'foo5\nDESCRIPTION\n123') - await session.shouldHaveReply('help foo6', 'foo6\nDESCRIPTION\n使用示例:\n EXAMPLE TEXT') - await session.shouldHaveReply('help foo7', 'foo7\nDESCRIPTION\n已调用次数:1/3。') - await session.shouldHaveReply('help foo8', 'foo8\nDESCRIPTION\n距离下次调用还需:60/180 秒。') - await session.shouldHaveReply('help foo9', 'foo9\nDESCRIPTION\n距离下次调用还需:0/180 秒。') + await session.shouldReply('help foo1', 'foo1\nDESCRIPTION\n别名:foo。') + await session.shouldReply('help foo2', 'foo2\nDESCRIPTION\n最低权限:2 级。') + await session.shouldReply('help foo3', 'foo3\nDESCRIPTION(指令已禁用)') + await session.shouldReply('help foo4', 'foo4\nDESCRIPTION\nUSAGE TEXT') + await session.shouldReply('help foo5', 'foo5\nDESCRIPTION\n123') + await session.shouldReply('help foo6', 'foo6\nDESCRIPTION\n使用示例:\n EXAMPLE TEXT') + await session.shouldReply('help foo7', 'foo7\nDESCRIPTION\n已调用次数:1/3。') + await session.shouldReply('help foo8', 'foo8\nDESCRIPTION\n距离下次调用还需:60/180 秒。') + await session.shouldReply('help foo9', 'foo9\nDESCRIPTION\n距离下次调用还需:0/180 秒。') clock.uninstall() }) @@ -75,18 +75,18 @@ describe('Help Command', () => { .option('opt2', '选项2', { notUsage: true }) .option('opt3', '选项3', { hidden: true }) - await session.shouldHaveReply('help bar', message = 'bar\nDESCRIPTION\n已调用次数:0/2。') + await session.shouldReply('help bar', message = 'bar\nDESCRIPTION\n已调用次数:0/2。') bar.config.hideOptions = false - await session.shouldHaveReply('help bar', [ + await session.shouldReply('help bar', [ message, '可用的选项有:', ' --opt1 选项1', ' --opt2 选项2(不计入总次数)', ].join('\n')) - await session.shouldHaveReply('help bar -H', [ + await session.shouldReply('help bar -H', [ message, '可用的选项有:', ' -h, --help 显示此信息', @@ -95,7 +95,7 @@ describe('Help Command', () => { ' --opt3 选项3', ].join('\n')) - await session.shouldHaveReply('help bar -a', [ + await session.shouldReply('help bar -a', [ message, '可用的选项有(括号内为额外要求的权限等级):', ' (2) --opt1 选项1', @@ -109,21 +109,21 @@ describe('Help Command', () => { const foo1 = foo2.subcommand('foo1') const foo3 = foo1.subcommand('foo3') - await session.shouldHaveReply('help foo2', [ + await session.shouldReply('help foo2', [ 'foo2', 'DESCRIPTION', '可用的子指令有:', ' foo1 DESCRIPTION', ].join('\n')) - await session.shouldHaveReply('help foo2 -a', [ + await session.shouldReply('help foo2 -a', [ 'foo2', 'DESCRIPTION', '可用的子指令有(括号内为对应的最低权限等级,标有星号的表示含有子指令):', ' foo1 (1*) DESCRIPTION', ].join('\n')) - await session.shouldHaveReply('help foo1 -a', [ + await session.shouldReply('help foo1 -a', [ 'foo1', 'DESCRIPTION', '别名:foo。', @@ -136,7 +136,7 @@ describe('Help Command', () => { Message.GLOBAL_HELP_EPILOG = '' const app = new App() - const session = app.createSession('user', 123) - await session.shouldHaveReply('help', '当前可用的指令有:\n help 显示帮助信息') + const session = app.session(123) + await session.shouldReply('help', '当前可用的指令有:\n help 显示帮助信息') }) }) diff --git a/packages/koishi-core/tests/hook.spec.ts b/packages/koishi-core/tests/hook.spec.ts index a0482b65e8..73c5e03dd0 100644 --- a/packages/koishi-core/tests/hook.spec.ts +++ b/packages/koishi-core/tests/hook.spec.ts @@ -97,7 +97,7 @@ describe('Hook API', () => { const mid2 = wrap((_, next) => next()) app.addMiddleware(mid1) app.addMiddleware(mid2) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') expect(callSequence).to.deep.equal([mid1, mid2]) }) @@ -107,7 +107,7 @@ describe('Hook API', () => { app.addMiddleware(mid1) app.addMiddleware(mid2) expect(callSequence).to.deep.equal([]) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') expect(callSequence).to.deep.equal([mid1]) }) @@ -118,7 +118,7 @@ describe('Hook API', () => { app.addMiddleware(mid1) app.prependMiddleware(mid2) app.prependMiddleware(mid3) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') expect(callSequence).to.deep.equal([mid3, mid2, mid1]) }) @@ -130,7 +130,7 @@ describe('Hook API', () => { const mid5 = wrap((next) => next()) app.addMiddleware(mid1) app.addMiddleware(mid2) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') expect(callSequence).to.deep.equal([mid1, mid2, mid3, mid4, mid5]) }) @@ -138,7 +138,7 @@ describe('Hook API', () => { midWarn.mockClear() const errorMessage = 'error message' app.addMiddleware(() => { throw new Error(errorMessage) }) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') expect(midWarn.mock.calls).to.have.length(1) }) @@ -146,7 +146,7 @@ describe('Hook API', () => { midWarn.mockClear() app.addMiddleware((_, next) => (next(), undefined)) app.addMiddleware((_, next) => sleep(0).then(() => next())) - await app.createSession('user', 123).send('foo') + await app.session(123).receive('foo') await sleep(0) expect(midWarn.mock.calls).to.have.length(1) }) diff --git a/packages/koishi-core/tests/runtime.spec.ts b/packages/koishi-core/tests/runtime.spec.ts index fa2b287831..b74c0c2a7c 100644 --- a/packages/koishi-core/tests/runtime.spec.ts +++ b/packages/koishi-core/tests/runtime.spec.ts @@ -13,11 +13,11 @@ app.plugin(memory) // make coverage happy Command.groupFields([]) -const session1 = app.createSession('user', 123) -const session2 = app.createSession('user', 456) -const session3 = app.createSession('user', 789) -const session4 = app.createSession('group', 123, 321) -const session5 = app.createSession('group', 123, 654) +const session1 = app.session(123) +const session2 = app.session(456) +const session3 = app.session(789) +const session4 = app.session(123, 321) +const session5 = app.session(123, 654) const cmd1 = app.command('cmd1 ', { authority: 2 }) .groupFields(['id']) @@ -55,48 +55,48 @@ describe('Runtime', () => { app.options.prefix = '!' app.prepare() - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveNoReply('cmd2') - await session1.shouldHaveReply('!cmd2', 'cmd2:123') - await session4.shouldHaveReply('!cmd2', 'cmd2:123') - await session1.shouldHaveNoReply('.cmd2') - await session4.shouldHaveNoReply('.cmd2') + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldNotReply('cmd2') + await session1.shouldReply('!cmd2', 'cmd2:123') + await session4.shouldReply('!cmd2', 'cmd2:123') + await session1.shouldNotReply('.cmd2') + await session4.shouldNotReply('.cmd2') }) it('multiple prefixes', async () => { app.options.prefix = ['!', '.'] app.prepare() - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveNoReply('cmd2') - await session1.shouldHaveReply('!cmd2', 'cmd2:123') - await session4.shouldHaveReply('!cmd2', 'cmd2:123') - await session1.shouldHaveReply('.cmd2', 'cmd2:123') - await session4.shouldHaveReply('.cmd2', 'cmd2:123') + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldNotReply('cmd2') + await session1.shouldReply('!cmd2', 'cmd2:123') + await session4.shouldReply('!cmd2', 'cmd2:123') + await session1.shouldReply('.cmd2', 'cmd2:123') + await session4.shouldReply('.cmd2', 'cmd2:123') }) it('optional prefix', async () => { app.options.prefix = ['.', ''] app.prepare() - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveReply('cmd2', 'cmd2:123') - await session1.shouldHaveNoReply('!cmd2') - await session4.shouldHaveNoReply('!cmd2') - await session1.shouldHaveReply('.cmd2', 'cmd2:123') - await session4.shouldHaveReply('.cmd2', 'cmd2:123') + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldReply('cmd2', 'cmd2:123') + await session1.shouldNotReply('!cmd2') + await session4.shouldNotReply('!cmd2') + await session1.shouldReply('.cmd2', 'cmd2:123') + await session4.shouldReply('.cmd2', 'cmd2:123') }) it('no prefix', async () => { app.options.prefix = null app.prepare() - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveReply('cmd2', 'cmd2:123') - await session1.shouldHaveNoReply('!cmd2') - await session4.shouldHaveNoReply('!cmd2') - await session1.shouldHaveNoReply('.cmd2') - await session4.shouldHaveNoReply('.cmd2') + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldReply('cmd2', 'cmd2:123') + await session1.shouldNotReply('!cmd2') + await session4.shouldNotReply('!cmd2') + await session1.shouldNotReply('.cmd2') + await session4.shouldNotReply('.cmd2') }) }) @@ -112,39 +112,39 @@ describe('Runtime', () => { }) it('no nickname', async () => { - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveNoReply('cmd2') - await session1.shouldHaveReply('-cmd2', 'cmd2:123') - await session4.shouldHaveReply('-cmd2', 'cmd2:123') - await session4.shouldHaveNoReply(`[CQ:reply,id=123][CQ:at,qq=${app.selfId}] cmd2`) + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldNotReply('cmd2') + await session1.shouldReply('-cmd2', 'cmd2:123') + await session4.shouldReply('-cmd2', 'cmd2:123') + await session4.shouldNotReply(`[CQ:reply,id=123][CQ:at,qq=${app.selfId}] cmd2`) }) it('single nickname', async () => { app.options.nickname = 'koishi' app.prepare() - await session1.shouldHaveReply('koishi, cmd2', 'cmd2:123') - await session4.shouldHaveReply('koishi, cmd2', 'cmd2:123') - await session1.shouldHaveReply('koishi\n cmd2', 'cmd2:123') - await session4.shouldHaveReply('koishi\n cmd2', 'cmd2:123') - await session1.shouldHaveReply('@koishi cmd2', 'cmd2:123') - await session4.shouldHaveReply('@koishi cmd2', 'cmd2:123') - await session1.shouldHaveNoReply('komeiji, cmd2') - await session4.shouldHaveNoReply('komeiji, cmd2') + await session1.shouldReply('koishi, cmd2', 'cmd2:123') + await session4.shouldReply('koishi, cmd2', 'cmd2:123') + await session1.shouldReply('koishi\n cmd2', 'cmd2:123') + await session4.shouldReply('koishi\n cmd2', 'cmd2:123') + await session1.shouldReply('@koishi cmd2', 'cmd2:123') + await session4.shouldReply('@koishi cmd2', 'cmd2:123') + await session1.shouldNotReply('komeiji, cmd2') + await session4.shouldNotReply('komeiji, cmd2') }) it('multiple nicknames', async () => { app.options.nickname = ['komeiji', 'koishi'] app.prepare() - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session4.shouldHaveNoReply('cmd2') - await session1.shouldHaveReply('-cmd2', 'cmd2:123') - await session4.shouldHaveReply('-cmd2', 'cmd2:123') - await session1.shouldHaveReply('koishi, cmd2', 'cmd2:123') - await session4.shouldHaveReply('koishi, cmd2', 'cmd2:123') - await session1.shouldHaveReply('komeiji cmd2', 'cmd2:123') - await session4.shouldHaveReply('komeiji cmd2', 'cmd2:123') + await session1.shouldReply('cmd2', 'cmd2:123') + await session4.shouldNotReply('cmd2') + await session1.shouldReply('-cmd2', 'cmd2:123') + await session4.shouldReply('-cmd2', 'cmd2:123') + await session1.shouldReply('koishi, cmd2', 'cmd2:123') + await session4.shouldReply('koishi, cmd2', 'cmd2:123') + await session1.shouldReply('komeiji cmd2', 'cmd2:123') + await session4.shouldReply('komeiji cmd2', 'cmd2:123') }) }) @@ -160,26 +160,26 @@ describe('Runtime', () => { }) it('single shortcut', async () => { - await session4.shouldHaveReply(' foo1 ', 'cmd1:bar') - await session4.shouldHaveReply(' foo2 ', 'cmd2:123') - await session4.shouldHaveNoReply('foo1 bar') - await session4.shouldHaveNoReply('foo2 -t bar') + await session4.shouldReply(' foo1 ', 'cmd1:bar') + await session4.shouldReply(' foo2 ', 'cmd2:123') + await session4.shouldNotReply('foo1 bar') + await session4.shouldNotReply('foo2 -t bar') }) it('no command prefix', async () => { - await session4.shouldHaveNoReply('#foo1') - await session4.shouldHaveNoReply('#foo2') + await session4.shouldNotReply('#foo1') + await session4.shouldNotReply('#foo2') }) it('nickname prefix & fuzzy', async () => { - await session4.shouldHaveNoReply('foo3 -t baz') - await session4.shouldHaveReply(`[CQ:at,qq=${app.selfId}] foo3 -t baz`, 'cmd2:123') + await session4.shouldNotReply('foo3 -t baz') + await session4.shouldReply(`[CQ:at,qq=${app.selfId}] foo3 -t baz`, 'cmd2:123') }) it('one argument & fuzzy', async () => { - await session4.shouldHaveReply('foo4 bar baz', 'cmd1:bar baz') - await session4.shouldHaveNoReply('foo4bar baz') - await session4.shouldHaveReply(`[CQ:at,qq=${app.selfId}] foo4bar baz`, 'cmd1:bar baz') + await session4.shouldReply('foo4 bar baz', 'cmd1:bar baz') + await session4.shouldNotReply('foo4bar baz') + await session4.shouldReply(`[CQ:at,qq=${app.selfId}] foo4bar baz`, 'cmd1:bar baz') }) }) @@ -189,23 +189,23 @@ describe('Runtime', () => { }) it('user.flag.ignore', async () => { - await session1.shouldHaveReply('cmd2', 'cmd2:123') - await session3.shouldHaveNoReply('cmd2') + await session1.shouldReply('cmd2', 'cmd2:123') + await session3.shouldNotReply('cmd2') }) it('group.assignee', async () => { - await session4.shouldHaveReply('cmd1 test --baz', 'cmd1:test') - await session4.shouldHaveReply('mid', 'mid') - await session5.shouldHaveNoReply('cmd1 test --baz') - await session5.shouldHaveReply(`[CQ:at,qq=${app.selfId}] cmd1 test --baz`, 'cmd1:test') + await session4.shouldReply('cmd1 test --baz', 'cmd1:test') + await session4.shouldReply('mid', 'mid') + await session5.shouldNotReply('cmd1 test --baz') + await session5.shouldReply(`[CQ:at,qq=${app.selfId}] cmd1 test --baz`, 'cmd1:test') }) it('group.flag.ignore', async () => { await app.database.setGroup(321, { flag: Group.Flag.ignore }) await sleep(0) - await session4.shouldHaveNoReply('mid') - await session4.shouldHaveNoReply('cmd1 --baz') - await session4.shouldHaveNoReply(`[CQ:at,qq=${app.selfId}] cmd1 --baz`) + await session4.shouldNotReply('mid') + await session4.shouldNotReply('cmd1 --baz') + await session4.shouldNotReply(`[CQ:at,qq=${app.selfId}] cmd1 --baz`) await app.database.setGroup(321, { flag: 0 }) }) }) @@ -213,54 +213,54 @@ describe('Runtime', () => { describe('Command Validation', () => { it('check authority', async () => { app.command('cmd1', { showWarning: true }) - await session2.shouldHaveReply('cmd1', '权限不足。') - await session1.shouldHaveReply('cmd1 --bar', '权限不足。') + await session2.shouldReply('cmd1', '权限不足。') + await session1.shouldReply('cmd1 --bar', '权限不足。') app.command('cmd1', { showWarning: false }) - await session1.shouldHaveNoReply('cmd1 --bar') + await session1.shouldNotReply('cmd1 --bar') }) it('check usage', async () => { cmd1.config.maxUsage = 1 cmd1.config.showWarning = true - await session4.shouldHaveReply('cmd1 test', 'cmd1:test') - await session4.shouldHaveReply('cmd1 test --baz', 'cmd1:test') - await session1.shouldHaveReply('cmd1 test', '调用次数已达上限。') - await session4.shouldHaveReply('cmd1 test --baz', 'cmd1:test') + await session4.shouldReply('cmd1 test', 'cmd1:test') + await session4.shouldReply('cmd1 test --baz', 'cmd1:test') + await session1.shouldReply('cmd1 test', '调用次数已达上限。') + await session4.shouldReply('cmd1 test --baz', 'cmd1:test') cmd1.config.showWarning = false - await session1.shouldHaveNoReply('cmd1') + await session1.shouldNotReply('cmd1') delete cmd1.config.maxUsage }) it('check frequency', async () => { cmd2.config.minInterval = () => 1000 cmd2.config.showWarning = true - await session2.shouldHaveReply('cmd2', 'cmd2:456') - await session2.shouldHaveReply('cmd2 --baz', 'cmd2:456') - await session2.shouldHaveReply('cmd2', '调用过于频繁,请稍后再试。') - await session2.shouldHaveReply('cmd2 --baz', 'cmd2:456') + await session2.shouldReply('cmd2', 'cmd2:456') + await session2.shouldReply('cmd2 --baz', 'cmd2:456') + await session2.shouldReply('cmd2', '调用过于频繁,请稍后再试。') + await session2.shouldReply('cmd2 --baz', 'cmd2:456') cmd2.config.showWarning = false - await session2.shouldHaveNoReply('cmd2') + await session2.shouldNotReply('cmd2') delete cmd2.config.minInterval }) it('check arg count', async () => { cmd1.config.checkArgCount = true cmd1.config.showWarning = true - await session4.shouldHaveReply('cmd1', '缺少参数,请检查指令语法。') - await session4.shouldHaveReply('cmd1 foo', 'cmd1:foo') - await session4.shouldHaveReply('cmd1 foo bar', '存在多余参数,请检查指令语法。') + await session4.shouldReply('cmd1', '缺少参数,请检查指令语法。') + await session4.shouldReply('cmd1 foo', 'cmd1:foo') + await session4.shouldReply('cmd1 foo bar', '存在多余参数,请检查指令语法。') cmd1.config.showWarning = false - await session4.shouldHaveNoReply('cmd1') + await session4.shouldNotReply('cmd1') cmd1.config.checkArgCount = false }) it('check unknown option', async () => { cmd2.config.checkUnknown = true cmd2.config.showWarning = true - await session2.shouldHaveReply('cmd2', 'cmd2:456') - await session2.shouldHaveReply('cmd2 --foo', '存在未知选项 foo,请检查指令语法。') + await session2.shouldReply('cmd2', 'cmd2:456') + await session2.shouldReply('cmd2 --foo', '存在未知选项 foo,请检查指令语法。') cmd2.config.showWarning = false - await session2.shouldHaveNoReply('cmd2 --foo') + await session2.shouldNotReply('cmd2 --foo') cmd2.config.checkUnknown = false }) @@ -269,21 +269,21 @@ describe('Runtime', () => { cmd3.option('foo', '', { validate: () => true }) cmd3.option('bar', '', { validate: () => 'SUFFIX' }) cmd3.option('baz', '', { validate: /$^/ }) - await session1.shouldHaveReply('cmd3', 'after cmd3') - await session1.shouldHaveReply('cmd3 --foo', '选项 foo 输入无效,请检查指令语法。') - await session1.shouldHaveReply('cmd3 --bar', '选项 bar 输入无效,SUFFIX') - await session1.shouldHaveReply('cmd3 --baz', '选项 baz 输入无效,请检查指令语法。') + await session1.shouldReply('cmd3', 'after cmd3') + await session1.shouldReply('cmd3 --foo', '选项 foo 输入无效,请检查指令语法。') + await session1.shouldReply('cmd3 --bar', '选项 bar 输入无效,SUFFIX') + await session1.shouldReply('cmd3 --baz', '选项 baz 输入无效,请检查指令语法。') cmd3.dispose() }) it('command.before', async () => { const cmd3 = app.command('cmd3').action(() => 'after cmd3') - await session1.shouldHaveReply('cmd3', 'after cmd3') + await session1.shouldReply('cmd3', 'after cmd3') let value: any = 'before cmd3' cmd3.before(() => value) - await session1.shouldHaveReply('cmd3', 'before cmd3') + await session1.shouldReply('cmd3', 'before cmd3') value = true - await session1.shouldHaveNoReply('cmd3') + await session1.shouldNotReply('cmd3') cmd3.dispose() }) }) diff --git a/packages/koishi-core/tests/session.spec.ts b/packages/koishi-core/tests/session.spec.ts index f14ef5d1bd..79c8cc9f33 100644 --- a/packages/koishi-core/tests/session.spec.ts +++ b/packages/koishi-core/tests/session.spec.ts @@ -4,8 +4,8 @@ import { sleep } from 'koishi-utils' describe('Session API', () => { describe('Command Suggestions', () => { const app = new App() - const session1 = app.createSession('user', 456) - const session2 = app.createSession('group', 789, 987) + const session1 = app.session(456) + const session2 = app.session(789, 987) app.command('foo ', { checkArgCount: true }) .action((_, bar) => 'foo' + bar) @@ -16,49 +16,49 @@ describe('Session API', () => { .action(({ options }) => 'fooo' + options.text) it('execute command', async () => { - await session1.shouldHaveReply('foo bar', 'foobar') - await session1.shouldHaveNoReply(' ') + await session1.shouldReply('foo bar', 'foobar') + await session1.shouldNotReply(' ') }) it('no suggestions', async () => { - await session1.shouldHaveNoReply('bar foo') + await session1.shouldNotReply('bar foo') }) it('apply suggestions 1', async () => { - await session1.shouldHaveReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') - await session2.shouldHaveReply('fooo -t bar', 'fooobar') - await session1.shouldHaveReply(' ', 'foobar') - await session1.shouldHaveNoReply(' ') + await session1.shouldReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') + await session2.shouldReply('fooo -t bar', 'fooobar') + await session1.shouldReply(' ', 'foobar') + await session1.shouldNotReply(' ') }) it('apply suggestions 2', async () => { - await session2.shouldHaveReply('foooo -t bar', '你要找的是不是“fooo”?发送空行或句号以调用推测的指令。') - await session1.shouldHaveReply('foo bar', 'foobar') - await session2.shouldHaveReply(' ', 'fooobar') - await session2.shouldHaveNoReply(' ') + await session2.shouldReply('foooo -t bar', '你要找的是不是“fooo”?发送空行或句号以调用推测的指令。') + await session1.shouldReply('foo bar', 'foobar') + await session2.shouldReply(' ', 'fooobar') + await session2.shouldNotReply(' ') }) it('ignore suggestions 1', async () => { - await session1.shouldHaveReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') - await session1.shouldHaveNoReply('bar foo') - await session1.shouldHaveNoReply(' ') + await session1.shouldReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') + await session1.shouldNotReply('bar foo') + await session1.shouldNotReply(' ') }) it('ignore suggestions 2', async () => { - await session2.shouldHaveReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') - await session2.shouldHaveReply('foo bar', 'foobar') - await session2.shouldHaveNoReply(' ') + await session2.shouldReply('fo bar', '你要找的是不是“foo”?发送空行或句号以调用推测的指令。') + await session2.shouldReply('foo bar', 'foobar') + await session2.shouldNotReply(' ') }) it('multiple suggestions', async () => { - await session1.shouldHaveReply('fool bar', '你要找的是不是“foo”或“fooo”或“bool”?') - await session1.shouldHaveNoReply(' ') + await session1.shouldReply('fool bar', '你要找的是不是“foo”或“fooo”或“bool”?') + await session1.shouldNotReply(' ') }) }) describe('Other Session Methods', () => { const app = new App({ prefix: '.' }) - const session = app.createSession('group', 123, 456) + const session = app.session(123, 456) const items = ['foo', 'bar'] const command = app.command('find [item]').action(({ session }, item) => { if (items.includes(item)) return 'found:' + item @@ -74,17 +74,17 @@ describe('Session API', () => { }) it('no suggestions', async () => { - await session.shouldHaveNoReply(' ') - await session.shouldHaveNoReply('find for') + await session.shouldNotReply(' ') + await session.shouldNotReply('find for') }) it('show suggestions', async () => { - await session.shouldHaveReply('.find 111', 'PREFIX') - await session.shouldHaveNoReply(' ') - await session.shouldHaveReply('.find for', `PREFIX你要找的是不是“foo”?SUFFIX`) - await session.shouldHaveReply(' ', 'found:foo') - await session.shouldHaveReply('.find bax', `PREFIX你要找的是不是“bar”或“baz”?`) - await session.shouldHaveNoReply(' ') + await session.shouldReply('.find 111', 'PREFIX') + await session.shouldNotReply(' ') + await session.shouldReply('.find for', `PREFIX你要找的是不是“foo”?SUFFIX`) + await session.shouldReply(' ', 'found:foo') + await session.shouldReply('.find bax', `PREFIX你要找的是不是“bar”或“baz”?`) + await session.shouldNotReply(' ') }) app.middleware(async (session, next) => { @@ -97,16 +97,16 @@ describe('Session API', () => { }) it('session.$prompt 1', async () => { - await session.shouldHaveReply('prompt', 'prompt text') - await session.shouldHaveReply('foo', 'received foo') - await session.shouldHaveNoReply('foo') + await session.shouldReply('prompt', 'prompt text') + await session.shouldReply('foo', 'received foo') + await session.shouldNotReply('foo') }) it('session.$prompt 2', async () => { app.options.promptTimeout = 0 - await session.shouldHaveReply('prompt', 'prompt text') + await session.shouldReply('prompt', 'prompt text') await sleep(0) - await session.shouldHaveReply('foo', 'received nothing') + await session.shouldReply('foo', 'received nothing') }) }) }) diff --git a/packages/koishi-test-utils/src/app.ts b/packages/koishi-test-utils/src/app.ts index ef399dde84..755bff90d9 100644 --- a/packages/koishi-test-utils/src/app.ts +++ b/packages/koishi-test-utils/src/app.ts @@ -1,5 +1,5 @@ import { AppOptions, App, Server, Session } from 'koishi-core' -import { expect, AssertionError } from 'chai' +import { assert } from 'chai' export const BASE_SELF_ID = 514 @@ -17,7 +17,7 @@ class MockedAppServer extends Server { Server.types.mock = MockedAppServer export class MockedApp extends App { - server: MockedAppServer + public server: MockedAppServer constructor(options: AppOptions = {}) { super({ selfId: BASE_SELF_ID, type: 'mock', ...options }) @@ -28,69 +28,88 @@ export class MockedApp extends App { } receive(meta: Partial) { - this.server.dispatch(new Session(this, { - selfId: this.bots[0].selfId, + const session = new Session(this, { + selfId: this.selfId, ...meta, - })) + }) + this.server.dispatch(session) + return session.$uuid } - createSession(type: 'user', userId: number): TestSession - createSession(type: 'group', userId: number, groupId: number): TestSession - createSession(type: 'user' | 'group', userId: number, ctxId: number = userId) { - return new TestSession(this, type, userId, ctxId) + session(userId: number, groupId?: number) { + return new TestSession(this, userId, groupId) } } -export const createMessageMeta = (app: App, type: 'user' | 'group', message: string, userId: number, ctxId: number) => new Session(app, { - [type + 'Id']: ctxId, - postType: 'message', - messageType: type === 'user' ? 'private' : type, - message, - userId, - sender: { - sex: 'unknown', - age: 0, - userId, - nickname: '' + userId, - }, -}) - export class TestSession { - meta: Session - replies: string[] = [] + public meta: Partial + + private replies: string[] = [] + + constructor(public app: MockedApp, public userId: number, public groupId?: number) { + this.meta = { + postType: 'message', + userId, + sender: { + sex: 'unknown', + age: 0, + userId, + nickname: '' + userId, + }, + } - constructor(public app: MockedApp, public type: 'user' | 'group', public userId: number, public ctxId: number) { - this.meta = createMessageMeta(app, type, null, userId, ctxId) + if (groupId) { + this.meta.groupId = groupId + this.meta.messageType = 'group' + } else { + this.meta.messageType = 'private' + } } - async send(message: string) { - const $send = async (message: string) => { - if (message) this.replies.push(message) - } + async receive(message: string, count?: number) { return new Promise((resolve) => { - this.app.once('after-middleware', () => { + let resolved = false + const _resolve = () => { + if (resolved) return + resolved = true + dispose() resolve(this.replies) this.replies = [] + } + const $send = async (message: string) => { + if (!message) return + const length = this.replies.push(message) + if (length >= count) _resolve() + } + const dispose = this.app.on('after-middleware', (session) => { + if (session.$uuid === uuid) _resolve() }) - this.app.receive({ ...this.meta, message, $send }) + const uuid = this.app.receive({ ...this.meta, $send, message }) }) } - shouldHaveReply(message: string, reply?: string) { - const assertion = expect(this.send(message).then(replies => replies[replies.length - 1])).eventually - if (reply) { - return assertion.equal(reply) - } else { - return assertion.ok + async shouldReply(message: string, reply?: string | RegExp | (string | RegExp)[]) { + if (!reply) { + const result = await this.receive(message) + return assert.ok(result.length, `expected "${message}" to be replied but not received nothing`) } - } - async shouldHaveNoReply(message: string) { - const replies = await this.send(message) - if (replies.length) { - throw new AssertionError(`expected "${message}" to have no reply but got "${this.replies[0]}"`) + if (!Array.isArray(reply)) reply = [reply] + const result = await this.receive(message, reply.length) + for (const index in reply) { + const expected = reply[index] + if (typeof expected === 'string') { + assert.strictEqual(result[index], expected) + } else { + assert.match(result[index], expected) + } } } + + async shouldNotReply(message: string) { + const result = await this.receive(message) + assert.ok(!result.length, `expected "${message}" to have no reply but received "${result[0]}"`) + } } export { MockedApp as App } diff --git a/packages/koishi-utils/package.json b/packages/koishi-utils/package.json index 06e3325ae0..1e4546dcd1 100644 --- a/packages/koishi-utils/package.json +++ b/packages/koishi-utils/package.json @@ -33,7 +33,6 @@ ], "devDependencies": { "@types/supports-color": "^5.3.0", - "mockdate": "^3.0.2", "koishi-test-utils": "^4.0.0" }, "dependencies": { diff --git a/packages/plugin-common/tests/admin.spec.ts b/packages/plugin-common/tests/admin.spec.ts index 1019a04553..57cc38d8c5 100644 --- a/packages/plugin-common/tests/admin.spec.ts +++ b/packages/plugin-common/tests/admin.spec.ts @@ -5,7 +5,7 @@ import { expect } from 'chai' import * as admin from '../src/admin' const app = new MockedApp() -const session = app.createSession('group', 123, 321) +const session = app.session(123, 321) app.plugin(memory) app.plugin(admin) @@ -23,7 +23,7 @@ before(async () => { describe('basic features', () => { it('check', async () => { - await session.shouldHaveReply('admin -u 456 -g 321', '不能同时目标为指定用户和群。') + await session.shouldReply('admin -u 456 -g 321', '不能同时目标为指定用户和群。') }) }) @@ -34,40 +34,40 @@ describe('user operations', () => { }) it('check target', async () => { - await session.shouldHaveReply('admin -u bar set-flag', '未指定目标。') - await session.shouldHaveReply('admin -u 233 set-flag', '未找到指定的用户。') - await session.shouldHaveReply('admin -u 789 show-usage', '权限不足。') + await session.shouldReply('admin -u bar set-flag', '未指定目标。') + await session.shouldReply('admin -u 233 set-flag', '未找到指定的用户。') + await session.shouldReply('admin -u 789 show-usage', '权限不足。') }) it('setAuth', async () => { - await session.shouldHaveReply('admin -u 456 set-auth -1', '参数错误。') - await session.shouldHaveReply('admin -u 456 set-auth 3', '用户权限未改动。') - await session.shouldHaveReply('admin -u 456 set-auth 2', '用户权限已修改。') - await session.shouldHaveReply('admin -u 456 set-auth 4', '权限不足。') + await session.shouldReply('admin -u 456 set-auth -1', '参数错误。') + await session.shouldReply('admin -u 456 set-auth 3', '用户权限未改动。') + await session.shouldReply('admin -u 456 set-auth 2', '用户权限已修改。') + await session.shouldReply('admin -u 456 set-auth 4', '权限不足。') }) const userFlags = enumKeys(User.Flag).join(', ') it('setFlag', async () => { - await session.shouldHaveReply('admin -u 456 set-flag', `可用的标记有 ${userFlags}。`) - await session.shouldHaveReply('admin -u 456 set-flag foo', '未找到标记 foo。') - await session.shouldHaveReply('admin -u 456 set-flag ignore', '用户信息已修改。') + await session.shouldReply('admin -u 456 set-flag', `可用的标记有 ${userFlags}。`) + await session.shouldReply('admin -u 456 set-flag foo', '未找到标记 foo。') + await session.shouldReply('admin -u 456 set-flag ignore', '用户信息已修改。') await expect(app.database.getUser(456)).eventually.to.have.property('flag', User.Flag.ignore) }) it('unsetFlag', async () => { - await session.shouldHaveReply('admin -u 456 unset-flag', `可用的标记有 ${userFlags}。`) - await session.shouldHaveReply('admin -u 456 unset-flag foo', '未找到标记 foo。') - await session.shouldHaveReply('admin -u 456 unset-flag ignore', '用户信息已修改。') + await session.shouldReply('admin -u 456 unset-flag', `可用的标记有 ${userFlags}。`) + await session.shouldReply('admin -u 456 unset-flag foo', '未找到标记 foo。') + await session.shouldReply('admin -u 456 unset-flag ignore', '用户信息已修改。') await expect(app.database.getUser(456)).eventually.to.have.property('flag', 0) }) it('clearUsage', async () => { - await session.shouldHaveReply('bar', 'foo') - await session.shouldHaveReply('admin clear-usage foo', '用户信息已修改。') - await session.shouldHaveReply('admin show-usage', '用户今日各指令的调用次数为:\nbar:1 次') - await session.shouldHaveReply('admin clear-usage', '用户信息已修改。') - await session.shouldHaveReply('admin show-usage', '用户今日没有调用过指令。') + await session.shouldReply('bar', 'foo') + await session.shouldReply('admin clear-usage foo', '用户信息已修改。') + await session.shouldReply('admin show-usage', '用户今日各指令的调用次数为:\nbar:1 次') + await session.shouldReply('admin clear-usage', '用户信息已修改。') + await session.shouldReply('admin show-usage', '用户今日没有调用过指令。') }) }) @@ -78,22 +78,22 @@ describe('group operations', () => { }) it('check target', async () => { - await session.shouldHaveReply('admin -g bar set-flag', '未找到指定的群。') + await session.shouldReply('admin -g bar set-flag', '未找到指定的群。') }) const groupFlags = enumKeys(Group.Flag).join(', ') it('setFlag', async () => { - await session.shouldHaveReply('admin -G set-flag', `可用的标记有 ${groupFlags}。`) - await session.shouldHaveReply('admin -g 654 set-flag foo', '未找到标记 foo。') - await session.shouldHaveReply('admin -g 654 set-flag silent', '群信息已修改。') + await session.shouldReply('admin -G set-flag', `可用的标记有 ${groupFlags}。`) + await session.shouldReply('admin -g 654 set-flag foo', '未找到标记 foo。') + await session.shouldReply('admin -g 654 set-flag silent', '群信息已修改。') await expect(app.database.getGroup(654)).eventually.to.have.property('flag', Group.Flag.silent) }) it('unsetFlag', async () => { - await session.shouldHaveReply('admin -G unset-flag', `可用的标记有 ${groupFlags}。`) - await session.shouldHaveReply('admin -g 654 unset-flag foo', '未找到标记 foo。') - await session.shouldHaveReply('admin -g 654 unset-flag silent ignore', '群信息已修改。') + await session.shouldReply('admin -G unset-flag', `可用的标记有 ${groupFlags}。`) + await session.shouldReply('admin -g 654 unset-flag foo', '未找到标记 foo。') + await session.shouldReply('admin -g 654 unset-flag silent ignore', '群信息已修改。') await expect(app.database.getGroup(654)).eventually.to.have.property('flag', 0) }) }) @@ -101,11 +101,11 @@ describe('group operations', () => { describe('custom actions', () => { it('user action', async () => { admin.UserAction.add('test', session => session.$send('foo')) - await session.shouldHaveReply('admin test', 'foo') + await session.shouldReply('admin test', 'foo') }) it('group action', async () => { admin.GroupAction.add('test', session => session.$send('bar')) - await session.shouldHaveReply('admin -G test', 'bar') + await session.shouldReply('admin -G test', 'bar') }) }) diff --git a/packages/plugin-common/tests/contextify.spec.ts b/packages/plugin-common/tests/contextify.spec.ts index a301204b5c..fe354b14c3 100644 --- a/packages/plugin-common/tests/contextify.spec.ts +++ b/packages/plugin-common/tests/contextify.spec.ts @@ -3,8 +3,8 @@ import { contextify } from '../src' import 'koishi-database-memory' const app = new MockedApp({ database: { memory: {} } }) -const session1 = app.createSession('user', 123) -const session2 = app.createSession('group', 123, 654) +const session1 = app.session(123) +const session2 = app.session(123, 654) app.plugin(contextify) app.command('show-context') @@ -21,22 +21,22 @@ beforeAll(async () => { }) test('check input', async () => { - await session1.shouldHaveReply('ctxf -u 456', '请输入要触发的指令。') - await session2.shouldHaveReply('ctxf -m foo show-context', '未指定目标。') - await session1.shouldHaveReply('ctxf show-context', '请提供新的上下文。') - await session1.shouldHaveReply('ctxf -u 789 show-context', '权限不足。') - await session1.shouldHaveReply('ctxf -m 456 show-context', '无法在私聊上下文使用 --member 选项。') + await session1.shouldReply('ctxf -u 456', '请输入要触发的指令。') + await session2.shouldReply('ctxf -m foo show-context', '未指定目标。') + await session1.shouldReply('ctxf show-context', '请提供新的上下文。') + await session1.shouldReply('ctxf -u 789 show-context', '权限不足。') + await session1.shouldReply('ctxf -m 456 show-context', '无法在私聊上下文使用 --member 选项。') }) test('user context', async () => { - await session1.shouldHaveReply('ctxf -u 456 show-context', '456,user,456,456,undefined') - await session1.shouldHaveReply('ctxf -g 654 show-context', '123,group,654,123,654') - await session1.shouldHaveReply('ctxf -d 654 show-context', '123,discuss,654,123,undefined') - await session1.shouldHaveReply('ctxf -u 456 -g 654 show-context', '456,group,654,456,654') - await session1.shouldHaveReply('ctxf -u 456 -d 654 show-context', '456,discuss,654,456,undefined') + await session1.shouldReply('ctxf -u 456 show-context', '456,user,456,456,undefined') + await session1.shouldReply('ctxf -g 654 show-context', '123,group,654,123,654') + await session1.shouldReply('ctxf -d 654 show-context', '123,discuss,654,123,undefined') + await session1.shouldReply('ctxf -u 456 -g 654 show-context', '456,group,654,456,654') + await session1.shouldReply('ctxf -u 456 -d 654 show-context', '456,discuss,654,456,undefined') }) test('group context', async () => { - await session2.shouldHaveReply('ctxf -u 456 show-context', '456,user,456,456,undefined') - await session2.shouldHaveReply('ctxf -m 456 show-context', '456,group,654,456,654') + await session2.shouldReply('ctxf -u 456 show-context', '456,user,456,456,undefined') + await session2.shouldReply('ctxf -m 456 show-context', '456,group,654,456,654') }) diff --git a/packages/plugin-common/tests/info.spec.ts b/packages/plugin-common/tests/info.spec.ts index a4924e0901..a9bae32fbc 100644 --- a/packages/plugin-common/tests/info.spec.ts +++ b/packages/plugin-common/tests/info.spec.ts @@ -11,7 +11,7 @@ describe('info', () => { beforeEach(async () => { app = new MockedApp() app.plugin(memory) - session = app.createSession('user', 123) + session = app.session(123) await app.start() await app.database.getUser(123, 3) await app.database.getUser(456, 4) @@ -32,10 +32,10 @@ describe('info', () => { age: 20, } - await session.shouldHaveReply('info', 'nick,您的权限为 3 级。\nfoo') - await session.shouldHaveReply('info -u', '未找到用户。') - await session.shouldHaveReply('info -u 654', '未找到用户。') - await session.shouldHaveReply('info -u 456', '456 的权限为 4 级。\nfoo') - await session.shouldHaveReply('info -u 789', 'bar (789) 的权限为 2 级。\nfoo') + await session.shouldReply('info', 'nick,您的权限为 3 级。\nfoo') + await session.shouldReply('info -u', '未找到用户。') + await session.shouldReply('info -u 654', '未找到用户。') + await session.shouldReply('info -u 456', '456 的权限为 4 级。\nfoo') + await session.shouldReply('info -u 789', 'bar (789) 的权限为 2 级。\nfoo') }) }) diff --git a/packages/plugin-common/tests/repeater.spec.ts b/packages/plugin-common/tests/repeater.spec.ts index c499882341..fc8b2545d8 100644 --- a/packages/plugin-common/tests/repeater.spec.ts +++ b/packages/plugin-common/tests/repeater.spec.ts @@ -3,21 +3,21 @@ import repeater from '../src/repeater' it.only('repeat', async () => { const app = new App() - const session1 = app.createSession('group', 123, 123) + const session1 = app.session(123, 123) app.plugin(repeater, { onRepeat: ({ repeated, times }, message) => !repeated && times >= 2 ? message : '', }) - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveReply('foo', 'foo') - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveNoReply('foo') + await session1.shouldNotReply('foo') + await session1.shouldReply('foo', 'foo') + await session1.shouldNotReply('foo') + await session1.shouldNotReply('foo') }) it('interrupt', async () => { const app = new App() - const session1 = app.createSession('group', 123, 123) + const session1 = app.session(123, 123) app.plugin(repeater, { repeat: (_, times) => times >= 2, @@ -26,15 +26,15 @@ it('interrupt', async () => { interruptCheck: false, }) - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveReply('foo', 'foo') - await session1.shouldHaveReply('foo', '打断复读!') + await session1.shouldNotReply('foo') + await session1.shouldReply('foo', 'foo') + await session1.shouldReply('foo', '打断复读!') }) it('repeat check', async () => { const app = new App() - const session1 = app.createSession('group', 123, 123) - const session2 = app.createSession('group', 456, 123) + const session1 = app.session(123, 123) + const session2 = app.session(456, 123) app.plugin(repeater, { repeat: (_, times) => times >= 2, @@ -43,15 +43,15 @@ it('repeat check', async () => { interruptCheck: false, }) - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveReply('foo', 'foo') - await session2.shouldHaveReply('foo', 'foo') - await session2.shouldHaveReply('foo', `[CQ:at,qq=${session2.userId}] 在?为什么重复复读?`) + await session1.shouldNotReply('foo') + await session1.shouldReply('foo', 'foo') + await session2.shouldReply('foo', 'foo') + await session2.shouldReply('foo', `[CQ:at,qq=${session2.userId}] 在?为什么重复复读?`) }) it('interrupt check', async () => { const app = new App() - const session1 = app.createSession('group', 123, 123) + const session1 = app.session(123, 123) app.plugin(repeater, { repeat: (_, times) => times >= 2, @@ -60,8 +60,8 @@ it('interrupt check', async () => { interruptCheck: (_, times) => times >= 2, }) - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveNoReply('bar') - await session1.shouldHaveReply('bar', 'bar') - await session1.shouldHaveReply('foo', `[CQ:at,qq=${session1.userId}] 在?为什么打断复读?`) + await session1.shouldNotReply('foo') + await session1.shouldNotReply('bar') + await session1.shouldReply('bar', 'bar') + await session1.shouldReply('foo', `[CQ:at,qq=${session1.userId}] 在?为什么打断复读?`) }) diff --git a/packages/plugin-common/tests/respondent.spec.ts b/packages/plugin-common/tests/respondent.spec.ts index 1c6da3f4f5..0696e8f908 100644 --- a/packages/plugin-common/tests/respondent.spec.ts +++ b/packages/plugin-common/tests/respondent.spec.ts @@ -2,7 +2,7 @@ import { MockedApp } from 'koishi-test-utils' import { respondent } from '../src' const app = new MockedApp() -const session = app.createSession('user', 123) +const session = app.session(123) // make coverage happy app.plugin(respondent) @@ -15,7 +15,7 @@ app.plugin(respondent, [{ }]) it('basic support', async () => { - await session.shouldHaveReply('挖坑一时爽', '填坑火葬场') - await session.shouldHaveReply('填坑一时爽', '一直填坑一直爽') - await session.shouldHaveNoReply('填坑一直爽') + await session.shouldReply('挖坑一时爽', '填坑火葬场') + await session.shouldReply('填坑一时爽', '一直填坑一直爽') + await session.shouldNotReply('填坑一直爽') }) diff --git a/packages/plugin-eval/tests/index.spec.ts b/packages/plugin-eval/tests/index.spec.ts index 6ae036ca1c..10c2efc815 100644 --- a/packages/plugin-eval/tests/index.spec.ts +++ b/packages/plugin-eval/tests/index.spec.ts @@ -16,7 +16,7 @@ app.plugin(pluginEval, { }, }) -const ses = app.createSession('user', 123) +const ses = app.session(123) before(() => app.start()) @@ -24,45 +24,45 @@ after(() => app.stop()) describe('Plugin Eval', () => { it('basic support', async () => { - await ses.shouldHaveReply('> 1+1', '2') - await ses.shouldHaveNoReply('>> 1+1') - await ses.shouldHaveReply('> send(1+1)', '2') - await ses.shouldHaveReply('>> send(1+1)', '2') + await ses.shouldReply('> 1+1', '2') + await ses.shouldNotReply('>> 1+1') + await ses.shouldReply('> send(1+1)', '2') + await ses.shouldReply('>> send(1+1)', '2') }) it('validation', async () => { - await ses.shouldHaveReply('>', '请输入要执行的脚本。') + await ses.shouldReply('>', '请输入要执行的脚本。') }) it('error', async () => { - await ses.shouldHaveReply('> throw 1', 'Uncaught: 1') - await ses.shouldHaveReply('> foo', 'ReferenceError: foo is not defined\n at stdin:1:1') - await ses.shouldHaveReply('> 1f', 'SyntaxError: Invalid or unexpected token\n at stdin:1:1') + await ses.shouldReply('> throw 1', 'Uncaught: 1') + await ses.shouldReply('> foo', 'ReferenceError: foo is not defined\n at stdin:1:1') + await ses.shouldReply('> 1f', 'SyntaxError: Invalid or unexpected token\n at stdin:1:1') }) it('exec', async () => { - await ses.shouldHaveReply('> exec()').which.matches(/^TypeError: The "message" argument must be of type string/) - await ses.shouldHaveReply('> exec("help")').which.matches(/^当前可用的指令有:/) + await ses.shouldReply('> exec()', /^TypeError: The "message" argument must be of type string/) + await ses.shouldReply('> exec("help")', /^当前可用的指令有:/) }) it('global', async () => { - await ses.shouldHaveNoReply('> global.console') - await ses.shouldHaveNoReply('> global.setTimeout') - await ses.shouldHaveNoReply('> global.setInterval') - await ses.shouldHaveReply('> exec', '[AsyncFunction: exec]') - await ses.shouldHaveReply('> exec.toString()', 'function exec() { [native code] }') + await ses.shouldNotReply('> global.console') + await ses.shouldNotReply('> global.setTimeout') + await ses.shouldNotReply('> global.setInterval') + await ses.shouldReply('> exec', '[AsyncFunction: exec]') + await ses.shouldReply('> exec.toString()', 'function exec() { [native code] }') }) it('attack 1', async () => { - await ses.shouldHaveReply(`> + await ses.shouldReply(`> const func1 = this.constructor.constructor("return Function('return Function')")()(); const func2 = this.constructor.constructor("return Function")(); func1 === func2; `, 'true') - await ses.shouldHaveReply(`> + await ses.shouldReply(`> const ForeignFunction = global.constructor.constructor; const process1 = ForeignFunction("return process")(); - `).which.matches(/^ReferenceError: process is not defined/) + `, /^ReferenceError: process is not defined/) }) }) diff --git a/packages/plugin-teach/tests/basic.spec.ts b/packages/plugin-teach/tests/basic.spec.ts index f8552fd936..0b8dedef1d 100644 --- a/packages/plugin-teach/tests/basic.spec.ts +++ b/packages/plugin-teach/tests/basic.spec.ts @@ -10,8 +10,8 @@ import axios from 'axios' describe('Plugin Teach', () => { describe('Basic Support', () => { const app = new App({ prefix: '.' }) - const session1 = app.createSession('group', 123, 456) - const session2 = app.createSession('group', 321, 456) + const session1 = app.session(123, 456) + const session2 = app.session(321, 456) app.plugin(teach, { historyAge: 0, @@ -28,55 +28,55 @@ describe('Plugin Teach', () => { }) it('create', async () => { - await session1.shouldHaveNoReply('foo') - await session1.shouldHaveReply('# foo', '缺少问题或回答,请检查指令语法。') - await session1.shouldHaveReply('# foo bar', '问答已添加,编号为 1。') - await session1.shouldHaveReply('# foo bar baz', '存在多余的参数,请检查指令语法或将含有空格或换行的问答置于一对引号内。') - await session1.shouldHaveReply('foo', 'bar') + await session1.shouldNotReply('foo') + await session1.shouldReply('# foo', '缺少问题或回答,请检查指令语法。') + await session1.shouldReply('# foo bar', '问答已添加,编号为 1。') + await session1.shouldReply('# foo bar baz', '存在多余的参数,请检查指令语法或将含有空格或换行的问答置于一对引号内。') + await session1.shouldReply('foo', 'bar') }) it('validate', async () => { - await session1.shouldHaveReply('# [CQ:image] bar', '问题必须是纯文本。') - await session1.shouldHaveReply('# foo[foo bar -x', '问题含有错误的或不支持的正则表达式语法。') + await session1.shouldReply('# [CQ:image] bar', '问题必须是纯文本。') + await session1.shouldReply('# foo[foo bar -x', '问题含有错误的或不支持的正则表达式语法。') }) it('modify', async () => { - await session1.shouldHaveReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。') - await session1.shouldHaveReply('# foo bar -P 1', '修改了已存在的问答,编号为 1。') - await session1.shouldHaveReply('#1 -P 1', '问答 1 没有发生改动。') - await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') - await session1.shouldHaveReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') - await session1.shouldHaveReply('.', '问答 1 已成功修改。') - await session1.shouldHaveReply('foo', 'baz') + await session1.shouldReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。') + await session1.shouldReply('# foo bar -P 1', '修改了已存在的问答,编号为 1。') + await session1.shouldReply('#1 -P 1', '问答 1 没有发生改动。') + await session1.shouldReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') + await session1.shouldReply('#1 baz', '推测你想修改的是回答而不是问题。发送空行或句号以修改回答,使用 -i 选项以忽略本提示。') + await session1.shouldReply('.', '问答 1 已成功修改。') + await session1.shouldReply('foo', 'baz') }) it('search 1', async () => { - await session1.shouldHaveReply('## foo', '问题“foo”的回答如下:\n1. [P=1] baz') - await session1.shouldHaveReply('## baz', '没有搜索到问题“baz”,请尝试使用正则表达式匹配。') - await session1.shouldHaveReply('## baz -x', '没有搜索到含有正则表达式“baz”的问题。') - await session1.shouldHaveReply('## ~ baz', '回答“baz”的问题如下:\n1. [P=1] foo') - await session1.shouldHaveReply('## ~ foo', '没有搜索到回答“foo”,请尝试使用正则表达式匹配。') - await session1.shouldHaveReply('## ~ foo -x', '没有搜索到含有正则表达式“foo”的回答。') - await session1.shouldHaveReply('## foo baz', '“foo”“baz”匹配的回答如下:\n1') - await session1.shouldHaveReply('## foo bar', '没有搜索到问答“foo”“bar”,请尝试使用正则表达式匹配。') - await session1.shouldHaveReply('## foo bar -x', '没有搜索到含有正则表达式“foo”“bar”的问答。') + await session1.shouldReply('## foo', '问题“foo”的回答如下:\n1. [P=1] baz') + await session1.shouldReply('## baz', '没有搜索到问题“baz”,请尝试使用正则表达式匹配。') + await session1.shouldReply('## baz -x', '没有搜索到含有正则表达式“baz”的问题。') + await session1.shouldReply('## ~ baz', '回答“baz”的问题如下:\n1. [P=1] foo') + await session1.shouldReply('## ~ foo', '没有搜索到回答“foo”,请尝试使用正则表达式匹配。') + await session1.shouldReply('## ~ foo -x', '没有搜索到含有正则表达式“foo”的回答。') + await session1.shouldReply('## foo baz', '“foo”“baz”匹配的回答如下:\n1') + await session1.shouldReply('## foo bar', '没有搜索到问答“foo”“bar”,请尝试使用正则表达式匹配。') + await session1.shouldReply('## foo bar -x', '没有搜索到含有正则表达式“foo”“bar”的问答。') }) it('search 2', async () => { - await session1.shouldHaveReply('# foo bar', '问答已添加,编号为 2。') - await session1.shouldHaveReply('# goo bar', '问答已添加,编号为 3。') - await session1.shouldHaveReply('##', '共收录了 2 个问题和 3 个回答。') - await session1.shouldHaveReply('## fo -x', '问题正则表达式“fo”的搜索结果如下:\n1. [P=1] 问题:foo,回答:baz\n2. 问题:foo,回答:bar') - await session1.shouldHaveReply('## ~ ar -x', '回答正则表达式“ar”的搜索结果如下:\n2. 问题:foo,回答:bar\n3. 问题:goo,回答:bar') - await session1.shouldHaveReply('## fo ar -x', '问答正则表达式“fo”“ar”的搜索结果如下:\n2. 问题:foo,回答:bar') - await session1.shouldHaveReply('### oo', '问题正则表达式“oo”的搜索结果如下:\nfoo (共 2 个回答)\ngoo (#3)') - await session1.shouldHaveReply('### ~ ba', '回答正则表达式“ba”的搜索结果如下:\nbaz (#1)\nbar (共 2 个问题)') + await session1.shouldReply('# foo bar', '问答已添加,编号为 2。') + await session1.shouldReply('# goo bar', '问答已添加,编号为 3。') + await session1.shouldReply('##', '共收录了 2 个问题和 3 个回答。') + await session1.shouldReply('## fo -x', '问题正则表达式“fo”的搜索结果如下:\n1. [P=1] 问题:foo,回答:baz\n2. 问题:foo,回答:bar') + await session1.shouldReply('## ~ ar -x', '回答正则表达式“ar”的搜索结果如下:\n2. 问题:foo,回答:bar\n3. 问题:goo,回答:bar') + await session1.shouldReply('## fo ar -x', '问答正则表达式“fo”“ar”的搜索结果如下:\n2. 问题:foo,回答:bar') + await session1.shouldReply('### oo', '问题正则表达式“oo”的搜索结果如下:\nfoo (共 2 个回答)\ngoo (#3)') + await session1.shouldReply('### ~ ba', '回答正则表达式“ba”的搜索结果如下:\nbaz (#1)\nbar (共 2 个问题)') }) it('miscellaneous', async () => { - await session1.shouldHaveNoReply('.foo') - await session1.shouldHaveReply('#') - await session2.shouldHaveReply('#') + await session1.shouldNotReply('.foo') + await session1.shouldReply('#') + await session2.shouldReply('#') }) }) @@ -84,15 +84,15 @@ describe('Plugin Teach', () => { const app = new App({ userCacheAge: Number.EPSILON, nickname: ['koishi', 'satori'] }) const u2id = 200, u3id = 300, u4id = 400 const g1id = 100, g2id = 200 - const u2 = app.createSession('user', u2id) - const u3 = app.createSession('user', u3id) - const u4 = app.createSession('user', u4id) - const u2g1 = app.createSession('group', u2id, g1id) - const u2g2 = app.createSession('group', u2id, g2id) - const u3g1 = app.createSession('group', u3id, g1id) - const u3g2 = app.createSession('group', u3id, g2id) - const u4g1 = app.createSession('group', u4id, g1id) - const u4g2 = app.createSession('group', u4id, g2id) + const u2 = app.session(u2id) + const u3 = app.session(u3id) + const u4 = app.session(u4id) + const u2g1 = app.session(u2id, g1id) + const u2g2 = app.session(u2id, g2id) + const u3g1 = app.session(u3id, g1id) + const u3g2 = app.session(u3id, g2id) + const u4g1 = app.session(u4id, g1id) + const u4g2 = app.session(u4id, g2id) app.plugin(teach, { historyAge: 0, @@ -139,33 +139,33 @@ describe('Plugin Teach', () => { }) it('appellative', async () => { - await u3g1.shouldHaveReply('# koishi,foo bar', '问答已添加,编号为 1。') - await u3g1.shouldHaveNoReply('foo') - await u3g1.shouldHaveReply('koishi, foo', 'bar') - await u3g1.shouldHaveReply('satori, foo', 'bar') + await u3g1.shouldReply('# koishi,foo bar', '问答已添加,编号为 1。') + await u3g1.shouldNotReply('foo') + await u3g1.shouldReply('koishi, foo', 'bar') + await u3g1.shouldReply('satori, foo', 'bar') // TODO support at-trigger - // await u3g1.shouldHaveReply(`[CQ:at,qq=${app.selfId}] foo`, 'bar') - await u3g1.shouldHaveReply('#1', '编号为 1 的问答信息:\n问题:koishi,foo\n回答:bar\n触发权重:p=0, P=1') - await u3g1.shouldHaveReply('## foo', SEARCH_HEAD + '1. [p=0, P=1] bar') + // await u3g1.shouldReply(`[CQ:at,qq=${app.selfId}] foo`, 'bar') + await u3g1.shouldReply('#1', '编号为 1 的问答信息:\n问题:koishi,foo\n回答:bar\n触发权重:p=0, P=1') + await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [p=0, P=1] bar') }) it('activated', async () => { - await u3g1.shouldHaveReply('# koishi ?', '问答已添加,编号为 2。') - await u3g1.shouldHaveReply('koishi', '?') - await u3g1.shouldHaveReply('foo', 'bar') + await u3g1.shouldReply('# koishi ?', '问答已添加,编号为 2。') + await u3g1.shouldReply('koishi', '?') + await u3g1.shouldReply('foo', 'bar') // due to mocked Random.real - await u3g1.shouldHaveReply('# satori ! -p 0.5', '问答已添加,编号为 3。') - await u3g1.shouldHaveNoReply('satori') + await u3g1.shouldReply('# satori ! -p 0.5', '问答已添加,编号为 3。') + await u3g1.shouldNotReply('satori') }) it('regular expression', async () => { clock.runAll() - await u3g1.shouldHaveReply('# foo baz -xP 0.5', '问答已添加,编号为 4。') - await u3g1.shouldHaveNoReply('foo') - await u3g1.shouldHaveReply('koishi, fooo', 'baz') - await u3g1.shouldHaveReply('#4 -p 0.5 -P 1', '问答 4 已成功修改。') - await u3g1.shouldHaveReply('koishi, fooo', 'baz') + await u3g1.shouldReply('# foo baz -xP 0.5', '问答已添加,编号为 4。') + await u3g1.shouldNotReply('foo') + await u3g1.shouldReply('koishi, fooo', 'baz') + await u3g1.shouldReply('#4 -p 0.5 -P 1', '问答 4 已成功修改。') + await u3g1.shouldReply('koishi, fooo', 'baz') }) }) @@ -173,66 +173,66 @@ describe('Plugin Teach', () => { const { u3, u3g1, u3g2 } = createEnvironment({ useContext: true }) it('validate options 1', async () => { - await u3.shouldHaveReply('# foo bar', '非群聊上下文中请使用 -E/-D 进行操作或指定 -g, --groups 选项。') - await u3.shouldHaveReply('# foo bar -g 100', '选项 -g, --groups 必须与 -d/-D/-e/-E 之一同时使用。') - await u3.shouldHaveReply('# foo bar -eg 100', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:本群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [e] bar') + await u3.shouldReply('# foo bar', '非群聊上下文中请使用 -E/-D 进行操作或指定 -g, --groups 选项。') + await u3.shouldReply('# foo bar -g 100', '选项 -g, --groups 必须与 -d/-D/-e/-E 之一同时使用。') + await u3.shouldReply('# foo bar -eg 100', '问答已添加,编号为 1。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:本群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [e] bar') }) it('validate options 2', async () => { - await u3g1.shouldHaveReply('#1 -de', '选项 -d, -e 不能同时使用。') - await u3g1.shouldHaveReply('#1 -DE', '选项 -D, -E 不能同时使用。') - await u3g1.shouldHaveReply('#1 -Dd', '选项 -D, -d 不能同时使用。') - await u3g1.shouldHaveReply('#1 -Ee', '选项 -E, -e 不能同时使用。') + await u3g1.shouldReply('#1 -de', '选项 -d, -e 不能同时使用。') + await u3g1.shouldReply('#1 -DE', '选项 -D, -E 不能同时使用。') + await u3g1.shouldReply('#1 -Dd', '选项 -D, -d 不能同时使用。') + await u3g1.shouldReply('#1 -Ee', '选项 -E, -e 不能同时使用。') }) it('limited group enabled (with current group)', async () => { - await u3g2.shouldHaveReply('# foo bar', '修改了已存在的问答,编号为 1。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:本群等 2 个群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [e] bar') + await u3g2.shouldReply('# foo bar', '修改了已存在的问答,编号为 1。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:本群等 2 个群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [e] bar') }) it('limited group enabled (without current group)', async () => { - await u3g1.shouldHaveReply('#1 -d', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:1 个群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [D] bar') + await u3g1.shouldReply('#1 -d', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:1 个群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [D] bar') }) it('limited group enabled (with no groups)', async () => { - await u3g1.shouldHaveReply('#1 -D', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:全局禁止') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [D] bar') + await u3g1.shouldReply('#1 -D', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:全局禁止') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [D] bar') }) it('unlimited group enabled (with all groups)', async () => { - await u3g1.shouldHaveReply('#1 -E', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:全局') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [E] bar') + await u3g1.shouldReply('#1 -E', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:全局') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [E] bar') }) it('unlimited group enabled (with current group)', async () => { - await u3g1.shouldHaveReply('#1 -dg 200', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:除 1 个群外的所有群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [E] bar') + await u3g1.shouldReply('#1 -dg 200', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:除 1 个群外的所有群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [E] bar') }) it('unlimited group enabled (without current group)', async () => { - await u3g1.shouldHaveReply('#1 -d', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:除本群等 2 个群外的所有群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [d] bar') + await u3g1.shouldReply('#1 -d', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:除本群等 2 个群外的所有群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [d] bar') }) it('limited group enabled (with current group only)', async () => { - await u3g1.shouldHaveReply('#1 -De', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:本群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [e] bar') + await u3g1.shouldReply('#1 -De', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:本群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [e] bar') }) it('unlimited group enabled (without current group only)', async () => { - await u3g1.shouldHaveReply('#1 -Ed', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '生效环境:除本群') - await u3g1.shouldHaveReply('## foo -G', SEARCH_HEAD + '1. [d] bar') + await u3g1.shouldReply('#1 -Ed', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '生效环境:除本群') + await u3g1.shouldReply('## foo -G', SEARCH_HEAD + '1. [d] bar') }) }) @@ -244,55 +244,55 @@ describe('Plugin Teach', () => { it('create writer', async () => { // 当自身未设置 name 时使用 session.sender u3g1.meta.sender.nickname = 'nick3' - await u3g1.shouldHaveReply('# foo bar', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '来源:nick3 (300)') + await u3g1.shouldReply('# foo bar', '问答已添加,编号为 1。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '来源:nick3 (300)') // 重复添加问答时不应该覆盖旧的作者 await app.database.setUser(300, { name: 'user3' }) - await u4g2.shouldHaveReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。') - await u4g2.shouldHaveReply('#1', DETAIL_HEAD + '来源:user3 (300)') + await u4g2.shouldReply('# foo bar', '问答已存在,编号为 1,如要修改请尝试使用 #1 指令。') + await u4g2.shouldReply('#1', DETAIL_HEAD + '来源:user3 (300)') }) it('modify writer', async () => { - await u2.shouldHaveReply('#1 -W', '问答 1 因权限过低无法修改。') - await u4g2.shouldHaveReply('#1 -w foo', '参数 -w, --writer 错误,请检查指令语法。') - await u4g2.shouldHaveReply('#1 -w [CQ:at,qq=500]', '指定的目标用户不存在。') - await u4g2.shouldHaveReply('#1 -w [CQ:at,qq=200]', '问答 1 已成功修改。') + await u2.shouldReply('#1 -W', '问答 1 因权限过低无法修改。') + await u4g2.shouldReply('#1 -w foo', '参数 -w, --writer 错误,请检查指令语法。') + await u4g2.shouldReply('#1 -w [CQ:at,qq=500]', '指定的目标用户不存在。') + await u4g2.shouldReply('#1 -w [CQ:at,qq=200]', '问答 1 已成功修改。') // 实在找不到名字就只显示 QQ 号 - await u4g2.shouldHaveReply('#1', DETAIL_HEAD + '来源:200') + await u4g2.shouldReply('#1', DETAIL_HEAD + '来源:200') const getMemberMap = app.bots[0].getMemberMap = fn() getMemberMap.mockReturnValue(Promise.resolve({ 200: 'mock2' })) - await u4g2.shouldHaveReply('#1', DETAIL_HEAD + '来源:mock2 (200)') + await u4g2.shouldReply('#1', DETAIL_HEAD + '来源:mock2 (200)') }) it('anonymous', async () => { u2.meta.sender.nickname = 'nick2' - await u2.shouldHaveReply('#1', DETAIL_HEAD + '来源:nick2 (200)') - await u2.shouldHaveReply('#1 -W', '问答 1 已成功修改。') - await u2.shouldHaveReply('#1', DETAIL_HEAD.slice(0, -1)) - await u2.shouldHaveReply('#1 -p 0', '问答 1 因权限过低无法修改。') + await u2.shouldReply('#1', DETAIL_HEAD + '来源:nick2 (200)') + await u2.shouldReply('#1 -W', '问答 1 已成功修改。') + await u2.shouldReply('#1', DETAIL_HEAD.slice(0, -1)) + await u2.shouldReply('#1 -p 0', '问答 1 因权限过低无法修改。') }) it('frozen', async () => { - await u3g1.shouldHaveReply('# foo baz -f', '权限不足。') - await u4g2.shouldHaveReply('# foo bar -f', '修改了已存在的问答,编号为 1。') - await u3g1.shouldHaveReply('# foo bar -p 0', '问答 1 因权限过低无法修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '此问答已锁定。') - await u3g1.shouldHaveReply('## foo', SEARCH_HEAD + '1. [锁定] bar') - await u4g2.shouldHaveReply('#1 -F', '问答 1 已成功修改。') + await u3g1.shouldReply('# foo baz -f', '权限不足。') + await u4g2.shouldReply('# foo bar -f', '修改了已存在的问答,编号为 1。') + await u3g1.shouldReply('# foo bar -p 0', '问答 1 因权限过低无法修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '此问答已锁定。') + await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [锁定] bar') + await u4g2.shouldReply('#1 -F', '问答 1 已成功修改。') }) it('substitute', async () => { u2g1.meta.sender.nickname = 'nick2' const DETAIL_HEAD = '编号为 1 的问答信息:\n问题:foo\n回答:%s:%{test}\n' - await u3g1.shouldHaveReply('#1 ~ %s:%{test}', '问答 1 已成功修改。') - await u2g1.shouldHaveReply('foo', 'nick2:200') - await u3g1.shouldHaveReply('#1 -s', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1 -w [CQ:at,qq=300]', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '来源:user3 (300)\n回答中的指令由教学者代行。') - await u3g1.shouldHaveReply('## foo', SEARCH_HEAD + '1. [代行] %s:%{test}') - await u2g1.shouldHaveReply('foo', 'nick2:300') + await u3g1.shouldReply('#1 ~ %s:%{test}', '问答 1 已成功修改。') + await u2g1.shouldReply('foo', 'nick2:200') + await u3g1.shouldReply('#1 -s', '问答 1 已成功修改。') + await u3g1.shouldReply('#1 -w [CQ:at,qq=300]', '问答 1 已成功修改。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '来源:user3 (300)\n回答中的指令由教学者代行。') + await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [代行] %s:%{test}') + await u2g1.shouldReply('foo', 'nick2:300') }) }) @@ -300,12 +300,12 @@ describe('Plugin Teach', () => { const { u3g1 } = createEnvironment({ useTime: true }) it('time', async () => { - await u3g1.shouldHaveReply('# bar foo -t baz', '选项 startTime 输入无效,请输入正确的时间。') - await u3g1.shouldHaveReply('# foo bar -t 8 -T 16', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('#1', DETAIL_HEAD + '触发时段:8:00-16:00') - await u3g1.shouldHaveReply('## foo', SEARCH_HEAD + '1. [8:00-16:00] bar') - await u3g1.shouldHaveReply('## foo -t 12', SEARCH_HEAD + '1. [8:00-16:00] bar') - await u3g1.shouldHaveReply('## foo -T 12', '没有搜索到问题“foo”,请尝试使用正则表达式匹配。') + await u3g1.shouldReply('# bar foo -t baz', '选项 startTime 输入无效,请输入正确的时间。') + await u3g1.shouldReply('# foo bar -t 8 -T 16', '问答已添加,编号为 1。') + await u3g1.shouldReply('#1', DETAIL_HEAD + '触发时段:8:00-16:00') + await u3g1.shouldReply('## foo', SEARCH_HEAD + '1. [8:00-16:00] bar') + await u3g1.shouldReply('## foo -t 12', SEARCH_HEAD + '1. [8:00-16:00] bar') + await u3g1.shouldReply('## foo -T 12', '没有搜索到问题“foo”,请尝试使用正则表达式匹配。') }) it('receiver', async () => { @@ -315,13 +315,13 @@ describe('Plugin Teach', () => { advanceTimeDelta: 5, }) - await u3g1.shouldHaveReply('foo', 'bar') + await u3g1.shouldReply('foo', 'bar') clock.tick(8 * Time.hour) // 20:00 - await u3g1.shouldHaveNoReply('foo') + await u3g1.shouldNotReply('foo') clock.tick(8 * Time.hour) // 4:00 - await u3g1.shouldHaveNoReply('foo') + await u3g1.shouldNotReply('foo') clock.tick(8 * Time.hour) // 12:00 - await u3g1.shouldHaveReply('foo', 'bar') + await u3g1.shouldReply('foo', 'bar') clock.uninstall() }) @@ -336,8 +336,8 @@ describe('Plugin Teach', () => { it('upload succeed', async () => { axiosGet.mockReturnValue(Promise.resolve()) - await u3g1.shouldHaveReply('# foo [CQ:image,file=baz,url=bar]', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('foo', '[CQ:image,file=https://127.0.0.1/image/baz]') + await u3g1.shouldReply('# foo [CQ:image,file=baz,url=bar]', '问答已添加,编号为 1。') + await u3g1.shouldReply('foo', '[CQ:image,file=https://127.0.0.1/image/baz]') expect(axiosGet.mock.calls).to.have.shape([[uploadServer, { params: { file: 'baz', url: 'bar' }, }]]) @@ -345,15 +345,15 @@ describe('Plugin Teach', () => { it('upload failed', async () => { axiosGet.mockReturnValue(Promise.reject(new Error('failed'))) - await u3g1.shouldHaveReply('#1 fooo', '问答 1 已成功修改。') - await u3g1.shouldHaveReply('#1 ~ [CQ:image,file=bar,url=baz]', '上传图片时发生错误。') + await u3g1.shouldReply('#1 fooo', '问答 1 已成功修改。') + await u3g1.shouldReply('#1 ~ [CQ:image,file=bar,url=baz]', '上传图片时发生错误。') }) it('get status', async () => { axiosGet.mockReturnValue(Promise.resolve({ data: { totalSize: 10000000, totalCount: 10 }, })) - await u3g1.shouldHaveReply('##', '共收录了 1 个问题和 1 个回答。\n收录图片 10 张,总体积 9.5 MB。') + await u3g1.shouldReply('##', '共收录了 1 个问题和 1 个回答。\n收录图片 10 张,总体积 9.5 MB。') }) }) @@ -367,28 +367,28 @@ describe('Plugin Teach', () => { const { u2g1, u3g1, u4g1, u4g2, start } = createEnvironment({ throttle: { interval: 1000, responses: 2 } }) await start() - await u3g1.shouldHaveReply('# baz bar', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('# foo => baz', '问答已添加,编号为 2。') - await u2g1.shouldHaveReply('foo', 'bar') - await u3g1.shouldHaveReply('foo', 'bar') - await u4g1.shouldHaveNoReply('foo') - await u4g2.shouldHaveReply('foo', 'bar') + await u3g1.shouldReply('# baz bar', '问答已添加,编号为 1。') + await u3g1.shouldReply('# foo => baz', '问答已添加,编号为 2。') + await u2g1.shouldReply('foo', 'bar') + await u3g1.shouldReply('foo', 'bar') + await u4g1.shouldNotReply('foo') + await u4g2.shouldReply('foo', 'bar') }) it('preventLoop', async () => { const { u2g1, u3g1, u4g1, start } = createEnvironment({ preventLoop: { length: 5, participants: 2 } }) await start() - await u3g1.shouldHaveReply('# baz bar', '问答已添加,编号为 1。') - await u3g1.shouldHaveReply('# foo => baz', '问答已添加,编号为 2。') - await u2g1.shouldHaveReply('foo', 'bar') - await u2g1.shouldHaveReply('foo', 'bar') - await u3g1.shouldHaveReply('foo', 'bar') - await u3g1.shouldHaveReply('foo', 'bar') - await u2g1.shouldHaveReply('foo', 'bar') - await u2g1.shouldHaveNoReply('foo') - await u3g1.shouldHaveNoReply('foo') - await u4g1.shouldHaveReply('foo', 'bar') + await u3g1.shouldReply('# baz bar', '问答已添加,编号为 1。') + await u3g1.shouldReply('# foo => baz', '问答已添加,编号为 2。') + await u2g1.shouldReply('foo', 'bar') + await u2g1.shouldReply('foo', 'bar') + await u3g1.shouldReply('foo', 'bar') + await u3g1.shouldReply('foo', 'bar') + await u2g1.shouldReply('foo', 'bar') + await u2g1.shouldNotReply('foo') + await u3g1.shouldNotReply('foo') + await u4g1.shouldReply('foo', 'bar') }) }) })