chewbranca-twibot 0.1.7.2
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/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
|