home · contact · privacy
Rename test file forgotten to change extension on in previous commit.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 2 Oct 2025 20:49:52 +0000 (22:49 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 2 Oct 2025 20:49:52 +0000 (22:49 +0200)
src/tests/test.test [new file with mode: 0644]
src/tests/test.txt [deleted file]

diff --git a/src/tests/test.test b/src/tests/test.test
new file mode 100644 (file)
index 0000000..72a007b
--- /dev/null
@@ -0,0 +1,409 @@
+# CONNECTED INTERACTIONS
+
+# on /connect init databases, log in new windows
+> /connect foo.bar.baz foo:bar baz:foobarbazquux
+| standard-clears-in
+| isupport-clear-in
+1 .$ isupport cleared
+1 .$ isupport:CHANTYPES set to: [#&]
+1 .$ isupport:PREFIX set to: [(ov)@+]
+1 .$ isupport:USERLEN set to: [10]
+| isupport-clear-out
+1 .$ caps cleared
+1 .$ users cleared
+1 .$ channels cleared
+| standard-clears-out
+, .$ DISCONNECTED
+
+# connect with values set by /connect, init CAP negotation
+1 .$ hostname set to: [foo.bar.baz]
+1 .$ port set to: [-1]
+1 .$ nick_wanted set to: [foo]
+1 .$ user_wanted set to: [foobarbazquux]
+1 .$ realname set to: [baz]
+1 .$ password set to: [bar]
+1 .$ port set to: [6697]
+| conn0
+1 .$ connection_state set to: [connecting]
+1 .$ connection_state set to: [connected]
+| conn1
+, .$ CONNECTED
+| conn2
+1 .> CAP LS :302
+1 .> USER foobarbazquux 0 * :baz
+1 .> NICK :foo
+
+# expect some NOTICE and PING to process/reply during initiation
+:0:1 .< :*.?.net NOTICE * :*** Looking up your ident...
+2 .< *** [ server] *** Looking up your ident...
+:0:1 .< :*.?.net NOTICE * :*** Looking up your hostname...
+2 .< *** [ server] *** Looking up your hostname...
+:0:1 .< :*.?.net NOTICE * :*** Found your hostname (foo.bar.baz)
+2 .< *** [ server] *** Found your hostname (foo.bar.baz)
+:0:1 .< PING :?
+1 .> PONG :?
+
+# handle 433
+:0:1 .< :*.?.net 433 * foo :Nickname already in use
+1 .!$ nickname already in use, trying increment
+1 .> NICK :foo0
+:0:1 .< :*.?.net 433 * foo0 :Nickname already in use
+1 .!$ nickname already in use, trying increment
+1 .> NICK :foo1
+
+# collect server capabilities
+:0:1 .< :*.?.net CAP * LS : foo bar sasl=PLAIN,EXTERNAL baz cap-notify
+1 .> CAP REQ :sasl
+1 .> CAP :LIST
+:0:1 .< :*.?.net CAP * ACK :sasl
+:0:1 .< :*.?.net CAP * LIST :cap-notify sasl
+1 .$ caps:bar:data set to: []
+1 .$ caps:baz:data set to: []
+1 .$ caps:cap-notify:data set to: []
+1 .$ caps:cap-notify:enabled set to: [True]
+1 .$ caps:foo:data set to: []
+1 .$ caps:sasl:data set to: []
+1 .$ caps:sasl:data set to: [PLAIN,EXTERNAL]
+1 .$ caps:sasl:enabled set to: [True]
+
+# authenticate via SASL, collect items of user identity
+1 .$ sasl_auth_state set to: [attempting]
+1 .> AUTHENTICATE :PLAIN
+:0:1 .< AUTHENTICATE +
+1 .> AUTHENTICATE :Zm9vAGZvbwBiYXI=
+:0:1 .< :foo.bar.baz 900 foo1 foo1!foobarbazq@baz.bar.foo foo :You are now logged in as foo
+1 .$ users:me:nick set to: [?]
+1 .$ users:me:nick set to: [foo1]
+1 .$ users:me:user set to: [foobarbazq]
+1 .$ users:me:host set to: [baz.bar.foo]
+1 .$ sasl_account set to: [foo]
+:0:1 .< :foo.bar.baz 903 foo1 :SASL authentication successful
+1 .$ sasl_auth_state set to: [SASL authentication successful]
+
+# finish CAP negotation, thus login procedure
+1 .> CAP :END
+
+# of all pre-MOTD greeting messages, only process isupports
+:0:1 .< :foo.bar.baz 001 foo1 :Welcome to the foo.bar.baz network
+| conn3
+:0:1 .< :foo.bar.baz 002 foo1 :Your host is foo.bar.baz
+:0:1 .< :foo.bar.baz 003 foo1 :This server was created Jan 1 2020
+:0:1 .< :foo.bar.baz 004 foo1 foo.bar.baz ircserver-1.0 abc def ghi
+:0:1 .< :foo.bar.baz 005 foo1 ABC=DEF GHI=JKL :are supported by this server
+1 .$ isupport:ABC set to: [DEF]
+1 .$ isupport:GHI set to: [JKL]
+:0:1 .< :foo.bar.baz 005 foo1 MNO=PQR STU=VWX Y=Z :are supported by this server
+1 .$ isupport:MNO set to: [PQR]
+1 .$ isupport:STU set to: [VWX]
+1 .$ isupport:Y set to: [Z]
+:0:1 .< :foo.bar.baz 251 foo1 :There are 10 users and 1000 invisible on 5 servers
+:0:1 .< :foo.bar.baz 252 foo1 7 :IRC Operators online
+:0:1 .< :foo.bar.baz 253 foo1 4 :unknown connection(s)
+:0:1 .< :foo.bar.baz 254 foo1 800 :channels formed
+:0:1 .< :foo.bar.baz 255 foo1 :I have 100 clients and 1 serveres
+:0:1 .< :foo.bar.baz 265 foo1 100 150 :Current local users 100, max 150
+:0:1 .< :foo.bar.baz 266 foo1 1010 1050 :Current global users 1010, max 1050
+:0:1 .< :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)
+:0:1 .< :foo.bar.baz 375 foo1 :- foo.bar.baz Message of the Day -
+:0:1 .< :foo.bar.baz 372 foo1 :- Howdy! -
+:0:1 .< :foo.bar.baz 372 foo1 :- Welcome! -
+:0:1 .< :foo.bar.baz 372 foo1 :- (to this server) -
+:0:1 .< :foo.bar.baz 376 foo1 :End of /MOTD command
+1 .$ motd set to:
+1 .$   - Howdy! -
+1 .$   - Welcome! -
+1 .$   - (to this server) -
+
+# collect user mode
+:0:1 .< :foo1 MODE foo1 :+Ziw
+1 .$ users:me:modes set to: [+Ziw]
+
+# handle bot query NOTICE
+:0:1 .< :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.
+| conn4
+
+# check difference in available commands when switching to client window
+> /join #test
+0 .!# invalid prompt command: /join unknown
+> /list
+0 .# windows available via /window:
+0 .#   0) :start
+0 .#   1) foo.bar.baz :DEBUG
+0 .#   2) foo.bar.baz  server
+0 .#   3) foo.bar.baz SaslServ
+| conn5
+> /window 1
+> /help
+1 .# commands available in this window:
+1 .#   /connect HOST_PORT [NICKNAME_PW] [REALNAME_USERNAME]
+1 .#   /disconnect [QUIT_MSG]
+1 .#   /help
+1 .#   /join CHANNEL
+1 .#   /list
+1 .#   /nick NEW_NICK
+1 .#   /privmsg TARGET MSG
+1 .#   /prompt_enter
+1 .#   /quit
+1 .#   /raw VERB [PARAMS_STR]
+1 .#   /reconnect
+1 .#   /window TOWARDS
+1 .#   /window.disconnect [QUIT_MSG]
+1 .#   /window.history.scroll DIRECTION
+1 .#   /window.join CHANNEL
+1 .#   /window.nick NEW_NICK
+1 .#   /window.paste
+1 .#   /window.privmsg TARGET MSG
+1 .#   /window.prompt.backspace
+1 .#   /window.prompt.move_cursor DIRECTION
+1 .#   /window.prompt.scroll DIRECTION
+1 .#   /window.raw VERB [PARAMS_STR]
+1 .#   /window.reconnect
+
+# test lack of implementation
+:0:1 .< foo bar baz
+1 .!$ No handler implemented for: foo bar baz
+
+# test recoverable 432
+> /nick @foo
+1 .> NICK :@foo
+:0:1 .< :*.?.net 432 foo1 @foo :Erroneous nickname
+1 .!$ nickname refused for bad format, keeping current one
+
+# join channel, collect topic, residents; update me:user from JOIN message; ensure topic.who not affecting users DB
+> /join #test
+1 .> JOIN :#test
+:0:1 .< :foo1!~foobarbaz@baz.bar.foo JOIN #test
+1 .$ users:me:user set to: [~foobarbaz]
+:0:1 .< :foo.bar.baz 332 foo1 #test :foo bar baz
+1 .$ channels:#test:exits cleared
+:0:1 .< :foo.bar.baz 333 foo1 #test bar!~bar@OLD.bar.bar 1234567890
+1 .$ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
+4 .$ bar!~bar@OLD.bar.bar set topic: foo bar baz
+:0:1 .< :foo.bar.baz 353 foo1 @ #test :foo1 @bar
+1 .$ users:1:nick set to: [?]
+1 .$ users:1:nick set to: [bar]
+:0:1 .< :foo.bar.baz 366 foo1 #test :End of /NAMES list.
+1 .$ channels:#test:user_ids set to:
+1 .$   1
+1 .$   me
+4 .$ residents: bar, foo1
+
+# deliver PRIVMSG to channel window, update sender's user+host from metadata
+:0:1 .< :bar!~bar@bar.bar PRIVMSG #test :hi there
+1 .$ users:1:user set to: [~bar]
+1 .$ users:1:host set to: [bar.bar]
+4 .< [bar] hi there
+
+# check _changing_ TOPIC message is communicated to channel window, as long as either content or who change
+:0:1 .< :bar!~bar@bar.bar TOPIC #test :foo bar baz
+1 .$ 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
+:0:1 .< :bar!~bar@bar.bar TOPIC #test :foo bar baz
+:0:1 .< :bar!~bar@bar.bar TOPIC #test :abc def ghi
+1 .$ 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
+:0:1 .< :baz!~baz@baz.baz JOIN :#test
+1 .$ users:2:nick set to: [?]
+1 .$ users:2:nick set to: [baz]
+1 .$ users:2:user set to: [~baz]
+1 .$ users:2:host set to: [baz.baz]
+1 .$ channels:#test:user_ids set to:
+1 .$   1
+1 .$   2
+1 .$   me
+4 .$ baz!~baz@baz.baz joins
+
+# join second channel with partial residents identity to compare distribution of resident-specific messages
+> /join #testtest
+1 .> JOIN :#testtest
+:0:1 .< :foo1!~foobarbaz@baz.bar.foo JOIN #testtest
+:0:1 .< :foo.bar.baz 332 foo1 #testtest :baz bar foo
+1 .$ channels:#testtest:exits cleared
+:0:1 .< :foo.bar.baz 333 foo1 #testtest bar!~bar@OLD.bar.bar 1234567890
+1 .$ channels:#testtest:topic set to: [Topic(what='baz bar foo', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
+5 .$ bar!~bar@OLD.bar.bar set topic: baz bar foo
+:0:1 .< :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
+:0:1 .< :foo.bar.baz 366 foo1 #testtest :End of /NAMES list.
+1 .$ channels:#testtest:user_ids set to:
+1 .$   2
+1 .$   me
+5 .$ residents: baz, foo1
+
+# handle query window with known user
+:0:1 .< :baz!~baz@baz.baz PRIVMSG foo1 :hi there
+6 .< [baz] hi there
+> /privmsg baz hello, how is it going
+1 .> PRIVMSG baz :hello, how is it going
+6 .> [foo1] hello, how is it going
+:0:1 .< :baz!~baz@baz.baz PRIVMSG foo1 :fine!
+6 .< [baz] fine!
+
+# handle failure to query absent user
+> /privmsg barbar hello!
+1 .> PRIVMSG barbar :hello!
+7 .> [foo1] hello!
+:0:1 .< :*.?.net 401 foo1 barbar :No such nick/channel
+7 .!$ barbar not online
+
+# handle non-self renaming
+:0:1 .< :baz!~baz@baz.baz NICK :bazbaz
+1 .$ 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
+:0:1 .< :bazbaz!~baz@baz.baz PART :#test
+1 .$ channels:#test:exits:2 set to: [P]
+1 .$ channels:#test:user_ids set to:
+1 .$   1
+1 .$   me
+4 .$ bazbaz!~baz@baz.baz parts
+1 .$ channels:#test:exits:2 cleared
+:0:1 .< :bazbaz!~baz@baz.baz JOIN :#test
+1 .$ channels:#test:user_ids set to:
+1 .$   1
+1 .$   2
+1 .$   me
+4 .$ bazbaz!~baz@baz.baz joins
+
+# handle non-self PART in only inhabited channel, lose identity, re-join as new identity
+:0:1 .< :bar!~bar@bar.bar PART :#test
+1 .$ channels:#test:exits:1 set to: [P]
+1 .$ channels:#test:user_ids set to:
+1 .$   2
+1 .$   me
+4 .$ bar!~bar@bar.bar parts
+1 .$ channels:#test:exits:1 cleared
+1 .$ users:1 cleared
+:0:1 .< :bar!~bar@bar.bar JOIN :#test
+1 .$ users:3:nick set to: [?]
+1 .$ users:3:nick set to: [bar]
+1 .$ users:3:user set to: [~bar]
+1 .$ users:3:host set to: [bar.bar]
+1 .$ channels:#test:user_ids set to:
+1 .$   2
+1 .$   3
+1 .$   me
+4 .$ bar!~bar@bar.bar joins
+
+# handle non-self QUIT
+:0:1 .< :bazbaz!~baz@baz.baz QUIT :Client Quit
+1 .$ users:2:exit_msg set to: [QClient Quit]
+6 .$ bazbaz!~baz@baz.baz quits: Client Quit
+1 .$ channels:#test:exits:2 set to: [QClient Quit]
+1 .$ channels:#test:user_ids set to:
+1 .$   3
+1 .$   me
+4 .$ bazbaz!~baz@baz.baz quits: Client Quit
+1 .$ channels:#test:exits:2 cleared
+1 .$ channels:#testtest:exits:2 set to: [QClient Quit]
+1 .$ channels:#testtest:user_ids set to:
+1 .$   me
+5 .$ bazbaz!~baz@baz.baz quits: Client Quit
+1 .$ channels:#testtest:exits:2 cleared
+1 .$ users:2 cleared
+
+# handle self-PART: clear channel, and its squatters
+:0:1 .< :foo1!~foobarbaz@baz.bar.foo PART :#test
+1 .$ channels:#test:exits:me set to: [P]
+1 .$ channels:#test:user_ids set to:
+1 .$   3
+4 .$ foo1!~foobarbaz@baz.bar.foo parts
+1 .$ channels:#test:exits:me cleared
+1 .$ channels:#test cleared
+1 .$ users:3 cleared
+
+# fail to reconnect while connected
+> /reconnect
+1 .!$ not re-connecting since already connected
+
+# handle /disconnect, clear all
+> /disconnect
+1 .> QUIT :ircplom says bye
+:0:1 .< :foo1!~foobarbaz@baz.bar.foo QUIT :Client Quit
+1 .$ users:me:exit_msg set to: [QClient Quit]
+2,3,6,7 .$ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
+1 .$ channels:#testtest:exits:me set to: [QClient Quit]
+1 .$ channels:#testtest:user_ids set to:
+5 .$ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
+1 .$ channels:#testtest:exits:me cleared
+:0:1 .< ERROR :Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]
+1 .$ connection_state set to: [Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]]
+repeat isupport-clear-in isupport-clear-out
+1 .$ caps cleared
+1 .$ channels cleared
+1 .$ connection_state set to: []
+2,3,4,5,6,7 .$ DISCONNECTED
+1 .$ motd set to:
+1 .$ sasl_account set to: []
+1 .$ sasl_auth_state set to: []
+
+# fail to send in disconnect, check alert window is command prompt window
+> /window 6
+> /privmsg barbar test
+1 .$ users cleared
+6 .!$ cannot send, connection seems closed
+> /window 1
+> /privmsg barbar test
+1 .!$ cannot send, connection seems closed
+> /privmsg #test test
+1 .!$ not sending, since not in channel
+| conn6
+
+# test setting up second client, but 432 irrecoverably
+> /connect baz.bar.foo ?foo foo:foo
+repeat standard-clears-in standard-clears-out 8
+, .$ DISCONNECTED
+8 .$ hostname set to: [baz.bar.foo]
+8 .$ port set to: [-1]
+8 .$ nick_wanted set to: [?foo]
+8 .$ user_wanted set to: [foo]
+8 .$ realname set to: [foo]
+8 .$ port set to: [6697]
+repeat conn0 conn1 8
+, .$ CONNECTED
+1:8 .> CAP LS :302
+1:8 .> USER foo 0 * :foo
+1:8 .> NICK :?foo
+:1:8 .< :*.?.net 432 * ?foo :Erroneous nickname
+repeat isupport-clear-in isupport-clear-out 8
+8 .$ connection_state set to: []
+, .$ DISCONNECTED
+8 .!$ nickname refused for bad format, giving up
+
+# test failing third connection
+> /connect baz.baz.baz baz baz:baz
+repeat standard-clears-in standard-clears-out 9
+, .$ DISCONNECTED
+9 .$ hostname set to: [baz.baz.baz]
+9 .$ port set to: [-1]
+9 .$ nick_wanted set to: [baz]
+9 .$ user_wanted set to: [baz]
+9 .$ realname set to: [baz]
+9 .$ port set to: [6697]
+repeat conn0 conn1 9
+, .$ CONNECTED
+2:9 .> CAP LS :302
+2:9 .> USER baz 0 * :baz
+2:9 .> NICK :baz
+<2 FAKE_IRC_CONN_ABORT_EXCEPTION
+9 .$ connection_state set to: [broken: FAKE_IRC_CONN_ABORT_EXCEPTION]
+repeat isupport-clear-in isupport-clear-out 9
+9 .$ connection_state set to: []
+, .$ DISCONNECTED
+
+# check that (save TUI tests assuming start on window 0, and no 4 yet) on reconnect, all the same effects can be expected
+> /reconnect
+repeat conn0 conn1
+2,3,4,5,6,7 .$ CONNECTED
+repeat conn2 conn3
+1 .> JOIN :#testtest
+repeat conn3 conn4
+repeat conn5 conn6
+
+> /quit
+0 .< 
diff --git a/src/tests/test.txt b/src/tests/test.txt
deleted file mode 100644 (file)
index 72a007b..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-# CONNECTED INTERACTIONS
-
-# on /connect init databases, log in new windows
-> /connect foo.bar.baz foo:bar baz:foobarbazquux
-| standard-clears-in
-| isupport-clear-in
-1 .$ isupport cleared
-1 .$ isupport:CHANTYPES set to: [#&]
-1 .$ isupport:PREFIX set to: [(ov)@+]
-1 .$ isupport:USERLEN set to: [10]
-| isupport-clear-out
-1 .$ caps cleared
-1 .$ users cleared
-1 .$ channels cleared
-| standard-clears-out
-, .$ DISCONNECTED
-
-# connect with values set by /connect, init CAP negotation
-1 .$ hostname set to: [foo.bar.baz]
-1 .$ port set to: [-1]
-1 .$ nick_wanted set to: [foo]
-1 .$ user_wanted set to: [foobarbazquux]
-1 .$ realname set to: [baz]
-1 .$ password set to: [bar]
-1 .$ port set to: [6697]
-| conn0
-1 .$ connection_state set to: [connecting]
-1 .$ connection_state set to: [connected]
-| conn1
-, .$ CONNECTED
-| conn2
-1 .> CAP LS :302
-1 .> USER foobarbazquux 0 * :baz
-1 .> NICK :foo
-
-# expect some NOTICE and PING to process/reply during initiation
-:0:1 .< :*.?.net NOTICE * :*** Looking up your ident...
-2 .< *** [ server] *** Looking up your ident...
-:0:1 .< :*.?.net NOTICE * :*** Looking up your hostname...
-2 .< *** [ server] *** Looking up your hostname...
-:0:1 .< :*.?.net NOTICE * :*** Found your hostname (foo.bar.baz)
-2 .< *** [ server] *** Found your hostname (foo.bar.baz)
-:0:1 .< PING :?
-1 .> PONG :?
-
-# handle 433
-:0:1 .< :*.?.net 433 * foo :Nickname already in use
-1 .!$ nickname already in use, trying increment
-1 .> NICK :foo0
-:0:1 .< :*.?.net 433 * foo0 :Nickname already in use
-1 .!$ nickname already in use, trying increment
-1 .> NICK :foo1
-
-# collect server capabilities
-:0:1 .< :*.?.net CAP * LS : foo bar sasl=PLAIN,EXTERNAL baz cap-notify
-1 .> CAP REQ :sasl
-1 .> CAP :LIST
-:0:1 .< :*.?.net CAP * ACK :sasl
-:0:1 .< :*.?.net CAP * LIST :cap-notify sasl
-1 .$ caps:bar:data set to: []
-1 .$ caps:baz:data set to: []
-1 .$ caps:cap-notify:data set to: []
-1 .$ caps:cap-notify:enabled set to: [True]
-1 .$ caps:foo:data set to: []
-1 .$ caps:sasl:data set to: []
-1 .$ caps:sasl:data set to: [PLAIN,EXTERNAL]
-1 .$ caps:sasl:enabled set to: [True]
-
-# authenticate via SASL, collect items of user identity
-1 .$ sasl_auth_state set to: [attempting]
-1 .> AUTHENTICATE :PLAIN
-:0:1 .< AUTHENTICATE +
-1 .> AUTHENTICATE :Zm9vAGZvbwBiYXI=
-:0:1 .< :foo.bar.baz 900 foo1 foo1!foobarbazq@baz.bar.foo foo :You are now logged in as foo
-1 .$ users:me:nick set to: [?]
-1 .$ users:me:nick set to: [foo1]
-1 .$ users:me:user set to: [foobarbazq]
-1 .$ users:me:host set to: [baz.bar.foo]
-1 .$ sasl_account set to: [foo]
-:0:1 .< :foo.bar.baz 903 foo1 :SASL authentication successful
-1 .$ sasl_auth_state set to: [SASL authentication successful]
-
-# finish CAP negotation, thus login procedure
-1 .> CAP :END
-
-# of all pre-MOTD greeting messages, only process isupports
-:0:1 .< :foo.bar.baz 001 foo1 :Welcome to the foo.bar.baz network
-| conn3
-:0:1 .< :foo.bar.baz 002 foo1 :Your host is foo.bar.baz
-:0:1 .< :foo.bar.baz 003 foo1 :This server was created Jan 1 2020
-:0:1 .< :foo.bar.baz 004 foo1 foo.bar.baz ircserver-1.0 abc def ghi
-:0:1 .< :foo.bar.baz 005 foo1 ABC=DEF GHI=JKL :are supported by this server
-1 .$ isupport:ABC set to: [DEF]
-1 .$ isupport:GHI set to: [JKL]
-:0:1 .< :foo.bar.baz 005 foo1 MNO=PQR STU=VWX Y=Z :are supported by this server
-1 .$ isupport:MNO set to: [PQR]
-1 .$ isupport:STU set to: [VWX]
-1 .$ isupport:Y set to: [Z]
-:0:1 .< :foo.bar.baz 251 foo1 :There are 10 users and 1000 invisible on 5 servers
-:0:1 .< :foo.bar.baz 252 foo1 7 :IRC Operators online
-:0:1 .< :foo.bar.baz 253 foo1 4 :unknown connection(s)
-:0:1 .< :foo.bar.baz 254 foo1 800 :channels formed
-:0:1 .< :foo.bar.baz 255 foo1 :I have 100 clients and 1 serveres
-:0:1 .< :foo.bar.baz 265 foo1 100 150 :Current local users 100, max 150
-:0:1 .< :foo.bar.baz 266 foo1 1010 1050 :Current global users 1010, max 1050
-:0:1 .< :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)
-:0:1 .< :foo.bar.baz 375 foo1 :- foo.bar.baz Message of the Day -
-:0:1 .< :foo.bar.baz 372 foo1 :- Howdy! -
-:0:1 .< :foo.bar.baz 372 foo1 :- Welcome! -
-:0:1 .< :foo.bar.baz 372 foo1 :- (to this server) -
-:0:1 .< :foo.bar.baz 376 foo1 :End of /MOTD command
-1 .$ motd set to:
-1 .$   - Howdy! -
-1 .$   - Welcome! -
-1 .$   - (to this server) -
-
-# collect user mode
-:0:1 .< :foo1 MODE foo1 :+Ziw
-1 .$ users:me:modes set to: [+Ziw]
-
-# handle bot query NOTICE
-:0:1 .< :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.
-| conn4
-
-# check difference in available commands when switching to client window
-> /join #test
-0 .!# invalid prompt command: /join unknown
-> /list
-0 .# windows available via /window:
-0 .#   0) :start
-0 .#   1) foo.bar.baz :DEBUG
-0 .#   2) foo.bar.baz  server
-0 .#   3) foo.bar.baz SaslServ
-| conn5
-> /window 1
-> /help
-1 .# commands available in this window:
-1 .#   /connect HOST_PORT [NICKNAME_PW] [REALNAME_USERNAME]
-1 .#   /disconnect [QUIT_MSG]
-1 .#   /help
-1 .#   /join CHANNEL
-1 .#   /list
-1 .#   /nick NEW_NICK
-1 .#   /privmsg TARGET MSG
-1 .#   /prompt_enter
-1 .#   /quit
-1 .#   /raw VERB [PARAMS_STR]
-1 .#   /reconnect
-1 .#   /window TOWARDS
-1 .#   /window.disconnect [QUIT_MSG]
-1 .#   /window.history.scroll DIRECTION
-1 .#   /window.join CHANNEL
-1 .#   /window.nick NEW_NICK
-1 .#   /window.paste
-1 .#   /window.privmsg TARGET MSG
-1 .#   /window.prompt.backspace
-1 .#   /window.prompt.move_cursor DIRECTION
-1 .#   /window.prompt.scroll DIRECTION
-1 .#   /window.raw VERB [PARAMS_STR]
-1 .#   /window.reconnect
-
-# test lack of implementation
-:0:1 .< foo bar baz
-1 .!$ No handler implemented for: foo bar baz
-
-# test recoverable 432
-> /nick @foo
-1 .> NICK :@foo
-:0:1 .< :*.?.net 432 foo1 @foo :Erroneous nickname
-1 .!$ nickname refused for bad format, keeping current one
-
-# join channel, collect topic, residents; update me:user from JOIN message; ensure topic.who not affecting users DB
-> /join #test
-1 .> JOIN :#test
-:0:1 .< :foo1!~foobarbaz@baz.bar.foo JOIN #test
-1 .$ users:me:user set to: [~foobarbaz]
-:0:1 .< :foo.bar.baz 332 foo1 #test :foo bar baz
-1 .$ channels:#test:exits cleared
-:0:1 .< :foo.bar.baz 333 foo1 #test bar!~bar@OLD.bar.bar 1234567890
-1 .$ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
-4 .$ bar!~bar@OLD.bar.bar set topic: foo bar baz
-:0:1 .< :foo.bar.baz 353 foo1 @ #test :foo1 @bar
-1 .$ users:1:nick set to: [?]
-1 .$ users:1:nick set to: [bar]
-:0:1 .< :foo.bar.baz 366 foo1 #test :End of /NAMES list.
-1 .$ channels:#test:user_ids set to:
-1 .$   1
-1 .$   me
-4 .$ residents: bar, foo1
-
-# deliver PRIVMSG to channel window, update sender's user+host from metadata
-:0:1 .< :bar!~bar@bar.bar PRIVMSG #test :hi there
-1 .$ users:1:user set to: [~bar]
-1 .$ users:1:host set to: [bar.bar]
-4 .< [bar] hi there
-
-# check _changing_ TOPIC message is communicated to channel window, as long as either content or who change
-:0:1 .< :bar!~bar@bar.bar TOPIC #test :foo bar baz
-1 .$ 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
-:0:1 .< :bar!~bar@bar.bar TOPIC #test :foo bar baz
-:0:1 .< :bar!~bar@bar.bar TOPIC #test :abc def ghi
-1 .$ 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
-:0:1 .< :baz!~baz@baz.baz JOIN :#test
-1 .$ users:2:nick set to: [?]
-1 .$ users:2:nick set to: [baz]
-1 .$ users:2:user set to: [~baz]
-1 .$ users:2:host set to: [baz.baz]
-1 .$ channels:#test:user_ids set to:
-1 .$   1
-1 .$   2
-1 .$   me
-4 .$ baz!~baz@baz.baz joins
-
-# join second channel with partial residents identity to compare distribution of resident-specific messages
-> /join #testtest
-1 .> JOIN :#testtest
-:0:1 .< :foo1!~foobarbaz@baz.bar.foo JOIN #testtest
-:0:1 .< :foo.bar.baz 332 foo1 #testtest :baz bar foo
-1 .$ channels:#testtest:exits cleared
-:0:1 .< :foo.bar.baz 333 foo1 #testtest bar!~bar@OLD.bar.bar 1234567890
-1 .$ channels:#testtest:topic set to: [Topic(what='baz bar foo', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
-5 .$ bar!~bar@OLD.bar.bar set topic: baz bar foo
-:0:1 .< :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
-:0:1 .< :foo.bar.baz 366 foo1 #testtest :End of /NAMES list.
-1 .$ channels:#testtest:user_ids set to:
-1 .$   2
-1 .$   me
-5 .$ residents: baz, foo1
-
-# handle query window with known user
-:0:1 .< :baz!~baz@baz.baz PRIVMSG foo1 :hi there
-6 .< [baz] hi there
-> /privmsg baz hello, how is it going
-1 .> PRIVMSG baz :hello, how is it going
-6 .> [foo1] hello, how is it going
-:0:1 .< :baz!~baz@baz.baz PRIVMSG foo1 :fine!
-6 .< [baz] fine!
-
-# handle failure to query absent user
-> /privmsg barbar hello!
-1 .> PRIVMSG barbar :hello!
-7 .> [foo1] hello!
-:0:1 .< :*.?.net 401 foo1 barbar :No such nick/channel
-7 .!$ barbar not online
-
-# handle non-self renaming
-:0:1 .< :baz!~baz@baz.baz NICK :bazbaz
-1 .$ 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
-:0:1 .< :bazbaz!~baz@baz.baz PART :#test
-1 .$ channels:#test:exits:2 set to: [P]
-1 .$ channels:#test:user_ids set to:
-1 .$   1
-1 .$   me
-4 .$ bazbaz!~baz@baz.baz parts
-1 .$ channels:#test:exits:2 cleared
-:0:1 .< :bazbaz!~baz@baz.baz JOIN :#test
-1 .$ channels:#test:user_ids set to:
-1 .$   1
-1 .$   2
-1 .$   me
-4 .$ bazbaz!~baz@baz.baz joins
-
-# handle non-self PART in only inhabited channel, lose identity, re-join as new identity
-:0:1 .< :bar!~bar@bar.bar PART :#test
-1 .$ channels:#test:exits:1 set to: [P]
-1 .$ channels:#test:user_ids set to:
-1 .$   2
-1 .$   me
-4 .$ bar!~bar@bar.bar parts
-1 .$ channels:#test:exits:1 cleared
-1 .$ users:1 cleared
-:0:1 .< :bar!~bar@bar.bar JOIN :#test
-1 .$ users:3:nick set to: [?]
-1 .$ users:3:nick set to: [bar]
-1 .$ users:3:user set to: [~bar]
-1 .$ users:3:host set to: [bar.bar]
-1 .$ channels:#test:user_ids set to:
-1 .$   2
-1 .$   3
-1 .$   me
-4 .$ bar!~bar@bar.bar joins
-
-# handle non-self QUIT
-:0:1 .< :bazbaz!~baz@baz.baz QUIT :Client Quit
-1 .$ users:2:exit_msg set to: [QClient Quit]
-6 .$ bazbaz!~baz@baz.baz quits: Client Quit
-1 .$ channels:#test:exits:2 set to: [QClient Quit]
-1 .$ channels:#test:user_ids set to:
-1 .$   3
-1 .$   me
-4 .$ bazbaz!~baz@baz.baz quits: Client Quit
-1 .$ channels:#test:exits:2 cleared
-1 .$ channels:#testtest:exits:2 set to: [QClient Quit]
-1 .$ channels:#testtest:user_ids set to:
-1 .$   me
-5 .$ bazbaz!~baz@baz.baz quits: Client Quit
-1 .$ channels:#testtest:exits:2 cleared
-1 .$ users:2 cleared
-
-# handle self-PART: clear channel, and its squatters
-:0:1 .< :foo1!~foobarbaz@baz.bar.foo PART :#test
-1 .$ channels:#test:exits:me set to: [P]
-1 .$ channels:#test:user_ids set to:
-1 .$   3
-4 .$ foo1!~foobarbaz@baz.bar.foo parts
-1 .$ channels:#test:exits:me cleared
-1 .$ channels:#test cleared
-1 .$ users:3 cleared
-
-# fail to reconnect while connected
-> /reconnect
-1 .!$ not re-connecting since already connected
-
-# handle /disconnect, clear all
-> /disconnect
-1 .> QUIT :ircplom says bye
-:0:1 .< :foo1!~foobarbaz@baz.bar.foo QUIT :Client Quit
-1 .$ users:me:exit_msg set to: [QClient Quit]
-2,3,6,7 .$ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
-1 .$ channels:#testtest:exits:me set to: [QClient Quit]
-1 .$ channels:#testtest:user_ids set to:
-5 .$ foo1!~foobarbaz@baz.bar.foo quits: Client Quit
-1 .$ channels:#testtest:exits:me cleared
-:0:1 .< ERROR :Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]
-1 .$ connection_state set to: [Closing link: (~foobarbaz@baz.bar.foo) [Quit: ircplom says bye]]
-repeat isupport-clear-in isupport-clear-out
-1 .$ caps cleared
-1 .$ channels cleared
-1 .$ connection_state set to: []
-2,3,4,5,6,7 .$ DISCONNECTED
-1 .$ motd set to:
-1 .$ sasl_account set to: []
-1 .$ sasl_auth_state set to: []
-
-# fail to send in disconnect, check alert window is command prompt window
-> /window 6
-> /privmsg barbar test
-1 .$ users cleared
-6 .!$ cannot send, connection seems closed
-> /window 1
-> /privmsg barbar test
-1 .!$ cannot send, connection seems closed
-> /privmsg #test test
-1 .!$ not sending, since not in channel
-| conn6
-
-# test setting up second client, but 432 irrecoverably
-> /connect baz.bar.foo ?foo foo:foo
-repeat standard-clears-in standard-clears-out 8
-, .$ DISCONNECTED
-8 .$ hostname set to: [baz.bar.foo]
-8 .$ port set to: [-1]
-8 .$ nick_wanted set to: [?foo]
-8 .$ user_wanted set to: [foo]
-8 .$ realname set to: [foo]
-8 .$ port set to: [6697]
-repeat conn0 conn1 8
-, .$ CONNECTED
-1:8 .> CAP LS :302
-1:8 .> USER foo 0 * :foo
-1:8 .> NICK :?foo
-:1:8 .< :*.?.net 432 * ?foo :Erroneous nickname
-repeat isupport-clear-in isupport-clear-out 8
-8 .$ connection_state set to: []
-, .$ DISCONNECTED
-8 .!$ nickname refused for bad format, giving up
-
-# test failing third connection
-> /connect baz.baz.baz baz baz:baz
-repeat standard-clears-in standard-clears-out 9
-, .$ DISCONNECTED
-9 .$ hostname set to: [baz.baz.baz]
-9 .$ port set to: [-1]
-9 .$ nick_wanted set to: [baz]
-9 .$ user_wanted set to: [baz]
-9 .$ realname set to: [baz]
-9 .$ port set to: [6697]
-repeat conn0 conn1 9
-, .$ CONNECTED
-2:9 .> CAP LS :302
-2:9 .> USER baz 0 * :baz
-2:9 .> NICK :baz
-<2 FAKE_IRC_CONN_ABORT_EXCEPTION
-9 .$ connection_state set to: [broken: FAKE_IRC_CONN_ABORT_EXCEPTION]
-repeat isupport-clear-in isupport-clear-out 9
-9 .$ connection_state set to: []
-, .$ DISCONNECTED
-
-# check that (save TUI tests assuming start on window 0, and no 4 yet) on reconnect, all the same effects can be expected
-> /reconnect
-repeat conn0 conn1
-2,3,4,5,6,7 .$ CONNECTED
-repeat conn2 conn3
-1 .> JOIN :#testtest
-repeat conn3 conn4
-repeat conn5 conn6
-
-> /quit
-0 .<