diff --git a/test/automated/advice-tests.el b/test/automated/advice-tests.el index 69c15e3..65577ad 100644 --- a/test/automated/advice-tests.el +++ b/test/automated/advice-tests.el @@ -23,6 +23,21 @@ (require 'ert) +(defun clear-advice (symbol) + "Reset SYMBOL's function to its original unadvised definition." + (let ((func (symbol-function symbol))) + (while (advice--p func) + (setq func (advice--cdr func))) + (fset symbol func))) + +(defmacro post-restore-func (func &rest body) + (let ((fdef (symbol-function func))) + `(unwind-protect + (progn ,@body) + (fset ',func ,fdef)))) +(put 'post-restore-func 'lisp-indent-function + (get 'prog1 'lisp-indent-function)) + (ert-deftest advice-tests-nadvice () "Test nadvice code." (defun sm-test1 (x) (+ x 4)) @@ -113,6 +128,60 @@ (cons (cons 2 (called-interactively-p)) (apply f args)))) (should (equal (call-interactively 'sm-test7) '((2 . t) (1 . t) 11)))) +(ert-deftest advice-test-called-interactively-p-2 () + "Check interaction between around advice and called-interactively-p. + +This tests the currently broken case of the innermost advice to a +function being an around advice." + :expected-result :failed + (defun sm-test7.2 () (interactive) (cons 1 (called-interactively-p))) + (clear-advice 'sm-test7.2) + (advice-add 'sm-test7.2 :around + (lambda (f &rest args) + (list (cons 1 (called-interactively-p)) (apply f args)))) + (advice-add 'sm-test7.2 :before #'ignore) + (advice-add 'sm-test7.2 :after #'ignore) + ;(advice-add 'sm-test7.2 :filter-args #'list) + ;(advice-add 'sm-test7.2 :filter-return #'identity) + (should (equal (sm-test7.2) '((1 . nil) (1 . nil)))) + (should (equal (call-interactively 'sm-test7.2) '((1 . t) (1 . t))))) + +(ert-deftest advice-test-called-interactively-p-3 () + "Check interaction between before advice and called-interactively-p. + +This tests the case of the innermost advice being before" + (defun sm-test7.3 () (interactive) (cons 1 (called-interactively-p))) + (advice-add 'sm-test7.3 :before #'ignore) + ;(advice-add 'sm-test7.3 :filter-args #'list) + ;(advice-add 'sm-test7.3 :filter-return #'identity) + (should (equal (sm-test7.3) '(1 . nil))) + (should (equal (call-interactively 'sm-test7.3) '(1 . t)))) + +(ert-deftest advice-test-called-interactively-p-4 () + "Check interaction between advice on call-interactively and called-interactively-p. + +This tests the case where call-interactively itself is advised, +which is currently broken." + :expected-result :failed + (defun sm-test7.4 () (interactive) (cons 1 (called-interactively-p))) + (post-restore-func call-interactively + (advice-add 'call-interactively :before #'ignore) + (should (equal (sm-test7.4) '(1 . nil))) + (should (equal (call-interactively 'sm-test7.4) '(1 . t))))) + +(ert-deftest advice-test-called-interactively-p-5 () + "Check interaction between non-innermost around advice and called-interactively-p. + +This tests the case where a function has around advice, but it is +not the innermost advice." + (defun sm-test7.5 () (interactive) (cons 1 (called-interactively-p))) + (advice-add 'sm-test7.5 :before #'ignore) + (advice-add 'sm-test7.5 :around #'funcall) + ;(advice-add 'sm-test7.5 :filter-args #'list) + ;(advice-add 'sm-test7.5 :filter-return #'identity) + (should (equal (sm-test7.5) '(1 . nil))) + (should (equal (call-interactively 'sm-test7.5) '(1 . t)))) + (ert-deftest advice-test-interactive () "Check handling of interactive spec." (defun sm-test8 (a) (interactive "p") a)