hubot-scripts hello をつくった。その過程で hubot-mock-adapter をためした。
hello.js は faithcreates/hubot-scripts にあったもの。faithcreates/sushi へ移植している。
今回の移植では、次のことに対応した。
- JavaScript -> CoffeeScript
- テストの追加
前者は簡単だ。もともとほとんど行数がないので、一瞬で終わる。問題は後者のテストである。
スクリプトに渡される robot を mock すればいいのだけど、そうすると正しく動くのかが怪しくなるので、hubot-mock-adapter で adapter を mock する。
# hubot スクリプトの例
module.exports = (robot) ->
robot.respond /hello$/i, (res) ->
res.send 'hello'
hubot-url について書いた時にもふれたのだけど、hubot-mock-adapter は機能が弱い。hubot-mock-adapter の README を見ればわかるが、やりたいことの割に記述が冗長すぎる。なので、Hubot 自体と hubot-mock-adapter を扱うための robot-driver をつくった。
まだ汎用性が低いためイマイチだが、汎用化できれば npm に公開したい。
{Promise} = require 'q' {Robot, TextMessage} = require 'hubot' class RobotDriver TIMEOUT = 100 # ms constructor: -> @robot = null # initialize in start() @adapter = null # initialize in start() @started = false @users = [] start: (options) -> throw new Error('already started') if @started @started = true new Promise (resolve, reject) => @robot = new Robot(null, 'mock-adapter', false, 'sushi') @robot.adapter.on 'connected', => @adapter = @robot.adapter (options.scripts or []).forEach (script) => script @robot (options.users or []).forEach (user) => @users.push @robot.brain.userForId(user.id, { name: user.name, room: user.room }) resolve() @robot.run() stop: -> throw new Error('call receiveMessage() after start()') unless @started @robot.shutdown() Promise.resolve() receiveMessage: (envelope, message) -> throw new Error('call receiveMessage() after start()') unless @started promise = new Promise (resolve, reject) => setTimeout -> reject new Error('timeout') , TIMEOUT @adapter.on 'send', (envelope, strings) -> resolve name: 'send' envelope: envelope strings: strings @adapter.receive new TextMessage(envelope, message) promise module.exports = RobotDriver