cinch 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -10,7 +10,11 @@ plugin, defining a rule, and watching your profits flourish.
10
10
  Cinch will do all of the hard work for you, so you can spend time creating cool plugins
11
11
  and extensions to wow your internet peers.
12
12
 
13
+ Cinch is not a fully fledged IRC framework, its base is extremely small. If you're looking
14
+ for a more controlled library check out {silverplatter-irc}[http://github.com/apeiros/silverplatter-irc].
15
+
13
16
  == Installation
17
+ The latest version of Cinch is 0.2
14
18
 
15
19
  === RubyGems
16
20
  You can install the latest version of Cinch using RubyGems
@@ -95,9 +99,28 @@ the rules given, for example if we want to reply only if the nick sending the me
95
99
  could pass the 'nick' option to the hash.
96
100
 
97
101
  bot.plugin("join :channel", :nick => 'injekt') do |m|
98
- m.join #{m.args[:channel]}
102
+ bot.join #{m.args[:channel]}
103
+ end
104
+
105
+ == Named Parameter Types
106
+ Since version 0.2, Cinch supports named parameter types. Although at the moment you're constrained
107
+ to the <i>digit</i>, <i>string</i> and <i>word</i> types. It means stuff like the this works:
108
+
109
+ bot.plugin("say :n-digit :text") do |m|
110
+ m.args[:n].to_i.times {
111
+ m.reply m.args[:text]
112
+ end
99
113
  end
100
114
 
115
+ This would provide the following output on IRC
116
+
117
+ injekt> !say foo bar
118
+ injekt> !say 2 foo bar
119
+ Cinch> foo bar
120
+ Cinch> foo bar
121
+
122
+ * See Cinch::Base#compile for more information
123
+
101
124
  == Authors
102
125
  Just me at the moment, sad poor lonely me...
103
126
  * {Lee Jarvis}[http://blog.injekt.net]
data/examples/hello.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch.setup do
4
+ server "irc.freenode.org"
5
+ channels %w( #cinch )
6
+ end
7
+
8
+ bot.plugin "hello" do |m|
9
+ m.reply "Hello, #{m.nick}!"
10
+ end
11
+
12
+ bot.run
13
+
@@ -0,0 +1,26 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch.setup do
4
+ server "irc.freenode.org"
5
+ nick "CinchBot"
6
+ channels %w( #cinch )
7
+ end
8
+
9
+ # Who should be able to access these plugins
10
+ admin = 'injekt'
11
+
12
+ bot.plugin "join :channel", :nick => admin do |m|
13
+ bot.join m.args[:channel]
14
+ end
15
+
16
+ bot.plugin "part :channel", :nick => admin do |m|
17
+ bot.part m.args[:channel]
18
+ end
19
+
20
+ # Part current channel if none is given
21
+ bot.plugin "part", :nick => admin do |m|
22
+ bot.part m.channel
23
+ end
24
+
25
+ bot.run
26
+
data/examples/msg.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch.setup do
4
+ server "irc.freenode.org"
5
+ nick "CinchBot"
6
+ channels %w/ #cinch /
7
+ end
8
+
9
+ bot.plugin("msg :who :text") do |m|
10
+ bot.privmsg m.args[:who], m.args[:text]
11
+ end
12
+
13
+ bot.run
14
+
@@ -0,0 +1,19 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch.setup do
4
+ server "irc.freenode.org"
5
+ channels %w( #cinch )
6
+ end
7
+
8
+ bot.plugin("say :n-digit :text") do |m|
9
+ m.args[:n].to_i.times {
10
+ m.reply m.args[:text]
11
+ }
12
+ end
13
+
14
+ bot.plugin("say :text-word :rest") do |m|
15
+ stuff = [m.args[:text], m.args[:rest]].join(' ')
16
+ m.reply stuff
17
+ end
18
+
19
+ bot.run
data/examples/seen.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'cinch'
2
+
3
+ users = {}
4
+
5
+ class Seen < Struct.new(:who, :where, :what, :time)
6
+ def to_s
7
+ "[#{time.asctime}] #{who} was seen in #{where} saying #{what}"
8
+ end
9
+ end
10
+
11
+ bot = Cinch.setup(
12
+ :server => 'irc.freenode.org',
13
+ :channels => ['#cinch'],
14
+ :prefix => '!',
15
+ :verbose => true,
16
+ )
17
+
18
+ # Only log a PRIVMSG
19
+ bot.on :privmsg do |m|
20
+ # Dont record a private message
21
+ unless m.private?
22
+ users[m.nick] = Seen.new(m.nick, m.channel, m.text, Time.new)
23
+ end
24
+ end
25
+
26
+ bot.plugin("seen :nick foo") do |m|
27
+ nick = m.args[:nick]
28
+
29
+ if nick == bot.nick
30
+ m.reply "That's me!"
31
+ elsif nick == m.nick
32
+ m.reply "That's you!"
33
+ elsif users.key?(nick)
34
+ m.reply users[nick].to_s
35
+ else
36
+ m.reply "I haven't seen #{nick}"
37
+ end
38
+ end
39
+
40
+ bot.run
41
+
data/lib/cinch.rb CHANGED
@@ -5,10 +5,11 @@ require 'ostruct'
5
5
  require 'optparse'
6
6
 
7
7
  require 'cinch/irc'
8
+ require 'cinch/rules'
8
9
  require 'cinch/base'
9
10
 
10
11
  module Cinch
11
- VERSION = '0.1'
12
+ VERSION = '0.2'
12
13
 
13
14
  # Setup bot options and return a new Cinch::Base instance
14
15
  def self.setup(ops={}, &blk)
data/lib/cinch/base.rb CHANGED
@@ -60,7 +60,7 @@ module Cinch
60
60
  options = DEFAULTS.merge(ops).merge(Options.new(&blk))
61
61
  @options = OpenStruct.new(options.merge(cli_ops))
62
62
 
63
- @rules = {}
63
+ @rules = Rules.new
64
64
  @listeners = {}
65
65
 
66
66
  @irc = IRC::Socket.new(options[:server], options[:port])
@@ -85,12 +85,15 @@ module Cinch
85
85
  op.on("-n nick") {|v| options[:nick] = v }
86
86
  op.on("-c command_prefix") {|v| options[:prefix] = v }
87
87
  op.on("-v", "--verbose", "Enable verbose mode") {|v| options[:verbose] = true }
88
- op.on("-j", "--channels x,y,z", Array, "Autojoin channels") {|v|
88
+ op.on("-C", "--channels x,y,z", Array, "Autojoin channels") {|v|
89
89
  options[:channels] = v.map {|c| %w(# + &).include?(c[0].chr) ? c : c.insert(0, '#') }
90
90
  }
91
91
  end.parse(ARGV)
92
92
  rescue OptionParser::MissingArgument => err
93
- warn "Missing values for options: #{err.args.join(', ')}\nFalling back to default"
93
+ warn "Missing values for options: #{err.args.join(', ')}\nFalling back to default"
94
+ rescue OptionParser::InvalidOption => err
95
+ warn err.message
96
+ exit
94
97
  end
95
98
  end
96
99
  options
@@ -104,7 +107,13 @@ module Cinch
104
107
  # end
105
108
  def plugin(rule, options={}, &blk)
106
109
  rule, keys = compile(rule)
107
- add_rule(rule, keys, options, &blk)
110
+
111
+ if @rules.has_rule?(rule)
112
+ @rules.add_callback(rule, blk)
113
+ @rules.merge_options(rule, options)
114
+ else
115
+ @rules.add_rule(rule, keys, options, blk)
116
+ end
108
117
  end
109
118
 
110
119
  # Add new listeners
@@ -123,35 +132,80 @@ module Cinch
123
132
  end
124
133
  end
125
134
 
126
- # Compile a rule string into regexp
135
+ # This method builds a regular expression from your rule
136
+ # and defines all named parameters, as well as dealing with
137
+ # types.
138
+ #
139
+ # So far 3 types are supported:
140
+ #
141
+ # * word - matches [a-zA-Z]+
142
+ # * string - matches \w+
143
+ # * digit - matches \d+
144
+ #
145
+ # == Examples
146
+ # For capturing individual words
147
+ # bot.plugin("say :text-word")
148
+ # * Does match !say foo
149
+ # * Does not match !say foo bar baz
150
+ #
151
+ # For capturing digits
152
+ # bot.plugin("say :text-digit")
153
+ # * Does match !say 3
154
+ # * Does not match !say 3 4
155
+ # * Does not match !say foo
156
+ #
157
+ # For both
158
+ # bot.plugin("say :n-digit :text-word")
159
+ # * Does match !say 3 foo
160
+ # * Does not match !say 3 foo bar
161
+ #
162
+ # For capturing until the end of the line
163
+ # bot.plugin("say :text")
164
+ # * Does match !say foo
165
+ # * Does match !say foo bar
166
+ #
167
+ # Or mix them all
168
+ # bot.plugin("say :n-digit :who-word :text")
169
+ #
170
+ # Using "!say 3 injekt some text here" would provide
171
+ # the following attributes
172
+ # m.args[:n] => 3
173
+ # m.args[:who] => injekt
174
+ # m.args[:text] => some text here
127
175
  def compile(rule)
128
- return [rule []] if rule.is_a?(Regexp)
176
+ return [rule, []] if rule.is_a?(Regexp)
129
177
  keys = []
130
178
  special_chars = %w{. + ( )}
131
179
 
132
- pattern = rule.to_s.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
180
+ pattern = rule.to_s.gsub(/((:[\w\-]+)|[\*#{special_chars.join}])/) do |match|
133
181
  case match
134
182
  when *special_chars
135
183
  Regexp.escape(match)
136
184
  else
137
- keys << $2[1..-1]
138
- "([^\x00\r\n]+?)"
185
+ k = $2
186
+ if k =~ /\-(\w+)$/
187
+ key, type = k.split('-')
188
+ keys << key[1..-1]
189
+
190
+ case type
191
+ when 'digit'; "(\\d+?)"
192
+ when 'word'; "([a-zA-Z]+?)"
193
+ when 'string'; "(\\w+?)"
194
+ else
195
+ "([^\x00\r\n]+?)"
196
+ end
197
+ else
198
+ keys << k[1..-1]
199
+ "([^\x00\r\n]+?)"
200
+ end
139
201
  end
140
202
  end
141
203
  ["^#{pattern}$", keys]
142
204
  end
143
205
 
144
- # Add a new rule, or add to an existing one if it
145
- # already exists
146
- def add_rule(rule, keys, options={}, &blk)
147
- unless @rules.key?(rule)
148
- @rules[rule] = [rule, keys, options, blk]
149
- end
150
- end
151
-
152
206
  # Run run run
153
- def run
154
- @irc.connect
207
+ def run
208
+ @irc.connect options.server, options.port
155
209
  @irc.nick options.nick
156
210
  @irc.user options.username, options.usermode, '*', options.realname
157
211
 
@@ -166,6 +220,7 @@ module Cinch
166
220
 
167
221
  # Process the next line read from the server
168
222
  def process(line)
223
+ return unless line
169
224
  message = @parser.parse(line)
170
225
  message.irc = @irc
171
226
  puts message if options.verbose
@@ -175,40 +230,21 @@ module Cinch
175
230
  end
176
231
 
177
232
  if [:privmsg].include?(message.symbol)
178
- rules.each_value do |attr|
179
- rule, keys, ops, blk = attr
180
- args = {}
181
-
182
- unless ops.has_key?(:prefix) || options.prefix == false
183
- rule.insert(1, options.prefix) unless rule[1].chr == options.prefix
233
+ rules.each do |rule|
234
+ unless rule.options.key?(:prefix) || options.prefix == false
235
+ rule.to_s.insert(1, options.prefix) unless rule.to_s[1].chr == options.prefix
184
236
  end
185
237
 
186
- if message.text && mdata = message.text.match(Regexp.new(rule))
187
- unless keys.empty? || mdata.captures.empty?
188
- args = Hash[keys.map {|k| k.to_sym}.zip(mdata.captures)]
238
+ if message.text && mdata = message.text.match(Regexp.new(rule.to_s))
239
+ unless rule.keys.empty? || mdata.captures.empty?
240
+ args = Hash[rule.keys.map {|k| k.to_sym}.zip(mdata.captures)]
189
241
  message.args = args
190
- end
191
- execute_rule(message, ops, blk)
192
- end
193
- end
194
- end
195
- end
196
-
197
- # Execute a rule
198
- def execute_rule(message, ops, blk)
199
- ops.keys.each do |k|
200
- case k
201
- when :nick; return unless ops[:nick] == message.nick
202
- when :user; return unless ops[:user] == message.user
203
- when :host; return unless ops[:host] == message.host
204
- when :channel
205
- if message.channel
206
- return unless ops[:channel] == message.channel
242
+ end
243
+ # execute rule
244
+ rule.execute(message)
207
245
  end
208
246
  end
209
247
  end
210
-
211
- blk.call(message)
212
248
  end
213
249
 
214
250
  # Catch methods
@@ -80,7 +80,7 @@ module Cinch
80
80
  # Parse the incoming raw IRC string and return
81
81
  # a nicely formatted IRC::Message
82
82
  def parse_servermessage(raw)
83
- raise ArgumentError, raw unless matches = raw.match(pattern(:message))
83
+ raise ArgumentError, raw unless raw && matches = raw.match(pattern(:message))
84
84
 
85
85
  prefix, command, parameters = matches.captures
86
86
 
@@ -87,8 +87,11 @@ module Cinch
87
87
 
88
88
  # Connect to an IRC server, returns true on a successful connection, or
89
89
  # raises otherwise
90
- def connect
91
- @socket = TCPSocket.new(server, port)
90
+ def connect(server=nil, port=nil)
91
+ @server = server if server
92
+ @port = port if port
93
+
94
+ @socket = TCPSocket.new(@server, @port)
92
95
  rescue Interrupt
93
96
  raise
94
97
  rescue Exception
@@ -0,0 +1,161 @@
1
+ module Cinch
2
+
3
+ # == Author
4
+ # * Lee Jarvis - ljjarvis@gmail.com
5
+ #
6
+ # == Description
7
+ # Every rule defined through the Cinch::Base#plugin method becomes an instance
8
+ # of this class. Each rule consists of keys used for named parameters, a hash
9
+ # of options, and an Array of callbacks.
10
+ #
11
+ # When a rule matches an IRC message, all options with be checked, then all
12
+ # callbacks will be invoked.
13
+ class Rule < Struct.new(:rule, :keys, :options, :callbacks)
14
+ def initialize(rule, keys, options, callback)
15
+ callbacks = [callback]
16
+ super(rule, keys, options, callbacks)
17
+ end
18
+
19
+ # Execute all callbacks, passing an Cinch::IRC::Message to them
20
+ def execute(message)
21
+ options.keys.each do |key|
22
+ case key
23
+ when :nick
24
+ return unless options[:nick] == message.nick
25
+ when :host
26
+ return unless options[:host] == message.host
27
+ when :user
28
+ return unless options[:user] == message.user
29
+ when :channel
30
+ if message.channel
31
+ return unless options[:channel] == message.channel
32
+ end
33
+ end
34
+ end
35
+
36
+ callbacks.each do |blk|
37
+ blk.call(message)
38
+ end
39
+ end
40
+
41
+ # The rule as a String
42
+ def to_s
43
+ rule
44
+ end
45
+ end
46
+
47
+ # == Author
48
+ # * Lee Jarvis - ljjarvis@gmail.com
49
+ #
50
+ # == Description
51
+ # This class provides an interface to manage rules. A rule should only ever be
52
+ # added using the Rules#add_rule method and retrieved using the Rules#get_rule
53
+ # method, or an alias of these.
54
+ #
55
+ # This class provides an easy way to add options or callbacks to an existing
56
+ # rule.
57
+ #
58
+ # Essentially the add_callback, add_option, and merge_options methods are just sugar
59
+ # so you don't have to edit Rule attributes directly
60
+ #
61
+ # == Example
62
+ # rules = Cinch::Rules.new
63
+ #
64
+ # rules.add('foo', [], {}, Proc.new{})
65
+ #
66
+ # rules.add_callback('foo', Proc.new{})
67
+ # rules['foo'].callbacks #=> [#<Proc:0x9f1e110@(main):100>, #<Proc:0x9f1e0f4@(main):150>]
68
+ #
69
+ # # Or assign directly
70
+ # rules.get('foo').callbacks << Proc.new {}
71
+ #
72
+ # rules['foo'].options #=> {}
73
+ # rules.add_option('foo', :nick, 'injekt')
74
+ # rules['foo'].options #=> {:nick => 'injekt'}
75
+ #
76
+ # # Or retrieve the rule first and assign directly
77
+ # rules.get_rule('foo')
78
+ # rules.options = {:foo => 'bar'}
79
+ # rules.options[:bar] = 'baz'
80
+ class Rules
81
+ def initialize
82
+ @rules = {}
83
+ end
84
+
85
+ # Add a new rule, overwrites an already existing rule
86
+ def add_rule(rule, keys, options, callback)
87
+ @rules[rule] = Rule.new(rule, keys, options, callback)
88
+ end
89
+ alias :add :add_rule
90
+
91
+ # Return a Cinch::Rule by its rule, or nil it one does not exist
92
+ def get_rule(rule)
93
+ @rules[rule]
94
+ end
95
+ alias :get :get_rule
96
+ alias :[] :get_rule
97
+
98
+ # Remove a rule
99
+ def remove_rule(rule)
100
+ @rules.delete(rule)
101
+ end
102
+ alias :remove :remove_rule
103
+
104
+ # Check if a rule exists
105
+ def include?(rule)
106
+ @rules.key?(rule)
107
+ end
108
+ alias :has_rule? :include?
109
+
110
+ # Add a callback for an already existing rule
111
+ def add_callback(rule, blk)
112
+ return unless include?(rule)
113
+ @rules[rule].callbacks << blk
114
+ end
115
+
116
+ # Add an option for an already existing rule
117
+ def add_option(rule, key, value)
118
+ return unless include?(rule)
119
+ @rules[rule].options[key] = value
120
+ end
121
+
122
+ # Merge rule options
123
+ def merge_options(rule, ops={})
124
+ return unless include?(rule)
125
+ @rules[rule].options.merge!(ops)
126
+ end
127
+
128
+ # Iterate over the rules
129
+ def each
130
+ @rules.each {|rule, obj| yield obj }
131
+ end
132
+
133
+ # Remove all rules
134
+ def clear
135
+ @rules.clear
136
+ end
137
+
138
+ # Check if any rules exist
139
+ def empty?
140
+ @rules.empty?
141
+ end
142
+
143
+ # Return how many rules exist
144
+ def count
145
+ @rules.size
146
+ end
147
+ alias :size :count
148
+
149
+ # Return the hash of rules
150
+ def all
151
+ @rules
152
+ end
153
+
154
+ # Return an Array of rules
155
+ def to_a
156
+ @rules.keys
157
+ end
158
+ end
159
+
160
+ end
161
+
data/spec/base_spec.rb ADDED
@@ -0,0 +1,107 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe "Cinch::Base" do
4
+ before do
5
+ @base = Cinch::Base.new
6
+
7
+ @full = Cinch::Base.new(
8
+ :server => 'irc.freenode.org',
9
+ :nick => 'CinchBot',
10
+ :channels => ['#cinch']
11
+ )
12
+ end
13
+
14
+ describe "::new" do
15
+ it "should add a default ping listener" do
16
+ @base.listeners.should include :ping
17
+ end
18
+
19
+ it "should add a 376 listener, only if channels are set" do
20
+ @base.listeners.should_not include :'376'
21
+ @full.listeners.should include :'376'
22
+ end
23
+ end
24
+
25
+ describe "#plugin" do
26
+ it "should compile and add a rule" do
27
+ @base.plugin('foo')
28
+ @base.rules.include?("^foo$").should == true
29
+ end
30
+
31
+ it "should add options to an existing rule" do
32
+ @base.plugin('foo') { }
33
+ @base.plugin('foo', :bar => 'baz') { }
34
+ rule = @base.rules.get('^foo$')
35
+ rule.options.should include :bar
36
+ end
37
+
38
+ it "should add its block to an existing rule" do
39
+ @base.plugin('foo') { }
40
+ @base.plugin('foo') { }
41
+ rule = @base.rules.get_rule('^foo$')
42
+ rule.callbacks.size.should == 2
43
+ end
44
+ end
45
+
46
+ describe "#on" do
47
+ it "should save a listener" do
48
+ @base.on(:foo) {}
49
+ @base.listeners.should include :foo
50
+ end
51
+
52
+ it "should store listener blocks in an Array" do
53
+ @base.listeners[:ping].should be_kind_of Array
54
+ end
55
+ end
56
+
57
+ describe "#compile" do
58
+ it "should return an Array of 2 values" do
59
+ ret = @base.compile("foo")
60
+ ret.should be_kind_of(Array)
61
+ ret.size.should == 2
62
+ end
63
+
64
+ it "should return an empty set of keys if no named parameters are labeled" do
65
+ rule, keys = @base.compile("foo")
66
+ keys.should be_empty
67
+ end
68
+
69
+ it "should return a key for each named parameter labeled" do
70
+ rule, keys = @base.compile("foo :bar :baz")
71
+ keys.size.should == 2
72
+ keys.should include "bar"
73
+ keys.should include "baz"
74
+ end
75
+
76
+ it "should return a rule of type String, unless Regexp is given" do
77
+ rule, keys = @base.compile(:foo)
78
+ rule.should be_kind_of(String)
79
+
80
+ rule, keys = @base.compile(/foo/)
81
+ rule.should be_kind_of(Regexp)
82
+ keys.should be_empty
83
+ end
84
+
85
+ it "should convert a digit type" do
86
+ rule, keys = @base.compile(":foo-digit")
87
+ rule.should == "^(\\d+?)$"
88
+ end
89
+
90
+ it "should convert a string type" do
91
+ rule, keys = @base.compile(":foo-string")
92
+ rule.should == "^(\\w+?)$"
93
+ end
94
+
95
+ it "should convert a word type" do
96
+ rule, keys = @base.compile(":foo-word")
97
+ rule.should == "^([a-zA-Z]+?)$"
98
+ end
99
+
100
+ it "should automatically add start and end anchors" do
101
+ rule, keys = @base.compile("foo bar baz")
102
+ rule[0].chr.should == "^"
103
+ rule[-1].chr.should == "$"
104
+ end
105
+ end
106
+ end
107
+
@@ -0,0 +1,109 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe "Cinch::Rules" do
4
+ before do
5
+ @rules = Cinch::Rules.new
6
+ @rules.add_rule('foo', [], {}, Proc.new{})
7
+ end
8
+
9
+ describe "::new" do
10
+ it "should define an empty set of rules" do
11
+ Cinch::Rules.new.empty?.should == true
12
+ end
13
+ end
14
+
15
+ describe "#add_rule" do
16
+ it "should add a new rule" do
17
+ @rules.add_rule('bar', [], {}, Proc.new{})
18
+ @rules.all.should include 'foo'
19
+ end
20
+
21
+ it "should replace an existing rule" do
22
+ @rules.add_rule('foo', [], {}, Proc.new{})
23
+ @rules.count.should == 1
24
+ end
25
+ end
26
+
27
+ describe "#get_rule" do
28
+ it "should return a Cinch::Rule" do
29
+ @rules.get_rule('foo').should be_kind_of Cinch::Rule
30
+ end
31
+ end
32
+
33
+ describe "#remove_rule" do
34
+ it "should remove a rule" do
35
+ @rules.remove_rule('foo')
36
+ @rules.include?('foo').should == false
37
+ @rules.count.should == 0
38
+ end
39
+ end
40
+
41
+ describe "#add_callback" do
42
+ it "should add a callback for a rule" do
43
+ @rules.add_callback('foo', Proc.new{})
44
+ rule = @rules.get_rule('foo')
45
+ rule.callbacks.size.should == 2
46
+ end
47
+ end
48
+
49
+ describe "#add_option" do
50
+ it "should add an option for a rule" do
51
+ @rules.add_option('foo', :nick, 'injekt')
52
+ rule = @rules.get('foo')
53
+ rule.options.should include :nick
54
+ rule.options[:nick].should == 'injekt'
55
+ end
56
+ end
57
+
58
+ describe "#merge_options" do
59
+ it "should merge rule options" do
60
+ @rules.merge_options('foo', {:bar => 'baz'})
61
+ rule = @rules['foo']
62
+ rule.options.should == {:bar => 'baz'}
63
+ end
64
+ end
65
+
66
+ describe "#include?" do
67
+ it "should check if a rule exists" do
68
+ @rules.include?('foo').should == true
69
+ end
70
+ end
71
+
72
+ describe "#clear" do
73
+ it "should clear all rules" do
74
+ @rules.clear
75
+ @rules.empty?.should == true
76
+ end
77
+ end
78
+
79
+ describe "#empty?" do
80
+ it "should check if any rules exist" do
81
+ @rules.empty?.should == false
82
+ @rules.clear
83
+ @rules.empty?.should == true
84
+ end
85
+ end
86
+
87
+ describe "#count" do
88
+ it "should show how many rules exist" do
89
+ @rules.count.should == 1
90
+ @rules.add_rule('bar', [], {}, Proc.new{})
91
+ @rules.count.should == 2
92
+ end
93
+ end
94
+
95
+ describe "#all" do
96
+ it "should return a Hash of all rules" do
97
+ @rules.all.should be_kind_of Hash
98
+ @rules.all.should include 'foo'
99
+ end
100
+ end
101
+
102
+ describe "#to_a" do
103
+ it "should return an Array of rules" do
104
+ @rules.to_a.should be_kind_of Array
105
+ @rules.to_a.include?('foo').should == true
106
+ end
107
+ end
108
+ end
109
+
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- version: "0.1"
7
+ - 2
8
+ version: "0.2"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Lee 'injekt' Jarvis
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-04-25 00:00:00 +01:00
16
+ date: 2010-04-26 00:00:00 +01:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
@@ -41,18 +41,26 @@ extra_rdoc_files:
41
41
  files:
42
42
  - README.rdoc
43
43
  - Rakefile
44
+ - spec/base_spec.rb
44
45
  - spec/irc/socket_spec.rb
45
46
  - spec/irc/helper.rb
46
47
  - spec/irc/message_spec.rb
47
48
  - spec/irc/parser_spec.rb
48
49
  - spec/helper.rb
50
+ - spec/rules_spec.rb
49
51
  - spec/options_spec.rb
50
52
  - lib/cinch.rb
51
53
  - lib/cinch/base.rb
52
54
  - lib/cinch/irc/message.rb
53
55
  - lib/cinch/irc/socket.rb
54
56
  - lib/cinch/irc/parser.rb
57
+ - lib/cinch/rules.rb
55
58
  - lib/cinch/irc.rb
59
+ - examples/join_part.rb
60
+ - examples/msg.rb
61
+ - examples/seen.rb
62
+ - examples/hello.rb
63
+ - examples/named-param-types.rb
56
64
  has_rdoc: true
57
65
  homepage: http://rdoc.injekt.net/cinch
58
66
  licenses: []