aboutsummaryrefslogtreecommitdiff
path: root/tests/test-dev-fkeys--projectile-capture-cmd.el
blob: 85d4603f7d1d3e4015bfffafd3c16bdf90dee206 (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
65
66
67
;;; test-dev-fkeys--projectile-capture-cmd.el --- Tests for cj/--projectile-capture-cmd -*- lexical-binding: t -*-

;;; Commentary:
;; Tests for the prior-cmd capture helper used by the auto-revert advice.
;; Captures the current cached cmd at the project root into a plist so a
;; later finish-hook can restore it if the compile fails after the cmd was
;; modified.

;;; Code:

(require 'ert)
(require 'cl-lib)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'dev-fkeys)

;; Test stub: projectile cmd-maps as defvars so `boundp' is non-nil and
;; `let'-binding has a target. In real use, projectile defines these.
(defvar projectile-compile-cmd-map nil)
(defvar projectile-test-cmd-map nil)
(defvar projectile-run-cmd-map nil)

;;; Normal Cases

(ert-deftest test-dev-fkeys-projectile-capture-cmd-stores-prior-value ()
  "Normal: captures the cached cmd at the project root into the state plist."
  (let* ((projectile-compile-cmd-map (make-hash-table :test 'equal))
         state)
    (puthash "/p/" "make build" projectile-compile-cmd-map)
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
      (setq state (cj/--projectile-capture-cmd 'projectile-compile-cmd-map)))
    (should (equal (plist-get state :map)
                   'projectile-compile-cmd-map))
    (should (equal (plist-get state :root) "/p/"))
    (should (equal (plist-get state :prior) "make build"))))

(ert-deftest test-dev-fkeys-projectile-capture-cmd-no-prior-stores-nil ()
  "Normal: when no cmd is cached, captures :prior nil — distinct from
\"didn't capture at all\" because :map and :root are still set."
  (let* ((projectile-test-cmd-map (make-hash-table :test 'equal))
         state)
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
      (setq state (cj/--projectile-capture-cmd 'projectile-test-cmd-map)))
    (should (eq (plist-get state :map)
                'projectile-test-cmd-map))
    (should (null (plist-get state :prior)))))

;;; Boundary Cases

(ert-deftest test-dev-fkeys-projectile-capture-cmd-nil-root-leaves-state-nil ()
  "Boundary: when no project root resolves, state stays nil so the
finish hook treats it as a no-op."
  (let ((projectile-compile-cmd-map (make-hash-table :test 'equal)))
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () nil)))
      (should-not (cj/--projectile-capture-cmd 'projectile-compile-cmd-map)))))

;;; Error Cases

(ert-deftest test-dev-fkeys-projectile-capture-cmd-unbound-map-leaves-state-nil ()
  "Error: when the cmd-map symbol is unbound (projectile not loaded),
state stays nil and no error is raised."
  (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
    ;; Use a clearly-unbound symbol to simulate projectile-not-loaded.
    (should-not
     (cj/--projectile-capture-cmd 'cj-test--definitely-not-bound-xyzzy))))

(provide 'test-dev-fkeys--projectile-capture-cmd)
;;; test-dev-fkeys--projectile-capture-cmd.el ends here