]> git.eshelyaron.com Git - emacs.git/commitdiff
Reuse old query buffers for reassumed nicks in ERC
authorF. Jason Park <jp@neverwas.me>
Thu, 9 May 2024 02:04:13 +0000 (19:04 -0700)
committerEshel Yaron <me@eshelyaron.com>
Wed, 29 May 2024 10:11:50 +0000 (12:11 +0200)
* lisp/erc/erc-backend.el
(erc--wrangle-query-buffers-on-nick-change): New function for handling
buffer renaming and message routing triggered by a nick change.  Such
twiddling used to reside in `erc-server-NICK' but has been separated
out for use by built-in modules overriding `erc-server-NICK'.  The
behavior has also changed to favor always reusing an existing query
buffer whenever possible instead of creating a new, <N>-suffixed
buffer.  This addresses some arguably unfinished business from
bug#48598.
(erc-server-NICK): Fix erroneous call to `erc-update-user-nick' that
passed the sender's login as the function's INFO argument.  Move
buffer renaming logic to `erc--wrangle-query-buffers-on-nick-change'
for use by "NICK" handlers managed by modules.  Also, print the notice
in all query buffers when the client changes its own nick.
(erc-server-QUIT): Show messages in all query buffers when the client
itself quits, but prevent `track' from updating the mode line with
redundant noise.
* lisp/erc/erc.el (erc-generate-new-buffer-name): Fix typo in doc.
(erc--query-list): New function.
* test/lisp/erc/erc-scenarios-base-query-participants.el: New file.
* test/lisp/erc/erc-scenarios-base-renick.el
(erc-scenarios-base-renick-queries-solo): Revise slightly to use
modern helper API.
(erc-scenarios-base-renick-queries/reassume): New test.
(erc-scenarios-base-renick-self/merge-query): New test.
* test/lisp/erc/resources/base/query-participants/legacy.eld: New file.
* test/lisp/erc/resources/base/reconnect/options-again.eld: Adjust
timeout.
* test/lisp/erc/resources/base/renick/queries/reassume.eld: New file.
* test/lisp/erc/resources/base/renick/self/manual.eld: Update timeouts.
* test/lisp/erc/resources/base/renick/self/merge-query-a.eld: New file.
* test/lisp/erc/resources/base/renick/self/merge-query-b.eld: New file.
(Bug#70928)

(cherry picked from commit 75aefe6514854bfdbe2a398cf1b7265012c9a88b)

lisp/erc/erc-backend.el
lisp/erc/erc.el
test/lisp/erc/erc-scenarios-base-query-participants.el [new file with mode: 0644]
test/lisp/erc/erc-scenarios-base-renick.el
test/lisp/erc/resources/base/query-participants/legacy.eld [new file with mode: 0644]
test/lisp/erc/resources/base/reconnect/options-again.eld
test/lisp/erc/resources/base/renick/queries/reassume.eld [new file with mode: 0644]
test/lisp/erc/resources/base/renick/self/manual.eld
test/lisp/erc/resources/base/renick/self/merge-query-a.eld [new file with mode: 0644]
test/lisp/erc/resources/base/renick/self/merge-query-b.eld [new file with mode: 0644]

index 90c46eadaf4ef2f6a34865b7e22822d260064761..97aab0e25c35c6890b954b263b493b042a8ebcf1 100644 (file)
 (declare-function erc--init-channel-modes "erc" (channel raw-args))
 (declare-function erc--open-target "erc" (target))
 (declare-function erc--parse-nuh "erc" (string))
+(declare-function erc--query-list "erc" ())
 (declare-function erc--target-from-string "erc" (string))
 (declare-function erc--update-modes "erc" (raw-args))
 (declare-function erc-active-buffer "erc" nil)
@@ -1839,6 +1840,37 @@ add things to `%s' instead."
                                  ?h host ?t tgt ?m mode)))
       (erc-banlist-update proc parsed))))
 
+(defun erc--wrangle-query-buffers-on-nick-change (old new)
+  "Create or reuse a query buffer for NEW nick after considering OLD nick.
+Return a list of buffers in which to announce the change."
+  ;; Note that `new-buffer' may be older than `old-buffer', e.g., if
+  ;; the query target is switching to a previously used nick.
+  (let ((new-buffer (erc-get-buffer new erc-server-process))
+        (old-buffer (erc-get-buffer old erc-server-process))
+        (selfp (erc-current-nick-p old)) ; e.g., for note taking, etc.
+        buffers)
+    (when new-buffer
+      (push new-buffer buffers))
+    (when old-buffer
+      (push old-buffer buffers)
+      ;; Ensure the new nick is absent from the old query.
+      (unless selfp
+        (erc-remove-channel-member old-buffer old))
+      (when (or selfp (null new-buffer))
+        (let ((target (erc--target-from-string new))
+              (id (erc-networks--id-given erc-networks--id)))
+          (with-current-buffer old-buffer
+            (setq erc-default-recipients (cons new
+                                               (cdr erc-default-recipients))
+                  erc--target target))
+          (setq new-buffer (erc-get-buffer-create erc-session-server
+                                                  erc-session-port
+                                                  nil target id)))))
+    (when new-buffer
+      (with-current-buffer new-buffer
+        (erc-update-mode-line)))
+    buffers))
+
 (define-erc-response-handler (NICK)
   "Handle nick change messages." nil
   (let ((nn (erc-response.contents parsed))
@@ -1853,21 +1885,14 @@ add things to `%s' instead."
       ;; erc-channel-users won't contain it
       ;;
       ;; Possibly still relevant: bug#12002
-      (when-let ((buf (erc-get-buffer nick erc-server-process))
-                 (tgt (erc--target-from-string nn)))
-        (with-current-buffer buf
-          (setq erc-default-recipients (cons nn (cdr erc-default-recipients))
-                erc--target tgt))
-        (with-current-buffer (erc-get-buffer-create erc-session-server
-                                                    erc-session-port nil tgt
-                                                    (erc-networks--id-given
-                                                     erc-networks--id))
-          ;; Current buffer is among bufs
-          (erc-update-mode-line)))
-      (erc-update-user-nick nick nn host nil nil login)
+      (dolist (buf (erc--wrangle-query-buffers-on-nick-change nick nn))
+        (cl-pushnew buf bufs))
+      (erc-update-user-nick nick nn host login)
       (cond
        ((string= nick (erc-current-nick))
         (cl-pushnew (erc-server-buffer) bufs)
+        ;; Show message in all query buffers.
+        (setq bufs (append (erc--query-list) bufs))
         (erc-set-current-nick nn)
         ;; Rename session, possibly rename server buf and all targets
         (when erc-server-connected
@@ -2103,15 +2128,20 @@ like `erc-insert-modify-hook'.")
 (define-erc-response-handler (QUIT)
   "Another user has quit IRC." nil
   (let ((reason (erc-response.contents parsed))
+        (erc--msg-prop-overrides erc--msg-prop-overrides)
         bufs)
     (pcase-let ((`(,nick ,login ,host)
                  (erc-parse-user (erc-response.sender parsed))))
       (setq bufs (erc-buffer-list-with-nick nick proc))
-      (erc-remove-user nick)
+      (when (erc-current-nick-p nick)
+        (setq bufs (append (erc--query-list) bufs))
+        (push '(erc--skip . (track)) erc--msg-prop-overrides))
       (setq reason (erc-wash-quit-reason reason nick login host))
       (erc-display-message parsed 'notice bufs
                            'QUIT ?n nick ?u login
-                           ?h host ?r reason))))
+                           ?h host ?r reason)
+      (erc-remove-user nick)))
+  nil)
 
 (define-erc-response-handler (TOPIC)
   "The channel topic has changed." nil
index 3a2f5ae5ba81da467460f196e387edc9ad1b1692..94130145d30e6303774404685593360ec3961c12 100644 (file)
@@ -1990,7 +1990,7 @@ either SERVER or PORT (but not both) to be nil to accommodate oddball
 `erc-server-connect-function's.
 
 When TGT-INFO is non-nil, expect its string field to match the redundant
-param TARGET (retained for compatibility).  Whenever possibly, prefer
+param TARGET (retained for compatibility).  Whenever possible, prefer
 returning TGT-INFO's string unmodified.  But when a case-insensitive
 collision prevents that, return target@ID when ID is non-nil or
 target@network otherwise after renaming the conflicting buffer in the
@@ -2151,6 +2151,10 @@ all channel buffers on all servers."
           (erc-server-user-buffers user)
         nil))))
 
+(defun erc--query-list ()
+  "Return all query buffers for the current connection."
+  (erc-buffer-list #'erc-query-buffer-p erc-server-process))
+
 ;; Some local variables
 
 ;; TODO eventually deprecate this variable
diff --git a/test/lisp/erc/erc-scenarios-base-query-participants.el b/test/lisp/erc/erc-scenarios-base-query-participants.el
new file mode 100644 (file)
index 0000000..9e91090
--- /dev/null
@@ -0,0 +1,117 @@
+;;; erc-scenarios-base-query-participants.el --- Query user tables -*- lexical-binding: t -*-
+
+;; Copyright (C) 2024 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert-x)
+(eval-and-compile
+  (let ((load-path (cons (ert-resource-directory) load-path)))
+    (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-base-query-participants ()
+  :tags '(:expensive-test)
+
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/query-participants")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'legacy))
+       (expect (erc-d-t-make-expecter))
+       (port (process-contact dumb-server :service)))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :user "tester"
+                                :full-name "tester")
+        (funcall expect 10 "This server is in debug mode")
+        (erc-scenarios-common-say "/query bob")))
+
+    (ert-info ("Opening query on untracked user bob doesn't create entry.")
+      (with-current-buffer "bob"
+        (should-not (erc-get-channel-member "bob"))))
+
+    (ert-info ("DM from untracked user creates a query entry.")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "dummy"))
+        (funcall expect 10 "<dummy> hi")
+        (should (erc-get-channel-member "dummy"))
+        (should (erc-get-server-user "dummy"))))
+
+    (with-current-buffer "foonet"
+      (erc-scenarios-common-say "/join #chan"))
+
+    (ert-info ("Members in new chan not added to existing query buffers")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+        (funcall expect 10 "bob ")) ; some user bob is present in #chan
+      (with-current-buffer "bob"
+        (should-not (erc-get-channel-member "bob"))))
+
+    (ert-info ("Opening query on tracked user doesn't create entry")
+      ;; And DM'ing them makes no difference.
+      (with-current-buffer "#chan"
+        (funcall expect 10 " alice") ;; some user alice is present
+        (erc-scenarios-common-say "hi channel")
+        (funcall expect 10 "<tester> hi channel")
+        (erc-scenarios-common-say "/query alice"))
+      (with-current-buffer "alice"
+        (should-not (erc-get-channel-member "alice"))))
+
+    (ert-info ("DM from a tracked user creates entry in preexisting buffer")
+      (with-current-buffer "bob"
+        (funcall expect 10 "<bob> hi")
+        (should (erc-get-channel-member "bob"))))
+
+    (ert-info ("Query pal parting channel doesn't remove them from query")
+      ;; Identical result if they're kicked: they're removed from the
+      ;; server if they have no target buffers remaining, which can't
+      ;; be true if a query with them remains.
+      (with-current-buffer "#chan"
+        (funcall expect 10 "has left")
+        (should-not (erc-get-channel-member "dummy"))
+        (should (erc-get-server-user "dummy")))
+      (with-current-buffer "dummy"
+        (should (erc-get-channel-member "dummy"))))
+
+    (ert-info ("Query pal quitting channel removes them everywhere")
+      (with-current-buffer "#chan"
+        (funcall expect 10 "has quit")
+        (should-not (erc-get-channel-member "bob"))
+        (should-not (erc-get-server-user "bob")))
+      (with-current-buffer "bob"
+        (should-not (erc-get-channel-member "bob"))))
+
+    (ert-info ("Query pal re-joining doesn't repopulate query")
+      (with-current-buffer "#chan"
+        (erc-scenarios-common-say "bob gone")
+        (funcall expect 10 "<alice> bob, welcome back!")
+        (should (erc-get-server-user "bob")))
+      (with-current-buffer "bob"
+        (should-not (erc-get-channel-member "bob"))))
+
+    (ert-info ("Parting removes chan members from server unless in some query")
+      (with-current-buffer "#chan"
+        (erc-scenarios-common-say "/part")
+        (funcall expect 10 "you have left")
+        (should-not (erc-get-server-user "fsbot"))
+        (should-not (erc-get-server-user "alice")) ; she never said anything
+        (should-not (erc-get-server-user "bob")) ; missing from query
+        (should (erc-get-server-user "dummy"))))))
+
+
+;;; erc-scenarios-base-query-participants.el ends here
index 3001fde6da007d73eb56df8bc301916aa5e327e4..19cb1ecde1d82521c71fb3aa1f9f2c303de3ea73 100644 (file)
        (erc-server-flood-penalty 0.1)
        (erc-server-flood-margin 20)
        (dumb-server (erc-d-run "localhost" t 'solo))
+       (expect (erc-d-t-make-expecter))
        (port (process-contact dumb-server :service))
        erc-autojoin-channels-alist
        erc-server-buffer-foo)
 
     (erc-d-t-wait-for 10 (get-buffer "foonet"))
 
-    (ert-info ("Joined by bouncer to #foo, pal persent")
+    (ert-info ("Joined by bouncer to #foo, pal Lal is present")
       (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo"))
-        (erc-d-t-search-for 5 "On Thursday")
+        (funcall expect 10 "<bob> alice: On Thursday")
         (erc-scenarios-common-say "hi")))
 
-    (erc-d-t-wait-for 10 "Query buffer appears with message from pal"
-      (get-buffer "Lal"))
-
-    (ert-info ("Chat with pal, who changes name")
-      (with-current-buffer "Lal"
-        (erc-d-t-search-for 3 "hello")
+    (ert-info ("Query buffer appears from Lal, who renicks")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "Lal"))
+        (funcall expect 10 "<Lal> hello")
         (erc-scenarios-common-say "hi")
-        (erc-d-t-search-for 10 "is now known as Linguo")
-        (should-not (search-forward "is now known as Linguo" nil t))))
-
-    (erc-d-t-wait-for 1 (get-buffer "Linguo"))
-    (should-not (get-buffer "Lal"))
-
-    (with-current-buffer "Linguo" (erc-scenarios-common-say "howdy Linguo"))
+        (funcall expect 10 "is now known as Linguo")
+        ;; No duplicate message.
+        (funcall expect -0.1 "is now known as Linguo")
+        ;; No duplicate buffer.
+        (erc-d-t-wait-for 1 (equal (buffer-name) "Linguo"))
+        (should-not (get-buffer "Lal"))
+        (erc-scenarios-common-say "howdy Linguo")))
 
     (with-current-buffer "#foo"
-      (erc-d-t-search-for 10 "is now known as Linguo")
-      (should-not (search-forward "is now known as Linguo" nil t))
-      (erc-cmd-PART ""))
+      (funcall expect 10 "is now known as Linguo")
+      (funcall expect -0.1 "is now known as Linguo")
+      (erc-scenarios-common-say "/part"))
 
     (with-current-buffer "Linguo"
-      (erc-d-t-search-for 10 "get along"))))
+      (funcall expect 10 "get along"))))
+
+;; Someone you have a query with disconnects and reconnects under a
+;; new nick (perhaps due to their client appending a backtick or
+;; underscore).  They then engage you in another query before
+;; renicking to their original nick.  Prior to 5.5, ERC would add a
+;; uniquifying suffix of the form bob<2> to the new, post-renick
+;; query.  ERC 5.6+ acts differently.  It mimics popular standalone
+;; clients in reusing existing query buffers.
+(ert-deftest erc-scenarios-base-renick-queries/reassume ()
+  :tags '(:expensive-test)
+
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/renick/queries")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'reassume))
+       (port (process-contact dumb-server :service))
+       (expect (erc-d-t-make-expecter))
+       (erc-autojoin-channels-alist '((foonet "#chan"))))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester")
+        (funcall expect 10 "This server is in debug mode")))
+
+    (ert-info ("User dummy opens a query with you")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "dummy"))
+        (funcall expect 10 "hi")))
+
+    (ert-info ("User dummy quits, reconnects as user warwick")
+      (with-current-buffer "#chan"
+        (funcall expect 10 "has quit")
+        (should-not (erc-get-channel-member "dummy"))
+        (with-current-buffer "dummy"
+          (should-not (erc-get-channel-member "dummy")))
+        (funcall expect 10 "<bob> Alas! sir")
+        (funcall expect 10 "<bob> warwick, welcome")
+        (funcall expect 10 "<warwick> hola")))
+
+    (ert-info ("User warwick queries you, creating a new buffer")
+      (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "warwick"))
+        (should (get-buffer "dummy")) ; not reused
+        (funcall expect 10 "<warwick> howdy")
+        (funcall expect 10 "is now known as dummy")
+        (should-not (erc-get-channel-member "warwick"))
+        (should-not (erc-get-channel-member "dummy"))))
+
+    (ert-info ("User warwick renicks as user dummy")
+      (with-current-buffer "#chan"
+        (funcall expect 10 "is now known as dummy")
+        (should-not (erc-get-channel-member "warwick"))))
+
+    (with-current-buffer "dummy"
+      (should-not (get-buffer "dummy<2>"))
+      (funcall expect 10 "has quit" (point-min))
+      (funcall expect -0.1 "merging buffer")
+      (funcall expect 10 "is now known as dummy")
+      (should (erc-get-channel-member "dummy"))
+      (funcall expect 10 "<dummy> hey"))
+
+    (with-current-buffer "#chan"
+      (funcall expect 10 "<alice> bob: Than those that"))))
+
+;; This test asserts behavior for the other side of the conversation
+;; described by `erc-scenarios-base-renick-queries/reassume' above.
+;; After speaking with someone in a query, you disconnect and
+;; reconnect under a new nick.  You then open a new query with the
+;; same person before changing your nick back to the previous one.
+;; The buffers for the two session should then be merged with the help
+;; of `erc-networks--transplant-target-buffer-function' and
+;; `erc-networks--copy-server-buffer-functions'.
+(ert-deftest erc-scenarios-base-renick-self/merge-query ()
+  :tags '(:expensive-test)
+
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/renick/self")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'merge-query-a 'merge-query-b))
+       (port (process-contact dumb-server :service))
+       (expect (erc-d-t-make-expecter))
+       (erc-autojoin-channels-alist '((foonet "#chan"))))
+
+    (ert-info ("Connect to foonet as tester")
+      (with-current-buffer (erc :server "127.0.0.1" :port port :nick "tester")
+        (funcall expect 10 "This server is in debug mode")))
+
+    (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+      (funcall expect 10 "<alice> bob: Speak to the people")
+      (erc-scenarios-common-say "/query observer"))
+
+    (with-current-buffer "observer"
+      (erc-scenarios-common-say "hi")
+      (funcall expect 10 "<observer> hi?"))
+
+    (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+      (erc-scenarios-common-say "/quit"))
+
+    (with-current-buffer "foonet"
+      (funcall expect 10 "*** ERC finished ***"))
+
+    (ert-info ("Reconnect to foonet as dummy")
+      (with-current-buffer (erc :server "127.0.0.1" :port port :nick "dummy")
+        (funcall expect 10 "This server is in debug mode")))
+
+    (with-current-buffer
+        (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/dummy"))
+      ;; Uniquification has been performed.
+      (should-not (get-buffer "#chan"))
+      (should (get-buffer "#chan@foonet/tester"))
+      (should-not (get-buffer "foonet"))
+      (should (get-buffer "foonet/tester"))
+      (should (get-buffer "foonet/dummy"))
+      (funcall expect 10 "<alice> bob: Pray you")
+      (erc-scenarios-common-say "/query observer"))
+
+    (with-current-buffer "observer@foonet/dummy"
+      (should-not (get-buffer "observer"))
+      (should (get-buffer "observer@foonet/tester"))
+      (erc-scenarios-common-say "hola")
+      (funcall expect 10 "<observer> whodis?"))
+
+    (with-current-buffer
+        (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/dummy"))
+      (erc-scenarios-common-say "/nick tester"))
+
+    ;; All buffers have been merged.
+    (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "observer"))
+      (should-not (get-buffer "observer@foonet/dummy"))
+      (should-not (get-buffer "observer@foonet/tester"))
+      ;; Goto last message from previous session.  Notice that the
+      ;; quit message appears in all buffers, including queries.
+      (funcall expect 10 "has quit" (point-min))
+      (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed
+      (funcall expect 1 (concat "*** Grafting buffer `observer@foonet/dummy'"
+                                " onto `observer@foonet/tester'"))
+      (funcall expect 1 "<dummy> hola")
+      (funcall expect 1 "<observer> whodis?")
+      ;; The nickname change is announced in the query as well so that
+      ;; the nature of the merge is clear.
+      (funcall expect 1 "*** Your new nickname is tester"))
+
+    (with-current-buffer "foonet"
+      (should-not (get-buffer "foonet/dummy"))
+      (should-not (get-buffer "foonet/tester"))
+      ;; Goto last assertion.
+      (funcall expect 10 "*** ERC finished ***" (point-min))
+      (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed
+      (funcall expect 5 "Grafting buffer `foonet/dummy' onto `foonet/tester'"))
+
+    (with-current-buffer "#chan"
+      (should-not (get-buffer "#chan@foonet/dummy"))
+      (should-not (get-buffer "#chan@foonet/tester"))
+      (funcall expect 10 "has quit" (point-min))
+      (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed
+      (funcall expect 1 (concat "*** Grafting buffer `#chan@foonet/dummy'"
+                                " onto `#chan@foonet/tester'"))
+      (funcall expect 1 "You have joined channel #chan")
+      (funcall expect 1 "<bob> alice: Have here bereft")
+      (funcall expect 1 "*** Your new nickname is tester"))))
 
 ;; You share a channel and a query buffer with a user on two different
 ;; networks (through a proxy).  The user changes their nick on both
diff --git a/test/lisp/erc/resources/base/query-participants/legacy.eld b/test/lisp/erc/resources/base/query-participants/legacy.eld
new file mode 100644 (file)
index 0000000..6b18023
--- /dev/null
@@ -0,0 +1,62 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK tester"))
+((user 10 "USER tester 0 * :tester")
+ (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
+ (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 26 May 2024 09:32:55 UTC")
+ (0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server")
+ (0.02 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0.00 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0.03 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0.00 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0.00 ":irc.foonet.org 422 tester :MOTD File is missing")
+ (0.00 ":irc.foonet.org 221 tester +Zi")
+ (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((mode 10 "MODE tester +i")
+ (0.00 ":irc.foonet.org 221 tester +Zi")
+ (0.07 ":dummy!~u@psu3bp52z9f34.irc PRIVMSG tester :hi"))
+
+((join 10 "JOIN #chan")
+ (0.02 ":tester!~u@psu3bp52z9f34.irc JOIN #chan")
+ (0.06 ":irc.foonet.org 353 tester = #chan :bob dummy tester @fsbot alice")
+ (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.00 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :tester, welcome!")
+ (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode-chan 10 "MODE #chan")
+ (0.02 ":irc.foonet.org 324 tester #chan +Cnt")
+ (0.01 ":irc.foonet.org 329 tester #chan 1716715981"))
+
+((privmsg-chan-a 10 "PRIVMSG #chan :hi channel")
+ (0.06 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :Perchance, Iago, I will ne'er go home.")
+
+ ;; Bob (now known) sends us a DM
+ (0.07 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG tester :hi")
+ (0.02 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :alice: He is most in the company of the right noble Claudio.")
+ (0.05 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob: Such were our faults; or then we thought them none.")
+ (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :You, sir, I entertain you for one of my hundred; only I do not like the fashion of your garments: you will say, they are Persian attire; but let them be changed.")
+
+ ;; Dummy parts
+ (0.01 ":dummy!~u@psu3bp52z9f34.irc PART #chan :bye")
+ (0.08 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :alice: To lay a complot to betray thy foes.")
+
+ ;; Bob quits
+ (0.02 ":bob!~u@zmmipd3xfii2w.irc QUIT :later")
+ (0.08 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob: He was famous, sir, in his profession, and it was his great right to be so: Gerard de Narbon."))
+
+;; Bob rejoins
+((privmsg-chan-b 10 "PRIVMSG #chan :bob gone")
+
+ (0.04 ":bob!~u@zmmipd3xfii2w.irc JOIN #chan")
+ (0.01 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob, welcome back!")
+ (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :Our states are forfeit: seek not to undo us."))
+
+((part 10 "PART #chan :\2ERC\2")
+ (0.02 ":tester!~u@psu3bp52z9f34.irc PART #chan :\2ERC\2"))
index 8a3264fda9cc802ea62ddcf72e1982cfe1e6cc95..a3a86fb710076348151e83213d75dbc8e0596e18 100644 (file)
@@ -18,7 +18,7 @@
  (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
  (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
 
-((mode-user 3.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  (0 ":irc.foonet.org 221 tester +i")
  (0 ":irc.foonet.org NOTICE tester :This server is still in debug mode."))
 
diff --git a/test/lisp/erc/resources/base/renick/queries/reassume.eld b/test/lisp/erc/resources/base/renick/queries/reassume.eld
new file mode 100644 (file)
index 0000000..50764a1
--- /dev/null
@@ -0,0 +1,64 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :unknown")
+ (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.00 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
+ (0.00 ":irc.foonet.org 003 tester :This server was created Thu, 09 May 2024 05:19:24 UTC")
+ (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
+ (0.00 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server")
+ (0.00 ":irc.foonet.org 251 tester :There are 0 users and 6 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0.00 ":irc.foonet.org 255 tester :I have 6 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 tester 6 6 :Current local users 6, max 6")
+ (0.00 ":irc.foonet.org 266 tester 6 6 :Current global users 6, max 6")
+ (0.00 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10 "MODE tester +i")
+ (0.00 ":irc.foonet.org 221 tester +i")
+ (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 10 "JOIN #chan")
+ (0.03 ":irc.foonet.org 221 tester +i") ; dupe
+ (0.00 ":tester!~u@s8ceryiqkkcxk.irc JOIN #chan")
+ (0.04 ":irc.foonet.org 353 tester = #chan :@fsbot bob alice dummy tester")
+ (0.00 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.00 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :tester, welcome!")
+ (0.00 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :tester, welcome!")
+ (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :That eye that told you so look'd but a-squint."))
+
+((mode-chan 10 "MODE #chan")
+ (0.00 ":irc.foonet.org 324 tester #chan +Cnt")
+ (0.01 ":irc.foonet.org 329 tester #chan 1715231970")
+
+ ;; existing query with dummy
+ (0.05 ":dummy!~u@s8ceryiqkkcxk.irc PRIVMSG tester :hi")
+ (0.02 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :alice: Villains, forbear! we are the empress' sons.")
+ (0.01 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: This matter of marrying his king's daughter,wherein he must be weighed rather by her value than his own,words him, I doubt not, a great deal from the matter.")
+
+ ;; dummy quits
+ (0.07 ":dummy!~u@s8ceryiqkkcxk.irc QUIT :Quit: \2ERC\2 5.5.0.29.1 (IRC client for GNU Emacs 29.3.50)")
+ (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :We will afflict the emperor in his pride.")
+ (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Why, then, is my pump well flowered.")
+ (0.05 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :Alas! sir, I know not Jupiter; I never drank with him in all my life.")
+
+ ;; rejoins as warwick
+ (0.03 ":warwick!~u@s8ceryiqkkcxk.irc JOIN #chan")
+ (0.00 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :warwick, welcome!")
+ (0.00 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :warwick, welcome!")
+ (0.03 ":warwick!~u@s8ceryiqkkcxk.irc PRIVMSG #chan :hola")
+ (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: And stint thou too, I pray thee, nurse, say I.")
+
+ ;; Makes contact in a query
+ (0.02 ":warwick!~u@s8ceryiqkkcxk.irc PRIVMSG tester :howdy")
+ (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Nor more willingly leaves winter; such summer-birds are men. Gentlemen, our dinner will not recompense this long stay: feast your ears with the music awhile, if they will fare so harshly o' the trumpet's sound; we shall to 't presently.")
+ (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :If it please your honour, I know not well what they are; but precise villains they are, that I am sure of, and void of all profanation in the world that good Christians ought to have.")
+
+ ;; warwick renicks back to dummy
+ (0.08 ":warwick!~u@s8ceryiqkkcxk.irc NICK dummy")
+ (0.04 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :Pleasure and action make the hours seem short.")
+ (0.01 ":dummy!~u@s8ceryiqkkcxk.irc PRIVMSG tester :hey")
+ (0.02 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Than those that have more cunning to be strange."))
index dd107b806d5eb8c1ea4ffd0f2a220f376b5e2d52..a6220ffc2e6698daae0cacd66d46a3e11087603c 100644 (file)
@@ -1,5 +1,5 @@
 ;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :foonet:changeme"))
+((pass 10 "PASS :foonet:changeme"))
 ((nick 1 "NICK tester"))
 ((user 1 "USER user 0 * :tester")
  (0 ":irc.foonet.org 001 tester :Welcome to the FooNet Internet Relay Chat Network tester")
@@ -24,7 +24,7 @@
  (0 ":irc.foonet.org 372 tester :- Please visit us in #libera for questions and support.")
  (0 ":irc.foonet.org 376 tester :End of /MOTD command."))
 
-((mode-user 1.2 "MODE tester +i")
+((mode-user 10 "MODE tester +i")
  (0 ":tester!~u@gq7yjr7gsu7nn.irc MODE tester :+RZi")
  (0 ":irc.znc.in 306 tester :You have been marked as being away")
  (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo")
  (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
  (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
 
-((mode 1 "MODE #foo")
+((mode-foo 10 "MODE #foo")
  (0 ":irc.foonet.org 324 tester #foo +nt")
  (0 ":irc.foonet.org 329 tester #foo 1622454985")
  (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
  (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: On Thursday, sir ? the time is very short."))
 
-((nick 2 "NICK dummy")
+((nick 10 "NICK dummy")
  (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy")
  (0.1 ":dummy!~u@gq7yjr7gsu7nn.irc MODE dummy :+RZi")
  (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :dummy: Hi."))
diff --git a/test/lisp/erc/resources/base/renick/self/merge-query-a.eld b/test/lisp/erc/resources/base/renick/self/merge-query-a.eld
new file mode 100644 (file)
index 0000000..27ef7ec
--- /dev/null
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :unknown")
+ (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1")
+ (0.00 ":irc.foonet.org 003 tester :This server was created Sun, 12 May 2024 00:41:10 UTC")
+ (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server")
+ (0.00 ":irc.foonet.org 251 tester :There are 0 users and 6 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.02 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0.01 ":irc.foonet.org 255 tester :I have 6 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 tester 6 6 :Current local users 6, max 6")
+ (0.00 ":irc.foonet.org 266 tester 6 6 :Current global users 6, max 6")
+ (0.00 ":irc.foonet.org 422 tester :MOTD File is missing")
+ (0.00 ":irc.foonet.org 221 tester +i")
+ (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((mode-user 10 "MODE tester +i"))
+
+((join 10 "JOIN #chan")
+ (0.00 ":irc.foonet.org 221 tester +i")
+ (0.00 ":tester!~u@hyyensdmcrjxc.irc JOIN #chan")
+ (0.02 ":irc.foonet.org 353 tester = #chan :someone tester @fsbot alice bob observer")
+ (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.00 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :tester, welcome!")
+ (0.01 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode-chan 10 "MODE #chan")
+ (0.00 ":irc.foonet.org 324 tester #chan +Cnt")
+ (0.02 ":irc.foonet.org 329 tester #chan 1715474476")
+ (0.09 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: And, uncle, so will I, an if I live.")
+ (0.03 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: Speak to the people, and they pity her."))
+
+((privmsg-observer 10 "PRIVMSG observer :hi")
+ (0.04 ":observer!~u@hyyensdmcrjxc.irc PRIVMSG tester :hi?")
+ (0.07 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :To ask of whence you are: report it."))
+
+((quit 10 "QUIT :\2ERC\2")
+ (0.03 ":tester!~u@hyyensdmcrjxc.irc QUIT :Quit: \2ERC\2 5.6-git (IRC client for GNU Emacs 30.0.50)")
+ (0.03 "ERROR :Quit: \2ERC\2 5.6-git (IRC client for GNU Emacs 30.0.50)"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/renick/self/merge-query-b.eld b/test/lisp/erc/resources/base/renick/self/merge-query-b.eld
new file mode 100644 (file)
index 0000000..4d7581b
--- /dev/null
@@ -0,0 +1,48 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK dummy"))
+((user 10 "USER user 0 * :unknown")
+ (0.01 ":irc.foonet.org 001 dummy :Welcome to the foonet IRC Network dummy")
+ (0.01 ":irc.foonet.org 002 dummy :Your host is irc.foonet.org, running version ergo-v2.11.1")
+ (0.01 ":irc.foonet.org 003 dummy :This server was created Sun, 12 May 2024 00:41:10 UTC")
+ (0.00 ":irc.foonet.org 004 dummy irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.03 ":irc.foonet.org 005 dummy AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server")
+ (0.03 ":irc.foonet.org 005 dummy KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 dummy draft/CHATHISTORY=25 :are supported by this server")
+ (0.00 ":irc.foonet.org 251 dummy :There are 0 users and 6 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 dummy 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 253 dummy 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 dummy 2 :channels formed")
+ (0.00 ":irc.foonet.org 255 dummy :I have 6 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 dummy 6 6 :Current local users 6, max 6")
+ (0.00 ":irc.foonet.org 266 dummy 6 6 :Current global users 6, max 6")
+ (0.03 ":irc.foonet.org 422 dummy :MOTD File is missing")
+ (0.00 ":irc.foonet.org 221 dummy +i")
+ (0.00 ":irc.foonet.org NOTICE dummy :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((mode-user 10 "MODE dummy +i"))
+
+((join-chan 10 "JOIN #chan")
+ (0.01 ":irc.foonet.org 221 dummy +i")
+ (0.00 ":dummy!~u@hyyensdmcrjxc.irc JOIN #chan")
+ (0.02 ":irc.foonet.org 353 dummy = #chan :@fsbot alice bob observer someone dummy")
+ (0.01 ":irc.foonet.org 366 dummy #chan :End of NAMES list")
+ (0.00 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :dummy, welcome!")
+ (0.01 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :dummy, welcome!"))
+
+((mode-chan 10 "MODE #chan")
+ (0.00 ":irc.foonet.org 324 dummy #chan +Cnt")
+ (0.02 ":irc.foonet.org 329 dummy #chan 1715474476")
+ (0.09 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: Indeed, sir, he that sleeps feels not the toothache; but a man that were to sleep your sleep, and a hangman to help him to bed, I think he would change places with his officer; for look you, sir, you know not which way you shall go.")
+ (0.03 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: Pray you, sir, deliver me this paper."))
+
+((privmsg-observer 10 "PRIVMSG observer :hola")
+ (0.01 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: In manner and form following, sir; all those three: I was seen with her in the manor-house, sitting with her upon the form, and taken following her into the park; which, put together, is, in manner and form following. Now, sir, for the manner,it is the manner of a man to speak to a woman, for the form,in some form.")
+ (0.05 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :In Isbel's case and mine own. Service is no heritage; and I think I shall never have the blessing of God till I have issue o' my body, for they say barnes are blessings.")
+ (0.01 ":observer!~u@hyyensdmcrjxc.irc PRIVMSG dummy :whodis?")
+ (0.02 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: Have here bereft my brother of his life."))
+
+((nick-tester 10 "NICK tester")
+ (0.02 ":dummy!~u@hyyensdmcrjxc.irc NICK tester")
+
+ (0.04 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: You have too courtly a wit for me: I'll rest.")
+ (0.07 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: And abstinence engenders maladies."))