;;; erc-join-tests.el --- Tests for erc-join. -*- lexical-binding:t -*- ;; Copyright (C) 2020-2022 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 . ;;; Code: (require 'ert-x) (require 'erc-join) (require 'erc-networks) (ert-deftest erc-autojoin-channels--connect () (should (eq erc-autojoin-timing 'connect)) (should (= erc-autojoin-delay 30)) (should-not erc--autojoin-timer) (let (calls common erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) (cl-letf (((symbol-function 'erc-server-send) (lambda (line) (push line calls)))) (setq common (lambda () (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-network 'FooNet erc-session-server "irc.gnu.chat" erc-server-current-nick "tester" erc-networks--id (erc-networks--id-create nil) erc-server-announced-name "foo.gnu.chat") (set-process-query-on-exit-flag erc-server-process nil) (erc-autojoin-channels erc-server-announced-name "tester") (should-not erc--autojoin-timer)))) (ert-info ("Join immediately on connect; server") (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan"))) (ert-info ("Join immediately on connect; network") (let ((erc-autojoin-channels-alist '((FooNet "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan"))) (ert-info ("Do nothing; server") (let ((erc-autojoin-channels-alist '(("bar\\.gnu\\.chat" "#chan")))) (funcall common)) (should-not calls)) (ert-info ("Do nothing; network") (let ((erc-autojoin-channels-alist '((BarNet "#chan")))) (funcall common)) (should-not calls))))) (ert-deftest erc-autojoin-channels--delay () (should (eq erc-autojoin-timing 'connect)) (should (= erc-autojoin-delay 30)) (should-not erc--autojoin-timer) (let (calls common erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook (erc-autojoin-timing 'ident) (erc-autojoin-delay 0.05)) (cl-letf (((symbol-function 'erc-server-send) (lambda (line) (push line calls))) ((symbol-function 'erc-autojoin-after-ident) (lambda (&rest _r) (error "I ran but shouldn't have")))) (setq common (lambda () (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-network 'FooNet erc-session-server "irc.gnu.chat" erc-server-current-nick "tester" erc-networks--id (erc-networks--id-create nil) erc-server-announced-name "foo.gnu.chat") (set-process-query-on-exit-flag erc-server-process nil) (should-not erc--autojoin-timer) (erc-autojoin-channels erc-server-announced-name "tester") (should erc--autojoin-timer) (should-not calls) (sleep-for 0.1)))) (ert-info ("Deferred on connect; server") (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan"))) (ert-info ("Deferred on connect; network") (let ((erc-autojoin-channels-alist '((FooNet "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan"))) (ert-info ("Do nothing; server") (let ((erc-autojoin-channels-alist '(("bar\\.gnu\\.chat" "#chan")))) (funcall common)) (should-not calls))))) (ert-deftest erc-autojoin-channels--ident () (should (eq erc-autojoin-timing 'connect)) (should (= erc-autojoin-delay 30)) (should-not erc--autojoin-timer) (let (calls common erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook (erc-autojoin-timing 'ident)) (cl-letf (((symbol-function 'erc-server-send) (lambda (line) (push line calls)))) (setq common (lambda () (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-network 'FooNet erc-server-current-nick "tester" erc-networks--id (erc-networks--id-create nil) erc-server-announced-name "foo.gnu.chat") (set-process-query-on-exit-flag erc-server-process nil) (erc-autojoin-after-ident 'FooNet "tester") (should-not erc--autojoin-timer)))) (ert-info ("Join on NickServ hook; server") (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan"))) (ert-info ("Join on NickServ hook; network") (let ((erc-autojoin-channels-alist '((FooNet "#chan")))) (funcall common)) (should (equal (pop calls) "JOIN #chan")))))) (defun erc-join-tests--autojoin-add--common (setup &optional fwd) (let (calls erc-autojoin-channels-alist erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) (cl-letf (((symbol-function 'erc-handle-parsed-server-response) (lambda (_p m) (push m calls)))) (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-server-current-nick "tester" erc--isupport-params (make-hash-table) erc-server-announced-name "foo.gnu.chat") (puthash 'CHANTYPES '("&#") erc--isupport-params) (funcall setup) (set-process-query-on-exit-flag erc-server-process nil) (should-not calls) (ert-info ("Add #chan") (erc-parse-server-response erc-server-process (concat ":tester!~i@c.u JOIN #chan" (and fwd " * :Tes Ter"))) (should calls) (erc-autojoin-add erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#chan"))))) (ert-info ("More recently joined chans are prepended") (erc-parse-server-response erc-server-process ; with account username (concat ":tester!~i@c.u JOIN #spam" (and fwd " tester :Tes Ter"))) (should calls) (erc-autojoin-add erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#spam" "#chan"))))) (ert-info ("Duplicates skipped") (erc-parse-server-response erc-server-process (concat ":tester!~i@c.u JOIN #chan" (and fwd " * :Tes Ter"))) (should calls) (erc-autojoin-add erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#spam" "#chan"))))) (ert-info ("Server used for local channel") (erc-parse-server-response erc-server-process (concat ":tester!~i@c.u JOIN &local" (and fwd " * :Tes Ter"))) (should calls) (erc-autojoin-add erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '(("foo\\.gnu\\.chat" "&local") (FooNet "#spam" "#chan"))))))))) (ert-deftest erc-autojoin-add--network () (erc-join-tests--autojoin-add--common (lambda () (setq erc-network 'FooNet erc-networks--id (erc-networks--id-create nil))))) (ert-deftest erc-autojoin-add--network-extended-syntax () (erc-join-tests--autojoin-add--common (lambda () (setq erc-network 'FooNet erc-networks--id (erc-networks--id-create nil))) 'forward-compatible)) (ert-deftest erc-autojoin-add--network-id () (erc-join-tests--autojoin-add--common (lambda () (setq erc-network 'invalid erc-networks--id (erc-networks--id-create 'FooNet))))) (ert-deftest erc-autojoin-add--server () (let (calls erc-autojoin-channels-alist erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) (cl-letf (((symbol-function 'erc-handle-parsed-server-response) (lambda (_p m) (push m calls)))) (ert-info ("Network unavailable, announced name used") (setq erc-autojoin-channels-alist nil) (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-server-current-nick "tester" erc-server-announced-name "foo.gnu.chat" erc-networks--id (make-erc-networks--id)) ; assume too early (set-process-query-on-exit-flag erc-server-process nil) (should-not calls) (erc-parse-server-response erc-server-process ":tester!~u@q6ddatxcq6txy.irc JOIN #chan") (should calls) (erc-autojoin-add erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '(("gnu.chat" "#chan"))))))))) (defun erc-join-tests--autojoin-remove--common (setup) (let (calls erc-autojoin-channels-alist erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) (cl-letf (((symbol-function 'erc-handle-parsed-server-response) (lambda (_p m) (push m calls)))) (setq erc-autojoin-channels-alist ; mutated, so can't quote whole thing (list '(FooNet "#spam" "##chan") '(BarNet "#bar" "##bar") '("foo\\.gnu\\.chat" "&local"))) (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-server-current-nick "tester" erc--isupport-params (make-hash-table) erc-server-announced-name "foo.gnu.chat") (puthash 'CHANTYPES '("&#") erc--isupport-params) (funcall setup) (set-process-query-on-exit-flag erc-server-process nil) (should-not calls) (ert-info ("Remove #chan") (erc-parse-server-response erc-server-process ":tester!~i@c.u PART ##chan") (should calls) (erc-autojoin-remove erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#spam") (BarNet "#bar" "##bar") ("foo\\.gnu\\.chat" "&local"))))) (ert-info ("Wrong network, nothing done") (erc-parse-server-response erc-server-process ":tester!~i@c.u PART #bar") (should calls) (erc-autojoin-remove erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#spam") (BarNet "#bar" "##bar") ("foo\\.gnu\\.chat" "&local"))))) (ert-info ("Local channel keyed by server found") (erc-parse-server-response erc-server-process ":tester!~i@c.u PART &local") (should calls) (erc-autojoin-remove erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '((FooNet "#spam") (BarNet "#bar" "##bar"))))))))) (ert-deftest erc-autojoin-remove--network () (erc-join-tests--autojoin-remove--common (lambda () (setq erc-network 'FooNet erc-networks--id (erc-networks--id-create nil))))) (ert-deftest erc-autojoin-remove--network-id () (erc-join-tests--autojoin-remove--common (lambda () (setq erc-network 'fake-a-roo erc-networks--id (erc-networks--id-create 'FooNet))))) (ert-deftest erc-autojoin-remove--server () (let (calls erc-autojoin-channels-alist erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) (cl-letf (((symbol-function 'erc-handle-parsed-server-response) (lambda (_p m) (push m calls)))) (setq erc-autojoin-channels-alist (list '("gnu.chat" "#spam" "##chan") '("fsf.chat" "#bar" "##bar"))) (ert-with-test-buffer (:name "foonet") (erc-mode) (setq erc-server-process (start-process "true" (current-buffer) "true") erc-server-current-nick "tester" erc-server-announced-name "foo.gnu.chat" ;; Assume special case w/o known network erc-networks--id (make-erc-networks--id)) (set-process-query-on-exit-flag erc-server-process nil) (should-not calls) (ert-info ("Announced name matched, #chan removed") (erc-parse-server-response erc-server-process ":tester!~i@c.u PART ##chan") (should calls) (erc-autojoin-remove erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '(("gnu.chat" "#spam") ("fsf.chat" "#bar" "##bar"))))) (ert-info ("Wrong announced name, nothing done") (erc-parse-server-response erc-server-process ":tester!~i@c.u PART #bar") (should calls) (erc-autojoin-remove erc-server-process (pop calls)) (should (equal erc-autojoin-channels-alist '(("gnu.chat" "#spam") ("fsf.chat" "#bar" "##bar"))))))))) ;;; erc-join-tests.el ends here