MH-E threads code: use mh-scan variables correctly
* lisp/mh-e/mh-thread.el (mh-thread-current-indentation-level) (mh-thread-find-children): Fix off-by-one error by using 'mh-scan-field-from-start-offset' directly, as 'mh-thread-parse-scan-line' does. Previously, these functions would incorrectly consider the "date note" column as part of the thread indenting. Since that column is almost always a Space character, that almost always worked. (mh-thread-ancestor): Update caller. * test/lisp/mh-e/mh-thread-tests.el: New unit tests for affected code. * lisp/mh-e/mh-scan.el (mh-msg-num-width-to-column): Fix doc string typo.
This commit is contained in:
parent
d3666ccdba
commit
4df334a0f7
3 changed files with 137 additions and 6 deletions
|
@ -509,7 +509,7 @@ with `mh-scan-msg-format-string'."
|
|||
Note that columns in Emacs start with 0.
|
||||
|
||||
If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this
|
||||
means that either `mh-scan-format-mh' or `mh-scan-format-nmh' are
|
||||
means that either `mh-scan-format-mh' or `mh-scan-format-nmh' is
|
||||
in use. This function therefore assumes that the first column is
|
||||
empty (to provide room for the cursor), the following WIDTH
|
||||
columns contain the message number, and the column for notations
|
||||
|
|
|
@ -139,7 +139,7 @@ to the message that started everything."
|
|||
(cond (thread-root-flag
|
||||
(while (mh-thread-immediate-ancestor))
|
||||
(mh-maybe-show))
|
||||
((equal current-level 1)
|
||||
((equal current-level 0)
|
||||
(message "Message has no ancestor"))
|
||||
(t (mh-thread-immediate-ancestor)
|
||||
(mh-maybe-show)))))
|
||||
|
@ -242,8 +242,8 @@ sibling."
|
|||
(defun mh-thread-current-indentation-level ()
|
||||
"Find the number of spaces by which current message is indented."
|
||||
(save-excursion
|
||||
(let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
|
||||
mh-scan-date-width 1))
|
||||
(let ((address-start-offset (+ mh-cmd-note
|
||||
mh-scan-field-from-start-offset))
|
||||
(level 0))
|
||||
(beginning-of-line)
|
||||
(forward-char address-start-offset)
|
||||
|
@ -275,8 +275,8 @@ at the end."
|
|||
(beginning-of-line)
|
||||
(if (eobp)
|
||||
nil
|
||||
(let ((address-start-offset (+ mh-cmd-note mh-scan-date-flag-width
|
||||
mh-scan-date-width 1))
|
||||
(let ((address-start-offset (+ mh-cmd-note
|
||||
mh-scan-field-from-start-offset))
|
||||
(level (mh-thread-current-indentation-level))
|
||||
spaces begin)
|
||||
(setq begin (point))
|
||||
|
|
131
test/lisp/mh-e/mh-thread-tests.el
Normal file
131
test/lisp/mh-e/mh-thread-tests.el
Normal file
|
@ -0,0 +1,131 @@
|
|||
;;; mh-thread-tests.el --- tests for mh-thread.el -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs 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.
|
||||
|
||||
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ert)
|
||||
(require 'mh-thread)
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
|
||||
(defun mh-thread-tests-before-from ()
|
||||
"Generate the fields of a scan line up to where the 'From' field would start.
|
||||
The exact contents are not important, but the number of characters is."
|
||||
(concat (make-string mh-cmd-note ?9)
|
||||
(make-string mh-scan-cmd-note-width ?A)
|
||||
(make-string mh-scan-destination-width ?t)
|
||||
(make-string mh-scan-date-width ?/)
|
||||
(make-string mh-scan-date-flag-width ?*)))
|
||||
|
||||
;;; Tests of support routines
|
||||
|
||||
(ert-deftest mh-thread-current-indentation-level ()
|
||||
"Test that `mh-thread-current-indentation-level' identifies the level."
|
||||
(with-temp-buffer
|
||||
(insert (mh-thread-tests-before-from) "[Sender One] Subject of msg 1\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Two] Subject of msg 2\n")
|
||||
(goto-char (point-min))
|
||||
(should (equal 0 (mh-thread-current-indentation-level)))
|
||||
(forward-line)
|
||||
(should (equal 2 (mh-thread-current-indentation-level)))))
|
||||
|
||||
(ert-deftest mh-thread-find-children ()
|
||||
"Test `mh-thread-find-children'."
|
||||
(let (expected-start expected-end)
|
||||
(with-temp-buffer
|
||||
(insert (mh-thread-tests-before-from) "[Sender One] line 1\n")
|
||||
(setq expected-start (point))
|
||||
(insert (mh-thread-tests-before-from) " [Sender Two] line 2\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Three] line 3\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Four] line 4\n")
|
||||
(setq expected-end (1- (point)))
|
||||
(insert (mh-thread-tests-before-from) " [Sender Five] line 5\n")
|
||||
(goto-char (1+ expected-start))
|
||||
(should (equal (list expected-start expected-end)
|
||||
(mh-thread-find-children))))))
|
||||
|
||||
(ert-deftest mh-thread-immediate-ancestor ()
|
||||
"Test that `mh-thread-immediate-ancestor' moves to the correct message."
|
||||
(with-temp-buffer
|
||||
(insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
|
||||
(insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
|
||||
(forward-line -1)
|
||||
(should (equal (line-number-at-pos) 6))
|
||||
(mh-thread-immediate-ancestor)
|
||||
(should (equal (line-number-at-pos) 4)) ;skips over sibling
|
||||
(mh-thread-immediate-ancestor)
|
||||
(should (equal (line-number-at-pos) 3)) ;goes up only one level at a time
|
||||
(mh-thread-immediate-ancestor)
|
||||
(should (equal (line-number-at-pos) 2))
|
||||
(mh-thread-immediate-ancestor)
|
||||
(should (equal (line-number-at-pos) 2)))) ;no further motion at thread root
|
||||
|
||||
;;; Tests of MH-Folder Commands
|
||||
|
||||
(ert-deftest mh-thread-sibling-and-ancestor ()
|
||||
"Test motion by `mh-thread-ancestor' and `mh-thread-next-sibling'."
|
||||
(with-temp-buffer
|
||||
(insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
|
||||
(insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
|
||||
(insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
|
||||
(forward-line -1)
|
||||
(let ((mh-view-ops '(unthread))
|
||||
(show-count 0))
|
||||
(cl-letf (((symbol-function 'mh-maybe-show)
|
||||
(lambda ()
|
||||
(setq show-count (1+ show-count)))))
|
||||
(should (equal (line-number-at-pos) 6))
|
||||
;; test mh-thread-ancestor
|
||||
(mh-thread-ancestor)
|
||||
(should (equal (line-number-at-pos) 4)) ;skips over sibling
|
||||
(should (equal show-count 1))
|
||||
(mh-thread-ancestor t)
|
||||
(should (equal (line-number-at-pos) 2)) ;root flag skips to root
|
||||
(should (equal show-count 2))
|
||||
(mh-thread-ancestor)
|
||||
(should (equal (line-number-at-pos) 2)) ;do not move from root
|
||||
(should (equal show-count 2)) ;do not re-show at root
|
||||
;; test mh-thread-sibling
|
||||
(mh-thread-next-sibling)
|
||||
(should (equal (line-number-at-pos) 2)) ;no next sibling, no motion
|
||||
(should (equal show-count 2)) ;no sibling, no show
|
||||
(mh-thread-next-sibling t)
|
||||
(should (equal (line-number-at-pos) 1))
|
||||
(should (equal show-count 3))
|
||||
(mh-thread-next-sibling t)
|
||||
(should (equal (line-number-at-pos) 1)) ;no previous sibling
|
||||
(should (equal show-count 3))
|
||||
(goto-char (point-max))
|
||||
(forward-line -1)
|
||||
(should (equal (line-number-at-pos) 6))
|
||||
(mh-thread-next-sibling t)
|
||||
(should (equal (line-number-at-pos) 5))
|
||||
(should (equal show-count 4))
|
||||
(mh-thread-next-sibling t)
|
||||
(should (equal (line-number-at-pos) 5)) ;no previous sibling
|
||||
(should (equal show-count 4))
|
||||
))))
|
||||
|
||||
;;; mh-thread-tests.el ends here
|
Loading…
Add table
Reference in a new issue