branch: externals/matlab-mode
commit 20bb2ef1e303ac6aa9935e8bbe0e71b4e5bdb289
Author: John Ciolfi <john.ciolfi...@gmail.com>
Commit: John Ciolfi <john.ciolfi...@gmail.com>

    matlab-ts-mode: have t-utils-xr mostly working, added test
    
    tests/test-matlab-ts-mode-defun-type.el leverages t-utils-xr to
    execute and record movement commands that test the
      (setq-local treesit-defun-type-regexp matlab-ts-mode--defun-type-regexp)
    setup
---
 tests/t-utils.el                                   | 308 ++++++++++++++++++---
 .../defun_type.m                                   |  19 +-
 .../defun_type_expected.org                        | 198 +++++++++++++
 tests/test-matlab-ts-mode-defun-type.el            |  58 ++++
 tests/test-matlab-ts-mode-font-lock.el             |   1 -
 tests/test-matlab-ts-mode-indent.el                |   1 -
 tests/test-matlab-ts-mode-syntax-table.el          |   3 +-
 7 files changed, 537 insertions(+), 51 deletions(-)

diff --git a/tests/t-utils.el b/tests/t-utils.el
index e744fb81e6..0332406b13 100644
--- a/tests/t-utils.el
+++ b/tests/t-utils.el
@@ -94,54 +94,274 @@ files.  The default MATCH is \"^test-.*\\\\.el$\""
                      (replace-regexp-in-string "\\.el" "" 
(file-name-nondirectory test-file)))))
       (funcall test-fun))))
 
+(defvar-local t-utils--buf-file nil
+  "Name of file associated with t-utils temporary buffers.")
+
+(defun t-utils--insert-file-for-test (file)
+  "Insert FILE into current temporary buffer for testing."
+  (insert-file-contents-literally file)
+  (goto-char (point-min))
+  (when (not (looking-at "^.* -\\*- \\([-a-z0-9]+\\) -\\*-"))
+    (error "First line of %s must contain -*- MODE-NAME -*-" file))
+  (let* ((mode (match-string 1))
+         (mode-cmd (intern (concat mode "-mode"))))
+    (funcall mode-cmd))
+  (setq-local t-utils--buf-file file)
+  ;; Incase the mode moves the point, reset to point-min.
+  (goto-char (point-min)))
+
 (defun t-utils--took (start-time)
   "Return \"- took N seconds\".
 N is `current-time' minus START-TIME."
   (format "- took %.2f seconds" (float-time (time-subtract (current-time) 
start-time))))
 
-(cl-defmacro t-utils-xr (&rest commands)
-  "Execute and record results of each command in list of COMMANDS.
-This returns a string recofrding point movement and buffer modification
-differences for each command."
-  (let ((result (format "Executing commands from line %d:\n%s\n"
-                        (line-number-at-pos)
-                        (buffer-substring-no-properties 
(line-beginning-position)
-                                                        (line-end-position))))
-        (result-seperator ""))
+(defun t-utils--get-buf-file ()
+  "Return the file corresponding to the buffer under test."
+  (cond ((and (local-variable-if-set-p 't-utils--buf-file)
+              t-utils--buf-file)
+         t-utils--buf-file)
+        ((buffer-file-name)
+         (buffer-file-name))
+        (t
+         (error "`t-utils-xr` must be invoked from within a file buffer"))))
+
+(defun t-utils--diff-strings (start-contents end-contents)
+  "Return an `org-mode' code block diff of START-CONTENTS and END-CONTENTS."
+  ;;; xxx do a one-time diff check on sameple start/end contents vs result
+  (save-window-excursion
+    (let* ((tmp-name-prefix (t-utils--get-buf-file))
+           (start-tmp-file (make-temp-file (concat tmp-name-prefix ".start.") 
nil ".txt"
+                                           start-contents))
+           (end-tmp-file (make-temp-file (concat tmp-name-prefix ".end.") nil 
".txt"
+                                         end-contents))
+           (diff-switches "-u") ;; ensure expected unified diff
+           (diff-win (diff start-tmp-file end-tmp-file))
+           (diff-buf (window-buffer diff-win)))
+      (with-current-buffer diff-buf
+        (read-only-mode -1)
+
+        ;; Delete the "diff -u start-file end-file" command
+        (goto-char (point-min))
+        (re-search-forward "^--- ")
+        (beginning-of-line)
+        (delete-region (point-min) (point))
+
+        ;; Remove temp file names and time stamps to make output stable and 
easier to read
+        (re-search-forward "^--- .+$")
+        (replace-match "--- start_contents")
+        (re-search-forward "^\\+\\+\\+ .+$")
+        (replace-match "+++ end_contents")
+
+        ;; Remove the diff finished buffer info. At end of buffer there's a 
blank line then
+        ;; "Diff finished. TIME"
+        (goto-char (point-max))
+        (forward-line -2)
+        (delete-region (point) (point-max))
+
+        (delete-file start-tmp-file)
+        (delete-file end-tmp-file)
+
+        (let ((diff-result (buffer-substring-no-properties (point-min) 
(point-max))))
+          (kill-buffer diff-buf)
+          (concat "  Buffer modified:\n"
+                  "  #+begin_src diff\n"
+                  diff-result
+                  "  #+end_src diff\n"))))))
+
+(defvar t-utils--xr-impl-result-active)
+(defvar t-utils--xr-impl-result)
+
+(defun t-utils--xr-impl (commands)
+  "Implementation for `t-utils-xr' that processes COMMANDS."
+  (when (or (= (point) 1)
+            (not (save-excursion (goto-char (1- (point))) (looking-at ")"))))
+    (error "Expected point to be after a closing parenthisis, \")\""))
+
+  (let* ((buf-file (t-utils--get-buf-file))
+         (start-line (line-number-at-pos))
+         (xr-end-point (point))
+         (xr-start-point
+          (save-excursion
+            (backward-list)
+            (when (not (looking-at "(t-utils-xr"))
+              (error "`backward-list from point, %d, didn't not jump to 
(t-utils-xr" xr-end-point))
+            (point)))
+         (xr-cmd (buffer-substring-no-properties xr-start-point xr-end-point))
+         (result (format "\n* Executing commands from %s:%d:%d:\n\n  %s\n"
+                         (file-name-nondirectory buf-file)
+                         (line-number-at-pos xr-start-point)
+                         (save-excursion (goto-char xr-start-point)
+                                         (current-column))
+                         xr-cmd)))
+
     (dolist (command commands)
       (let ((start-point (point))
-            (start-contents (buffer-substring-no-properties (point-min) 
(point-max))))
-        (setq result (concat result result-seperator
-                             (format "--> %s // invoked at start point %d\n" 
command start-point)))
-        (setq result-seperator "\n")
-        (eval command)
+            (start-contents (buffer-substring-no-properties (point-min) 
(point-max)))
+            (key-command (when (eq (type-of command) 'string)
+                           ;; Keybinding, e.g. (t-utils-xr "C-M-a")
+                           (let ((cmd (key-binding (kbd command))))
+                             (when (not cmd)
+                               (user-error "%s:%d: Command, %s, is not a known 
keybinding"
+                                           buf-file start-line command))
+                             cmd))))
+
+        (setq result (concat result "\n"
+                             (format "- Invoking      : %S%s\n"
+                                     command (if key-command
+                                                 (concat " = " (symbol-name 
key-command))
+                                               ""))
+                             (format "  Start point   : %4d\n" start-point)))
+
+        (if key-command
+            ;; a keybinding: (t-util-xr "C-M-a")
+            (call-interactively key-command)
+          ;; a command: (t-utils-xr (beginning-of-defun))
+          (eval command))
+
         (let ((end-point (point))
               (end-contents (buffer-substring-no-properties (point-min) 
(point-max))))
+
+          ;; Record point movement by adding what happened to result
           (if (equal start-point end-point)
-              (setq result (concat result "No point movement\n"))
+              (setq result (concat result "  No point movement\n"))
             (let* ((current-line (buffer-substring-no-properties 
(line-beginning-position)
                                                                  
(line-end-position)))
                    (position (format "%d:%d: " (line-number-at-pos) 
(current-column)))
                    (carrot (concat (make-string (+ (length position) 
(current-column)) ?\s) "^")))
-              (setq result (concat result
-                                   (format "End point: %d\n|%s%s\n|%s\n"
-                                           end-point position current-line 
carrot)))))
-          (if (equal start-contents end-contents)
-              (setq result (concat result "No buffer modifications\n"))
-            (let* ((tmp-name-prefix (buffer-name))
-                   (start-tmp-file (make-temp-file (concat tmp-name-prefix 
".start.") nil ".txt"
-                                                   start-contents))
-                   (end-tmp-file (make-temp-file (concat tmp-name-prefix 
".end.") nil ".txt"
-                                                 end-contents))
-                   (diff-buf (diff start-tmp-file end-tmp-file)))
-              (save-window-excursion
-                (with-current-buffer diff-buf
-                  (setq result (concat result
-                                       (concat "New contents (diff):\n"
-                                               (buffer-substring-no-properties
-                                                (point-min) (point-max))))))
-                (kill-buffer diff-buf)))))))
-    result))
+              (setq result (concat result (format "  Moved to point: %4d\n  : 
%s%s\n  : %s\n"
+                                                  end-point position 
current-line carrot)))))
+
+          ;; Record buffer modifications by adding what happened to result
+          (setq result (concat result
+                               (if (equal start-contents end-contents)
+                                   "  No buffer modifications\n"
+                                 (t-utils--diff-strings start-contents 
end-contents)))))))
+    (if t-utils--xr-impl-result-active
+        (progn
+          (setq t-utils--xr-impl-result result)
+          nil)
+      result)))
+
+(cl-defmacro t-utils-xr (&rest commands)
+  "Execute and record results of each command in list of COMMANDS.
+This returns a string recofrding point movement and buffer modification
+differences for each command.  See `t-utils-test-xr' for details."
+  (t-utils--xr-impl commands))
+
+(defun t-utils-test-xr (test-name lang-files)
+  "Execute and record (t-utils-xr COMMANDS) from LANG-FILES list.
+For each NAME.EXT in LANG-FILES, run each (t-utils-xr COMMANDS) and
+compare results against NAME_expected.org.  TEST-NAME is used in
+messages.
+
+The commands that you can place within (t-utils-xr COMMANDS) are
+ 1. Lisp expressions.  For example,
+      (t-utils-xr (beginning-of-defun))
+ 2. Keybindings.  For example,
+      (t-utils-xr \"C-M-a\")
+Multiple expressions or keybindings can be specified.
+
+Consider ./test-defun-movement/my_test.c:
+
+  1 | #include <stdlib.h>
+  2 |
+  3 | int fcn1(void) {
+  4 |   // (t-utils-xr \"C-M-e\" \"C-M-e\")
+  5 |   return 1;
+  6 | }
+  7 |
+  8 | int main(void) {
+  9 |   return fcn1();
+  10|   // (t-utils-xr (beginning-of-defun) (beginning-of-defun))
+  11| }
+
+You can interactively evaulate each (t-utils-xr COMMANDS) by placing the
+`point' on the closing parenthesis and typing \\[eval-last-sexp].  For
+example, with the point after the closing parenthesis on line 4 and
+running \\[eval-last-sexp], we'll see in the *Messages* buffer:
+
+    * Executing commands from my_test.c:4:
+
+      // (t-utils-xr \"C-M-e\" \"C-M-e\")
+
+    - Invoking      : \"C-M-e\" = c-end-of-defun
+      Start point   :   72
+      Moved to point:   87
+      : 7:0:
+      :      ^
+      No buffer modifications
+
+    - Invoking      : \"C-M-e\" = c-end-of-defun
+      Start point   :   87
+      Moved to point:  158
+      : 12:0:
+      :       ^
+      No buffer modifications
+
+Running
+
+  M-: (t-utils-test-xr \"test-defun-movement\"
+                       \\='(\"test-defun-movement/my_test.c\"))
+
+will run the two (t-utils-xr COMMANDS) statements from line 4 and 10 of
+my_test.c.  The result is compared against
+test-defun-movement/my_test_expected.org.  If my_test_expected.org does
+not exist or result doesn't match the existing my_test_expected.org,
+my_test_expected.org~ is generated and if it looks correct, you should
+rename it to my_test_expected.org.  The contents of my_test_expected.org
+for this example is:
+
+  TODO xxx contents of my_test_expected.org"
+
+  (dolist (lang-file lang-files)
+    (with-temp-buffer
+      (t-utils--insert-file-for-test lang-file)
+      (let* ((start-time (current-time))
+             (expected-file (replace-regexp-in-string "\\.[^.]+$" 
"_expected.org"
+                                                      lang-file))
+             (expected (when (file-exists-p expected-file)
+                         (with-temp-buffer
+                           (insert-file-contents-literally expected-file)
+                           (buffer-string))))
+             (got "#+startup: showall\n")
+             (got-file (concat expected-file "~")))
+
+        (message "START: %s %s" test-name lang-file)
+
+        (while (re-search-forward "(t-utils-xr" nil t)
+          (re-search-backward "(")
+          (forward-list)
+          (let* ((xr-end-point (point)))
+            ;; Setting t-utils--xr-impl-result-active to t prevents 
t-utils--xr-impl from returning
+            ;; the result and instead returns the result via global 
t-utils--xr-impl-result. This
+            ;; prevents the result text from being displayed when run via 
emacs --batch. However,
+            ;; we still see 'nil' displayed, but I don't think there's much we 
can do about that.
+            (setq t-utils--xr-impl-result-active t)
+            (condition-case err
+                (progn
+                  (eval-last-sexp nil)
+                  (setq got (concat got t-utils--xr-impl-result)))
+              (error (setq t-utils--xr-impl-result-active nil)
+                     (signal (car err) (cdr err))))
+            ;; look for next (t-utils-xr COMMANDS)
+            (goto-char xr-end-point)))
+
+        (kill-buffer)
+
+        (when (string= got "")
+          (error "No (t-utils-xr COMMANDS) found in %s" lang-file))
+
+        (when (not (string= got expected))
+          (let ((coding-system-for-write 'raw-text-unix))
+            (write-region got nil got-file))
+          (when (not expected)
+            (error "Baseline for %s does not exists.  \
+See %s and if it looks good rename it to %s"
+                   lang-file got-file expected-file))
+          (error "Baseline for %s does not match, got: %s, expected: %s"
+                 lang-file got-file expected-file))
+
+        (message "PASS: %s %s %s" test-name lang-file (t-utils--took 
start-time))))))
 
 (defun t-utils-test-font-lock (test-name lang-files code-to-face)
   "Test font-lock using on each lang-file in LANG-FILES list.
@@ -170,12 +390,15 @@ where int and void are keywords, etc. and CODE-TO-FACE 
contains:
     (\"D\" . font-lock-delimiter-face)
     (\"f\" . font-lock-function-name-face)
     (\"k\" . font-lock-keyword-face)
-    (\"n\" . font-lock-constant-face))"
+    (\"n\" . font-lock-constant-face))
+
+xxx give example calling test-name.el (and for others)"
 
   (let ((face-to-code (mapcar (lambda (pair)
                                 (cons (cdr pair) (car pair)))
                               code-to-face)))
     (dolist (lang-file lang-files)
+      ;; xxx save window excursion?
       (save-excursion
         (let ((start-time (current-time)))
           (message "START: %s %s" test-name lang-file)
@@ -191,14 +414,15 @@ where int and void are keywords, etc. and CODE-TO-FACE 
contains:
           (font-lock-ensure (point-min) (point-max))
 
           (goto-char (point-min))
-          (let* ((got "")
-                 (expected-file (replace-regexp-in-string "\\.[^.]+$" 
"_expected.txt"
+          (let* ((expected-file (replace-regexp-in-string "\\.[^.]+$" 
"_expected.txt"
                                                           lang-file))
-                 (got-file (concat expected-file "~"))
                  (expected (when (file-exists-p expected-file)
                              (with-temp-buffer
                                (insert-file-contents-literally expected-file)
-                               (buffer-string)))))
+                               (buffer-string))))
+                 (got "")
+                 (got-file (concat expected-file "~")))
+
             (while (not (eobp))
               (let* ((face (if (face-at-point) (face-at-point) 'default))
                      (code (if (looking-at "\\([ \t\n]\\)")
@@ -212,6 +436,8 @@ where int and void are keywords, etc. and CODE-TO-FACE 
contains:
                   (setq got (concat got "\n"))
                   (forward-char))))
 
+            ;; xxx (kill-buffer) and elsewhere to ensure when test fails, 
state is unchanged
+
             (when (not (string= got expected))
               (let ((coding-system-for-write 'raw-text-unix))
                 (write-region got nil got-file))
@@ -339,7 +565,7 @@ See `t-utils--test-indent-type' for LINE-MANIPULATOR."
                          (insert-file-contents-literally expected-file)
                          (buffer-string))))
            lang-file-major-mode)
-      
+
       ;; Indent lang-file
       (save-excursion
         (let ((start-time (current-time)))
@@ -407,7 +633,7 @@ the messages to accept the generated baseline after 
validating it."
                                             (line-number-at-pos)
                                             (buffer-substring-no-properties 
(point)
                                                                             
(line-end-position))))))
-            
+
             (let ((char (buffer-substring-no-properties (point) (1+ (point)))))
               (when (string= char "\n")
                 (setq char "\\n"))
diff --git a/tests/test-matlab-ts-mode-defun-type-files/defun_type.m 
b/tests/test-matlab-ts-mode-defun-type-files/defun_type.m
index 92a947e4ce..c5149702ee 100644
--- a/tests/test-matlab-ts-mode-defun-type-files/defun_type.m
+++ b/tests/test-matlab-ts-mode-defun-type-files/defun_type.m
@@ -1,28 +1,35 @@
 % -*- matlab-ts -*-
 
+% Test validates that
+%  (setq-local treesit-defun-type-regexp matlab-ts-mode--defun-type-regexp)
+% is setup correctly.
+
 function b = defun_type(a)
 
     % (t-utils-xr (beginning-of-defun))
+    % (t-utils-xr "C-M-a")
     x = 1;
 
     % (t-utils-xr (end-of-defun) (end-of-defun) (end-of-defun) (end-of-defun))
+    % (t-utils-xr "C-M-e" "C-M-e" "C-M-e" "C-M-e")
 
     b = nested1(a) + nested2(a);
 
     function out = nested1(in)
         out = x + helper1(in);
-        % (t-utils-xr (beginning-of-defun))
-        % (t-utils-xr (beginning-of-defun) (beginning-of-defun))
-        % (t-utils-xr (end-of-defun) (end-of-defun) (end-of-defun) 
(end-of-defun))
+        % (t-utils-xr "C-M-a")
+        % (t-utils-xr "C-M-a" "C-M-a")
+        % (t-utils-xr "C-M-e" "C-M-e" "C-M-e" "C-M-e")
     end
 
     function out = nested2(in)
 
-        % (t-utils-xr (beginning-of-defun))
+        % (t-utils-xr "C-M-a")
         out = 2 * x + in;
-        % (t-utils-xr (beginning-of-defun))
+        % (t-utils-xr "C-M-a")
     end
 
+    b = 2 * b;
 end
 
 function out = helper1(in)
@@ -31,5 +38,5 @@ end
 
 function out = helper2(in)
     out = in *2;
-    % (t-utils-xr (beginning-of-defun) (beginning-of-defun) 
(beginning-of-defun))
+    % (t-utils-xr "C-M-a" "C-M-a" "C-M-a" "C-M-a")
 end
diff --git a/tests/test-matlab-ts-mode-defun-type-files/defun_type_expected.org 
b/tests/test-matlab-ts-mode-defun-type-files/defun_type_expected.org
new file mode 100644
index 0000000000..b8260df99a
--- /dev/null
+++ b/tests/test-matlab-ts-mode-defun-type-files/defun_type_expected.org
@@ -0,0 +1,198 @@
+#+startup: showall
+
+* Executing commands from defun_type.m:9:6:
+
+  (t-utils-xr (beginning-of-defun))
+
+- Invoking      : (beginning-of-defun)
+  Start point   :  210
+  Moved to point:  143
+  : 7:0: function b = defun_type(a)
+  :      ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:10:6:
+
+  (t-utils-xr "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  237
+  Moved to point:  143
+  : 7:0: function b = defun_type(a)
+  :      ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:13:6:
+
+  (t-utils-xr (end-of-defun) (end-of-defun) (end-of-defun) (end-of-defun))
+
+- Invoking      : (end-of-defun)
+  Start point   :  328
+  Moved to point:  759
+  : 34:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : (end-of-defun)
+  Start point   :  759
+  Moved to point:  818
+  : 38:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : (end-of-defun)
+  Start point   :  818
+  Moved to point:  918
+  : 43:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : (end-of-defun)
+  Start point   :  918
+  No point movement
+  No buffer modifications
+
+* Executing commands from defun_type.m:14:6:
+
+  (t-utils-xr "C-M-e" "C-M-e" "C-M-e" "C-M-e")
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  379
+  Moved to point:  610
+  : 24:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  610
+  Moved to point:  739
+  : 31:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  739
+  Moved to point:  759
+  : 34:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  759
+  Moved to point:  818
+  : 38:0: 
+  :       ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:20:10:
+
+  (t-utils-xr "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  507
+  Moved to point:  415
+  : 18:0:     function out = nested1(in)
+  :       ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:21:10:
+
+  (t-utils-xr "C-M-a" "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  546
+  Moved to point:  415
+  : 18:0:     function out = nested1(in)
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  415
+  Moved to point:  143
+  : 7:0: function b = defun_type(a)
+  :      ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:22:10:
+
+  (t-utils-xr "C-M-e" "C-M-e" "C-M-e" "C-M-e")
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  601
+  Moved to point:  610
+  : 24:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  610
+  Moved to point:  739
+  : 31:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  739
+  Moved to point:  759
+  : 34:0: 
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-e" = treesit-end-of-defun
+  Start point   :  759
+  Moved to point:  818
+  : 38:0: 
+  :       ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:27:10:
+
+  (t-utils-xr "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  673
+  Moved to point:  611
+  : 25:0:     function out = nested2(in)
+  :       ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:29:10:
+
+  (t-utils-xr "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  730
+  Moved to point:  611
+  : 25:0:     function out = nested2(in)
+  :       ^
+  No buffer modifications
+
+* Executing commands from defun_type.m:41:6:
+
+  (t-utils-xr "C-M-a" "C-M-a" "C-M-a" "C-M-a")
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  913
+  Moved to point:  819
+  : 39:0: function out = helper2(in)
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  819
+  Moved to point:  760
+  : 35:0: function out = helper1(in)
+  :       ^
+  No buffer modifications
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  760
+  Moved to point:  143
+  : 7:0: function b = defun_type(a)
+  :      ^
+  No buffer modifications
+
+- Invoking      : "C-M-a" = treesit-beginning-of-defun
+  Start point   :  143
+  No point movement
+  No buffer modifications
diff --git a/tests/test-matlab-ts-mode-defun-type.el 
b/tests/test-matlab-ts-mode-defun-type.el
new file mode 100644
index 0000000000..56df98aaab
--- /dev/null
+++ b/tests/test-matlab-ts-mode-defun-type.el
@@ -0,0 +1,58 @@
+;;; test-matlab-ts-mode-defun-type.el --- Test matlab-ts-mode indent -*- 
lexical-binding: t -*-
+;;
+;; Copyright 2025 Free Software Foundation, Inc.
+;;
+;; 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, 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+
+;;; Commentary:
+;;
+;; Validate matlab-ts-mode indent.
+;; Load ../matlab-ts-mode.el via require and run indent tests using
+;; ./test-matlab-ts-mode-defun-type-files/NAME.m comparing against
+;; ./test-matlab-ts-mode-defun-type-files/NAME_expected.org
+;;
+
+;;; Code:
+
+(require 't-utils)
+(require 'matlab-ts-mode)
+
+(cl-defun test-matlab-ts-mode-defun-type (&optional m-file)
+  "Test defun movement using ./test-matlab-ts-mode-defun-type-files/NAME.m.
+Using ./test-matlab-ts-mode-defun-type-files/NAME.m, compare defun
+movement against
+./test-matlab-ts-mode-defun-type-files/NAME_expected.org.  If M-FILE is
+not provided, loop comparing all
+./test-matlab-ts-mode-defun-type-files/NAME.m files.
+
+To add a test, create
+  ./test-matlab-ts-mode-defun-type-files/NAME.m
+and run this function.  The baseline is saved for you as
+  ./test-matlab-ts-mode-defun-type-files/NAME_expected.org~
+after validating it, rename it to
+  ./test-matlab-ts-mode-defun-type-files/NAME_expected.org"
+
+  (let ((test-name "test-matlab-ts-mode-defun-type"))
+
+    (when (not (t-utils-is-treesit-available 'matlab test-name))
+      (cl-return-from test-matlab-ts-mode-font-lock))
+
+    (let ((m-files (t-utils-get-files (concat test-name "-files") "\\.m$" nil 
m-file)))
+      (t-utils-test-xr test-name m-files)))
+    "success")
+
+(provide 'test-matlab-ts-mode-defun-type)
+;;; test-matlab-ts-mode-defun-type.el ends here
diff --git a/tests/test-matlab-ts-mode-font-lock.el 
b/tests/test-matlab-ts-mode-font-lock.el
index e258c2baa6..9fbe5b733d 100644
--- a/tests/test-matlab-ts-mode-font-lock.el
+++ b/tests/test-matlab-ts-mode-font-lock.el
@@ -72,7 +72,6 @@ after validating it, rename it to
                            ("w" . font-lock-warning-face)
                            )))
       (t-utils-test-font-lock test-name m-files code-to-face))
-    ;; return "success" for M-: (test-matlab-ts-mode-font-lock)
     "success"))
 
 (provide 'test-matlab-ts-mode-font-lock)
diff --git a/tests/test-matlab-ts-mode-indent.el 
b/tests/test-matlab-ts-mode-indent.el
index 5c54d5cd42..2c2c8ad222 100644
--- a/tests/test-matlab-ts-mode-indent.el
+++ b/tests/test-matlab-ts-mode-indent.el
@@ -65,7 +65,6 @@ after validating it, rename it to
                                 (forward-line)))))
 
       (t-utils-test-indent test-name m-files line-manipulator)))
-    ;; return "success" for M-: (test-matlab-ts-mode-font-lock)
     "success")
 
 (provide 'test-matlab-ts-mode-indent)
diff --git a/tests/test-matlab-ts-mode-syntax-table.el 
b/tests/test-matlab-ts-mode-syntax-table.el
index ba2923cfef..569b56cd92 100644
--- a/tests/test-matlab-ts-mode-syntax-table.el
+++ b/tests/test-matlab-ts-mode-syntax-table.el
@@ -49,8 +49,7 @@ after validating it, rename it to
 
     (let ((m-files (t-utils-get-files (concat test-name "-files") "\\.m$" nil 
m-file)))
       (t-utils-test-syntax-table test-name m-files)))
-  
-  ;; return "success" for M-: (test-matlab-ts-mode-font-lock)
+
   "success")
 
 (provide 'test-matlab-ts-mode-syntax-table)

Reply via email to