From ab824f5b33ec3977684af25266a658fd44c93b3d Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Mon, 21 Nov 2022 05:50:53 -0800 Subject: [PATCH 0/8] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (8): Add GS2 authorization to sasl-scram-rfc Don't set erc-networks--id until network is known Make erc--server-reconnecting non-buffer-local Support local ERC modules in erc-mode buffers Call erc-login indirectly via new generic wrapper Add non-IRCv3 SASL module to ERC Accept functions in place of passwords in ERC Add test scenarios for local ERC modules doc/misc/erc.texi | 188 +++++++- etc/ERC-NEWS | 13 +- lisp/erc/erc-backend.el | 34 +- lisp/erc/erc-common.el | 82 +++- lisp/erc/erc-compat.el | 104 +++++ lisp/erc/erc-goodies.el | 1 + lisp/erc/erc-networks.el | 53 +-- lisp/erc/erc-sasl.el | 428 ++++++++++++++++++ lisp/erc/erc-services.el | 5 +- lisp/erc/erc.el | 166 +++++-- lisp/net/sasl-scram-rfc.el | 21 +- test/lisp/erc/erc-sasl-tests.el | 344 ++++++++++++++ .../erc-scenarios-base-association-nick.el | 84 ++-- .../erc/erc-scenarios-base-local-modules.el | 243 ++++++++++ test/lisp/erc/erc-scenarios-sasl.el | 144 ++++++ test/lisp/erc/erc-services-tests.el | 16 +- test/lisp/erc/erc-tests.el | 178 ++++++++ .../resources/base/local-modules/first.eld | 53 +++ .../resources/base/local-modules/fourth.eld | 53 +++ .../resources/base/local-modules/second.eld | 47 ++ .../resources/base/local-modules/third.eld | 43 ++ test/lisp/erc/resources/sasl/external.eld | 33 ++ test/lisp/erc/resources/sasl/plain-failed.eld | 16 + test/lisp/erc/resources/sasl/plain.eld | 39 ++ test/lisp/erc/resources/sasl/scram-sha-1.eld | 47 ++ .../lisp/erc/resources/sasl/scram-sha-256.eld | 47 ++ 26 files changed, 2320 insertions(+), 162 deletions(-) create mode 100644 lisp/erc/erc-sasl.el create mode 100644 test/lisp/erc/erc-sasl-tests.el create mode 100644 test/lisp/erc/erc-scenarios-base-local-modules.el create mode 100644 test/lisp/erc/erc-scenarios-sasl.el create mode 100644 test/lisp/erc/resources/base/local-modules/first.eld create mode 100644 test/lisp/erc/resources/base/local-modules/fourth.eld create mode 100644 test/lisp/erc/resources/base/local-modules/second.eld create mode 100644 test/lisp/erc/resources/base/local-modules/third.eld create mode 100644 test/lisp/erc/resources/sasl/external.eld create mode 100644 test/lisp/erc/resources/sasl/plain-failed.eld create mode 100644 test/lisp/erc/resources/sasl/plain.eld create mode 100644 test/lisp/erc/resources/sasl/scram-sha-1.eld create mode 100644 test/lisp/erc/resources/sasl/scram-sha-256.eld Interdiff: diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi index 834f1cbf2c..0c3137999a 100644 --- a/doc/misc/erc.texi +++ b/doc/misc/erc.texi @@ -391,15 +391,11 @@ Modules There is a spiffy customize interface, which may be reached by typing @kbd{M-x customize-option @key{RET} erc-modules @key{RET}}. -Alternatively, set @code{erc-modules} manually, and ERC will load them -and run their setup code during buffer initialization. Third-party -code may need to call the function @code{erc-update-modules} -explicitly, although this is typically unnecessary. - -All modules operate as minor modes under the hood, and some newer ones -are defined as buffer-local. For everyday use, the only practical -difference is that local modules can only be enabled in ERC buffers, -and their toggle commands never mutate @code{erc-modules}. +When removing a module outside of the Customize ecosystem, you may +wish to ensure it's disabled by invoking its associated minor-mode +toggle, such as @kbd{M-x erc-spelling-mode @key{RET}}. It may also be +worth noting that, these days, calling @code{erc-update-modules} in an +init file is typically unnecessary. The following is a list of available modules. @@ -529,6 +525,36 @@ Modules @end table +@subheading Local Modules + +All modules operate as minor modes under the hood, and some newer ones +may be defined as buffer-local. For everyday use, the only practical +differences are + +@enumerate +@item +``control variables,'' like @code{erc-sasl-mode}, are stateful across +IRC sessions and override @code{erc-module} membership when influencing +module activation in new sessions +@item +removing a local module from @code{erc-modules} via Customize not only +disables its mode but also kills its control variable in all ERC +buffers +@item +``toggle commands,'' like @code{erc-sasl-mode} and +@code{erc-sasl-enable}, behave differently, both from each other and +from their global counterparts +@end enumerate + +By default, all local-mode toggles, like @code{erc-sasl-mode}, only +affect the current buffer, but their ``non-mode'' variants, such as +@code{erc-sasl-enable}, operate on all buffers belonging to a +connection when called interactively. Keep in mind that whether +enabled or not, a module may effectively be ``inert'' in certain types +of buffers, such as queries and channels. Whatever the case, a local +toggle never mutates @code{erc-modules}. + + @c PRE5_4: Document every option of every module in its own subnode diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 3cd949ddd3..f387491d4c 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -161,7 +161,6 @@ erc-whowas-on-nosuchnick (declare-function erc-login "erc" nil) (declare-function erc-make-notice "erc" (message)) (declare-function erc-network "erc-networks" nil) -(declare-function erc-networks--id-ensure-reload "erc-networks" (nid)) (declare-function erc-networks--id-given "erc-networks" (arg &rest args)) (declare-function erc-networks--id-reload "erc-networks" (arg &rest args)) (declare-function erc-nickname-in-use "erc" (nick reason)) @@ -1638,7 +1637,8 @@ define-erc-response-handler 'NICK-you ?n nick ?N nn) (run-hook-with-args 'erc-nick-changed-functions nn nick)) (t - (erc-networks--id-ensure-reload erc-networks--id) + (when erc-server-connected + (erc-networks--id-reload erc-networks--id proc parsed)) (erc-handle-user-status-change 'nick (list nick login host) (list nn)) (erc-display-message parsed 'notice bufs 'NICK ?n nick ?u login ?h host ?N nn)))))) @@ -2265,7 +2265,8 @@ erc-server-322-message (define-erc-response-handler (433) "Login-time \"nick in use\"." nil - (erc-networks--id-ensure-reload erc-networks--id) + (when erc-server-connected + (erc-networks--id-reload erc-networks--id proc parsed)) (erc-nickname-in-use (cadr (erc-response.command-args parsed)) "already in use")) diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index b791866ee2..a4046ba9b3 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -123,6 +123,30 @@ erc--normalize-module-symbol (setq symbol (intern (downcase (symbol-name symbol)))) (or (cdr (assq symbol erc--module-name-migrations)) symbol)) +(defun erc--assemble-toggle (localp name ablsym mode val body) + (let ((arg (make-symbol "arg"))) + `(defun ,ablsym ,(if localp `(&optional ,arg) '()) + ,(concat + (if val "Enable" "Disable") + " ERC " (symbol-name name) " mode." + (when localp + "\nWith ARG, do so in all buffers for the current connection.")) + (interactive ,@(when localp '("p"))) + ,@(if localp + `((when (derived-mode-p 'erc-mode) + (if ,arg + (erc-with-all-buffers-of-server erc-server-process nil + (,ablsym)) + (setq ,mode ,val) + ,@body))) + `(,(if val + `(cl-pushnew ',(erc--normalize-module-symbol name) + erc-modules) + `(setq erc-modules (delq ',(erc--normalize-module-symbol name) + erc-modules))) + (setq ,mode ,val) + ,@body))))) + (defmacro define-erc-module (name alias doc enable-body disable-body &optional local-p) "Define a new minor mode using ERC conventions. @@ -136,9 +160,14 @@ define-erc-module This will define a minor mode called erc-NAME-mode, possibly an alias erc-ALIAS-mode, as well as the helper functions -erc-NAME-enable, and erc-NAME-disable. Beware that for global -modules, these helpers, as well as the minor-mode toggle, all mutate -the user option `erc-modules'. +erc-NAME-enable, and erc-NAME-disable. + +With LOCAL-P, these helpers take on an optional argument that, +when non-nil, causes them to act on all buffers of a connection. +This feature is mainly intended for interactive use and does not +carry over to their respective minor-mode toggles. Beware that +for global modules, these helpers and toggles all mutate +`erc-modules'. Example: @@ -151,7 +180,6 @@ define-erc-module #\\='erc-replace-insert)))" (declare (doc-string 3) (indent defun)) (let* ((sn (symbol-name name)) - (mod (erc--normalize-module-symbol name)) (mode (intern (format "erc-%s-mode" (downcase sn)))) (group (intern (format "erc-%s" (downcase sn)))) (enable (intern (format "erc-%s-enable" (downcase sn)))) @@ -171,24 +199,8 @@ define-erc-module (if ,mode (,enable) (,disable))) - (defun ,enable () - ,(format "Enable ERC %S mode." - name) - (interactive) - ,@(unless local-p `((cl-pushnew ',mod erc-modules))) - ,@(if local-p - `((when (setq ,mode (and (derived-mode-p 'erc-mode) t)) - ,@enable-body)) - `((setq ,mode t) ,@enable-body))) - (defun ,disable () - ,(format "Disable ERC %S mode." - name) - (interactive) - ,@(unless local-p `((setq erc-modules (delq ',mod erc-modules)))) - ,@(macroexp-unprogn - `(,@(if local-p '(when (derived-mode-p 'erc-mode)) '(progn)) - (setq ,mode nil) - ,@disable-body))) + ,(erc--assemble-toggle local-p name enable mode t enable-body) + ,(erc--assemble-toggle local-p name disable mode nil disable-body) ,(when (and alias (not (eq name alias))) `(defalias ',(intern diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el index fed9b3591b..19a7ab8643 100644 --- a/lisp/erc/erc-networks.el +++ b/lisp/erc/erc-networks.el @@ -985,20 +985,6 @@ erc-networks--id-reload ((not (equal (buffer-name) new-name)))) (rename-buffer new-name 'unique)))) -(cl-defgeneric erc-networks--id-ensure-reload (_nid) - "Schedule or run a reload for IDs derived from nicks." - nil) - -(cl-defmethod erc-networks--id-ensure-reload - ((nid erc-networks--id-qualifying)) - (if erc-server-connected - (erc-networks--id-reload nid) - (letrec ((fn (lambda (&rest _) - (when (eq nid erc-networks--id) - (erc-networks--id-reload nid)) - (remove-hook 'erc-after-connect fn t)))) - (add-hook 'erc-after-connect fn nil t)))) - (cl-defgeneric erc-networks--id-ensure-comparable (self other) "Take measures to ensure two net identities are in comparable states.") @@ -1404,16 +1390,17 @@ erc-networks--update-server-identity ;; server buffer, whereas `erc-networks--rename-server-buffer' can run ;; mid-session, after an identity's core components have changed. -(defun erc-networks--init-identity (_proc _parsed) +(defun erc-networks--init-identity (proc parsed) "Update identity with real network name." ;; Initialize identity for real now that we know the network (cl-assert erc-network) - (unless erc-networks--id - (setq erc-networks--id (erc-networks--id-create nil))) - ;; Find duplicate identities or other conflicting ones and act - ;; accordingly. - (erc-networks--update-server-identity) - ;; + (if erc-networks--id + (erc-networks--id-reload erc-networks--id proc parsed) + (setq erc-networks--id (erc-networks--id-create nil)) + ;; Find duplicate identities or other conflicting ones and act + ;; accordingly. + (erc-networks--update-server-identity) + (erc-networks--rename-server-buffer proc parsed)) nil) (defun erc-networks--rename-server-buffer (new-proc &optional _parsed) @@ -1481,8 +1468,7 @@ erc-networks-on-MOTD-end ;; For now, retain compatibility with erc-server-NNN-functions. (or (erc-networks--ensure-announced proc parsed) (erc-networks--set-name proc parsed) - (erc-networks--init-identity proc parsed) - (erc-networks--rename-server-buffer proc parsed))) + (erc-networks--init-identity proc parsed))) (define-erc-module networks nil "Provide data about IRC networks." diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el index 16fe93f50d..0158161b84 100644 --- a/lisp/erc/erc-sasl.el +++ b/lisp/erc/erc-sasl.el @@ -345,8 +345,7 @@ erc-sasl--authenticate-handler (define-erc-module sasl nil "Non-IRCv3 SASL support for ERC. This doesn't solicit or validate a suite of supported mechanisms." - ;; See bug#49860 for a full, CAP 3.2-aware implementation, currently - ;; a WIP as of ERC 5.5. + ;; See bug#49860 for a CAP 3.2-aware WIP implementation. ((unless erc--target (add-hook 'erc-server-AUTHENTICATE-functions #'erc-sasl--authenticate-handler 0 t) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 8daf8397d1..f18e214d55 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1810,9 +1810,16 @@ erc-modules (dolist (module erc-modules) (unless (member module val) (let ((f (intern-soft (format "erc-%s-mode" module)))) - (when (and (fboundp f) (boundp f) (symbol-value f)) - (message "Disabling `erc-%s'" module) - (funcall f 0)))))) + (when (and (fboundp f) (boundp f)) + (when (symbol-value f) + (message "Disabling `erc-%s'" module) + (funcall f 0)) + (unless (or (custom-variable-p f) + (not (fboundp 'erc-buffer-filter))) + (erc-buffer-filter (lambda () + (when (symbol-value f) + (funcall f 0)) + (kill-local-variable f))))))))) (set sym val) ;; this test is for the case where erc hasn't been loaded yet (when (fboundp 'erc-update-modules) @@ -1963,6 +1970,7 @@ erc-open (let* ((target (and channel (erc--target-from-string channel))) (buffer (erc-get-buffer-create server port nil target id)) (old-buffer (current-buffer)) + (old-vars (and (not connect) (buffer-local-variables))) (old-recon-count erc-server-reconnect-count) (old-point nil) (delayed-modules nil) @@ -1973,8 +1981,9 @@ erc-open (when connect (run-hook-with-args 'erc-before-connect server port nick)) (set-buffer buffer) (setq old-point (point)) - (setq delayed-modules (erc--merge-local-modes (erc--update-modules) - erc--server-reconnecting)) + (setq delayed-modules + (erc--merge-local-modes (erc--update-modules) + (or erc--server-reconnecting old-vars))) (delay-mode-hooks (erc-mode)) @@ -5950,7 +5959,8 @@ erc-set-current-nick (setq erc-server-current-nick nick) ;; This seems sensible but may well be superfluous. Should ;; really prove that it's actually needed via test scenario. - (erc-networks--id-ensure-reload erc-networks--id)) + (when erc-server-connected + (erc-networks--id-reload erc-networks--id))) nick)) (defun erc-current-nick () diff --git a/test/lisp/erc/erc-scenarios-base-local-modules.el b/test/lisp/erc/erc-scenarios-base-local-modules.el new file mode 100644 index 0000000000..417705de09 --- /dev/null +++ b/test/lisp/erc/erc-scenarios-base-local-modules.el @@ -0,0 +1,243 @@ +;;; erc-scenarios-local-modules.el --- Local modules tests for ERC -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. +;; +;; This file is part of GNU Emacs. +;; +;; This program 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. +;; +;; This program 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 this program. If not, see +;; . + +;;; Code: + +;;; Commentary: + +;; These tests all use `sasl' because, as of ERC 5.5, it's the one +;; and only local module. + +(require 'ert-x) +(eval-and-compile + (let ((load-path (cons (ert-resource-directory) load-path))) + (require 'erc-scenarios-common))) + +(require 'erc-sasl) + +;; This asserts that a local module's options and its inclusion in +;; (and absence from) `erc-update-modules' can be let-bound. + +(ert-deftest erc-scenarios-base-local-modules--reconnect-let () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "sasl") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'plain 'plain)) + (port (process-contact dumb-server :service)) + (expect (erc-d-t-make-expecter))) + + (ert-info ("Connect with options let-bound") + (with-current-buffer + ;; This won't work unless the library is already loaded + (let ((erc-modules (cons 'sasl erc-modules)) + (erc-sasl-mechanism 'plain) + (erc-sasl-password "password123")) + (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :full-name "tester")) + (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "ExampleOrg")) + + (ert-info ("First connection succeeds") + (funcall expect 10 "This server is in debug mode") + (erc-cmd-QUIT "") + (funcall expect 10 "finished")) + + (should-not (memq 'sasl erc-modules)) + (erc-d-t-wait-for 10 (not (erc-server-process-alive))) + (erc-cmd-RECONNECT) + + (ert-info ("Second connection succeeds") + (funcall expect 10 "This server is in debug mode") + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))))) + +;; After quitting a session for which `sasl' is enabled, you +;; disconnect and toggle `erc-sasl-mode' off. You then reconnect +;; using an alternate nickname. You again disconnect and reconnect, +;; this time immediately, and the mode stays disabled. Finally, you +;; once again disconnect, toggle the mode back on, and reconnect. You +;; are authenticated successfully, just like in the initial session. +;; +;; This is meant to show that a user's local mode settings persist +;; between sessions. It also happens to show (in round four, below) +;; that a server renicking a user on 001 after a 903 is handled just +;; like a user-initiated renick, although this is not the main thrust. + +(ert-deftest erc-scenarios-base-local-modules--mode-persistence () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/local-modules") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'first 'second 'third 'fourth)) + (port (process-contact dumb-server :service)) + (erc-modules (cons 'sasl erc-modules)) + (expect (erc-d-t-make-expecter)) + (server-buffer-name (format "127.0.0.1:%d" port))) + + (ert-info ("Round one, initial authentication succeeds as expected") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :password "changeme" + :full-name "tester") + (should (string= (buffer-name) server-buffer-name)) + (funcall expect 10 "You are now logged in as tester")) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "foonet")) + (funcall expect 10 "This server is in debug mode") + (erc-cmd-JOIN "#chan") + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (funcall expect 20 "She is Lavinia, therefore must")) + + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))) + + (ert-info ("Round two, nick rejected, alternate granted") + (with-current-buffer "foonet" + + (ert-info ("Toggle mode off, reconnect") + (erc-sasl-mode -1) + (erc-cmd-RECONNECT)) + + (funcall expect 10 "User modes for tester`") + (should-not (cdr (erc-scenarios-common-buflist "foonet"))) + (should (equal (buffer-name) "foonet")) + (should-not (cdr (erc-scenarios-common-buflist "#chan"))) + + (with-current-buffer "#chan" + (funcall expect 10 "Some enigma, some riddle")) + + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))) + + (ert-info ("Round three, send alternate nick initially") + (with-current-buffer "foonet" + + (ert-info ("Keep mode off, reconnect") + (should-not erc-sasl-mode) + (should (local-variable-p 'erc-sasl-mode)) + (erc-cmd-RECONNECT)) + + (funcall expect 10 "User modes for tester`") + (should-not (cdr (erc-scenarios-common-buflist "foonet"))) + (should (equal (buffer-name) "foonet")) + (should-not (cdr (erc-scenarios-common-buflist "#chan"))) + + (with-current-buffer "#chan" + (funcall expect 10 "Let our reciprocal vows be remembered.")) + + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))) + + (ert-info ("Round four, authenticated successfully again") + (with-current-buffer "foonet" + + (ert-info ("Toggle mode on, reconnect") + (should-not erc-sasl-mode) + (should (local-variable-p 'erc-sasl-mode)) + (erc-sasl-mode +1) + (erc-cmd-RECONNECT)) + + (funcall expect 10 "User modes for tester") + (should-not (cdr (erc-scenarios-common-buflist "foonet"))) + (should (equal (buffer-name) "foonet")) + (should-not (cdr (erc-scenarios-common-buflist "#chan"))) + + (with-current-buffer "#chan" + (funcall expect 10 "Well met; good morrow, Titus and Hortensius.")) + + (erc-cmd-QUIT ""))))) + +;; For local modules, the twin toggle commands `erc-FOO-enable' and +;; `erc-FOO-disable' affect all buffers of a connection, whereas +;; `erc-FOO-mode' continues to operate only on the current buffer. + +(ert-deftest erc-scenarios-base-local-modules--toggle-helpers () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/local-modules") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'first 'second 'fourth)) + (port (process-contact dumb-server :service)) + (erc-modules (cons 'sasl erc-modules)) + (expect (erc-d-t-make-expecter)) + (server-buffer-name (format "127.0.0.1:%d" port))) + + (ert-info ("Initial authentication succeeds as expected") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :password "changeme" + :full-name "tester") + (should (string= (buffer-name) server-buffer-name)) + (funcall expect 10 "You are now logged in as tester")) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "foonet")) + (funcall expect 10 "This server is in debug mode") + (erc-cmd-JOIN "#chan") + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (funcall expect 20 "She is Lavinia, therefore must")) + + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))) + + (ert-info ("Disabling works from a target buffer.") + (with-current-buffer "#chan" + (should erc-sasl-mode) + (call-interactively #'erc-sasl-disable) + (should-not erc-sasl-mode) + (should (local-variable-p 'erc-sasl-mode)) + (should-not (buffer-local-value 'erc-sasl-mode (get-buffer "foonet"))) + (erc-cmd-RECONNECT) + (with-current-buffer "#chan" + (funcall expect 10 "Some enigma, some riddle") + (should-not erc-sasl-mode) ; regression + (should (local-variable-p 'erc-sasl-mode)))) + + (with-current-buffer "foonet" + (should (local-variable-p 'erc-sasl-mode)) + (funcall expect 10 "User modes for tester`") + (erc-cmd-QUIT "") + (funcall expect 10 "finished"))) + + (ert-info ("Enabling works from a target buffer") + (with-current-buffer "#chan" + (call-interactively #'erc-sasl-enable) + (should (local-variable-p 'erc-sasl-mode)) + (should erc-sasl-mode) + (erc-cmd-RECONNECT) + (funcall expect 10 "Well met; good morrow, Titus and Hortensius.") + (erc-cmd-QUIT "")) + + (with-current-buffer "foonet" + (should (local-variable-p 'erc-sasl-mode)) + (should erc-sasl-mode) + (funcall expect 10 "User modes for tester"))))) + +;;; erc-scenarios-local-modules.el ends here diff --git a/test/lisp/erc/erc-scenarios-sasl.el b/test/lisp/erc/erc-scenarios-sasl.el index 713c9929c3..6c5e78d0c8 100644 --- a/test/lisp/erc/erc-scenarios-sasl.el +++ b/test/lisp/erc/erc-scenarios-sasl.el @@ -25,22 +25,17 @@ (let ((load-path (cons (ert-resource-directory) load-path))) (require 'erc-scenarios-common))) -(declare-function sasl-client-name "sasl" (client)) - -(require 'erc-scenarios-common) (require 'erc-sasl) (ert-deftest erc-scenarios-sasl--plain () :tags '(:expensive-test) (erc-scenarios-common-with-cleanup ((erc-scenarios-common-dialog "sasl") - (erc-d-linger-secs 0.5) (erc-server-flood-penalty 0.1) (dumb-server (erc-d-run "localhost" t 'plain)) (port (process-contact dumb-server :service)) (erc-modules (cons 'sasl erc-modules)) (erc-sasl-password "password123") - (inhibit-message noninteractive) (expect (erc-d-t-make-expecter))) (ert-info ("Connect") @@ -51,66 +46,21 @@ erc-scenarios-sasl--plain :full-name "tester") (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) - (erc-d-t-wait-for 10 "server buffer ready" (get-buffer "ExampleOrg")) - (ert-info ("Notices received") - (with-current-buffer "ExampleOrg" + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "ExampleOrg")) (funcall expect 10 "This server is in debug mode") ;; Regression "\0\0\0\0 ..." caused by (fillarray passphrase 0) (should (string= erc-sasl-password "password123")))))) -;; This is meant to assert `erc-update-modules' and local-module -;; behavior generally. It only exists here for convenience because as -;; of ERC 5.5, `sasl' is the only local module. -(ert-deftest erc-scenarios-sasl--local-modules-reconnect () - :tags '(:expensive-test) - (erc-scenarios-common-with-cleanup - ((erc-scenarios-common-dialog "sasl") - (erc-server-flood-penalty 0.1) - (dumb-server (erc-d-run "localhost" t 'plain 'plain)) - (port (process-contact dumb-server :service)) - (inhibit-message noninteractive) - (expect (erc-d-t-make-expecter))) - - (ert-info ("Connect with options let-bound") - (with-current-buffer - ;; This won't work unless the library is already loaded - (let ((erc-modules (cons 'sasl erc-modules)) - (erc-sasl-mechanism 'plain) - (erc-sasl-password "password123")) - (erc :server "127.0.0.1" - :port port - :nick "tester" - :user "tester" - :full-name "tester")) - (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) - - (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "ExampleOrg")) - (ert-info ("First connection succeeds") - (funcall expect 10 "This server is in debug mode") - (erc-cmd-QUIT "") - (funcall expect 10 "finished")) - - (should-not (memq 'sasl erc-modules)) - - (erc-d-t-wait-for 10 (not (erc-server-process-alive))) - (erc-cmd-RECONNECT) - (ert-info ("Second connection succeeds") - (funcall expect 10 "This server is in debug mode") - (erc-cmd-QUIT "") - (funcall expect 10 "finished"))))) - (ert-deftest erc-scenarios-sasl--external () :tags '(:expensive-test) (erc-scenarios-common-with-cleanup ((erc-scenarios-common-dialog "sasl") - (erc-d-linger-secs 0.5) (erc-server-flood-penalty 0.1) (dumb-server (erc-d-run "localhost" t 'external)) (port (process-contact dumb-server :service)) (erc-modules (cons 'sasl erc-modules)) (erc-sasl-mechanism 'external) - (inhibit-message noninteractive) (expect (erc-d-t-make-expecter))) (ert-info ("Connect") @@ -121,25 +71,21 @@ erc-scenarios-sasl--external :full-name "tester") (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) - (erc-d-t-wait-for 10 "server buffer ready" (get-buffer "ExampleOrg")) - (ert-info ("Notices received") - (with-current-buffer "ExampleOrg" - (funcall expect 10 "903 * Authentication successful") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "ExampleOrg")) + (funcall expect 10 "Authentication successful") (funcall expect 10 "This server is in debug mode"))))) (ert-deftest erc-scenarios-sasl--plain-fail () :tags '(:expensive-test) (erc-scenarios-common-with-cleanup ((erc-scenarios-common-dialog "sasl") - (erc-d-linger-secs 0.5) (erc-server-flood-penalty 0.1) (dumb-server (erc-d-run "localhost" t 'plain-failed)) (port (process-contact dumb-server :service)) (erc-modules (cons 'sasl erc-modules)) (erc-sasl-password "wrong") (erc-sasl-mechanism 'plain) - (inhibit-message noninteractive) (expect (erc-d-t-make-expecter)) (buf nil)) @@ -161,7 +107,6 @@ erc-scenarios-sasl--plain-fail (defun erc-scenarios--common--sasl (mech) (erc-scenarios-common-with-cleanup ((erc-scenarios-common-dialog "sasl") - (erc-d-linger-secs 0.5) (erc-server-flood-penalty 0.1) (dumb-server (erc-d-run "localhost" t mech)) (port (process-contact dumb-server :service)) @@ -170,7 +115,6 @@ erc-scenarios--common--sasl (erc-sasl-mechanism mech) (mock-rvs (list "c5RqLCZy0L4fGkKAZ0hujFBs" "")) (sasl-unique-id-function (lambda () (pop mock-rvs))) - (inhibit-message noninteractive) (expect (erc-d-t-make-expecter))) (ert-info ("Connect") @@ -181,10 +125,8 @@ erc-scenarios--common--sasl :full-name "jilles") (should (string= (buffer-name) (format "127.0.0.1:%d" port))))) - (erc-d-t-wait-for 10 "server buffer ready" (get-buffer "jaguar")) - (ert-info ("Notices received") - (with-current-buffer "jaguar" + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "jaguar")) (funcall expect 10 "Found your hostname") (funcall expect 20 "marked as being away"))))) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index c74c2e4747..4d0d69cd7b 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1261,4 +1261,99 @@ erc--merge-local-modes (should (equal (erc--merge-local-modes new old) '((erc-d-mode erc-e-mode) . (erc-b-mode))))))) +(ert-deftest define-erc-module--global () + (let ((global-module '(define-erc-module mname malias + "Some docstring" + ((ignore a) (ignore b)) + ((ignore c) (ignore d))))) + + (should (equal (macroexpand global-module) + `(progn + + (define-minor-mode erc-mname-mode + "Toggle ERC mname mode. +With a prefix argument ARG, enable mname if ARG is positive, +and disable it otherwise. If called from Lisp, enable the mode +if ARG is omitted or nil. +Some docstring" + :global t + :group 'erc-mname + (if erc-mname-mode + (erc-mname-enable) + (erc-mname-disable))) + + (defun erc-mname-enable () + "Enable ERC mname mode." + (interactive) + (cl-pushnew 'mname erc-modules) + (setq erc-mname-mode t) + (ignore a) (ignore b)) + + (defun erc-mname-disable () + "Disable ERC mname mode." + (interactive) + (setq erc-modules (delq 'mname erc-modules)) + (setq erc-mname-mode nil) + (ignore c) (ignore d)) + + (defalias 'erc-malias-mode #'erc-mname-mode) + + (put 'erc-mname-mode 'definition-name 'mname) + (put 'erc-mname-enable 'definition-name 'mname) + (put 'erc-mname-disable 'definition-name 'mname)))))) + +(ert-deftest define-erc-module--local () + (let* ((global-module '(define-erc-module mname malias + "Some docstring" + ((ignore a) (ignore b)) + ((ignore c) (ignore d)) + 'local)) + (got (macroexpand global-module)) + (arg-en (cadr (nth 2 (nth 2 got)))) + (arg-dis (cadr (nth 2 (nth 3 got))))) + + (should (equal got + `(progn + (define-minor-mode erc-mname-mode + "Toggle ERC mname mode. +With a prefix argument ARG, enable mname if ARG is positive, +and disable it otherwise. If called from Lisp, enable the mode +if ARG is omitted or nil. +Some docstring" + :global nil + :group 'erc-mname + (if erc-mname-mode + (erc-mname-enable) + (erc-mname-disable))) + + (defun erc-mname-enable (&optional ,arg-en) + "Enable ERC mname mode. +With ARG, do so in all buffers for the current connection." + (interactive "p") + (when (derived-mode-p 'erc-mode) + (if ,arg-en + (erc-with-all-buffers-of-server + erc-server-process nil + (erc-mname-enable)) + (setq erc-mname-mode t) + (ignore a) (ignore b)))) + + (defun erc-mname-disable (&optional ,arg-dis) + "Disable ERC mname mode. +With ARG, do so in all buffers for the current connection." + (interactive "p") + (when (derived-mode-p 'erc-mode) + (if ,arg-dis + (erc-with-all-buffers-of-server + erc-server-process nil + (erc-mname-disable)) + (setq erc-mname-mode nil) + (ignore c) (ignore d)))) + + (defalias 'erc-malias-mode #'erc-mname-mode) + + (put 'erc-mname-mode 'definition-name 'mname) + (put 'erc-mname-enable 'definition-name 'mname) + (put 'erc-mname-disable 'definition-name 'mname)))))) + ;;; erc-tests.el ends here diff --git a/test/lisp/erc/resources/base/local-modules/first.eld b/test/lisp/erc/resources/base/local-modules/first.eld new file mode 100644 index 0000000000..f9181a80fb --- /dev/null +++ b/test/lisp/erc/resources/base/local-modules/first.eld @@ -0,0 +1,53 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl")) +((nick 1 "NICK tester")) +((user 1 "USER tester 0 * :tester")) + +((authenticate 5 "AUTHENTICATE PLAIN") + (0.0 ":irc.foonet.org CAP * ACK sasl") + (0.0 "AUTHENTICATE +")) + +((authenticate 5 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.0 ":irc.foonet.org 900 * * tester :You are now logged in as tester") + (0.01 ":irc.foonet.org 903 * :Authentication successful")) + +((cap 3.2 "CAP END") + (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.8.0") + (0.2 ":irc.foonet.org 003 tester :This server was created Sun, 20 Nov 2022 23:10:36 UTC") + (0.0 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server") + (0.0 ":irc.foonet.org 005 tester 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 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server") + (0.0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server") + (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)") + (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0.0 ":irc.foonet.org 253 tester 0 :unregistered connections") + (0.0 ":irc.foonet.org 254 tester 1 :channels formed") + (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers") + (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3") + (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") + (0.0 ":irc.foonet.org 422 tester :MOTD File is missing") + (0.0 ":irc.foonet.org 221 tester +i") + (0.0 ":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.02 ":irc.foonet.org 221 tester +i")) + +((join 10 "JOIN #chan") + (0.00 ":tester!~u@u9iqi96sfwk9s.irc JOIN #chan") + (0.06 ":irc.foonet.org 353 tester = #chan :@bob alice tester") + (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list") + (0.02 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester, welcome!") + (0.01 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester, welcome!") + (0.04 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: Either your unparagoned mistress is dead, or she's outprized by a trifle.")) + +((mode 12 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester #chan +nt") + (0.02 ":irc.foonet.org 329 tester #chan 1668985854") + (0.98 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: Come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of ? Come me to what was done to her.") + (0.01 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: She is Lavinia, therefore must be lov'd.")) + +((quit 10 "QUIT :\2ERC\2") + (0.02 ":tester!~u@u9iqi96sfwk9s.irc QUIT :Quit")) + +((drop 0 DROP)) diff --git a/test/lisp/erc/resources/base/local-modules/fourth.eld b/test/lisp/erc/resources/base/local-modules/fourth.eld new file mode 100644 index 0000000000..fd6d62b6cc --- /dev/null +++ b/test/lisp/erc/resources/base/local-modules/fourth.eld @@ -0,0 +1,53 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl")) +((nick 10 "NICK tester`")) +((user 10 "USER tester 0 * :tester")) + +((authenticate 10 "AUTHENTICATE PLAIN") + (0.0 ":irc.foonet.org CAP * ACK sasl") + (0.0 "AUTHENTICATE +")) + +((authenticate 10 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.00 ":irc.foonet.org 900 * * tester :You are now logged in as tester") + (0.01 ":irc.foonet.org 903 * :Authentication successful")) + +((cap 10 "CAP END") + (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.8.0") + (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 20 Nov 2022 23:10:36 UTC") + (0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.13 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server") + (0.01 ":irc.foonet.org 005 tester 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 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server") + (0.03 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 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 1 :channels formed") + (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3") + (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") + (0.03 ":irc.foonet.org 422 tester :MOTD File is missing") + (0.02 ":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 10 "MODE tester +i") + (0.0 ":irc.foonet.org 221 tester +i")) + +((join 10 "JOIN #chan") + (0.00 ":tester!~u@u9iqi96sfwk9s.irc JOIN #chan") + (0.09 ":irc.foonet.org 353 tester = #chan :alice tester @bob") + (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list") + (0.00 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester, welcome!") + (0.00 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester, welcome!") + (0.03 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: And both shall cease, without your remedy.") + (0.02 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: Nay, tarry; I'll go along with thee: I can tell thee pretty tales of the duke.")) + +((mode 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester #chan +nt") + (0.01 ":irc.foonet.org 329 tester #chan 1668985854") + (0.03 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: Do: I'll take the sacrament on't, how and which way you will.") + (0.00 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: Worthy Macbeth, we stay upon your leisure.") + (0.00 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: Well met; good morrow, Titus and Hortensius.")) + +((quit 10 "QUIT :\2ERC\2") + (0.03 ":tester!~u@u9iqi96sfwk9s.irc QUIT :Quit")) diff --git a/test/lisp/erc/resources/base/local-modules/second.eld b/test/lisp/erc/resources/base/local-modules/second.eld new file mode 100644 index 0000000000..a96103b2aa --- /dev/null +++ b/test/lisp/erc/resources/base/local-modules/second.eld @@ -0,0 +1,47 @@ +;; -*- mode: lisp-data; -*- +((pass 10 "PASS :changeme")) +((nick 1 "NICK tester")) +((user 1 "USER tester 0 * :tester") + (0.0 ":irc.foonet.org 433 * tester :Nickname is reserved by a different account")) + +((nick 10 "NICK tester`") + (0.01 ":irc.foonet.org FAIL NICK NICKNAME_RESERVED tester :Nickname is reserved by a different account") + (0.06 ":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.8.0") + (0.01 ":irc.foonet.org 003 tester` :This server was created Sun, 20 Nov 2022 23:10:36 UTC") + (0.01 ":irc.foonet.org 004 tester` irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.01 ":irc.foonet.org 005 tester` AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server") + (0.01 ":irc.foonet.org 005 tester` 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 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester` draft/CHATHISTORY=100 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester` :There are 0 users and 3 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` 1 :channels formed") + (0.00 ":irc.foonet.org 255 tester` :I have 3 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester` 3 3 :Current local users 3, max 3") + (0.00 ":irc.foonet.org 266 tester` 3 3 :Current global users 3, max 3") + (0.00 ":irc.foonet.org 422 tester` :MOTD File is missing") + (0.02 ":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 12 "MODE tester` +i") + (0.0 ":irc.foonet.org 221 tester` +i")) + +((join 10 "JOIN #chan") + (0.00 ":tester`!~u@u9iqi96sfwk9s.irc JOIN #chan") + (0.08 ":irc.foonet.org 353 tester` = #chan :@bob alice tester`") + (0.01 ":irc.foonet.org 366 tester` #chan :End of NAMES list") + (0.00 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester`, welcome!") + (0.01 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester`, welcome!") + (0.05 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: And Jove, for your love, would infringe an oath.")) + +((mode 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester` #chan +nt") + (0.02 ":irc.foonet.org 329 tester` #chan 1668985854") + (0.07 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: To you that know them not. This to my mother.") + (0.00 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: Some enigma, some riddle: come, thy l'envoy; begin.")) + +((quit 1 "QUIT :\2ERC\2") + (0.03 ":tester`!~u@u9iqi96sfwk9s.irc QUIT")) + +((drop 0 DROP)) diff --git a/test/lisp/erc/resources/base/local-modules/third.eld b/test/lisp/erc/resources/base/local-modules/third.eld new file mode 100644 index 0000000000..060083656a --- /dev/null +++ b/test/lisp/erc/resources/base/local-modules/third.eld @@ -0,0 +1,43 @@ +;; -*- mode: lisp-data; -*- +((pass 10 "PASS :changeme")) +((nick 1 "NICK tester`")) +((user 1 "USER tester 0 * :tester") + (0.06 ":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.8.0") + (0.01 ":irc.foonet.org 003 tester` :This server was created Sun, 20 Nov 2022 23:10:36 UTC") + (0.01 ":irc.foonet.org 004 tester` irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.01 ":irc.foonet.org 005 tester` AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server") + (0.01 ":irc.foonet.org 005 tester` 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 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester` draft/CHATHISTORY=100 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester` :There are 0 users and 3 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` 1 :channels formed") + (0.00 ":irc.foonet.org 255 tester` :I have 3 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester` 3 3 :Current local users 3, max 3") + (0.00 ":irc.foonet.org 266 tester` 3 3 :Current global users 3, max 3") + (0.00 ":irc.foonet.org 422 tester` :MOTD File is missing") + (0.02 ":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 12 "MODE tester` +i") + (0.0 ":irc.foonet.org 221 tester` +i")) + +((join 10 "JOIN #chan") + (0.00 ":tester`!~u@u9iqi96sfwk9s.irc JOIN #chan") + (0.08 ":irc.foonet.org 353 tester` = #chan :@bob alice tester`") + (0.01 ":irc.foonet.org 366 tester` #chan :End of NAMES list") + (0.00 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester`, welcome!") + (0.01 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :tester`, welcome!") + (0.05 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: With pomp, with triumph, and with revelling.")) + +((mode 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester` #chan +nt") + (0.02 ":irc.foonet.org 329 tester` #chan 1668985854") + (0.00 ":alice!~u@2fzfcku68ehqa.irc PRIVMSG #chan :bob: No remedy, my lord, when walls are so wilful to hear without warning.") + (0.01 ":bob!~u@2fzfcku68ehqa.irc PRIVMSG #chan :alice: Let our reciprocal vows be remembered. You have many opportunities to cut him off; if your will want not, time and place will be fruitfully offered. There is nothing done if he return the conqueror; then am I the prisoner, and his bed my gaol; from the loathed warmth whereof deliver me, and supply the place for your labour.")) + +((quit 1 "QUIT :\2ERC\2") + (0.03 ":tester`!~u@u9iqi96sfwk9s.irc QUIT :Quit")) + +((drop 0 DROP)) -- 2.38.1