cinch 0.3.5 → 1.0.0
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/LICENSE +20 -0
- data/README.md +192 -0
- data/Rakefile +53 -43
- data/examples/basic/autovoice.rb +32 -0
- data/examples/basic/google.rb +35 -0
- data/examples/basic/hello.rb +15 -0
- data/examples/basic/join_part.rb +38 -0
- data/examples/basic/memo.rb +39 -0
- data/examples/basic/msg.rb +16 -0
- data/examples/basic/seen.rb +36 -0
- data/examples/basic/urban_dict.rb +35 -0
- data/examples/basic/url_shorten.rb +35 -0
- data/examples/plugins/autovoice.rb +40 -0
- data/examples/plugins/custom_prefix.rb +23 -0
- data/examples/plugins/google.rb +37 -0
- data/examples/plugins/hello.rb +22 -0
- data/examples/plugins/join_part.rb +42 -0
- data/examples/plugins/memo.rb +50 -0
- data/examples/plugins/msg.rb +22 -0
- data/examples/plugins/multiple_matches.rb +41 -0
- data/examples/plugins/seen.rb +45 -0
- data/examples/plugins/urban_dict.rb +30 -0
- data/examples/plugins/url_shorten.rb +32 -0
- data/lib/cinch.rb +7 -20
- data/lib/cinch/ban.rb +41 -0
- data/lib/cinch/bot.rb +479 -0
- data/lib/cinch/callback.rb +11 -0
- data/lib/cinch/channel.rb +419 -0
- data/lib/cinch/constants.rb +369 -0
- data/lib/cinch/exceptions.rb +25 -0
- data/lib/cinch/helpers.rb +21 -0
- data/lib/cinch/irc.rb +344 -38
- data/lib/cinch/isupport.rb +96 -0
- data/lib/cinch/logger/formatted_logger.rb +80 -0
- data/lib/cinch/logger/logger.rb +44 -0
- data/lib/cinch/logger/null_logger.rb +18 -0
- data/lib/cinch/mask.rb +46 -0
- data/lib/cinch/message.rb +183 -0
- data/lib/cinch/message_queue.rb +62 -0
- data/lib/cinch/plugin.rb +205 -0
- data/lib/cinch/rubyext/infinity.rb +1 -0
- data/lib/cinch/rubyext/module.rb +18 -0
- data/lib/cinch/rubyext/queue.rb +19 -0
- data/lib/cinch/rubyext/string.rb +24 -0
- data/lib/cinch/syncable.rb +55 -0
- data/lib/cinch/user.rb +325 -0
- data/spec/bot_spec.rb +5 -0
- data/spec/channel_spec.rb +5 -0
- data/spec/cinch_spec.rb +5 -0
- data/spec/irc_spec.rb +5 -0
- data/spec/message_spec.rb +5 -0
- data/spec/plugin_spec.rb +5 -0
- data/spec/{helper.rb → spec_helper.rb} +0 -0
- data/spec/user_spec.rb +5 -0
- metadata +69 -51
- data/README.rdoc +0 -195
- data/examples/autovoice.rb +0 -32
- data/examples/custom_patterns.rb +0 -19
- data/examples/custom_prefix.rb +0 -25
- data/examples/google.rb +0 -31
- data/examples/hello.rb +0 -13
- data/examples/join_part.rb +0 -26
- data/examples/memo.rb +0 -40
- data/examples/msg.rb +0 -14
- data/examples/named-param-types.rb +0 -19
- data/examples/seen.rb +0 -41
- data/examples/urban_dict.rb +0 -31
- data/examples/url_shorten.rb +0 -34
- data/lib/cinch/base.rb +0 -368
- data/lib/cinch/irc/message.rb +0 -135
- data/lib/cinch/irc/parser.rb +0 -141
- data/lib/cinch/irc/socket.rb +0 -329
- data/lib/cinch/names.rb +0 -54
- data/lib/cinch/rules.rb +0 -171
- data/spec/base_spec.rb +0 -94
- data/spec/irc/helper.rb +0 -8
- data/spec/irc/message_spec.rb +0 -61
- data/spec/irc/parser_spec.rb +0 -103
- data/spec/irc/socket_spec.rb +0 -90
- data/spec/names_spec.rb +0 -393
- data/spec/options_spec.rb +0 -45
- data/spec/rules_spec.rb +0 -109
data/lib/cinch/names.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
module Cinch
|
2
|
-
module Names
|
3
|
-
attr_reader :channel_names
|
4
|
-
|
5
|
-
def tracking_names?
|
6
|
-
!!@tracking_names
|
7
|
-
end
|
8
|
-
|
9
|
-
def track_names
|
10
|
-
return if tracking_names?
|
11
|
-
|
12
|
-
@tracking_names = true
|
13
|
-
|
14
|
-
@channel_names = {}
|
15
|
-
|
16
|
-
on(:join) do |m|
|
17
|
-
if m.nick == nick
|
18
|
-
names(m.channel)
|
19
|
-
else
|
20
|
-
channel_names[m.channel] ||= []
|
21
|
-
channel_names[m.channel].push m.nick
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
on(353) do |m|
|
26
|
-
channel = m.params.detect { |c| c.match(/^#/) }
|
27
|
-
names = m.text.split.collect { |n| n.sub(/^@/, '') }
|
28
|
-
channel_names[channel] ||= []
|
29
|
-
channel_names[channel] += names
|
30
|
-
end
|
31
|
-
|
32
|
-
on(:part) do |m|
|
33
|
-
if m.nick == nick
|
34
|
-
channel_names.delete(m.channel)
|
35
|
-
else
|
36
|
-
channel_names[m.channel] ||= []
|
37
|
-
channel_names[m.channel].delete m.nick
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
on(:quit, :kill) do |m|
|
42
|
-
channel_names.each_value { |names| names.delete m.nick }
|
43
|
-
end
|
44
|
-
|
45
|
-
on(:nick) do |m|
|
46
|
-
channel_names.each_value { |names| names.push m.recipient if names.delete m.nick }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Cinch::Base
|
53
|
-
include Cinch::Names
|
54
|
-
end
|
data/lib/cinch/rules.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
module Cinch
|
2
|
-
|
3
|
-
# == Description
|
4
|
-
# Every rule defined through the Cinch::Base#plugin method becomes an instance
|
5
|
-
# of this class. Each rule consists of keys used for named parameters, a hash
|
6
|
-
# of options, and an Array of callbacks.
|
7
|
-
#
|
8
|
-
# When a rule matches an IRC message, all options with be checked, then all
|
9
|
-
# callbacks will be invoked.
|
10
|
-
#
|
11
|
-
# == Author
|
12
|
-
# * Lee Jarvis - ljjarvis@gmail.com
|
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 a Cinch::IRC::Message to them
|
20
|
-
def execute(message)
|
21
|
-
options.keys.each do |key|
|
22
|
-
case key
|
23
|
-
when :nick, :nicks
|
24
|
-
return unless validate(options[:nick] || options[:nicks], message.nick)
|
25
|
-
when :host, :hosts
|
26
|
-
return unless validate(options[:host] || options[:hosts], message.host)
|
27
|
-
when :user, :users
|
28
|
-
return unless validate(options[:user] || options[:users], message.user)
|
29
|
-
when :channel, :channels
|
30
|
-
if message.channel
|
31
|
-
return unless validate(options[:channel] || options[:channels], message.channel)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
callbacks.each do |blk|
|
37
|
-
blk.call(message)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Validate rule attributes
|
42
|
-
def validate(option, attr)
|
43
|
-
if option.is_a?(Array)
|
44
|
-
return unless option.any?{|o| o == attr }
|
45
|
-
else
|
46
|
-
return unless option.to_s == attr
|
47
|
-
end
|
48
|
-
true
|
49
|
-
end
|
50
|
-
|
51
|
-
# The rule as a String
|
52
|
-
def to_s
|
53
|
-
rule
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# == Description
|
58
|
-
# This class provides an interface to manage rules. A rule should only ever be
|
59
|
-
# added using the Rules#add_rule method and retrieved using the Rules#get_rule
|
60
|
-
# method, or an alias of these.
|
61
|
-
#
|
62
|
-
# This class provides an easy way to add options or callbacks to an existing
|
63
|
-
# rule.
|
64
|
-
#
|
65
|
-
# Essentially the add_callback, add_option, and merge_options methods are just sugar
|
66
|
-
# so you don't have to edit Rule attributes directly
|
67
|
-
#
|
68
|
-
# == Example
|
69
|
-
# rules = Cinch::Rules.new
|
70
|
-
#
|
71
|
-
# rules.add('foo', [], {}, Proc.new{})
|
72
|
-
#
|
73
|
-
# rules.add_callback('foo', Proc.new{})
|
74
|
-
# rules['foo'].callbacks #=> [#<Proc:0x9f1e110@(main):100>, #<Proc:0x9f1e0f4@(main):150>]
|
75
|
-
#
|
76
|
-
# # Or assign directly
|
77
|
-
# rules.get('foo').callbacks << Proc.new {}
|
78
|
-
#
|
79
|
-
# rules['foo'].options #=> {}
|
80
|
-
# rules.add_option('foo', :nick, 'injekt')
|
81
|
-
# rules['foo'].options #=> {:nick => 'injekt'}
|
82
|
-
#
|
83
|
-
# # Or retrieve the rule first and assign directly
|
84
|
-
# rules.get_rule('foo')
|
85
|
-
# rules.options = {:foo => 'bar'}
|
86
|
-
# rules.options[:bar] = 'baz'
|
87
|
-
#
|
88
|
-
# == Author
|
89
|
-
# * Lee Jarvis - ljjarvis@gmail.com
|
90
|
-
class Rules
|
91
|
-
def initialize
|
92
|
-
@rules = {}
|
93
|
-
end
|
94
|
-
|
95
|
-
# Add a new rule, overwrites an already existing rule
|
96
|
-
def add_rule(rule, keys, options, callback)
|
97
|
-
@rules[rule] = Rule.new(rule, keys, options, callback)
|
98
|
-
end
|
99
|
-
alias :add :add_rule
|
100
|
-
|
101
|
-
# Return a Cinch::Rule by its rule, or nil it one does not exist
|
102
|
-
def get_rule(rule)
|
103
|
-
@rules[rule]
|
104
|
-
end
|
105
|
-
alias :get :get_rule
|
106
|
-
alias :[] :get_rule
|
107
|
-
|
108
|
-
# Remove a rule
|
109
|
-
def remove_rule(rule)
|
110
|
-
@rules.delete(rule)
|
111
|
-
end
|
112
|
-
alias :remove :remove_rule
|
113
|
-
|
114
|
-
# Check if a rule exists
|
115
|
-
def include?(rule)
|
116
|
-
@rules.key?(rule)
|
117
|
-
end
|
118
|
-
alias :has_rule? :include?
|
119
|
-
|
120
|
-
# Add a callback for an already existing rule
|
121
|
-
def add_callback(rule, blk)
|
122
|
-
return unless include?(rule)
|
123
|
-
@rules[rule].callbacks << blk
|
124
|
-
end
|
125
|
-
|
126
|
-
# Add an option for an already existing rule
|
127
|
-
def add_option(rule, key, value)
|
128
|
-
return unless include?(rule)
|
129
|
-
@rules[rule].options[key] = value
|
130
|
-
end
|
131
|
-
|
132
|
-
# Merge rule options
|
133
|
-
def merge_options(rule, ops={})
|
134
|
-
return unless include?(rule)
|
135
|
-
@rules[rule].options.merge!(ops)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Iterate over the rules
|
139
|
-
def each
|
140
|
-
@rules.each {|rule, obj| yield obj }
|
141
|
-
end
|
142
|
-
|
143
|
-
# Remove all rules
|
144
|
-
def clear
|
145
|
-
@rules.clear
|
146
|
-
end
|
147
|
-
|
148
|
-
# Check if any rules exist
|
149
|
-
def empty?
|
150
|
-
@rules.empty?
|
151
|
-
end
|
152
|
-
|
153
|
-
# Return how many rules exist
|
154
|
-
def count
|
155
|
-
@rules.size
|
156
|
-
end
|
157
|
-
alias :size :count
|
158
|
-
|
159
|
-
# Return the hash of rules
|
160
|
-
def all
|
161
|
-
@rules
|
162
|
-
end
|
163
|
-
|
164
|
-
# Return an Array of rules
|
165
|
-
def to_a
|
166
|
-
@rules.keys
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
data/spec/base_spec.rb
DELETED
@@ -1,94 +0,0 @@
|
|
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 ctcp version listener" do
|
16
|
-
@base.listeners.should include :ctcp
|
17
|
-
@base.listeners[:ctcp].should include :version
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "#plugin" do
|
22
|
-
it "should compile and add a rule" do
|
23
|
-
@base.plugin('foo')
|
24
|
-
@base.rules.include?("^foo$").should == true
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should add options to an existing rule" do
|
28
|
-
@base.plugin('foo') { }
|
29
|
-
@base.plugin('foo', :bar => 'baz') { }
|
30
|
-
rule = @base.rules.get('^foo$')
|
31
|
-
rule.options.should include :bar
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should add its block to an existing rule" do
|
35
|
-
@base.plugin('foo') { }
|
36
|
-
@base.plugin('foo') { }
|
37
|
-
rule = @base.rules.get_rule('^foo$')
|
38
|
-
rule.callbacks.size.should == 2
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "#on" do
|
43
|
-
it "should save a listener" do
|
44
|
-
@base.on(:foo) {}
|
45
|
-
@base.listeners.should include :foo
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should store listener blocks in an Array" do
|
49
|
-
@base.listeners[:ping].should be_kind_of Array
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#compile" do
|
54
|
-
it "should return an Array of 2 values" do
|
55
|
-
ret = @base.compile("foo")
|
56
|
-
ret.should be_kind_of(Array)
|
57
|
-
ret.size.should == 2
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should return an empty set of keys if no named parameters are labeled" do
|
61
|
-
rule, keys = @base.compile("foo")
|
62
|
-
keys.should be_empty
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should return a key for each named parameter labeled" do
|
66
|
-
rule, keys = @base.compile("foo :bar :baz")
|
67
|
-
keys.size.should == 2
|
68
|
-
keys.should include "bar"
|
69
|
-
keys.should include "baz"
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should return a rule of type String, unless Regexp is given" do
|
73
|
-
rule, keys = @base.compile(:foo)
|
74
|
-
rule.should be_kind_of(String)
|
75
|
-
|
76
|
-
rule, keys = @base.compile(/foo/)
|
77
|
-
rule.should be_kind_of(Regexp)
|
78
|
-
keys.should be_empty
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should convert a custom pattern" do
|
82
|
-
@base.add_custom_pattern(:people, "foo|bar|baz")
|
83
|
-
rule, keys = @base.compile(":foo-people")
|
84
|
-
rule.should == "^(foo|bar|baz)$"
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should automatically add start and end anchors" do
|
88
|
-
rule, keys = @base.compile("foo bar baz")
|
89
|
-
rule[0].chr.should == "^"
|
90
|
-
rule[-1].chr.should == "$"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
data/spec/irc/helper.rb
DELETED
data/spec/irc/message_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/helper'
|
2
|
-
|
3
|
-
describe "IRC::Message" do
|
4
|
-
before do
|
5
|
-
@message = Cinch::IRC::Message.new('rawline', 'prefix', 'COMMAND', ['#chan', 'hello world'])
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "#add, #[]=" do
|
9
|
-
it "should add an attribute" do
|
10
|
-
@message.add(:custom, 'something')
|
11
|
-
@message.data.should include :custom
|
12
|
-
@message.data[:custom].should == "something"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "#delete" do
|
17
|
-
it "should remove an attribute" do
|
18
|
-
@message.add(:custom, 'something')
|
19
|
-
@message.delete(:custom)
|
20
|
-
@message.data.should_not include :custom
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "#to_s" do
|
25
|
-
it "should return the raw IRC message" do
|
26
|
-
@message.to_s.should == @message.raw
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "#method_missing" do
|
31
|
-
it "should return an attribute if it exists" do
|
32
|
-
@message.add(:custom, 'something')
|
33
|
-
@message.custom.should == 'something'
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should return nil if no attribute exists" do
|
37
|
-
@message.foobar.should == nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "default attributes" do
|
42
|
-
it "should contain a prefix" do
|
43
|
-
@message.prefix.should == 'prefix'
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should contain a command" do
|
47
|
-
@message.command.should == "COMMAND"
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should contain params" do
|
51
|
-
@message.params.should be_kind_of(Array)
|
52
|
-
@message.params.size.should == 2
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should contain a symbolized command" do
|
56
|
-
@message.symbol.should == :command
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
data/spec/irc/parser_spec.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/helper'
|
2
|
-
|
3
|
-
# Common commands
|
4
|
-
commands = {
|
5
|
-
:ping => "PING :foobar",
|
6
|
-
:nick => ":foo!~baz@host.com NICK Baz",
|
7
|
-
:join => ":foo!~bar@host.com JOIN #baz",
|
8
|
-
:ctcp => ":foo!~bar@host.com PRIVMSG Baz :\001VERSION\001",
|
9
|
-
|
10
|
-
:privmsg => {
|
11
|
-
"to a channel" => ":foo!~bar@host.com PRIVMSG #baz :hello world",
|
12
|
-
"to a user" => ":foo!~bar@host.com PRIVMSG Baz :hello world",
|
13
|
-
},
|
14
|
-
|
15
|
-
:notice => {
|
16
|
-
"to a channel" => ":foo!~bar@host.com NOTICE #baz :hello world",
|
17
|
-
"to a user" => ":foo!~bar@host.com NOTICE Baz :hello world",
|
18
|
-
},
|
19
|
-
|
20
|
-
:part => {
|
21
|
-
"without a message" => ":foo!~bar@host.com PART #baz",
|
22
|
-
"with a message" => ":foo!~bar@host.com PART #baz :beer",
|
23
|
-
},
|
24
|
-
|
25
|
-
:quit => {
|
26
|
-
"without a message" => ":foo!~bar@host.com QUIT",
|
27
|
-
"with a message" => ":foo!~bar@host.com QUIT :baz"
|
28
|
-
}
|
29
|
-
}
|
30
|
-
|
31
|
-
describe "IRC::Parser" do
|
32
|
-
before do
|
33
|
-
@parser = Cinch::IRC::Parser.new
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "#add_pattern" do
|
37
|
-
it "should add a pattern" do
|
38
|
-
@parser.add_pattern(:custom, /foo/)
|
39
|
-
@parser.patterns.key?(:custom)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "#remove_pattern" do
|
44
|
-
it "should remove a pattern" do
|
45
|
-
@parser.add_pattern(:custom, /foo/)
|
46
|
-
@parser.remove_pattern(:custom)
|
47
|
-
@parser.patterns.keys.should_not include(:custom)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should return nil if a pattern doesn't exist" do
|
51
|
-
@parser.remove_pattern(:foo).should be nil
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "#parse" do
|
56
|
-
it "should return an IRC::Message" do
|
57
|
-
@parser.parse("foo :bar").should be_kind_of(Cinch::IRC::Message)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should raise if given an invalid message" do
|
61
|
-
lambda { @parser.parse("#") }.should raise_error(ArgumentError)
|
62
|
-
end
|
63
|
-
|
64
|
-
commands.each do |cmd, passes|
|
65
|
-
if passes.is_a?(Hash)
|
66
|
-
passes.each do |extra, pass|
|
67
|
-
it "should parse a #{cmd.to_s.upcase} command #{extra}" do
|
68
|
-
m = @parser.parse(pass)
|
69
|
-
m.symbol.should == cmd
|
70
|
-
end
|
71
|
-
end
|
72
|
-
else
|
73
|
-
it "should parse a #{cmd.to_s.upcase} command" do
|
74
|
-
m = @parser.parse(passes)
|
75
|
-
m.symbol.should == cmd
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
describe "#parse_userhost" do
|
83
|
-
it "should return an Array" do
|
84
|
-
@parser.parse_userhost(":foo!bar@baz").should be_kind_of(Array)
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should return 3 values" do
|
88
|
-
@parser.parse_userhost(":foo!bar@baz").size.should be 3
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "#valid_channel?" do
|
93
|
-
it "should return true with a valid channel name" do
|
94
|
-
@parser.valid_channel?("#foo").should be true
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should return false with an invalid channel name" do
|
98
|
-
@parser.valid_channel?("foo").should be false
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|