File: net-irc_spec.rb

package info (click to toggle)
ruby-net-irc 0.0.9-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 408 kB
  • sloc: ruby: 7,268; makefile: 3
file content (337 lines) | stat: -rwxr-xr-x 8,902 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
#!spec
# coding: ASCII-8BIT
# vim:encoding=UTF-8:

$LOAD_PATH << "lib"
$LOAD_PATH << "../lib"

require "rubygems"
require "spec"
require "net/irc"
include Net::IRC
include Constants

describe Net::IRC::Message, "construct" do

	it "should generate message correctly" do
		m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
		m.to_s.should == ":foo PRIVMSG #channel message\r\n"

		m = Message.new("foo", "PRIVMSG", ["#channel", "message with space"])
		m.to_s.should == ":foo PRIVMSG #channel :message with space\r\n"

		m = Message.new(nil, "PRIVMSG", ["#channel", "message"])
		m.to_s.should == "PRIVMSG #channel message\r\n"

		m = Message.new(nil, "PRIVMSG", ["#channel", "message with space"])
		m.to_s.should == "PRIVMSG #channel :message with space\r\n"

		m = Message.new(nil, "MODE", [
			"#channel",
			"+ooo",
			"nick1",
			"nick2",
			"nick3"
		])
		m.to_s.should == "MODE #channel +ooo nick1 nick2 nick3\r\n"

		m = Message.new(nil, "KICK", [
			"#channel,#channel1",
			"nick1,nick2",
		])
		m.to_s.should == "KICK #channel,#channel1 nick1,nick2\r\n"
	end

	it "should have ctcp? method" do
		m = Message.new("foo", "PRIVMSG", ["#channel", "\x01ACTION foo\x01"])
		m.ctcp?.should be_true
	end

	it "should behave as Array contains params" do
		m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
		m[0].should   == m.params[0]
		m[1].should   == m.params[1]
		m.to_a.should == ["#channel", "message"]

		channel, message = *m
		channel.should == "#channel"
		message.should == "message"
	end

	it "#to_a should return duplicated array" do
		m = Message.new("foo", "PRIVMSG", ["#channel", "message"])
		m[0].should   == m.params[0]
		m[1].should   == m.params[1]
		m.to_a.should == ["#channel", "message"]
		m.to_a.clear
		m.to_a.should == ["#channel", "message"]
	end
end

describe Net::IRC::Message, "parse" do
	it "should parse correctly following RFC." do
		m = Message.parse("PRIVMSG #channel message\r\n")
		m.prefix.should  == ""
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "message"]

		m = Message.parse("PRIVMSG #channel :message leading :\r\n")
		m.prefix.should  == ""
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "message leading :"]

		m = Message.parse("PRIVMSG #channel middle :message leading :\r\n")
		m.prefix.should  == ""
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "middle", "message leading :"]

		m = Message.parse("PRIVMSG #channel middle message with middle\r\n")
		m.prefix.should  == ""
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "middle", "message", "with", "middle"]

		m = Message.parse(":prefix PRIVMSG #channel message\r\n")
		m.prefix.should  == "prefix"
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "message"]

		m = Message.parse(":prefix PRIVMSG #channel :message leading :\r\n")
		m.prefix.should  == "prefix"
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "message leading :"]
	end

	it "should allow multibyte " do
		m = Message.parse(":てすと PRIVMSG #channel :message leading :\r\n")
		m.prefix.should  == "てすと"
		m.command.should == "PRIVMSG"
		m.params.should  == ["#channel", "message leading :"]
	end

	it "should allow space at end" do
		m = Message.parse("JOIN #foobar \r\n")
		m.prefix.should  == ""
		m.command.should == "JOIN"
		m.params.should  == ["#foobar"]
	end
end

describe Net::IRC::Constants, "lookup" do
	it "should lookup numeric replies from Net::IRC::COMMANDS" do
		welcome = Net::IRC::Constants.const_get("RPL_WELCOME")
		welcome.should == "001"
		Net::IRC::COMMANDS[welcome].should == "RPL_WELCOME"
	end
end

describe Net::IRC::Prefix, "" do
	it "should be kind of String" do
		Prefix.new("").should be_kind_of(String)
	end

	it "should parse prefix correctly." do
		prefix = Prefix.new("foo!bar@localhost")
		prefix.extract.should == ["foo", "bar", "localhost"]

		prefix = Prefix.new("foo!-bar@localhost")
		prefix.extract.should == ["foo", "-bar", "localhost"]

		prefix = Prefix.new("foo!+bar@localhost")
		prefix.extract.should == ["foo", "+bar", "localhost"]

		prefix = Prefix.new("foo!~bar@localhost")
		prefix.extract.should == ["foo", "~bar", "localhost"]
	end

	it "should allow multibyte in nick." do
		prefix = Prefix.new("あああ!~bar@localhost")
		prefix.extract.should == ["あああ", "~bar", "localhost"]
	end

	it "should allow lame prefix." do
		prefix = Prefix.new("nick")
		prefix.extract.should == ["nick", nil, nil]
	end

	it "has nick method" do
		prefix = Prefix.new("foo!bar@localhost")
		prefix.nick.should == "foo"
	end

	it "has user method" do
		prefix = Prefix.new("foo!bar@localhost")
		prefix.user.should == "bar"
	end

	it "has host method" do
		prefix = Prefix.new("foo!bar@localhost")
		prefix.host.should == "localhost"
	end
end

describe Net::IRC, "utilities" do
	it "has ctcp_encode method" do
		message = ctcp_encode "ACTION hehe"
		message.should == "\x01ACTION hehe\x01"

		message = ctcp_encode "ACTION \x01 \x5c "
		message.should == "\x01ACTION \x5c\x61 \x5c\x5c \x01"

		message = ctcp_encode "ACTION \x00 \x0a \x0d \x10 "
		message.should == "\x01ACTION \x100 \x10n \x10r \x10\x10 \x01"
	end

	it "has ctcp_decode method" do
		message = ctcp_decode "\x01ACTION hehe\x01"
		message.should == "ACTION hehe"

		message = ctcp_decode "\x01ACTION \x5c\x61 \x5c\x5c \x01"
		message.should == "ACTION \x01 \x5c "

		message = ctcp_decode "\x01ACTION \x100 \x10n \x10r \x10\x10 \x01"
		message.should == "ACTION \x00 \x0a \x0d \x10 "
	end
end

class TestServerSession < Net::IRC::Server::Session
	@@testq = SizedQueue.new(1)
	@@instance = nil

	def self.testq
		@@testq
	end

	def self.instance
		@@instance
	end

	def initialize(*args)
		super
		@@instance = self
	end

	def on_message(m)
		@@testq << m
	end
end

class TestClient < Net::IRC::Client
	@@testq = SizedQueue.new(1)

	def self.testq
		@@testq
	end

	def on_message(m)
		@@testq << m
	end
end

describe Net::IRC, "server and client" do
	before :all do
		@port = nil
		@server, @client = nil, nil

		Thread.abort_on_exception = true
		@tserver = Thread.start do
			@server = Net::IRC::Server.new("localhost", @port, TestServerSession, {
				:logger => Logger.new(nil),
			})
			@server.start
		end

		Thread.pass
		true until @server.instance_variable_get(:@serv)

		@port = @server.instance_variable_get(:@serv).addr[1]

		@tclient = Thread.start do
			@client = TestClient.new("localhost", @port, {
				:nick   => "foonick",
				:user   => "foouser",
				:real   => "foo real name",
				:pass   => "foopass",
				:logger => Logger.new(nil),
			})
			@client.start
		end

		Thread.pass
		true until @client
	end

	server_q = TestServerSession.testq
	client_q = TestClient.testq

	it "client should send pass/nick/user sequence." do
		server_q.pop.to_s.should == "PASS foopass\r\n"
		server_q.pop.to_s.should == "NICK foonick\r\n"
		server_q.pop.to_s.should == "USER foouser 0 * :foo real name\r\n"
	end

	it "server should send 001,002,003 numeric replies." do
		client_q.pop.to_s.should match(/^:net-irc 001 foonick :Welcome to the Internet Relay Network \S+!\S+@\S+/)
		client_q.pop.to_s.should match(/^:net-irc 002 foonick :Your host is .+?, running version /)
		client_q.pop.to_s.should match(/^:net-irc 003 foonick :This server was created /)
	end

	it "client posts PRIVMSG and server receives it." do
		@client.instance_eval do
			post PRIVMSG, "#channel", "message a b c"
		end

		message = server_q.pop
		message.should be_a_kind_of(Net::IRC::Message)
		message.to_s.should == "PRIVMSG #channel :message a b c\r\n"
	end

	if defined? Encoding
		it "dummy encoding: client posts PRIVMSG and server receives it." do
			@client.instance_eval do
				s = "てすと".force_encoding("UTF-8")
				post PRIVMSG, "#channel", s
			end

			message = server_q.pop
			message.should be_a_kind_of(Net::IRC::Message)
			message.to_s.should == "PRIVMSG #channel てすと\r\n"
		end

		it "dummy encoding: client posts PRIVMSG and server receives it." do
			@client.instance_eval do
				s = "てすと".force_encoding("UTF-8")
				s.encode!("ISO-2022-JP")
				post PRIVMSG, "#channel", s
			end

			message = server_q.pop
			message.should be_a_kind_of(Net::IRC::Message)
			message.to_s.should == "PRIVMSG #channel \e$B$F$9$H\e(B\r\n"
		end
	end

	it "should allow lame RPL_WELCOME (not prefix but nick)" do
		client = @client
		TestServerSession.instance.instance_eval do
			Thread.exclusive do
				post "server", RPL_WELCOME, client.prefix.nick, "Welcome to the Internet Relay Network #{client.prefix.nick}"
				post nil,      NOTICE, "#test", "sep1"
			end
		end
		Thread.pass
		true until client_q.pop.to_s == "NOTICE #test sep1\r\n"
		client.prefix.should == "foonick"
	end

#	it "should destroy closed session" do
#	end

	after :all do
		@server.finish
		@client.finish
		@tserver.kill
		@tclient.kill
		@server = @client = @tserver = @tclient = nil
	end
end