提交 8610c1af 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

split puppet-mock out (#1177)

上级 421c3029
# WECHATY # WECHATY
[![Wechaty](https://chatie.io/wechaty/images/wechaty-logo-en.png)](https://github.com/chatie/wechaty) [![Wechaty](https://chatie.io/wechaty/images/wechaty-logo-en.png)](https://github.com/chatie/wechaty)
......
...@@ -180,7 +180,8 @@ ...@@ -180,7 +180,8 @@
"tslint-config-standard": "^7.0.0", "tslint-config-standard": "^7.0.0",
"tuling123-client": "^0.0.2", "tuling123-client": "^0.0.2",
"typedoc": "^0.11.1", "typedoc": "^0.11.1",
"typescript": "^2.9.2" "typescript": "^2.9.2",
"wechaty-puppet-mock": "0.0.3"
}, },
"files_comment__whitelist_npm_publish": "http://stackoverflow.com/a/8617868/1123955", "files_comment__whitelist_npm_publish": "http://stackoverflow.com/a/8617868/1123955",
"files": [ "files": [
......
import { PuppetMock } from './puppet-mock/' import { PuppetMock } from 'wechaty-puppet-mock'
import { PuppetPuppeteer } from './puppet-puppeteer/' import { PuppetPuppeteer } from './puppet-puppeteer/'
import { PuppetPadchat } from './puppet-padchat' import { PuppetPadchat } from './puppet-padchat'
import { PuppetWechat4u } from './puppet-wechat4u/' import { PuppetWechat4u } from './puppet-wechat4u/'
......
# PUPPET-MOCK
```ts
import PuppetMock from '@chatie/wechaty-puppet-mock'
const wechaty = new Wechaty()
const puppet = new PuppetMock({
profile,
wechaty,
})
```
## HELPER UTILITIES
### StateSwitch
```ts
this.state.on('pending')
this.state.on(true)
this.state.off('pending')
this.state.off(true)
await this.state.ready('on')
await this.state.ready('off')
```
### Watchdog
```ts
```
### Profile
```ts
await this.profile.set('config', { id: 1, key: 'xxx' })
const config = await this.profile.get('config')
console.log(config)
// Output: { id: 1, key: 'xxx' }
```
/**
* Wechaty - https://github.com/chatie/wechaty
*
* @copyright 2016-2018 Huan LI <zixia@zixia.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { PuppetMock } from './puppet-mock'
export {
PuppetMock,
}
export default PuppetMock
#!/usr/bin/env ts-node
// tslint:disable:no-shadowed-variable
import test from 'blue-tape'
import { MemoryCard } from 'memory-card'
import { PuppetMock } from './puppet-mock'
class PuppetMockTest extends PuppetMock {
}
test('PuppetMock restart without problem', async t => {
const puppet = new PuppetMockTest({
memory : new MemoryCard(),
})
try {
for (let i = 0; i < 3; i++) {
await puppet.start()
await puppet.stop()
t.pass('start/stop-ed at #' + i)
}
t.pass('PuppetMock() start/restart successed.')
} catch (e) {
t.fail(e)
}
})
/**
* Wechaty - https://github.com/chatie/wechaty
*
* @copyright 2016-2018 Huan LI <zixia@zixia.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import path from 'path'
import {
FileBox,
} from 'file-box'
import {
MessagePayload,
ContactGender,
ContactType,
ContactPayload,
FriendshipPayload,
RoomPayload,
RoomMemberPayload,
Puppet,
PuppetOptions,
Receiver,
MessageType,
} from 'wechaty-puppet'
import {
log,
qrCodeForChatie,
} from '../config'
export type PuppetFoodType = 'scan' | 'ding'
export type ScanFoodType = 'scan' | 'login' | 'logout'
export interface MockContactRawPayload {
name : string,
}
export interface MockMessageRawPayload {
id : string,
from : string,
to : string,
text : string
}
export interface MockRoomRawPayload {
topic : string,
memberList : string[],
ownerId : string,
}
export class PuppetMock extends Puppet {
private loopTimer?: NodeJS.Timer
constructor(
public options: PuppetOptions,
) {
super(options)
}
public async start(): Promise<void> {
log.verbose('PuppetMock', `start() with ${this.options.memory.name}`)
this.state.on('pending')
// await some tasks...
this.state.on(true)
this.id = 'logined_user_id'
// const user = this.Contact.load(this.id)
this.emit('login', this.id)
const MOCK_MSG_ID = 'mockid'
this.cacheMessagePayload.set(MOCK_MSG_ID, {
id : MOCK_MSG_ID,
type : MessageType.Text,
text : 'mock text',
timestamp : Date.now(),
fromId : 'xxx',
toId : 'xxx',
})
this.loopTimer = setInterval(() => {
log.verbose('PuppetMock', `start() setInterval() pretending received a new message: ${MOCK_MSG_ID}`)
this.emit('message', MOCK_MSG_ID)
}, 3000)
}
public async stop(): Promise<void> {
log.verbose('PuppetMock', 'quit()')
if (this.state.off()) {
log.warn('PuppetMock', 'quit() is called on a OFF puppet. await ready(off) and return.')
await this.state.ready('off')
return
}
this.state.off('pending')
if (this.loopTimer) {
clearInterval(this.loopTimer)
}
// await some tasks...
this.state.off(true)
}
public async logout(): Promise<void> {
log.verbose('PuppetMock', 'logout()')
if (!this.id) {
throw new Error('logout before login?')
}
this.emit('logout', this.id) // becore we will throw above by logonoff() when this.user===undefined
this.id = undefined
// TODO: do the logout job
}
/**
*
* Contact
*
*/
public contactAlias(contactId: string) : Promise<string>
public contactAlias(contactId: string, alias: string | null): Promise<void>
public async contactAlias(contactId: string, alias?: string|null): Promise<void | string> {
log.verbose('PuppetMock', 'contactAlias(%s, %s)', contactId, alias)
if (typeof alias === 'undefined') {
return 'mock alias'
}
return
}
public async contactList(): Promise<string[]> {
log.verbose('PuppetMock', 'contactList()')
return []
}
public async contactQrcode(contactId: string): Promise<string> {
if (contactId !== this.selfId()) {
throw new Error('can not set avatar for others')
}
throw new Error('not supported')
// return await this.bridge.WXqr
}
public async contactAvatar(contactId: string) : Promise<FileBox>
public async contactAvatar(contactId: string, file: FileBox) : Promise<void>
public async contactAvatar(contactId: string, file?: FileBox): Promise<void | FileBox> {
log.verbose('PuppetMock', 'contactAvatar(%s)', contactId)
/**
* 1. set
*/
if (file) {
return
}
/**
* 2. get
*/
const WECHATY_ICON_PNG = path.resolve('../../docs/images/wechaty-icon.png')
return FileBox.fromFile(WECHATY_ICON_PNG)
}
public async contactRawPayload(id: string): Promise<MockContactRawPayload> {
log.verbose('PuppetMock', 'contactRawPayload(%s)', id)
const rawPayload: MockContactRawPayload = {
name : 'mock name',
}
return rawPayload
}
public async contactRawPayloadParser(rawPayload: MockContactRawPayload): Promise<ContactPayload> {
log.verbose('PuppetMock', 'contactRawPayloadParser(%s)', rawPayload)
const payload: ContactPayload = {
id : 'id',
gender : ContactGender.Unknown,
type : ContactType.Unknown,
}
return payload
}
/**
*
* Message
*
*/
public async messageFile(id: string): Promise<FileBox> {
return FileBox.fromBase64(
'cRH9qeL3XyVnaXJkppBuH20tf5JlcG9uFX1lL2IvdHRRRS9kMMQxOPLKNYIzQQ==',
'mock-file' + id + '.txt',
)
}
public async messageRawPayload(id: string): Promise<MockMessageRawPayload> {
log.verbose('PuppetMock', 'messageRawPayload(%s)', id)
const rawPayload: MockMessageRawPayload = {
id : 'id',
from : 'from_id',
text : 'mock message text',
to : 'to_id',
}
return rawPayload
}
public async messageRawPayloadParser(rawPayload: MockMessageRawPayload): Promise<MessagePayload> {
log.verbose('PuppetMock', 'messagePayload(%s)', rawPayload)
const payload: MessagePayload = {
id : rawPayload.id,
timestamp : Date.now(),
fromId : 'xxx',
text : 'mock message text',
toId : this.selfId(),
type : MessageType.Text,
}
return payload
}
public async messageSendText(
receiver : Receiver,
text : string,
): Promise<void> {
log.verbose('PuppetMock', 'messageSend(%s, %s)', receiver, text)
}
public async messageSendFile(
receiver : Receiver,
file : FileBox,
): Promise<void> {
log.verbose('PuppetMock', 'messageSend(%s, %s)', receiver, file)
}
public async messageSendContact(
receiver : Receiver,
contactId : string,
): Promise<void> {
log.verbose('PuppetMock', 'messageSend("%s", %s)', JSON.stringify(receiver), contactId)
return
}
public async messageForward(
receiver : Receiver,
messageId : string,
): Promise<void> {
log.verbose('PuppetMock', 'messageForward(%s, %s)',
receiver,
messageId,
)
}
/**
*
* Room
*
*/
public async roomRawPayload(
id: string,
): Promise<MockRoomRawPayload> {
log.verbose('PuppetMock', 'roomRawPayload(%s)', id)
const rawPayload: MockRoomRawPayload = {
ownerId : 'mock_room_owner_id',
topic : 'mock topic',
memberList : [],
}
return rawPayload
}
public async roomRawPayloadParser(
rawPayload: MockRoomRawPayload,
): Promise<RoomPayload> {
log.verbose('PuppetMock', 'roomRawPayloadParser(%s)', rawPayload)
const payload: RoomPayload = {
id : 'id',
topic : 'mock topic',
}
return payload
}
public async roomList(): Promise<string[]> {
log.verbose('PuppetMock', 'roomList()')
return []
}
public async roomDel(
roomId : string,
contactId : string,
): Promise<void> {
log.verbose('PuppetMock', 'roomDel(%s, %s)', roomId, contactId)
}
public async roomAvatar(roomId: string): Promise<FileBox> {
log.verbose('PuppetMock', 'roomAvatar(%s)', roomId)
const payload = await this.roomPayload(roomId)
if (payload.avatar) {
return FileBox.fromUrl(payload.avatar)
}
log.warn('PuppetMock', 'roomAvatar() avatar not found, use the chatie default.')
return qrCodeForChatie()
}
public async roomAdd(
roomId : string,
contactId : string,
): Promise<void> {
log.verbose('PuppetMock', 'roomAdd(%s, %s)', roomId, contactId)
}
public async roomTopic(roomId: string) : Promise<string>
public async roomTopic(roomId: string, topic: string) : Promise<void>
public async roomTopic(
roomId: string,
topic?: string,
): Promise<void | string> {
log.verbose('PuppetMock', 'roomTopic(%s, %s)', roomId, topic)
if (typeof topic === 'undefined') {
return 'mock room topic'
}
return
}
public async roomCreate(
contactIdList : string[],
topic : string,
): Promise<string> {
log.verbose('PuppetMock', 'roomCreate(%s, %s)', contactIdList, topic)
return 'mock_room_id'
}
public async roomQuit(roomId: string): Promise<void> {
log.verbose('PuppetMock', 'roomQuit(%s)', roomId)
}
public async roomQrcode(roomId: string): Promise<string> {
return roomId + ' mock qrcode'
}
public async roomMemberList(roomId: string) : Promise<string[]> {
log.verbose('PuppetMock', 'roommemberList(%s)', roomId)
return []
}
public async roomMemberRawPayload(roomId: string, contactId: string): Promise<any> {
log.verbose('PuppetMock', 'roomMemberRawPayload(%s, %s)', roomId, contactId)
return {}
}
public async roomMemberRawPayloadParser(rawPayload: any): Promise<RoomMemberPayload> {
log.verbose('PuppetMock', 'roomMemberRawPayloadParser(%s)', rawPayload)
return {
id: 'xx',
roomAlias: 'yy',
}
}
public async roomAnnounce(roomId: string) : Promise<string>
public async roomAnnounce(roomId: string, text: string) : Promise<void>
public async roomAnnounce(roomId: string, text?: string) : Promise<void | string> {
if (text) {
return
}
return 'mock announcement for ' + roomId
}
/**
*
* Friendship
*
*/
public async friendshipRawPayload(id: string) : Promise<any> {
return {id} as any
}
public async friendshipRawPayloadParser(rawPayload: any) : Promise<FriendshipPayload> {
return rawPayload
}
public async friendshipVerify(
contactId : string,
hello : string,
): Promise<void> {
log.verbose('PuppetMock', 'friendshipVerify(%s, %s)', contactId, hello)
}
public async friendshipAccept(
friendshipId : string,
): Promise<void> {
log.verbose('PuppetMock', 'friendshipAccept(%s)', friendshipId)
}
public ding(data?: string): void {
log.silly('PuppetMock', 'ding(%s)', data || '')
this.emit('dong', data)
return
}
}
export default PuppetMock
...@@ -14,7 +14,7 @@ import { ...@@ -14,7 +14,7 @@ import {
} from './contact' } from './contact'
import { import {
PuppetMock, PuppetMock,
} from '../puppet-mock' } from 'wechaty-puppet-mock'
// tslint:disable-next-line:variable-name // tslint:disable-next-line:variable-name
const Contact = cloneClass(GlobalContact) const Contact = cloneClass(GlobalContact)
......
...@@ -23,6 +23,7 @@ import test from 'blue-tape' ...@@ -23,6 +23,7 @@ import test from 'blue-tape'
import sinon from 'sinon' import sinon from 'sinon'
// import asyncHooks from 'async_hooks' // import asyncHooks from 'async_hooks'
import { PuppetMock } from 'wechaty-puppet-mock'
import { import {
Wechaty, Wechaty,
...@@ -43,7 +44,6 @@ import { ...@@ -43,7 +44,6 @@ import {
import { import {
Puppet, Puppet,
} from 'wechaty-puppet' } from 'wechaty-puppet'
import { PuppetMock } from './puppet-mock'
import { MemoryCard } from 'memory-card' import { MemoryCard } from 'memory-card'
class WechatyTest extends Wechaty { class WechatyTest extends Wechaty {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册