net-irc2 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS.txt +33 -0
- data/ChangeLog +95 -0
- data/README +91 -0
- data/Rakefile +69 -0
- data/examples/2ch.rb +225 -0
- data/examples/2ig.rb +267 -0
- data/examples/client.rb +23 -0
- data/examples/echo_bot.rb +31 -0
- data/examples/echo_bot_celluloid.rb +33 -0
- data/examples/gig.rb +192 -0
- data/examples/gmail.rb +202 -0
- data/examples/gtig.rb +420 -0
- data/examples/hatena-star-stream.rb +270 -0
- data/examples/hcig.rb +285 -0
- data/examples/hig.rb +771 -0
- data/examples/iig.rb +819 -0
- data/examples/ircd.rb +358 -0
- data/examples/lig.rb +551 -0
- data/examples/lingr.rb +327 -0
- data/examples/mixi.rb +252 -0
- data/examples/sig.rb +188 -0
- data/examples/tig.rb +2712 -0
- data/lib/net/irc/client/channel_manager.rb +144 -0
- data/lib/net/irc/client.rb +117 -0
- data/lib/net/irc/constants.rb +214 -0
- data/lib/net/irc/message/modeparser.rb +85 -0
- data/lib/net/irc/message/serverconfig.rb +30 -0
- data/lib/net/irc/message.rb +109 -0
- data/lib/net/irc/pattern.rb +68 -0
- data/lib/net/irc/server.rb +186 -0
- data/lib/net/irc.rb +77 -0
- data/spec/channel_manager_spec.rb +184 -0
- data/spec/modeparser_spec.rb +165 -0
- data/spec/net-irc_spec.rb +337 -0
- data/spec/spec.opts +1 -0
- metadata +91 -0
@@ -0,0 +1,337 @@
|
|
1
|
+
#!spec
|
2
|
+
# coding: ASCII-8BIT
|
3
|
+
# vim:encoding=UTF-8:
|
4
|
+
|
5
|
+
$LOAD_PATH << "lib"
|
6
|
+
$LOAD_PATH << "../lib"
|
7
|
+
|
8
|
+
require "rubygems"
|
9
|
+
require "rspec"
|
10
|
+
require "net/irc"
|
11
|
+
include Net::IRC
|
12
|
+
include Constants
|
13
|
+
|
14
|
+
describe Net::IRC::Message, "construct" do
|
15
|
+
|
16
|
+
it "should generate message correctly" do
|
17
|
+
m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
|
18
|
+
m.to_s.should == ":foo PRIVMSG #channel message\r\n"
|
19
|
+
|
20
|
+
m = Message.new("foo", "PRIVMSG", ["#channel", "message with space"])
|
21
|
+
m.to_s.should == ":foo PRIVMSG #channel :message with space\r\n"
|
22
|
+
|
23
|
+
m = Message.new(nil, "PRIVMSG", ["#channel", "message"])
|
24
|
+
m.to_s.should == "PRIVMSG #channel message\r\n"
|
25
|
+
|
26
|
+
m = Message.new(nil, "PRIVMSG", ["#channel", "message with space"])
|
27
|
+
m.to_s.should == "PRIVMSG #channel :message with space\r\n"
|
28
|
+
|
29
|
+
m = Message.new(nil, "MODE", [
|
30
|
+
"#channel",
|
31
|
+
"+ooo",
|
32
|
+
"nick1",
|
33
|
+
"nick2",
|
34
|
+
"nick3"
|
35
|
+
])
|
36
|
+
m.to_s.should == "MODE #channel +ooo nick1 nick2 nick3\r\n"
|
37
|
+
|
38
|
+
m = Message.new(nil, "KICK", [
|
39
|
+
"#channel,#channel1",
|
40
|
+
"nick1,nick2",
|
41
|
+
])
|
42
|
+
m.to_s.should == "KICK #channel,#channel1 nick1,nick2\r\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have ctcp? method" do
|
46
|
+
m = Message.new("foo", "PRIVMSG", ["#channel", "\x01ACTION foo\x01"])
|
47
|
+
m.ctcp?.should == true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should behave as Array contains params" do
|
51
|
+
m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
|
52
|
+
m[0].should == m.params[0]
|
53
|
+
m[1].should == m.params[1]
|
54
|
+
m.to_a.should == ["#channel", "message"]
|
55
|
+
|
56
|
+
channel, message = *m
|
57
|
+
channel.should == "#channel"
|
58
|
+
message.should == "message"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "#to_a should return duplicated array" do
|
62
|
+
m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
|
63
|
+
m[0].should == m.params[0]
|
64
|
+
m[1].should == m.params[1]
|
65
|
+
m.to_a.should == ["#channel", "message"]
|
66
|
+
m.to_a.clear
|
67
|
+
m.to_a.should == ["#channel", "message"]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe Net::IRC::Message, "parse" do
|
72
|
+
it "should parse correctly following RFC." do
|
73
|
+
m = Message.parse("PRIVMSG #channel message\r\n")
|
74
|
+
m.prefix.should == ""
|
75
|
+
m.command.should == "PRIVMSG"
|
76
|
+
m.params.should == ["#channel", "message"]
|
77
|
+
|
78
|
+
m = Message.parse("PRIVMSG #channel :message leading :\r\n")
|
79
|
+
m.prefix.should == ""
|
80
|
+
m.command.should == "PRIVMSG"
|
81
|
+
m.params.should == ["#channel", "message leading :"]
|
82
|
+
|
83
|
+
m = Message.parse("PRIVMSG #channel middle :message leading :\r\n")
|
84
|
+
m.prefix.should == ""
|
85
|
+
m.command.should == "PRIVMSG"
|
86
|
+
m.params.should == ["#channel", "middle", "message leading :"]
|
87
|
+
|
88
|
+
m = Message.parse("PRIVMSG #channel middle message with middle\r\n")
|
89
|
+
m.prefix.should == ""
|
90
|
+
m.command.should == "PRIVMSG"
|
91
|
+
m.params.should == ["#channel", "middle", "message", "with", "middle"]
|
92
|
+
|
93
|
+
m = Message.parse(":prefix PRIVMSG #channel message\r\n")
|
94
|
+
m.prefix.should == "prefix"
|
95
|
+
m.command.should == "PRIVMSG"
|
96
|
+
m.params.should == ["#channel", "message"]
|
97
|
+
|
98
|
+
m = Message.parse(":prefix PRIVMSG #channel :message leading :\r\n")
|
99
|
+
m.prefix.should == "prefix"
|
100
|
+
m.command.should == "PRIVMSG"
|
101
|
+
m.params.should == ["#channel", "message leading :"]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should allow multibyte " do
|
105
|
+
m = Message.parse(":てすと PRIVMSG #channel :message leading :\r\n")
|
106
|
+
m.prefix.should == "てすと"
|
107
|
+
m.command.should == "PRIVMSG"
|
108
|
+
m.params.should == ["#channel", "message leading :"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should allow space at end" do
|
112
|
+
m = Message.parse("JOIN #foobar \r\n")
|
113
|
+
m.prefix.should == ""
|
114
|
+
m.command.should == "JOIN"
|
115
|
+
m.params.should == ["#foobar"]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe Net::IRC::Constants, "lookup" do
|
120
|
+
it "should lookup numeric replies from Net::IRC::COMMANDS" do
|
121
|
+
welcome = Net::IRC::Constants.const_get("RPL_WELCOME")
|
122
|
+
welcome.should == "001"
|
123
|
+
Net::IRC::COMMANDS[welcome].should == "RPL_WELCOME"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe Net::IRC::Prefix, "" do
|
128
|
+
it "should be kind of String" do
|
129
|
+
Prefix.new("").should be_kind_of(String)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should parse prefix correctly." do
|
133
|
+
prefix = Prefix.new("foo!bar@localhost")
|
134
|
+
prefix.extract.should == ["foo", "bar", "localhost"]
|
135
|
+
|
136
|
+
prefix = Prefix.new("foo!-bar@localhost")
|
137
|
+
prefix.extract.should == ["foo", "-bar", "localhost"]
|
138
|
+
|
139
|
+
prefix = Prefix.new("foo!+bar@localhost")
|
140
|
+
prefix.extract.should == ["foo", "+bar", "localhost"]
|
141
|
+
|
142
|
+
prefix = Prefix.new("foo!~bar@localhost")
|
143
|
+
prefix.extract.should == ["foo", "~bar", "localhost"]
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should allow multibyte in nick." do
|
147
|
+
prefix = Prefix.new("あああ!~bar@localhost")
|
148
|
+
prefix.extract.should == ["あああ", "~bar", "localhost"]
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should allow lame prefix." do
|
152
|
+
prefix = Prefix.new("nick")
|
153
|
+
prefix.extract.should == ["nick", nil, nil]
|
154
|
+
end
|
155
|
+
|
156
|
+
it "has nick method" do
|
157
|
+
prefix = Prefix.new("foo!bar@localhost")
|
158
|
+
prefix.nick.should == "foo"
|
159
|
+
end
|
160
|
+
|
161
|
+
it "has user method" do
|
162
|
+
prefix = Prefix.new("foo!bar@localhost")
|
163
|
+
prefix.user.should == "bar"
|
164
|
+
end
|
165
|
+
|
166
|
+
it "has host method" do
|
167
|
+
prefix = Prefix.new("foo!bar@localhost")
|
168
|
+
prefix.host.should == "localhost"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe Net::IRC, "utilities" do
|
173
|
+
it "has ctcp_encode method" do
|
174
|
+
message = ctcp_encode "ACTION hehe"
|
175
|
+
message.should == "\x01ACTION hehe\x01"
|
176
|
+
|
177
|
+
message = ctcp_encode "ACTION \x01 \x5c "
|
178
|
+
message.should == "\x01ACTION \x5c\x61 \x5c\x5c \x01"
|
179
|
+
|
180
|
+
message = ctcp_encode "ACTION \x00 \x0a \x0d \x10 "
|
181
|
+
message.should == "\x01ACTION \x100 \x10n \x10r \x10\x10 \x01"
|
182
|
+
end
|
183
|
+
|
184
|
+
it "has ctcp_decode method" do
|
185
|
+
message = ctcp_decode "\x01ACTION hehe\x01"
|
186
|
+
message.should == "ACTION hehe"
|
187
|
+
|
188
|
+
message = ctcp_decode "\x01ACTION \x5c\x61 \x5c\x5c \x01"
|
189
|
+
message.should == "ACTION \x01 \x5c "
|
190
|
+
|
191
|
+
message = ctcp_decode "\x01ACTION \x100 \x10n \x10r \x10\x10 \x01"
|
192
|
+
message.should == "ACTION \x00 \x0a \x0d \x10 "
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class TestServerSession < Net::IRC::Server::Session
|
197
|
+
@@testq = SizedQueue.new(1)
|
198
|
+
@@instance = nil
|
199
|
+
|
200
|
+
def self.testq
|
201
|
+
@@testq
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.instance
|
205
|
+
@@instance
|
206
|
+
end
|
207
|
+
|
208
|
+
def initialize(*args)
|
209
|
+
super
|
210
|
+
@@instance = self
|
211
|
+
end
|
212
|
+
|
213
|
+
def on_message(m)
|
214
|
+
@@testq << m
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class TestClient < Net::IRC::Client
|
219
|
+
@@testq = SizedQueue.new(1)
|
220
|
+
|
221
|
+
def self.testq
|
222
|
+
@@testq
|
223
|
+
end
|
224
|
+
|
225
|
+
def on_message(m)
|
226
|
+
@@testq << m
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe Net::IRC, "server and client" do
|
231
|
+
before :all do
|
232
|
+
@port = nil
|
233
|
+
@server, @client = nil, nil
|
234
|
+
|
235
|
+
Thread.abort_on_exception = true
|
236
|
+
@tserver = Thread.start do
|
237
|
+
@server = Net::IRC::Server.new("localhost", @port, TestServerSession, {
|
238
|
+
:logger => Logger.new(nil),
|
239
|
+
})
|
240
|
+
@server.start
|
241
|
+
end
|
242
|
+
|
243
|
+
Thread.pass
|
244
|
+
true until @server.instance_variable_get(:@serv)
|
245
|
+
|
246
|
+
@port = @server.instance_variable_get(:@serv).addr[1]
|
247
|
+
|
248
|
+
@tclient = Thread.start do
|
249
|
+
@client = TestClient.new("localhost", @port, {
|
250
|
+
:nick => "foonick",
|
251
|
+
:user => "foouser",
|
252
|
+
:real => "foo real name",
|
253
|
+
:pass => "foopass",
|
254
|
+
:logger => Logger.new(nil),
|
255
|
+
})
|
256
|
+
@client.start
|
257
|
+
end
|
258
|
+
|
259
|
+
Thread.pass
|
260
|
+
true until @client
|
261
|
+
end
|
262
|
+
|
263
|
+
server_q = TestServerSession.testq
|
264
|
+
client_q = TestClient.testq
|
265
|
+
|
266
|
+
it "client should send pass/nick/user sequence." do
|
267
|
+
server_q.pop.to_s.should == "PASS foopass\r\n"
|
268
|
+
server_q.pop.to_s.should == "NICK foonick\r\n"
|
269
|
+
server_q.pop.to_s.should == "USER foouser 0 * :foo real name\r\n"
|
270
|
+
end
|
271
|
+
|
272
|
+
it "server should send 001,002,003 numeric replies." do
|
273
|
+
client_q.pop.to_s.should match(/^:net-irc 001 foonick :Welcome to the Internet Relay Network \S+!\S+@\S+/)
|
274
|
+
client_q.pop.to_s.should match(/^:net-irc 002 foonick :Your host is .+?, running version /)
|
275
|
+
client_q.pop.to_s.should match(/^:net-irc 003 foonick :This server was created /)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "client posts PRIVMSG and server receives it." do
|
279
|
+
@client.instance_eval do
|
280
|
+
post PRIVMSG, "#channel", "message a b c"
|
281
|
+
end
|
282
|
+
|
283
|
+
message = server_q.pop
|
284
|
+
message.should be_a_kind_of(Net::IRC::Message)
|
285
|
+
message.to_s.should == "PRIVMSG #channel :message a b c\r\n"
|
286
|
+
end
|
287
|
+
|
288
|
+
if defined? Encoding
|
289
|
+
it "dummy encoding: client posts PRIVMSG and server receives it." do
|
290
|
+
@client.instance_eval do
|
291
|
+
s = "てすと".force_encoding("UTF-8")
|
292
|
+
post PRIVMSG, "#channel", s
|
293
|
+
end
|
294
|
+
|
295
|
+
message = server_q.pop
|
296
|
+
message.should be_a_kind_of(Net::IRC::Message)
|
297
|
+
message.to_s.should == "PRIVMSG #channel てすと\r\n"
|
298
|
+
end
|
299
|
+
|
300
|
+
it "dummy encoding: client posts PRIVMSG and server receives it." do
|
301
|
+
@client.instance_eval do
|
302
|
+
s = "てすと".force_encoding("UTF-8")
|
303
|
+
s.encode!("ISO-2022-JP")
|
304
|
+
post PRIVMSG, "#channel", s
|
305
|
+
end
|
306
|
+
|
307
|
+
message = server_q.pop
|
308
|
+
message.should be_a_kind_of(Net::IRC::Message)
|
309
|
+
message.to_s.should == "PRIVMSG #channel \e$B$F$9$H\e(B\r\n"
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should allow lame RPL_WELCOME (not prefix but nick)" do
|
314
|
+
client = @client
|
315
|
+
TestServerSession.instance.instance_eval do
|
316
|
+
Thread.exclusive do
|
317
|
+
post "server", RPL_WELCOME, client.prefix.nick, "Welcome to the Internet Relay Network #{client.prefix.nick}"
|
318
|
+
post nil, NOTICE, "#test", "sep1"
|
319
|
+
end
|
320
|
+
end
|
321
|
+
Thread.pass
|
322
|
+
true until client_q.pop.to_s == "NOTICE #test sep1\r\n"
|
323
|
+
client.prefix.should == "foonick"
|
324
|
+
end
|
325
|
+
|
326
|
+
# it "should destroy closed session" do
|
327
|
+
# end
|
328
|
+
|
329
|
+
after :all do
|
330
|
+
@server.finish
|
331
|
+
@client.finish
|
332
|
+
@tserver.kill
|
333
|
+
@tclient.kill
|
334
|
+
@server = @client = @tserver = @tclient = nil
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: net-irc2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.10
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcin Łabanowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: library for implementing IRC server and client
|
14
|
+
email: marcin@6irc.net
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files:
|
18
|
+
- README
|
19
|
+
- ChangeLog
|
20
|
+
files:
|
21
|
+
- README
|
22
|
+
- ChangeLog
|
23
|
+
- Rakefile
|
24
|
+
- AUTHORS.txt
|
25
|
+
- spec/spec.opts
|
26
|
+
- spec/modeparser_spec.rb
|
27
|
+
- spec/net-irc_spec.rb
|
28
|
+
- spec/channel_manager_spec.rb
|
29
|
+
- lib/net/irc/client/channel_manager.rb
|
30
|
+
- lib/net/irc/message/modeparser.rb
|
31
|
+
- lib/net/irc/message/serverconfig.rb
|
32
|
+
- lib/net/irc/constants.rb
|
33
|
+
- lib/net/irc/message.rb
|
34
|
+
- lib/net/irc/pattern.rb
|
35
|
+
- lib/net/irc/server.rb
|
36
|
+
- lib/net/irc/client.rb
|
37
|
+
- lib/net/irc.rb
|
38
|
+
- examples/2ch.rb
|
39
|
+
- examples/2ig.rb
|
40
|
+
- examples/client.rb
|
41
|
+
- examples/echo_bot.rb
|
42
|
+
- examples/gig.rb
|
43
|
+
- examples/gmail.rb
|
44
|
+
- examples/gtig.rb
|
45
|
+
- examples/hatena-star-stream.rb
|
46
|
+
- examples/hcig.rb
|
47
|
+
- examples/hig.rb
|
48
|
+
- examples/iig.rb
|
49
|
+
- examples/ircd.rb
|
50
|
+
- examples/lingr.rb
|
51
|
+
- examples/mixi.rb
|
52
|
+
- examples/sig.rb
|
53
|
+
- examples/tig.rb
|
54
|
+
- examples/echo_bot_celluloid.rb
|
55
|
+
- examples/lig.rb
|
56
|
+
homepage: https://github.com/czaks/net-irc/
|
57
|
+
licenses: []
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --exclude
|
62
|
+
- ^(examples|extras)/
|
63
|
+
- --title
|
64
|
+
- net-irc documentation
|
65
|
+
- --charset
|
66
|
+
- utf-8
|
67
|
+
- --opname
|
68
|
+
- index.html
|
69
|
+
- --line-numbers
|
70
|
+
- --main
|
71
|
+
- README
|
72
|
+
- --inline-source
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.1.11
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: library for implementing IRC server and client
|
91
|
+
test_files: []
|