diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-25 21:22:27 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-25 21:22:27 -0500 |
| commit | 60b51e1c996f1c8f152696946b9440f26ea9a956 (patch) | |
| tree | 3154332cc2b7d5bb3e0eb71a812d9effc8c46633 /tests/test-pearl-assignee-labels.el | |
| parent | f9841539b3adb192d0c15470fa9c31d6cbbdf447 (diff) | |
| download | pearl-60b51e1c996f1c8f152696946b9440f26ea9a956.tar.gz pearl-60b51e1c996f1c8f152696946b9440f26ea9a956.zip | |
refactor(save): retire the immediate-push field setters for buffer-editors
The structured fields now reconcile at save (the previous commits), so the immediate-push setters are the duplicate path that made the package feel like it had two save models. I retired them. pearl-set-priority is deleted outright — priority is edited org-natively through the heading cookie. pearl-set-state, pearl-set-assignee, and pearl-set-labels become pearl-edit-state / -assignee / -labels: the same completing-read picker, but it writes the buffer representation (keyword/name/id, the assignee drawer, the labels drawer plus the live LINEAR-LABEL-IDS set) and marks the field dirty instead of pushing. The change goes out at the next pearl-save-issue / pearl-save-all. pearl-compose-current-description is renamed pearl-edit-description (its compose-and-push behavior is unchanged — v2 doesn't touch the compose buffers).
The transient, the C-; L e keymap, the affordance preamble, and the README follow the new names, and the priority slots are dropped (no command — it's the org cookie). Deleting the setters left pearl--push-issue-field and pearl--priority-choices with no callers, so both are gone, along with the killed-buffer test that only exercised the removed helper. I filed a follow-up: the atomic savers' async commit callbacks need the same killed-buffer guard that helper carried.
The setter command tests are rewritten to assert the buffer-write-and-no-push contract. The reconcile-and-push path they used to cover is exercised in test-pearl-save.
Diffstat (limited to 'tests/test-pearl-assignee-labels.el')
| -rw-r--r-- | tests/test-pearl-assignee-labels.el | 121 |
1 files changed, 43 insertions, 78 deletions
diff --git a/tests/test-pearl-assignee-labels.el b/tests/test-pearl-assignee-labels.el index 7a4a352..e7be619 100644 --- a/tests/test-pearl-assignee-labels.el +++ b/tests/test-pearl-assignee-labels.el @@ -19,10 +19,11 @@ ;;; Commentary: -;; Tests for the two drawer-field commands that resolve names to ids: -;; `pearl-set-assignee' and `pearl-set-labels'. They push via -;; the generic `--update-issue-async' and update the LINEAR-ASSIGNEE / LABELS -;; drawer. The resolver and the mutation are stubbed. +;; Tests for the two picker commands that resolve names to ids: +;; `pearl-edit-assignee' and `pearl-edit-labels'. As save-model-v2 +;; buffer-editors they write the LINEAR-ASSIGNEE / LABELS drawer (and the live +;; id sets) but do NOT push -- the change reconciles at the next save (the push +;; path is covered in test-pearl-save). The resolver is stubbed. ;;; Code: @@ -38,57 +39,38 @@ (goto-char (point-min)) ,@body)) -;;; set-assignee +;;; edit-assignee (buffer-editor: writes the drawer, no push) -(ert-deftest test-pearl-set-assignee-pushes-id-and-updates-drawer () - "Setting an assignee resolves the name, pushes the id, and updates the drawer." +(ert-deftest test-pearl-edit-assignee-writes-drawer-no-push () + "edit-assignee resolves the name, writes the drawer, and does not push." (let ((pushed nil)) (test-pearl--in-org "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-ASSIGNEE-ID: old\n:LINEAR-ASSIGNEE-NAME: Someone\n:END:\n" (cl-letf (((symbol-function 'pearl--resolve-team-id) (lambda (_kind _name _team &optional _force) "u9")) ((symbol-function 'pearl--update-issue-async) - (lambda (_id input cb) (setq pushed input) (funcall cb '(:success t))))) - (pearl-set-assignee "Craig") - (should (string= "u9" (cdr (assoc "assigneeId" pushed)))) + (lambda (&rest _) (setq pushed t)))) + (pearl-edit-assignee "Craig") + (should-not pushed) (should (string= "Craig" (org-entry-get nil "LINEAR-ASSIGNEE-NAME"))) (should (string= "u9" (org-entry-get nil "LINEAR-ASSIGNEE-ID"))))))) -(ert-deftest test-pearl-set-assignee-unresolvable-errors () - "An unresolvable assignee name signals a user error and pushes nothing." - (let ((pushed nil)) - (test-pearl--in-org - "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:END:\n" - (cl-letf (((symbol-function 'pearl--resolve-team-id) - (lambda (&rest _) nil)) - ((symbol-function 'pearl--update-issue-async) - (lambda (&rest _) (setq pushed t)))) - (should-error (pearl-set-assignee "Nobody") :type 'user-error) - (should-not pushed))))) +(ert-deftest test-pearl-edit-assignee-unresolvable-errors () + "An unresolvable assignee name signals a user error and writes nothing." + (test-pearl--in-org + "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:END:\n" + (cl-letf (((symbol-function 'pearl--resolve-team-id) (lambda (&rest _) nil))) + (should-error (pearl-edit-assignee "Nobody") :type 'user-error)))) -(ert-deftest test-pearl-set-assignee-not-on-issue-errors () - "Setting an assignee outside a Linear issue heading signals a user error." +(ert-deftest test-pearl-edit-assignee-not-on-issue-errors () + "edit-assignee outside a Linear issue heading signals a user error." (test-pearl--in-org "* Plain heading\nno id\n" - (should-error (pearl-set-assignee "Craig") :type 'user-error))) - -(ert-deftest test-pearl-set-assignee-failure-preserves-drawer () - "A failed assignee push attempts the mutation but leaves the drawer unchanged." - (let (pushed) - (test-pearl--in-org - "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-ASSIGNEE-ID: old\n:LINEAR-ASSIGNEE-NAME: Someone\n:END:\n" - (cl-letf (((symbol-function 'pearl--resolve-team-id) - (lambda (_kind _name _team &optional _force) "u9")) - ((symbol-function 'pearl--update-issue-async) - (lambda (_id input cb) (setq pushed input) (funcall cb '(:success nil))))) - (pearl-set-assignee "Craig") - (should (string= "u9" (cdr (assoc "assigneeId" pushed)))) - (should (string= "Someone" (org-entry-get nil "LINEAR-ASSIGNEE-NAME"))) - (should (string= "old" (org-entry-get nil "LINEAR-ASSIGNEE-ID"))))))) + (should-error (pearl-edit-assignee "Craig") :type 'user-error))) -;;; set-labels +;;; edit-labels (buffer-editor: writes the drawer + live ids, no push) -(ert-deftest test-pearl-set-labels-pushes-ids-and-updates-drawer () - "Setting labels resolves each name, pushes the id list, and updates the drawer." +(ert-deftest test-pearl-edit-labels-writes-names-and-ids-no-push () + "edit-labels resolves each name, writes LINEAR-LABELS + LINEAR-LABEL-IDS, no push." (let ((pushed nil)) (test-pearl--in-org "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-LABELS: []\n:END:\n" @@ -96,47 +78,30 @@ (lambda (_kind name _team &optional _force) (pcase name ("bug" "l1") ("p1" "l2") (_ nil)))) ((symbol-function 'pearl--update-issue-async) - (lambda (_id input cb) (setq pushed input) (funcall cb '(:success t))))) - (pearl-set-labels '("bug" "p1")) - (should (equal '("l1" "l2") (cdr (assoc "labelIds" pushed)))) - (should (string= "[bug, p1]" (org-entry-get nil "LINEAR-LABELS"))))))) - -(ert-deftest test-pearl-set-labels-clear-pushes-empty () - "Clearing labels (empty list) pushes an empty id list and empties the drawer." - (let ((pushed 'unset)) - (test-pearl--in-org - "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-LABELS: [bug]\n:END:\n" - (cl-letf (((symbol-function 'pearl--update-issue-async) - (lambda (_id input cb) (setq pushed input) (funcall cb '(:success t))))) - (pearl-set-labels '()) - (should (equal '() (cdr (assoc "labelIds" pushed)))) - (should (string= "[]" (org-entry-get nil "LINEAR-LABELS"))))))) + (lambda (&rest _) (setq pushed t)))) + (pearl-edit-labels '("bug" "p1")) + (should-not pushed) + (should (string= "[bug, p1]" (org-entry-get nil "LINEAR-LABELS"))) + (should (string= "l1 l2" (org-entry-get nil "LINEAR-LABEL-IDS"))))))) -(ert-deftest test-pearl-set-labels-unresolvable-errors () - "An unresolvable label name signals a user error and pushes nothing." +(ert-deftest test-pearl-edit-labels-clear-writes-empty () + "Clearing labels writes an empty drawer and empty id set, no push." (let ((pushed nil)) (test-pearl--in-org - "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:END:\n" - (cl-letf (((symbol-function 'pearl--resolve-team-id) - (lambda (&rest _) nil)) - ((symbol-function 'pearl--update-issue-async) + "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-LABELS: [bug]\n:LINEAR-LABEL-IDS: l1\n:END:\n" + (cl-letf (((symbol-function 'pearl--update-issue-async) (lambda (&rest _) (setq pushed t)))) - (should-error (pearl-set-labels '("ghost")) :type 'user-error) - (should-not pushed))))) - -(ert-deftest test-pearl-set-labels-failure-preserves-drawer () - "A failed labels push attempts the mutation but leaves the labels drawer unchanged." - (let (pushed) - (test-pearl--in-org - "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:LINEAR-LABELS: [bug]\n:END:\n" - (cl-letf (((symbol-function 'pearl--resolve-team-id) - (lambda (_kind name _team &optional _force) - (pcase name ("p1" "l2") (_ nil)))) - ((symbol-function 'pearl--update-issue-async) - (lambda (_id input cb) (setq pushed input) (funcall cb '(:success nil))))) - (pearl-set-labels '("p1")) - (should (equal '("l2") (cdr (assoc "labelIds" pushed)))) - (should (string= "[bug]" (org-entry-get nil "LINEAR-LABELS"))))))) + (pearl-edit-labels '()) + (should-not pushed) + (should (string= "[]" (org-entry-get nil "LINEAR-LABELS"))) + (should (string= "" (org-entry-get nil "LINEAR-LABEL-IDS"))))))) + +(ert-deftest test-pearl-edit-labels-unresolvable-errors () + "An unresolvable label name signals a user error and writes nothing." + (test-pearl--in-org + "*** TODO Title\n:PROPERTIES:\n:LINEAR-ID: a\n:LINEAR-TEAM-ID: team-1\n:END:\n" + (cl-letf (((symbol-function 'pearl--resolve-team-id) (lambda (&rest _) nil))) + (should-error (pearl-edit-labels '("ghost")) :type 'user-error)))) (provide 'test-pearl-assignee-labels) ;;; test-pearl-assignee-labels.el ends here |
