2 > NICK :foo
# expect some NOTICE and PING to process/reply during initiation
-2 < :*.?.net NOTICE * :*** Looking up your ident...
+0:2 < :*.?.net NOTICE * :*** Looking up your ident...
1,2 $$$ *** Looking up your ident...
-2 < :*.?.net NOTICE * :*** Looking up your hostname...
+0:2 < :*.?.net NOTICE * :*** Looking up your hostname...
1,2 $$$ *** Looking up your hostname...
-2 < :*.?.net NOTICE * :*** Found your hostname (baz.bar.foo)
+0:2 < :*.?.net NOTICE * :*** Found your hostname (baz.bar.foo)
1,2 $$$ *** Found your hostname (baz.bar.foo)
-2 < PING :?
+0:2 < PING :?
2 > PONG :?
# handle 433
-2 < :*.?.net 433 * foo :Nickname already in use
+0:2 < :*.?.net 433 * foo :Nickname already in use
1,2 !$ nickname already in use, trying increment
2 > NICK :foo0
-2 < :*.?.net 433 * foo0 :Nickname already in use
+0:2 < :*.?.net 433 * foo0 :Nickname already in use
1,2 !$ nickname already in use, trying increment
2 > NICK :foo1
# collect server capabilities
-2 < :*.?.net CAP * LS : foo bar sasl=PLAIN,EXTERNAL baz
+0:2 < :*.?.net CAP * LS : foo bar sasl=PLAIN,EXTERNAL baz
2 > CAP REQ :sasl
2 > CAP :LIST
-2 < :*.?.net CAP * ACK :sasl
-2 < :*.?.net CAP * LIST :cap-notify sasl
+0:2 < :*.?.net CAP * ACK :sasl
+0:2 < :*.?.net CAP * LIST :cap-notify sasl
1,2 $ caps:bar:data set to: []
1,2 $ caps:baz:data set to: []
1,2 $ caps:foo:data set to: []
# authenticate via SASL, collect items of user identity
1,2 $ sasl_auth_state set to: [attempting]
2 > AUTHENTICATE :PLAIN
-2 < AUTHENTICATE +
+0:2 < AUTHENTICATE +
2 > AUTHENTICATE :Zm9vAGZvbwBiYXI=
-2 < :foo.bar.baz 900 foo1 foo1!foobarbazq@baz.bar.foo foo :You are now logged in as foo
+0:2 < :foo.bar.baz 900 foo1 foo1!foobarbazq@baz.bar.foo foo :You are now logged in as foo
1,2 $ users:me:nick set to: [?]
1,2 $ users:me:nick set to: [foo1]
1,2 $ users:me:user set to: [foobarbazq]
1,2 $ users:me:host set to: [baz.bar.foo]
1,2 $ sasl_account set to: [foo]
-2 < :foo.bar.baz 903 foo1 :SASL authentication successful
+0:2 < :foo.bar.baz 903 foo1 :SASL authentication successful
1,2 $ sasl_auth_state set to: [SASL authentication successful]
# finish CAP negotation, thus login procedure
2 > CAP :END
# of all pre-MOTD greeting messages, only process isupports
-2 < :foo.bar.baz 001 foo1 :Welcome to the foo.bar.baz network
-2 < :foo.bar.baz 002 foo1 :Your host is foo.bar.baz
-2 < :foo.bar.baz 003 foo1 :This server was created Jan 1 2020
-2 < :foo.bar.baz 004 foo1 foo.bar.baz ircserver-1.0 abc def ghi
-2 < :foo.bar.baz 005 foo1 ABC=DEF GHI=JKL :are supported by this server
+0:2 < :foo.bar.baz 001 foo1 :Welcome to the foo.bar.baz network
+0:2 < :foo.bar.baz 002 foo1 :Your host is foo.bar.baz
+0:2 < :foo.bar.baz 003 foo1 :This server was created Jan 1 2020
+0:2 < :foo.bar.baz 004 foo1 foo.bar.baz ircserver-1.0 abc def ghi
+0:2 < :foo.bar.baz 005 foo1 ABC=DEF GHI=JKL :are supported by this server
1,2 $ isupport:ABC set to: [DEF]
1,2 $ isupport:GHI set to: [JKL]
-2 < :foo.bar.baz 005 foo1 MNO=PQR STU=VWX Y=Z :are supported by this server
+0:2 < :foo.bar.baz 005 foo1 MNO=PQR STU=VWX Y=Z :are supported by this server
1,2 $ isupport:MNO set to: [PQR]
1,2 $ isupport:STU set to: [VWX]
1,2 $ isupport:Y set to: [Z]
-2 < :foo.bar.baz 251 foo1 :There are 10 users and 1000 invisible on 5 servers
-2 < :foo.bar.baz 252 foo1 7 :IRC Operators online
-2 < :foo.bar.baz 253 foo1 4 :unknown connection(s)
-2 < :foo.bar.baz 254 foo1 800 :channels formed
-2 < :foo.bar.baz 255 foo1 :I have 100 clients and 1 serveres
-2 < :foo.bar.baz 265 foo1 100 150 :Current local users 100, max 150
-2 < :foo.bar.baz 266 foo1 1010 1050 :Current global users 1010, max 1050
-2 < :foo.bar.baz 250 foo1 :Highest connection count: 151 (150 clients) (1080 connections received)
+0:2 < :foo.bar.baz 251 foo1 :There are 10 users and 1000 invisible on 5 servers
+0:2 < :foo.bar.baz 252 foo1 7 :IRC Operators online
+0:2 < :foo.bar.baz 253 foo1 4 :unknown connection(s)
+0:2 < :foo.bar.baz 254 foo1 800 :channels formed
+0:2 < :foo.bar.baz 255 foo1 :I have 100 clients and 1 serveres
+0:2 < :foo.bar.baz 265 foo1 100 150 :Current local users 100, max 150
+0:2 < :foo.bar.baz 266 foo1 1010 1050 :Current global users 1010, max 1050
+0:2 < :foo.bar.baz 250 foo1 :Highest connection count: 151 (150 clients) (1080 connections received)
# collect MOTD into a single output (rather than line-by-line)
-2 < :foo.bar.baz 375 foo1 :- foo.bar.baz Message of the Day -
-2 < :foo.bar.baz 372 foo1 :- Howdy! -
-2 < :foo.bar.baz 372 foo1 :- Welcome! -
-2 < :foo.bar.baz 372 foo1 :- (to this server) -
-2 < :foo.bar.baz 376 foo1 :End of /MOTD command
+0:2 < :foo.bar.baz 375 foo1 :- foo.bar.baz Message of the Day -
+0:2 < :foo.bar.baz 372 foo1 :- Howdy! -
+0:2 < :foo.bar.baz 372 foo1 :- Welcome! -
+0:2 < :foo.bar.baz 372 foo1 :- (to this server) -
+0:2 < :foo.bar.baz 376 foo1 :End of /MOTD command
1,2 $ motd set to:
1,2 $ - Howdy! -
1,2 $ - Welcome! -
1,2 $ - (to this server) -
# collect user mode
-2 < :foo1 MODE foo1 :+Ziw
+0:2 < :foo1 MODE foo1 :+Ziw
1,2 $ users:me:modes set to: [+Ziw]
# handle bot query NOTICE
-2 < :SaslServ!SaslServ@services.bar.baz NOTICE foo1 :Last login from ~foobarbaz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
+0:2 < :SaslServ!SaslServ@services.bar.baz NOTICE foo1 :Last login from ~foobarbaz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
3 <<< [SaslServ] Last login from ~foobarbaz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
# check difference in available commands when switching to client window
# test recoverable 432
> /nick @foo
2 > NICK :@foo
-2 < :*.?.net 432 foo1 @foo :Erroneous nickname
+0:2 < :*.?.net 432 foo1 @foo :Erroneous nickname
1,2 !$ nickname refused for bad format
# join channel, collect topic, residents; update me:user from JOIN message
> /join #test
2 > JOIN :#test
-2 < :foo1!~foobarbaz@baz.bar.foo JOIN #test
+0:2 < :foo1!~foobarbaz@baz.bar.foo JOIN #test
1,2 $ users:me:user set to: [~foobarbaz]
-2 < :foo.bar.baz 332 foo1 #test :foo bar baz
+0:2 < :foo.bar.baz 332 foo1 #test :foo bar baz
1,2 $ channels:#test:exits cleared
-2 < :foo.bar.baz 333 foo1 #test bar!~bar@bar.bar 1234567890
+0:2 < :foo.bar.baz 333 foo1 #test bar!~bar@bar.bar 1234567890
1,2 $ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='bar.bar'))]
4 $ bar!~bar@bar.bar set topic: foo bar baz
-2 < :foo.bar.baz 353 foo1 @ #test :foo1 @bar
+0:2 < :foo.bar.baz 353 foo1 @ #test :foo1 @bar
1,2 $ users:1:nick set to: [?]
1,2 $ users:1:nick set to: [bar]
-2 < :foo.bar.baz 366 foo1 #test :End of /NAMES list.
+0:2 < :foo.bar.baz 366 foo1 #test :End of /NAMES list.
1,2 $ channels:#test:user_ids set to:
1,2 $ 1
1,2 $ me
4 $ residents: bar, foo1
# deliver PRIVMSG to channel window, update sender's user+host from metadata
-2 < :bar!~bar@bar.bar PRIVMSG #test :hi there
+0:2 < :bar!~bar@bar.bar PRIVMSG #test :hi there
1,2 $ users:1:user set to: [~bar]
1,2 $ users:1:host set to: [bar.bar]
4 < [bar] hi there
# check _changing_ TOPIC message is communicated to channel window
-2 < :bar!~bar@bar.bar TOPIC #test :foo bar baz
-2 < :bar!~bar@bar.bar TOPIC #test :abc def ghi
+0:2 < :bar!~bar@bar.bar TOPIC #test :foo bar baz
+0:2 < :bar!~bar@bar.bar TOPIC #test :abc def ghi
1,2 $ channels:#test:topic set to: [Topic(what='abc def ghi', who=NickUserHost(nick='bar', user='~bar', host='bar.bar'))]
4 $ bar!~bar@bar.bar set topic: abc def ghi
# process non-self channel JOIN
-2 < :baz!~baz@baz.baz JOIN :#test
+0:2 < :baz!~baz@baz.baz JOIN :#test
1,2 $ users:2:nick set to: [?]
1,2 $ users:2:nick set to: [baz]
1,2 $ users:2:user set to: [~baz]
# join second channel with partial residents identity to compare distribution of resident-specific messages
> /join #testtest
2 > JOIN :#testtest
-2 < :foo1!~foobarbaz@baz.bar.foo JOIN #testtest
-2 < :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
+0:2 < :foo1!~foobarbaz@baz.bar.foo JOIN #testtest
+0:2 < :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
1,2 $ channels:#testtest:exits cleared
-2 < :foo.bar.baz 366 foo1 #testtest :End of /NAMES list.
+0:2 < :foo.bar.baz 366 foo1 #testtest :End of /NAMES list.
1,2 $ channels:#testtest:user_ids set to:
1,2 $ 2
1,2 $ me
5 $ residents: baz, foo1
# handle query window with known user
-2 < :baz!~baz@baz.baz PRIVMSG foo1 :hi there
+0:2 < :baz!~baz@baz.baz PRIVMSG foo1 :hi there
6 < [baz] hi there
> /privmsg baz hello, how is it going
2 > PRIVMSG baz :hello, how is it going
6 > [foo1] hello, how is it going
-2 < :baz!~baz@baz.baz PRIVMSG foo1 :fine!
+0:2 < :baz!~baz@baz.baz PRIVMSG foo1 :fine!
6 < [baz] fine!
# handle non-self renaming
-2 < :baz!~baz@baz.baz NICK :bazbaz
+0:2 < :baz!~baz@baz.baz NICK :bazbaz
1,2 $ users:2:nick set to: [bazbaz]
4,5,6 $ baz!~baz@baz.baz renames bazbaz
# handle non-self PART in one of two inhabited channels, preserve identity into re-JOIN
-2 < :bazbaz!~baz@baz.baz PART :#test
+0:2 < :bazbaz!~baz@baz.baz PART :#test
1,2 $ channels:#test:exits:2 set to: [P]
1,2 $ channels:#test:user_ids set to:
1,2 $ 1
1,2 $ me
4 $ bazbaz!~baz@baz.baz parts
1,2 $ channels:#test:exits:2 cleared
-2 < :bazbaz!~baz@baz.baz JOIN :#test
+0:2 < :bazbaz!~baz@baz.baz JOIN :#test
1,2 $ channels:#test:user_ids set to:
1,2 $ 1
1,2 $ 2
4 $ bazbaz!~baz@baz.baz joins
# handle non-self PART in only inhabited channel, lose identity, re-join as new identity
-2 < :bar!~bar@bar.bar PART :#test
+0:2 < :bar!~bar@bar.bar PART :#test
1,2 $ channels:#test:exits:1 set to: [P]
1,2 $ channels:#test:user_ids set to:
1,2 $ 2
4 $ bar!~bar@bar.bar parts
1,2 $ channels:#test:exits:1 cleared
1,2 $ users:1 cleared
-2 < :bar!~bar@bar.bar JOIN :#test
+0:2 < :bar!~bar@bar.bar JOIN :#test
1,2 $ users:3:nick set to: [?]
1,2 $ users:3:nick set to: [bar]
1,2 $ users:3:user set to: [~bar]
4 $ bar!~bar@bar.bar joins
# handle non-self QUIT
-2 < :bazbaz!~baz@baz.baz QUIT :Client Quit
+0:2 < :bazbaz!~baz@baz.baz QUIT :Client Quit
1,2 $ users:2:exit_msg set to: [QClient Quit]
6 $ bazbaz!~baz@baz.baz quits: Client Quit
1,2 $ channels:#test:exits:2 set to: [QClient Quit]
1,2 $ users:2 cleared
# handle self-PART: clear channel, and its squatters
-2 < :foo1!~foobarbaz@baz.bar.foo PART :#test
+0:2 < :foo1!~foobarbaz@baz.bar.foo PART :#test
1,2 $ channels:#test:exits:me set to: [P]
1,2 $ channels:#test:user_ids set to:
1,2 $ 3
> /disconnect
1,2 $ requesting disconnect …
2 > QUIT :ircplom says bye
-2 < :foo1!~foobarbaz@baz.bar.foo QUIT :Client Quit
+0:2 < :foo1!~foobarbaz@baz.bar.foo QUIT :Client Quit
1,2 $ users:me:exit_msg set to: [QClient Quit]
3,6 $ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
1,2 $ channels:#testtest:exits:me set to: [QClient Quit]
1,2 $ channels:#testtest:user_ids set to:
5 $ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
1,2 $ channels:#testtest:exits:me cleared
-2 < ERROR :Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]
+0:2 < ERROR :Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]
1,2 $ connection_state set to: [Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]]
1,2 $ connection_state set to: []
3,4,5,6 $ DISCONNECTED
repeat 66:158
repeat 167:357
+# test setting up second client, but 432 irrecoverably
+> /connect baz.bar.foo ?foo foo:foo
+7,8 $ isupport cleared
+7,8 $ isupport:CHANTYPES set to: [#&]
+7,8 $ isupport:PREFIX set to: [(ov)@+]
+7,8 $ isupport:USERLEN set to: [10]
+7,8 $ hostname set to: [baz.bar.foo]
+7,8 $ port set to: [-1]
+7,8 $ nick_wanted set to: [?foo]
+7,8 $ user_wanted set to: [foo]
+7,8 $ realname set to: [foo]
+7,8 $ port set to: [6697]
+7,8 $ connection_state set to: [connecting]
+7,8 $ connection_state set to: [connected]
+, $ CONNECTED
+1:8 > CAP LS :302
+1:8 > USER foo 0 * :foo
+1:8 > NICK :?foo
+1:8 < :*.?.net 432 * ?foo :Erroneous nickname
+7,8 $ connection_state set to: []
+, $ DISCONNECTED
+7,8 $ isupport cleared
+7,8 $ isupport:CHANTYPES set to: [#&]
+7,8 $ isupport:PREFIX set to: [(ov)@+]
+7,8 $ isupport:USERLEN set to: [10]
+7,8 !$ nickname refused for bad format, giving up
+
> /quit
0 <