aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-pearl-fetch-all-comments.el128
-rw-r--r--tests/test-pearl-menu.el4
2 files changed, 131 insertions, 1 deletions
diff --git a/tests/test-pearl-fetch-all-comments.el b/tests/test-pearl-fetch-all-comments.el
new file mode 100644
index 0000000..04dfe31
--- /dev/null
+++ b/tests/test-pearl-fetch-all-comments.el
@@ -0,0 +1,128 @@
+;;; test-pearl-fetch-all-comments.el --- Tests for fetching a full comment thread -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Craig Jennings
+
+;; Author: Craig Jennings <c@cjennings.net>
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for pearl-fetch-all-comments: the keybinding, the in-place
+;; Comments-subtree replacement with an exact N/N count, and the unpushed-edit
+;; guard that refuses to clobber a locally-edited comment.
+
+;;; Code:
+
+(require 'test-bootstrap (expand-file-name "test-bootstrap.el"))
+(require 'cl-lib)
+
+(defmacro test-pearl-fac--in-org (content &rest body)
+ "Run BODY in an org-mode temp buffer holding CONTENT."
+ (declare (indent 1))
+ `(let ((org-todo-keywords '((sequence "TODO" "IN-PROGRESS" "|" "DONE"))))
+ (with-temp-buffer
+ (insert ,content)
+ (org-mode)
+ (goto-char (point-min))
+ ,@body)))
+
+(defconst test-pearl-fac--with-comments
+ (concat
+ "* My open issues\n"
+ "** TODO SE-1: Alpha\n:PROPERTIES:\n:LINEAR-ID: i1\n:LINEAR-IDENTIFIER: SE-1\n:END:\n"
+ "The description body.\n"
+ "*** Comments 2/5+\n"
+ "**** Old Author — 2026-01-01T00:00:00.000Z\n"
+ ":PROPERTIES:\n:LINEAR-COMMENT-ID: oc1\n:LINEAR-COMMENT-AUTHOR-ID: u1\n"
+ ":LINEAR-COMMENT-SHA256: deadbeef\n:LINEAR-COMMENT-ORG-SHA256: deadbeef\n:END:\n"
+ "old comment one\n")
+ "An issue with a capped (overflowing) Comments subtree and a stale-hash comment.")
+
+(defconst test-pearl-fac--no-comments
+ (concat
+ "* My open issues\n"
+ "** TODO SE-1: Alpha\n:PROPERTIES:\n:LINEAR-ID: i1\n:LINEAR-IDENTIFIER: SE-1\n:END:\n"
+ "The description body.\n")
+ "An issue with no Comments subtree.")
+
+(defun test-pearl-fac--goto-issue ()
+ "Move point onto the issue heading."
+ (goto-char (point-min))
+ (re-search-forward "^\\*\\* TODO SE-1")
+ (beginning-of-line))
+
+;;; keybinding
+
+(ert-deftest test-pearl-fetch-all-comments-bound ()
+ "The command is bound under the fetch sub-keymap at `c'."
+ (should (eq 'pearl-fetch-all-comments (lookup-key pearl-fetch-map (kbd "c")))))
+
+;;; subtree replacement
+
+(ert-deftest test-pearl-replace-comments-subtree-replaces-and-counts ()
+ "Replacing swaps the capped thread for the full set with an exact N/N count."
+ (test-pearl-fac--in-org test-pearl-fac--with-comments
+ (test-pearl-fac--goto-issue)
+ (pearl--replace-comments-subtree
+ (list '(:id "c1" :author "Bob" :created-at "2026-02-01T00:00:00.000Z" :body "new one")
+ '(:id "c2" :author "Sue" :created-at "2026-02-02T00:00:00.000Z" :body "new two")))
+ (goto-char (point-min))
+ (should (search-forward "Comments 2/2" nil t))
+ (goto-char (point-min))
+ (should (search-forward "The description body." nil t))
+ (goto-char (point-min))
+ (should (search-forward "new one" nil t))
+ (goto-char (point-min))
+ (should-not (search-forward "old comment one" nil t))))
+
+(ert-deftest test-pearl-replace-comments-subtree-creates-when-absent ()
+ "An issue with no Comments subtree gets one inserted."
+ (test-pearl-fac--in-org test-pearl-fac--no-comments
+ (test-pearl-fac--goto-issue)
+ (pearl--replace-comments-subtree
+ (list '(:id "c1" :author "Bob" :created-at "2026-02-01T00:00:00.000Z" :body "hello")))
+ (goto-char (point-min))
+ (should (search-forward "Comments 1/1" nil t))
+ (goto-char (point-min))
+ (should (search-forward "hello" nil t))
+ (goto-char (point-min))
+ (should (search-forward "The description body." nil t))))
+
+(ert-deftest test-pearl-replace-comments-subtree-empty-clears ()
+ "An empty thread clears the Comments subtree."
+ (test-pearl-fac--in-org test-pearl-fac--with-comments
+ (test-pearl-fac--goto-issue)
+ (pearl--replace-comments-subtree nil)
+ (goto-char (point-min))
+ (should-not (search-forward "Comments" nil t))
+ (goto-char (point-min))
+ (should (search-forward "The description body." nil t))))
+
+;;; unpushed-edit guard
+
+(ert-deftest test-pearl-unpushed-comment-edits-p-detects-dirty ()
+ "A comment whose body no longer matches its stored hash is an unpushed edit."
+ (test-pearl-fac--in-org test-pearl-fac--with-comments
+ (test-pearl-fac--goto-issue)
+ (should (pearl--unpushed-comment-edits-p))))
+
+(ert-deftest test-pearl-unpushed-comment-edits-p-clean-when-no-comments ()
+ "An issue with no comments has no unpushed comment edits."
+ (test-pearl-fac--in-org test-pearl-fac--no-comments
+ (test-pearl-fac--goto-issue)
+ (should-not (pearl--unpushed-comment-edits-p))))
+
+(provide 'test-pearl-fetch-all-comments)
+;;; test-pearl-fetch-all-comments.el ends here
diff --git a/tests/test-pearl-menu.el b/tests/test-pearl-menu.el
index 8d23023..825d6bc 100644
--- a/tests/test-pearl-menu.el
+++ b/tests/test-pearl-menu.el
@@ -76,7 +76,9 @@ menu entry that still points at it fails here."
pearl-switch-account
pearl-copy-issue-url
;; set-default-view: the new Views-group entry
- pearl-set-default-view))
+ pearl-set-default-view
+ ;; fetch the full comment thread for the issue at point
+ pearl-fetch-all-comments))
(should (memq expected cmds)))))
(provide 'test-pearl-menu)