chewbranca-twibot 0.1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +50 -0
- data/Rakefile +30 -0
- data/Readme.rdoc +269 -0
- data/lib/hash.rb +8 -0
- data/lib/twibot/bot.rb +422 -0
- data/lib/twibot/config.rb +140 -0
- data/lib/twibot/handlers.rb +122 -0
- data/lib/twibot/macros.rb +101 -0
- data/lib/twibot/tweets.rb +4 -0
- data/lib/twibot.rb +87 -0
- data/test/test_bot.rb +300 -0
- data/test/test_config.rb +89 -0
- data/test/test_handler.rb +191 -0
- data/test/test_hash.rb +34 -0
- data/test/test_helper.rb +44 -0
- data/test/test_twibot.rb +1 -0
- data/twibot.gemspec +38 -0
- metadata +97 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
module Twibot
|
2
|
+
@@prompt = false
|
3
|
+
|
4
|
+
def self.prompt=(p)
|
5
|
+
@@prompt = f
|
6
|
+
end
|
7
|
+
|
8
|
+
module Macros
|
9
|
+
def self.included(mod)
|
10
|
+
@@bot = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure(&blk)
|
14
|
+
bot.configure(&blk)
|
15
|
+
end
|
16
|
+
|
17
|
+
def message(pattern = nil, options = {}, &blk)
|
18
|
+
add_handler(:message, pattern, options, &blk)
|
19
|
+
end
|
20
|
+
|
21
|
+
def reply(pattern = nil, options = {}, &blk)
|
22
|
+
add_handler(:reply, pattern, options, &blk)
|
23
|
+
end
|
24
|
+
|
25
|
+
def tweet(pattern = nil, options = {}, &blk)
|
26
|
+
add_handler(:tweet, pattern, options, &blk)
|
27
|
+
end
|
28
|
+
|
29
|
+
def follower(&blk)
|
30
|
+
add_handler(:follower, nil, {}, &blk)
|
31
|
+
end
|
32
|
+
|
33
|
+
def hashtag(tag_or_tags, pattern = nil, options = {}, &blk)
|
34
|
+
query = [tag_or_tags].flatten.map {|ht| ht.to_s[0] == ?# ? ht.to_s : "##{ht}"}.join(" OR ")
|
35
|
+
add_handler([:search, query], pattern, options, &blk)
|
36
|
+
end
|
37
|
+
alias_method :hashtags, :hashtag
|
38
|
+
|
39
|
+
def search(query, pattern = nil, options = {}, &blk)
|
40
|
+
add_handler([:search, query], pattern, options, &blk)
|
41
|
+
end
|
42
|
+
|
43
|
+
def after(event=:all, &blk)
|
44
|
+
add_hook :"after_#{event}", &blk
|
45
|
+
end
|
46
|
+
|
47
|
+
def before(event=:all, &blk)
|
48
|
+
add_hook :"before_#{event}", &blk
|
49
|
+
end
|
50
|
+
|
51
|
+
def twitter
|
52
|
+
bot.twitter
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :client, :twitter
|
56
|
+
|
57
|
+
def post_tweet(msg)
|
58
|
+
message = msg.respond_to?(:text) ? msg.text : msg
|
59
|
+
puts message
|
60
|
+
client.status(:post, message)
|
61
|
+
end
|
62
|
+
|
63
|
+
def post_reply(status, msg)
|
64
|
+
text = msg.respond_to?(:text) ? msg.text : msg
|
65
|
+
reply_to_screen_name = status.user.screen_name
|
66
|
+
reply_to_status_id = status.id
|
67
|
+
message = "@#{reply_to_screen_name} #{text}"
|
68
|
+
puts message
|
69
|
+
client.status(:reply, message, reply_to_status_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
def run?
|
73
|
+
!@@bot.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def add_handler(type, pattern, options, &blk)
|
78
|
+
bot.add_handler(type, Twibot::Handler.new(pattern, options, &blk))
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_hook(hook, &blk)
|
82
|
+
bot.add_hook(hook, &blk)
|
83
|
+
end
|
84
|
+
|
85
|
+
def bot
|
86
|
+
return @@bot unless @@bot.nil?
|
87
|
+
|
88
|
+
begin
|
89
|
+
@@bot = Twibot::Bot.new nil, true
|
90
|
+
rescue Exception
|
91
|
+
@@bot = Twibot::Bot.new(Twibot::Config.default << Twibot::CliConfig.new, true)
|
92
|
+
end
|
93
|
+
|
94
|
+
@@bot
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.bot=(bot)
|
98
|
+
@@bot = bot
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/twibot.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'twitter'
|
3
|
+
require 'twitter/client'
|
4
|
+
require 'yaml'
|
5
|
+
require File.join(File.dirname(__FILE__), 'hash')
|
6
|
+
|
7
|
+
module Twibot
|
8
|
+
|
9
|
+
# :stopdoc:
|
10
|
+
VERSION = '0.1.7'
|
11
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
12
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
13
|
+
# :startdoc:
|
14
|
+
|
15
|
+
# Returns the version string for the library.
|
16
|
+
#
|
17
|
+
def self.version
|
18
|
+
VERSION
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the library path for the module. If any arguments are given,
|
22
|
+
# they will be joined to the end of the libray path using
|
23
|
+
# <tt>File.join</tt>.
|
24
|
+
#
|
25
|
+
def self.libpath( *args )
|
26
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the lpath for the module. If any arguments are given,
|
30
|
+
# they will be joined to the end of the path using
|
31
|
+
# <tt>File.join</tt>.
|
32
|
+
#
|
33
|
+
def self.path( *args )
|
34
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Utility method used to require all files ending in .rb that lie in the
|
38
|
+
# directory below this file that has the same name as the filename passed
|
39
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
40
|
+
# the _filename_ does not have to be equivalent to the directory.
|
41
|
+
#
|
42
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
43
|
+
dir ||= File.basename(fname, '.*')
|
44
|
+
search_me = File.expand_path(File.join(File.dirname(fname), dir, '**', '*.rb'))
|
45
|
+
Dir.glob(search_me).sort.each {|rb| require rb }
|
46
|
+
end
|
47
|
+
|
48
|
+
@@app_file = lambda do
|
49
|
+
ignore = [
|
50
|
+
/lib\/twibot.*\.rb/, # Library
|
51
|
+
/\(.*\)/, # Generated code
|
52
|
+
/custom_require\.rb/ # RubyGems require
|
53
|
+
]
|
54
|
+
|
55
|
+
path = caller.map { |line| line.split(/:\d/, 2).first }.find do |file|
|
56
|
+
next if ignore.any? { |pattern| file =~ pattern }
|
57
|
+
file
|
58
|
+
end
|
59
|
+
|
60
|
+
path || $0
|
61
|
+
end.call
|
62
|
+
|
63
|
+
#
|
64
|
+
# File name of the application file. Inspired by Sinatra
|
65
|
+
#
|
66
|
+
def self.app_file
|
67
|
+
@@app_file
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Runs application if application file is the script being executed
|
72
|
+
#
|
73
|
+
def self.run?
|
74
|
+
self.app_file == $0
|
75
|
+
end
|
76
|
+
|
77
|
+
end # module Twibot
|
78
|
+
|
79
|
+
Twitter::Client.configure do |config|
|
80
|
+
config.application_name = 'Twibot'
|
81
|
+
config.application_version = Twibot.version
|
82
|
+
config.application_url = 'http://github.com/cjohansen/twibot'
|
83
|
+
end
|
84
|
+
|
85
|
+
Twibot.require_all_libs_relative_to(__FILE__)
|
86
|
+
|
87
|
+
# EOF
|
data/test/test_bot.rb
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) unless defined?(Twibot)
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
class TestBot < Test::Unit::TestCase
|
5
|
+
should "not raise errors when initialized" do
|
6
|
+
assert_nothing_raised do
|
7
|
+
Twibot::Bot.new Twibot::Config.new
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
should "raise errors when initialized without config file" do
|
12
|
+
assert_raise SystemExit do
|
13
|
+
Twibot::Bot.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
should "not raise error on initialize when config file exists" do
|
18
|
+
if File.exists?("config")
|
19
|
+
FileUtils.rm("config/bot.yml")
|
20
|
+
else
|
21
|
+
FileUtils.mkdir("config")
|
22
|
+
end
|
23
|
+
|
24
|
+
File.open("config/bot.yml", "w") { |f| f.puts "" }
|
25
|
+
|
26
|
+
assert_nothing_raised do
|
27
|
+
Twibot::Bot.new
|
28
|
+
end
|
29
|
+
|
30
|
+
FileUtils.rm_rf("config")
|
31
|
+
end
|
32
|
+
|
33
|
+
should "provide configuration settings as methods" do
|
34
|
+
bot = Twibot::Bot.new Twibot::Config.new(:max_interval => 3)
|
35
|
+
assert_equal 3, bot.max_interval
|
36
|
+
end
|
37
|
+
|
38
|
+
should "return logger instance" do
|
39
|
+
bot = Twibot::Bot.new(Twibot::Config.default << Twibot::Config.new)
|
40
|
+
assert bot.log.is_a?(Logger)
|
41
|
+
end
|
42
|
+
|
43
|
+
should "respect configured log level" do
|
44
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "info"))
|
45
|
+
assert_equal Logger::INFO, bot.log.level
|
46
|
+
|
47
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "warn"))
|
48
|
+
assert_equal Logger::WARN, bot.log.level
|
49
|
+
end
|
50
|
+
|
51
|
+
should "should return false from receive without handlers" do
|
52
|
+
bot = Twibot::Bot.new(Twibot::Config.new)
|
53
|
+
assert !bot.receive_messages
|
54
|
+
assert !bot.receive_replies
|
55
|
+
assert !bot.receive_tweets
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with the process option specified" do
|
59
|
+
setup do
|
60
|
+
@bot = Twibot::Bot.new(@config = Twibot::Config.default)
|
61
|
+
@bot.stubs(:prompt?).returns(false)
|
62
|
+
@bot.stubs(:twitter).returns(stub)
|
63
|
+
@bot.stubs(:processed).returns(stub)
|
64
|
+
|
65
|
+
# stop Bot actually starting during tests
|
66
|
+
@bot.stubs(:poll)
|
67
|
+
end
|
68
|
+
|
69
|
+
should "not process tweets prior to bot launch if :process option is set to :new" do
|
70
|
+
@bot.stubs(:handlers).returns({:tweet => [stub], :reply => []})
|
71
|
+
|
72
|
+
# Should fetch the latest ID for both messages and tweets
|
73
|
+
@bot.twitter.expects(:messages).with(:received, { :count => 1 }).
|
74
|
+
returns([stub(:id => (message_id = stub))]).once
|
75
|
+
@bot.twitter.expects(:timeline_for).with(:public, { :count => 1 }).
|
76
|
+
returns([stub(:id => (tweet_id = stub))]).once
|
77
|
+
|
78
|
+
# And set them to the since_id value to be used for future polling
|
79
|
+
@bot.processed.expects(:[]=).with(:message, message_id)
|
80
|
+
@bot.processed.expects(:[]=).with(:tweet, tweet_id)
|
81
|
+
@bot.processed.expects(:[]=).with(:reply, tweet_id)
|
82
|
+
|
83
|
+
@bot.configure { |c| c.process = :new }
|
84
|
+
@bot.run!
|
85
|
+
end
|
86
|
+
|
87
|
+
[:all, nil].each do |value|
|
88
|
+
should "process all tweets if :process option is set to #{value.inspect}" do
|
89
|
+
@bot.twitter.expects(:messages).never
|
90
|
+
@bot.twitter.expects(:timeline_for).never
|
91
|
+
|
92
|
+
# Shout not set the any value for the since_id tweets
|
93
|
+
@bot.processed.expects(:[]=).never
|
94
|
+
|
95
|
+
@bot.configure { |c| c.process = value }
|
96
|
+
@bot.run!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
should "process all tweets after the ID specified in the :process option" do
|
101
|
+
tweet_id = 12345
|
102
|
+
|
103
|
+
@bot.processed.expects(:[]=).with(anything, 12345).times(3)
|
104
|
+
|
105
|
+
@bot.configure { |c| c.process = tweet_id }
|
106
|
+
@bot.run!
|
107
|
+
end
|
108
|
+
|
109
|
+
should "raise exit when the :process option is not recognized" do
|
110
|
+
@bot.configure { |c| c.process = "something random" }
|
111
|
+
assert_raise(SystemExit) { @bot.run! }
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
should "receive message" do
|
117
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
118
|
+
bot.add_handler(:message, Twibot::Handler.new)
|
119
|
+
bot.twitter.expects(:messages).with(:received, {}).returns([twitter_message("cjno", "Hei der!")])
|
120
|
+
|
121
|
+
assert bot.receive_messages
|
122
|
+
end
|
123
|
+
|
124
|
+
should "remember last received message" do
|
125
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
126
|
+
bot.add_handler(:message, Twibot::Handler.new)
|
127
|
+
bot.twitter.expects(:messages).with(:received, {}).returns([twitter_message("cjno", "Hei der!")])
|
128
|
+
assert_equal 1, bot.receive_messages
|
129
|
+
|
130
|
+
bot.twitter.expects(:messages).with(:received, { :since_id => 1 }).returns([])
|
131
|
+
assert_equal 0, bot.receive_messages
|
132
|
+
end
|
133
|
+
|
134
|
+
should "receive tweet" do
|
135
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
136
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
137
|
+
bot.twitter.expects(:timeline_for).with(:public, {}).returns([tweet("cjno", "Hei der!")])
|
138
|
+
|
139
|
+
assert_equal 1, bot.receive_tweets
|
140
|
+
end
|
141
|
+
|
142
|
+
should "receive friend tweets if configured" do
|
143
|
+
bot = Twibot::Bot.new(Twibot::Config.new({:log_level => "error", :timeline_for => :friends}))
|
144
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
145
|
+
bot.twitter.expects(:timeline_for).with(:friends, {}).returns([tweet("cjno", "Hei der!")])
|
146
|
+
|
147
|
+
assert_equal 1, bot.receive_tweets
|
148
|
+
end
|
149
|
+
|
150
|
+
should "remember received tweets" do
|
151
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
152
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
153
|
+
bot.twitter.expects(:timeline_for).with(:public, {}).returns([tweet("cjno", "Hei der!")])
|
154
|
+
assert_equal 1, bot.receive_tweets
|
155
|
+
|
156
|
+
bot.twitter.expects(:timeline_for).with(:public, { :since_id => 1 }).returns([])
|
157
|
+
assert_equal 0, bot.receive_tweets
|
158
|
+
end
|
159
|
+
|
160
|
+
should "receive reply when tweet starts with login" do
|
161
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error", :login => "irbno"))
|
162
|
+
bot.add_handler(:reply, Twibot::Handler.new)
|
163
|
+
bot.twitter.expects(:status).with(:replies, {}).returns([tweet("cjno", "@irbno Hei der!")])
|
164
|
+
|
165
|
+
assert_equal 1, bot.receive_replies
|
166
|
+
end
|
167
|
+
|
168
|
+
should "remember received replies" do
|
169
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error", :login => "irbno"))
|
170
|
+
bot.add_handler(:reply, Twibot::Handler.new)
|
171
|
+
bot.twitter.expects(:status).with(:replies, {}).returns([tweet("cjno", "@irbno Hei der!")])
|
172
|
+
assert_equal 1, bot.receive_replies
|
173
|
+
|
174
|
+
bot.twitter.expects(:status).with(:replies, { :since_id => 1 }).returns([])
|
175
|
+
assert_equal 0, bot.receive_replies
|
176
|
+
end
|
177
|
+
|
178
|
+
should "use public as default timeline method for tweet 'verb'" do
|
179
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
180
|
+
assert_equal :public, bot.instance_eval { @config.to_hash[:timeline_for] }
|
181
|
+
end
|
182
|
+
|
183
|
+
context "sandboxed network errors" do
|
184
|
+
should "rescue certain errors" do
|
185
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
186
|
+
|
187
|
+
assert_nothing_raised do
|
188
|
+
bot.send(:sandbox) { raise Twitter::RESTError.new }
|
189
|
+
bot.send(:sandbox) { raise Errno::ECONNRESET.new }
|
190
|
+
bot.send(:sandbox) { raise Timeout::Error.new }
|
191
|
+
bot.send(:sandbox) { raise EOFError.new }
|
192
|
+
bot.send(:sandbox) { raise Errno::ETIMEDOUT.new }
|
193
|
+
bot.send(:sandbox) { raise JSON::ParserError.new }
|
194
|
+
bot.send(:sandbox) { raise OpenSSL::SSL::SSLError.new }
|
195
|
+
bot.send(:sandbox) { raise SystemStackError.new }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
should "return default value if error is rescued" do
|
200
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
201
|
+
assert_equal(42, bot.send(:sandbox, 42) { raise Twitter::RESTError })
|
202
|
+
end
|
203
|
+
|
204
|
+
should "not return default value when no error was raised" do
|
205
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
206
|
+
assert_equal(65, bot.send(:sandbox, 42) { 65 })
|
207
|
+
end
|
208
|
+
|
209
|
+
should "not swallow unknown errors" do
|
210
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
211
|
+
|
212
|
+
assert_raise StandardError do
|
213
|
+
bot.send(:sandbox) { raise StandardError.new "Oops!" }
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class TestBotMacros < Test::Unit::TestCase
|
220
|
+
should "provide configure macro" do
|
221
|
+
assert respond_to?(:configure)
|
222
|
+
end
|
223
|
+
|
224
|
+
should "yield configuration" do
|
225
|
+
Twibot::Macros.bot = Twibot::Bot.new Twibot::Config.default
|
226
|
+
bot.prompt = false
|
227
|
+
|
228
|
+
conf = nil
|
229
|
+
assert_nothing_raised { configure { |c| conf = c } }
|
230
|
+
assert conf.is_a?(Twibot::Config)
|
231
|
+
end
|
232
|
+
|
233
|
+
should "add handler" do
|
234
|
+
Twibot::Macros.bot = Twibot::Bot.new Twibot::Config.default
|
235
|
+
bot.prompt = false
|
236
|
+
|
237
|
+
handler = add_handler(:message, ":command", :from => :cjno)
|
238
|
+
assert handler.is_a?(Twibot::Handler), handler.class
|
239
|
+
end
|
240
|
+
|
241
|
+
should "provide twitter macro" do
|
242
|
+
assert respond_to?(:twitter)
|
243
|
+
assert respond_to?(:client)
|
244
|
+
end
|
245
|
+
|
246
|
+
context "posting replies" do
|
247
|
+
should "work with string messages" do
|
248
|
+
text = "Hey there"
|
249
|
+
status = Twitter::Status.new(:id => 123,
|
250
|
+
:text => "Some text",
|
251
|
+
:user => Twitter::User.new(:screen_name => "cjno"))
|
252
|
+
client.expects(:status).with(:reply, "@cjno #{text}", 123).returns(true)
|
253
|
+
|
254
|
+
assert post_reply(status, text)
|
255
|
+
end
|
256
|
+
|
257
|
+
should "work with status object messages" do
|
258
|
+
reply = Twitter::Status.new :text => "Hey there"
|
259
|
+
status = Twitter::Status.new(:id => 123,
|
260
|
+
:text => "Some text",
|
261
|
+
:user => Twitter::User.new(:screen_name => "cjno"))
|
262
|
+
client.expects(:status).with(:reply, "@cjno Hey there", 123).returns(true)
|
263
|
+
|
264
|
+
assert post_reply(status, reply)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class TestBotHandlers < Test::Unit::TestCase
|
270
|
+
|
271
|
+
should "include handlers" do
|
272
|
+
bot = Twibot::Bot.new(Twibot::Config.new)
|
273
|
+
|
274
|
+
assert_not_nil bot.handlers
|
275
|
+
assert_not_nil bot.handlers[:message]
|
276
|
+
assert_not_nil bot.handlers[:reply]
|
277
|
+
assert_not_nil bot.handlers[:tweet]
|
278
|
+
end
|
279
|
+
|
280
|
+
should "add handler" do
|
281
|
+
bot = Twibot::Bot.new(Twibot::Config.new)
|
282
|
+
bot.add_handler :message, Twibot::Handler.new
|
283
|
+
assert_equal 1, bot.handlers[:message].length
|
284
|
+
|
285
|
+
bot.add_handler :message, Twibot::Handler.new
|
286
|
+
assert_equal 2, bot.handlers[:message].length
|
287
|
+
|
288
|
+
bot.add_handler :reply, Twibot::Handler.new
|
289
|
+
assert_equal 1, bot.handlers[:reply].length
|
290
|
+
|
291
|
+
bot.add_handler :reply, Twibot::Handler.new
|
292
|
+
assert_equal 2, bot.handlers[:reply].length
|
293
|
+
|
294
|
+
bot.add_handler :tweet, Twibot::Handler.new
|
295
|
+
assert_equal 1, bot.handlers[:tweet].length
|
296
|
+
|
297
|
+
bot.add_handler :tweet, Twibot::Handler.new
|
298
|
+
assert_equal 2, bot.handlers[:tweet].length
|
299
|
+
end
|
300
|
+
end
|
data/test/test_config.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) unless defined?(Twibot)
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class TestConfig < Test::Unit::TestCase
|
5
|
+
should "default configuration be a hash" do
|
6
|
+
assert_not_nil Twibot::Config::DEFAULT
|
7
|
+
assert Twibot::Config::DEFAULT.is_a?(Hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
should "initialize with no options" do
|
11
|
+
assert_hashes_equal({}, Twibot::Config.new.settings)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "return config from add" do
|
15
|
+
config = Twibot::Config.new
|
16
|
+
assert_equal config, config.add(Twibot::Config.new)
|
17
|
+
end
|
18
|
+
|
19
|
+
should "alias add to <<" do
|
20
|
+
config = Twibot::Config.new
|
21
|
+
assert config.respond_to?(:<<)
|
22
|
+
assert config << Twibot::Config.new
|
23
|
+
end
|
24
|
+
|
25
|
+
should "mirror method_missing as config getters" do
|
26
|
+
config = Twibot::Config.default << Twibot::Config.new
|
27
|
+
assert_equal Twibot::Config::DEFAULT[:min_interval], config.min_interval
|
28
|
+
assert_equal Twibot::Config::DEFAULT[:login], config.login
|
29
|
+
end
|
30
|
+
|
31
|
+
should "mirror missing methods as config setters" do
|
32
|
+
config = Twibot::Config.default << Twibot::Config.new
|
33
|
+
assert_equal Twibot::Config::DEFAULT[:min_interval], config.min_interval
|
34
|
+
|
35
|
+
val = config.min_interval
|
36
|
+
config.min_interval = val + 5
|
37
|
+
assert_not_equal Twibot::Config::DEFAULT[:min_interval], config.min_interval
|
38
|
+
assert_equal val + 5, config.min_interval
|
39
|
+
end
|
40
|
+
|
41
|
+
should "not override default hash" do
|
42
|
+
config = Twibot::Config.default
|
43
|
+
hash = Twibot::Config::DEFAULT
|
44
|
+
|
45
|
+
config.min_interval = 0
|
46
|
+
config.max_interval = 0
|
47
|
+
|
48
|
+
assert_hashes_not_equal Twibot::Config::DEFAULT, config.to_hash
|
49
|
+
assert_hashes_equal hash, Twibot::Config::DEFAULT
|
50
|
+
end
|
51
|
+
|
52
|
+
should "return merged configuration from to_hash" do
|
53
|
+
config = Twibot::Config.new
|
54
|
+
config.min_interval = 10
|
55
|
+
config.max_interval = 10
|
56
|
+
|
57
|
+
config2 = Twibot::Config.new({})
|
58
|
+
config2.min_interval = 1
|
59
|
+
config << config2
|
60
|
+
options = config.to_hash
|
61
|
+
|
62
|
+
assert_equal 10, options[:max_interval]
|
63
|
+
assert_equal 1, options[:min_interval]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class TestCliConfig < Test::Unit::TestCase
|
68
|
+
should "configure from options" do
|
69
|
+
config = Twibot::CliConfig.new %w{--min-interval 10 --max-interval 15}
|
70
|
+
assert_equal 10, config.min_interval
|
71
|
+
assert_equal 15, config.max_interval
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class TestFileConfig < Test::Unit::TestCase
|
76
|
+
should "subclass config for file config" do
|
77
|
+
assert Twibot::FileConfig.new(StringIO.new).is_a?(Twibot::Config)
|
78
|
+
end
|
79
|
+
|
80
|
+
should "read settings from stream" do
|
81
|
+
config = Twibot::FileConfig.new(StringIO.new <<-YAML)
|
82
|
+
min_interval: 10
|
83
|
+
max_interval: 20
|
84
|
+
YAML
|
85
|
+
|
86
|
+
assert_equal 10, config.min_interval
|
87
|
+
assert_equal 20, config.max_interval
|
88
|
+
end
|
89
|
+
end
|