aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-28 01:11:22 -0500
committerCraig Jennings <c@cjennings.net>2026-05-28 01:11:22 -0500
commitb34909973bcf9f0fed940cab5e3192e54708ad7f (patch)
treec5a8714fbd7e22d41e4e88199b08140c2bcc5df0 /tests
parentb75e6ecc1eb0bc16ffd7f8ca6c8a42229419c8d6 (diff)
downloadpearl-b34909973bcf9f0fed940cab5e3192e54708ad7f.tar.gz
pearl-b34909973bcf9f0fed940cab5e3192e54708ad7f.zip
feat(saved): add pearl-delete-saved-query and a sentinel cancel for run
`pearl-saved-queries' was write-only from a user's perspective. Save was bound to the builder, run was bound to a key, but removing a stale entry meant `M-x customize-variable RET pearl-saved-queries RET` and a manual delete from the Customize buffer. `pearl-delete-saved-query` under `C-; L k q` (and `q` in the transient's Delete group) closes that gap: completes over the saved query names with `[ None. ]` at the top as a cancel, confirms, removes the entry, and persists via `customize-save-variable`. Linear is untouched. Saved queries are local. Pushing them up to Linear as custom views is a separate spec. While in the same path, `pearl-run-saved-query` got the same sentinel cancel. Both prompts use the keep-order completion table so `[ None. ]` stays at the top regardless of the user's completion sorter. Both error cleanly when `pearl-saved-queries` is empty rather than offering an empty picker. Six tests cover the new command (delete-on-yes, no-at-confirm, sentinel-cancels, unknown-name-errors, empty-list-errors) plus run's sentinel cancel.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-pearl-adhoc.el61
-rw-r--r--tests/test-pearl-keymap.el3
2 files changed, 63 insertions, 1 deletions
diff --git a/tests/test-pearl-adhoc.el b/tests/test-pearl-adhoc.el
index 2bcc575..2dec1a3 100644
--- a/tests/test-pearl-adhoc.el
+++ b/tests/test-pearl-adhoc.el
@@ -124,6 +124,67 @@ candidate list, so completion still works the way the framework expects."
(should (equal '(:priority 1)
(plist-get (cdr (assoc "Dup" pearl-saved-queries)) :filter))))))
+;;; pearl-delete-saved-query
+
+(ert-deftest test-pearl-delete-saved-query-removes-entry-on-yes ()
+ "Confirming the prompt removes the named entry and persists."
+ (let ((pearl-saved-queries '(("Keep" :filter (:open t))
+ ("Drop" :filter (:priority 1))))
+ (persisted nil))
+ (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
+ ((symbol-function 'customize-save-variable)
+ (lambda (&rest _) (setq persisted t))))
+ (pearl-delete-saved-query "Drop")
+ (should-not (assoc "Drop" pearl-saved-queries))
+ (should (assoc "Keep" pearl-saved-queries))
+ (should persisted))))
+
+(ert-deftest test-pearl-delete-saved-query-no-at-confirm-keeps-entry ()
+ "Declining the confirm prompt leaves the entry in place and does not persist."
+ (let ((pearl-saved-queries '(("Keep" :filter (:open t))))
+ (persisted nil))
+ (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) nil))
+ ((symbol-function 'customize-save-variable)
+ (lambda (&rest _) (setq persisted t))))
+ (pearl-delete-saved-query "Keep")
+ (should (assoc "Keep" pearl-saved-queries))
+ (should-not persisted))))
+
+(ert-deftest test-pearl-delete-saved-query-sentinel-cancels ()
+ "Picking the `pearl--filter-none' sentinel cancels without touching anything."
+ (let ((pearl-saved-queries '(("Keep" :filter (:open t))))
+ (confirmed nil))
+ (cl-letf (((symbol-function 'yes-or-no-p)
+ (lambda (&rest _) (setq confirmed t) t))
+ ((symbol-function 'customize-save-variable)
+ (lambda (&rest _) nil)))
+ (pearl-delete-saved-query pearl--filter-none)
+ (should (assoc "Keep" pearl-saved-queries))
+ (should-not confirmed))))
+
+(ert-deftest test-pearl-delete-saved-query-unknown-name-errors ()
+ "An unknown name (e.g. typed past completion) signals a user-error."
+ (let ((pearl-saved-queries '(("Keep" :filter (:open t)))))
+ (should-error (pearl-delete-saved-query "Nope") :type 'user-error)))
+
+(ert-deftest test-pearl-delete-saved-query-empty-list-errors-on-interactive ()
+ "Called interactively with no saved queries, the command errors cleanly
+rather than offering an empty picker."
+ (let ((pearl-saved-queries nil))
+ (should-error (call-interactively #'pearl-delete-saved-query)
+ :type 'user-error)))
+
+;;; pearl-run-saved-query sentinel cancel
+
+(ert-deftest test-pearl-run-saved-query-sentinel-cancels ()
+ "Picking the `pearl--filter-none' sentinel cancels the run without fetching."
+ (let ((fetched nil)
+ (pearl-saved-queries '(("Open" :filter (:open t)))))
+ (cl-letf (((symbol-function 'pearl--query-issues-async)
+ (lambda (&rest _) (setq fetched t))))
+ (should-error (pearl-run-saved-query pearl--filter-none) :type 'user-error)
+ (should-not fetched))))
+
;;; pearl-list-issues-filtered
(ert-deftest test-pearl-list-issues-filtered-runs-with-source ()
diff --git a/tests/test-pearl-keymap.el b/tests/test-pearl-keymap.el
index 5cc658d..d04e309 100644
--- a/tests/test-pearl-keymap.el
+++ b/tests/test-pearl-keymap.el
@@ -89,7 +89,8 @@ The lowercase `c' is no longer a direct command -- it is the create prefix."
(should (eq 'pearl-create-issue (lookup-key pearl-prefix-map (kbd "c t"))))
(should (eq 'pearl-create-comment (lookup-key pearl-prefix-map (kbd "c c"))))
(should (eq 'pearl-delete-current-issue (lookup-key pearl-prefix-map (kbd "k t"))))
- (should (eq 'pearl-delete-current-comment (lookup-key pearl-prefix-map (kbd "k c")))))
+ (should (eq 'pearl-delete-current-comment (lookup-key pearl-prefix-map (kbd "k c"))))
+ (should (eq 'pearl-delete-saved-query (lookup-key pearl-prefix-map (kbd "k q")))))
(ert-deftest test-pearl-prefix-map-open-and-copy-groups ()
"The open group resolves the two open actions; copy resolves copy-url."