branch: externals/hyperbole
commit 550d4fed2fb2c3bfd9d1698eba86a1a802940b17
Merge: 2653b386e2 a7f6199602
Author: bw <[email protected]>
Commit: bw <[email protected]>

    Merge branch 'master' into rsw
---
 ChangeLog                |  26 +++++
 hsys-www.el              |   5 +-
 test/MANIFEST            |   4 +
 test/hpath-tests.el      |  13 ++-
 test/hywiki-tests.el     |  47 +++++++-
 test/hywiki-yki-tests.el | 274 +++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 366 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6203eed307..4bb8ec596f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,12 +8,38 @@
     a space was on a line before the double quoted path with prefix char, e.g.
     SPC "!/bin/ls" or SPC "!ls".
 
+2025-11-12  Mats Lidell  <[email protected]>
+
+* test/MANIFEST: Add hywiki-yki-tests.el plus older tests missing from
+    MANIFEST: hproperty-test.el, hypb-ert-tests.el and hywiki-tests.el.
+
+* test/hywiki-yki-tests.el: Add hywiki yank, kill and insert tests.
+
+2025-11-11  Mats Lidell  <[email protected]>
+
+* test/hpath-tests.el 
(hpath:path-at-point-finds-path-when-unbalanced-quote-on-same-line):
+    Verify that unbalanced quotes on same line as quoted path does not
+    interfere with finding the path.
+
 2025-11-09  Bob Weiner  <[email protected]>
 
 * hibtypes.el (action): Remove deletion of region on Action Key press when
     point is in a string.  Make Action Button behavior consistent independent
     of point.
 
+2025-11-07  Mats Lidell  <[email protected]>
+
+* hsys-www.el (eww--dwim-expand-url): Declare function to silence warning.
+    (www-eww-browse-url): Defvar url-allow-non-local-files to silence
+    warning in Emacs 28 where it is not defined. Introduced with Emacs 29.
+
+2025-11-06  Mats Lidell  <[email protected]>
+
+* test/hywiki-tests.el (hywiki-tests--hywiki-face-regions): Helper for
+    verifying generated overlays.
+    (hywiki-tests--maybe-highlight-page-names): Verify
+    overlays created by hywiki-maybe-highlight-page-names.
+
 2025-11-02  Mats Lidell  <[email protected]>
 
 * test/hywiki-tests.el
diff --git a/hsys-www.el b/hsys-www.el
index 41242d8099..71fb13ac32 100644
--- a/hsys-www.el
+++ b/hsys-www.el
@@ -3,7 +3,7 @@
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:     7-Apr-94 at 17:17:39 by Bob Weiner
-;; Last-Mod:      5-Oct-25 at 13:51:02 by Bob Weiner
+;; Last-Mod:      7-Nov-25 at 19:23:34 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -43,6 +43,8 @@
 
 (defvar hpath:display-where-alist)      ; "hpath.el"
 
+(declare-function eww--dwim-expand-url "eww" (url))
+
 (declare-function hpath:remote-available-p "hpath")
 (declare-function hpath:remote-p "hpath")
 (declare-function hpath:remote-at-p "hpath")
@@ -226,6 +228,7 @@ instead of `browse-url-new-window-flag'."
       (format "*eww-%s*" (url-host (url-generic-parse-url
                                     (eww--dwim-expand-url url)))))))
   (eww-mode)
+  (defvar url-allow-non-local-files)    ; Defined from Emacs 29.
   (let ((url-allow-non-local-files t))
     (eww url)))
 
diff --git a/test/MANIFEST b/test/MANIFEST
index 042808d613..d60a830cb3 100644
--- a/test/MANIFEST
+++ b/test/MANIFEST
@@ -10,6 +10,7 @@ hibtypes-tests.el       - unit test for hib-kbd
 hmouse-drv-tests.el     - hmouse-drv unit tests
 hmouse-info-tests.el    - hmouse-info unit tests
 hpath-tests.el          - unit tests for hpath
+hproperty-tests.el      - hproperty tests
 hsettings-tests.el      - unit tests for hsettings
 hsys-org-tests.el       - hsys-org tests
 hui-mini-tests.el       - hui-mini tests
@@ -21,10 +22,13 @@ hy-test-coverage.el     - provide test coverage information
 hy-test-dependencies.el - Hyperbole test dependencies
 hy-test-helpers.el      - unit test helpers
 hycontrol-tests.el      - hycontrol unit tests
+hypb-ert-tests.el       - hypb-ert tests
 hypb-tests.el           - tests for hypb.el utility functions
 hyperbole-tests.el      - tests for hyperbole.el
 hyrolo-tests.el         - unit tests for hyrolo.el
 hywconfig-tests.el      - tests for hyperbole window configuration management
+hywiki-tests.el         - hywiki tests
+hywiki-yki-tests.el     - hywiki yank, kill and insert tests
 kcell-tests.el          - test for kcells in Koutlines
 kexport-tests.el        - test exporting Koutlines to file types
 kimport-tests.el        - test importing file types to Koutlines
diff --git a/test/hpath-tests.el b/test/hpath-tests.el
index 3519ebd923..a2edccd035 100644
--- a/test/hpath-tests.el
+++ b/test/hpath-tests.el
@@ -3,7 +3,7 @@
 ;; Author:       Mats Lidell <[email protected]>
 ;;
 ;; Orig-Date:    28-Feb-21 at 23:26:00
-;; Last-Mod:     18-Oct-25 at 12:43:56 by Bob Weiner
+;; Last-Mod:     11-Nov-25 at 16:27:32 by Mats Lidell
 ;;
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 ;;
@@ -126,6 +126,17 @@
     (goto-char 7)
     (should (not (hpath:at-p)))))
 
+(ert-deftest hpath:path-at-point-finds-path-when-unbalanced-quote-on-same-line 
()
+  "Find path at point finds a path even with unbalanced quotes on same line."
+  :expected-result :failed
+  (dolist (v '(("  \"/tmp\"  ")       ; Reference case: no quotes
+               ("  \"/tmp\" \"")      ; Quote after: Works
+               ("\" \"/tmp\"  ")))    ; Quote before: FAILS
+    (with-temp-buffer
+      (insert (format "%s\n" v))
+      (goto-char 6)
+      (should (string= (hpath:at-p nil t) "/tmp")))))
+
 (ert-deftest hpath:find-exec-shell-cmd-test ()
   "Path prefix ! will run pathname as a non windowed program."
   (let ((was-called nil))
diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el
index 0431c4980b..eba21113a3 100644
--- a/test/hywiki-tests.el
+++ b/test/hywiki-tests.el
@@ -1417,7 +1417,7 @@ named WikiReferent with a non-page referent type."
 
 ;; Command
 (defun hywiki-tests--command (wikiword)
-  "Test command."
+  "Verify WIKIWORD is WikiReferent."
   (interactive)
   (should (string= "WikiReferent" wikiword)))
 
@@ -1629,6 +1629,20 @@ See gh#rswgnu/hyperbole/669."
         (hy-delete-file-and-buffer wiki-page)
         (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))))
 
+(defun hywiki-tests--hywiki-face-regions ()
+  "Return (start . end) for all hywiki--word-face overlays in buffer.
+The result is returned as a lexicographical sorted list to make
+comparison with expected overlays stable."
+  (let (overlay-list)
+    (dolist (overlay (overlays-in (point-min) (point-max)))
+      (when (equal (overlay-get overlay 'face) 'hywiki--word-face)
+        (push (cons (overlay-start overlay) (overlay-end overlay)) 
overlay-list)))
+    (sort overlay-list
+          (lambda (x y)
+            (or (< (car x) (car y))
+                (and (= (car x) (car y))
+                     (< (cdr x) (cdr y))))))))
+
 (defun hywiki-tests--hywiki-face-region-at (&optional pos)
   "Get the start and end of the hywiki--word-face overlay at POS or point.
 Return nil if not at a `hywiki--word-face' overlay."
@@ -2034,6 +2048,37 @@ face is verified during the change."
         (hy-delete-files-and-buffers (list wikiHi wikiHo))
         (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))))
 
+(ert-deftest hywiki-tests--maybe-highlight-page-names ()
+  "Verify `hywiki-maybe-highlight-page-names'."
+  (hywiki-tests--preserve-hywiki-mode
+    (let* ((hywiki-directory (make-temp-file "hywiki_" t))
+          (wikiword (cdr (hywiki-add-page "WiWo"))))
+      (unwind-protect
+         (progn
+            (hywiki-mode 1)
+            (dolist (v `(("WiWo" . ((1 . 5)))
+                         ("WiWo text" . ((1 . 5)))
+                         ("WiWo WiWo" . ((1 . 5) (6 . 10)))
+                         ("WiWo text WiWo" . ((1 . 5) (11 . 15)))
+                         ("\"WiWo\"" . ((2 . 6)))
+                         ("\"WiWo text\"" . ((2 . 6)))
+                         ;; FIXME: Failing tests below.
+                         ;; ("\"WiWo WiWo\"" . ((2 . 6) (7 . 11)))
+                         ;; ("\"WiWo text WiWo\"" . ((2 . 6) (12 . 16)))
+                         ;; ("\"WiWo WiWo WiWo\"" . ((2 . 6) (7 . 11) (12 . 
16)))
+                         ))
+              (let ((input (car v))
+                    (overlay-regions (cdr v)))
+               (with-temp-buffer
+                  (insert input)
+                 (hywiki-maybe-highlight-page-names (point-min) (point-max))
+                 ;; Verify Overlays
+                  (ert-info ((format "Text '%s' => Expected overlays '%s'" 
input overlay-regions))
+                    (should (equal (hywiki-tests--hywiki-face-regions) 
overlay-regions)))))))
+        ;; Unwind
+        (hy-delete-file-and-buffer wikiword)
+        (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory)))))
+
 (ert-deftest hywiki-tests--consult-grep ()
   "Verify `hywiki-consult-grep' calls `hsys-consult-grep'."
   (let ((hywiki-directory (make-temp-file "hywiki" t))
diff --git a/test/hywiki-yki-tests.el b/test/hywiki-yki-tests.el
new file mode 100644
index 0000000000..487b00a725
--- /dev/null
+++ b/test/hywiki-yki-tests.el
@@ -0,0 +1,274 @@
+;;; hywiki-yki.tests --- Yank, kill and insert tests for hywiki  -*- 
lexical-binding: t; -*-
+;;
+;; Author:       Mats Lidell
+;;
+;; Orig-Date:    13-Jul-25 at 19:50:37
+;; Last-Mod:     16-Nov-25 at 11:16:45 by Bob Weiner
+;;
+;; SPDX-License-Identifier: GPL-3.0-or-later
+;;
+;; Copyright (C) 2025  Free Software Foundation, Inc.
+;; See the "../HY-COPY" file for license information.
+;;
+;; This file is part of GNU Hyperbole.
+
+;;; Commentary:
+;;
+;; Development area for new hywiki-tests and their support functions.
+;; Will eventually, when finished, be moved into "hywiki-test.el" or
+;; maybe stay as here in a separate file!?
+
+;;; Code:
+
+(require 'ert)
+(require 'el-mock)
+(require 'ert-x)
+(require 'hy-test-helpers)
+(require 'hywiki)
+
+(require 'hywiki-tests) ;; For functions and variables in hywiki-tests
+
+;; The testing idea here is based on functions in simple-test.el add
+;; support for also marking highlighted words in buffers using the
+;; same idea with point-tag and mark-tag also for start and end of
+;; highlighted regions. Note that for setting the highlighted areas
+;; hywiki-mode is used. The tag notation is not used for that. It is
+;; only used for the verification.
+
+(defconst hywiki-test--point-char "^")
+(defconst hywiki-test--highlight-start-char "<")
+(defconst hywiki-test--highlight-end-char ">")
+
+(defun hywiki-test--insert-chars (positions)
+  "Insert in string representation of current buffer start, end and point 
chars.
+POSITIONS is a list of cons cells (START . END) with beginning of string
+at index 1.  For every highlighted word in the buffer a
+`hywiki-test--highlight-start-char' and
+`hywiki-test--highlight-end-char' surrounding the highlighted word is
+inserted.  Finally a `hywiki-test--point-char' is inserted where point is."
+  (let* ((buffer-string (buffer-substring-no-properties (point-min) 
(point-max)))
+         (current-point (point))
+         ;; Convert 1-based positions to 0-based for string operations
+         ;; Note: Emacs ranges are (start . end) where end is exclusive
+         (zero-based-positions (mapcar (lambda (pos)
+                                        (cons (1- (car pos)) (1- (cdr pos))))
+                                      (or positions '())))
+         ;; Sort ranges in reverse order for right-to-left processing
+         (sorted-positions (sort zero-based-positions
+                                (lambda (a b) (> (car a) (car b)))))
+         (result buffer-string))
+
+    ;; First, process all ranges from right to left
+    (dolist (pos sorted-positions)
+      (let* ((start (car pos))
+             (end (cdr pos))
+             (before (substring result 0 start))
+             (middle (substring result start end))
+             (after (substring result end)))
+
+        (setq result (concat before hywiki-test--highlight-start-char middle 
hywiki-test--highlight-end-char after))))
+
+    ;; Then insert point char adjusting for inserted chars.
+    (let* ((point-pos (1- current-point))
+           (tags-before-point 0))
+
+      ;; Count characters and check if point is within ranges
+      (dolist (pos zero-based-positions)
+        (let ((range-start (car pos))
+              (range-end (cdr pos)))
+          (cond
+           ((and (> point-pos range-start) (< point-pos range-end))
+            (setq tags-before-point (+ tags-before-point (length 
hywiki-test--highlight-start-char))))
+           ((<= range-end point-pos)
+            (setq tags-before-point (+ tags-before-point
+                                     (length hywiki-test--highlight-start-char)
+                                     (length 
hywiki-test--highlight-end-char)))))))
+
+      ;; Insert point char at adjusted position
+      (let* ((adjusted-point (+ point-pos tags-before-point))
+             (before (substring result 0 adjusted-point))
+             (after (substring result adjusted-point)))
+        (setq result (concat before hywiki-test--point-char after))))
+
+    result))
+
+(ert-deftest hywiki-test--insert--test ()
+  "Verify `hywiki-test--insert-chars'."
+  (with-temp-buffer
+    (insert "Hello World\n")
+    (goto-char 6)
+    (should (string= (hywiki-test--insert-chars nil)
+                     "Hello^ World\n"))
+    (should (string= (hywiki-test--insert-chars '((1 . 6) (7 . 12)))
+                     "<Hello>^ <World>\n"))
+    (goto-char 5)
+    (should (string= (hywiki-test--insert-chars '((1 . 6) (7 . 12)))
+                     "<Hell^o> <World>\n"))))
+
+(defun hywiki-test--insert (string)
+  "Command to insert a STRING at point."
+  (interactive "s: ")
+  (dolist (c (string-to-list string))
+    (hywiki-tests--command-execute #'self-insert-command 1 c)))
+
+(defun hywiki-test--insert-with-point (string)
+  "Insert STRING and return new POINT pos given by `hywiki-test--point-char'.
+The point char is not inserted."
+  (interactive "s: ")
+  (let ((pos (point)))
+    (dolist (c (string-to-list string) pos)
+      (if (equal (char-to-string c) hywiki-test--point-char)
+          (setq pos (point))
+        (hywiki-tests--command-execute #'self-insert-command 1 c)))))
+
+(defun hywiki-test--set-buffer-text-with-point-and-highlight (description)
+  "Set the current buffer's text, point and mark according to DESCRIPTION.
+
+Erase current buffer and insert DESCRIPTION.  Set point to the first
+occurrence of `hywiki-test--point-char' in the buffer, removing it.  If
+there is no `hywiki-test--point-char', set point to the beginning of the
+buffer.
+
+End the insertion of text by turning on hywiki-mode and perform a dummy
+command to get the pre- and post-hooks executed.  This creates the
+highlighting overlays we want to test."
+  (erase-buffer)
+  (hywiki-mode 1)
+  (goto-char (hywiki-test--insert-with-point description)))
+
+(defun hywiki-test--get-buffer-text-with-point-and-highlight ()
+  "An inverse of `hywiki-test--set-buffer-text-with-point-and-highlight'.
+Inserts tags for highlighted areas as well as point."
+  (hywiki-test--insert-chars (hywiki-get-reference-positions)))
+
+(ert-deftest hywiki--verify-get-buffer-text-with-point-and-highlight-compact ()
+  "Verify proper highlighting after different editing actions.
+Actions can be move, insertion, killing and deletion.
+
+Each test is constructed as three phases:
+
+* First phase, pre:, empties the buffer from any previous test and then
+  prepares the text and sets the point.  Hywiki-mode is activated in the
+  prepare phase in order to set any initial
+  highlighting.
+
+* The second phase performs some action.  It can be insertion, killing
+  or deletion.  The action should call the pre- and post-command-hooks
+  in order for the highlighting overlays to be constructed.
+
+* The third phase, post:, does a verification.  A representation of the
+  `buffer-string' as a string is constructed where chars are used for
+  point, and start and stop of the highlighting with angle brackets.
+  That is then compared to the expected string."
+  (skip-unless (not noninteractive))    ; Only works in interactive mode for 
now
+  (hywiki-tests--preserve-hywiki-mode
+   (let* ((hywiki-directory (make-temp-file "hywiki" t))
+          (wikiHi (cdr (hywiki-add-page "Hi")))
+          (wikiHo (cdr (hywiki-add-page "Ho")))
+          (wikiWord (cdr (hywiki-add-page "WikiWord")))
+          (hywiki-tests--with-face-test t))
+     (cl-flet* ((pre: (start)
+                  (hywiki-test--set-buffer-text-with-point-and-highlight 
start))
+                (exec: (cmd &rest args)
+                  (apply #'hywiki-tests--command-execute cmd args))
+                (del: (str)
+                  (exec: #'delete-region (point) (+ (point) (length str))))
+                (post: (stop)
+                  (should (string= stop 
(hywiki-test--get-buffer-text-with-point-and-highlight)))))
+       (unwind-protect
+           (progn
+             (ert-info ("1" :prefix "Verify point, no highlighting:")
+               (pre: "hej^hopp")
+               (post: "hej^hopp"))
+             (ert-info ("2" :prefix "Verify point, no highlighting: ")
+               (pre: "hej^hopp")
+               (forward-char 1)
+               (post: "hejh^opp"))
+             (ert-info ("3" :prefix "Verify highlighting: ")
+               (pre: "^Hi")
+               (post: "^<Hi>"))
+             (ert-info ("4" :prefix "Verify highlighting: ")
+               (pre: "Hi^Ho")
+               (hywiki-test--insert "\"text\"")
+               (post: "Hi\"text\"^<Ho>"))
+             (ert-info ("5" :prefix "Verify highlighting: ")
+               (pre: "Hi^Ho")
+               (hywiki-test--insert " \"text\"")
+               (post: "<Hi> \"text\"^<Ho>"))
+
+             ;; PASS: Wiki<delete-region>Word -> highlight {WikiWord} after 
delete
+             (ert-info ("6" :prefix "Verify highlighting: ")
+               (pre: "Wiki^delete-regionWord")
+               (del:      "delete-region")
+               (post: "<Wiki^Word>"))
+
+             ;; PASS: Wiki#sec<tion>Word -> no highlight after adding "tion"
+             (ert-info ("7" :prefix "Verify highlighting: ")
+               (pre: "Wiki#sec^tionWord")
+               (del:          "tion")
+               (post: "Wiki#sec^Word"))
+
+             ;; PASS: Wiki<#section>Word -> highlight {WikiWord} after delete 
of "#section"
+             (ert-info ("8" :prefix "Verify highlighting: ")
+               (pre: "Wiki^#sectionWord")
+               (del:      "#section")
+               (post: "<Wiki^Word>"))
+
+             ;; PASS: WikiWord -> dehighlight "WikiWo<kill-word>rd"
+             (ert-info ("8" :prefix "Verify highlighting: ")
+               (pre: "WikiWo^kill-wordrd")
+               (del:        "kill-word")
+               (post: "<WikiWo^rd>"))
+
+             ;; PASS: "WikiWord#section with spaces" -> shrink highlight
+             ;;        to {WikiWord#section} with this operation:
+             ;;        <delete-char>"WikiWord#section with spaces"
+             (ert-info ("9" :prefix "Verify highlighting: ")
+               (pre: "^\"WikiWord#section with spaces\"")
+               (exec: #'delete-char 1)
+               (post: "^<WikiWord#section> with spaces\""))
+
+             ;; PASS: "WikiWord#section"<delete-char-backwards> -> no
+             ;; highlight change "{WikiWord#section}
+             (ert-info ("10" :prefix "Verify highlighting: ")
+               (pre: "\"WikiWord#section\"^")
+               (exec: #'backward-delete-char-untabify 1)
+               (post: "\"<WikiWord#section>^"))
+
+             ;; PASS: "WikiWord#section with spaces"<delete-char-backwards>
+             ;; -> shrink highlight to "{WikiWord#section} with spaces
+             (ert-info ("11" :prefix "Verify highlighting: ")
+               (pre: "\"WikiWord#section with spaces\"^")
+               (exec: #'backward-delete-char-untabify 1)
+               (post: "\"<WikiWord#section> with spaces^"))
+
+             ;; PASS: WikiWord abc WikiWord
+             (ert-info ("12" :prefix "Verify highlighting: ")
+               (pre: "WikiWord ^abc WikiWord")
+               (del:           "abc ")
+               (post: "<WikiWord> ^<WikiWord>"))
+
+             ;; PASS: WikiWord abc WikiWord
+             (ert-info ("13" :prefix "Verify highlighting: ")
+               (pre: "WikiWord ^abc WikiWord")
+               (del:           "abc")
+               (post: "<WikiWord> ^ <WikiWord>"))
+
+             ;; PASS: WikiWord abc abc WikiWord
+             (ert-info ("14" :prefix "Verify highlighting: ")
+               (pre: "WikiWord ^abc abc WikiWord")
+               (del:           "abc abc ")
+               (post: "<WikiWord> ^<WikiWord>"))
+
+             ;; PASS: WikiWord <abc> abc WikiWord
+             (ert-info ("15" :prefix "Verify highlighting: ")
+               (pre: "WikiWord ^<abc> abc WikiWord")
+               (del:           "<abc> abc")
+               (post: "<WikiWord> ^ <WikiWord>")))
+
+         (hy-delete-files-and-buffers (list wikiHi wikiHo wikiWord))
+         (hywiki-tests--delete-hywiki-dir-and-buffer hywiki-directory))))))
+
+(provide 'hywiki-yki-tests)
+
+;;; hywiki-yki-tests.el ends here

Reply via email to