aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-pearl-adhoc.el114
-rw-r--r--tests/test-pearl-save.el8
2 files changed, 87 insertions, 35 deletions
diff --git a/tests/test-pearl-adhoc.el b/tests/test-pearl-adhoc.el
index 2dec1a3..558578a 100644
--- a/tests/test-pearl-adhoc.el
+++ b/tests/test-pearl-adhoc.el
@@ -28,34 +28,43 @@
(require 'test-bootstrap (expand-file-name "test-bootstrap.el"))
(require 'cl-lib)
-;;; --filter-none sentinel helpers
-
-(ert-deftest test-pearl-filter-none-value-p-recognizes-sentinel ()
- "The sentinel string reads as a `no constraint' value."
- (should (pearl--filter-none-value-p pearl--filter-none)))
-
-(ert-deftest test-pearl-filter-none-value-p-recognizes-empty-and-nil ()
- "Empty input and nil also read as `no constraint' (for back-compat)."
- (should (pearl--filter-none-value-p ""))
- (should (pearl--filter-none-value-p nil)))
-
-(ert-deftest test-pearl-filter-none-value-p-rejects-real-values ()
- "An actual picked value does not read as `no constraint'."
- (should-not (pearl--filter-none-value-p "In Progress"))
- (should-not (pearl--filter-none-value-p "Platform"))
- (should-not (pearl--filter-none-value-p "bug")))
-
-(ert-deftest test-pearl-with-none-prepends-sentinel ()
- "`pearl--with-none' puts the sentinel first so it sits at the top of the
-completing-read candidate list."
- (let ((wrapped (pearl--with-none '("alpha" "beta"))))
- (should (string= pearl--filter-none (car wrapped)))
- (should (equal '("alpha" "beta") (cdr wrapped)))))
-
-(ert-deftest test-pearl-with-none-empty-list-yields-just-the-sentinel ()
+;;; sentinel helpers
+
+(ert-deftest test-pearl-filter-sentinel-value-p-recognizes-any-and-cancel ()
+ "Both opt-out sentinels read as sentinel values."
+ (should (pearl--filter-sentinel-value-p pearl--filter-any))
+ (should (pearl--filter-sentinel-value-p pearl--filter-cancel)))
+
+(ert-deftest test-pearl-filter-sentinel-value-p-recognizes-empty-and-nil ()
+ "Empty input and nil also read as opt-out (back-compat for the legacy
+empty-input idiom and for callers that pass nil)."
+ (should (pearl--filter-sentinel-value-p ""))
+ (should (pearl--filter-sentinel-value-p nil)))
+
+(ert-deftest test-pearl-filter-sentinel-value-p-rejects-real-values ()
+ "An actual picked value does not read as opt-out."
+ (should-not (pearl--filter-sentinel-value-p "In Progress"))
+ (should-not (pearl--filter-sentinel-value-p "Platform"))
+ (should-not (pearl--filter-sentinel-value-p "bug")))
+
+(ert-deftest test-pearl-filter-any-and-cancel-are-distinct-strings ()
+ "The two sentinels carry different labels so the prompt reads accurately
+for its case: \"any\" for filter dimensions, \"cancel\" for pick-an-existing."
+ (should-not (string= pearl--filter-any pearl--filter-cancel)))
+
+(ert-deftest test-pearl-with-sentinel-prepends-the-given-sentinel ()
+ "`pearl--with-sentinel' puts SENTINEL first so it sits at the top of the
+candidate list."
+ (let ((wrapped-any (pearl--with-sentinel pearl--filter-any '("alpha" "beta"))))
+ (should (string= pearl--filter-any (car wrapped-any)))
+ (should (equal '("alpha" "beta") (cdr wrapped-any))))
+ (let ((wrapped-cancel (pearl--with-sentinel pearl--filter-cancel '("a" "b"))))
+ (should (string= pearl--filter-cancel (car wrapped-cancel)))))
+
+(ert-deftest test-pearl-with-sentinel-empty-list-yields-just-the-sentinel ()
"An empty candidate list still yields a one-element list with the sentinel."
- (let ((wrapped (pearl--with-none '())))
- (should (equal (list pearl--filter-none) wrapped))))
+ (let ((wrapped (pearl--with-sentinel pearl--filter-any '())))
+ (should (equal (list pearl--filter-any) wrapped))))
(ert-deftest test-pearl-completion-table-keep-order-metadata-pins-identity ()
"Action `metadata' returns an alist with `display-sort-function' bound to
@@ -66,6 +75,49 @@ completing-read candidate list."
(should (eq #'identity (alist-get 'display-sort-function (cdr meta))))
(should (eq #'identity (alist-get 'cycle-sort-function (cdr meta))))))
+(ert-deftest test-pearl-read-yes-no-returns-t-for-yes ()
+ "A `yes' choice returns t."
+ (cl-letf (((symbol-function 'completing-read) (lambda (&rest _) "yes")))
+ (should (eq t (pearl--read-yes-no "Anything? ")))))
+
+(ert-deftest test-pearl-read-yes-no-returns-nil-for-no ()
+ "A `no' choice returns nil."
+ (cl-letf (((symbol-function 'completing-read) (lambda (&rest _) "no")))
+ (should-not (pearl--read-yes-no "Anything? "))))
+
+(ert-deftest test-pearl-read-yes-no-default-passed-as-default-arg ()
+ "The DEFAULT argument is the value RET takes without typing; the helper
+forwards it as completing-read's default so the framework highlights it."
+ (let (forwarded-default)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (&rest args) (setq forwarded-default (nth 6 args)) "no")))
+ (pearl--read-yes-no "?" "no")
+ (should (string= "no" forwarded-default)))))
+
+(ert-deftest test-pearl-read-yes-no-default-yes-orders-yes-first ()
+ "With the default `yes' (the omitted-arg case), the candidate list is
+ordered yes-then-no so the most-common choice sits at the top."
+ (let (captured-collection)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (_p coll &rest _)
+ (setq captured-collection
+ (when (functionp coll) (all-completions "" coll)))
+ "yes")))
+ (pearl--read-yes-no "?")
+ (should (equal '("yes" "no") captured-collection)))))
+
+(ert-deftest test-pearl-read-yes-no-default-no-orders-no-first ()
+ "With DEFAULT \"no\", the candidate list is ordered no-then-yes so a
+non-affirmative default is what the user lands on."
+ (let (captured-collection)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (_p coll &rest _)
+ (setq captured-collection
+ (when (functionp coll) (all-completions "" coll)))
+ "no")))
+ (pearl--read-yes-no "?" "no")
+ (should (equal '("no" "yes") captured-collection)))))
+
(ert-deftest test-pearl-completion-table-keep-order-delegates-all-completions ()
"Non-metadata actions delegate to `complete-with-action' over the original
candidate list, so completion still works the way the framework expects."
@@ -151,14 +203,14 @@ candidate list, so completion still works the way the framework expects."
(should-not persisted))))
(ert-deftest test-pearl-delete-saved-query-sentinel-cancels ()
- "Picking the `pearl--filter-none' sentinel cancels without touching anything."
+ "Picking the `pearl--filter-cancel' 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)
+ (pearl-delete-saved-query pearl--filter-cancel)
(should (assoc "Keep" pearl-saved-queries))
(should-not confirmed))))
@@ -177,12 +229,12 @@ rather than offering an empty picker."
;;; 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."
+ "Picking the `pearl--filter-cancel' 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-error (pearl-run-saved-query pearl--filter-cancel) :type 'user-error)
(should-not fetched))))
;;; pearl-list-issues-filtered
diff --git a/tests/test-pearl-save.el b/tests/test-pearl-save.el
index 47b48c2..b82ca04 100644
--- a/tests/test-pearl-save.el
+++ b/tests/test-pearl-save.el
@@ -755,7 +755,7 @@ description hash is left untouched and the title still saved."
(test-pearl-save--in-two-issues
(let ((prompted nil) (fetched nil))
(test-pearl-save--with-net
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) (setq prompted t) t))
+ (cl-letf (((symbol-function 'pearl--read-yes-no) (lambda (&rest _) (setq prompted t) t))
((symbol-function 'pearl--fetch-issue-description-async)
(lambda (&rest _) (setq fetched t))))
(pearl-save-all)
@@ -770,7 +770,7 @@ description hash is left untouched and the title still saved."
(end-of-line) (insert " EDITED"))
(goto-char (point-min))
(test-pearl-save--with-net
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) t))
+ (cl-letf (((symbol-function 'pearl--read-yes-no) (lambda (&rest _) t))
((symbol-function 'pearl--fetch-issue-description-async)
(lambda (_id cb) (funcall cb '(:description "Body." :updated-at "t0")))))
(pearl-save-all)
@@ -783,7 +783,7 @@ description hash is left untouched and the title still saved."
(end-of-line) (insert " EDITED"))
(goto-char (point-min))
(test-pearl-save--with-net
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) nil))
+ (cl-letf (((symbol-function 'pearl--read-yes-no) (lambda (&rest _) nil))
((symbol-function 'pearl--fetch-issue-description-async)
(lambda (_id cb) (funcall cb '(:description "Body." :updated-at "t0")))))
(pearl-save-all)
@@ -803,7 +803,7 @@ description hash is left untouched and the title still saved."
(end-of-line) (insert " EDITED"))
(goto-char (point-min))
(test-pearl-save--with-net
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) t))
+ (cl-letf (((symbol-function 'pearl--read-yes-no) (lambda (&rest _) t))
((symbol-function 'pearl--fetch-issue-description-async)
(lambda (_id cb) (funcall cb '(:description "Body." :updated-at "t0")))))
(pearl-save-all)