chatterbot 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +81 -12
- data/bin/chatterbot-register +3 -3
- data/chatterbot.gemspec +13 -28
- data/examples/echoes_bot.rb +4 -4
- data/lib/chatterbot.rb +5 -2
- data/lib/chatterbot/blacklist.rb +2 -2
- data/lib/chatterbot/bot.rb +13 -6
- data/lib/chatterbot/client.rb +103 -61
- data/lib/chatterbot/config.rb +25 -13
- data/lib/chatterbot/dsl.rb +104 -45
- data/lib/chatterbot/helpers.rb +3 -0
- data/lib/chatterbot/reply.rb +9 -13
- data/lib/chatterbot/retweet.rb +1 -1
- data/lib/chatterbot/search.rb +10 -14
- data/lib/chatterbot/tweet.rb +6 -4
- data/lib/chatterbot/ui.rb +96 -0
- data/lib/chatterbot/version.rb +1 -1
- data/spec/blacklist_spec.rb +4 -4
- data/spec/bot_spec.rb +1 -1
- data/spec/client_spec.rb +40 -10
- data/spec/config_spec.rb +24 -9
- data/spec/dsl_spec.rb +12 -6
- data/spec/helpers_spec.rb +1 -1
- data/spec/reply_spec.rb +17 -23
- data/spec/retweet_spec.rb +2 -2
- data/spec/search_spec.rb +21 -26
- data/spec/spec_helper.rb +25 -17
- data/spec/tweet_spec.rb +4 -4
- metadata +136 -18
data/lib/chatterbot/version.rb
CHANGED
data/spec/blacklist_spec.rb
CHANGED
@@ -27,8 +27,8 @@ describe "Chatterbot::Blacklist" do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "works with result hashes" do
|
30
|
-
@bot.skip_me?(
|
31
|
-
@bot.skip_me?(
|
30
|
+
@bot.skip_me?(Twitter::Status.new(:id => 1, :text => "did you know that i hate bots?")).should == true
|
31
|
+
@bot.skip_me?(Twitter::Status.new(:id => 1, :text => "a tweet without any bad content")).should == false
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -52,8 +52,8 @@ describe "Chatterbot::Blacklist" do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it "works with result hashes" do
|
55
|
-
@bot.on_blacklist?(
|
56
|
-
@bot.on_blacklist?(
|
55
|
+
@bot.on_blacklist?(Twitter::Status.new(:id => 1, :from_user => "skippy")).should == true
|
56
|
+
@bot.on_blacklist?(Twitter::Status.new(:id => 1, :from_user => "flippy")).should == false
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
data/spec/bot_spec.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -6,12 +6,42 @@ describe "Chatterbot::Client" do
|
|
6
6
|
@bot.client = mock(Object)
|
7
7
|
end
|
8
8
|
|
9
|
+
describe "reset_since_id" do
|
10
|
+
it "runs a search to get a new max_id" do
|
11
|
+
bot = test_bot
|
12
|
+
|
13
|
+
bot.stub!(:search_client).and_return(fake_search(100, 1))
|
14
|
+
bot.search_client.should_receive(:search).with("a")
|
15
|
+
bot.reset_since_id
|
16
|
+
|
17
|
+
bot.config[:tmp_since_id].should == 100
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
9
21
|
it "runs init_client and login on #require_login" do
|
10
22
|
@bot.should_receive(:init_client).and_return(true)
|
11
23
|
@bot.should_receive(:login).and_return(true)
|
12
24
|
@bot.require_login
|
13
25
|
end
|
14
26
|
|
27
|
+
describe "init_client" do
|
28
|
+
before(:each) do
|
29
|
+
@client = mock(Twitter::Client)
|
30
|
+
@bot.should_receive(:client).and_return(@client)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns true when client has credentials" do
|
34
|
+
@client.should_receive(:credentials?).and_return(true)
|
35
|
+
@bot.init_client.should == true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns false when client does not have credentials" do
|
39
|
+
@client.should_receive(:credentials?).and_return(false)
|
40
|
+
@bot.init_client.should == false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
15
45
|
it "reset_client resets the client instance" do
|
16
46
|
@bot.should_receive(:init_client).and_return(true)
|
17
47
|
@bot.reset_client
|
@@ -31,18 +61,19 @@ describe "Chatterbot::Client" do
|
|
31
61
|
@bot.should_receive(:needs_api_key?).and_return(false)
|
32
62
|
@bot.should_receive(:needs_auth_token?).and_return(true)
|
33
63
|
@bot.should_receive(:get_oauth_verifier).and_return("pin")
|
34
|
-
@bot.client.should_receive(:request_token).and_return(
|
35
|
-
mock(:token => "token",
|
36
|
-
:secret => "secret"
|
37
|
-
)
|
38
|
-
)
|
39
|
-
@bot.client.should_receive(:authorize).
|
40
|
-
with("token", "secret", { :oauth_verifier => "pin"}).
|
41
|
-
and_return(mock(:token => "access_token", :secret => "access_secret"))
|
42
64
|
end
|
43
65
|
|
44
66
|
it "handles getting an auth token" do
|
45
|
-
|
67
|
+
token = mock(Object,
|
68
|
+
:token => "token",
|
69
|
+
:secret => "secret"
|
70
|
+
)
|
71
|
+
|
72
|
+
@bot.should_receive(:request_token).and_return(token)
|
73
|
+
token.should_receive(:get_access_token).with(:oauth_verifier => "pin").
|
74
|
+
and_return(mock(:token => "access_token", :secret => "access_secret"))
|
75
|
+
|
76
|
+
@bot.should_receive(:get_screen_name)
|
46
77
|
@bot.should_receive(:update_config)
|
47
78
|
|
48
79
|
@bot.login
|
@@ -52,7 +83,6 @@ describe "Chatterbot::Client" do
|
|
52
83
|
end
|
53
84
|
|
54
85
|
it "handles errors" do
|
55
|
-
@bot.client.should_receive(:authorized?).and_return(false)
|
56
86
|
@bot.should_receive(:display_oauth_error)
|
57
87
|
@bot.login
|
58
88
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -96,6 +96,20 @@ describe "Chatterbot::Config" do
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
+
describe "reset_bot?" do
|
100
|
+
it "works when reset_bot isn't set" do
|
101
|
+
@bot.reset_bot?.should == false
|
102
|
+
end
|
103
|
+
|
104
|
+
it "works when reset_bot is set" do
|
105
|
+
@bot.config[:reset_since_id] = false
|
106
|
+
@bot.reset_bot?.should == false
|
107
|
+
|
108
|
+
@bot.config[:reset_since_id] = true
|
109
|
+
@bot.reset_bot?.should == true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
99
113
|
|
100
114
|
describe "debug_mode?" do
|
101
115
|
it "works when debug_mode isn't set" do
|
@@ -120,26 +134,27 @@ describe "Chatterbot::Config" do
|
|
120
134
|
|
121
135
|
describe "update_since_id" do
|
122
136
|
it "works with searches" do
|
137
|
+
# data = [ fake_tweet(1000) ]
|
138
|
+
|
139
|
+
data = fake_search(1000, 1).search
|
140
|
+
|
123
141
|
@bot.config[:tmp_since_id] = 100
|
124
|
-
@bot.update_since_id(
|
142
|
+
@bot.update_since_id(data)
|
125
143
|
@bot.config[:tmp_since_id].should == 1000
|
126
144
|
end
|
127
145
|
|
128
146
|
it "works with tweets" do
|
129
147
|
@bot.config[:tmp_since_id] = 100
|
130
|
-
@bot.update_since_id({ :id => 1000 })
|
131
|
-
@bot.config[:tmp_since_id].should == 1000
|
132
|
-
end
|
133
148
|
|
134
|
-
|
135
|
-
@bot.
|
136
|
-
@bot.
|
137
|
-
@bot.config[:tmp_since_id].should == 100
|
149
|
+
data = fake_tweet(1000, 1000, true)
|
150
|
+
@bot.update_since_id(data)
|
151
|
+
@bot.config[:tmp_since_id].should == 1000
|
138
152
|
end
|
139
153
|
|
140
154
|
it "never rolls back" do
|
141
155
|
@bot.config[:tmp_since_id] = 100
|
142
|
-
|
156
|
+
data = fake_tweet(50, 50, true)
|
157
|
+
@bot.update_since_id(data)
|
143
158
|
@bot.config[:tmp_since_id].should == 100
|
144
159
|
end
|
145
160
|
end
|
data/spec/dsl_spec.rb
CHANGED
@@ -62,15 +62,21 @@ describe "Chatterbot::DSL" do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
describe "search" do
|
66
|
+
it "passes along to bot object" do
|
67
|
+
@bot.should_receive(:search).with("foo", { })
|
68
|
+
search("foo")
|
69
|
+
end
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
71
|
+
it "passes multiple queries along to bot object" do
|
72
|
+
@bot.should_receive(:search).with(["foo","bar"], { })
|
73
|
+
search(["foo","bar"])
|
74
|
+
end
|
69
75
|
end
|
70
76
|
|
71
|
-
it "#
|
72
|
-
@bot.should_receive(:
|
73
|
-
|
77
|
+
it "#retweet passes along to bot object" do
|
78
|
+
@bot.should_receive(:retweet).with(1234)
|
79
|
+
retweet(1234)
|
74
80
|
end
|
75
81
|
|
76
82
|
it "#replies passes along to bot object" do
|
data/spec/helpers_spec.rb
CHANGED
data/spec/reply_spec.rb
CHANGED
@@ -8,14 +8,19 @@ describe "Chatterbot::Reply" do
|
|
8
8
|
bot.replies
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
it "updates since_id when complete" do
|
12
|
+
bot = test_bot
|
13
|
+
bot.should_receive(:require_login).and_return(true)
|
14
|
+
results = fake_replies(100, 1, 1000)
|
15
|
+
|
16
|
+
bot.stub!(:client).and_return(results)
|
17
|
+
|
18
|
+
bot.replies do |x|
|
19
|
+
;
|
20
|
+
end
|
16
21
|
|
17
|
-
|
18
|
-
|
22
|
+
bot.config[:tmp_since_id].should == 1000
|
23
|
+
end
|
19
24
|
|
20
25
|
it "iterates results" do
|
21
26
|
bot = test_bot
|
@@ -26,7 +31,7 @@ describe "Chatterbot::Reply" do
|
|
26
31
|
|
27
32
|
indexes = []
|
28
33
|
bot.replies do |x|
|
29
|
-
indexes << x[:
|
34
|
+
indexes << x[:id]
|
30
35
|
end
|
31
36
|
|
32
37
|
indexes.should == [1,2,3]
|
@@ -41,9 +46,10 @@ describe "Chatterbot::Reply" do
|
|
41
46
|
|
42
47
|
bot.stub!(:on_blacklist?).and_return(true, false)
|
43
48
|
|
49
|
+
|
44
50
|
indexes = []
|
45
51
|
bot.replies do |x|
|
46
|
-
indexes << x[:
|
52
|
+
indexes << x[:id]
|
47
53
|
end
|
48
54
|
|
49
55
|
indexes.should == [2,3]
|
@@ -56,7 +62,7 @@ describe "Chatterbot::Reply" do
|
|
56
62
|
bot.stub!(:client).and_return(fake_replies(100, 3))
|
57
63
|
bot.stub!(:since_id).and_return(123)
|
58
64
|
|
59
|
-
bot.client.should_receive(:
|
65
|
+
bot.client.should_receive(:mentions).with({:since_id => 123, :count => 200})
|
60
66
|
|
61
67
|
bot.replies
|
62
68
|
end
|
@@ -68,20 +74,8 @@ describe "Chatterbot::Reply" do
|
|
68
74
|
bot.stub!(:client).and_return(fake_replies(100, 3))
|
69
75
|
bot.stub!(:since_id).and_return(0)
|
70
76
|
|
71
|
-
bot.client.should_receive(:
|
77
|
+
bot.client.should_receive(:mentions).with({:count => 200})
|
72
78
|
|
73
79
|
bot.replies
|
74
80
|
end
|
75
|
-
|
76
|
-
|
77
|
-
it "outputs an error if we get one from API" do
|
78
|
-
bot = test_bot
|
79
|
-
bot.stub!(:require_login).and_return(true)
|
80
|
-
bot.stub!(:client).and_return(mock(Object, :replies => {"error" => "You messed up"}))
|
81
|
-
|
82
|
-
bot.should_receive(:critical).with("You messed up")
|
83
|
-
|
84
|
-
bot.replies
|
85
|
-
end
|
86
|
-
|
87
81
|
end
|
data/spec/retweet_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe "Chatterbot::Retweet" do
|
|
15
15
|
bot = test_bot
|
16
16
|
|
17
17
|
bot.should_receive(:require_login).and_return(true)
|
18
|
-
bot.stub!(:client).and_return(mock(
|
18
|
+
bot.stub!(:client).and_return(mock(Twitter::Client))
|
19
19
|
|
20
20
|
bot.stub!(:debug_mode?).and_return(false)
|
21
21
|
|
@@ -24,4 +24,4 @@ describe "Chatterbot::Retweet" do
|
|
24
24
|
bot.retweet(tweet_id)
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
data/spec/search_spec.rb
CHANGED
@@ -24,29 +24,24 @@ describe "Chatterbot::Search" do
|
|
24
24
|
bot.should_receive(:search)
|
25
25
|
bot.search("foo")
|
26
26
|
end
|
27
|
-
|
28
|
-
it "calls init_client" do
|
29
|
-
bot = test_bot
|
30
|
-
bot.should_receive(:init_client).and_return(false)
|
31
|
-
bot.search("foo")
|
32
|
-
end
|
27
|
+
|
33
28
|
|
34
29
|
it "calls update_since_id" do
|
35
30
|
bot = test_bot
|
36
31
|
|
37
|
-
|
38
|
-
bot.
|
39
|
-
|
32
|
+
data = fake_search(100, 1)
|
33
|
+
bot.stub!(:search_client).and_return(data)
|
34
|
+
bot.should_receive(:update_since_id).with(100)
|
35
|
+
|
40
36
|
bot.search("foo")
|
41
37
|
end
|
42
38
|
|
43
39
|
it "accepts multiple searches at once" do
|
44
40
|
bot = test_bot
|
45
|
-
#bot = Chatterbot::Bot.new
|
46
41
|
|
47
|
-
bot.stub!(:
|
48
|
-
bot.
|
49
|
-
bot.
|
42
|
+
bot.stub!(:search_client).and_return(fake_search(100, 1))
|
43
|
+
bot.search_client.should_receive(:search).with("foo -include:retweets", {:result_type=>"recent"})
|
44
|
+
bot.search_client.should_receive(:search).with("bar -include:retweets", {:result_type=>"recent"})
|
50
45
|
|
51
46
|
bot.search(["foo", "bar"])
|
52
47
|
end
|
@@ -54,8 +49,8 @@ describe "Chatterbot::Search" do
|
|
54
49
|
it "accepts extra params" do
|
55
50
|
bot = test_bot
|
56
51
|
|
57
|
-
bot.stub!(:
|
58
|
-
bot.
|
52
|
+
bot.stub!(:search_client).and_return(fake_search(100, 1))
|
53
|
+
bot.search_client.should_receive(:search).with("foo -include:retweets", {:lang => "en", :result_type=>"recent"})
|
59
54
|
|
60
55
|
bot.search("foo", :lang => "en")
|
61
56
|
end
|
@@ -63,8 +58,8 @@ describe "Chatterbot::Search" do
|
|
63
58
|
it "accepts a single search query" do
|
64
59
|
bot = test_bot
|
65
60
|
|
66
|
-
bot.stub!(:
|
67
|
-
bot.
|
61
|
+
bot.stub!(:search_client).and_return(fake_search(100, 1))
|
62
|
+
bot.search_client.should_receive(:search).with("foo -include:retweets", {:result_type=>"recent"})
|
68
63
|
|
69
64
|
bot.search("foo")
|
70
65
|
end
|
@@ -73,28 +68,28 @@ describe "Chatterbot::Search" do
|
|
73
68
|
bot = test_bot
|
74
69
|
bot.stub!(:since_id).and_return(123)
|
75
70
|
|
76
|
-
bot.stub!(:
|
77
|
-
bot.
|
71
|
+
bot.stub!(:search_client).and_return(fake_search(100, 1))
|
72
|
+
bot.search_client.should_receive(:search).with("foo -include:retweets", {:since_id => 123, :result_type => "recent"})
|
78
73
|
|
79
74
|
bot.search("foo")
|
80
75
|
end
|
81
76
|
|
82
77
|
it "updates since_id when complete" do
|
83
78
|
bot = test_bot
|
84
|
-
results = fake_search(
|
85
|
-
|
86
|
-
bot.stub!(:client).and_return(results)
|
79
|
+
results = fake_search(1000, 1)
|
80
|
+
bot.stub!(:search_client).and_return(results)
|
87
81
|
|
82
|
+
bot.should_receive(:update_since_id).with(1000)
|
88
83
|
bot.search("foo")
|
89
84
|
end
|
90
85
|
|
91
86
|
it "iterates results" do
|
92
87
|
bot = test_bot
|
93
|
-
bot.stub!(:
|
88
|
+
bot.stub!(:search_client).and_return(fake_search(100, 3))
|
94
89
|
indexes = []
|
95
90
|
|
96
91
|
bot.search("foo") do |x|
|
97
|
-
indexes << x[:index]
|
92
|
+
indexes << x.attrs[:index]
|
98
93
|
end
|
99
94
|
|
100
95
|
indexes.should == [1,2,3]
|
@@ -102,13 +97,13 @@ describe "Chatterbot::Search" do
|
|
102
97
|
|
103
98
|
it "checks blacklist" do
|
104
99
|
bot = test_bot
|
105
|
-
bot.stub!(:
|
100
|
+
bot.stub!(:search_client).and_return(fake_search(100, 3))
|
106
101
|
|
107
102
|
bot.stub!(:on_blacklist?).and_return(true, false)
|
108
103
|
|
109
104
|
indexes = []
|
110
105
|
bot.search("foo") do |x|
|
111
|
-
indexes << x[:index]
|
106
|
+
indexes << x.attrs[:index]
|
112
107
|
end
|
113
108
|
|
114
109
|
indexes.should == [2,3]
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'simplecov'
|
2
3
|
SimpleCov.start
|
3
4
|
#$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
@@ -6,11 +7,8 @@ SimpleCov.start
|
|
6
7
|
require 'bundler/setup'
|
7
8
|
Bundler.require
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
#require 'chatterbot'
|
12
|
-
|
13
|
-
require "twitter_oauth"
|
10
|
+
#require "twitter_oauth"
|
11
|
+
require "twitter"
|
14
12
|
|
15
13
|
require 'tempfile'
|
16
14
|
require 'sqlite3'
|
@@ -28,29 +26,39 @@ def test_bot
|
|
28
26
|
end
|
29
27
|
|
30
28
|
def fake_search(max_id = 100, result_count = 0, id_base=0)
|
31
|
-
mock(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
'results' => 1.upto(result_count).collect { |i| fake_tweet(i, id_base) }
|
36
|
-
}
|
37
|
-
}
|
29
|
+
mock(Twitter::Client,
|
30
|
+
:credentials? => true,
|
31
|
+
:search => Twitter::SearchResults.new(:max_id => max_id,
|
32
|
+
:results => 1.upto(result_count).collect { |i| fake_tweet(i, id_base) } )
|
38
33
|
)
|
34
|
+
|
35
|
+
# mock(Twitter::Client,
|
36
|
+
# {
|
37
|
+
# :credentials? => true,
|
38
|
+
# :search => 1.upto(result_count).collect { |i| fake_tweet(i, id_base) }
|
39
|
+
# }
|
40
|
+
# )
|
39
41
|
end
|
40
42
|
|
41
43
|
def fake_replies(max_id = 100, result_count = 0, id_base = 0)
|
42
|
-
mock(
|
44
|
+
mock(Twitter::Client,
|
43
45
|
{
|
44
|
-
:
|
46
|
+
:credentials? => true,
|
47
|
+
:mentions => 1.upto(result_count).collect { |i| fake_tweet(i, id_base, true) }
|
45
48
|
}
|
46
49
|
)
|
47
50
|
end
|
48
51
|
|
49
|
-
def fake_tweet(index, id=0)
|
52
|
+
def fake_tweet(index, id=0, as_object = false)
|
50
53
|
id = index if id <= 0
|
51
|
-
{
|
54
|
+
x = {
|
52
55
|
:from_user => "chatterbot",
|
53
56
|
:index => index,
|
54
|
-
:id => id
|
57
|
+
:id => id,
|
58
|
+
:user => {
|
59
|
+
'screen_name' => "chatterbot"
|
60
|
+
}
|
55
61
|
}
|
62
|
+
|
63
|
+
as_object == true ? Twitter::Status.new(x) : x
|
56
64
|
end
|