From a74334bc9a321ddbb9b2ba81266f264d3522cc8c Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 27 May 2026 19:19:35 -0500 Subject: refactor: verb-align command names and prefixes, use issue not ticket The keybinding prefixes now each name an action verb: f fetch, e edit, c create, k delete, o open, y copy. The url group is gone, its actions split into open and copy, and the direct lowercase c (new comment) is dropped so c can head the create group. Two commands carried non-verb names, so I renamed them: pearl-new-issue is now pearl-create-issue and pearl-add-comment is now pearl-create-comment. The old sync helper that already held the pearl-create-issue name moved to the private pearl--create-issue, where it belongs as internal plumbing. I also swept "ticket" to "issue" across the labels, transient, docstrings, and README. Linear's own term is "issue" and the buffer mirrors Linear, so the command names already said "issue" while the labels said "ticket". Now they agree. The transient's per-entry keys still trail the keymap verbs, which stays its own task. --- tests/test-integration-acceptance.el | 4 +-- tests/test-pearl-commands.el | 10 ++++---- tests/test-pearl-comment-editing.el | 4 +-- tests/test-pearl-comments.el | 16 ++++++------ tests/test-pearl-compose.el | 10 ++++---- tests/test-pearl-keymap.el | 50 ++++++++++++++++++------------------ tests/test-pearl-menu.el | 4 +-- tests/test-pearl-save.el | 2 +- tests/test-pearl-smoke.el | 2 +- tests/test-pearl-sync-wrappers.el | 4 +-- 10 files changed, 53 insertions(+), 53 deletions(-) (limited to 'tests') diff --git a/tests/test-integration-acceptance.el b/tests/test-integration-acceptance.el index 48dd70a..37dce34 100644 --- a/tests/test-integration-acceptance.el +++ b/tests/test-integration-acceptance.el @@ -36,7 +36,7 @@ ;; - --read-active-source / --build-org-content header round-trip ;; - pearl-refresh-current-view -> --merge-query-result (in-place merge) ;; - pearl-sync-current-issue -> --sync-decision -> --update-issue-description-async -;; - pearl-add-comment -> --create-comment-async -> --append-comment-to-issue +;; - pearl-create-comment -> --create-comment-async -> --append-comment-to-issue ;; - edit the priority cookie + pearl-save-issue -> --save-priority-field -> --update-issue-async ;;; Code: @@ -189,7 +189,7 @@ because the description-update mutation contains both `IssueDescription' and (goto-char (point-min)) (re-search-forward "First issue") (setq test-integration--ops nil) - (pearl-add-comment "looks good") + (pearl-create-comment "looks good") (should (memq 'comment-create test-integration--ops)) (goto-char (point-min)) (should (re-search-forward "^\\*\\*\\* 💬 Comments 1/1$" nil t)) diff --git a/tests/test-pearl-commands.el b/tests/test-pearl-commands.el index 77f2d46..ccd39c8 100644 --- a/tests/test-pearl-commands.el +++ b/tests/test-pearl-commands.el @@ -98,9 +98,9 @@ (pearl-list-issues-by-project) (should-not called)))) -;;; pearl-new-issue +;;; pearl-create-issue -(ert-deftest test-pearl-new-issue-success-returns-issue () +(ert-deftest test-pearl-create-issue-success-returns-issue () "new-issue builds the input, sends it, and returns the created issue." (let ((pearl-default-team-id "team-1")) (cl-letf (((symbol-function 'read-string) @@ -120,13 +120,13 @@ (lambda (_q &optional _v) '((data (issueCreate (success . t) (issue (id . "i1") (identifier . "ENG-1") (title . "My Issue")))))))) - (should (string-equal "ENG-1" (cdr (assoc 'identifier (pearl-new-issue)))))))) + (should (string-equal "ENG-1" (cdr (assoc 'identifier (pearl-create-issue)))))))) -(ert-deftest test-pearl-new-issue-no-team-stops () +(ert-deftest test-pearl-create-issue-no-team-stops () "new-issue stops cleanly when no team is selected." (let ((pearl-default-team-id nil)) (cl-letf (((symbol-function 'pearl-select-team) (lambda () nil))) - (should (progn (pearl-new-issue) t))))) + (should (progn (pearl-create-issue) t))))) ;;; pearl-test-connection / check-setup diff --git a/tests/test-pearl-comment-editing.el b/tests/test-pearl-comment-editing.el index 4853548..5d5204a 100644 --- a/tests/test-pearl-comment-editing.el +++ b/tests/test-pearl-comment-editing.el @@ -328,7 +328,7 @@ the refresh / add-comment / view-merge paths, never on the initial render." (when (find-buffer-visiting tmp) (kill-buffer (find-buffer-visiting tmp))) (ignore-errors (delete-file tmp))))) -(ert-deftest test-pearl-add-comment-from-inside-comment-walks-up () +(ert-deftest test-pearl-create-comment-from-inside-comment-walks-up () "From inside a comment subtree, add-comment walks up to the enclosing issue and adds the comment there rather than refusing." (test-pearl--in-org (test-pearl--comment-doc "u-me" "stored" "uniquecommentline") @@ -340,7 +340,7 @@ adds the comment there rather than refusing." :created-at "2026-05-26T00:00:00.000Z" :body "hi"))))) (goto-char (point-min)) (re-search-forward "uniquecommentline") ; point inside the comment subtree - (pearl-add-comment "hi")) + (pearl-create-comment "hi")) ;; resolved the enclosing issue's LINEAR-ID ("a"), not the comment's (should (equal "a" created-on))))) diff --git a/tests/test-pearl-comments.el b/tests/test-pearl-comments.el index 99b705a..323d7b7 100644 --- a/tests/test-pearl-comments.el +++ b/tests/test-pearl-comments.el @@ -23,7 +23,7 @@ ;; Comments subtree (ordered per `pearl-comment-sort-order'), including comments ;; in the issue render, the commentCreate helper (stubbed at the HTTP boundary), ;; the in-place append under the Comments subtree (creating it when absent), and the -;; `pearl-add-comment' command. +;; `pearl-create-comment' command. ;;; Code: @@ -165,9 +165,9 @@ (should (< (progn (re-search-forward "first") (point)) (progn (re-search-forward "second") (point))))))) -;;; pearl-add-comment +;;; pearl-create-comment -(ert-deftest test-pearl-add-comment-appends-returned-comment () +(ert-deftest test-pearl-create-comment-appends-returned-comment () "The command creates a comment and inserts the returned one in the buffer." (test-pearl--in-org "*** TODO [#B] Title\n:PROPERTIES:\n:LINEAR-ID: a\n:END:\nBody.\n" @@ -176,25 +176,25 @@ (funcall cb (list :id "c1" :author "Craig" :created-at "2026-05-23T14:00:00.000Z" :body body))))) (re-search-forward "Body.") - (pearl-add-comment "my new comment") + (pearl-create-comment "my new comment") (goto-char (point-min)) (should (re-search-forward "^\\*\\*\\* 💬 Comments 1/1$" nil t)) (should (re-search-forward "my new comment" nil t))))) -(ert-deftest test-pearl-add-comment-reports-failure () +(ert-deftest test-pearl-create-comment-reports-failure () "A failed create does not insert a Comments subtree." (test-pearl--in-org "*** TODO [#B] Title\n:PROPERTIES:\n:LINEAR-ID: a\n:END:\nBody.\n" (cl-letf (((symbol-function 'pearl--create-comment-async) (lambda (_id _body cb) (funcall cb nil)))) - (pearl-add-comment "x") + (pearl-create-comment "x") (goto-char (point-min)) (should-not (re-search-forward "^\\*\\*\\* Comments$" nil t))))) -(ert-deftest test-pearl-add-comment-not-on-issue-errors () +(ert-deftest test-pearl-create-comment-not-on-issue-errors () "Adding a comment outside a Linear issue heading signals a user error." (test-pearl--in-org "* Plain heading\nno id\n" - (should-error (pearl-add-comment "x") :type 'user-error))) + (should-error (pearl-create-comment "x") :type 'user-error))) (ert-deftest test-pearl-append-comment-targets-current-issue-not-sibling () "Appending adds under the current issue's Comments, not a later issue's subtree." diff --git a/tests/test-pearl-compose.el b/tests/test-pearl-compose.el index 3e62c09..4f4d611 100644 --- a/tests/test-pearl-compose.el +++ b/tests/test-pearl-compose.el @@ -21,7 +21,7 @@ ;; Tests for the shared compose buffer (`pearl--compose-in-buffer' and its ;; submit/abort/body helpers) and the two commands wired onto it: -;; `pearl-add-comment' (interactive composer path) and +;; `pearl-create-comment' (interactive composer path) and ;; `pearl-edit-description'. The body is extracted below a read-only ;; header and converted Org->Markdown by the callers. @@ -102,7 +102,7 @@ Binds `captured' to the value the on-finish receives (or `:none'). Stubs (re-search-forward "Body\\.") ,@body))) -(ert-deftest test-pearl-add-comment-interactive-composes-and-converts () +(ert-deftest test-pearl-create-comment-interactive-composes-and-converts () "An interactive add-comment composes Org and sends the Markdown conversion." (test-pearl--in-issue (let (sent) @@ -113,11 +113,11 @@ Binds `captured' to the value the on-finish receives (or `:none'). Stubs (funcall on-finish "see *bold* and `code`"))) ((symbol-function 'pearl--create-comment-async) (lambda (_id body _cb) (setq sent body)))) - (pearl-add-comment) ; interactive form: body nil + (pearl-create-comment) ; interactive form: body nil ;; Org markup converted to Markdown before sending (should (string= "see **bold** and `code`" sent)))))) -(ert-deftest test-pearl-add-comment-with-body-skips-composer () +(ert-deftest test-pearl-create-comment-with-body-skips-composer () "A non-interactive add-comment with BODY sends it directly, no composer." (test-pearl--in-issue (let ((composed nil) sent) @@ -125,7 +125,7 @@ Binds `captured' to the value the on-finish receives (or `:none'). Stubs (lambda (&rest _) (setq composed t))) ((symbol-function 'pearl--create-comment-async) (lambda (_id body _cb) (setq sent body)))) - (pearl-add-comment "literal body") + (pearl-create-comment "literal body") (should-not composed) (should (string= "literal body" sent)))))) diff --git a/tests/test-pearl-keymap.el b/tests/test-pearl-keymap.el index 25b63d9..b465395 100644 --- a/tests/test-pearl-keymap.el +++ b/tests/test-pearl-keymap.el @@ -46,23 +46,24 @@ Walks MAP looking for a labeled binding (\"label\" . COMMAND)." (should (keymapp pearl-prefix-map))) (ert-deftest test-pearl-prefix-map-direct-hot-keys () - "The hot-path commands resolve in one key under the prefix." + "The hot-path commands resolve in one key under the prefix. +The lowercase `c' is no longer a direct command -- it is the create prefix." (should (eq 'pearl-list-issues (lookup-key pearl-prefix-map (kbd "l")))) (should (eq 'pearl-refresh-current-view (lookup-key pearl-prefix-map (kbd "g")))) (should (eq 'pearl-refresh-current-issue (lookup-key pearl-prefix-map (kbd "r")))) (should (eq 'pearl-save-issue (lookup-key pearl-prefix-map (kbd "s")))) (should (eq 'pearl-save-all (lookup-key pearl-prefix-map (kbd "S")))) (should (eq 'pearl-edit-description (lookup-key pearl-prefix-map (kbd "d")))) - (should (eq 'pearl-add-comment (lookup-key pearl-prefix-map (kbd "c")))) (should (eq 'pearl-menu (lookup-key pearl-prefix-map (kbd "m"))))) -(ert-deftest test-pearl-prefix-map-sub-prefixes-are-keymaps () - "The category keys are sub-prefixes, not commands." - (should (keymapp (lookup-key pearl-prefix-map (kbd "f")))) - (should (keymapp (lookup-key pearl-prefix-map (kbd "e")))) - (should (keymapp (lookup-key pearl-prefix-map (kbd "n")))) - (should (keymapp (lookup-key pearl-prefix-map (kbd "k")))) - (should (keymapp (lookup-key pearl-prefix-map (kbd "u"))))) +(ert-deftest test-pearl-prefix-map-sub-prefixes-are-verbs () + "Each category key is a sub-prefix keymap named for an action verb." + (should (keymapp (lookup-key pearl-prefix-map (kbd "f")))) ; fetch + (should (keymapp (lookup-key pearl-prefix-map (kbd "e")))) ; edit + (should (keymapp (lookup-key pearl-prefix-map (kbd "c")))) ; create + (should (keymapp (lookup-key pearl-prefix-map (kbd "k")))) ; delete + (should (keymapp (lookup-key pearl-prefix-map (kbd "o")))) ; open + (should (keymapp (lookup-key pearl-prefix-map (kbd "y"))))) ; copy (ert-deftest test-pearl-prefix-map-fetch-group () "The fetch group resolves each source command." @@ -82,27 +83,24 @@ Walks MAP looking for a labeled binding (\"label\" . COMMAND)." ;; priority has no edit command (org-native cookie); e p is unbound (should-not (lookup-key pearl-prefix-map (kbd "e p")))) -(ert-deftest test-pearl-prefix-map-new-and-delete-groups () - "New and delete groups resolve ticket/comment, with delete under k." - (should (eq 'pearl-new-issue (lookup-key pearl-prefix-map (kbd "n t")))) - (should (eq 'pearl-add-comment (lookup-key pearl-prefix-map (kbd "n c")))) +(ert-deftest test-pearl-prefix-map-create-and-delete-groups () + "Create and delete groups resolve issue/comment under c and k." + (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"))))) -(ert-deftest test-pearl-prefix-map-url-group () - "The url group resolves open-in-browser, copy-url, and open-view." - (should (eq 'pearl-open-current-issue (lookup-key pearl-prefix-map (kbd "u o")))) - (should (eq 'pearl-copy-issue-url (lookup-key pearl-prefix-map (kbd "u c")))) - (should (eq 'pearl-open-current-view-in-linear (lookup-key pearl-prefix-map (kbd "u v"))))) +(ert-deftest test-pearl-prefix-map-open-and-copy-groups () + "The open group resolves the two open actions; copy resolves copy-url." + (should (eq 'pearl-open-current-issue (lookup-key pearl-prefix-map (kbd "o i")))) + (should (eq 'pearl-open-current-view-in-linear (lookup-key pearl-prefix-map (kbd "o v")))) + (should (eq 'pearl-copy-issue-url (lookup-key pearl-prefix-map (kbd "y u"))))) (ert-deftest test-pearl-prefix-map-common-commands-bound-twice () "The most common commands resolve both directly and inside their group." ;; edit-description: direct d and e d (should (eq (lookup-key pearl-prefix-map (kbd "d")) (lookup-key pearl-prefix-map (kbd "e d")))) - ;; new comment: direct c and n c - (should (eq (lookup-key pearl-prefix-map (kbd "c")) - (lookup-key pearl-prefix-map (kbd "n c")))) ;; list issues: direct l and f o (should (eq (lookup-key pearl-prefix-map (kbd "l")) (lookup-key pearl-prefix-map (kbd "f o"))))) @@ -111,12 +109,14 @@ Walks MAP looking for a labeled binding (\"label\" . COMMAND)." "Leaf bindings carry verb labels; sub-prefixes carry +labels." (should (string= "edit state" (test-pearl-keymap--label-of pearl-edit-map 'pearl-edit-state))) - (should (string= "new ticket" - (test-pearl-keymap--label-of pearl-new-map 'pearl-new-issue))) + (should (string= "create issue" + (test-pearl-keymap--label-of pearl-create-map 'pearl-create-issue))) (should (string= "open issue in browser" - (test-pearl-keymap--label-of pearl-url-map 'pearl-open-current-issue))) + (test-pearl-keymap--label-of pearl-open-map 'pearl-open-current-issue))) + (should (string= "copy issue URL" + (test-pearl-keymap--label-of pearl-copy-map 'pearl-copy-issue-url))) (should (string= "+edit" (test-pearl-keymap--label-of pearl-prefix-map pearl-edit-map))) - (should (string= "+url" (test-pearl-keymap--label-of pearl-prefix-map pearl-url-map)))) + (should (string= "+open" (test-pearl-keymap--label-of pearl-prefix-map pearl-open-map)))) (ert-deftest test-pearl-prefix-map-not-bound-at-load () "Loading pearl binds nothing globally; the keys are live only via pearl-mode." diff --git a/tests/test-pearl-menu.el b/tests/test-pearl-menu.el index 5964d31..63b925c 100644 --- a/tests/test-pearl-menu.el +++ b/tests/test-pearl-menu.el @@ -65,8 +65,8 @@ menu entry that still points at it fails here." pearl-save-issue pearl-save-all pearl-edit-state - pearl-add-comment - pearl-new-issue + pearl-create-comment + pearl-create-issue pearl-delete-current-issue)) (should (memq expected cmds))))) diff --git a/tests/test-pearl-save.el b/tests/test-pearl-save.el index 2f7b312..47b48c2 100644 --- a/tests/test-pearl-save.el +++ b/tests/test-pearl-save.el @@ -600,7 +600,7 @@ with no push." (ert-deftest test-pearl-save-description-advances-both-hashes () "A description push advances both the markdown and the Org provenance hashes, -so the next local dirty scan (which uses the Org hash) sees the ticket as clean." +so the next local dirty scan (which uses the Org hash) sees the issue as clean." (test-pearl-save--in-rendered (test-pearl-save--issue) (re-search-forward "Original description\\.") (end-of-line) diff --git a/tests/test-pearl-smoke.el b/tests/test-pearl-smoke.el index 53c4d06..760da2a 100644 --- a/tests/test-pearl-smoke.el +++ b/tests/test-pearl-smoke.el @@ -31,7 +31,7 @@ "The package source loads and defines its public commands." (should (featurep 'pearl)) (should (fboundp 'pearl-list-issues)) - (should (fboundp 'pearl-new-issue))) + (should (fboundp 'pearl-create-issue))) (provide 'test-pearl-smoke) ;;; test-pearl-smoke.el ends here diff --git a/tests/test-pearl-sync-wrappers.el b/tests/test-pearl-sync-wrappers.el index a5c9c70..cb4ac96 100644 --- a/tests/test-pearl-sync-wrappers.el +++ b/tests/test-pearl-sync-wrappers.el @@ -43,11 +43,11 @@ '((data (team (states (nodes . (((id . "s1") (name . "Todo")))))) )) (should (= 1 (length (pearl-get-states "team-1")))))) -(ert-deftest test-pearl-create-issue-sync-returns-issue () +(ert-deftest test-pearl--create-issue-sync-returns-issue () "The sync create wrapper returns the created issue node." (testutil-linear-with-response '((data (issueCreate (success . t) (issue (id . "i1") (identifier . "ENG-1") (title . "T"))))) - (should (string-equal "ENG-1" (cdr (assoc 'identifier (pearl-create-issue "T" "" "team"))))))) + (should (string-equal "ENG-1" (cdr (assoc 'identifier (pearl--create-issue "T" "" "team"))))))) (ert-deftest test-pearl-sync-wrapper-times-out-without-callback () "A sync wrapper returns nil instead of hanging when no callback fires." -- cgit v1.2.3