aboutsummaryrefslogtreecommitdiff
path: root/tests/test-dev-fkeys--projectile-capture-cmd.el
blob: 92309198eca189712fe8e4fae9197e4ae94b8657 (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
68
69
70
;;; 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
;; `cj/--projectile-revert-state' 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* ((cj/--projectile-revert-state nil)
         (projectile-compile-cmd-map (make-hash-table :test 'equal)))
    (puthash "/p/" "make build" projectile-compile-cmd-map)
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
      (cj/--projectile-capture-cmd 'projectile-compile-cmd-map))
    (should (equal (plist-get cj/--projectile-revert-state :map)
                   'projectile-compile-cmd-map))
    (should (equal (plist-get cj/--projectile-revert-state :root) "/p/"))
    (should (equal (plist-get cj/--projectile-revert-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* ((cj/--projectile-revert-state nil)
         (projectile-test-cmd-map (make-hash-table :test 'equal)))
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
      (cj/--projectile-capture-cmd 'projectile-test-cmd-map))
    (should (eq (plist-get cj/--projectile-revert-state :map)
                'projectile-test-cmd-map))
    (should (null (plist-get cj/--projectile-revert-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 ((cj/--projectile-revert-state nil)
        (projectile-compile-cmd-map (make-hash-table :test 'equal)))
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () nil)))
      (cj/--projectile-capture-cmd 'projectile-compile-cmd-map))
    (should (null cj/--projectile-revert-state))))

;;; 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."
  (let ((cj/--projectile-revert-state nil))
    (cl-letf (((symbol-function 'cj/--f4-project-root) (lambda () "/p/")))
      ;; Use a clearly-unbound symbol to simulate projectile-not-loaded.
      (cj/--projectile-capture-cmd 'cj-test--definitely-not-bound-xyzzy))
    (should (null cj/--projectile-revert-state))))

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