Add basic python bindings for linestack.
[jelmer/ctrlproxy.git] / libirc / python / tests / test_irc.py
1 # Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
2  
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.
7
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.
12
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/>.
15
16 import irc
17 import unittest
18
19 class LineTestCase(unittest.TestCase):
20
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")
25
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")
34
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")
43
44     def test_create_other(self):
45         l = irc.Line(":origin PRIVMSG bla")
46         newl = irc.Line(l)
47         self.assertEquals(str(l), str(newl))
48
49     def test_create_inval(self):
50         self.assertRaises(TypeError, irc.Line, 1)
51
52     def test__str__(self):
53         l = irc.Line(":origin PRIVMSG bla")
54         self.assertEquals(str(l), ":origin PRIVMSG bla")
55
56     def test_repr(self):
57         l = irc.Line(":origin PRIVMSG bla")
58         self.assertEquals(repr(l), "Line(':origin PRIVMSG bla')")
59
60     def test_get_nick(self):
61         l = irc.Line(":origin PRIVMSG bla")
62         self.assertEquals(l.get_nick(), "origin")
63
64     def test_len(self):
65         l = irc.Line(":origin PRIVMSG bla")
66         self.assertEquals(len(l), 2)
67
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])
73
74
75 class ChannelStateTests(unittest.TestCase):
76
77     def test_create(self):
78         s = irc.ChannelState("#foo")
79         self.assertTrue(s is not None)
80         self.assertEquals("#foo", s.name)
81
82     def test_nicks(self):
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"])
87
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)
93
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"))
100
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'])
106
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'])
112
113     def test_get_modes(self):
114         s = irc.ChannelState("#foo")
115         self.assertEquals("", s.modes)
116
117     def test_set_modes(self):
118         s = irc.ChannelState("#foo")
119         s.modes = "+n"
120         self.assertEquals("+n", s.modes)
121
122     def test_get_topic(self):
123         s = irc.ChannelState("#foo")
124         self.assertEquals(None, s.topic)
125
126     def test_set_topic(self):
127         s = irc.ChannelState("#foo")
128         s.topic = None
129         s.topic = "BLA"
130         self.assertEquals("BLA", s.topic)
131
132     def test_get_topic_time(self):
133         s = irc.ChannelState("#foo")
134         self.assertEquals(0, s.topic_set_time)
135
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)
140
141     def test_creationtime(self):
142         s = irc.ChannelState("#foo")
143         self.assertEquals(0, s.creation_time)
144
145     def test_creationtime_set(self):
146         s = irc.ChannelState("#foo")
147         s.creation_time = 423423
148         self.assertEquals(423423, s.creation_time)
149
150
151
152 class BaseNetworkStateTests(unittest.TestCase):
153
154     def test_create(self):
155         s = irc.NetworkState("nick", "user", "host")
156         self.assertTrue(s is not None)
157
158     def test_info(self):
159         s = irc.NetworkState("nick", "user", "host")
160         self.assertTrue(s.info is not None)
161
162
163 class NetworkStateTestCase(unittest.TestCase):
164
165     def setUp(self):
166         super(NetworkStateTestCase, self).setUp()
167         self.state = irc.NetworkState("nick", "user", "host")
168
169     def test_add_channel(self):
170         c = irc.ChannelState("#foo")
171         self.state.add(c)
172         self.assertEquals(c.name, self.state["#foo"].name)
173
174     def test_add_nick(self):
175         n = irc.Nick("me!user@host")
176         self.state.add(n)
177         self.assertEquals(n.nick, self.state["me"].nick)
178
179     def test_handle_line(self):
180         self.state.handle_line(":nick!user@host JOIN #foo")
181
182     def test_channels_empty(self):
183         self.assertEquals([], list(self.state.channels))
184         
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)
191
192     def test_get_channel(self):
193         self.state.handle_line(":nick!user@host JOIN #foo")
194         self.assertEquals(self.state["#foo"].name, "#foo")
195
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")
202
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])
208
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"])
213
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"])
219
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)
224
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))
228
229
230 class NetworkInfoTests(unittest.TestCase):
231
232     def test_create(self):
233         s = irc.NetworkInfo()
234         self.assertTrue(s is not None)
235
236     def test_prefix_by_mode(self):
237         s = irc.NetworkInfo()
238         self.assertEquals("@", s.get_prefix_by_mode("o"))
239
240     def test_irccmp_samecase(self):
241         s = irc.NetworkInfo()
242         self.assertEquals(s.irccmp("bla", "bla"), 0)
243
244     def test_irccmp_diff(self):
245         s = irc.NetworkInfo()
246         self.assertNotEqual(s.irccmp("bla", "bloe"), 0)
247
248     def test_irccmp_diffcase(self):
249         s = irc.NetworkInfo()
250         self.assertEqual(s.irccmp("BlA", "bla"), 0)
251
252     def test_is_prefix(self):
253         s = irc.NetworkInfo()
254         self.assertTrue(s.is_prefix("@"))
255         self.assertFalse(s.is_prefix("a"))
256
257     def test_is_channelname(self):
258         s = irc.NetworkInfo()
259         self.assertTrue(s.is_channelname("#bla"))
260         self.assertFalse(s.is_channelname("nietchannel"))
261
262
263 class NetworkNickTests(unittest.TestCase):
264
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)
271
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)
279
280     def test_set_nick(self):
281         nick = irc.Nick("nick", "user", "host")
282         nick.nick = "my"
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)
287
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)
295
296     def test_default_mode(self):
297         nick = irc.Nick("nick", "user", "host")
298         self.assertEquals(None, nick.modes)
299
300     def test_set_mode(self):
301         nick = irc.Nick("nick", "user", "host")
302         nick.modes = "+o"
303         self.assertEquals("+o", nick.modes)
304
305     def test_remove_mode(self):
306         nick = irc.Nick("nick", "user", "host")
307         nick.modes = ""
308         self.assertEquals(None, nick.modes)
309
310
311 class QueryStackTests(unittest.TestCase):
312
313     def setUp(self):
314         self.stack = irc.QueryStack()
315
316     def test_empty(self):
317         self.assertEquals([], list(self.stack))
318
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])
325
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])
335
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))
345
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))
356
357
358 class TransportTests(unittest.TestCase):
359
360     def test_create(self):
361         t = irc.Transport()
362
363
364 class DummyTransport(object):
365     """Trivial Transport."""
366
367     def __init__(self):
368         self._sent_lines = []
369
370     def str_lines(self):
371         return [str(l) for l in self._sent_lines]
372
373     def send_line(self, line):
374         self._sent_lines.append(line)
375
376     def is_connected(self):
377         return True
378
379
380 class ClientTests(unittest.TestCase):
381
382     def test_create(self):
383         c = irc.Client(DummyTransport(), "myorigin", "description")
384
385     def test_transport(self):
386         t = DummyTransport()
387         c = irc.Client(t, "myorigin", "description")
388         self.assertEquals(t, c.transport)
389
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)
397
398     def test_authenticated(self):
399         c = irc.Client(DummyTransport(), "myorigin", "description")
400         self.assertEquals(False, c.authenticated)
401
402     def test_state(self):
403         c = irc.Client(DummyTransport(), "myorigin", "description")
404         self.assertEquals(None, c.state)
405
406     def test_send_line(self):
407         t = DummyTransport()
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]))
412
413     def test_default_target(self):
414         c = irc.Client(DummyTransport(), "myorigin", "description")
415         self.assertEquals("*", c.default_target)
416
417     def test_default_origin(self):
418         c = irc.Client(DummyTransport(), "myorigin", "description")
419         self.assertEquals("myorigin", c.default_origin)
420
421     def test_own_hostmask_not_known(self):
422         c = irc.Client(DummyTransport(), "myorigin", "description")
423         self.assertEquals(None, c.own_hostmask)
424
425     def test_send_motd(self):
426         t = DummyTransport()
427         c = irc.Client(t, "myorigin", "description")
428         c.send_motd(["bla", "blie bloe"])
429         self.assertEquals([
430             ':myorigin 375 * :Start of MOTD',
431             ':myorigin 372 * :bla',
432             ':myorigin 372 * :blie bloe',
433             ':myorigin 376 * :End of MOTD'], t.str_lines())
434
435     def test_send_luserchannels(self):
436         t = DummyTransport()
437         c = irc.Client(t, "myorigin", "description")
438         c.send_luserchannels(42)
439         self.assertEquals([':myorigin 254 * 42 :channels formed'],
440                 t.str_lines())
441
442     def test_send_netsplit_none(self):
443         t = DummyTransport()
444         c = irc.Client(t, "myorigin", "description")
445         c.send_netsplit("us", "myserver")
446         self.assertEquals([], t.str_lines())
447
448     def test_send_channel_mode_none(self):
449         t = DummyTransport()
450         c = irc.Client(t, "myorigin", "description")
451         ch = irc.ChannelState("#ch")
452         c.send_channel_mode(ch)
453         self.assertEquals([], t.str_lines())
454
455     def test_send_banlist(self):
456         t = DummyTransport()
457         c = irc.Client(t, "myorigin", "description")
458         ch = irc.ChannelState("#ch")
459         c.send_banlist(ch)
460         self.assertEquals([':myorigin 368 * #ch :End of channel ban list'],
461             t.str_lines())
462
463     def test_send_nameslist(self):
464         t = DummyTransport()
465         c = irc.Client(t, "myorigin", "description")
466         ch = irc.ChannelState("#ch")
467         c.send_nameslist(ch)
468         self.assertEquals([':myorigin 366 * #ch :End of /NAMES list'],
469             t.str_lines())
470
471     def test_send_channel_state(self):
472         t = DummyTransport()
473         c = irc.Client(t, "myorigin", "description")
474         ch = irc.ChannelState("#ch")
475         c.send_channel_state(ch)
476         self.assertEquals([
477             'JOIN #ch', 
478             ':myorigin 366 * #ch :End of /NAMES list'],
479             t.str_lines())
480
481     def test_send_channel_state_diff(self):
482         t = DummyTransport()
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())
488
489     def test_send_topic(self):
490         t = DummyTransport()
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())
497         t._sent_lines = []
498         ch.topic = "LALALA"
499         ch.topic_set_time = 4324324L
500         c.send_topic(ch)
501         self.assertEquals([':myorigin 332 * #ch :LALALA'], t.str_lines())
502
503     def test_last_ping(self):
504         t = DummyTransport()
505         c = irc.Client(t, "myorigin", "description")
506         self.assertEquals(0, c.last_ping)
507
508     def test_last_pong(self):
509         t = DummyTransport()
510         c = irc.Client(t, "myorigin", "description")
511         self.assertEquals(0, c.last_pong)
512
513     def test_description(self):
514         t = DummyTransport()
515         c = irc.Client(t, "myorigin", "description")
516         self.assertEquals("description", c.description)
517
518
519 class ClientSendStateTests(unittest.TestCase):
520
521     def setUp(self):
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")
526
527     def assertLines(self, lines):
528         self.assertEquals(lines, self.transport.str_lines())
529
530     def test_empty(self):
531         self.client.send_state(self.state)
532         self.assertLines([])
533
534     def test_with_channel(self):
535         ch = irc.ChannelState("#foo")
536         ch.topic = "bla la"
537         self.state.add(ch)
538         self.client.send_state(self.state)
539         self.assertLines([
540             'JOIN #foo', 
541             ':myorigin 332 * #foo :bla la', 
542             ':myorigin 366 * #foo :End of /NAMES list'])
543
544     def test_empty_diff(self):
545         self.client.send_state_diff(self.state, self.state)
546         self.assertLines([])
547
548
549 class NetworkStateDiffTests(unittest.TestCase):
550
551     def setUp(self):
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")
557
558     def assertLines(self, lines):
559         self.assertEquals(lines, self.transport.str_lines())
560
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'])
566
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'])
571
572
573 class ChannelStateDiffTests(unittest.TestCase):
574
575     def setUp(self):
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)
585
586     def assertLines(self, lines):
587         self.assertEquals(lines, self.transport.str_lines())
588
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'])
593
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'])
598
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'])
604
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'])
610
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'])
616
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'])
621
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'])
627
628
629 class NetsplitTests(unittest.TestCase):
630
631     def setUp(self):
632         super(NetsplitTests, self).setUp()
633         self.transport = DummyTransport()
634         self.client = irc.Client(self.transport, "myserverorigin", 
635                 "description")
636         self.client.inject_line("NICK mynick")
637         self.client.inject_line("USER a a a a")
638         self.assertEquals(True, self.client.authenticated)
639
640     def assertLines(self, lines):
641         self.client.send_netsplit("us", "upstream")
642         self.assertEquals(lines, self.transport.str_lines())
643
644     def test_no_channels(self):
645         self.assertLines([])
646
647     def test_channel_no_nicks(self):
648         self.client.state.add(irc.ChannelState("#foo"))
649         self.assertLines([])
650
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"])
656
657     def test_channel_lots_of_nicks(self):
658         c = irc.ChannelState("#foo")
659         for i in range(10):
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)])
663
664
665 class LinestackTests(unittest.TestCase):
666
667     def get_basedir(self):
668         return "/tmp"
669
670     def get_state(self):
671         return irc.NetworkState("nick", "user", "host")
672
673     def test_create(self):
674         ls = irc.Linestack("network", True, self.get_basedir(), self.get_state())
675         self.assertTrue(ls is not None)
676
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)