diff options
| -rw-r--r-- | pearl.el | 25 | ||||
| -rw-r--r-- | tests/test-pearl-adhoc.el | 40 |
2 files changed, 57 insertions, 8 deletions
@@ -4168,15 +4168,24 @@ an id), or `pearl--filter-any' (any assignee, no scoping)." (team-id (and (not (pearl--filter-sentinel-value-p team-name)) (pearl--get-team-id-by-name team-name))) (open (pearl--read-yes-no "Open issues only? ")) + ;; Multi-select, like the Labels prompt: pick one or several states. + ;; One picked -> a string (`:state' scalar); several -> a list + ;; (`state.name.in'); none -> no state constraint. (state (and team-id - (let ((s (completing-read - "State: " - (pearl--completion-table-keep-order - (pearl--with-sentinel pearl--filter-any - (mapcar (lambda (st) (cdr (assoc 'name st))) - (pearl--team-states team-id)))) - nil t))) - (unless (pearl--filter-sentinel-value-p s) s)))) + (let ((picked + (cl-remove + pearl--filter-any + (completing-read-multiple + "States (comma-separated): " + (pearl--completion-table-keep-order + (pearl--with-sentinel pearl--filter-any + (mapcar (lambda (st) (cdr (assoc 'name st))) + (pearl--team-states team-id)))) + nil t) + :test #'string=))) + (cond ((null picked) nil) + ((= 1 (length picked)) (car picked)) + (t picked))))) (project (and team-id (let ((p (completing-read "Project: " diff --git a/tests/test-pearl-adhoc.el b/tests/test-pearl-adhoc.el index 68a920c..0c87add 100644 --- a/tests/test-pearl-adhoc.el +++ b/tests/test-pearl-adhoc.el @@ -266,5 +266,45 @@ rather than offering an empty picker." (pearl-list-issues-filtered '(:open t) "Saved adhoc") (should (assoc "Saved adhoc" pearl-local-views))))) +;;; builder State prompt is multi-select (multi-state filter spec, phase 2) + +(defun test-pearl-adhoc--build-with-states (state-picks) + "Run `pearl--read-filter-interactively' stubbed so only State varies. +STATE-PICKS is the list the State `completing-read-multiple' returns; every +other dimension resolves to no constraint. Returns the filter plist." + (cl-letf (((symbol-function 'pearl--all-teams) + (lambda () '(((id . "t1") (key . "ENG") (name . "Engineering"))))) + ((symbol-function 'pearl--get-team-id-by-name) (lambda (&rest _) "t1")) + ((symbol-function 'pearl--read-yes-no) (lambda (&rest _) nil)) + ((symbol-function 'pearl--team-states) + (lambda (&rest _) + '(((name . "Todo")) ((name . "In Review")) ((name . "Done"))))) + ((symbol-function 'pearl--team-collection-names) (lambda (&rest _) nil)) + ((symbol-function 'pearl--resolve-team-id) (lambda (&rest _) nil)) + ((symbol-function 'completing-read) + (lambda (prompt &rest _) + (if (string-prefix-p "Team" prompt) "Engineering" pearl--filter-any))) + ((symbol-function 'completing-read-multiple) + (lambda (prompt &rest _) + (if (string-prefix-p "States" prompt) + (copy-sequence state-picks) + (list pearl--filter-any))))) + (pearl--read-filter-interactively))) + +(ert-deftest test-pearl-adhoc-builder-state-multi-yields-list () + "Picking two states yields a list-valued :state." + (should (equal (plist-get (test-pearl-adhoc--build-with-states '("Todo" "In Review")) + :state) + '("Todo" "In Review")))) + +(ert-deftest test-pearl-adhoc-builder-state-one-yields-string () + "Picking one state yields a scalar :state." + (should (equal (plist-get (test-pearl-adhoc--build-with-states '("Todo")) :state) + "Todo"))) + +(ert-deftest test-pearl-adhoc-builder-state-none-yields-no-key () + "Picking no state leaves :state out of the filter." + (should-not (plist-member (test-pearl-adhoc--build-with-states '()) :state))) + (provide 'test-pearl-adhoc) ;;; test-pearl-adhoc.el ends here |
