module Cinch::Test

Module to allow near network I/O free testing of cinch plugins.

Versioning Info

Constants

Reply
VERSION

Public Instance Methods

catch_channel_messages(message, mutex, replies) click to toggle source
# File lib/cinch/test.rb, line 114
def catch_channel_messages(message, mutex, replies)
  return unless message.channel
  (class << message.channel; self; end).class_eval do
    [[:send, :channel], [:action, :action]].each do |method, event|
      define_method method do |msg|
        reply = Reply.new(msg, event, Time.now)
        mutex.synchronize { replies << reply }
      end
    end
  end
end
catch_direct_messages(message, mutex, replies) click to toggle source
# File lib/cinch/test.rb, line 103
def catch_direct_messages(message, mutex, replies)
  (class << message.user; self; end).class_eval do
    [:send, :msg, :privmsg].each do |method|
      define_method method do |msg, notice = false|
        reply = Reply.new(msg, (notice ? :notice : :private), Time.now)
        mutex.synchronize { replies << reply }
      end
    end
  end
end
catch_replies(message, mutex, replies) click to toggle source
# File lib/cinch/test.rb, line 87
def catch_replies(message, mutex, replies)
  (class << message; self; end).class_eval do
    [:reply, :safe_reply, :action_reply, :safe_action_reply].each do |name|
      define_method name do |msg, prefix = false|
        msg = [user.nick, msg].join(': ') if prefix
        if name == :safe_reply || name == :safe_action_reply
          msg = Cinch::Utilities::String.filter_string(msg)
        end
        reply = Reply.new(msg, name.match(/action/) ? :action : :message,
                          Time.now)
        mutex.synchronize { replies << reply }
      end
    end
  end
end
get_events(message, event) click to toggle source
# File lib/cinch/test.rb, line 166
def get_events(message, event)
  # Deal with secondary event types
  # See http://rubydoc.info/github/cinchrb/cinch/file/docs/events.md
  events = event.is_a?(Array) ? [:catchall] + event : [:catchall, event]

  # If the message has a channel add the :channel event otherwise
  #   add :private
  events << (message.channel.nil? ? :private : :channel)

  # If the message is :private also trigger :message
  events << :message if events.include?(:private)

  events.uniq
end
get_replies(message, event = :message) click to toggle source

Process message and return all replies. @parmam [Cinch::Test::MockMessage] message A MockMessage object. @param [Symbol] event The event type of the message.

# File lib/cinch/test.rb, line 129
def get_replies(message, event = :message)
  mutex = Mutex.new
  replies = []

  # Catch all m.reply
  catch_replies(message, mutex, replies)

  # Catch all user.(msg|send|privmsg)
  catch_direct_messages(message, mutex, replies)

  # Catch all channel.send and action
  catch_channel_messages(message, mutex, replies)

  process_message(message, event)

  replies
end
make_bot(plugin = nil, opts = {}, &b) click to toggle source
# File lib/cinch/test.rb, line 68
def make_bot(plugin = nil, opts = {}, &b)
  MockBot.new do
    configure do |c|
      c.nick = 'testbot'
      c.server = nil
      c.channels = ['#test']
      c.plugins.plugins = [plugin] unless plugin.nil?
      c.plugins.options[plugin] = opts
      c.reconnect = false
    end

    instance_eval(&b) if b
  end
end
make_message(bot, text, opts = {}) click to toggle source
# File lib/cinch/test.rb, line 83
def make_message(bot, text, opts = {})
  MockMessage.new(text, bot, opts)
end
process_message(message, event) click to toggle source

Process message by dispatching it to the handlers @param [Cinch::Test::MockMessage] message A MockMessage object. @param [Symbol] event The event type of the message.

# File lib/cinch/test.rb, line 150
def process_message(message, event)
  handlers = message.bot.handlers

  # Get a list of applicable event types.
  events = get_events(message, event)

  # Dispatch each of the events to the handlers
  events.each { |e| handlers.dispatch(e, message) }

  # join all of the freaking threads, like seriously
  # why is there no option to dispatch synchronously
  handlers.each do |handler|
    handler.thread_group.list.each(&:join)
  end
end