chatterbot 1.0.2 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/LICENSE.txt +18 -9
  4. data/README.markdown +83 -65
  5. data/bin/chatterbot-register +0 -1
  6. data/chatterbot.gemspec +3 -10
  7. data/examples/class_bot.rb +0 -1
  8. data/examples/echoes_bot.rb +2 -2
  9. data/examples/search_bot.rb +1 -1
  10. data/examples/streaming_bot.rb +21 -15
  11. data/lib/chatterbot.rb +7 -12
  12. data/lib/chatterbot/blocklist.rb +61 -0
  13. data/lib/chatterbot/bot.rb +118 -13
  14. data/lib/chatterbot/client.rb +52 -20
  15. data/lib/chatterbot/config.rb +92 -215
  16. data/lib/chatterbot/config_manager.rb +49 -0
  17. data/lib/chatterbot/direct_messages.rb +46 -0
  18. data/lib/chatterbot/dsl.rb +157 -78
  19. data/lib/chatterbot/followers.rb +4 -0
  20. data/lib/chatterbot/handler.rb +29 -0
  21. data/lib/chatterbot/helpers.rb +14 -3
  22. data/lib/chatterbot/home_timeline.rb +5 -8
  23. data/lib/chatterbot/logging.rb +0 -17
  24. data/lib/chatterbot/profile.rb +0 -1
  25. data/lib/chatterbot/reply.rb +6 -11
  26. data/lib/chatterbot/retweet.rb +2 -6
  27. data/lib/chatterbot/safelist.rb +33 -0
  28. data/lib/chatterbot/search.rb +26 -16
  29. data/lib/chatterbot/skeleton.rb +7 -38
  30. data/lib/chatterbot/streaming.rb +26 -33
  31. data/lib/chatterbot/tweet.rb +0 -1
  32. data/lib/chatterbot/ui.rb +9 -2
  33. data/lib/chatterbot/utils.rb +13 -0
  34. data/lib/chatterbot/version.rb +1 -1
  35. data/spec/blocklist_spec.rb +170 -0
  36. data/spec/bot_spec.rb +83 -8
  37. data/spec/client_spec.rb +61 -7
  38. data/spec/config_manager_spec.rb +59 -0
  39. data/spec/config_spec.rb +33 -158
  40. data/spec/direct_messages_spec.rb +115 -0
  41. data/spec/dsl_spec.rb +95 -53
  42. data/spec/handler_spec.rb +27 -0
  43. data/spec/helpers_spec.rb +7 -11
  44. data/spec/home_timeline_spec.rb +42 -31
  45. data/spec/logging_spec.rb +0 -34
  46. data/spec/reply_spec.rb +10 -34
  47. data/spec/search_spec.rb +65 -6
  48. data/spec/spec_helper.rb +25 -1
  49. data/spec/streaming_spec.rb +56 -58
  50. data/spec/whitelist_spec.rb +10 -10
  51. data/specs.watchr +2 -4
  52. data/templates/skeleton.txt +148 -12
  53. metadata +20 -22
  54. data/bin/chatterbot-blacklist +0 -65
  55. data/bin/chatterbot-status +0 -55
  56. data/examples/loop_bot.rb +0 -44
  57. data/lib/chatterbot/blacklist.rb +0 -61
  58. data/lib/chatterbot/db.rb +0 -79
  59. data/lib/chatterbot/streaming_handler.rb +0 -96
  60. data/lib/chatterbot/whitelist.rb +0 -32
  61. data/spec/blacklist_spec.rb +0 -116
  62. data/spec/db_spec.rb +0 -53
  63. data/spec/streaming_handler_spec.rb +0 -78
data/spec/dsl_spec.rb CHANGED
@@ -3,10 +3,11 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
  describe "Chatterbot::DSL" do
4
4
  describe "client routines" do
5
5
  before(:each) do
6
- @bot = double(Chatterbot::Bot, :config => {})
6
+ @bot = instance_double(Chatterbot::Bot, :config => {})
7
7
  @bot.send :require, 'chatterbot/dsl'
8
8
 
9
9
  allow(Chatterbot::DSL).to receive(:bot).and_return(@bot)
10
+ allow(Chatterbot::DSL).to receive(:call_if_immediate)
10
11
  end
11
12
 
12
13
  describe "client" do
@@ -15,46 +16,44 @@ describe "Chatterbot::DSL" do
15
16
  end
16
17
  end
17
18
 
18
- describe "blacklist" do
19
- it "#blacklist passes along to bot object" do
20
- expect(@bot).to receive(:blacklist=).with(["foo"])
21
- blacklist ["foo"]
19
+ describe "blocklist" do
20
+ it "#blocklist passes along to bot object" do
21
+ expect(@bot).to receive(:blocklist=).with(["foo"])
22
+ blocklist ["foo"]
22
23
  end
23
24
 
24
- it "#blacklist turns single-string arg into an array" do
25
- expect(@bot).to receive(:blacklist=).with(["foo"])
26
- blacklist "foo"
25
+ it "#blocklist turns single-string arg into an array" do
26
+ expect(@bot).to receive(:blocklist=).with(["foo"])
27
+ blocklist "foo"
27
28
  end
28
29
 
29
- it "#blacklist turns comma-delimited string arg into an array" do
30
- expect(@bot).to receive(:blacklist=).with(["foo", "bar"])
31
- blacklist "foo, bar"
30
+ it "#blocklist turns comma-delimited string arg into an array" do
31
+ expect(@bot).to receive(:blocklist=).with(["foo", "bar"])
32
+ blocklist "foo, bar"
32
33
  end
33
34
  end
34
35
 
35
- describe "whitelist" do
36
- it "#whitelist passes along to bot object" do
37
- expect(@bot).to receive(:whitelist=).with(["foo"])
38
- whitelist ["foo"]
36
+ describe "safelist" do
37
+ it "#safelist passes along to bot object" do
38
+ expect(@bot).to receive(:safelist=).with(["foo"])
39
+ safelist ["foo"]
39
40
  end
40
41
 
41
- it "#whitelist turns single-string arg into an array" do
42
- expect(@bot).to receive(:whitelist=).with(["foo"])
43
- whitelist "foo"
42
+ it "#safelist turns single-string arg into an array" do
43
+ expect(@bot).to receive(:safelist=).with(["foo"])
44
+ safelist "foo"
44
45
  end
45
46
 
46
- it "#whitelist turns comma-delimited string arg into an array" do
47
- expect(@bot).to receive(:whitelist=).with(["foo", "bar"])
48
- whitelist "foo, bar"
47
+ it "#safelist turns comma-delimited string arg into an array" do
48
+ expect(@bot).to receive(:safelist=).with(["foo", "bar"])
49
+ safelist "foo, bar"
49
50
  end
50
51
  end
51
52
 
52
53
  describe "only_interact_with_followers" do
53
- it "sets whitelist to be the bot's followers" do
54
- f = fake_follower
55
- allow(@bot).to receive(:followers).and_return([f])
56
- expect(@bot).to receive(:whitelist=).with([f])
54
+ it "sets flag" do
57
55
  only_interact_with_followers
56
+ expect(@bot.config[:only_interact_with_followers]).to eq(true)
58
57
  end
59
58
  end
60
59
 
@@ -101,20 +100,53 @@ describe "Chatterbot::DSL" do
101
100
 
102
101
  describe "search" do
103
102
  it "passes along to bot object" do
104
- expect(@bot).to receive(:search).with("foo", { })
105
- search("foo")
103
+ allow(@bot).to receive(:run_or_stream)
104
+ expect(@bot).to receive(:register_handler).with(:search, ["foo"])
105
+ search("foo") {}
106
106
  end
107
107
 
108
108
  it "passes multiple queries along to bot object" do
109
- expect(@bot).to receive(:search).with(["foo","bar"], { })
110
- search(["foo","bar"])
109
+ expect(@bot).to receive(:register_handler).with(:search, [["foo", "bar"]])
110
+ search(["foo","bar"]) {}
111
111
  end
112
112
  end
113
113
 
114
+ describe "direct_messages" do
115
+ it "passes along to bot object" do
116
+ expect(@bot).to receive(:register_handler).with(:direct_messages, instance_of(Proc))
117
+ direct_messages {}
118
+ end
119
+ end
120
+
121
+ describe "favorited" do
122
+ it "passes along to bot object" do
123
+ expect(@bot).to receive(:register_handler).with(:favorited, instance_of(Proc))
124
+
125
+ favorited {}
126
+ end
127
+ end
128
+
129
+ describe "followed" do
130
+ it "passes along to bot object" do
131
+ expect(@bot).to receive(:register_handler).with(:followed, instance_of(Proc))
132
+
133
+ followed {}
134
+ end
135
+ end
136
+
137
+ describe "deleted" do
138
+ it "passes along to bot object" do
139
+ expect(@bot).to receive(:register_handler).with(:deleted, instance_of(Proc))
140
+
141
+ deleted {}
142
+ end
143
+ end
144
+
145
+
114
146
  describe "streaming" do
115
147
  it "passes along to bot object" do
116
- expect(@bot).to receive(:do_streaming)
117
- streaming {}
148
+ expect(@bot).to receive(:streaming=).with(true)
149
+ use_streaming
118
150
  end
119
151
  end
120
152
 
@@ -130,18 +162,13 @@ describe "Chatterbot::DSL" do
130
162
  end
131
163
 
132
164
  it "#replies passes along to bot object" do
133
- expect(@bot).to receive(:replies)
134
- replies
165
+ expect(@bot).to receive(:register_handler).with(:replies, instance_of(Proc))
166
+ replies {}
135
167
  end
136
168
 
137
169
  it "#home_timeline passes along to bot object" do
138
- expect(@bot).to receive(:home_timeline)
139
- home_timeline
140
- end
141
-
142
- it "#streaming_tweets passes along to bot object" do
143
- expect(@bot).to receive(:streaming_tweets)
144
- streaming_tweets
170
+ expect(@bot).to receive(:register_handler).with(:home_timeline, instance_of(Proc))
171
+ home_timeline { |x| "foo" }
145
172
  end
146
173
 
147
174
  it "#followers passes along to bot object" do
@@ -164,6 +191,19 @@ describe "Chatterbot::DSL" do
164
191
  reply "hello sailor!", { :source => "source "}
165
192
  end
166
193
 
194
+ describe "#direct_message" do
195
+ it "passes along to bot object" do
196
+ expect(@bot).to receive(:direct_message).with("hello sailor!", nil)
197
+ direct_message "hello sailor!"
198
+ end
199
+
200
+ it "passes along to bot object with user, if specified" do
201
+ user = fake_user("DM user")
202
+ expect(@bot).to receive(:direct_message).with("hello sailor!", user)
203
+ direct_message "hello sailor!", user
204
+ end
205
+ end
206
+
167
207
  it "#profile_text setter passes along to bot object" do
168
208
  expect(@bot).to receive(:profile_text).with("hello sailor!")
169
209
  profile_text "hello sailor!"
@@ -185,10 +225,21 @@ describe "Chatterbot::DSL" do
185
225
  end
186
226
 
187
227
  context "setters" do
188
- [:consumer_secret, :consumer_key, :token, :secret].each do |k|
189
- it "should be able to set #{k}" do
190
- send(k, "foo")
191
- expect(@bot.config[k]).to eq("foo")
228
+ before(:each) do
229
+ allow(@bot).to receive(:deprecated)
230
+ end
231
+ [
232
+ {:consumer_secret => :consumer_secret},
233
+ {:consumer_key => :consumer_key},
234
+ {:token => :access_token},
235
+ {:secret => :access_token_secret}
236
+ ].each do |k|
237
+ key = k.keys.first
238
+ value = k[key]
239
+
240
+ it "should be able to set #{key}" do
241
+ send(key, "foo")
242
+ expect(@bot.config[value]).to eq("foo")
192
243
  end
193
244
  end
194
245
  end
@@ -219,14 +270,5 @@ describe "Chatterbot::DSL" do
219
270
  end
220
271
  end
221
272
 
222
- describe "db" do
223
- it "should pass to bot object" do
224
- bot_db = double(Object)
225
- expect(@bot).to receive(:db).and_return(bot_db)
226
-
227
- expect(db).to eql(bot_db)
228
- end
229
- end
230
-
231
273
  end
232
274
  end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Chatterbot::Handler" do
4
+ it "accepts a block" do
5
+ @foo = nil
6
+ h = Chatterbot::Handler.new({}) do |_|
7
+ @foo = "bar"
8
+ end
9
+
10
+ h.call
11
+
12
+ expect(@foo).to eql("bar")
13
+ end
14
+
15
+ it "accepts a proc/etc directly" do
16
+ @foo = nil
17
+ @proc = Proc.new do |_|
18
+ @foo = "bar"
19
+ end
20
+
21
+ h = Chatterbot::Handler.new(@proc)
22
+ h.call
23
+
24
+ expect(@foo).to eql("bar")
25
+
26
+ end
27
+ end
data/spec/helpers_spec.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Chatterbot::Helpers" do
4
- it "#tweet_user works with [:from_user]" do
4
+ it "#tweet_user works with Tweet" do
5
5
  bot = Chatterbot::Bot.new
6
- expect(bot.tweet_user({:from_user => "foo"})).to eq("@foo")
7
- expect(bot.tweet_user({:from_user => "@foo"})).to eq("@foo")
6
+ t = Twitter::Tweet.new(:id => 1, :user => {:id => 1, :screen_name => "skippy"})
7
+ expect(bot.tweet_user(t)).to eq("@skippy")
8
8
  end
9
9
 
10
- it "#tweet_user works with [:user][:screen_name]" do
10
+ it "#tweet_user works with User" do
11
11
  bot = Chatterbot::Bot.new
12
- expect(bot.tweet_user({:user => {:screen_name => "foo"}})).to eq("@foo")
13
- expect(bot.tweet_user({:user => {:screen_name => "@foo"}})).to eq("@foo")
12
+ u = Twitter::User.new({:id => 1, :name => "skippy"})
13
+ expect(bot.tweet_user(u)).to eq("@skippy")
14
14
  end
15
15
 
16
16
  it "#tweet_user works with string" do
@@ -37,10 +37,6 @@ describe "Chatterbot::Helpers" do
37
37
  u = Twitter::User.new(:id => 123, :name => "x")
38
38
  expect(@bot.from_user(fake_user("x"))).to eq("x")
39
39
  end
40
-
41
- it "should accept :screen_name" do
42
- expect(@bot.from_user(:user => {:screen_name => "x"})).to eq("x")
43
- end
44
40
  end
45
41
 
46
42
  describe "#botname" do
@@ -61,7 +57,7 @@ describe "Chatterbot::Helpers" do
61
57
  end
62
58
 
63
59
  it "calls botname for non-inherited bots" do
64
- expect(File).to receive(:basename).and_return("bot")
60
+ allow(File).to receive(:basename).and_return("bot")
65
61
  expect(@bot.botname).to eq("bot")
66
62
  end
67
63
 
@@ -2,52 +2,63 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Chatterbot::HomeTimeline" do
4
4
  it "calls require_login" do
5
- bot = test_bot
6
- expect(bot).to receive(:require_login).and_return(false)
7
- bot.home_timeline
5
+ @bot = test_bot
6
+ expect(@bot).to receive(:require_login).and_return(false)
7
+ @bot.home_timeline
8
8
  end
9
9
 
10
10
  it "updates since_id when complete" do
11
- bot = test_bot
12
- expect(bot).to receive(:require_login).and_return(true)
11
+ @bot = test_bot
12
+ expect(@bot).to receive(:require_login).and_return(true)
13
13
  results = fake_home_timeline(1, 1000)
14
14
 
15
- allow(bot).to receive(:client).and_return(results)
16
-
17
- bot.home_timeline do
15
+ allow(@bot).to receive(:client).and_return(results)
16
+
17
+ @bot.home_timeline do
18
18
  end
19
19
 
20
- expect(bot.config[:tmp_since_id]).to eq(1000)
20
+ expect(@bot.config[:since_id_home_timeline]).to eq(1000)
21
21
  end
22
22
 
23
- it "iterates results" do
24
- bot = test_bot
25
- expect(bot).to receive(:require_login).and_return(true)
26
- allow(bot).to receive(:client).and_return(fake_home_timeline(3))
27
-
28
- expect(bot).to receive(:update_since_id).exactly(3).times
29
-
30
- indexes = []
31
- bot.home_timeline do |x|
32
- indexes << x[:id]
23
+ describe "handling results" do
24
+ before(:each) do
25
+ @bot = test_bot
26
+ expect(@bot).to receive(:require_login).and_return(true)
27
+ allow(@bot).to receive(:client).and_return(fake_home_timeline(3))
33
28
  end
34
29
 
35
- expect(indexes).to eq([1,2,3])
36
- end
30
+ it "iterates results" do
31
+ expect(@bot).to receive(:update_since_id_home_timeline).exactly(3).times
37
32
 
38
- it "checks blacklist" do
39
- bot = test_bot
40
- expect(bot).to receive(:require_login).and_return(true)
41
- allow(bot).to receive(:client).and_return(fake_home_timeline(3))
42
-
43
- allow(bot).to receive(:on_blacklist?).and_return(true, false, false)
33
+ indexes = []
34
+ @bot.home_timeline do |x|
35
+ indexes << x.id
36
+ end
37
+
38
+ expect(indexes).to eq([1,2,3])
39
+ end
44
40
 
41
+ it "checks blocklist" do
42
+ allow(@bot).to receive(:on_blocklist?).and_return(true, false, false)
45
43
 
46
- indexes = []
47
- bot.home_timeline do |x|
48
- indexes << x[:id]
44
+ indexes = []
45
+ @bot.home_timeline do |x|
46
+ indexes << x.id
47
+ end
48
+
49
+ expect(indexes).to eq([2,3])
49
50
  end
50
51
 
51
- expect(indexes).to eq([2,3])
52
+ it "checks safelist" do
53
+ allow(@bot).to receive(:has_safelist?).and_return(true)
54
+ allow(@bot).to receive(:on_safelist?).and_return(true, false, false)
55
+
56
+ indexes = []
57
+ @bot.home_timeline do |x|
58
+ indexes << x.id
59
+ end
60
+
61
+ expect(indexes).to eq([1])
62
+ end
52
63
  end
53
64
  end
data/spec/logging_spec.rb CHANGED
@@ -29,38 +29,4 @@ describe "Chatterbot::Logging" do
29
29
  end
30
30
  end
31
31
 
32
- describe "#log to database" do
33
- before(:each) do
34
- @db_tmp = Tempfile.new("config.db")
35
- @db_uri = "sqlite://#{@db_tmp.path}"
36
-
37
- @bot = Chatterbot::Bot.new
38
- @bot.config[:db_uri] = @db_uri
39
-
40
- expect(@bot).to receive(:log_tweets?).and_return(true)
41
-
42
- expect(@bot).to receive(:botname).and_return("logger")
43
- allow(Time).to receive(:now).and_return(123)
44
-
45
- @tweets_table = double(Object)
46
- allow(@bot).to receive(:db).and_return({
47
- :tweets => @tweets_table
48
- })
49
- end
50
-
51
- it "logs tweets to the db" do
52
- expect(@tweets_table).to receive(:insert).with({ :txt => "TEST", :bot => "logger", :created_at => 123})
53
- @bot.log "TEST"
54
- end
55
-
56
- it "logs tweets with some source info to the db" do
57
- source_tweet = Twitter::Tweet.new({:id => 12345, :text => "i should trigger a bot", :user => {:screen_name => "replytome", :id => 456}})
58
-
59
- params = {:txt=>"TEST", :bot=>"logger", :created_at=>123, :user=>"replytome", :source_id=>12345, :source_tweet=>"i should trigger a bot"}
60
-
61
- expect(@tweets_table).to receive(:insert).with(params)
62
-
63
- @bot.log "TEST", source_tweet
64
- end
65
- end
66
32
  end
data/spec/reply_spec.rb CHANGED
@@ -13,39 +13,39 @@ describe "Chatterbot::Reply" do
13
13
  results = fake_replies(1, 1000)
14
14
 
15
15
  allow(bot).to receive(:client).and_return(results)
16
-
16
+
17
17
  bot.replies do
18
18
  end
19
19
 
20
- expect(bot.config[:tmp_since_id_reply]).to eq(1000)
20
+ expect(bot.config[:since_id_reply]).to eq(1000)
21
21
  end
22
22
 
23
23
  it "iterates results" do
24
24
  bot = test_bot
25
25
  expect(bot).to receive(:require_login).and_return(true)
26
26
  allow(bot).to receive(:client).and_return(fake_replies(3))
27
-
27
+
28
28
  expect(bot).to receive(:update_since_id_reply).exactly(3).times
29
29
 
30
30
  indexes = []
31
31
  bot.replies do |x|
32
- indexes << x[:id]
32
+ indexes << x.id
33
33
  end
34
34
 
35
35
  expect(indexes).to eq([1,2,3])
36
36
  end
37
37
 
38
- it "checks blacklist" do
38
+ it "checks blocklist" do
39
39
  bot = test_bot
40
40
  expect(bot).to receive(:require_login).and_return(true)
41
41
  allow(bot).to receive(:client).and_return(fake_replies(3))
42
-
43
- allow(bot).to receive(:on_blacklist?).and_return(true, false, false)
42
+
43
+ allow(bot).to receive(:on_blocklist?).and_return(true, false, false)
44
44
 
45
45
 
46
46
  indexes = []
47
47
  bot.replies do |x|
48
- indexes << x[:id]
48
+ indexes << x.id
49
49
  end
50
50
 
51
51
  expect(indexes).to eq([2,3])
@@ -53,37 +53,13 @@ describe "Chatterbot::Reply" do
53
53
 
54
54
 
55
55
  it "passes along since_id_reply" do
56
- bot = test_bot
57
- expect(bot).to receive(:require_login).and_return(true)
58
- allow(bot).to receive(:client).and_return(fake_replies(100, 3))
59
- allow(bot).to receive(:since_id_reply).and_return(123)
60
-
61
- expect(bot.client).to receive(:mentions_timeline).with({:since_id => 123, :count => 200})
62
-
63
- bot.replies
64
- end
65
-
66
-
67
- it "doesn't pass along invalid since_id_reply" do
68
- bot = test_bot
69
- expect(bot).to receive(:require_login).and_return(true)
70
- allow(bot).to receive(:client).and_return(fake_replies(100, 3))
71
- allow(bot).to receive(:since_id_reply).and_return(0)
72
-
73
- expect(bot.client).to receive(:mentions_timeline).with({:count => 200})
74
-
75
- bot.replies
76
- end
77
-
78
- it "pass along since_id if since_id_reply is nil or zero" do
79
56
  bot = test_bot
80
57
  expect(bot).to receive(:require_login).and_return(true)
81
58
  allow(bot).to receive(:client).and_return(fake_replies(100, 3))
82
- allow(bot).to receive(:since_id).and_return(12345)
59
+ allow(bot).to receive(:since_id_reply).and_return(123)
83
60
 
84
- expect(bot.client).to receive(:mentions_timeline).with({:count => 200, :since_id => 12345})
61
+ expect(bot.client).to receive(:mentions_timeline).with({:since_id => 123, :count => 200})
85
62
 
86
63
  bot.replies
87
-
88
64
  end
89
65
  end