blob: 071e1ca96586e6739ed147029ab78cd98a3db2df (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
;;; test-prog-python--lsp-guard.el --- Python LSP guard tests -*- lexical-binding: t; -*-
;;; Commentary:
;; The config audit found lsp-pyright's unguarded :hook lambda calling
;; (require 'lsp-pyright) + (lsp-deferred) on every python-ts buffer, so
;; pyright-less machines got the LSP attach prompt that cj/python-setup's
;; guard exists to prevent. The guarded branch now owns the require and
;; the attach, and both classic and treesit modes run the same setup.
;;; Code:
(require 'ert)
(require 'cl-lib)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'prog-python)
(defmacro test-python-guard--setup (pyright-found &rest body)
"Run `cj/python-setup' with pyright presence set to PYRIGHT-FOUND.
Records requires into `required' and lsp attaches into `attached';
BODY sees both. Package minor modes are stubbed at their boundary."
(declare (indent 1))
`(let ((required '()) (attached nil))
(cl-letf (((symbol-function 'company-mode) #'ignore)
((symbol-function 'flyspell-prog-mode) #'ignore)
((symbol-function 'superword-mode) #'ignore)
((symbol-function 'executable-find)
(lambda (&rest _) ,pyright-found))
((symbol-function 'require)
(lambda (feature &rest _) (push feature required) feature))
((symbol-function 'lsp-deferred)
(lambda () (setq attached t))))
(with-temp-buffer
(cj/python-setup))
,@body)))
(ert-deftest test-prog-python-setup-pyright-absent-no-lsp ()
"Error: without pyright, setup neither loads lsp-pyright nor attaches."
(test-python-guard--setup nil
(should-not (memq 'lsp-pyright required))
(should-not attached)))
(ert-deftest test-prog-python-setup-pyright-present-attaches ()
"Normal: with pyright on PATH, setup loads lsp-pyright then attaches."
(test-python-guard--setup "/usr/bin/pyright"
(should (memq 'lsp-pyright required))
(should attached)))
(ert-deftest test-prog-python-hooks-cover-both-mode-variants ()
"Normal: classic and treesit python modes both run the same setup."
(dolist (hook '(python-mode-hook python-ts-mode-hook))
(should (memq #'cj/python-setup (symbol-value hook)))
(should (memq #'cj/python-mode-keybindings (symbol-value hook)))))
(ert-deftest test-prog-python-no-anonymous-hook-lambdas ()
"Boundary: no anonymous lambda remains on the python hooks.
The audit's unguarded lsp-pyright lambda was anonymous; symbols only
means every hook entry is a named, greppable function."
(dolist (hook '(python-mode-hook python-ts-mode-hook))
(dolist (fn (symbol-value hook))
(should (symbolp fn)))))
(provide 'test-prog-python--lsp-guard)
;;; test-prog-python--lsp-guard.el ends here
|