botfly 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/TODO +23 -0
  2. data/VERSION +1 -1
  3. data/botfly.gemspec +5 -8
  4. data/lib/botfly.rb +6 -0
  5. data/lib/botfly/bot.rb +1 -1
  6. data/lib/botfly/callback_context.rb +45 -0
  7. data/lib/botfly/common_block_acceptor.rb +1 -1
  8. data/lib/botfly/matcher.rb +0 -1
  9. data/lib/botfly/muc_client.rb +1 -1
  10. data/lib/botfly/responder.rb +0 -3
  11. data/lib/botfly/responder/common_responder_methods.rb +1 -1
  12. data/lib/botfly/responder/message_responder.rb +0 -10
  13. data/lib/botfly/responder/responder.rb +25 -14
  14. data/lib/botfly/responder/subscription_request_responder.rb +1 -8
  15. data/spec/botfly/bot_spec.rb +9 -7
  16. data/spec/botfly/callback_context_spec.rb +125 -0
  17. data/spec/botfly/common_block_acceptor_spec.rb +7 -2
  18. data/spec/botfly/matcher/body_matcher_spec.rb +6 -0
  19. data/spec/botfly/matcher/matcher_spec.rb +6 -0
  20. data/spec/botfly/matcher/muc_nick_matcher_spec.rb +6 -0
  21. data/spec/botfly/matcher/muc_text_matcher_spec.rb +6 -0
  22. data/spec/botfly/matcher/muc_time_matcher_spec.rb +6 -0
  23. data/spec/botfly/matcher/nick_matcher_spec.rb +6 -0
  24. data/spec/botfly/matcher/subject_matcher_spec.rb +6 -0
  25. data/spec/botfly/responder/common_responder_methods_spec.rb +9 -7
  26. data/spec/botfly/responder/message_responder_spec.rb +6 -0
  27. data/spec/botfly/responder/muc_responder_spec.rb +6 -0
  28. data/spec/botfly/responder/responder_spec.rb +83 -0
  29. data/spec/botfly/responder/subscription_request_responder_spec.rb +6 -0
  30. metadata +6 -9
  31. data/lib/botfly/responder/muc_message_responder.rb +0 -4
  32. data/lib/botfly/responder/presence_responder.rb +0 -25
  33. data/spec/botfly/responder/muc_message_responder_spec.rb +0 -0
  34. 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.3
1
+ 0.3.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{botfly}
8
- s.version = "0.3.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-05}
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",
@@ -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'
@@ -50,7 +50,7 @@ module Botfly
50
50
  end
51
51
 
52
52
  @client.add_presence_callback do |new_presence,old_presence|
53
- respond_to(:preesence, :old => old_presence, :new => new_presence)
53
+ respond_to(:preesence, :old_presence => old_presence, :presence => new_presence)
54
54
  end
55
55
 
56
56
  end
@@ -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
@@ -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'
@@ -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
 
@@ -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,6 +1,6 @@
1
1
  module Botfly
2
2
  module CommonResponderMethods
3
- def send(nick, message, opts = {})
3
+ def tell(nick, message, opts = {})
4
4
  Botfly.logger.debug("RSP: Sending message")
5
5
 
6
6
  # Fix the nickname if no domain/resource was given by adding your domain
@@ -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(" RSP: #{self.class.to_s}#new")
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(" RSP: Responder##{method}(#{condition.inspect})")
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(" RSP: Callback recorded: #{block.inspect}")
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(" RSP: Launching callback with params: #{params.inspect}")
47
+ Botfly.logger.debug("RSP: Launching callback with params: #{params.inspect}")
34
48
 
35
- setup_instance_variables(params)
49
+ context = callback_context(params)
36
50
  if @matcher_chain.all? {|matcher| matcher.match(params) }
37
- Botfly.logger.debug(" RSP: All matchers passed")
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(" RSP: Adding to matcher chain: #{@matcher_chain.inspect}")
64
+ Botfly.logger.debug("RSP: Adding to matcher chain: #{@matcher_chain.inspect}")
54
65
  end
55
66
 
56
- def setup_instance_variables(params)
57
- raise "AbstractMethodError: You must implement this method in a concrete subclass"
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
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
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
- let(:bot) { Bot.new('jid', 'pass') }
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
- bot.roster.should_receive :add_subscription_request_callback
36
- bot.client.should_receive :add_presence_callback
37
- bot.client.should_receive :add_message_callback
38
- bot.send(:register_for_callbacks)
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(:each) do
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)
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::BodyMatcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::Matcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::MUCNickMatcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::MUCTextMatcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::MUCTimeMatcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::NickMatcher do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::SubjectMatcher do
5
+ it "should be tested"
6
+ end
@@ -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( :each) { responder.send ('bar', "message")}
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 :send
27
+ responder.client.should_receive(:send).with(an_instance_of(Jabber::Message))
27
28
  end
28
- it "should pass the string given as a the message's body" do
29
- pending
30
- end
31
- it "should pass the nickname given as the message's destination" do
32
- pending
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,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::MessageResponder do
5
+ it "should be tested"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::MUCResponder do
5
+ it "should be tested"
6
+ 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
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ include Botfly
4
+ describe Botfly::SubscriptionRequestResponder do
5
+ it "should be tested"
6
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 3
9
- version: 0.3.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-05 00:00:00 -05:00
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,4 +0,0 @@
1
- module Botfly
2
- class MUCMessageResponder < MUCResponder
3
- end
4
- end
@@ -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