botfly 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/TODO +23 -0
- data/VERSION +1 -1
- data/botfly.gemspec +5 -8
- data/lib/botfly.rb +6 -0
- data/lib/botfly/bot.rb +1 -1
- data/lib/botfly/callback_context.rb +45 -0
- data/lib/botfly/common_block_acceptor.rb +1 -1
- data/lib/botfly/matcher.rb +0 -1
- data/lib/botfly/muc_client.rb +1 -1
- data/lib/botfly/responder.rb +0 -3
- data/lib/botfly/responder/common_responder_methods.rb +1 -1
- data/lib/botfly/responder/message_responder.rb +0 -10
- data/lib/botfly/responder/responder.rb +25 -14
- data/lib/botfly/responder/subscription_request_responder.rb +1 -8
- data/spec/botfly/bot_spec.rb +9 -7
- data/spec/botfly/callback_context_spec.rb +125 -0
- data/spec/botfly/common_block_acceptor_spec.rb +7 -2
- data/spec/botfly/matcher/body_matcher_spec.rb +6 -0
- data/spec/botfly/matcher/matcher_spec.rb +6 -0
- data/spec/botfly/matcher/muc_nick_matcher_spec.rb +6 -0
- data/spec/botfly/matcher/muc_text_matcher_spec.rb +6 -0
- data/spec/botfly/matcher/muc_time_matcher_spec.rb +6 -0
- data/spec/botfly/matcher/nick_matcher_spec.rb +6 -0
- data/spec/botfly/matcher/subject_matcher_spec.rb +6 -0
- data/spec/botfly/responder/common_responder_methods_spec.rb +9 -7
- data/spec/botfly/responder/message_responder_spec.rb +6 -0
- data/spec/botfly/responder/muc_responder_spec.rb +6 -0
- data/spec/botfly/responder/responder_spec.rb +83 -0
- data/spec/botfly/responder/subscription_request_responder_spec.rb +6 -0
- metadata +6 -9
- data/lib/botfly/responder/muc_message_responder.rb +0 -4
- data/lib/botfly/responder/presence_responder.rb +0 -25
- data/spec/botfly/responder/muc_message_responder_spec.rb +0 -0
- data/spec/botfly/responder/presence_responder_spec.rb +0 -0
data/TODO
CHANGED
@@ -1,12 +1,35 @@
|
|
1
1
|
Botfly Todo List (by priority)
|
2
2
|
==============================
|
3
|
+
* Have Bot.new and Bot#run instead of just #login that always runs
|
3
4
|
* Replace CommonBlockAcceptor responder chain array with ResponderChain object
|
4
5
|
** Spec & create ResponderChain class
|
5
6
|
** Have responder chain stop call first responder ONLY after reaching a match
|
6
7
|
** Additionally provide DSL for on... chain to give priority to responders (that is to say one can specify which responders fire first)
|
7
8
|
* Finish speccing matchers, responders
|
8
9
|
* More robust instance methods on responders (i.e. provide access to variables through methods and not ivars)
|
10
|
+
-> In fact, the base Responder class should, for each parameter, set up a set of default instance methods for each parameter (since, largely, these parameters are standard across their names)
|
11
|
+
This will DRY up the "setup_instance_variables" as that paradigm performs horribly in flog and other stats
|
9
12
|
* Additional matchers on single and multi-user chat (not sure what, but doesn't feel complete)
|
10
13
|
* Add configure method to accept list of configuration paramaters.
|
11
14
|
* Support any of a bevy of features provided by xmpp4r
|
12
15
|
|
16
|
+
|
17
|
+
Unsorted
|
18
|
+
========
|
19
|
+
* Some sort of xmpp4r mock/helper to more easily test external services
|
20
|
+
I'm imagining skipping most of the xml junk that goes on internally in xmpp4r. Something maybe like this:
|
21
|
+
|
22
|
+
it "should reply 'yo!' to any message" do
|
23
|
+
|
24
|
+
bot = Botfly.new("doesn't", "matter") do
|
25
|
+
on.message do
|
26
|
+
reply "yo!"
|
27
|
+
end
|
28
|
+
on.subscription_request { accept }
|
29
|
+
end
|
30
|
+
|
31
|
+
bot.should
|
32
|
+
receive(:message, :from => 'jim@someserver.com/home', :message => "Hi!").
|
33
|
+
then reply_with "yo!"
|
34
|
+
# A full range of starting custom matchers (get, be_added_by, something, etc.) and set of response matcher
|
35
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.4
|
data/botfly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{botfly}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Neufeld"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-10}
|
13
13
|
s.description = %q{Botfly is a Jabber Bot DSL that lets you write bots with ease. Enjoy, while it's still fresh and VERY ALPHA.}
|
14
14
|
s.email = %q{ryan@ryanneufeld.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
"example.rb",
|
29
29
|
"lib/botfly.rb",
|
30
30
|
"lib/botfly/bot.rb",
|
31
|
+
"lib/botfly/callback_context.rb",
|
31
32
|
"lib/botfly/common_block_acceptor.rb",
|
32
33
|
"lib/botfly/matcher.rb",
|
33
34
|
"lib/botfly/matcher/body_matcher.rb",
|
@@ -41,13 +42,12 @@ Gem::Specification.new do |s|
|
|
41
42
|
"lib/botfly/responder.rb",
|
42
43
|
"lib/botfly/responder/common_responder_methods.rb",
|
43
44
|
"lib/botfly/responder/message_responder.rb",
|
44
|
-
"lib/botfly/responder/muc_message_responder.rb",
|
45
45
|
"lib/botfly/responder/muc_responder.rb",
|
46
|
-
"lib/botfly/responder/presence_responder.rb",
|
47
46
|
"lib/botfly/responder/responder.rb",
|
48
47
|
"lib/botfly/responder/subscription_request_responder.rb",
|
49
48
|
"retrobot.rb",
|
50
49
|
"spec/botfly/bot_spec.rb",
|
50
|
+
"spec/botfly/callback_context_spec.rb",
|
51
51
|
"spec/botfly/common_block_acceptor_spec.rb",
|
52
52
|
"spec/botfly/matcher/body_matcher_spec.rb",
|
53
53
|
"spec/botfly/matcher/matcher_spec.rb",
|
@@ -59,9 +59,7 @@ Gem::Specification.new do |s|
|
|
59
59
|
"spec/botfly/muc_client_spec.rb",
|
60
60
|
"spec/botfly/responder/common_responder_methods_spec.rb",
|
61
61
|
"spec/botfly/responder/message_responder_spec.rb",
|
62
|
-
"spec/botfly/responder/muc_message_responder_spec.rb",
|
63
62
|
"spec/botfly/responder/muc_responder_spec.rb",
|
64
|
-
"spec/botfly/responder/presence_responder_spec.rb",
|
65
63
|
"spec/botfly/responder/responder_spec.rb",
|
66
64
|
"spec/botfly/responder/subscription_request_responder_spec.rb",
|
67
65
|
"spec/botfly_spec.rb",
|
@@ -77,6 +75,7 @@ Gem::Specification.new do |s|
|
|
77
75
|
s.summary = %q{A quick and easy DSL for generating Jabber bots}
|
78
76
|
s.test_files = [
|
79
77
|
"spec/botfly/bot_spec.rb",
|
78
|
+
"spec/botfly/callback_context_spec.rb",
|
80
79
|
"spec/botfly/common_block_acceptor_spec.rb",
|
81
80
|
"spec/botfly/matcher/body_matcher_spec.rb",
|
82
81
|
"spec/botfly/matcher/matcher_spec.rb",
|
@@ -88,9 +87,7 @@ Gem::Specification.new do |s|
|
|
88
87
|
"spec/botfly/muc_client_spec.rb",
|
89
88
|
"spec/botfly/responder/common_responder_methods_spec.rb",
|
90
89
|
"spec/botfly/responder/message_responder_spec.rb",
|
91
|
-
"spec/botfly/responder/muc_message_responder_spec.rb",
|
92
90
|
"spec/botfly/responder/muc_responder_spec.rb",
|
93
|
-
"spec/botfly/responder/presence_responder_spec.rb",
|
94
91
|
"spec/botfly/responder/responder_spec.rb",
|
95
92
|
"spec/botfly/responder/subscription_request_responder_spec.rb",
|
96
93
|
"spec/botfly_spec.rb",
|
data/lib/botfly.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# I know this isn't completely proper, but for some reason my lib wasn't on the loadpath, and i SHOULD be able to assume it is
|
2
|
+
unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
4
|
+
end
|
5
|
+
|
1
6
|
require 'rubygems'
|
2
7
|
|
3
8
|
require 'logger'
|
@@ -7,6 +12,7 @@ require 'xmpp4r'
|
|
7
12
|
require 'xmpp4r/muc'
|
8
13
|
require 'xmpp4r/roster'
|
9
14
|
|
15
|
+
require 'botfly/callback_context'
|
10
16
|
require 'botfly/common_block_acceptor'
|
11
17
|
require 'botfly/responder'
|
12
18
|
require 'botfly/bot'
|
data/lib/botfly/bot.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Botfly
|
2
|
+
class CallbackContext
|
3
|
+
def initialize(caller, params)
|
4
|
+
setup_params(params)
|
5
|
+
@caller = caller
|
6
|
+
end
|
7
|
+
def method_missing(name, *args)
|
8
|
+
@caller.send(name,*args) if name.to_s.scan(/^setup/).empty?
|
9
|
+
end
|
10
|
+
private
|
11
|
+
# OK, so. Get the instance's eigenclass, then, call the private method define_method - thus created the method called #{name} that returns value. Basically attr_reader but for any generic variable.
|
12
|
+
def expose(name, value)
|
13
|
+
(class<<self;self;end).send(:define_method,name,proc{value})
|
14
|
+
end
|
15
|
+
def setup_params(params)
|
16
|
+
params.each do |name,value|
|
17
|
+
send(:"setup_#{name}", value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def setup_roster_item(roster_item)
|
21
|
+
expose(:roster_item, roster_item)
|
22
|
+
end
|
23
|
+
def setup_message(message)
|
24
|
+
expose(:message, message)
|
25
|
+
expose(:body, message.body)
|
26
|
+
expose(:chat_state, message.chat_state)
|
27
|
+
expose(:subject, message.subject)
|
28
|
+
expose(:type, message.type)
|
29
|
+
expose(:from, message.from)
|
30
|
+
expose(:to, message.to)
|
31
|
+
end
|
32
|
+
def setup_presence(presence, pre = '')
|
33
|
+
expose(:"#{pre}presence", presence)
|
34
|
+
expose(:"#{pre}from", presence.from)
|
35
|
+
expose(:"#{pre}show", presence.show)
|
36
|
+
expose(:"#{pre}priority", presence.priority)
|
37
|
+
expose(:"#{pre}status", presence.status)
|
38
|
+
expose(:"#{pre}type", presence.type)
|
39
|
+
end
|
40
|
+
def setup_old_presence(presence); setup_presence(presence, 'old_') end
|
41
|
+
def setup_time(time); expose(:time, time) end
|
42
|
+
def setup_nick(nick); expose(:from, nick); end
|
43
|
+
def setup_text(text); expose(:text, text); expose(:body, text); end
|
44
|
+
end
|
45
|
+
end
|
@@ -35,7 +35,7 @@ module Botfly
|
|
35
35
|
|
36
36
|
def method_missing(name,&block)
|
37
37
|
Botfly.logger.info("#{@obj.to_debug_s}: Bot#on")
|
38
|
-
klass = Botfly.const_get(@obj.class_prefix + name.to_s.capitalize + "Responder")
|
38
|
+
klass = Botfly.const_get(@obj.class_prefix + name.to_s.split('_').map(&:capitalize).join + "Responder")
|
39
39
|
(@obj.responders[name] ||= []) << responder = klass.new(@obj, &block)
|
40
40
|
Botfly.logger.info("#{@obj.to_debug_s}: #{@obj.class_prefix}#{name.to_s.capitalize}Responder added to responder chain")
|
41
41
|
return responder
|
data/lib/botfly/matcher.rb
CHANGED
@@ -3,7 +3,6 @@ require 'botfly/matcher/matcher'
|
|
3
3
|
require 'botfly/matcher/nick_matcher'
|
4
4
|
require 'botfly/matcher/body_matcher'
|
5
5
|
require 'botfly/matcher/subject_matcher'
|
6
|
-
|
7
6
|
require 'botfly/matcher/muc_nick_matcher'
|
8
7
|
require 'botfly/matcher/muc_text_matcher'
|
9
8
|
require 'botfly/matcher/muc_time_matcher'
|
data/lib/botfly/muc_client.rb
CHANGED
@@ -45,7 +45,7 @@ module Botfly
|
|
45
45
|
@muc = Jabber::MUC::SimpleMUCClient.new(@bot.client)
|
46
46
|
register_for_callbacks
|
47
47
|
@jid = Jabber::JID.new("#{@room}@#{@domain}/#{@resource}")
|
48
|
-
@muc.join(@jid, nil, :history => false)
|
48
|
+
@muc.join(@jid,nil)#@muc.join(@jid, nil, :history => false)
|
49
49
|
Botfly.logger.info("MUC: Done connecting")
|
50
50
|
end
|
51
51
|
|
data/lib/botfly/responder.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
# TODO: Dry this up
|
2
1
|
require 'botfly/responder/common_responder_methods'
|
3
2
|
require 'botfly/responder/responder'
|
4
3
|
require 'botfly/responder/message_responder'
|
5
|
-
require 'botfly/responder/presence_responder'
|
6
4
|
require 'botfly/responder/muc_responder'
|
7
|
-
require 'botfly/responder/muc_message_responder'
|
8
5
|
require 'botfly/responder/subscription_request_responder'
|
@@ -1,16 +1,6 @@
|
|
1
1
|
module Botfly
|
2
2
|
class MessageResponder < Responder
|
3
3
|
extend Forwardable
|
4
|
-
def setup_instance_variables(params)
|
5
|
-
Botfly.logger.debug("RSP: MessageResponder setting up instance variables")
|
6
|
-
@message = params[:message]
|
7
|
-
@body = @message.body
|
8
|
-
@chat_state = @message.chat_state
|
9
|
-
@subject = @message.subject
|
10
|
-
@type = @message.type
|
11
|
-
@from = @message.from
|
12
|
-
@to = @message.to
|
13
|
-
end
|
14
4
|
|
15
5
|
def reply(text)
|
16
6
|
Botfly.logger.debug("RSP: MessageResponder#reply called")
|
@@ -6,22 +6,32 @@ module Botfly
|
|
6
6
|
|
7
7
|
attr_reader :callback, :callback_type, :id, :bot
|
8
8
|
def_delegator :@bot, :client
|
9
|
+
def_delegator :@bot, :quit
|
9
10
|
|
10
11
|
def initialize(bot,&block)
|
11
|
-
Botfly.logger.info("
|
12
|
+
Botfly.logger.info("RSP: #{self.class.to_s}#new")
|
12
13
|
@matcher_chain = []
|
13
14
|
@bot = bot
|
14
15
|
@callback = block if block_given?
|
15
16
|
@id = @@id += 1
|
16
17
|
end
|
17
18
|
|
19
|
+
##
|
20
|
+
# Allows for the nifty DSL that lets you chain matchers after specifying a callback type.
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# e.g. on.message.matcher1(:foo).matcher2(:bar) { ... }
|
24
|
+
#
|
25
|
+
# @param [String] method The name of the matcher to be added to the matcher chain
|
26
|
+
# @param condition The condition or set of conditions to be matched against when attempting execution.
|
27
|
+
# @return [self] Chain to your hearts content.
|
18
28
|
def method_missing(method,condition,&block)
|
19
|
-
Botfly.logger.info("
|
29
|
+
Botfly.logger.info("RSP: Responder##{method}(#{condition.inspect})")
|
20
30
|
|
21
31
|
add_matcher(method,condition)
|
22
32
|
|
23
33
|
if block_given?
|
24
|
-
Botfly.logger.info("
|
34
|
+
Botfly.logger.info("RSP: Callback recorded: #{block.inspect}")
|
25
35
|
@callback = block
|
26
36
|
return @id
|
27
37
|
end
|
@@ -29,32 +39,33 @@ module Botfly
|
|
29
39
|
return self
|
30
40
|
end
|
31
41
|
|
42
|
+
##
|
43
|
+
# Attempt to execute the callback on a responder. Only called if all matchers pass based on the supplied params
|
44
|
+
#
|
45
|
+
# @param [Hash] params The parameters necessary to execute the callback. Supplied by xmpp4r and pass through to here.
|
32
46
|
def callback_with(params)
|
33
|
-
Botfly.logger.debug("
|
47
|
+
Botfly.logger.debug("RSP: Launching callback with params: #{params.inspect}")
|
34
48
|
|
35
|
-
|
49
|
+
context = callback_context(params)
|
36
50
|
if @matcher_chain.all? {|matcher| matcher.match(params) }
|
37
|
-
Botfly.logger.debug("
|
51
|
+
Botfly.logger.debug("RSP: All matchers passed")
|
38
52
|
cb = @callback # Ruby makes it difficult to apply & to an instance variable
|
39
|
-
instance_eval &cb
|
53
|
+
context.instance_eval &cb
|
40
54
|
end
|
41
55
|
end
|
42
56
|
|
43
|
-
def quit
|
44
|
-
@bot.quit
|
45
|
-
end
|
46
57
|
# TODO: add other @client actions as delegates
|
47
58
|
|
48
59
|
private
|
49
60
|
def add_matcher(method, condition)
|
50
|
-
klass = Botfly.const_get(method.to_s.capitalize + "Matcher")
|
61
|
+
klass = Botfly.const_get(method.to_s.split('_').map(&:capitalize).join + "Matcher")
|
51
62
|
@matcher_chain << klass.new(condition)
|
52
63
|
|
53
|
-
Botfly.logger.debug("
|
64
|
+
Botfly.logger.debug("RSP: Adding to matcher chain: #{@matcher_chain.inspect}")
|
54
65
|
end
|
55
66
|
|
56
|
-
def
|
57
|
-
|
67
|
+
def callback_context(params)
|
68
|
+
Botfly::CallbackContext.new(self, params)
|
58
69
|
end
|
59
70
|
end
|
60
71
|
end
|
@@ -1,13 +1,6 @@
|
|
1
1
|
module Botfly
|
2
2
|
class SubscriptionRequestResponder < Responder
|
3
|
-
extend Forwardable
|
4
|
-
def setup_instance_variables(params)
|
5
|
-
Botfly.logger.debug(" RSP: SubscriptionRequestResponder setting up instance variables")
|
6
|
-
@roster_item = params[:roster_item]
|
7
|
-
@presence = params[:presence]
|
8
|
-
@from = @presence.from
|
9
|
-
end
|
10
|
-
|
3
|
+
extend Forwardable
|
11
4
|
def accept
|
12
5
|
@bot.roster.accept_subscription(@from)
|
13
6
|
end
|
data/spec/botfly/bot_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
include Botfly
|
4
4
|
describe Botfly::Bot do
|
@@ -29,13 +29,15 @@ describe Botfly::Bot do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#register_for_callbacks" do
|
32
|
-
|
33
|
-
before(:each) { stub_jabber_client }
|
32
|
+
subject { Bot.new('jid', 'pass') }
|
33
|
+
before(:each) { stub_jabber_client; }
|
34
|
+
after(:each) { subject.send(:register_for_callbacks)}
|
34
35
|
it "should register calls for each callback" do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
subject.instance_variable_set(:"@roster", mock("roster")) # I would prefer to do this elsewhere
|
37
|
+
subject.roster.should_receive :add_subscription_request_callback
|
38
|
+
subject.client.should_receive :add_presence_callback
|
39
|
+
subject.client.should_receive :add_message_callback
|
40
|
+
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include Botfly
|
4
|
+
describe CallbackContext do
|
5
|
+
let(:caller) { mock "Caller" }
|
6
|
+
let(:params) { Hash.new }
|
7
|
+
subject { CallbackContext.new(caller,params) }
|
8
|
+
|
9
|
+
it "should pass along unknown methods to the caller" do
|
10
|
+
caller.should_receive(:foo)
|
11
|
+
subject.foo
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should pass along complex method calls to the caller" do
|
15
|
+
caller.should_receive(:foo).with(:bar,:baz)
|
16
|
+
subject.foo(:bar,:baz)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#setup_params" do
|
20
|
+
it "should call setup for each parameter passed" do
|
21
|
+
subject.should_receive(:setup_message)
|
22
|
+
subject.send(:setup_params, {:message => :foo})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#expose" do
|
27
|
+
it "should define a method that returns value" do
|
28
|
+
subject.send(:expose, :foo, :bar)
|
29
|
+
subject.foo.should be :bar
|
30
|
+
end
|
31
|
+
it "should not define methods on the class" do
|
32
|
+
expect { CallbackContext.send(:expose, :foo, :bar) }.to raise_error NoMethodError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "private setup method" do
|
37
|
+
let(:presence) do
|
38
|
+
stub("Presence", :from => :from, :show => :show, :priority => :priority,
|
39
|
+
:status => :status, :type => :type)
|
40
|
+
end
|
41
|
+
let(:message) do
|
42
|
+
stub("Message", :body => :body, :to => :to, :from => :from,
|
43
|
+
:chat_state => :chat_state, :type => :type, :subject => subject)
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#setup_roster_item" do
|
47
|
+
subject { CallbackContext.new(caller,params) }
|
48
|
+
it { subject.respond_to?(:setup_roster_item, true).should be true }
|
49
|
+
it "should set up instance methods for supplied values" do
|
50
|
+
subject.send(:setup_roster_item, :foo)
|
51
|
+
subject.roster_item.should be :foo
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#setup_message" do
|
56
|
+
subject { CallbackContext.new(caller,params) }
|
57
|
+
it { subject.respond_to?(:setup_message, true).should be true }
|
58
|
+
it "should set up instance methods for supplied values" do
|
59
|
+
subject.send(:setup_message, message)
|
60
|
+
subject.message.should be message
|
61
|
+
subject.body.should be message.body
|
62
|
+
subject.to.should be message.to
|
63
|
+
subject.from.should be message.from
|
64
|
+
subject.chat_state.should be message.chat_state
|
65
|
+
subject.type.should be message.type
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#setup_presence" do
|
70
|
+
subject { CallbackContext.new(caller,params) }
|
71
|
+
it { subject.respond_to?(:setup_presence, true).should be true }
|
72
|
+
it "should set up instance methods for supplied values" do
|
73
|
+
subject.send(:setup_presence, presence)
|
74
|
+
subject.presence.should be :presence
|
75
|
+
subject.from.should be :from
|
76
|
+
subject.show.should be :show
|
77
|
+
subject.priority.should be :priority
|
78
|
+
subject.status.should be :status
|
79
|
+
subject.type.should be :type
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#setup_old_presence" do
|
84
|
+
subject { CallbackContext.new(caller,params) }
|
85
|
+
it { subject.respond_to?(:setup_old_presence, true).should be true }
|
86
|
+
it "should set up instance methods for supplied values" do
|
87
|
+
subject.send(:setup_old_presence, presence)
|
88
|
+
subject.old_presence.should be :presence
|
89
|
+
subject.old_from.should be :from
|
90
|
+
subject.old_show.should be :show
|
91
|
+
subject.old_priority.should be :priority
|
92
|
+
subject.old_status.should be :status
|
93
|
+
subject.old_type.should be :type
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#setup_time" do
|
98
|
+
subject { CallbackContext.new(caller,params) }
|
99
|
+
it { subject.respond_to?(:setup_time, true).should be true }
|
100
|
+
it "should set up instance methods for supplied values" do
|
101
|
+
subject.send(:setup_time, :foo)
|
102
|
+
subject.time.should be :foo
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#setup_nick" do
|
107
|
+
subject { CallbackContext.new(caller,params) }
|
108
|
+
it { subject.respond_to?(:setup_nick, true).should be true }
|
109
|
+
it "should set up instance methods for supplied values" do
|
110
|
+
subject.send(:setup_nick, :foo)
|
111
|
+
subject.from.should be :foo
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#setup_text" do
|
116
|
+
subject { CallbackContext.new(caller,params) }
|
117
|
+
it { subject.respond_to?(:setup_text, true).should be true }
|
118
|
+
it "should set up instance methods for supplied values" do
|
119
|
+
subject.send(:setup_text, :foo)
|
120
|
+
subject.text.should be :foo
|
121
|
+
subject.body.should be :foo
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -47,7 +47,7 @@ describe CommonBlockAcceptor do
|
|
47
47
|
context "::OnRecognizer" do
|
48
48
|
let(:acceptor) { CommonBlockAcceptor.new }
|
49
49
|
let(:on) { acceptor.on }
|
50
|
-
before(:
|
50
|
+
before(:all) do
|
51
51
|
class FooResponder; def initialize(bar); end; end
|
52
52
|
class FooBarResponder; def initialize(baz);end; end
|
53
53
|
end
|
@@ -56,7 +56,12 @@ describe CommonBlockAcceptor do
|
|
56
56
|
FooResponder.should_receive(:new)
|
57
57
|
on.foo
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
|
+
it "should turn snake_case into CamelCase" do
|
61
|
+
FooBarResponder.should_receive(:new)
|
62
|
+
on.foo_bar
|
63
|
+
end
|
64
|
+
|
60
65
|
it "should add class prefix to front of responder class" do
|
61
66
|
acceptor.stub(:class_prefix).and_return('Foo')
|
62
67
|
Botfly.should_receive(:const_get).with('FooBarResponder').and_return(FooBarResponder)
|
@@ -20,16 +20,18 @@ describe CommonResponderMethods do
|
|
20
20
|
before(:each) do
|
21
21
|
responder.bot.stub_chain(:jid,:domain => 'foo.com')
|
22
22
|
end
|
23
|
-
after(
|
23
|
+
after(:each) { responder.tell('foo@bar.baz/home', "message") }
|
24
24
|
subject { responder }
|
25
|
+
|
25
26
|
it "should pass the message along to the bot's jabber client" do
|
26
|
-
responder.client.should_receive
|
27
|
+
responder.client.should_receive(:send).with(an_instance_of(Jabber::Message))
|
27
28
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
|
30
|
+
it "should set the nickname and body appropriately in the message" do
|
31
|
+
responder.client.should_receive(:send) do |msg|
|
32
|
+
msg.to.to_s.should == 'foo@bar.baz/home'
|
33
|
+
msg.body.should == 'message'
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include Botfly
|
4
|
+
describe Botfly::Responder do
|
5
|
+
describe ".new" do
|
6
|
+
subject { Responder.new(mock("bot")) }
|
7
|
+
it { should assign :matcher_chain }
|
8
|
+
it { should assign :bot }
|
9
|
+
it { should_not assign :callback }
|
10
|
+
it "should assign callback if block given" do
|
11
|
+
proc = Proc.new {}
|
12
|
+
Responder.new(mock("bot"), &proc).should assign :callback
|
13
|
+
end
|
14
|
+
it "should give out incremental IDs" do
|
15
|
+
bot = mock("bot")
|
16
|
+
@id = Responder.new(bot).id
|
17
|
+
expect { @id = Responder.new(bot).id }.to change {@id}.by(1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "instance" do
|
22
|
+
let(:bot) { mock "bot" }
|
23
|
+
subject { Responder.new(bot) }
|
24
|
+
it "should delegate client to @bot" do
|
25
|
+
bot.should_receive :client
|
26
|
+
subject.client
|
27
|
+
end
|
28
|
+
it "should delegate quit to @bot" do
|
29
|
+
bot.should_receive :quit
|
30
|
+
subject.quit
|
31
|
+
end
|
32
|
+
it "should provide attr_reader for @bot" do
|
33
|
+
subject.bot.should be bot
|
34
|
+
end
|
35
|
+
it { should be_a CommonResponderMethods }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#method_missing" do
|
39
|
+
subject { Responder.new(mock("bot")) }
|
40
|
+
before(:all) { class FooMatchMatcher < Matcher; end }
|
41
|
+
it "should add matcher" do
|
42
|
+
subject.should_receive(:add_matcher).with(:foo_match,:bar)
|
43
|
+
subject.foo_match(:bar)
|
44
|
+
end
|
45
|
+
it "should assign callback if block given" do
|
46
|
+
expect { subject.foo_match(:bar) { :baz } }.to change { subject.instance_variable_get(:'@callback') }
|
47
|
+
end
|
48
|
+
it "should return self" do
|
49
|
+
subject.foo_match(:bar).should be subject
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#add_matcher" do
|
54
|
+
subject { Responder.new(mock("bot")) }
|
55
|
+
before(:all) { class FooBarMatcher; def initialize(*args); end; end }
|
56
|
+
it "should map matcher name to proper class" do
|
57
|
+
FooBarMatcher.should_receive(:new)
|
58
|
+
subject.send(:add_matcher, :foo_bar, :baz)
|
59
|
+
end
|
60
|
+
it "should add instanciated matcher to matcher chain" do
|
61
|
+
expect { subject.send(:add_matcher, :foo_bar, :baz) }.to change { subject.instance_variable_get(:'@matcher_chain').count }.by(1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#callback_with" do
|
66
|
+
subject { Responder.new(mock "bot") }
|
67
|
+
let(:params) { double "params" }
|
68
|
+
after(:each) { subject.callback_with(params) }
|
69
|
+
it "should create callback context" do
|
70
|
+
CallbackContext.should_receive(:new).with(subject, params)
|
71
|
+
subject.instance_variable_set(:"@callback", Proc.new {} )
|
72
|
+
end
|
73
|
+
it "should execute callback in created context" do
|
74
|
+
context = mock("Context", :foo => :bar)
|
75
|
+
CallbackContext.should_receive(:new).and_return(context)
|
76
|
+
context.should_receive(:instance_eval)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#callback_context" do
|
81
|
+
specify { Responder.new(mock("bot")).send(:callback_context, {}).should be_a CallbackContext }
|
82
|
+
end
|
83
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 4
|
9
|
+
version: 0.3.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ryan Neufeld
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-10 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- example.rb
|
66
66
|
- lib/botfly.rb
|
67
67
|
- lib/botfly/bot.rb
|
68
|
+
- lib/botfly/callback_context.rb
|
68
69
|
- lib/botfly/common_block_acceptor.rb
|
69
70
|
- lib/botfly/matcher.rb
|
70
71
|
- lib/botfly/matcher/body_matcher.rb
|
@@ -78,13 +79,12 @@ files:
|
|
78
79
|
- lib/botfly/responder.rb
|
79
80
|
- lib/botfly/responder/common_responder_methods.rb
|
80
81
|
- lib/botfly/responder/message_responder.rb
|
81
|
-
- lib/botfly/responder/muc_message_responder.rb
|
82
82
|
- lib/botfly/responder/muc_responder.rb
|
83
|
-
- lib/botfly/responder/presence_responder.rb
|
84
83
|
- lib/botfly/responder/responder.rb
|
85
84
|
- lib/botfly/responder/subscription_request_responder.rb
|
86
85
|
- retrobot.rb
|
87
86
|
- spec/botfly/bot_spec.rb
|
87
|
+
- spec/botfly/callback_context_spec.rb
|
88
88
|
- spec/botfly/common_block_acceptor_spec.rb
|
89
89
|
- spec/botfly/matcher/body_matcher_spec.rb
|
90
90
|
- spec/botfly/matcher/matcher_spec.rb
|
@@ -96,9 +96,7 @@ files:
|
|
96
96
|
- spec/botfly/muc_client_spec.rb
|
97
97
|
- spec/botfly/responder/common_responder_methods_spec.rb
|
98
98
|
- spec/botfly/responder/message_responder_spec.rb
|
99
|
-
- spec/botfly/responder/muc_message_responder_spec.rb
|
100
99
|
- spec/botfly/responder/muc_responder_spec.rb
|
101
|
-
- spec/botfly/responder/presence_responder_spec.rb
|
102
100
|
- spec/botfly/responder/responder_spec.rb
|
103
101
|
- spec/botfly/responder/subscription_request_responder_spec.rb
|
104
102
|
- spec/botfly_spec.rb
|
@@ -138,6 +136,7 @@ specification_version: 3
|
|
138
136
|
summary: A quick and easy DSL for generating Jabber bots
|
139
137
|
test_files:
|
140
138
|
- spec/botfly/bot_spec.rb
|
139
|
+
- spec/botfly/callback_context_spec.rb
|
141
140
|
- spec/botfly/common_block_acceptor_spec.rb
|
142
141
|
- spec/botfly/matcher/body_matcher_spec.rb
|
143
142
|
- spec/botfly/matcher/matcher_spec.rb
|
@@ -149,9 +148,7 @@ test_files:
|
|
149
148
|
- spec/botfly/muc_client_spec.rb
|
150
149
|
- spec/botfly/responder/common_responder_methods_spec.rb
|
151
150
|
- spec/botfly/responder/message_responder_spec.rb
|
152
|
-
- spec/botfly/responder/muc_message_responder_spec.rb
|
153
151
|
- spec/botfly/responder/muc_responder_spec.rb
|
154
|
-
- spec/botfly/responder/presence_responder_spec.rb
|
155
152
|
- spec/botfly/responder/responder_spec.rb
|
156
153
|
- spec/botfly/responder/subscription_request_responder_spec.rb
|
157
154
|
- spec/botfly_spec.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Botfly
|
2
|
-
class PresenceResponder < Responder
|
3
|
-
def setup_instance_variables(params)
|
4
|
-
Botfly.logger.debug(" RSP: #{self.class} setting up instance variables")
|
5
|
-
|
6
|
-
# TODO: Figure out how xmpp works with presence messages so I know what to expect
|
7
|
-
if params[:new]
|
8
|
-
@presence = params[:new]
|
9
|
-
@from = @presence.from
|
10
|
-
@show = @presence.show
|
11
|
-
@priority = @presence.priority
|
12
|
-
@status = @presence.status
|
13
|
-
@type = @presence.type
|
14
|
-
end
|
15
|
-
|
16
|
-
if params[:old]
|
17
|
-
@old_presence = params[:old]
|
18
|
-
@old_status = @old_presence.status
|
19
|
-
@old_priority = @old_presence.priority
|
20
|
-
@old_type = @old_presence.type
|
21
|
-
@old_show = @old_presence.show
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
File without changes
|
File without changes
|