campfire-bot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/.autotest +11 -0
  2. data/.gitignore +6 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +57 -0
  5. data/README.textile +52 -0
  6. data/TODO +72 -0
  7. data/bin/bot +13 -0
  8. data/campfire-bot.gemspec +27 -0
  9. data/cfbot-stop.sh +8 -0
  10. data/config.example.yml +31 -0
  11. data/lib/bot.rb +194 -0
  12. data/lib/event.rb +114 -0
  13. data/lib/message.rb +30 -0
  14. data/lib/plugin.rb +77 -0
  15. data/lib/version.rb +3 -0
  16. data/plugins/accountability.rb +45 -0
  17. data/plugins/austin.rb +29 -0
  18. data/plugins/basecamp.rb +48 -0
  19. data/plugins/beer.rb +214 -0
  20. data/plugins/beijing_tally.rb +30 -0
  21. data/plugins/boop.rb +127 -0
  22. data/plugins/bruce.rb +15 -0
  23. data/plugins/bugzilla.rb +198 -0
  24. data/plugins/calvin.rb +43 -0
  25. data/plugins/chuck.rb +23 -0
  26. data/plugins/dilbert.rb +51 -0
  27. data/plugins/excuse.rb +478 -0
  28. data/plugins/fail.rb +16 -0
  29. data/plugins/figlet.rb +10 -0
  30. data/plugins/fun.rb +95 -0
  31. data/plugins/garfield.rb +43 -0
  32. data/plugins/generic_search.rb +66 -0
  33. data/plugins/help.rb +13 -0
  34. data/plugins/infobot.rb +58 -0
  35. data/plugins/insult.rb +87 -0
  36. data/plugins/jira.rb +197 -0
  37. data/plugins/lolcats.rb +17 -0
  38. data/plugins/our_quotes.rb +195 -0
  39. data/plugins/quote.rb +31 -0
  40. data/plugins/schneier.rb +28 -0
  41. data/plugins/seen.rb +88 -0
  42. data/plugins/signal_filter.rb +9 -0
  43. data/plugins/svn.rb +167 -0
  44. data/plugins/twitter_echo.rb +54 -0
  45. data/plugins/unfuddle.rb +69 -0
  46. data/plugins/weather.rb +25 -0
  47. data/plugins/xkcd.rb +43 -0
  48. data/spec/beer_spec.rb +224 -0
  49. data/spec/bugzilla_spec.rb +90 -0
  50. data/spec/command_spec.rb +96 -0
  51. data/spec/jira_spec.rb +264 -0
  52. data/spec/our_quotes_spec.rb +186 -0
  53. data/spec/plugin_spec.rb +43 -0
  54. data/spec/spec.opts +1 -0
  55. data/vendor/escape/ChangeLog +30 -0
  56. data/vendor/escape/Makefile +5 -0
  57. data/vendor/escape/README +81 -0
  58. data/vendor/escape/VERSION +1 -0
  59. data/vendor/escape/escape.rb +302 -0
  60. data/vendor/escape/install.rb +109 -0
  61. data/vendor/escape/misc/README.erb +85 -0
  62. data/vendor/escape/rdoc/classes/Escape.html +427 -0
  63. data/vendor/escape/rdoc/classes/Escape.src/M000022.html +19 -0
  64. data/vendor/escape/rdoc/classes/Escape.src/M000023.html +32 -0
  65. data/vendor/escape/rdoc/classes/Escape.src/M000024.html +24 -0
  66. data/vendor/escape/rdoc/classes/Escape.src/M000025.html +19 -0
  67. data/vendor/escape/rdoc/classes/Escape.src/M000026.html +48 -0
  68. data/vendor/escape/rdoc/classes/Escape.src/M000027.html +19 -0
  69. data/vendor/escape/rdoc/classes/Escape.src/M000028.html +19 -0
  70. data/vendor/escape/rdoc/classes/Escape/HTMLAttrValue.html +113 -0
  71. data/vendor/escape/rdoc/classes/Escape/HTMLEscaped.html +113 -0
  72. data/vendor/escape/rdoc/classes/Escape/PercentEncoded.html +113 -0
  73. data/vendor/escape/rdoc/classes/Escape/ShellEscaped.html +113 -0
  74. data/vendor/escape/rdoc/classes/Escape/StringWrapper.html +242 -0
  75. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000029.html +18 -0
  76. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000030.html +18 -0
  77. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000031.html +18 -0
  78. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000032.html +18 -0
  79. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000033.html +18 -0
  80. data/vendor/escape/rdoc/classes/Escape/StringWrapper.src/M000035.html +18 -0
  81. data/vendor/escape/rdoc/classes/TestEscapeHTML.html +182 -0
  82. data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000008.html +18 -0
  83. data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000009.html +18 -0
  84. data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000010.html +18 -0
  85. data/vendor/escape/rdoc/classes/TestEscapeHTML.src/M000011.html +18 -0
  86. data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.html +182 -0
  87. data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000012.html +18 -0
  88. data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000013.html +19 -0
  89. data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000014.html +20 -0
  90. data/vendor/escape/rdoc/classes/TestEscapePercentEncoded.src/M000015.html +22 -0
  91. data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.html +167 -0
  92. data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000016.html +18 -0
  93. data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000017.html +20 -0
  94. data/vendor/escape/rdoc/classes/TestEscapeShellEscaped.src/M000018.html +20 -0
  95. data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.html +167 -0
  96. data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000019.html +20 -0
  97. data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000020.html +24 -0
  98. data/vendor/escape/rdoc/classes/TestEscapeStringWrapper.src/M000021.html +22 -0
  99. data/vendor/escape/rdoc/files/escape_rb.html +136 -0
  100. data/vendor/escape/rdoc/files/install_rb.html +250 -0
  101. data/vendor/escape/rdoc/files/install_rb.src/M000001.html +23 -0
  102. data/vendor/escape/rdoc/files/install_rb.src/M000002.html +31 -0
  103. data/vendor/escape/rdoc/files/install_rb.src/M000003.html +27 -0
  104. data/vendor/escape/rdoc/files/install_rb.src/M000004.html +27 -0
  105. data/vendor/escape/rdoc/files/install_rb.src/M000005.html +21 -0
  106. data/vendor/escape/rdoc/files/install_rb.src/M000006.html +23 -0
  107. data/vendor/escape/rdoc/files/install_rb.src/M000007.html +21 -0
  108. data/vendor/escape/rdoc/files/test/test-escape_rb.html +109 -0
  109. data/vendor/escape/rdoc/fr_class_index.html +36 -0
  110. data/vendor/escape/rdoc/fr_file_index.html +29 -0
  111. data/vendor/escape/rdoc/fr_method_index.html +61 -0
  112. data/vendor/escape/rdoc/index.html +24 -0
  113. data/vendor/escape/rdoc/rdoc-style.css +208 -0
  114. data/vendor/escape/test/test-escape.rb +90 -0
  115. metadata +259 -0
@@ -0,0 +1,96 @@
1
+ require 'spec'
2
+ BOT_ROOT = File.join(File.dirname(__FILE__), '..')
3
+ BOT_ENVIRONMENT = 'development'
4
+
5
+ require File.join(File.dirname(__FILE__), '../lib/bot.rb')
6
+ bot = CampfireBot::Bot.instance
7
+ require "#{BOT_ROOT}/lib/event.rb"
8
+
9
+
10
+ class TestingCommand < CampfireBot::Event::Command
11
+
12
+ def filter_message(msg)
13
+ super
14
+ end
15
+ end
16
+
17
+ describe "processing messages" do
18
+
19
+ before(:all) do
20
+ bot = CampfireBot::Bot.instance
21
+ @nickname = bot.config['nickname']
22
+ end
23
+
24
+ before(:each) do
25
+ @command = TestingCommand.new("command", nil, nil)
26
+ end
27
+
28
+ def match?(msg)
29
+ @command.match?({:message => msg})
30
+ end
31
+
32
+ describe "and recognizing a command" do
33
+
34
+ it "should handle a !command" do
35
+ match?("!command").should be_true
36
+ end
37
+
38
+ it "should handle a !command with arguments" do
39
+ match?("!command foo").should be_true
40
+ end
41
+
42
+ it "should handle a command with nickname and a comma" do
43
+ match?("#{@nickname}, command").should be_true
44
+ end
45
+
46
+ it "should handle a command with nickname and a colon" do
47
+ match?("#{@nickname}: command").should be_true
48
+ end
49
+
50
+ it "should handle a command with nickname and arguments" do
51
+ match?("#{@nickname}, command foo").should be_true
52
+ end
53
+
54
+ it "should ignore a non-matching !command" do
55
+ match?("!foo").should be_false
56
+ end
57
+
58
+ it "should ignore an addressed non-command" do
59
+ match?("#{@nickname}, nothing").should be_false
60
+ end
61
+
62
+ it "should ignore things that aren't commands at all" do
63
+ ["nothing", "#{@nickname}, ", " ! command", "hey #{@nickname}", "!command!command", "!command,command"].each do |t|
64
+ match?(t).should be_false
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "and filtering it" do
70
+
71
+ def filter(msg)
72
+ @command.filter_message({:message => msg})[:message]
73
+ end
74
+
75
+ it "should be empty with no arguments" do
76
+ filter("!command").should == ""
77
+ filter("#{@nickname}, command").should == ""
78
+ end
79
+
80
+ it "should return one argument" do
81
+ filter("!command foo").should == "foo"
82
+ filter("#{@nickname}, command foo").should == "foo"
83
+ end
84
+
85
+ it "should return more than one argument" do
86
+ filter("!command foo bar baz").should == "foo bar baz"
87
+ filter("#{@nickname}, command foo bar baz").should == "foo bar baz"
88
+ end
89
+
90
+ it "should deal with some weirdness" do
91
+ filter("!command !command").should == "!command"
92
+ end
93
+
94
+ end
95
+ end
96
+
@@ -0,0 +1,264 @@
1
+ require 'spec'
2
+ require 'rubygems'
3
+ require 'xmlsimple'
4
+
5
+ BOT_ROOT = File.join(File.dirname(__FILE__), '..')
6
+ BOT_ENVIRONMENT = 'development'
7
+
8
+ require File.join(File.dirname(__FILE__), '../lib/bot.rb')
9
+ bot = CampfireBot::Bot.instance
10
+ require "#{BOT_ROOT}/plugins/jira.rb"
11
+
12
+
13
+ class SpecMessage < CampfireBot::Message
14
+ attr_reader :response
15
+
16
+ #overwrite message.speak method so that we can expose the output
17
+ def speak(msg)
18
+ puts "specmessage.speak(#{msg})"
19
+ @response = msg
20
+ end
21
+
22
+ end
23
+
24
+ class SpecJira < CampfireBot::Plugin::Jira
25
+ attr_accessor :cached_ids, :last_checked
26
+ end
27
+
28
+
29
+
30
+ describe "checking jira and" do
31
+
32
+
33
+ # send a message to the room and return the response
34
+ def sendmsg(msg)
35
+ # puts "sendmsg(#{msg})"
36
+ @message[:message] = msg
37
+ @message[:room] = mock('room', :name => 'test')
38
+ bot.send(:handle_message, @message)
39
+ # puts "sendmsg returns #{@message.response}"
40
+ @message.response
41
+ end
42
+
43
+ # instantiate the bot and the plugin fresh
44
+
45
+ def setup
46
+ bot = CampfireBot::Bot.instance
47
+ bot.stub!(:config).and_return({'nickname' => 'Bot', 'jira_url' => 'foo'})
48
+ YAML.stub!(:load).and_return {}
49
+ YAML.stub!(:dump).and_return true
50
+
51
+
52
+
53
+ @jira = SpecJira.new()
54
+ CampfireBot::Plugin.registered_plugins['Jira'] = @jira
55
+ @jira.cached_ids = {}
56
+ @jira.last_checked = 15.minutes.ago
57
+ @message = nil
58
+ end
59
+
60
+ def jira_response(ticketarray)
61
+
62
+ jira_hash = {'rss' => {'channel' => [] }}
63
+
64
+ ticketarray.each do |ticket|
65
+ ticket.merge!({'description' => 'foo',
66
+ 'link' => "http://oz/jira/browse/#{ticket['key']}",
67
+ 'title' => 'foo',
68
+ 'reporter' => 'foo',
69
+ 'priority' => 'Critical',
70
+ 'type' => 'Bug'})
71
+
72
+ jira_hash['rss']['channel'] << {'item' => ticket }
73
+ end
74
+
75
+ @message = SpecMessage.new(:person => 'Josh', :room => mock('room', :name => 'test'))
76
+
77
+ xmldata = XmlSimple.xml_out(jira_hash, {'NoAttr' => true, 'RootName' => nil})
78
+
79
+ @jira.stub!(:open).and_return(mock('foo', :read => xmldata))
80
+
81
+ @jira.check_jira(@message)
82
+ end
83
+
84
+ describe "seeing a ticket higher than the last stored id" do
85
+
86
+ before(:all) do
87
+ setup
88
+ jira_response([{
89
+ 'key' => 'PIM-123',
90
+ 'description' => 'foo',
91
+ 'link' => 'http://oz/jira/browse/PIM-123',
92
+ 'title' => 'foo',
93
+ 'reporter' => 'foo',
94
+ 'priority' => 'Critical',
95
+ 'type' => 'Bug',
96
+ 'updated' => 5.minutes.ago.to_s
97
+ }])
98
+
99
+ @jira.last_checked = 5.minutes.ago
100
+ jira_response([{
101
+ 'key' => 'PIM-124',
102
+ 'description' => 'foo',
103
+ 'link' => 'http://oz/jira/browse/PIM-124',
104
+ 'title' => 'foo',
105
+ 'reporter' => 'foo',
106
+ 'priority' => 'Critical',
107
+ 'type' => 'Bug',
108
+ 'updated' => 3.minutes.ago.to_s
109
+ }])
110
+ end
111
+
112
+ it "should update the cached highest id" do
113
+ @jira.cached_ids['PIM'].should eql(124)
114
+ end
115
+
116
+ it "should speak the info of the ticket" do
117
+ @message.response.should match(/PIM-124/)
118
+ end
119
+
120
+
121
+ end
122
+
123
+ describe "seeing a ticket we've already seen" do
124
+
125
+ before(:all) do
126
+ setup
127
+ jira_response([{
128
+ 'key' => 'PIM-123',
129
+
130
+ 'updated' => Time.now().to_s
131
+ }])
132
+
133
+ jira_response([{
134
+ 'key' => 'PIM-123',
135
+ 'description' => 'foo',
136
+ 'link' => 'http://oz/jira/browse/PIM-123',
137
+ 'title' => 'foo',
138
+ 'reporter' => 'foo',
139
+ 'priority' => 'Critical',
140
+ 'type' => 'Bug',
141
+ 'updated' => Time.now().to_s
142
+ }])
143
+ end
144
+
145
+ it "should be quiet" do
146
+ @message.response.should be(nil)
147
+ end
148
+
149
+ it "should not change the list of cached ids" do
150
+ @jira.cached_ids.size.should eql(1)
151
+ end
152
+
153
+
154
+ end
155
+
156
+ describe "seeing a ticket whose ID is lower than the highest seen id" do
157
+ before(:all) do
158
+ setup
159
+ jira_response([{
160
+ 'key' => 'PIM-123',
161
+ 'updated' => 5.minutes.ago.to_s
162
+ }])
163
+
164
+ @jira.last_checked = 3.minutes.ago
165
+
166
+ jira_response([{
167
+ 'key' => 'PIM-120',
168
+ 'updated' => Time.now().to_s
169
+ }])
170
+
171
+ end
172
+
173
+ it "should be quiet" do
174
+ @message.response.should be(nil)
175
+ end
176
+
177
+ end
178
+
179
+ describe "seeing a space we've never seen before" do
180
+ before(:all) do
181
+ setup
182
+ jira_response([{
183
+ 'key' => 'PIM-123',
184
+ 'updated' => 5.minutes.ago.to_s
185
+ }])
186
+
187
+ @jira.last_checked = 5.minutes.ago
188
+ jira_response([{
189
+ 'key' => 'FOO-124',
190
+ 'updated' => 3.minutes.ago.to_s
191
+ }])
192
+ end
193
+
194
+ it "should update the cached highest id" do
195
+ @jira.cached_ids['FOO'].should eql(124)
196
+ end
197
+
198
+ it "should speak the info of the ticket" do
199
+ @message.response.should match(/FOO-124/)
200
+ end
201
+ end
202
+
203
+ describe "getting a bunch of tickets in one go" do
204
+ before(:all) do
205
+ setup
206
+ end
207
+
208
+ it "with all new" do
209
+ @jira.cached_ids = {}
210
+
211
+ msg = SpecMessage.new(:person => 'Josh', :room => mock('room', :name => 'test'))
212
+ SpecMessage.should_receive(:new).and_return(msg)
213
+ msg.should_receive(:speak).twice
214
+
215
+ jira_response([{
216
+ 'key' => 'PIM-1124',
217
+ 'updated' => 5.minutes.ago.to_s
218
+ },
219
+ {'key' => 'PIM-1123',
220
+ 'updated' => 5.minutes.ago.to_s}])
221
+ @jira.cached_ids['PIM'].should eql(1124)
222
+
223
+ end
224
+
225
+ it "with a mix of old and new" do
226
+ msg = SpecMessage.new(:person => 'Josh', :room => mock('room', :name => 'test'))
227
+ SpecMessage.should_receive(:new).and_return(msg)
228
+ msg.should_receive(:speak).twice
229
+
230
+ @jira.cached_ids['PIM'] = 1124
231
+ jira_response([{
232
+ 'key' => 'PIM-1126',
233
+ 'updated' => 5.minutes.ago.to_s
234
+ },
235
+ {
236
+ 'key' => 'PIM-1125',
237
+ 'updated' => 5.minutes.ago.to_s
238
+ },
239
+ {
240
+ 'key' => 'PIM-1124',
241
+ 'updated' => 5.minutes.ago.to_s
242
+ }
243
+ ])
244
+ @jira.cached_ids['PIM'].should eql(1126)
245
+ end
246
+
247
+ it "with all old" do
248
+ @jira.cached_ids['PIM'] = 1125
249
+ jira_response([{
250
+ 'key' => 'PIM-1125',
251
+ 'updated' => 5.minutes.ago.to_s
252
+ },
253
+ {'key' => 'PIM-1124',
254
+ 'updated' => 5.minutes.ago.to_s}])
255
+ @jira.cached_ids['PIM'].should eql(1125)
256
+ end
257
+
258
+
259
+
260
+
261
+ end
262
+
263
+ end
264
+
@@ -0,0 +1,186 @@
1
+ require 'spec'
2
+ BOT_ROOT = File.join(File.dirname(__FILE__), '..')
3
+ BOT_ENVIRONMENT = 'test'
4
+
5
+ require File.join(File.dirname(__FILE__), '../lib/bot.rb')
6
+ bot = CampfireBot::Bot.instance
7
+ require "#{BOT_ROOT}/plugins/our_quotes.rb"
8
+
9
+ describe "OurQuotes plugin" do
10
+
11
+ it "should remember added quotes" do
12
+ when_saying "!addquote Someone: Hello world."
13
+ bot_should_reply "Added quote #1."
14
+ quotes[0].should == "Someone: Hello world."
15
+ end
16
+
17
+ it "should complain when !addquote is given without a quote" do
18
+ when_saying "!addquote"
19
+ bot_should_reply "Please include the text of the quote and attribution."
20
+ quotes.size.should == 0
21
+ end
22
+
23
+ it "should regurgitate random quotes" do
24
+ with_quote_log {
25
+ add "Someone: Hello world."
26
+ }
27
+ when_saying "!quote"
28
+ # How to show attribution, index, room, and timestamp?
29
+ #bot_should_reply "Someone spake thusly: Hello world"
30
+ # "Foo quoth thither
31
+ bot_should_reply "#1 Someone: Hello world."
32
+ end
33
+
34
+ it "should find matching quotes" do
35
+ with_quote_log {
36
+ add "Anyone: Hello world."
37
+ add "Someone: Hello world."
38
+ del 1
39
+ add "Someone: It's too cold."
40
+ }
41
+ when_saying "!quote o w"
42
+ bot_should_reply "#2 Someone: Hello world. (1 match)"
43
+ end
44
+
45
+ it "should use proper grammer when showing number of matches" do
46
+ with_quote_log {
47
+ add "Anyone: hi!"
48
+ add "Anyone: bye."
49
+ }
50
+ when_saying "!quote Anyone"
51
+ bot_should_reply %r/ \(2 matches\)$/
52
+ end
53
+
54
+ it "should retrieve quotes by ID when the query is numeric" do
55
+ with_quote_log {
56
+ add "Anyone: 2+2"
57
+ add "Anyone: hi!"
58
+ }
59
+ when_saying "!quote 2"
60
+ bot_should_reply "#2 Anyone: hi!"
61
+ end
62
+
63
+ it "should display an explanation when !quote is given an invalid ID" do
64
+ when_saying "!quote 1"
65
+ bot_should_reply "No quote #1."
66
+ end
67
+
68
+ # Implementation idea: save array of matches in a hash
69
+ # keyed by query and perhaps user. Should expire after
70
+ # a few minutes, so don't bother persisting it even to tmp/.
71
+ it "should iterate through results on repeat command" do
72
+ pending
73
+ with_quote_log {
74
+ add "Someone: Foo"
75
+ add "Someone: Bar"
76
+ add "Someone: Baz"
77
+ }
78
+ when_saying "!quote Someone"
79
+ bot_should_reply %r/#\d Someone: ... \(3 matches\)$/
80
+ when_saying "!quote Someone"
81
+ bot_should_reply %r/#\d Someone: ... \(2 of 3 matches\)$/
82
+ when_saying "!quote Someone"
83
+ bot_should_reply %r/#\d Someone: ... \(3 of 3 matches\)$/
84
+ # Or maybe (3 matches, none left) ?
85
+ end
86
+
87
+ it "should remove last quote upon request" do
88
+ with_quote_log {
89
+ add "Hello world."
90
+ }
91
+ when_saying "!rmquote 1"
92
+ bot_should_reply "Deleted quote #1."
93
+ @quote.quotes.size.should == 0
94
+ end
95
+
96
+ it "should free trailing IDs when removing quotes" do
97
+ with_quote_log {
98
+ add "One"
99
+ add "Two"
100
+ add "Three"
101
+ add "Four"
102
+ del 3
103
+ del 4
104
+ add "III"
105
+ }
106
+ quotes[3 - 1].should == "III"
107
+ end
108
+
109
+ it "should preserve IDs of quotes after the removed one" do
110
+ with_quote_log {
111
+ add "One"
112
+ add "Two"
113
+ add "Three"
114
+ del 2
115
+ }
116
+ quotes[3 - 1].should == "Three"
117
+ end
118
+
119
+ it "should display an explanation when !rmquote is given an invalid ID" do
120
+ when_saying "!rmquote 1"
121
+ bot_should_reply "No quote #1."
122
+ end
123
+
124
+ it "should save quotes between runs" do
125
+ with_quote_log {
126
+ add "One"
127
+ add "Two"
128
+ }
129
+ init_plugin # Should re-read the .yml file
130
+ quotes[2 - 1].should == "Two"
131
+ end
132
+
133
+ it "should handle angle brackets appropriately" do
134
+ # One convention for attribution is to place the speaker in brackets.
135
+ # And this is how Campfire+Tinder+CampfireBot send us the message.
136
+ when_saying "!addquote \\u0026lt;Someone\\u0026gt; Hello"
137
+ bot_should_reply "Added quote #1."
138
+ quotes[1 - 1].should == "<Someone> Hello"
139
+ end
140
+
141
+
142
+ before :each do
143
+ @bot = CampfireBot::Bot.instance
144
+ @bot.stub!(:config).and_return('nickname' => 'Bot',
145
+ 'our_quotes_recall_command' => 'quote'
146
+ #,'our_quotes_debug_enabled' => true
147
+ )
148
+ init_plugin
149
+ end
150
+ after :each do
151
+ if File.exist? @quote.data_file
152
+ File.unlink(@quote.data_file)
153
+ end
154
+ end
155
+ def init_plugin
156
+ @quote = OurQuotes.new
157
+ CampfireBot::Plugin.registered_plugins['OurQuotes'] = @quote
158
+ end
159
+
160
+ def when_saying(msg)
161
+ @message = CampfireBot::Message.new(:room => Tinder::Room.new(42, "Room1"),
162
+ :message => msg,
163
+ :person => 'Josh')
164
+ end
165
+ def bot_should_reply(msg)
166
+ @message.should_receive(:speak).with(msg)
167
+ @bot.send(:handle_message, @message)
168
+ end
169
+
170
+ # Group log setup calls into a block
171
+ def with_quote_log
172
+ yield
173
+ end
174
+ # Add a quote to the log
175
+ def add(quote)
176
+ @quote.append_add("Someoneelse", "Room1", quote)
177
+ end
178
+ # Remove a quote from the log by id
179
+ def del(quote_id)
180
+ @quote.append_del("Someoneelse", "Room1", quote_id)
181
+ end
182
+ def quotes
183
+ @quote.quotes
184
+ end
185
+
186
+ end