diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-14 03:43:46 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-14 03:43:46 -0500 |
| commit | f6cfaee02412944e281c7ec4c6b20512b3e45708 (patch) | |
| tree | edb0710fe73a7314d68969bf07b6d42c2c33f870 | |
| parent | e546f00daac8e716c5a747d7013c908c0e9ef526 (diff) | |
| download | dotemacs-f6cfaee02412944e281c7ec4c6b20512b3e45708.tar.gz dotemacs-f6cfaee02412944e281c7ec4c6b20512b3e45708.zip | |
test(external-open): cover xdg-open, open-this-file-with, find-file-auto
Sibling tests in `test-external-open-lib-*.el` covered the pure helpers (`cj/external-open-command`, `cj/external-open-launcher-p`). This batch covers the user-facing wrappers:
- `cj/xdg-open`: posix path triggers `call-process` with the open program; errors when no file is associated; errors when no command resolves on the host.
- `cj/open-this-file-with`: errors outside a file-visiting buffer; posix path spawns a detached process via `call-process-shell-command` with `nohup ... >/dev/null 2>&1 &`.
- `cj/find-file-auto`: routes a `.mp4` (in `default-open-extensions`) to `cj/xdg-open`, passes `.txt` through to the original `find-file`, and falls through cleanly for a nil filename argument.
Host predicates, call-process, and the underlying `cj/xdg-open` are stubbed throughout.
| -rw-r--r-- | tests/test-external-open-commands.el | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/test-external-open-commands.el b/tests/test-external-open-commands.el new file mode 100644 index 00000000..c0c83a34 --- /dev/null +++ b/tests/test-external-open-commands.el @@ -0,0 +1,120 @@ +;;; test-external-open-commands.el --- Tests for external-open commands -*- lexical-binding: t; -*- + +;;; Commentary: +;; Sibling tests in `test-external-open-lib-*.el' cover the pure +;; `cj/external-open-command' and launcher-p helpers. This file +;; covers the user-facing wrappers: +;; +;; cj/xdg-open +;; cj/open-this-file-with +;; cj/find-file-auto +;; +;; Process primitives and host-environment predicates are stubbed. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'external-open) + +;;; cj/xdg-open + +(ert-deftest test-external-open-xdg-open-runs-call-process-on-posix () + "Normal: a usable command and file yields a `call-process' invocation." + (let ((tmp (make-temp-file "test-ext-open-" nil ".tmp")) + (call-args nil)) + (unwind-protect + (cl-letf (((symbol-function 'env-windows-p) (lambda () nil)) + ((symbol-function 'cj/external-open-command) + (lambda () "/usr/bin/xdg-open")) + ((symbol-function 'call-process) + (lambda (prog _infile _buf _disp &rest args) + (setq call-args (cons prog args)) + 0))) + (cj/xdg-open tmp)) + (delete-file tmp)) + (should (equal (car call-args) "/usr/bin/xdg-open")) + ;; The file's basename lands somewhere in the args. + (let ((basename (file-name-nondirectory tmp))) + (should (cl-find-if (lambda (a) + (and (stringp a) (string-match-p basename a))) + call-args))))) + +(ert-deftest test-external-open-xdg-open-errors-when-no-file () + "Error: a buffer with no associated file signals user-error." + (with-temp-buffer + (cl-letf (((symbol-function 'cj/file-from-context) (lambda (_) nil))) + (should-error (cj/xdg-open) :type 'user-error)))) + +(ert-deftest test-external-open-xdg-open-errors-when-no-command () + "Error: an unsupported host environment signals user-error." + (let ((tmp (make-temp-file "test-ext-open-no-cmd-" nil ".tmp"))) + (unwind-protect + (cl-letf (((symbol-function 'cj/external-open-command) (lambda () nil))) + (should-error (cj/xdg-open tmp) :type 'user-error)) + (delete-file tmp)))) + +;;; cj/open-this-file-with + +(ert-deftest test-external-open-open-this-file-with-errors-no-file () + "Error: outside a file-visiting buffer signals user-error." + (with-temp-buffer + (should-error (cj/open-this-file-with "vlc") :type 'user-error))) + +(ert-deftest test-external-open-open-this-file-with-spawns-detached-process () + "Normal: posix path invokes `call-process-shell-command' with nohup + bg." + (let ((cmd nil)) + (with-temp-buffer + (setq buffer-file-name "/tmp/foo.mp4") + (cl-letf (((symbol-function 'env-windows-p) (lambda () nil)) + ((symbol-function 'call-process-shell-command) + (lambda (c _infile _buf &rest _) + (setq cmd c)))) + (cj/open-this-file-with "vlc")) + (setq buffer-file-name nil)) + (should (string-match-p "^nohup vlc " cmd)) + (should (string-match-p "&$" cmd)) + (should (string-match-p ">/dev/null" cmd)))) + +;;; cj/find-file-auto + +(ert-deftest test-external-open-find-file-auto-routes-media-externally () + "Normal: a `.mp4' filename (in `default-open-extensions') triggers +`cj/xdg-open' instead of the original `find-file'." + (let ((opened nil) + (orig-called nil)) + (cl-letf (((symbol-function 'cj/xdg-open) + (lambda (file) (setq opened file))) + ;; orig-fun replacement -- shouldn't run for a routed extension. + ((symbol-function 'cj/find-file-auto--orig-stub) + (lambda (&rest _) (setq orig-called t)))) + (cj/find-file-auto #'cj/find-file-auto--orig-stub "/tmp/video.mp4")) + (should (equal opened "/tmp/video.mp4")) + (should-not orig-called))) + +(ert-deftest test-external-open-find-file-auto-passes-through-text-files () + "Boundary: a `.txt' filename falls through to the original `find-file'." + (let ((opened nil) + (orig-args nil)) + (cl-letf (((symbol-function 'cj/xdg-open) + (lambda (file) (setq opened file))) + ((symbol-function 'cj/find-file-auto--orig-stub) + (lambda (&rest args) (setq orig-args args)))) + (cj/find-file-auto #'cj/find-file-auto--orig-stub "/tmp/notes.txt")) + (should-not opened) + (should (equal (car orig-args) "/tmp/notes.txt")))) + +(ert-deftest test-external-open-find-file-auto-non-string-passes-through () + "Boundary: a nil filename falls through (the routing only matches strings)." + (let ((orig-called nil)) + (cl-letf (((symbol-function 'cj/xdg-open) + (lambda (_) (error "should not be called"))) + ((symbol-function 'cj/find-file-auto--orig-stub) + (lambda (&rest _) (setq orig-called t)))) + (cj/find-file-auto #'cj/find-file-auto--orig-stub nil)) + (should orig-called))) + +(provide 'test-external-open-commands) +;;; test-external-open-commands.el ends here |
