diff options
Diffstat (limited to 'tests/test-pearl-fetch-all-comments.el')
| -rw-r--r-- | tests/test-pearl-fetch-all-comments.el | 128 |
1 files changed, 128 insertions, 0 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 |
