UNPKG

8.47 kBPlain TextView Raw
1#!/usr/bin/env ts-node
2
3/**
4 * Wechaty Chatbot SDK - https://github.com/wechaty/wechaty
5 *
6 * @copyright 2016 Huan LI (李卓桓) <https://github.com/huan>, and
7 * Wechaty Contributors <https://github.com/wechaty>.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 */
22import test from 'blue-tape'
23import sinon from 'sinon'
24
25import { PuppetMock } from 'wechaty-puppet-mock'
26
27import {
28 Wechaty,
29} from './wechaty'
30
31import {
32 config,
33 Contact,
34 Friendship,
35 IoClient,
36 log,
37 Message,
38
39 Room,
40} from './mod'
41
42import {
43 Puppet,
44} from 'wechaty-puppet'
45
46class WechatyTest extends Wechaty {
47
48 public wechatifyUserModulesTest (puppet: Puppet): void {
49 return this.wechatifyUserModules(puppet)
50 }
51
52}
53
54test('Export of the Framework', async t => {
55 t.ok(Contact, 'should export Contact')
56 t.ok(Friendship, 'should export Friendship')
57 t.ok(IoClient, 'should export IoClient')
58 t.ok(Message, 'should export Message')
59 t.ok(Puppet, 'should export Puppet')
60 t.ok(Room, 'should export Room')
61 t.ok(Wechaty, 'should export Wechaty')
62 t.ok(log, 'should export log')
63})
64
65test('static VERSION', async t => {
66 t.true('VERSION' in Wechaty, 'Wechaty should has a static VERSION property')
67})
68
69test('Config setting', async t => {
70 t.ok(config, 'should export Config')
71 // t.ok(config.default.DEFAULT_PUPPET , 'should has DEFAULT_PUPPET')
72})
73
74test('event:start/stop', async t => {
75 const wechaty = new Wechaty({ puppet: 'wechaty-puppet-mock' })
76
77 const startSpy = sinon.spy()
78 const stopSpy = sinon.spy()
79
80 wechaty.on('start', startSpy)
81 wechaty.on('stop', stopSpy)
82
83 await wechaty.start()
84 await wechaty.stop()
85
86 // console.log(startSpy.callCount)
87 t.ok(startSpy.calledOnce, 'should get event:start once')
88 t.ok(stopSpy.calledOnce, 'should get event:stop once')
89})
90
91//
92// FIXME: restore this unit test !!!
93//
94// test.only('event:scan', async t => {
95// const m = {} as any
96
97// const asyncHook = asyncHooks.createHook({
98// init(asyncId: number, type: string, triggerAsyncId: number, resource: Object) {
99// m[asyncId] = type
100// },
101// before(asyncId) {
102// // delete m[asyncId]
103// },
104// after(asyncId) {
105// // delete m[asyncId]
106// },
107// destroy(asyncId) {
108// delete m[asyncId]
109// },
110// })
111// asyncHook.enable()
112
113// const wechaty = Wechaty.instance()
114
115// const spy = sinon.spy()
116
117// wechaty.on('scan', spy)
118
119// const scanFuture = new Promise(resolve => wechaty.once('scan', resolve))
120// // wechaty.once('scan', () => console.log('FAINT'))
121
122// await wechaty.start()
123// await scanFuture
124// // await new Promise(r => setTimeout(r, 1000))
125// await wechaty.stop()
126
127// t.ok(spy.calledOnce, 'should get event:scan')
128// asyncHook.disable()
129
130// console.log(m)
131// })
132
133test.skip('SKIP DEALING WITH THE LISTENER EXCEPTIONS. on(event, Function)', async t => {
134 const spy = sinon.spy()
135 const wechaty = Wechaty.instance()
136
137 const EXPECTED_ERROR = new Error('testing123')
138 wechaty.on('message', () => { throw EXPECTED_ERROR })
139 // wechaty.on('scan', () => 42)
140 wechaty.on('error', spy)
141
142 const messageFuture = new Promise(resolve => wechaty.once('message', resolve))
143 wechaty.emit('message', {} as any)
144
145 await messageFuture
146 await wechaty.stop()
147
148 t.ok(spy.calledOnce, 'should get event:error once')
149 t.equal(spy.firstCall.args[0], EXPECTED_ERROR, 'should get error from message listener')
150
151})
152
153test.skip('SKIP DEALING WITH THE LISTENER EXCEPTIONS. test async error', async (t) => {
154
155 // Do not modify the global Wechaty instance
156 class MyWechatyTest extends Wechaty {}
157
158 const EXPECTED_ERROR = new Error('test')
159
160 const bot = new MyWechatyTest({
161 puppet: new PuppetMock(),
162 })
163
164 const asyncErrorFunction = function () {
165 return new Promise<void>((resolve, reject) => {
166 setTimeout(function () {
167 reject(EXPECTED_ERROR)
168 }, 100)
169 // tslint ask resolve must be called,
170 // so write a falsy value, so that it never called
171 if (+new Date() < 0) {
172 resolve()
173 }
174 })
175 }
176
177 bot.on('message', async () => {
178 await asyncErrorFunction()
179 })
180 bot.on('error', (e) => {
181 t.ok(e.message === EXPECTED_ERROR.message)
182 })
183
184 bot.emit('message', {} as any)
185
186 await bot.stop()
187})
188
189test('use plugin', async (t) => {
190
191 // Do not modify the gloabl Wechaty instance
192 class MyWechatyTest extends Wechaty {}
193
194 let result = ''
195
196 const myGlobalPlugin = function () {
197 return function (bot: Wechaty) {
198 bot.on('message', () => (result += 'FROM_GLOBAL_PLUGIN:'))
199 }
200 }
201
202 const myPlugin = function () {
203 return function (bot: Wechaty) {
204 bot.on('message', () => (result += 'FROM_MY_PLUGIN:'))
205 }
206 }
207
208 MyWechatyTest.use(myGlobalPlugin())
209
210 const bot = new MyWechatyTest({
211 puppet: new PuppetMock(),
212 })
213
214 bot.use(myPlugin())
215
216 bot.on('message', () => (result += 'FROM_BOT'))
217
218 bot.emit('message', {} as any)
219
220 await bot.stop()
221
222 t.ok(result === 'FROM_GLOBAL_PLUGIN:FROM_MY_PLUGIN:FROM_BOT')
223
224})
225
226test('initPuppetAccessory()', async t => {
227 const wechatyTest = new WechatyTest()
228
229 const puppet = new PuppetMock()
230 t.doesNotThrow(() => wechatyTest.wechatifyUserModulesTest(puppet), 'should not throw for the 1st time init')
231 t.throws(() => wechatyTest.wechatifyUserModulesTest(puppet), 'should throw for the 2nd time init')
232})
233
234// TODO: add test for event args
235
236test('Wechaty restart for many times', async t => {
237 const wechaty = new Wechaty({
238 puppet: new PuppetMock(),
239 })
240
241 try {
242 for (let i = 0; i < 3; i++) {
243 await wechaty.start()
244 await wechaty.stop()
245 t.pass('start/stop-ed at #' + i)
246 }
247 t.pass('Wechaty start/restart successed.')
248 } catch (e) {
249 t.fail(e)
250 }
251
252})
253
254test('@event ready', async t => {
255 const puppet = new PuppetMock()
256 const wechaty = new Wechaty({ puppet })
257
258 const sandbox = sinon.createSandbox()
259 const spy = sandbox.spy()
260
261 wechaty.on('ready', spy)
262 t.true(spy.notCalled, 'should no ready event with new wechaty instance')
263
264 await wechaty.start()
265 t.true(spy.notCalled, 'should no ready event right start wechaty started')
266
267 puppet.emit('ready', { data: 'test' })
268 t.true(spy.calledOnce, 'should fire ready event after puppet ready')
269
270 await wechaty.stop()
271 await wechaty.start()
272 puppet.emit('ready', { data: 'test' })
273
274 t.true(spy.calledTwice, 'should fire ready event second time after stop/start wechaty')
275
276 await wechaty.stop()
277})
278
279test('ready()', async t => {
280 const puppet = new PuppetMock()
281 const wechaty = new Wechaty({ puppet })
282
283 const sandbox = sinon.createSandbox()
284
285 const spy = sandbox.spy()
286
287 wechaty.ready()
288 .then(spy)
289 .catch(e => t.fail('rejection: ' + e))
290
291 t.true(spy.notCalled, 'should not ready with new wechaty instance')
292
293 await wechaty.start()
294
295 t.true(spy.notCalled, 'should not ready after right start wechaty')
296
297 puppet.emit('ready', { data: 'test' })
298 await new Promise(resolve => setImmediate(resolve))
299 t.true(spy.calledOnce, 'should ready after puppet ready')
300
301 await wechaty.stop()
302 await wechaty.start()
303 wechaty.ready()
304 .then(spy)
305 .catch(e => t.fail('rejection: ' + e))
306
307 puppet.emit('ready', { data: 'test' })
308 await new Promise(resolve => setImmediate(resolve))
309 t.true(spy.calledTwice, 'should ready again after stop/start wechaty')
310
311 await wechaty.stop()
312})
313
314test('on/off event listener management', async t => {
315 const puppet = new PuppetMock()
316 const wechaty = new Wechaty({ puppet })
317
318 const onMessage = (_: any) => {}
319 t.equal(wechaty.listenerCount('message'), 0, 'should no listener after initializing')
320
321 wechaty.on('message', onMessage)
322 t.equal(wechaty.listenerCount('message'), 1, 'should +1 listener after on(message)')
323
324 wechaty.off('message', onMessage)
325 t.equal(wechaty.listenerCount('message'), 0, 'should -1 listener after off(message)')
326
327})
328
\No newline at end of file