diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-14 00:24:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-14 00:24:34 -0500 |
| commit | bcd26c73b0efd857b78096a2351f4b782a0e0673 (patch) | |
| tree | d82b29964571140a388c1ab785936aeaa6ccecb0 /tests | |
| parent | 0058495e770bb63e41c6e7d52067000d52842ecd (diff) | |
| download | dotemacs-bcd26c73b0efd857b78096a2351f4b782a0e0673.tar.gz dotemacs-bcd26c73b0efd857b78096a2351f4b782a0e0673.zip | |
fix(prog-python): keep the pyright guard authoritative for LSP attach
lsp-pyright's :hook lambda called require and lsp-deferred unguarded on every python-ts buffer, so a machine without pyright still 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 the hook is gone.
Classic python-mode now runs the same setup hooks as python-ts-mode, so treesit-auto's grammar-unavailable fallback keeps indentation, keys, and LSP. Four tests cover the guard branches and pin that every python hook entry stays a named function.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-prog-python--lsp-guard.el | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/tests/test-prog-python--lsp-guard.el b/tests/test-prog-python--lsp-guard.el new file mode 100644 index 00000000..071e1ca9 --- /dev/null +++ b/tests/test-prog-python--lsp-guard.el @@ -0,0 +1,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 |
