From: F. Jason Park Date: Mon, 14 Oct 2024 05:45:05 +0000 (-0700) Subject: Move experimental module querypoll to erc-notify X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0cbaa97ed03ccb8c8e6e3c819b8b6812e05ced6b;p=emacs.git Move experimental module querypoll to erc-notify * etc/ERC-NEWS: Announce migration of misplaced `querypoll' module from erc-goodies.el to erc-notify.el. * lisp/erc/erc-goodies.el: Move all definitions associated with experimental module `querypoll' to erc-notify. * lisp/erc/erc-notify.el (erc--querypoll-ring) (erc--querypoll-timer, erc-querypoll-exclude-regexp) (erc-querypoll-mode, erc-querypoll-enable, erc-querypoll-disable) (erc--queries-current-p, erc-querypoll-period-params) (erc--querypoll-compute-period, erc--querypoll-target-in-chan-p) (erc--querypoll-get-length, erc--querypoll-get-next) (erc--querypoll-subscribe, erc--querypoll-on-352) (erc--querypoll-send): Move here from erc-goodies. * test/lisp/erc/erc-goodies-tests.el (erc--querypoll-compute-period) (erc--querypoll-target-in-chan-p, erc--querypoll-get-length) (erc--querypoll-get-next): Move to new file erc-notify-tests.el. * test/lisp/erc/erc-notify-tests.el: New file. The `querypoll' module was first introduced as part of bug#70928 in ERC 5.6. (cherry picked from commit be3318baddbcb3ff607c784a14c1f21a70e392de) --- diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 39403c17486..3970f67d725 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -55,6 +55,13 @@ indicator stick with the most recent speaker's face, even when they're monologuing, instead of alternating between it and the highest ranked 'erc-track-faces-normal-list' member in a given message. +** Module 'querypoll' has left 'goodies' and moved in with 'notify'. +The 'querypoll' module was initially placed in 'erc-goodies' even though +a far more sensible home existed in 'erc-notify'. Given the similarity +of concerns and the newer module's "experimental" status, the migration +was deemed worth any potential disruption, despite this being a point +release. ERC appreciates your understanding in this matter. + * Changes in ERC 5.6 diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el index ec1e0054dd5..28a9894525c 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el @@ -1148,195 +1148,6 @@ servers. If called from a program, PROC specifies the server process." (multi-occur (erc-buffer-list nil proc) string)) -;;;; querypoll - -(declare-function ring-empty-p "ring" (ring)) -(declare-function ring-insert "ring" (ring item)) -(declare-function ring-insert+extend "ring" (ring item)) -(declare-function ring-length "ring" (ring)) -(declare-function ring-member "ring" (ring item)) -(declare-function ring-ref "ring" (ring index)) -(declare-function ring-remove "ring" (ring &optional index)) - -(defvar-local erc--querypoll-ring nil) -(defvar-local erc--querypoll-timer nil) - -(defcustom erc-querypoll-exclude-regexp - (rx bot (or (: "*" (+ nonl)) (: (+ (in "A-Za-z")) "Serv")) eot) - "Pattern to skip polling for bots and services you regularly query." - :group 'erc - :package-version '(ERC . "5.6") - :type 'regexp) - -;;;###autoload(autoload 'erc-querypoll-mode "erc-goodies" nil t) -(define-erc-module querypoll nil - "Send periodic \"WHO\" requests for each query buffer. -Omit query participants who are currently present in some channel. -Instead of announcing arrivals and departures, rely on other modules, -like `nickbar', to provide UI feedback when changes occur. - -Once ERC implements the `monitor' extension, this module will serve as -an optional fallback for keeping query-participant rolls up to date on -servers that lack support or are stingy with their allotments. Until -such time, this module should be considered experimental. - -This is a local ERC module, so selectively polling only a subset of -query targets is possible but cumbersome. To do so, ensure -`erc-querypoll-mode' is enabled in the server buffer, and then toggle it -as appropriate in desired query buffers. To stop polling for the -current connection, toggle off the command \\[erc-querypoll-mode] from a -server buffer, or run \\`M-x C-u erc-querypoll-disable RET' from a -target buffer." - ((if erc--target - (if (erc-query-buffer-p) - (progn ; accommodate those who eschew `erc-modules' - (erc-with-server-buffer - (unless erc-querypoll-mode - (erc-querypoll-mode +1))) - (erc--querypoll-subscribe (current-buffer))) - (erc-querypoll-mode -1)) - (cl-assert (not erc--decouple-query-and-channel-membership-p)) - (setq-local erc--querypoll-ring (make-ring 5)) - (erc-with-all-buffers-of-server erc-server-process nil - (unless erc-querypoll-mode - (erc-querypoll-mode +1))))) - ((when erc--querypoll-timer - (cancel-timer erc--querypoll-timer)) - (if erc--target - (when-let (((erc-query-buffer-p)) - (ring (erc-with-server-buffer erc--querypoll-ring)) - (index (ring-member ring (current-buffer))) - ((not (erc--querypoll-target-in-chan-p (current-buffer))))) - (ring-remove ring index) - (unless (erc-current-nick-p (erc-target)) - (erc-remove-current-channel-member (erc-target)))) - (erc-with-all-buffers-of-server erc-server-process #'erc-query-buffer-p - (erc-querypoll-mode -1))) - (kill-local-variable 'erc--querypoll-ring) - (kill-local-variable 'erc--querypoll-timer)) - 'local) - -(cl-defmethod erc--queries-current-p (&context (erc-querypoll-mode (eql t))) t) - -(defvar erc-querypoll-period-params '(10 10 1) - "Parameters affecting the delay with respect to the number of buffers. -The elements represent some parameters of an exponential decay function, -a(e)^{-x/b}+c. The first number (a) affects the overall scaling. A -higher value means longer delays for all query buffers relative to queue -length. The second number (b) determines how quickly the delay -decreases as the queue length increases. Larger values make the delay -taper off more gradually. The last number (c) sets the minimum delay -between updates regardless of queue length.") - -(defun erc--querypoll-compute-period (queue-size) - "Calculate delay based on QUEUE-SIZE." - (let ((scale (nth 0 erc-querypoll-period-params)) - (rate (* 1.0 (nth 1 erc-querypoll-period-params))) - (min (nth 2 erc-querypoll-period-params))) - (+ (* scale (exp (/ (- queue-size) rate))) min))) - -(defun erc--querypoll-target-in-chan-p (buffer) - "Determine whether buffer's target, as a user, is joined to any channels." - (and-let* - ((target (erc--target-string (buffer-local-value 'erc--target buffer))) - (user (erc-get-server-user target)) - (buffers (erc-server-user-buffers user)) - ((seq-some #'erc-channel-p buffers))))) - -(defun erc--querypoll-get-length (ring) - "Return the effective length of RING, discounting chan members." - (let ((count 0)) - (dotimes (i (ring-length ring)) - (unless (erc--querypoll-target-in-chan-p (ring-ref ring i)) - (cl-incf count 1))) - count)) - -(defun erc--querypoll-get-next (ring) - (let ((n (ring-length ring))) - (catch 'found - (while (natnump (cl-decf n)) - (when-let ((buffer (ring-remove ring)) - ((buffer-live-p buffer))) - ;; Push back buffers for users joined to some chan. - (if (erc--querypoll-target-in-chan-p buffer) - (ring-insert ring buffer) - (throw 'found buffer))))))) - -(defun erc--querypoll-subscribe (query-buffer &optional penalty) - "Add QUERY-BUFFER to FIFO and ensure timer is running." - (when query-buffer - (cl-assert (erc-query-buffer-p query-buffer))) - (erc-with-server-buffer - (when (and query-buffer - (not (with-current-buffer query-buffer - (or (erc-current-nick-p (erc-target)) - (string-match erc-querypoll-exclude-regexp - (erc-target))))) - (not (ring-member erc--querypoll-ring query-buffer))) - (ring-insert+extend erc--querypoll-ring query-buffer)) - (unless erc--querypoll-timer - (setq erc--querypoll-timer - (let* ((length (erc--querypoll-get-length erc--querypoll-ring)) - (period (erc--querypoll-compute-period length))) - (run-at-time (+ (or penalty 0) period) - nil #'erc--querypoll-send (current-buffer))))))) - -(defun erc--querypoll-on-352 (target-nick args) - "Add or update `erc-server-users' data for TARGET-NICK from ARGS. -Then add user to participant rolls in any existing query buffers." - (pcase-let - ((`(,_ ,channel ,login ,host ,_server ,nick ,_flags, hop-real) args)) - (when (and (string= channel "*") (erc-nick-equal-p nick target-nick)) - (if-let ((user (erc-get-server-user nick))) - (erc-update-user user nick host login - (erc--extract-352-full-name hop-real)) - ;; Don't add unless target is already known. - (when (erc-get-buffer nick erc-server-process) - (erc-add-server-user - nick (make-erc-server-user - :nickname nick :login login :host host - :full-name (erc--extract-352-full-name hop-real))))) - (erc--ensure-query-member nick) - t))) - -;; This uses heuristics to associate replies to the initial request -;; because ERC does not yet support `labeled-response'. -(defun erc--querypoll-send (server-buffer) - "Send a captive \"WHO\" in SERVER-BUFFER." - (when (and (buffer-live-p server-buffer) - (buffer-local-value 'erc-server-connected server-buffer)) - (with-current-buffer server-buffer - (setq erc--querypoll-timer nil) - (if-let ((buffer (erc--querypoll-get-next erc--querypoll-ring))) - (letrec - ((target (erc--target-string - (buffer-local-value 'erc--target buffer))) - (penalty 0) - (here-fn (erc-once-with-server-event - "352" (lambda (_ parsed) - (erc--querypoll-on-352 - target (erc-response.command-args parsed))))) - (done-fn (erc-once-with-server-event - "315" - (lambda (_ parsed) - (if (memq here-fn erc-server-352-functions) - (erc-remove-user - (nth 1 (erc-response.command-args parsed))) - (remove-hook 'erc-server-352-functions here-fn t)) - (remove-hook 'erc-server-263-functions fail-fn t) - (remove-hook 'erc-server-315-functions done-fn t) - (erc--querypoll-subscribe buffer penalty) - t))) - (fail-fn (erc-once-with-server-event - "263" - (lambda (proc parsed) - (setq penalty 60) - (funcall done-fn proc parsed) - t)))) - (erc-server-send (concat "WHO " target))) - (unless (ring-empty-p erc--querypoll-ring) - (erc--querypoll-subscribe nil 30)))))) - (provide 'erc-goodies) ;;; erc-goodies.el ends here diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el index 45b0fb12c43..a32c8b46118 100644 --- a/lisp/erc/erc-notify.el +++ b/lisp/erc/erc-notify.el @@ -262,6 +262,202 @@ with args, toggle notify status of people." (notify-on . "Detected %n on IRC network %m") (notify-off . "%n has left IRC network %m")) + +;;;; Module `querypoll' + +;; This module is similar to `notify' in that it periodically tries to +;; discover whether certain users are online. Unlike that module, it's +;; not really configurable. Rather, it only selects users you've +;; corresponded with in a query buffer, and it keeps `erc-server-users' +;; entries for them updated. + +(declare-function ring-empty-p "ring" (ring)) +(declare-function ring-insert "ring" (ring item)) +(declare-function ring-insert+extend "ring" (ring item)) +(declare-function ring-length "ring" (ring)) +(declare-function ring-member "ring" (ring item)) +(declare-function ring-ref "ring" (ring index)) +(declare-function ring-remove "ring" (ring &optional index)) + +(defvar-local erc--querypoll-ring nil) +(defvar-local erc--querypoll-timer nil) + +(defcustom erc-querypoll-exclude-regexp + (rx bot (or (: "*" (+ nonl)) (: (+ (in "A-Za-z")) "Serv")) eot) + "Pattern to skip polling for bots and services you regularly query." + :group 'erc + :package-version '(ERC . "5.6") + :type 'regexp) + +;;;###autoload(autoload 'erc-querypoll-mode "erc-notify" nil t) +(define-erc-module querypoll nil + "Send periodic \"WHO\" requests for each query buffer. +Omit query participants who are currently present in some channel. +Instead of announcing arrivals and departures, rely on other modules, +like `nickbar', to provide UI feedback when changes occur. + +Once ERC implements the `monitor' extension, this module will serve as +an optional fallback for keeping query-participant rolls up to date on +servers that lack support or are stingy with their allotments. Until +such time, this module should be considered experimental. + +This is a local ERC module, so selectively polling only a subset of +query targets is possible but cumbersome. To do so, ensure +`erc-querypoll-mode' is enabled in the server buffer, and then toggle it +as appropriate in desired query buffers. To stop polling for the +current connection, toggle off the command \\[erc-querypoll-mode] from a +server buffer, or run \\`M-x C-u erc-querypoll-disable RET' from a +target buffer." + ((if erc--target + (if (erc-query-buffer-p) + (progn ; accommodate those who eschew `erc-modules' + (erc-with-server-buffer + (unless erc-querypoll-mode + (erc-querypoll-mode +1))) + (erc--querypoll-subscribe (current-buffer))) + (erc-querypoll-mode -1)) + (cl-assert (not erc--decouple-query-and-channel-membership-p)) + (setq-local erc--querypoll-ring (make-ring 5)) + (erc-with-all-buffers-of-server erc-server-process nil + (unless erc-querypoll-mode + (erc-querypoll-mode +1))))) + ((when erc--querypoll-timer + (cancel-timer erc--querypoll-timer)) + (if erc--target + (when-let (((erc-query-buffer-p)) + (ring (erc-with-server-buffer erc--querypoll-ring)) + (index (ring-member ring (current-buffer))) + ((not (erc--querypoll-target-in-chan-p (current-buffer))))) + (ring-remove ring index) + (unless (erc-current-nick-p (erc-target)) + (erc-remove-current-channel-member (erc-target)))) + (erc-with-all-buffers-of-server erc-server-process #'erc-query-buffer-p + (erc-querypoll-mode -1))) + (kill-local-variable 'erc--querypoll-ring) + (kill-local-variable 'erc--querypoll-timer)) + 'local) + +(cl-defmethod erc--queries-current-p (&context (erc-querypoll-mode (eql t))) t) + +(defvar erc-querypoll-period-params '(10 10 1) + "Parameters affecting the delay with respect to the number of buffers. +The elements represent some parameters of an exponential decay function, +a(e)^{-x/b}+c. The first number (a) affects the overall scaling. A +higher value means longer delays for all query buffers relative to queue +length. The second number (b) determines how quickly the delay +decreases as the queue length increases. Larger values make the delay +taper off more gradually. The last number (c) sets the minimum delay +between updates regardless of queue length.") + +(defun erc--querypoll-compute-period (queue-size) + "Calculate delay based on QUEUE-SIZE." + (let ((scale (nth 0 erc-querypoll-period-params)) + (rate (* 1.0 (nth 1 erc-querypoll-period-params))) + (min (nth 2 erc-querypoll-period-params))) + (+ (* scale (exp (/ (- queue-size) rate))) min))) + +(defun erc--querypoll-target-in-chan-p (buffer) + "Determine whether buffer's target, as a user, is joined to any channels." + (and-let* + ((target (erc--target-string (buffer-local-value 'erc--target buffer))) + (user (erc-get-server-user target)) + (buffers (erc-server-user-buffers user)) + ((seq-some #'erc-channel-p buffers))))) + +(defun erc--querypoll-get-length (ring) + "Return the effective length of RING, discounting chan members." + (let ((count 0)) + (dotimes (i (ring-length ring)) + (unless (erc--querypoll-target-in-chan-p (ring-ref ring i)) + (cl-incf count 1))) + count)) + +(defun erc--querypoll-get-next (ring) + (let ((n (ring-length ring))) + (catch 'found + (while (natnump (cl-decf n)) + (when-let ((buffer (ring-remove ring)) + ((buffer-live-p buffer))) + ;; Push back buffers for users joined to some chan. + (if (erc--querypoll-target-in-chan-p buffer) + (ring-insert ring buffer) + (throw 'found buffer))))))) + +(defun erc--querypoll-subscribe (query-buffer &optional penalty) + "Add QUERY-BUFFER to FIFO and ensure timer is running." + (when query-buffer + (cl-assert (erc-query-buffer-p query-buffer))) + (erc-with-server-buffer + (when (and query-buffer + (not (with-current-buffer query-buffer + (or (erc-current-nick-p (erc-target)) + (string-match erc-querypoll-exclude-regexp + (erc-target))))) + (not (ring-member erc--querypoll-ring query-buffer))) + (ring-insert+extend erc--querypoll-ring query-buffer)) + (unless erc--querypoll-timer + (setq erc--querypoll-timer + (let* ((length (erc--querypoll-get-length erc--querypoll-ring)) + (period (erc--querypoll-compute-period length))) + (run-at-time (+ (or penalty 0) period) + nil #'erc--querypoll-send (current-buffer))))))) + +(defun erc--querypoll-on-352 (target-nick args) + "Add or update `erc-server-users' data for TARGET-NICK from ARGS. +Then add user to participant rolls in any existing query buffers." + (pcase-let + ((`(,_ ,channel ,login ,host ,_server ,nick ,_flags, hop-real) args)) + (when (and (string= channel "*") (erc-nick-equal-p nick target-nick)) + (if-let ((user (erc-get-server-user nick))) + (erc-update-user user nick host login + (erc--extract-352-full-name hop-real)) + ;; Don't add unless target is already known. + (when (erc-get-buffer nick erc-server-process) + (erc-add-server-user + nick (make-erc-server-user + :nickname nick :login login :host host + :full-name (erc--extract-352-full-name hop-real))))) + (erc--ensure-query-member nick) + t))) + +;; This uses heuristics to associate replies to the initial request +;; because ERC does not yet support `labeled-response'. +(defun erc--querypoll-send (server-buffer) + "Send a captive \"WHO\" in SERVER-BUFFER." + (when (and (buffer-live-p server-buffer) + (buffer-local-value 'erc-server-connected server-buffer)) + (with-current-buffer server-buffer + (setq erc--querypoll-timer nil) + (if-let ((buffer (erc--querypoll-get-next erc--querypoll-ring))) + (letrec + ((target (erc--target-string + (buffer-local-value 'erc--target buffer))) + (penalty 0) + (here-fn (erc-once-with-server-event + "352" (lambda (_ parsed) + (erc--querypoll-on-352 + target (erc-response.command-args parsed))))) + (done-fn (erc-once-with-server-event + "315" + (lambda (_ parsed) + (if (memq here-fn erc-server-352-functions) + (erc-remove-user + (nth 1 (erc-response.command-args parsed))) + (remove-hook 'erc-server-352-functions here-fn t)) + (remove-hook 'erc-server-263-functions fail-fn t) + (remove-hook 'erc-server-315-functions done-fn t) + (erc--querypoll-subscribe buffer penalty) + t))) + (fail-fn (erc-once-with-server-event + "263" + (lambda (proc parsed) + (setq penalty 60) + (funcall done-fn proc parsed) + t)))) + (erc-server-send (concat "WHO " target))) + (unless (ring-empty-p erc--querypoll-ring) + (erc--querypoll-subscribe nil 30)))))) + (provide 'erc-notify) ;;; erc-notify.el ends here diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el index 1d74025c5ce..9a805fb05a6 100644 --- a/test/lisp/erc/erc-goodies-tests.el +++ b/test/lisp/erc/erc-goodies-tests.el @@ -614,61 +614,4 @@ (should (equal '(3 . 11) (erc--get-inserted-msg-bounds arg)))))) -;;;; querypoll - -(ert-deftest erc--querypoll-compute-period () - (should (equal (mapcar (lambda (i) - (/ (round (* 100 (erc--querypoll-compute-period i))) - 100.0)) - (number-sequence 0 10)) - '(11.0 10.05 9.19 8.41 7.7 7.07 6.49 5.97 5.49 5.07 4.68)))) - -(declare-function ring-insert "ring" (ring item)) - -(ert-deftest erc--querypoll-target-in-chan-p () - (erc-tests-common-make-server-buf) - (with-current-buffer (erc--open-target "#chan") - (erc-update-current-channel-member "bob" "bob" 'addp)) - - (with-current-buffer (erc--open-target "bob") - (should (erc--querypoll-target-in-chan-p (current-buffer)))) - - (with-current-buffer (erc--open-target "alice") - (should-not (erc--querypoll-target-in-chan-p (current-buffer)))) - - (when noninteractive - (erc-tests-common-kill-buffers))) - -(ert-deftest erc--querypoll-get-length () - (erc-tests-common-make-server-buf) - (with-current-buffer (erc--open-target "#chan") - (erc-update-current-channel-member "bob" "bob" 'addp)) - - (let ((ring (make-ring 5))) - (ring-insert ring (with-current-buffer (erc--open-target "bob"))) - (should (= 0 (erc--querypoll-get-length ring))) - (ring-insert ring (with-current-buffer (erc--open-target "alice"))) - (should (= 1 (erc--querypoll-get-length ring)))) - - (when noninteractive - (erc-tests-common-kill-buffers))) - -(ert-deftest erc--querypoll-get-next () - (erc-tests-common-make-server-buf) - (with-current-buffer (erc--open-target "#chan") - (erc-update-current-channel-member "bob" "bob" 'addp) - (erc-update-current-channel-member "alice" "alice" 'addp)) - - (let ((ring (make-ring 5))) - (ring-insert ring (with-current-buffer (erc--open-target "bob"))) - (ring-insert ring (with-current-buffer (erc--open-target "dummy"))) - (ring-insert ring (with-current-buffer (erc--open-target "alice"))) - (ring-insert ring (with-current-buffer (erc--open-target "tester"))) - (kill-buffer (get-buffer "dummy")) - - (should (eq (get-buffer "tester") (erc--querypoll-get-next ring)))) - - (when noninteractive - (erc-tests-common-kill-buffers))) - ;;; erc-goodies-tests.el ends here diff --git a/test/lisp/erc/erc-notify-tests.el b/test/lisp/erc/erc-notify-tests.el new file mode 100644 index 00000000000..f8dafb0ea19 --- /dev/null +++ b/test/lisp/erc/erc-notify-tests.el @@ -0,0 +1,87 @@ +;;; erc-notify-tests.el --- Tests for erc-notify -*- 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 . + +;;; Commentary: +;;; Code: +(require 'erc-notify) + +(require 'ert-x) +(eval-and-compile + (let ((load-path (cons (ert-resource-directory) load-path))) + (require 'erc-tests-common))) + + +;;;; Module `querypoll' + +(ert-deftest erc--querypoll-compute-period () + (should (equal (mapcar (lambda (i) + (/ (round (* 100 (erc--querypoll-compute-period i))) + 100.0)) + (number-sequence 0 10)) + '(11.0 10.05 9.19 8.41 7.7 7.07 6.49 5.97 5.49 5.07 4.68)))) + +(declare-function ring-insert "ring" (ring item)) + +(ert-deftest erc--querypoll-target-in-chan-p () + (erc-tests-common-make-server-buf) + (with-current-buffer (erc--open-target "#chan") + (erc-update-current-channel-member "bob" "bob" 'addp)) + + (with-current-buffer (erc--open-target "bob") + (should (erc--querypoll-target-in-chan-p (current-buffer)))) + + (with-current-buffer (erc--open-target "alice") + (should-not (erc--querypoll-target-in-chan-p (current-buffer)))) + + (when noninteractive + (erc-tests-common-kill-buffers))) + +(ert-deftest erc--querypoll-get-length () + (erc-tests-common-make-server-buf) + (with-current-buffer (erc--open-target "#chan") + (erc-update-current-channel-member "bob" "bob" 'addp)) + + (let ((ring (make-ring 5))) + (ring-insert ring (with-current-buffer (erc--open-target "bob"))) + (should (= 0 (erc--querypoll-get-length ring))) + (ring-insert ring (with-current-buffer (erc--open-target "alice"))) + (should (= 1 (erc--querypoll-get-length ring)))) + + (when noninteractive + (erc-tests-common-kill-buffers))) + +(ert-deftest erc--querypoll-get-next () + (erc-tests-common-make-server-buf) + (with-current-buffer (erc--open-target "#chan") + (erc-update-current-channel-member "bob" "bob" 'addp) + (erc-update-current-channel-member "alice" "alice" 'addp)) + + (let ((ring (make-ring 5))) + (ring-insert ring (with-current-buffer (erc--open-target "bob"))) + (ring-insert ring (with-current-buffer (erc--open-target "dummy"))) + (ring-insert ring (with-current-buffer (erc--open-target "alice"))) + (ring-insert ring (with-current-buffer (erc--open-target "tester"))) + (kill-buffer (get-buffer "dummy")) + + (should (eq (get-buffer "tester") (erc--querypoll-get-next ring)))) + + (when noninteractive + (erc-tests-common-kill-buffers))) + +;;; erc-notify-tests.el ends here