bjeanes-twibot 0.1.6
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 +24 -0
- data/Rakefile +30 -0
- data/Readme.rdoc +175 -0
- data/lib/hash.rb +8 -0
- data/lib/twibot/bot.rb +231 -0
- data/lib/twibot/config.rb +138 -0
- data/lib/twibot/handlers.rb +111 -0
- data/lib/twibot/macros.rb +66 -0
- data/lib/twibot/tweets.rb +4 -0
- data/lib/twibot.rb +87 -0
- data/test/test_bot.rb +185 -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 +95 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
module Twibot
|
2
|
+
module Handlers
|
3
|
+
#
|
4
|
+
# Add a handler for this bot
|
5
|
+
#
|
6
|
+
def add_handler(type, handler)
|
7
|
+
handlers[type] << handler
|
8
|
+
handler
|
9
|
+
end
|
10
|
+
|
11
|
+
def dispatch(type, message)
|
12
|
+
handlers[type].each { |handler| handler.dispatch(message) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def handlers
|
16
|
+
@handlers ||= {
|
17
|
+
:message => [],
|
18
|
+
:reply => [],
|
19
|
+
:tweet => []
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def handlers=(hash)
|
24
|
+
@handlers = hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# A Handler object is an object which can handle a direct message, tweet or
|
30
|
+
# at reply.
|
31
|
+
#
|
32
|
+
class Handler
|
33
|
+
def initialize(pattern = nil, options = {}, &blk)
|
34
|
+
if pattern.is_a?(Hash)
|
35
|
+
options = pattern
|
36
|
+
pattern = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
@options = options
|
40
|
+
@options[:from].collect! { |s| s.to_s } if @options[:from] && @options[:from].is_a?(Array)
|
41
|
+
@options[:from] = [@options[:from].to_s] if @options[:from] && @options[:from].is_a?(String)
|
42
|
+
@handler = nil
|
43
|
+
@handler = block_given? ? blk : nil
|
44
|
+
self.pattern = pattern
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Parse pattern string and set options
|
49
|
+
#
|
50
|
+
def pattern=(pattern)
|
51
|
+
return if pattern.nil? || pattern == ""
|
52
|
+
|
53
|
+
if pattern.is_a?(Regexp)
|
54
|
+
@options[:pattern] = pattern
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
words = pattern.split.collect { |s| s.strip } # Get all words in pattern
|
59
|
+
@options[:tokens] = words.inject([]) do |sum, token| # Find all tokens, ie :symbol :like :names
|
60
|
+
next sum unless token =~ /^:.*/ # Don't process regular words
|
61
|
+
sym = token.sub(":", "").to_sym # Turn token string into symbol, ie ":token" => :token
|
62
|
+
regex = @options[sym] || '[^\s]+' # Fetch regex if configured, else use any character but space matching
|
63
|
+
pattern.sub!(/(^|\s)#{token}(\s|$)/, '\1(' + regex.to_s + ')\2') # Make sure regex captures named switch
|
64
|
+
sum << sym
|
65
|
+
end
|
66
|
+
|
67
|
+
@options[:pattern] = /#{pattern}(\s.+)?/
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Determines if this handler is suited to handle an incoming message
|
72
|
+
#
|
73
|
+
def recognize?(message)
|
74
|
+
return false if @options[:pattern] && message.text !~ @options[:pattern] # Pattern check
|
75
|
+
|
76
|
+
users = @options[:from] ? @options[:from] : nil
|
77
|
+
sender = message.respond_to?(:sender) ? message.sender : message.user
|
78
|
+
return false if users && !users.include?(sender.screen_name.downcase) # Check allowed senders
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Process message to build params hash and pass message along with params of
|
84
|
+
# to +handle+
|
85
|
+
#
|
86
|
+
def dispatch(message)
|
87
|
+
return unless recognize?(message)
|
88
|
+
@params = {}
|
89
|
+
|
90
|
+
if @options[:pattern] && @options[:tokens]
|
91
|
+
matches = message.text.match(@options[:pattern])
|
92
|
+
@options[:tokens].each_with_index { |token, i| @params[token] = matches[i+1] }
|
93
|
+
@params[:text] = (matches[@options[:tokens].length+1] || "").strip
|
94
|
+
elsif @options[:pattern] && !@options[:tokens]
|
95
|
+
@params = message.text.match(@options[:pattern]).to_a[1..-1] || []
|
96
|
+
else
|
97
|
+
@params[:text] = message.text
|
98
|
+
end
|
99
|
+
|
100
|
+
handle(message, @params)
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Handle a message. Calls the internal Proc with the message and the params
|
105
|
+
# hash as parameters.
|
106
|
+
#
|
107
|
+
def handle(message, params)
|
108
|
+
@handler.call(message, params) if @handler
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,66 @@
|
|
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 twitter
|
30
|
+
bot.twitter
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :client, :twitter
|
34
|
+
|
35
|
+
def post_tweet(msg)
|
36
|
+
message = msg.respond_to?(:text) ? msg.text : msg
|
37
|
+
puts message
|
38
|
+
client.status(:post, message)
|
39
|
+
end
|
40
|
+
|
41
|
+
def run?
|
42
|
+
!@@bot.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def add_handler(type, pattern, options, &blk)
|
47
|
+
bot.add_handler(type, Twibot::Handler.new(pattern, options, &blk))
|
48
|
+
end
|
49
|
+
|
50
|
+
def bot
|
51
|
+
return @@bot unless @@bot.nil?
|
52
|
+
|
53
|
+
begin
|
54
|
+
@@bot = Twibot::Bot.new nil, true
|
55
|
+
rescue Exception
|
56
|
+
@@bot = Twibot::Bot.new(Twibot::Config.default << Twibot::CliConfig.new, true)
|
57
|
+
end
|
58
|
+
|
59
|
+
@@bot
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.bot=(bot)
|
63
|
+
@@bot = bot
|
64
|
+
end
|
65
|
+
end
|
66
|
+
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.6'
|
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,185 @@
|
|
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
|
+
should "receive message" do
|
59
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
60
|
+
bot.add_handler(:message, Twibot::Handler.new)
|
61
|
+
Twitter::Client.any_instance.expects(:messages).with(:received, {}).returns([twitter_message("cjno", "Hei der!")])
|
62
|
+
|
63
|
+
assert bot.receive_messages
|
64
|
+
end
|
65
|
+
|
66
|
+
should "remember last received message" do
|
67
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
68
|
+
bot.add_handler(:message, Twibot::Handler.new)
|
69
|
+
Twitter::Client.any_instance.expects(:messages).with(:received, {}).returns([twitter_message("cjno", "Hei der!")])
|
70
|
+
assert_equal 1, bot.receive_messages
|
71
|
+
|
72
|
+
Twitter::Client.any_instance.expects(:messages).with(:received, { :since_id => 1 }).returns([])
|
73
|
+
assert_equal 0, bot.receive_messages
|
74
|
+
end
|
75
|
+
|
76
|
+
should "receive tweet" do
|
77
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
78
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
79
|
+
Twitter::Client.any_instance.expects(:timeline_for).with(:me, {}).returns([tweet("cjno", "Hei der!")])
|
80
|
+
|
81
|
+
assert_equal 1, bot.receive_tweets
|
82
|
+
end
|
83
|
+
|
84
|
+
should "receive friend tweets if configured" do
|
85
|
+
bot = Twibot::Bot.new(Twibot::Config.new({:log_level => "error", :include_friends => true}))
|
86
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
87
|
+
Twitter::Client.any_instance.expects(:timeline_for).with(:friends, {}).returns([tweet("cjno", "Hei der!")])
|
88
|
+
|
89
|
+
assert_equal 1, bot.receive_tweets
|
90
|
+
end
|
91
|
+
|
92
|
+
should "remember received tweets" do
|
93
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error"))
|
94
|
+
bot.add_handler(:tweet, Twibot::Handler.new)
|
95
|
+
Twitter::Client.any_instance.expects(:timeline_for).with(:me, {}).returns([tweet("cjno", "Hei der!")])
|
96
|
+
assert_equal 1, bot.receive_tweets
|
97
|
+
|
98
|
+
Twitter::Client.any_instance.expects(:timeline_for).with(:me, { :since_id => 1 }).returns([])
|
99
|
+
assert_equal 0, bot.receive_tweets
|
100
|
+
end
|
101
|
+
|
102
|
+
should "receive reply when tweet starts with login" do
|
103
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error", :login => "irbno"))
|
104
|
+
bot.add_handler(:reply, Twibot::Handler.new)
|
105
|
+
Twitter::Client.any_instance.expects(:status).with(:replies, {}).returns([tweet("cjno", "@irbno Hei der!")])
|
106
|
+
|
107
|
+
assert_equal 1, bot.receive_replies
|
108
|
+
end
|
109
|
+
|
110
|
+
should "remember received replies" do
|
111
|
+
bot = Twibot::Bot.new(Twibot::Config.new(:log_level => "error", :login => "irbno"))
|
112
|
+
bot.add_handler(:reply, Twibot::Handler.new)
|
113
|
+
Twitter::Client.any_instance.expects(:status).with(:replies, {}).returns([tweet("cjno", "@irbno Hei der!")])
|
114
|
+
assert_equal 1, bot.receive_replies
|
115
|
+
|
116
|
+
Twitter::Client.any_instance.expects(:status).with(:replies, { :since_id => 1 }).returns([])
|
117
|
+
assert_equal 0, bot.receive_replies
|
118
|
+
end
|
119
|
+
|
120
|
+
should "use public as default timeline method for tweet 'verb'" do
|
121
|
+
bot = Twibot::Bot.new(Twibot::Config.default)
|
122
|
+
assert_equal :public, bot.instance_eval { @config.to_hash[:timeline_for] }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class TestBotMacros < Test::Unit::TestCase
|
127
|
+
should "provide configure macro" do
|
128
|
+
assert respond_to?(:configure)
|
129
|
+
end
|
130
|
+
|
131
|
+
should "yield configuration" do
|
132
|
+
Twibot::Macros.bot = Twibot::Bot.new Twibot::Config.default
|
133
|
+
bot.prompt = false
|
134
|
+
|
135
|
+
conf = nil
|
136
|
+
assert_nothing_raised { configure { |c| conf = c } }
|
137
|
+
assert conf.is_a?(Twibot::Config)
|
138
|
+
end
|
139
|
+
|
140
|
+
should "add handler" do
|
141
|
+
Twibot::Macros.bot = Twibot::Bot.new Twibot::Config.default
|
142
|
+
bot.prompt = false
|
143
|
+
|
144
|
+
handler = add_handler(:message, ":command", :from => :cjno)
|
145
|
+
assert handler.is_a?(Twibot::Handler), handler.class
|
146
|
+
end
|
147
|
+
|
148
|
+
should "provide twitter macro" do
|
149
|
+
assert respond_to?(:twitter)
|
150
|
+
assert respond_to?(:client)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class TestBotHandlers < Test::Unit::TestCase
|
155
|
+
|
156
|
+
should "include handlers" do
|
157
|
+
bot = Twibot::Bot.new(Twibot::Config.new)
|
158
|
+
|
159
|
+
assert_not_nil bot.handlers
|
160
|
+
assert_not_nil bot.handlers[:message]
|
161
|
+
assert_not_nil bot.handlers[:reply]
|
162
|
+
assert_not_nil bot.handlers[:tweet]
|
163
|
+
end
|
164
|
+
|
165
|
+
should "add handler" do
|
166
|
+
bot = Twibot::Bot.new(Twibot::Config.new)
|
167
|
+
bot.add_handler :message, Twibot::Handler.new
|
168
|
+
assert_equal 1, bot.handlers[:message].length
|
169
|
+
|
170
|
+
bot.add_handler :message, Twibot::Handler.new
|
171
|
+
assert_equal 2, bot.handlers[:message].length
|
172
|
+
|
173
|
+
bot.add_handler :reply, Twibot::Handler.new
|
174
|
+
assert_equal 1, bot.handlers[:reply].length
|
175
|
+
|
176
|
+
bot.add_handler :reply, Twibot::Handler.new
|
177
|
+
assert_equal 2, bot.handlers[:reply].length
|
178
|
+
|
179
|
+
bot.add_handler :tweet, Twibot::Handler.new
|
180
|
+
assert_equal 1, bot.handlers[:tweet].length
|
181
|
+
|
182
|
+
bot.add_handler :tweet, Twibot::Handler.new
|
183
|
+
assert_equal 2, bot.handlers[:tweet].length
|
184
|
+
end
|
185
|
+
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
|