1 # Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 class LineTestCase(unittest.TestCase):
21 def test_create_str(self):
22 l = irc.Line(":origin PRIVMSG bla")
23 self.assertTrue(l is not None)
24 self.assertEquals(str(l), ":origin PRIVMSG bla")
26 def test_create_list_origin(self):
27 l = irc.Line([":origin", "PRIVMSG", "bla"])
28 self.assertTrue(l is not None)
29 self.assertEquals("origin", l.origin)
30 self.assertEquals(2, len(l))
31 self.assertEquals("PRIVMSG", l[0])
32 self.assertEquals("bla", l[1])
33 self.assertEqual(str(l), ":origin PRIVMSG :bla")
35 def test_create_list_no_origin(self):
36 l = irc.Line(["PRIVMSG", "bla"])
37 self.assertTrue(l is not None)
38 self.assertEquals(None, l.origin)
39 self.assertEquals(2, len(l))
40 self.assertEquals("PRIVMSG", l[0])
41 self.assertEquals("bla", l[1])
42 self.assertEqual(str(l), "PRIVMSG :bla")
44 def test_create_other(self):
45 l = irc.Line(":origin PRIVMSG bla")
47 self.assertEquals(str(l), str(newl))
49 def test_create_inval(self):
50 self.assertRaises(TypeError, irc.Line, 1)
52 def test__str__(self):
53 l = irc.Line(":origin PRIVMSG bla")
54 self.assertEquals(str(l), ":origin PRIVMSG bla")
57 l = irc.Line(":origin PRIVMSG bla")
58 self.assertEquals(repr(l), "Line(':origin PRIVMSG bla')")
60 def test_get_nick(self):
61 l = irc.Line(":origin PRIVMSG bla")
62 self.assertEquals(l.get_nick(), "origin")
65 l = irc.Line(":origin PRIVMSG bla")
66 self.assertEquals(len(l), 2)
68 def test_getitem(self):
69 l = irc.Line(":origin PRIVMSG bla")
70 self.assertEquals(l[0], "PRIVMSG")
71 self.assertEquals(l[1], "bla")
72 self.assertRaises(KeyError, lambda: l[2])
75 class ChannelStateTests(unittest.TestCase):
77 def test_create(self):
78 s = irc.ChannelState("#foo")
79 self.assertTrue(s is not None)
80 self.assertEquals("#foo", s.name)
83 s = irc.ChannelState("#foo")
84 self.assertTrue(s.nicks is not None)
85 self.assertEquals(0, len(s.nicks))
86 self.assertRaises(KeyError, lambda: s.nicks["nick"])
88 def test_add_nick(self):
89 s = irc.ChannelState("#foo")
90 s.nicks.add(irc.Nick("me!foo@bar"))
91 self.assertEquals(1, len(s.nicks))
92 self.assertEquals("me", s.nicks["me"].nick)
94 def test_add_nick_mode(self):
95 s = irc.ChannelState("#foo")
96 s.nicks.add(irc.Nick("me!foo@bar"), "+o")
97 self.assertEquals(1, len(s.nicks))
98 self.assertEquals("me", s.nicks["me"].nick)
99 self.assertEquals("+o", s.nicks.nick_mode("me"))
101 def test_set_key(self):
102 s = irc.ChannelState("#foo")
103 self.assertRaises(KeyError, lambda:s.mode_option['k'])
104 s.mode_option['k'] = "bar"
105 self.assertEquals("bar", s.mode_option['k'])
107 def test_limit(self):
108 s = irc.ChannelState("#foo")
109 self.assertRaises(KeyError, lambda:s.mode_option['l'])
110 s.mode_option['l'] = "42"
111 self.assertEquals("42", s.mode_option['l'])
113 def test_get_modes(self):
114 s = irc.ChannelState("#foo")
115 self.assertEquals("", s.modes)
117 def test_set_modes(self):
118 s = irc.ChannelState("#foo")
120 self.assertEquals("+n", s.modes)
122 def test_get_topic(self):
123 s = irc.ChannelState("#foo")
124 self.assertEquals(None, s.topic)
126 def test_set_topic(self):
127 s = irc.ChannelState("#foo")
130 self.assertEquals("BLA", s.topic)
132 def test_get_topic_time(self):
133 s = irc.ChannelState("#foo")
134 self.assertEquals(0, s.topic_set_time)
136 def test_get_topic_time_set(self):
137 s = irc.ChannelState("#foo")
138 s.topic_set_time = 42
139 self.assertEquals(42, s.topic_set_time)
141 def test_creationtime(self):
142 s = irc.ChannelState("#foo")
143 self.assertEquals(0, s.creation_time)
145 def test_creationtime_set(self):
146 s = irc.ChannelState("#foo")
147 s.creation_time = 423423
148 self.assertEquals(423423, s.creation_time)
152 class BaseNetworkStateTests(unittest.TestCase):
154 def test_create(self):
155 s = irc.NetworkState("nick", "user", "host")
156 self.assertTrue(s is not None)
159 s = irc.NetworkState("nick", "user", "host")
160 self.assertTrue(s.info is not None)
163 class NetworkStateTestCase(unittest.TestCase):
166 super(NetworkStateTestCase, self).setUp()
167 self.state = irc.NetworkState("nick", "user", "host")
169 def test_add_channel(self):
170 c = irc.ChannelState("#foo")
172 self.assertEquals(c.name, self.state["#foo"].name)
174 def test_add_nick(self):
175 n = irc.Nick("me!user@host")
177 self.assertEquals(n.nick, self.state["me"].nick)
179 def test_handle_line(self):
180 self.state.handle_line(":nick!user@host JOIN #foo")
182 def test_channels_empty(self):
183 self.assertEquals([], list(self.state.channels))
185 def test_channels(self):
186 self.state.handle_line(":nick!user@host JOIN #foo")
187 channels = self.state.channels
188 self.assertEquals(1, len(channels))
189 self.assertEquals("#foo", list(channels)[0].name)
190 self.assertEquals("#foo", channels["#foo"].name)
192 def test_get_channel(self):
193 self.state.handle_line(":nick!user@host JOIN #foo")
194 self.assertEquals(self.state["#foo"].name, "#foo")
196 def test_leave_channel(self):
197 self.state.handle_line(":nick!user@host JOIN #foo")
198 self.assertEquals(["#foo"], [c.name for c in self.state.channels])
199 self.state.handle_line(":nick!user@host PART #foo")
200 self.assertEquals([], [c.name for c in self.state.channels])
201 self.state.handle_line(":nick!user@host PART #ba")
203 def test_kicked_off_channel(self):
204 self.state.handle_line(":nick!user@host JOIN #foo")
205 self.assertEquals(["#foo"], [c.name for c in self.state.channels])
206 self.state.handle_line(":othernick!user@host KICK #foo :nick")
207 self.assertEquals([], [c.name for c in self.state.channels])
209 def test_channel_mode_option(self):
210 self.state.handle_line(":nick!user@host JOIN #foo")
211 self.state.handle_line(":somenick MODE #foo +l 42")
212 self.assertEquals("42", self.state["#foo"].mode_option["l"])
214 def test_channel_mode_two_options(self):
215 self.state.handle_line(":nick!user@host JOIN #foo")
216 self.state.handle_line(":somenick MODE #foo +kl bla 42")
217 self.assertEquals("42", self.state["#foo"].mode_option["l"])
218 self.assertEquals("bla", self.state["#foo"].mode_option["k"])
220 def test_channel_topic(self):
221 self.state.handle_line(":nick!user@host JOIN #foo")
222 self.state.handle_line(":someserver 332 nick #foo :The TOPIC")
223 self.assertEquals("The TOPIC", self.state["#foo"].topic)
225 def test_nick_channels(self):
226 self.state.handle_line(":nick!user@host JOIN #foo")
227 self.assertEquals(["#foo"], list(self.state["nick"].channels))
230 class NetworkInfoTests(unittest.TestCase):
232 def test_create(self):
233 s = irc.NetworkInfo()
234 self.assertTrue(s is not None)
236 def test_prefix_by_mode(self):
237 s = irc.NetworkInfo()
238 self.assertEquals("@", s.get_prefix_by_mode("o"))
240 def test_irccmp_samecase(self):
241 s = irc.NetworkInfo()
242 self.assertEquals(s.irccmp("bla", "bla"), 0)
244 def test_irccmp_diff(self):
245 s = irc.NetworkInfo()
246 self.assertNotEqual(s.irccmp("bla", "bloe"), 0)
248 def test_irccmp_diffcase(self):
249 s = irc.NetworkInfo()
250 self.assertEqual(s.irccmp("BlA", "bla"), 0)
252 def test_is_prefix(self):
253 s = irc.NetworkInfo()
254 self.assertTrue(s.is_prefix("@"))
255 self.assertFalse(s.is_prefix("a"))
257 def test_is_channelname(self):
258 s = irc.NetworkInfo()
259 self.assertTrue(s.is_channelname("#bla"))
260 self.assertFalse(s.is_channelname("nietchannel"))
263 class NetworkNickTests(unittest.TestCase):
265 def test_create(self):
266 nick = irc.Nick("nick", "user", "host")
267 self.assertEquals("nick", nick.nick)
268 self.assertEquals("user", nick.username)
269 self.assertEquals("host", nick.hostname)
270 self.assertEquals("nick!user@host", nick.hostmask)
272 def test_set_hostmask(self):
273 nick = irc.Nick("nick", "user", "host")
274 nick.hostmask = "my!new@mask"
275 self.assertEquals("my", nick.nick)
276 self.assertEquals("new", nick.username)
277 self.assertEquals("mask", nick.hostname)
278 self.assertEquals("my!new@mask", nick.hostmask)
280 def test_set_nick(self):
281 nick = irc.Nick("nick", "user", "host")
283 self.assertEquals("my", nick.nick)
284 self.assertEquals("user", nick.username)
285 self.assertEquals("host", nick.hostname)
286 self.assertEquals("my!user@host", nick.hostmask)
288 def test_set_username(self):
289 nick = irc.Nick("nick", "user", "host")
290 nick.username = "uname"
291 self.assertEquals("nick", nick.nick)
292 self.assertEquals("uname", nick.username)
293 self.assertEquals("host", nick.hostname)
294 self.assertEquals("nick!uname@host", nick.hostmask)
296 def test_default_mode(self):
297 nick = irc.Nick("nick", "user", "host")
298 self.assertEquals(None, nick.modes)
300 def test_set_mode(self):
301 nick = irc.Nick("nick", "user", "host")
303 self.assertEquals("+o", nick.modes)
305 def test_remove_mode(self):
306 nick = irc.Nick("nick", "user", "host")
308 self.assertEquals(None, nick.modes)
311 class QueryStackTests(unittest.TestCase):
314 self.stack = irc.QueryStack()
316 def test_empty(self):
317 self.assertEquals([], list(self.stack))
319 def test_privmsg(self):
320 self.stack.record("token", "PRIVMSG joe :bla")
321 entries = list(self.stack)
322 self.assertEquals(1, len(entries))
323 self.assertEquals("token", entries[0][0])
324 self.assertEquals("PRIVMSG", entries[0][1])
326 def test_privmsg2(self):
327 self.stack.record("token", "PRIVMSG joe :bla")
328 self.stack.record("token", "PRIVMSG bla :bar")
329 entries = list(self.stack)
330 self.assertEquals(2, len(entries))
331 self.assertEquals("token", entries[0][0])
332 self.assertEquals("PRIVMSG", entries[0][1])
333 self.assertEquals("token", entries[1][0])
334 self.assertEquals("PRIVMSG", entries[1][1])
336 def test_unknown_command(self):
337 self.stack.record("token", "IDONTKNOW joe :bla")
338 entries = list(self.stack)
339 self.assertEquals(1, len(entries))
340 self.assertEquals("token", entries[0][0])
341 self.assertEquals(None, entries[0][1])
342 self.assertEquals("token",
343 self.stack.response(":server 421 user :No such command"))
344 self.assertEquals([], list(self.stack))
346 def test_removes_old_unreplied(self):
347 self.stack.record("token1", "PRIVMSG joe :bla")
348 self.stack.record("token2", "UNKNOWN joe :bla")
349 entries = list(self.stack)
350 self.assertEquals(2, len(entries))
351 self.assertEquals("token1", entries[0][0])
352 self.assertEquals("token2", entries[1][0])
353 self.assertEquals("token2",
354 self.stack.response(":server 421 user :No such command"))
355 # FIXME: self.assertEquals([], list(self.stack))
358 class TransportTests(unittest.TestCase):
360 def test_create(self):
364 class DummyTransport(object):
365 """Trivial Transport."""
368 self._sent_lines = []
371 return [str(l) for l in self._sent_lines]
373 def send_line(self, line):
374 self._sent_lines.append(line)
376 def is_connected(self):
380 class ClientTests(unittest.TestCase):
382 def test_create(self):
383 c = irc.Client(DummyTransport(), "myorigin", "description")
385 def test_transport(self):
387 c = irc.Client(t, "myorigin", "description")
388 self.assertEquals(t, c.transport)
390 def test_authenticate(self):
391 c = irc.Client(DummyTransport(), "myorigin", "description")
392 self.assertEquals(False, c.authenticated)
393 c.inject_line("NICK mynick")
394 c.inject_line("USER a a a a")
395 self.assertTrue(c.state is not None)
396 self.assertEquals(True, c.authenticated)
398 def test_authenticated(self):
399 c = irc.Client(DummyTransport(), "myorigin", "description")
400 self.assertEquals(False, c.authenticated)
402 def test_state(self):
403 c = irc.Client(DummyTransport(), "myorigin", "description")
404 self.assertEquals(None, c.state)
406 def test_send_line(self):
408 c = irc.Client(t, "myorigin", "description")
409 c.send_line(":server NOTICE mynick :bla")
410 self.assertEquals(1, len(t._sent_lines))
411 self.assertEquals(":server NOTICE mynick :bla", str(t._sent_lines[0]))
413 def test_default_target(self):
414 c = irc.Client(DummyTransport(), "myorigin", "description")
415 self.assertEquals("*", c.default_target)
417 def test_default_origin(self):
418 c = irc.Client(DummyTransport(), "myorigin", "description")
419 self.assertEquals("myorigin", c.default_origin)
421 def test_own_hostmask_not_known(self):
422 c = irc.Client(DummyTransport(), "myorigin", "description")
423 self.assertEquals(None, c.own_hostmask)
425 def test_send_motd(self):
427 c = irc.Client(t, "myorigin", "description")
428 c.send_motd(["bla", "blie bloe"])
430 ':myorigin 375 * :Start of MOTD',
431 ':myorigin 372 * :bla',
432 ':myorigin 372 * :blie bloe',
433 ':myorigin 376 * :End of MOTD'], t.str_lines())
435 def test_send_luserchannels(self):
437 c = irc.Client(t, "myorigin", "description")
438 c.send_luserchannels(42)
439 self.assertEquals([':myorigin 254 * 42 :channels formed'],
442 def test_send_netsplit_none(self):
444 c = irc.Client(t, "myorigin", "description")
445 c.send_netsplit("us", "myserver")
446 self.assertEquals([], t.str_lines())
448 def test_send_channel_mode_none(self):
450 c = irc.Client(t, "myorigin", "description")
451 ch = irc.ChannelState("#ch")
452 c.send_channel_mode(ch)
453 self.assertEquals([], t.str_lines())
455 def test_send_banlist(self):
457 c = irc.Client(t, "myorigin", "description")
458 ch = irc.ChannelState("#ch")
460 self.assertEquals([':myorigin 368 * #ch :End of channel ban list'],
463 def test_send_nameslist(self):
465 c = irc.Client(t, "myorigin", "description")
466 ch = irc.ChannelState("#ch")
468 self.assertEquals([':myorigin 366 * #ch :End of /NAMES list'],
471 def test_send_channel_state(self):
473 c = irc.Client(t, "myorigin", "description")
474 ch = irc.ChannelState("#ch")
475 c.send_channel_state(ch)
478 ':myorigin 366 * #ch :End of /NAMES list'],
481 def test_send_channel_state_diff(self):
483 c = irc.Client(t, "myorigin", "description")
484 ch1 = irc.ChannelState("#ch")
485 ch2 = irc.ChannelState("#ch")
486 c.send_channel_state_diff(ch1, ch2)
487 self.assertEquals([], t.str_lines())
489 def test_send_topic(self):
491 c = irc.Client(t, "myorigin", "description")
492 ch = irc.ChannelState("#ch")
493 c.send_topic(ch, False)
494 self.assertEquals([], t.str_lines())
495 c.send_topic(ch, True)
496 self.assertEquals([':myorigin 331 * #ch :No topic set'], t.str_lines())
499 ch.topic_set_time = 4324324L
501 self.assertEquals([':myorigin 332 * #ch :LALALA'], t.str_lines())
503 def test_last_ping(self):
505 c = irc.Client(t, "myorigin", "description")
506 self.assertEquals(0, c.last_ping)
508 def test_last_pong(self):
510 c = irc.Client(t, "myorigin", "description")
511 self.assertEquals(0, c.last_pong)
513 def test_description(self):
515 c = irc.Client(t, "myorigin", "description")
516 self.assertEquals("description", c.description)
519 class ClientSendStateTests(unittest.TestCase):
522 super(ClientSendStateTests, self).setUp()
523 self.transport = DummyTransport()
524 self.client = irc.Client(self.transport, "myorigin", "description")
525 self.state = irc.NetworkState("nick", "user", "host")
527 def assertLines(self, lines):
528 self.assertEquals(lines, self.transport.str_lines())
530 def test_empty(self):
531 self.client.send_state(self.state)
534 def test_with_channel(self):
535 ch = irc.ChannelState("#foo")
538 self.client.send_state(self.state)
541 ':myorigin 332 * #foo :bla la',
542 ':myorigin 366 * #foo :End of /NAMES list'])
544 def test_empty_diff(self):
545 self.client.send_state_diff(self.state, self.state)
549 class NetworkStateDiffTests(unittest.TestCase):
552 super(NetworkStateDiffTests, self).setUp()
553 self.transport = DummyTransport()
554 self.client = irc.Client(self.transport, "myorigin", "description")
555 self.state1 = irc.NetworkState("nick", "user", "host")
556 self.state2 = irc.NetworkState("nick", "user", "host")
558 def assertLines(self, lines):
559 self.assertEquals(lines, self.transport.str_lines())
561 def test_new_channel(self):
562 self.state2.add(irc.ChannelState("#foo"))
563 self.client.send_state_diff(self.state1, self.state2)
564 self.assertLines(['JOIN #foo',
565 ':myorigin 366 * #foo :End of /NAMES list'])
567 def test_leave_channel(self):
568 self.state1.add(irc.ChannelState("#foo"))
569 self.client.send_state_diff(self.state1, self.state2)
570 self.assertLines(['PART #foo'])
573 class ChannelStateDiffTests(unittest.TestCase):
576 super(ChannelStateDiffTests, self).setUp()
577 self.transport = DummyTransport()
578 self.client = irc.Client(self.transport, "myorigin", "description")
579 self.state1 = irc.NetworkState("nick", "user", "host")
580 self.state2 = irc.NetworkState("nick", "user", "host")
581 self.channel1 = irc.ChannelState("#foo")
582 self.channel2 = irc.ChannelState("#foo")
583 self.state1.add(self.channel1)
584 self.state2.add(self.channel2)
586 def assertLines(self, lines):
587 self.assertEquals(lines, self.transport.str_lines())
589 def test_diff_topic_set(self):
590 self.channel2.topic = "bla la"
591 self.client.send_state_diff(self.state1, self.state2)
592 self.assertLines(['TOPIC #foo :bla la'])
594 def test_diff_topic_unset(self):
595 self.channel1.topic = "bla la"
596 self.client.send_state_diff(self.state1, self.state2)
597 self.assertLines(['TOPIC #foo'])
599 def test_diff_nicks_leave(self):
600 self.channel1.nicks.add(irc.Nick("me!foo@bar"))
601 self.channel1.nicks.add(irc.Nick("you!foo@bar"))
602 self.client.send_state_diff(self.state1, self.state2)
603 self.assertLines([':me!foo@bar PART #foo', ':you!foo@bar PART #foo'])
605 def test_diff_nicks_join(self):
606 self.channel2.nicks.add(irc.Nick("me!foo@bar"))
607 self.channel2.nicks.add(irc.Nick("you!foo@bar"))
608 self.client.send_state_diff(self.state1, self.state2)
609 self.assertLines([':me!foo@bar JOIN #foo', ':you!foo@bar JOIN #foo'])
611 def test_diff_nick_change(self):
612 self.channel1.nicks.add(irc.Nick("me!foo@bar"))
613 self.channel2.nicks.add(irc.Nick("you!foo@bar"))
614 self.client.send_state_diff(self.state1, self.state2)
615 # FIXME: self.assertLines([':me!foo@bar NICK you'])
617 def test_diff_mode(self):
618 self.channel2.modes = "+r"
619 self.client.send_state_diff(self.state1, self.state2)
620 self.assertLines([':myorigin MODE #foo +r'])
622 def test_diff_mode_remove(self):
623 self.channel1.modes = "+p"
624 self.channel2.modes = "+r"
625 self.client.send_state_diff(self.state1, self.state2)
626 #FIXME: self.assertLines([':myorigin MODE #foo -p+r'])
629 class NetsplitTests(unittest.TestCase):
632 super(NetsplitTests, self).setUp()
633 self.transport = DummyTransport()
634 self.client = irc.Client(self.transport, "myserverorigin",
636 self.client.inject_line("NICK mynick")
637 self.client.inject_line("USER a a a a")
638 self.assertEquals(True, self.client.authenticated)
640 def assertLines(self, lines):
641 self.client.send_netsplit("us", "upstream")
642 self.assertEquals(lines, self.transport.str_lines())
644 def test_no_channels(self):
647 def test_channel_no_nicks(self):
648 self.client.state.add(irc.ChannelState("#foo"))
651 def test_channel_one_nick(self):
652 c = irc.ChannelState("#foo")
653 c.nicks.add(irc.Nick("somebody!someuser@somehost"))
654 self.client.state.add(c)
655 self.assertLines([":somebody!someuser@somehost QUIT :us upstream"])
657 def test_channel_lots_of_nicks(self):
658 c = irc.ChannelState("#foo")
660 c.nicks.add(irc.Nick("some%d!someuser@somehost" % i))
661 self.client.state.add(c)
662 self.assertLines([":some%d!someuser@somehost QUIT :us upstream" % i for i in range(10)])
665 class LinestackTests(unittest.TestCase):
667 def get_basedir(self):
671 return irc.NetworkState("nick", "user", "host")
673 def test_create(self):
674 ls = irc.Linestack("network", True, self.get_basedir(), self.get_state())
675 self.assertTrue(ls is not None)
677 def test_insert_line(self):
678 state = self.get_state()
679 ls = irc.Linestack("insert_line", True, self.get_basedir(), state)
680 ls.insert_line(":somebody!some@host PRIVMSG #bla :BAR!",
681 irc.TO_SERVER, state)