net-irc2 0.0.10
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.
- 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: []
|