Skip to content

Commit

Permalink
fix(mock): support multiple messages
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Feb 20, 2023
1 parent f5eb2de commit abe1724
Showing 1 changed file with 36 additions and 16 deletions.
52 changes: 36 additions & 16 deletions plugins/mock/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import assert from 'assert'
import { Context, segment, Session, Universal } from 'koishi'
import { Context, Messenger, segment, SendOptions, Session, Universal } from 'koishi'
import { format } from 'util'
import { MockBot } from './adapter'

Expand All @@ -9,12 +9,38 @@ const RECEIVED_OTHERWISE = 'expected "%s" to be replied with %s but received "%s
const RECEIVED_NTH_NOTHING = 'expected "%s" to be replied at index %s but received nothing'
const RECEIVED_NTH_OTHERWISE = 'expected "%s" to be replied with %s at index %s but received "%s"'

export class MockMessenger extends Messenger {
private buffer = ''

constructor(private client: MessageClient, options?: SendOptions) {
super(client.bot, client.meta.channelId, client.meta.guildId, options)
}

async flush() {
this.buffer = this.buffer.trim()
if (!this.buffer) return
this.client.replies.push(this.buffer)
this.client.resolve(true)
this.buffer = ''
}

async visit(element: segment) {
const { type, children } = element
if (type === 'message' || type === 'figure') {
await this.flush()
await this.render(children)
await this.flush()
} else {
this.buffer += element.toString()
}
}
}

export class MessageClient {
public app: Context
public meta: Session.Payload & Partial<Session>

_resolve: (checkLength?: boolean) => void
private replies: string[] = []
public resolve: (checkLength?: boolean) => void
public replies: string[] = []

constructor(public bot: MockBot, public userId: string, public channelId?: string) {
this.app = bot.ctx.root
Expand All @@ -39,23 +65,17 @@ export class MessageClient {
}

const self = this
this._resolve = () => {}
this.meta.send = async function (this: Session, fragment, options) {
const elements = await this.transform(segment.normalize(fragment))
if (!elements.length) return
const session = this.app.bots[0].session({ ...self.meta, elements })
if (await this.app.serial(session, 'before-send', session, options)) return
if (!session?.content) return []
self.replies.push(session.content)
self._resolve(true)
return []
this.resolve = () => {}
this.meta.send = function (this: Session, fragment, options = {}) {
options.session = this
return new MockMessenger(self, options).send(fragment)
}
}

async receive(content: string, count = Infinity) {
return new Promise<string[]>((resolve) => {
let resolved = false
this._resolve = (checkLength = false) => {
this.resolve = (checkLength = false) => {
if (resolved) return
if (checkLength && this.replies.length < count) return
resolved = true
Expand All @@ -64,7 +84,7 @@ export class MessageClient {
this.replies = []
}
const dispose = this.app.on('middleware', (session) => {
if (session.id === uuid) process.nextTick(this._resolve)
if (session.id === uuid) process.nextTick(this.resolve)
})
let quote: Universal.Message
const elements = segment.parse(content)
Expand Down

0 comments on commit abe1724

Please sign in to comment.