From 6283c01e6da88ba2c031f118684922aa2f64c16e Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 6 Aug 2024 19:13:51 -0700 Subject: [PATCH 2/5] [5.6.1] Store one string per user in erc--spkr msg prop * lisp/erc/erc.el (erc--msg-props): Mention that the `erc--spkr' msg-prop value is taken from the `nickname' slot of the user's `erc-server-users' entry. (erc--speakerize-nick): Avoid using the provided NICK parameter for the `erc--spkr' property. Instead, use the version from the `nickname' slot of its `erc-server-users' item, which is itself an `erc-server-user' object. These text props were originally introduced in ERC 5.6 as part of Bug#67677. * test/lisp/erc/erc-tests.el (erc--refresh-prompt) (erc--check-prompt-input-functions, erc-send-current-line) (erc--check-prompt-input-for-multiline-blanks) (erc-send-whitespace-lines): Use more convenient helper utility to create fake server buffer where possible. (erc--speakerize-nick): New test. * test/lisp/erc/resources/erc-tests-common.el (erc-tests-common-make-server-buf): Don't use ERT temp buffer's name for dialed server, etc., because it contains unwanted chars. (erc-tests-common-with-process-input-spy): Defer to each test to set up its own prompt, etc. --- lisp/erc/erc.el | 29 ++++----- test/lisp/erc/erc-tests.el | 71 ++++++++++++++++++--- test/lisp/erc/resources/erc-tests-common.el | 9 +-- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 5e8fa3051c7..8b3eef94ee4 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -173,7 +173,8 @@ erc--msg-props and help text, and on outgoing messages unless echoed back by the server (assuming future support) - - `erc--spkr': a string, the nick of the person speaking + - `erc--spkr': a string, the non-case-mapped nick of the speaker as + stored in the `nickname' slot of its `erc-server-users' item - `erc--ctcp': a CTCP command, like `ACTION' @@ -6339,20 +6340,18 @@ erc--message-speaker-ctcp-action-statusmsg-input "Template for a CTCP ACTION status message from current client.") (defun erc--speakerize-nick (nick &optional disp) - "Propertize NICK with `erc--speaker' if not already present. -Do so to DISP instead if it's non-nil. In either case, assign -NICK, sans properties, as the `erc--speaker' value. As a side -effect, pair the latter string (the same `eq'-able object) with -the symbol `erc--spkr' in the \"msg prop\" environment for any -imminent `erc-display-message' invocations. While doing so, -include any overrides defined in `erc--message-speaker-catalog'." - (let ((plain-nick (substring-no-properties nick))) - (erc--ensure-spkr-prop plain-nick (get erc--message-speaker-catalog - 'erc--msg-prop-overrides)) - (if (text-property-not-all 0 (length (or disp nick)) - 'erc--speaker nil (or disp nick)) - (or disp nick) - (propertize (or disp nick) 'erc--speaker plain-nick)))) + "Return propertized NICK with canonical NICK in `erc--speaker'. +Return propertized DISP instead if given. As a side effect, pair NICK +with `erc--spkr' in the \"msg prop\" environment for any imminent +`erc-display-message' invocations, and include any overrides defined in +`erc--message-speaker-catalog'. Expect NICK (but not necessarily DISP) +to be absent of any existing text properties." + (when-let ((erc-server-process) + (cusr (erc-get-server-user nick))) + (setq nick (erc-server-user-nickname cusr))) + (erc--ensure-spkr-prop nick (get erc--message-speaker-catalog + 'erc--msg-prop-overrides)) + (propertize (or disp nick) 'erc--speaker nick)) (defun erc--determine-speaker-message-format-args (nick message queryp privmsgp inputp &optional statusmsg prefix disp-nick) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index f65c1496087..b11f994bce8 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -330,16 +330,12 @@ erc--refresh-prompt (ert-info ("Server buffer") (with-current-buffer (get-buffer-create "ServNet") - (erc-tests-common-prep-for-insertion) + (erc-tests-common-make-server-buf "ServNet") (goto-char erc-insert-marker) (should (looking-at-p "ServNet 3>")) (erc-tests-common-init-server-proc "sleep" "1") (set-process-sentinel erc-server-process #'ignore) - (setq erc-network 'ServNet - erc-server-current-nick "tester" - erc-networks--id (erc-networks--id-create nil) - erc-server-users (make-hash-table :test 'equal)) - (set-process-query-on-exit-flag erc-server-process nil) + (setq erc-server-current-nick "tester") ;; Incoming message redraws prompt (erc-display-message nil 'notice nil "Welcome") (should (looking-at-p (rx "*** Welcome"))) @@ -364,6 +360,8 @@ erc--refresh-prompt (should-not (search-forward (rx (any "3-5") ">") nil t))))) (ert-info ("Channel buffer") + ;; Create buffer manually instead of using `erc--open-target' in + ;; order to show prompt before/after network is known. (with-current-buffer (get-buffer-create "#chan") (erc-tests-common-prep-for-insertion) (goto-char erc-insert-marker) @@ -1521,6 +1519,7 @@ erc--input-line-delim-regexp (ert-deftest erc--check-prompt-input-functions () (erc-tests-common-with-process-input-spy (lambda (next) + (erc-tests-common-prep-for-insertion) (ert-info ("Errors when point not in prompt area") ; actually just dings (insert "/msg #chan hi") @@ -1556,7 +1555,7 @@ erc--check-prompt-input-functions (ert-deftest erc-send-current-line () (erc-tests-common-with-process-input-spy (lambda (next) - (erc-tests-common-init-server-proc "sleep" "1") + (erc-tests-common-make-server-buf (buffer-name)) (should (= 0 erc-last-input-time)) (ert-info ("Simple command") @@ -1639,7 +1638,8 @@ erc--check-prompt-input-for-multiline-blanks (ert-with-message-capture messages (erc-tests-common-with-process-input-spy (lambda (next) - (erc-tests-common-init-server-proc "sleep" "300") + (erc-tests-common-make-server-buf (buffer-name)) + (should-not erc-send-whitespace-lines) (should erc-warn-about-blank-lines) @@ -1717,7 +1717,8 @@ erc--check-prompt-input-for-multiline-blanks/explanations (ert-deftest erc-send-whitespace-lines () (erc-tests-common-with-process-input-spy (lambda (next) - (erc-tests-common-init-server-proc "sleep" "1") + (erc-tests-common-make-server-buf (buffer-name)) + (setq-local erc-send-whitespace-lines t) (ert-info ("Multiline hunk with blank line correctly split") @@ -2653,6 +2654,58 @@ erc-tests--format-privmessage (erc--determine-speaker-message-format-args nick msg privp msgp inputp nil pfx)))) +;; This test demonstrates that ERC uses the same string for the +;; `erc--spkr' and `erc--speaker' text properties, which it gets from +;; the `nickname' shot of the speaker's server user. +(ert-deftest erc--speakerize-nick () + (erc-tests-common-make-server-buf) + (setq erc-server-current-nick "tester") + + (let ((sentinel "alice")) + (with-current-buffer (erc--open-target "#chan") + (erc-update-current-channel-member "bob" "bob" t nil nil nil nil nil + "example.org" "~u" "bob") + (erc-update-current-channel-member "alice" sentinel t nil nil nil nil nil + "fsf.org" "~u" "alice")) + + (erc-call-hooks nil (make-erc-response + :sender "alice!~u@fsf.org" + :command "PRIVMSG" + :command-args '("#chan" "one") + :contents "one" + :unparsed ":alice!~u@fsf.org PRIVMSG #chan :one")) + (erc-call-hooks nil (make-erc-response + :sender "bob!~u@example.org" + :command "PRIVMSG" + :command-args '("#chan" "hi") + :contents "hi" + :unparsed ":bob!~u@example.org PRIVMSG #chan :hi")) + (erc-call-hooks nil (make-erc-response + :sender "alice!~u@fsf.org" + :command "PRIVMSG" + :command-args '("#chan" "two") + :contents "two" + :unparsed ":alice!~u@fsf.org PRIVMSG #chan :two")) + + (with-current-buffer (get-buffer "#chan") + (should (eq sentinel + (erc-server-user-nickname (erc-get-server-user "alice")))) + (goto-char (point-min)) + + (should (search-forward " one")) + (should (eq (get-text-property (point) 'erc--speaker) sentinel)) + (should (eq (erc--get-inserted-msg-prop 'erc--spkr) sentinel)) + + (should (search-forward " hi" nil t)) + + (should (search-forward " two")) + (should (eq (get-text-property (point) 'erc--speaker) sentinel)) + (should (eq (erc--get-inserted-msg-prop 'erc--spkr) sentinel)) + + (when noninteractive (kill-buffer))))) + ;; This asserts that `erc--determine-speaker-message-format-args' ;; behaves identically to `erc-format-privmessage', the function whose ;; role it basically replaced. diff --git a/test/lisp/erc/resources/erc-tests-common.el b/test/lisp/erc/resources/erc-tests-common.el index 2ec32db77cd..b5bb1fb09c3 100644 --- a/test/lisp/erc/resources/erc-tests-common.el +++ b/test/lisp/erc/resources/erc-tests-common.el @@ -103,16 +103,17 @@ erc-tests-common-with-process-input-spy (lambda (&rest r) (push r calls))) ((symbol-function 'erc-server-buffer) (lambda () (current-buffer)))) - (erc-tests-common-prep-for-insertion) (funcall test-fn (lambda () (pop calls))))) (when noninteractive (kill-buffer)))) (defun erc-tests-common-make-server-buf (&optional name) "Return a server buffer named NAME, creating it if necessary. Use NAME for the network and the session server as well." - (unless name - (cl-assert (string-prefix-p " *temp*" (setq name (buffer-name))))) - (with-current-buffer (get-buffer-create name) + (with-current-buffer (if name + (get-buffer-create name) + (and (string-search "temp" (buffer-name)) + (setq name "foonet") + (buffer-name))) (erc-tests-common-prep-for-insertion) (erc-tests-common-init-server-proc "sleep" "1") (setq erc-session-server (concat "irc." name ".org") -- 2.46.0