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.
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