
Rework the code we have in Fdefalias that tries to keep track of definitions so as to be able to undo them later. We used to store in `load-history` when an autoload is redefined as a non-autoload and in the `autoload` symbol property we used to store the autoload data that used to be used before it got overriden. Instead, store the history of the function definition of a symbol in its `function-history` symbol property. To make this list cheap in the default case, the latest value is not stored in the list (since it's in the `symbol-function`) and neither is the first file. So if there's only been a single definition (the most common case), the list is empty and the property is just not present at all. The patch also gets rid of the `autoload` vs `defun` distinction in `load-history` which seems unnecessary (a significant part of the motivation for this patch was to get rid of the special handling of autoloads in this part of the code). * src/data.c (add_to_function_history): New function. (defalias): Use it. Don't add the `t` entries for autoloads and always use `defun` regardless of the kind of definition. Change `Vautoload_queue` to only hold the function symbols since the rest is now available from `function-history`. * src/eval.c (un_autoload): Adjust accordingly. * src/lread.c (load-history): Udate docstring. * lisp/loadhist.el (loadhist-unload-filename): New var. (unload-feature): Bind it. (loadhist-unload-element): Document its availability. (loadhist--restore-autoload): Delete var. (loadhist--unload-function): Delete function. (loadhist-unload-element): Delete the `t` and `autoload` methods. Rewrite the `defun` method using `function-history`. * lisp/help-fns.el: Require `seq`. (help-fns--autoloaded-p): Rewrite. (help-fns-function-description-header): Adjust call accordingly. * doc/lispref/loading.texi (Where Defined): Remove `autoload` and `t` entries from `load-history` since we don't generate them any more. Document the `function-history` which replaces the `autoload` property. (Unloading): Adjust symbol property name accordingly. * test/lisp/loadhist-resources/loadhist--bar.el: * test/lisp/loadhist-resources/loadhist--foo.el: New files. * test/lisp/loadhist-tests.el (loadhist-tests-unload-feature-nested) (loadhist-tests-unload-feature-notnested): New tests.
104 lines
4.2 KiB
EmacsLisp
104 lines
4.2 KiB
EmacsLisp
;;; loadhist-tests.el --- Tests for loadhist.el -*- lexical-binding:t -*-
|
|
|
|
;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
|
|
|
;; Author: Stefan Kangas <stefankangas@gmail.com>
|
|
|
|
;; 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)
|
|
(require 'loadhist)
|
|
|
|
(ert-deftest loadhist-tests-feature-symbols ()
|
|
(should (equal (file-name-base (car (feature-symbols 'loadhist))) "loadhist"))
|
|
(should-not (feature-symbols 'non-existent-feature)))
|
|
|
|
(ert-deftest loadhist-tests-feature-file ()
|
|
(should (equal (file-name-base (feature-file 'loadhist)) "loadhist"))
|
|
(should-error (feature-file 'non-existent-feature)))
|
|
|
|
(ert-deftest loadhist-tests-file-loadhist-lookup ()
|
|
;; This should probably be extended...
|
|
(should (listp (file-loadhist-lookup "loadhist"))))
|
|
|
|
(ert-deftest loadhist-tests-file-provides ()
|
|
(should (eq (car (file-provides "loadhist")) 'loadhist)))
|
|
|
|
(ert-deftest loadhist-tests-file-requires ()
|
|
(should-not (file-requires "loadhist")))
|
|
|
|
(ert-deftest loadhist-tests-file-dependents ()
|
|
(require 'dired-x)
|
|
(let ((deps (file-dependents "dired")))
|
|
(should (member "dired-x" (mapcar #'file-name-base deps)))))
|
|
|
|
(ert-deftest loadhist-tests-unload-feature ()
|
|
(require 'dired-x)
|
|
(should-error (unload-feature 'dired))
|
|
(unload-feature 'dired-x))
|
|
|
|
(defvar loadhist--tests-dir (file-name-directory (macroexp-file-name)))
|
|
|
|
(ert-deftest loadhist-tests-unload-feature-nested ()
|
|
(add-to-list 'load-path (expand-file-name
|
|
"loadhist-resources/"
|
|
loadhist--tests-dir))
|
|
(declare-function loadhist--foo-inc "loadhist--foo")
|
|
(declare-function loadhist--bar-dec "loadhist--dec")
|
|
(load "loadhist--foo" nil t)
|
|
(should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
|
|
(should (autoloadp (symbol-function 'loadhist--bar-dec)))
|
|
(load "loadhist--bar" nil t)
|
|
(should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
|
|
(should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
|
|
(should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
|
|
(should (equal (list 40 42)
|
|
(list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
|
|
(unload-feature 'loadhist--bar)
|
|
(should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
|
|
(should (autoloadp (symbol-function 'loadhist--bar-dec)))
|
|
(should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
|
|
(unload-feature 'loadhist--foo)
|
|
(should (null (symbol-function 'loadhist--bar-dec)))
|
|
(should (null (symbol-function 'loadhist--foo-inc)))
|
|
(should (null (get 'loadhist--bar-dec 'function-history)))
|
|
(should (null (get 'loadhist--foo-inc 'function-history))))
|
|
|
|
(ert-deftest loadhist-tests-unload-feature-notnested ()
|
|
(add-to-list 'load-path (expand-file-name
|
|
"loadhist-resources/"
|
|
loadhist--tests-dir))
|
|
(load "loadhist--foo" nil t)
|
|
(load "loadhist--bar" nil t)
|
|
(should (equal (list 40 42)
|
|
(list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
|
|
(unload-feature 'loadhist--foo)
|
|
(should (functionp 'loadhist--bar-dec))
|
|
(should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
|
|
(should (let ((f (symbol-function 'loadhist--foo-inc)))
|
|
;; Both choices seem acceptable.
|
|
(or (null f) (autoloadp f))))
|
|
(unload-feature 'loadhist--bar)
|
|
(should (null (symbol-function 'loadhist--bar-dec)))
|
|
(should (null (symbol-function 'loadhist--foo-inc)))
|
|
(should (null (get 'loadhist--bar-dec 'function-history)))
|
|
(should (null (get 'loadhist--foo-inc 'function-history))))
|
|
|
|
;;; loadhist-tests.el ends here
|