Integrated repository, worktree, git stacker, and project manager
0

Configure Feed

Select the types of activity you want to include in your feed.

emacs: ERT tests for the pm-serve sidebar

Cover the pure pieces of pm-serve: the SOURCE&EMACS instance-scoping filter
query, session-key derivation, the snapshot/update/remove SSE handlers
(render stubbed) against the session table, and the fit pad/ellipsize
invariant.

Jordan Isaacs (Jun 22, 2026, 8:06 PM UTC) a5097968 2d4c5ffc

+65 -1
+65 -1
integrations/emacs/pm-tests.el
··· 25 25 (require 'pm-table) 26 26 27 27 ;; magit-section is required for `pm-status', `pm-list', `pm-pool', 28 - ;; `pm-repo', `pm-agent'. Tests that touch those modules guard on it. 28 + ;; `pm-repo', `pm-agent', `pm-serve'. Tests that touch those modules guard 29 + ;; on it. 29 30 (defconst pm-test--has-magit-section 30 31 (require 'magit-section nil t)) 31 32 (when pm-test--has-magit-section ··· 34 35 (require 'pm-pool) 35 36 (require 'pm-repo) 36 37 (require 'pm-agent) 38 + (require 'pm-serve) 37 39 (require 'pm-stacker)) 38 40 39 41 (defmacro pm-test--with-fixture (var &rest body) ··· 1051 1053 (pm--stacker-pr-unlink "kms" nil t #'ignore) 1052 1054 (should (equal argv 1053 1055 '("stacker" "pr" "unlink" "--all" "--repo" "kms" "--json"))))))) 1056 + 1057 + ;;;; pm-serve sidebar 1058 + 1059 + (when pm-test--has-magit-section 1060 + (ert-deftest pm-test--serve-filter-query-scopes-to-instance () 1061 + "The SSE filter pins SOURCE and the launching Emacs instance (EMACS)." 1062 + (let* ((pm-agent-serve-source "emacs") 1063 + (q (pm-serve--filter-query))) 1064 + (should (string-match-p "meta\\.SOURCE=emacs" q)) 1065 + (should (string-match-p (format "meta\\.EMACS=%d" (emacs-pid)) q)))) 1066 + 1067 + (ert-deftest pm-test--serve-session-key () 1068 + "Sessions are keyed by agent + NUL + vendor id; missing fields are empty." 1069 + (should (equal (pm-serve--session-key '((agent . "claude") (vendor_session_id . "s1"))) 1070 + (concat "claude" "\0" "s1"))) 1071 + (should (equal (pm-serve--session-key '((agent . "codex") (vendor_session_id . "x"))) 1072 + (concat "codex" "\0" "x"))) 1073 + (should (equal (pm-serve--session-key '()) (concat "" "\0" "")))) 1074 + 1075 + (ert-deftest pm-test--serve-handle-snapshot-populates () 1076 + "A snapshot clears and repopulates the session table." 1077 + (cl-letf (((symbol-function 'pm-serve--render) #'ignore)) 1078 + (let ((pm-serve--sessions (make-hash-table :test 'equal))) 1079 + (puthash "stale" '((agent . "x")) pm-serve--sessions) 1080 + (pm-serve--handle 1081 + (concat "{\"type\":\"snapshot\",\"sessions\":[" 1082 + "{\"agent\":\"claude\",\"vendor_session_id\":\"s1\"}," 1083 + "{\"agent\":\"codex\",\"vendor_session_id\":\"s2\"}]}")) 1084 + (should (= 2 (hash-table-count pm-serve--sessions))) 1085 + (should (gethash (concat "claude" "\0" "s1") pm-serve--sessions)) 1086 + (should (gethash (concat "codex" "\0" "s2") pm-serve--sessions)) 1087 + (should-not (gethash "stale" pm-serve--sessions))))) 1088 + 1089 + (ert-deftest pm-test--serve-handle-update-upserts () 1090 + "An update inserts then replaces the same key in place (no duplicates)." 1091 + (cl-letf (((symbol-function 'pm-serve--render) #'ignore)) 1092 + (let ((pm-serve--sessions (make-hash-table :test 'equal)) 1093 + (key (concat "claude" "\0" "s1"))) 1094 + (pm-serve--handle 1095 + "{\"type\":\"update\",\"session\":{\"agent\":\"claude\",\"vendor_session_id\":\"s1\",\"status\":\"working\"}}") 1096 + (should (equal (alist-get 'status (gethash key pm-serve--sessions)) "working")) 1097 + (pm-serve--handle 1098 + "{\"type\":\"update\",\"session\":{\"agent\":\"claude\",\"vendor_session_id\":\"s1\",\"status\":\"idle\"}}") 1099 + (should (= 1 (hash-table-count pm-serve--sessions))) 1100 + (should (equal (alist-get 'status (gethash key pm-serve--sessions)) "idle"))))) 1101 + 1102 + (ert-deftest pm-test--serve-handle-remove-deletes () 1103 + "A remove event drops the session keyed by its top-level agent/vendor id." 1104 + (cl-letf (((symbol-function 'pm-serve--render) #'ignore)) 1105 + (let ((pm-serve--sessions (make-hash-table :test 'equal))) 1106 + (pm-serve--handle 1107 + "{\"type\":\"update\",\"session\":{\"agent\":\"claude\",\"vendor_session_id\":\"s1\"}}") 1108 + (should (= 1 (hash-table-count pm-serve--sessions))) 1109 + (pm-serve--handle "{\"type\":\"remove\",\"agent\":\"claude\",\"vendor_session_id\":\"s1\"}") 1110 + (should (= 0 (hash-table-count pm-serve--sessions)))))) 1111 + 1112 + (ert-deftest pm-test--serve-fit-pads-and-truncates () 1113 + "`pm-serve--fit' returns exactly WIDTH chars: pad short, ellipsize long." 1114 + (let ((short (pm-serve--fit "hi" 6))) 1115 + (should (= (length short) 6)) 1116 + (should (string-prefix-p "hi" short))) 1117 + (should (= (length (pm-serve--fit "abcdefghij" 5)) 5)))) 1054 1118 1055 1119 (provide 'pm-tests) 1056 1120