1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-19 13:24:44 -07:00
emacs/test/lisp/subr-tests.el
Basil L. Contovounesios 9da2efb670 Audit some plist uses with new predicate argument
* doc/lispref/lists.texi (Plist Access): Improve description of
default predicate.
* lisp/emacs-lisp/cl-extra.el (cl-getf, cl--set-getf): Assume
plist-member always returns a cons.
* lisp/emacs-lisp/gv.el (plist-get): Support new optional predicate
argument (bug#47425#91).
* lisp/emacs-lisp/map.el: Bump minor version.
(map--dispatch): Remove now that bug#58563 is fixed.  Break two
remaining uses out into corresponding cl-defmethods.
(map--plist-p): Add docstring.
(map--plist-has-predicate, map--plist-member-1, map--plist-member)
(map--plist-put-1, map--plist-put): New definitions for supporting
predicate argument backward compatibly.
(map-elt): Fix generalized variable getter under a
predicate (bug#58531).  Use predicate when given a plist.
(map-put): Avoid gratuitous warnings when called without the hidden
predicate argument.  Improve obsoletion message.
(map-put!): Use predicate when given a plist.
(map-contains-key): Ditto.  Declare forgotten
advertised-calling-convention (bug#58531#19).
(map--put): Group definition in file together with that of map-put!.
* lisp/files-x.el (connection-local-normalize-criteria): Simplify
using mapcan + plist-get.
* lisp/net/eudc.el (eudc--plist-member): New convenience function.
(eudc-plist-member, eudc-plist-get, eudc-lax-plist-get): Use it
instead of open-coding plist-member.
* src/fns.c (Fplist_get, plist_get, Fplist_put, plist_put): Pass the
plist element as the first argument to the predicate, for
consistency with assoc + alist-get.
(Fplist_member, plist_member): Move from widget to plist section.
Open-code the EQ case in plist_member, and call it from
Fplist_member in that case, rather than the other way around.

* test/lisp/apropos-tests.el (apropos-tests-format-plist): Avoid
polluting obarray.
* test/lisp/emacs-lisp/cl-extra-tests.el (cl-getf): Extend test with
generalized variables, degenerate plists, and improper lists.
* test/lisp/emacs-lisp/gv-tests.el: Byte-compile file; in the
meantime bug#24402 seems to have been fixed or worked around.
(gv-setter-edebug): Inhibit printing messages.
(gv-plist-get): Avoid modifying constant literals.  Also test with a
predicate argument.
* test/lisp/emacs-lisp/map-tests.el (with-maps-do): Simplify
docstring.
(test-map-elt-testfn): Rename...
(test-map-elt-testfn-alist): ...to this.  Also test with a predicate
argument.
(test-map-elt-testfn-plist, test-map-elt-gv, test-map-elt-signature)
(test-map-put!-plist, test-map-put!-signature)
(test-map-contains-key-signature, test-map-plist-member)
(test-map-plist-put): New tests.
(test-map-contains-key-testfn): Also test with a predicate argument.
(test-map-setf-alist-overwrite-key, test-map-setf-plist-insert-key)
(test-map-setf-plist-overwrite-key): Avoid modifying constant
literals.
(test-hash-table-setf-insert-key)
(test-hash-table-setf-overwrite-key): Fix indentation.
(test-setf-map-with-function): Make test more precise.
* test/lisp/net/eudc-tests.el: New file.
* test/lisp/subr-tests.el (test-plistp): Extend test with circular
list.
* test/src/fns-tests.el (test-cycle-equal, test-cycle-nconc): Move
from plist section to circular list section.
(plist-put/odd-number-of-elements): Avoid modifying constant
literals.
(plist-member/improper-list): Simplify.
(test-plist): Move to plist section.  Also test with a predicate
argument.
2022-10-22 19:33:12 +03:00

1173 lines
44 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; subr-tests.el --- Tests for subr.el -*- lexical-binding:t -*-
;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
;; Author: Oleh Krehel <ohwoeowho@gmail.com>,
;; Nicolas Petton <nicolas@petton.fr>
;; Keywords:
;; 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/>.
;;; Commentary:
;;
;;; Code:
(require 'ert)
(eval-when-compile (require 'cl-lib))
(ert-deftest let-when-compile ()
;; good case
(should (equal (macroexpand '(let-when-compile ((foo (+ 2 3)))
(setq bar (eval-when-compile (+ foo foo)))
(setq boo (eval-when-compile (* foo foo)))))
'(progn
(setq bar (quote 10))
(setq boo (quote 25)))))
;; bad case: `eval-when-compile' omitted, byte compiler should catch this
(should (equal (macroexpand
'(let-when-compile ((foo (+ 2 3)))
(setq bar (+ foo foo))
(setq boo (eval-when-compile (* foo foo)))))
'(progn
(setq bar (+ foo foo))
(setq boo (quote 25)))))
;; something practical
(should (equal (macroexpand
'(let-when-compile ((keywords '("true" "false")))
(font-lock-add-keywords
'c++-mode
`((,(eval-when-compile
(format "\\<%s\\>" (regexp-opt keywords)))
0 font-lock-keyword-face)))))
'(font-lock-add-keywords
(quote c++-mode)
(list
(cons (quote
"\\<\\(?:\\(?:fals\\|tru\\)e\\)\\>")
(quote
(0 font-lock-keyword-face))))))))
;;;; List functions.
(ert-deftest subr-test-caaar ()
(should (null (caaar '())))
(should (null (caaar '(() (2)))))
(should (null (caaar '((() (2)) (a b)))))
(should-error (caaar '(1 2)) :type 'wrong-type-argument)
(should-error (caaar '((1 2))) :type 'wrong-type-argument)
(should (= 1 (caaar '(((1 2) (3 4))))))
(should (null (caaar '((() (3 4)))))))
(ert-deftest subr-test-caadr ()
(should (null (caadr '())))
(should (null (caadr '(1))))
(should-error (caadr '(1 2)) :type 'wrong-type-argument)
(should (= 2 (caadr '(1 (2 3)))))
(should (equal '((2) (3)) (caadr '((1) (((2) (3))) (4))))))
;;;; Keymap support.
(ert-deftest subr-test-kbd ()
(should (equal (kbd "") ""))
(should (equal (kbd "f") "f"))
(should (equal (kbd "X") "X"))
(should (equal (kbd "foobar") "foobar")) ; 6 characters
(should (equal (kbd "return") "return")) ; 6 characters
(should (equal (kbd "<F2>") [F2]))
(should (equal (kbd "<f1> <f2> TAB") [f1 f2 ?\t]))
(should (equal (kbd "<f1> RET") [f1 ?\r]))
(should (equal (kbd "<f1> SPC") [f1 ? ]))
(should (equal (kbd "<f1>") [f1]))
(should (equal (kbd "<f1>") [f1]))
(should (equal (kbd "[f1]") "[f1]"))
(should (equal (kbd "<return>") [return]))
(should (equal (kbd "< right >") "<right>")) ; 7 characters
;; Modifiers:
(should (equal (kbd "C-x") "\C-x"))
(should (equal (kbd "C-x a") "\C-xa"))
(should (equal (kbd "C-;") [?\C-\;]))
(should (equal (kbd "C-a") "\C-a"))
(should (equal (kbd "C-c SPC") "\C-c "))
(should (equal (kbd "C-c TAB") "\C-c\t"))
(should (equal (kbd "C-c c") "\C-cc"))
(should (equal (kbd "C-x 4 C-f") "\C-x4\C-f"))
(should (equal (kbd "C-x C-f") "\C-x\C-f"))
(should (equal (kbd "C-M-<down>") [C-M-down]))
(should (equal (kbd "<C-M-down>") [C-M-down]))
(should (equal (kbd "C-RET") [?\C-\r]))
(should (equal (kbd "C-SPC") [?\C- ]))
(should (equal (kbd "C-TAB") [?\C-\t]))
(should (equal (kbd "C-<down>") [C-down]))
(should (equal (kbd "C-c C-c C-c") "\C-c\C-c\C-c"))
(should (equal (kbd "M-a") [?\M-a]))
(should (equal (kbd "M-<DEL>") [?\M-\d]))
(should (equal (kbd "M-C-a") [?\M-\C-a]))
(should (equal (kbd "M-ESC") [?\M-\e]))
(should (equal (kbd "M-RET") [?\M-\r]))
(should (equal (kbd "M-SPC") [?\M- ]))
(should (equal (kbd "M-TAB") [?\M-\t]))
(should (equal (kbd "M-x a") [?\M-x ?a]))
(should (equal (kbd "M-<up>") [M-up]))
(should (equal (kbd "M-c M-c M-c") [?\M-c ?\M-c ?\M-c]))
(should (equal (kbd "s-SPC") [?\s- ]))
(should (equal (kbd "s-a") [?\s-a]))
(should (equal (kbd "s-x a") [?\s-x ?a]))
(should (equal (kbd "s-c s-c s-c") [?\s-c ?\s-c ?\s-c]))
(should (equal (kbd "S-H-a") [?\S-\H-a]))
(should (equal (kbd "S-a") [?\S-a]))
(should (equal (kbd "S-x a") [?\S-x ?a]))
(should (equal (kbd "S-c S-c S-c") [?\S-c ?\S-c ?\S-c]))
(should (equal (kbd "H-<RET>") [?\H-\r]))
(should (equal (kbd "H-DEL") [?\H-\d]))
(should (equal (kbd "H-a") [?\H-a]))
(should (equal (kbd "H-x a") [?\H-x ?a]))
(should (equal (kbd "H-c H-c H-c") [?\H-c ?\H-c ?\H-c]))
(should (equal (kbd "A-H-a") [?\A-\H-a]))
(should (equal (kbd "A-SPC") [?\A- ]))
(should (equal (kbd "A-TAB") [?\A-\t]))
(should (equal (kbd "A-a") [?\A-a]))
(should (equal (kbd "A-c A-c A-c") [?\A-c ?\A-c ?\A-c]))
(should (equal (kbd "C-M-a") [?\C-\M-a]))
(should (equal (kbd "C-M-<up>") [C-M-up]))
;; Special characters.
(should (equal (kbd "DEL") "\d"))
(should (equal (kbd "ESC C-a") "\e\C-a"))
(should (equal (kbd "ESC") "\e"))
(should (equal (kbd "LFD") "\n"))
(should (equal (kbd "NUL") "\0"))
(should (equal (kbd "RET") "\C-m"))
(should (equal (kbd "SPC") "\s"))
(should (equal (kbd "TAB") "\t"))
(should (equal (kbd "\^i") ""))
(should (equal (kbd "^M") "\^M"))
;; With numbers.
(should (equal (kbd "\177") "\^?"))
(should (equal (kbd "\000") "\0"))
(should (equal (kbd "\\177") "\^?"))
(should (equal (kbd "\\000") "\0"))
(should (equal (kbd "C-x \\150") "\C-xh"))
;; Multibyte
(should (equal (kbd "ñ") []))
(should (equal (kbd "ü") []))
(should (equal (kbd "ö") []))
(should (equal (kbd "ğ") []))
(should (equal (kbd "ա") [?ա]))
(should (equal (kbd "üüöö") [ ]))
(should (equal (kbd "C-ü") [?\C]))
(should (equal (kbd "M-ü") [?\M]))
(should (equal (kbd "H-ü") [?\H]))
;; Handle both new and old style key descriptions (bug#45536).
(should (equal (kbd "s-<return>") [s-return]))
(should (equal (kbd "<s-return>") [s-return]))
(should (equal (kbd "C-M-<return>") [C-M-return]))
(should (equal (kbd "<C-M-return>") [C-M-return]))
;; Error.
(should-error (kbd "C-xx"))
(should-error (kbd "M-xx"))
(should-error (kbd "M-x<TAB>"))
;; These should be equivalent:
(should (equal (kbd "\C-xf") (kbd "C-x f"))))
(ert-deftest subr-test-key-valid-p ()
(should (not (key-valid-p "")))
(should (key-valid-p "f"))
(should (key-valid-p "X"))
(should (not (key-valid-p " X")))
(should (key-valid-p "X f"))
(should (not (key-valid-p "a b")))
(should (not (key-valid-p "foobar")))
(should (not (key-valid-p "return")))
(should (key-valid-p "<F2>"))
(should (key-valid-p "<f1> <f2> TAB"))
(should (key-valid-p "<f1> RET"))
(should (key-valid-p "<f1> SPC"))
(should (key-valid-p "<f1>"))
(should (not (key-valid-p "[f1]")))
(should (key-valid-p "<return>"))
(should (not (key-valid-p "< right >")))
;; Modifiers:
(should (key-valid-p "C-x"))
(should (key-valid-p "C-x a"))
(should (key-valid-p "C-;"))
(should (key-valid-p "C-a"))
(should (key-valid-p "C-c SPC"))
(should (key-valid-p "C-c TAB"))
(should (key-valid-p "C-c c"))
(should (key-valid-p "C-x 4 C-f"))
(should (key-valid-p "C-x C-f"))
(should (key-valid-p "C-M-<down>"))
(should (not (key-valid-p "<C-M-down>")))
(should (key-valid-p "C-RET"))
(should (key-valid-p "C-SPC"))
(should (key-valid-p "C-TAB"))
(should (key-valid-p "C-<down>"))
(should (key-valid-p "C-c C-c C-c"))
(should (key-valid-p "M-a"))
(should (key-valid-p "M-<DEL>"))
(should (not (key-valid-p "M-C-a")))
(should (key-valid-p "C-M-a"))
(should (key-valid-p "M-ESC"))
(should (key-valid-p "M-RET"))
(should (key-valid-p "M-SPC"))
(should (key-valid-p "M-TAB"))
(should (key-valid-p "M-x a"))
(should (key-valid-p "M-<up>"))
(should (key-valid-p "M-c M-c M-c"))
(should (key-valid-p "s-SPC"))
(should (key-valid-p "s-a"))
(should (key-valid-p "s-x a"))
(should (key-valid-p "s-c s-c s-c"))
(should (not (key-valid-p "S-H-a")))
(should (key-valid-p "S-a"))
(should (key-valid-p "S-x a"))
(should (key-valid-p "S-c S-c S-c"))
(should (key-valid-p "H-<RET>"))
(should (key-valid-p "H-DEL"))
(should (key-valid-p "H-a"))
(should (key-valid-p "H-x a"))
(should (key-valid-p "H-c H-c H-c"))
(should (key-valid-p "A-H-a"))
(should (key-valid-p "A-SPC"))
(should (key-valid-p "A-TAB"))
(should (key-valid-p "A-a"))
(should (key-valid-p "A-c A-c A-c"))
(should (key-valid-p "C-M-a"))
(should (key-valid-p "C-M-<up>"))
;; Special characters.
(should (key-valid-p "DEL"))
(should (key-valid-p "ESC C-a"))
(should (key-valid-p "ESC"))
(should (key-valid-p "LFD"))
(should (key-valid-p "NUL"))
(should (key-valid-p "RET"))
(should (key-valid-p "SPC"))
(should (key-valid-p "TAB"))
(should (not (key-valid-p "\^i")))
(should (not (key-valid-p "^M")))
;; With numbers.
(should (not (key-valid-p "\177")))
(should (not (key-valid-p "\000")))
(should (not (key-valid-p "\\177")))
(should (not (key-valid-p "\\000")))
(should (not (key-valid-p "C-x \\150")))
;; Multibyte
(should (key-valid-p "ñ"))
(should (key-valid-p "ü"))
(should (key-valid-p "ö"))
(should (key-valid-p "ğ"))
(should (key-valid-p "ա"))
(should (not (key-valid-p "üüöö")))
(should (key-valid-p "C-ü"))
(should (key-valid-p "M-ü"))
(should (key-valid-p "H-ü"))
;; Handle both new and old style key descriptions (bug#45536).
(should (key-valid-p "s-<return>"))
(should (not (key-valid-p "<s-return>")))
(should (key-valid-p "C-M-<return>"))
(should (not (key-valid-p "<C-M-return>")))
(should (key-valid-p "<mouse-1>"))
(should (key-valid-p "<Scroll_Lock>"))
(should (not (key-valid-p "c-x")))
(should (not (key-valid-p "C-xx")))
(should (not (key-valid-p "M-xx")))
(should (not (key-valid-p "M-x<TAB>"))))
(ert-deftest subr-test-define-prefix-command ()
(define-prefix-command 'foo-prefix-map)
(defvar foo-prefix-map)
(declare-function foo-prefix-map "subr-tests")
(should (keymapp foo-prefix-map))
(should (fboundp #'foo-prefix-map))
;; With optional argument.
(define-prefix-command 'bar-prefix 'bar-prefix-map)
(defvar bar-prefix-map)
(declare-function bar-prefix "subr-tests")
(should (keymapp bar-prefix-map))
(should (fboundp #'bar-prefix))
;; Returns the symbol.
(should (eq (define-prefix-command 'foo-bar) 'foo-bar)))
(ert-deftest subr-test-local-key-binding ()
(with-temp-buffer
(emacs-lisp-mode)
(should (keymapp (local-key-binding [menu-bar])))
(should-not (local-key-binding [f12]))))
(ert-deftest subr-test-global-key-binding ()
(should (eq (global-key-binding [f1]) 'help-command))
(should (eq (global-key-binding "x") 'self-insert-command))
(should-not (global-key-binding [f12])))
;;;; Mode hooks.
(defalias 'subr-tests--parent-mode
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
(ert-deftest provided-mode-derived-p ()
;; base case: `derived-mode' directly derives `prog-mode'
(should (progn
(define-derived-mode derived-mode prog-mode "test")
(provided-mode-derived-p 'derived-mode 'prog-mode)))
;; edge case: `derived-mode' derives an alias of `prog-mode'
(should (progn
(define-derived-mode derived-mode subr-tests--parent-mode "test")
(provided-mode-derived-p 'derived-mode 'prog-mode))))
(ert-deftest number-sequence-test ()
(should (= (length
(number-sequence (1- most-positive-fixnum) most-positive-fixnum))
2))
(should (= (length
(number-sequence
(1+ most-negative-fixnum) most-negative-fixnum -1))
2)))
(ert-deftest string-comparison-test ()
(should (string-equal-ignore-case "abc" "abc"))
(should (string-equal-ignore-case "abc" "ABC"))
(should (string-equal-ignore-case "abc" "abC"))
(should-not (string-equal-ignore-case "abc" "abCD"))
(should (string-equal-ignore-case "S" "s"))
(should (string-equal-ignore-case "" "ß"))
(should (string-equal-ignore-case "Dz" "DZ"))
(should (string-equal-ignore-case "Όσος" "ΌΣΟΣ"))
;; not yet: (should (string-equal-ignore-case "SS" "ß"))
;; not yet: (should (string-equal-ignore-case "SS" "ẞ"))
(should (string-lessp "abc" "acb"))
(should (string-lessp "aBc" "abc"))
(should (string-lessp "abc" "abcd"))
(should (string-lessp "abc" "abcd"))
(should-not (string-lessp "abc" "abc"))
(should-not (string-lessp "" ""))
(should (string-greaterp "acb" "abc"))
(should (string-greaterp "abc" "aBc"))
(should (string-greaterp "abcd" "abc"))
(should (string-greaterp "abcd" "abc"))
(should-not (string-greaterp "abc" "abc"))
(should-not (string-greaterp "" ""))
;; Symbols are also accepted
(should (string-lessp 'abc 'acb))
(should (string-lessp "abc" 'acb))
(should (string-greaterp 'acb 'abc))
(should (string-greaterp "acb" 'abc)))
(ert-deftest subr-test-when ()
(should (equal (when t 1) 1))
(should (equal (when t 2) 2))
(should (equal (when nil 1) nil))
(should (equal (when nil 2) nil))
(should (equal (when t 'x 1) 1))
(should (equal (when t 'x 2) 2))
(should (equal (when nil 'x 1) nil))
(should (equal (when nil 'x 2) nil))
(let ((x 1))
(should-not (when nil
(setq x (1+ x))
x))
(should (= x 1))
(should (= 2 (when t
(setq x (1+ x))
x)))
(should (= x 2)))
(should (equal (macroexpand-all '(when a b c d))
'(if a (progn b c d)))))
(ert-deftest subr-test-xor ()
"Test `xor'."
(should-not (xor nil nil))
(should (eq (xor nil 'true) 'true))
(should (eq (xor 'true nil) 'true))
(should-not (xor t t)))
(ert-deftest subr-test-version-parsing ()
(should (equal (version-to-list ".5") '(0 5)))
(should (equal (version-to-list "0.9 alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0.9 snapshot") '(0 9 -4)))
(should (equal (version-to-list "0.9-alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0.9-snapshot") '(0 9 -4)))
(should (equal (version-to-list "0.9.snapshot") '(0 9 -4)))
(should (equal (version-to-list "0.9_snapshot") '(0 9 -4)))
(should (equal (version-to-list "0.9alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0.9snapshot") '(0 9 -4)))
(should (equal (version-to-list "1.0 git") '(1 0 -4)))
(should (equal (version-to-list "1.0 pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1.0-git") '(1 0 -4)))
(should (equal (version-to-list "1.0-pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1.0.1-a") '(1 0 1 1)))
(should (equal (version-to-list "1.0.1-f") '(1 0 1 6)))
(should (equal (version-to-list "1.0.1.a") '(1 0 1 1)))
(should (equal (version-to-list "1.0.1.f") '(1 0 1 6)))
(should (equal (version-to-list "1.0.1_a") '(1 0 1 1)))
(should (equal (version-to-list "1.0.1_f") '(1 0 1 6)))
(should (equal (version-to-list "1.0.1a") '(1 0 1 1)))
(should (equal (version-to-list "1.0.1f") '(1 0 1 6)))
(should (equal (version-to-list "1.0.7.5") '(1 0 7 5)))
(should (equal (version-to-list "1.0.git") '(1 0 -4)))
(should (equal (version-to-list "1.0.pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1.0_git") '(1 0 -4)))
(should (equal (version-to-list "1.0_pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1.0git") '(1 0 -4)))
(should (equal (version-to-list "1.0pre2") '(1 0 -1 2)))
(should (equal (version-to-list "22.8 beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22.8-beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22.8.beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22.8_beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22.8beta3") '(22 8 -2 3)))
(should (equal (version-to-list "6.9.30 Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6.9.30-Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6.9.30.Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6.9.30Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6.9.30_Beta") '(6 9 30 -2)))
(let ((text-quoting-style 'grave))
(should (equal
(error-message-string (should-error (version-to-list "OTP-18.1.5")))
"Invalid version syntax: `OTP-18.1.5' (must start with a number)"))
(should (equal
(error-message-string (should-error (version-to-list "")))
"Invalid version syntax: `' (must start with a number)"))
(should (equal
(error-message-string (should-error (version-to-list "1.0..7.5")))
"Invalid version syntax: `1.0..7.5'"))
(should (equal
(error-message-string (should-error (version-to-list "1.0prepre2")))
"Invalid version syntax: `1.0prepre2'"))
(should (equal
(error-message-string (should-error (version-to-list "22.8X3")))
"Invalid version syntax: `22.8X3'"))
(should (equal
(error-message-string (should-error (version-to-list "beta22.8alpha3")))
"Invalid version syntax: `beta22.8alpha3' (must start with a number)"))
(should (equal
(error-message-string (should-error (version-to-list "honk")))
"Invalid version syntax: `honk' (must start with a number)")))
(should (equal
(error-message-string (should-error (version-to-list 9)))
"Version must be a string"))
(let ((version-separator "_"))
(should (equal (version-to-list "_5") '(0 5)))
(should (equal (version-to-list "0_9 alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0_9 snapshot") '(0 9 -4)))
(should (equal (version-to-list "0_9-alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0_9-snapshot") '(0 9 -4)))
(should (equal (version-to-list "0_9.alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0_9.snapshot") '(0 9 -4)))
(should (equal (version-to-list "0_9alpha1") '(0 9 -3 1)))
(should (equal (version-to-list "0_9snapshot") '(0 9 -4)))
(should (equal (version-to-list "1_0 git") '(1 0 -4)))
(should (equal (version-to-list "1_0 pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1_0-git") '(1 0 -4)))
(should (equal (version-to-list "1_0.pre2") '(1 0 -1 2)))
(should (equal (version-to-list "1_0_1-a") '(1 0 1 1)))
(should (equal (version-to-list "1_0_1-f") '(1 0 1 6)))
(should (equal (version-to-list "1_0_1.a") '(1 0 1 1)))
(should (equal (version-to-list "1_0_1.f") '(1 0 1 6)))
(should (equal (version-to-list "1_0_1_a") '(1 0 1 1)))
(should (equal (version-to-list "1_0_1_f") '(1 0 1 6)))
(should (equal (version-to-list "1_0_1a") '(1 0 1 1)))
(should (equal (version-to-list "1_0_1f") '(1 0 1 6)))
(should (equal (version-to-list "1_0_7_5") '(1 0 7 5)))
(should (equal (version-to-list "1_0_git") '(1 0 -4)))
(should (equal (version-to-list "1_0pre2") '(1 0 -1 2)))
(should (equal (version-to-list "22_8 beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22_8-beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22_8.beta3") '(22 8 -2 3)))
(should (equal (version-to-list "22_8beta3") '(22 8 -2 3)))
(should (equal (version-to-list "6_9_30 Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6_9_30-Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6_9_30.Beta") '(6 9 30 -2)))
(should (equal (version-to-list "6_9_30Beta") '(6 9 30 -2)))
(let ((text-quoting-style 'grave))
(should (equal
(error-message-string (should-error (version-to-list "1_0__7_5")))
"Invalid version syntax: `1_0__7_5'"))
(should (equal
(error-message-string (should-error (version-to-list "1_0prepre2")))
"Invalid version syntax: `1_0prepre2'"))
(should (equal
(error-message-string (should-error (version-to-list "22.8X3")))
"Invalid version syntax: `22.8X3'"))
(should (equal
(error-message-string (should-error (version-to-list "beta22_8alpha3")))
"Invalid version syntax: `beta22_8alpha3' (must start with a number)")))))
(ert-deftest subr-test-version-list-< ()
(should (version-list-< '(0) '(1)))
(should (version-list-< '(0 9) '(1 0)))
(should (version-list-< '(1 -1) '(1 0)))
(should (version-list-< '(1 -2) '(1 -1)))
(should (not (version-list-< '(1) '(0))))
(should (not (version-list-< '(1 1) '(1 0))))
(should (not (version-list-< '(1) '(1 0))))
(should (not (version-list-< '(1 0) '(1 0 0)))))
(ert-deftest subr-test-version-list-= ()
(should (version-list-= '(1) '(1)))
(should (version-list-= '(1 0) '(1)))
(should (not (version-list-= '(0) '(1)))))
(ert-deftest subr-test-version-list-<= ()
(should (version-list-<= '(0) '(1)))
(should (version-list-<= '(1) '(1)))
(should (version-list-<= '(1 0) '(1)))
(should (not (version-list-<= '(1) '(0)))))
(defun subr-test--backtrace-frames-with-backtrace-frame (base)
"Reference implementation of `backtrace-frames'."
(let ((idx 0)
(frame nil)
(frames nil))
(while (setq frame (backtrace-frame idx base))
(push frame frames)
(setq idx (1+ idx)))
(nreverse frames)))
(defun subr-test--frames-2 (base)
(let ((_dummy nil))
(progn ;; Add a few frames to top of stack
(unwind-protect
(cons (mapcar (pcase-lambda (`(,evald ,func ,args ,_))
`(,evald ,func ,@args))
(backtrace-frames base))
(subr-test--backtrace-frames-with-backtrace-frame base))))))
(defun subr-test--frames-1 (base)
(subr-test--frames-2 base))
(ert-deftest subr-test-backtrace-simple-tests ()
"Test backtrace-related functions (simple tests).
This exercises `backtrace-frame', and indirectly `mapbacktrace'."
;; `mapbacktrace' returns nil
(should (equal (mapbacktrace #'ignore) nil))
;; Unbound BASE is silently ignored
(let ((unbound (make-symbol "ub")))
(should (equal (backtrace-frame 0 unbound) nil))
(should (equal (mapbacktrace #'error unbound) nil)))
;; First frame is backtrace-related function
(should (equal (backtrace-frame 0) '(t backtrace-frame 0)))
(let ((throw-args (lambda (&rest args) (throw 'ret args))))
(should (equal (catch 'ret (mapbacktrace throw-args))
`(t mapbacktrace (,throw-args) nil))))
;; Past-end NFRAMES is silently ignored
(should (equal (backtrace-frame most-positive-fixnum) nil)))
(ert-deftest subr-test-backtrace-integration-test ()
"Test backtrace-related functions (integration test).
This exercises `backtrace-frame', `backtrace-frames', and
indirectly `mapbacktrace'."
;; Compare two implementations of backtrace-frames
(let ((frame-lists (subr-test--frames-1 'subr-test--frames-2)))
(should (equal (car frame-lists) (cdr frame-lists)))))
(ert-deftest subr-tests--string-match-p--blank ()
"Test that [:blank:] matches horizontal whitespace, cf. Bug#25366."
(should (equal (string-match-p "\\`[[:blank:]]\\'" " ") 0))
(should (equal (string-match-p "\\`[[:blank:]]\\'" "\t") 0))
(should-not (string-match-p "\\`[[:blank:]]\\'" "\n"))
(should-not (string-match-p "\\`[[:blank:]]\\'" "a"))
(should (equal (string-match-p "\\`[[:blank:]]\\'" "\N{HAIR SPACE}") 0))
(should (equal (string-match-p "\\`[[:blank:]]\\'" "\u3000") 0))
(should-not (string-match-p "\\`[[:blank:]]\\'" "\N{LINE SEPARATOR}")))
(ert-deftest subr-tests--dolist--wrong-number-of-args ()
"Test that `dolist' doesn't accept wrong types or length of SPEC,
cf. Bug#25477."
(dolist (lb '(nil t))
(should-error (eval '(dolist (a)) lb)
:type 'wrong-number-of-arguments)
(should-error (eval '(dolist (a () 'result 'invalid)) lb)
:type 'wrong-number-of-arguments)
(should-error (eval '(dolist "foo") lb)
:type 'wrong-type-argument)))
(ert-deftest subr-tests-bug22027 ()
"Test for https://debbugs.gnu.org/22027 ."
(let ((default "foo") res)
(cl-letf (((symbol-function 'read-string)
(lambda (_prompt &optional _init _hist def _inher-input) def)))
(setq res (read-passwd "pass: " 'confirm (mapconcat #'string default)))
(should (string= default res)))))
(ert-deftest subr-tests--gensym ()
"Test `gensym' behavior."
(should (equal (symbol-name (let ((gensym-counter 0)) (gensym)))
"g0"))
(should (eq (string-to-char (symbol-name (gensym))) ?g))
(should (eq (string-to-char (symbol-name (gensym "X"))) ?X)))
(ert-deftest subr-tests--assq-delete-all ()
"Test `assq-delete-all' behavior."
(cl-flet ((new-list-fn
()
(list (cons 'a 1) (cons 'b 2) (cons 'c 3) 'd (cons "foo" "bar"))))
(should (equal (cdr (new-list-fn)) (assq-delete-all 'a (new-list-fn))))
(should (equal (new-list-fn) (assq-delete-all 'd (new-list-fn))))
(should (equal (new-list-fn) (assq-delete-all "foo" (new-list-fn))))))
(ert-deftest subr-tests--assoc-delete-all ()
"Test `assoc-delete-all' behavior."
(cl-flet ((new-list-fn
()
(list (cons 'a 1) (cons 'b 2) (cons 'c 3) 'd (cons "foo" "bar"))))
(should (equal (cdr (new-list-fn)) (assoc-delete-all 'a (new-list-fn))))
(should (equal (new-list-fn) (assoc-delete-all 'd (new-list-fn))))
(should (equal (butlast (new-list-fn))
(assoc-delete-all "foo" (new-list-fn))))))
(ert-deftest shell-quote-argument-%-on-w32 ()
"Quoting of `%' in w32 shells isn't perfect.
See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
:expected-result :failed
(skip-unless (and (fboundp 'w32-shell-dos-semantics)
(w32-shell-dos-semantics)))
(let ((process-environment (append '("ca^=with-caret"
"ca=without-caret")
process-environment)))
;; It actually results in
;; without-caret with-caret
(should (equal (shell-command-to-string
(format "echo %s %s"
"%ca%"
(shell-quote-argument "%ca%")))
"without-caret %ca%"))))
(ert-deftest subr-tests-flatten-tree ()
"Test `flatten-tree' behavior."
(should (equal (flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7))
'(1 2 3 4 5 6 7)))
(should (equal (flatten-tree '((1 . 2)))
'(1 2)))
(should (equal (flatten-tree '(1 nil 2))
'(1 2)))
(should (equal (flatten-tree 42)
'(42)))
(should (equal (flatten-tree t)
'(t)))
(should (equal (flatten-tree nil)
nil))
(should (equal (flatten-tree '((nil) ((((nil)))) nil))
nil))
(should (equal (flatten-tree '(1 ("foo" "bar") 2))
'(1 "foo" "bar" 2))))
(ert-deftest subr--tests-letrec ()
;; Test that simple cases of `letrec' get optimized back to `let*'.
(should (equal (macroexpand '(letrec ((subr-tests-var1 1)
(subr-tests-var2 subr-tests-var1))
(+ subr-tests-var1 subr-tests-var2)))
'(let* ((subr-tests-var1 1)
(subr-tests-var2 subr-tests-var1))
(+ subr-tests-var1 subr-tests-var2)))))
(defvar subr-tests--hook nil)
(ert-deftest subr-tests-add-hook-depth ()
"Test the `depth' arg of `add-hook'."
(setq-default subr-tests--hook nil)
(add-hook 'subr-tests--hook 'f1)
(add-hook 'subr-tests--hook 'f2)
(should (equal subr-tests--hook '(f2 f1)))
(add-hook 'subr-tests--hook 'f3 t)
(should (equal subr-tests--hook '(f2 f1 f3)))
(add-hook 'subr-tests--hook 'f4 50)
(should (equal subr-tests--hook '(f2 f1 f4 f3)))
(add-hook 'subr-tests--hook 'f5 -50)
(should (equal subr-tests--hook '(f5 f2 f1 f4 f3)))
(add-hook 'subr-tests--hook 'f6)
(should (equal subr-tests--hook '(f5 f6 f2 f1 f4 f3)))
;; Make sure t is equivalent to 90.
(add-hook 'subr-tests--hook 'f7 90)
(add-hook 'subr-tests--hook 'f8 t)
(should (equal subr-tests--hook '(f5 f6 f2 f1 f4 f3 f7 f8)))
;; Make sure nil is equivalent to 0.
(add-hook 'subr-tests--hook 'f9 0)
(add-hook 'subr-tests--hook 'f10)
(should (equal subr-tests--hook '(f5 f10 f9 f6 f2 f1 f4 f3 f7 f8)))
)
(ert-deftest ignore-error-tests ()
(should (equal (ignore-error (end-of-file)
(read ""))
nil))
(should (equal (ignore-error end-of-file
(read ""))
nil))
(should-error (ignore-error foo
(read ""))))
(ert-deftest string-replace ()
(should (equal (string-replace "foo" "bar" "zot")
"zot"))
(should (equal (string-replace "foo" "bar" "foozot")
"barzot"))
(should (equal (string-replace "foo" "bar" "barfoozot")
"barbarzot"))
(should (equal (string-replace "zot" "bar" "barfoozot")
"barfoobar"))
(should (equal (string-replace "z" "bar" "barfoozot")
"barfoobarot"))
(should (equal (string-replace "zot" "bar" "zat")
"zat"))
(should (equal (string-replace "azot" "bar" "zat")
"zat"))
(should (equal (string-replace "azot" "bar" "azot")
"bar"))
(should (equal (string-replace "azot" "bar" "foozotbar")
"foozotbar"))
(should (equal (string-replace "fo" "bar" "lafofofozot")
"labarbarbarzot"))
(should (equal (string-replace "\377" "x" "a\377b")
"axb"))
(should (equal (string-replace "\377" "x" "a\377ø")
"axø"))
(should (equal (string-replace (string-to-multibyte "\377") "x" "a\377b")
"axb"))
(should (equal (string-replace (string-to-multibyte "\377") "x" "a\377ø")
"axø"))
(should (equal (string-replace "ana" "ANA" "ananas") "ANAnas"))
(should (equal (string-replace "a" "" "") ""))
(should (equal (string-replace "a" "" "aaaaa") ""))
(should (equal (string-replace "ab" "" "ababab") ""))
(should (equal (string-replace "ab" "" "abcabcabc") "ccc"))
(should (equal (string-replace "a" "aa" "aaa") "aaaaaa"))
(should (equal (string-replace "abc" "defg" "abc") "defg"))
(should (equal (should-error (string-replace "" "x" "abc"))
'(wrong-length-argument 0))))
(ert-deftest subr-replace-regexp-in-string ()
(should (equal (replace-regexp-in-string "a+" "xy" "abaabbabaaba")
"xybxybbxybxybxy"))
;; FIXEDCASE
(let ((case-fold-search t))
(should (equal (replace-regexp-in-string "a+" "xy" "ABAABBABAABA")
"XYBXYBBXYBXYBXY"))
(should (equal (replace-regexp-in-string "a+" "xy" "ABAABBABAABA" t)
"xyBxyBBxyBxyBxy"))
(should (equal (replace-regexp-in-string
"a[bc]*" "xyz"
"a A ab AB Ab aB abc ABC Abc AbC aBc")
"xyz XYZ xyz XYZ Xyz xyz xyz XYZ Xyz Xyz xyz"))
(should (equal (replace-regexp-in-string
"a[bc]*" "xyz"
"a A ab AB Ab aB abc ABC Abc AbC aBc" t)
"xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz")))
(let ((case-fold-search nil))
(should (equal (replace-regexp-in-string "a+" "xy" "ABAABBABAABA")
"ABAABBABAABA")))
;; group substitution
(should (equal (replace-regexp-in-string
"a\\(b*\\)" "<\\1,\\&>" "babbcaabacbab")
"b<bb,abb>c<,a><b,ab><,a>cb<b,ab>"))
(should (equal (replace-regexp-in-string
"x\\(?2:..\\)\\(?1:..\\)\\(..\\)\\(..\\)\\(..\\)"
"<\\3,\\5,\\4,\\1,\\2>" "yxabcdefghijkl")
"y<ef,ij,gh,cd,ab>kl"))
;; LITERAL
(should (equal (replace-regexp-in-string
"a\\(b*\\)" "<\\1,\\&>" "babbcaabacbab" nil t)
"b<\\1,\\&>c<\\1,\\&><\\1,\\&><\\1,\\&>cb<\\1,\\&>"))
(should (equal (replace-regexp-in-string
"a" "\\\\,\\?" "aba")
"\\,\\?b\\,\\?"))
(should (equal (replace-regexp-in-string
"a" "\\\\,\\?" "aba" nil t)
"\\\\,\\?b\\\\,\\?"))
;; SUBEXP
(should (equal (replace-regexp-in-string
"\\(a\\)\\(b*\\)c" "xy" "babbcdacd" nil nil 2)
"baxycdaxycd"))
;; START
(should (equal (replace-regexp-in-string
"ab" "x" "abcabdabeabf" nil nil nil 4)
"bdxexf"))
;; An empty pattern matches once before every character.
(should (equal (replace-regexp-in-string "" "x" "abc")
"xaxbxc"))
(should (equal (replace-regexp-in-string "y*" "x" "abc")
"xaxbxc"))
;; replacement function
(should (equal (replace-regexp-in-string
"a\\(b*\\)c"
(lambda (s)
(format "<%s,%s,%s,%s,%s>"
s
(match-beginning 0) (match-end 0)
(match-beginning 1) (match-end 1)))
"babbcaacabc")
"b<abbc,0,4,1,3>a<ac,0,2,1,1><abc,0,3,1,2>"))
;; anchors (bug#15107, bug#44861)
(should (equal (replace-regexp-in-string "a\\B" "b" "a aaaa")
"a bbba"))
(should (equal (replace-regexp-in-string "\\`\\|x" "z" "--xx--")
"z--zz--")))
(ert-deftest subr-match-substitute-replacement ()
(with-temp-buffer
(insert "Alpha Beta Gamma Delta Epsilon")
(goto-char (point-min))
(re-search-forward "B\\(..\\)a")
(should (equal (match-substitute-replacement "carrot")
"Carrot"))
(should (equal (match-substitute-replacement "<\\&>")
"<Beta>"))
(should (equal (match-substitute-replacement "m\\1a")
"Meta"))
(should (equal (match-substitute-replacement "ernin" nil nil nil 1)
"Bernina")))
(let ((s "Tau Beta Gamma Delta Epsilon"))
(string-match "B\\(..\\)a" s)
(should (equal (match-substitute-replacement "carrot" nil nil s)
"Carrot"))
(should (equal (match-substitute-replacement "<\\&>" nil nil s)
"<Beta>"))
(should (equal (match-substitute-replacement "m\\1a" nil nil s)
"Meta"))
(should (equal (match-substitute-replacement "ernin" nil nil s 1)
"Bernina"))))
(ert-deftest subr-tests--change-group-33341 ()
(with-temp-buffer
(buffer-enable-undo)
(insert "0\n")
(let ((g (prepare-change-group)))
(activate-change-group g)
(insert "b\n")
(insert "c\n")
(cancel-change-group g))
(should (equal (buffer-string) "0\n"))
(erase-buffer)
(setq buffer-undo-list nil)
(insert "0\n")
(let ((g (prepare-change-group)))
(activate-change-group g)
(insert "b\n")
(insert "c\n")
(accept-change-group g))
(should (equal (buffer-string) "0\nb\nc\n"))
(undo-boundary)
(undo)
(should (equal (buffer-string) ""))))
(defvar subr--ordered nil)
(ert-deftest subr--add-to-ordered-list-eq ()
(setq subr--ordered nil)
(add-to-ordered-list 'subr--ordered 'b 2)
(should (equal subr--ordered '(b)))
(add-to-ordered-list 'subr--ordered 'c 3)
(should (equal subr--ordered '(b c)))
(add-to-ordered-list 'subr--ordered 'a 1)
(should (equal subr--ordered '(a b c)))
(add-to-ordered-list 'subr--ordered 'e)
(should (equal subr--ordered '(a b c e)))
(add-to-ordered-list 'subr--ordered 'd 4)
(should (equal subr--ordered '(a b c d e)))
(add-to-ordered-list 'subr--ordered 'e)
(should (equal subr--ordered '(a b c d e)))
(add-to-ordered-list 'subr--ordered 'b 5)
(should (equal subr--ordered '(a c d b e))))
;;; Apropos.
(ert-deftest apropos-apropos-internal ()
(should (equal (apropos-internal "^next-line$") '(next-line)))
(should (>= (length (apropos-internal "^help")) 100))
(should-not (apropos-internal "^test-a-missing-symbol-foo-bar-zot$")))
(ert-deftest apropos-apropos-internal/predicate ()
(should (equal (apropos-internal "^next-line$" #'commandp) '(next-line)))
(should (>= (length (apropos-internal "^help" #'commandp)) 15))
(should-not (apropos-internal "^next-line$" #'keymapp)))
(defvar test-global-boundp)
(ert-deftest test-buffer-local-boundp ()
(let ((buf (generate-new-buffer "boundp")))
(with-current-buffer buf
(setq-local test-boundp t))
(setq test-global-boundp t)
(should (buffer-local-boundp 'test-boundp buf))
(should-not (buffer-local-boundp 'test-not-boundp buf))
(should (buffer-local-boundp 'test-global-boundp buf))))
(ert-deftest test-replace-string-in-region ()
(with-temp-buffer
(insert "foo bar zot foobar")
(should (= (replace-string-in-region "foo" "new" (point-min) (point-max))
2))
(should (equal (buffer-string) "new bar zot newbar")))
(with-temp-buffer
(insert "foo bar zot foobar")
(should (= (replace-string-in-region "foo" "new" (point-min) 14)
1))
(should (equal (buffer-string) "new bar zot foobar")))
(with-temp-buffer
(insert "foo bar zot foobar")
(should-error (replace-string-in-region "foo" "new" (point-min) 30)))
(with-temp-buffer
(insert "Foo bar zot foobar")
(should (= (replace-string-in-region "Foo" "new" (point-min))
1))
(should (equal (buffer-string) "new bar zot foobar")))
(with-temp-buffer
(insert "foo bar baz")
(should (= (replace-string-in-region "ba" "quux corge grault" (point-min))
2))
(should (equal (buffer-string)
"foo quux corge graultr quux corge graultz")))
(with-temp-buffer
(insert "foo bar bar")
(should (= (replace-string-in-region " bar" "" (point-min) 8)
1))
(should (equal (buffer-string)
"foo bar"))))
(ert-deftest test-replace-regexp-in-region ()
(with-temp-buffer
(insert "foo bar zot foobar")
(should (= (replace-regexp-in-region "fo+" "new" (point-min) (point-max))
2))
(should (equal (buffer-string) "new bar zot newbar")))
(with-temp-buffer
(insert "foo bar zot foobar")
(should (= (replace-regexp-in-region "fo+" "new" (point-min) 14)
1))
(should (equal (buffer-string) "new bar zot foobar")))
(with-temp-buffer
(insert "foo bar zot foobar")
(should-error (replace-regexp-in-region "fo+" "new" (point-min) 30)))
(with-temp-buffer
(insert "Foo bar zot foobar")
(should (= (replace-regexp-in-region "Fo+" "new" (point-min))
1))
(should (equal (buffer-string) "new bar zot foobar")))
(with-temp-buffer
(insert "foo bar baz")
(should (= (replace-regexp-in-region "ba." "quux corge grault" (point-min))
2))
(should (equal (buffer-string)
"foo quux corge grault quux corge grault")))
(with-temp-buffer
(insert "foo bar bar")
(should (= (replace-regexp-in-region " bar" "" (point-min) 8)
1))
(should (equal (buffer-string)
"foo bar"))))
(ert-deftest test-with-existing-directory ()
(let ((dir (make-temp-name "/tmp/not-exist-")))
(let ((default-directory dir))
(should-not (file-exists-p default-directory)))
(with-existing-directory
(should-not (equal dir default-directory))
(should (file-exists-p default-directory)))))
(ert-deftest subr-test-internal--format-docstring-line ()
(should
(string= (let ((fill-column 70))
(internal--format-docstring-line
"In addition to any hooks its parent mode might have run, this \
mode runs the hook foo-bar-baz-very-long-name-indeed-mode-hook, as the final \
or penultimate step during initialization."))
"In addition to any hooks its parent mode might have run, this mode
runs the hook foo-bar-baz-very-long-name-indeed-mode-hook, as the
final or penultimate step during initialization."))
(should-error (internal--format-docstring-line "foo\nbar")))
(ert-deftest test-ensure-list ()
(should (equal (ensure-list nil) nil))
(should (equal (ensure-list :foo) '(:foo)))
(should (equal (ensure-list '(1 2 3)) '(1 2 3))))
(ert-deftest test-alias-p ()
(should-not (function-alias-p 1))
(defun subr-tests--fun ())
(should-not (function-alias-p 'subr-tests--fun))
(defalias 'subr-tests--a 'subr-tests--b)
(defalias 'subr-tests--b 'subr-tests--c)
(should (equal (function-alias-p 'subr-tests--a)
'(subr-tests--b subr-tests--c)))
(defalias 'subr-tests--d 'subr-tests--e)
(defalias 'subr-tests--e 'subr-tests--d)
(should-error (function-alias-p 'subr-tests--d))
(should (equal (function-alias-p 'subr-tests--d t)
'(subr-tests--e))))
(ert-deftest test-readablep ()
(should (readablep "foo"))
(should-not (readablep (list (make-marker))))
(should-not (readablep (make-marker))))
(ert-deftest test-print-unreadable-function ()
;; Check that problem with unwinding properly is fixed (bug#56773).
(let* ((before nil)
(after nil)
(r (with-temp-buffer
(setq before (current-buffer))
(prog1 (readablep (make-marker))
(setq after (current-buffer))))))
(should (equal after before))
(should (equal r nil))))
(ert-deftest test-string-lines ()
(should (equal (string-lines "") '("")))
(should (equal (string-lines "" t) '()))
(should (equal (string-lines "foo") '("foo")))
(should (equal (string-lines "foo\n") '("foo")))
(should (equal (string-lines "foo\nbar") '("foo" "bar")))
(should (equal (string-lines "foo" t) '("foo")))
(should (equal (string-lines "foo\n" t) '("foo")))
(should (equal (string-lines "foo\nbar" t) '("foo" "bar")))
(should (equal (string-lines "foo\n\n\nbar" t) '("foo" "bar")))
(should (equal (string-lines "foo" nil t) '("foo")))
(should (equal (string-lines "foo\n" nil t) '("foo\n")))
(should (equal (string-lines "foo\nbar" nil t) '("foo\n" "bar")))
(should (equal (string-lines "foo\n\n\nbar" nil t)
'("foo\n" "\n" "\n" "bar")))
(should (equal (string-lines "foo" t t) '("foo")))
(should (equal (string-lines "foo\n" t t) '("foo\n")))
(should (equal (string-lines "foo\nbar" t t) '("foo\n" "bar")))
(should (equal (string-lines "foo\n\n\nbar" t t)
'("foo\n" "bar"))))
(ert-deftest test-keymap-parse-macros ()
(should (equal (key-parse "C-x ( C-d C-x )") [24 40 4 24 41]))
(should (equal (kbd "C-x ( C-d C-x )") ""))
(should (equal (kbd "C-x ( C-x )") "")))
(defvar subr-test--global)
(ert-deftest test-local-set-state ()
(setq subr-test--global 1)
(with-temp-buffer
(setq-local subr-test--local 2)
(let ((state (buffer-local-set-state subr-test--global 10
subr-test--local 20
subr-test--unexist 30)))
(should (= subr-test--global 10))
(should (= subr-test--local 20))
(should (= subr-test--unexist 30))
(buffer-local-restore-state state)
(should (= subr-test--global 1))
(should (= subr-test--local 2))
(should-not (boundp 'subr-test--unexist)))))
(ert-deftest test-char-uppercase-p ()
"Tests for `char-uppercase-p'."
(dolist (c (list ?R ?S ))
(should (char-uppercase-p c)))
(dolist (c (list ?a ?b ?α ))
(should-not (char-uppercase-p c))))
(ert-deftest test-plistp ()
(should (plistp nil))
(should-not (plistp 1))
(should (plistp '(1 2)))
(should-not (plistp '(1 . 2)))
(should (plistp '(1 2 3 4)))
(should-not (plistp '(1 2 3)))
(should-not (plistp '(1 2 3 . 4)))
(let ((cycle (list 1 2 3)))
(nconc cycle cycle)
(should-not (plistp cycle))))
(defun subr-tests--butlast-ref (list &optional n)
"Reference implementation of `butlast'."
(let ((m (or n 1))
(len (length list)))
(let ((r nil))
(while (and list (> len m))
(push (car list) r)
(setq list (cdr list))
(setq len (1- len)))
(nreverse r))))
(ert-deftest subr-butlast ()
(dolist (l '(nil '(a) '(a b) '(a b c) '(a b c d)))
(dolist (n (cons nil (number-sequence -2 6)))
(should (equal (butlast l n)
(subr-tests--butlast-ref l n))))))
(ert-deftest test-list-of-strings-p ()
(should-not (list-of-strings-p 1))
(should (list-of-strings-p nil))
(should (list-of-strings-p '("a" "b")))
(should-not (list-of-strings-p ["a" "b"]))
(should-not (list-of-strings-p '("a" nil "b")))
(should-not (list-of-strings-p '("a" "b" . "c"))))
(provide 'subr-tests)
;;; subr-tests.el ends here