diff options
| author | Ankit R Gadiya | 2024-05-14 00:14:03 +0530 |
|---|---|---|
| committer | Eli Zaretskii | 2024-07-21 09:03:18 +0300 |
| commit | f249c81f868e8fea9d2a05ce258b3ebefba6620f (patch) | |
| tree | 739fa2b8f260ee784d9b04d37e3031d279d35e53 | |
| parent | e63fa29b98f3be18b7c66c9ca289e787b172ec37 (diff) | |
| download | emacs-f249c81f868e8fea9d2a05ce258b3ebefba6620f.tar.gz emacs-f249c81f868e8fea9d2a05ce258b3ebefba6620f.zip | |
Add commands to run unit tests in 'go-ts-mode'
* lisp/progmodes/go-ts-mode.el (go-ts-mode-build-tags): New variable.
(go-ts-mode-map): Add new bindings.
(go-ts-mode--get-build-tags-flag, go-ts-mode--compile-test)
(go-ts-mode--find-defun-at, go-ts-mode--get-function-regexp)
(go-ts-mode--get-functions-in-range)
(go-ts-mode--get-test-regexp-at-point)
(go-ts-mode-test-function-at-point, go-ts-mode-test-this-file)
(go-ts-mode-test-this-package): New functions.
* etc/NEWS: Mention the change.
(Bug#70939)
| -rw-r--r-- | etc/NEWS | 19 | ||||
| -rw-r--r-- | lisp/progmodes/go-ts-mode.el | 88 |
2 files changed, 106 insertions, 1 deletions
| @@ -100,6 +100,25 @@ Advanced" node in the EWW manual. | |||
| 100 | By customizing 'shr-image-zoom-levels', you can change the list of zoom | 100 | By customizing 'shr-image-zoom-levels', you can change the list of zoom |
| 101 | levels that SHR cycles through when calling 'shr-zoom-image'. | 101 | levels that SHR cycles through when calling 'shr-zoom-image'. |
| 102 | 102 | ||
| 103 | ** Go-ts mode | ||
| 104 | |||
| 105 | +++ | ||
| 106 | *** New unit test commands. | ||
| 107 | Three new commands are now available to run unit tests. | ||
| 108 | |||
| 109 | The 'go-ts-mode-test-function-at-point' command runs the unit test at | ||
| 110 | point. If a region is active, it runs all the unit tests under the | ||
| 111 | region. It is bound to 'C-c C-t t' in 'go-ts-mode'. | ||
| 112 | |||
| 113 | The 'go-ts-mode-test-this-file' command runs all unit tests in the current | ||
| 114 | file. It is bound to 'C-c C-t f' in 'go-ts-mode'. | ||
| 115 | |||
| 116 | The 'go-ts-mode-test-this-package' command runs all unit tests under the | ||
| 117 | package of the current buffer. It is bound to 'C-c C-t p' in 'go-ts-mode'. | ||
| 118 | |||
| 119 | The 'go-ts-mode-build-tags' variable is available to set a list of build | ||
| 120 | tags for the test commands. | ||
| 121 | |||
| 103 | ** Emacs Lisp mode | 122 | ** Emacs Lisp mode |
| 104 | 123 | ||
| 105 | --- | 124 | --- |
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 2d3e6aac090..3fe427fa911 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el | |||
| @@ -46,6 +46,12 @@ | |||
| 46 | :safe 'integerp | 46 | :safe 'integerp |
| 47 | :group 'go) | 47 | :group 'go) |
| 48 | 48 | ||
| 49 | (defcustom go-ts-mode-build-tags nil | ||
| 50 | "List of Go build tags for the test commands." | ||
| 51 | :version "30.1" | ||
| 52 | :type '(repeat string) | ||
| 53 | :group 'go) | ||
| 54 | |||
| 49 | (defvar go-ts-mode--syntax-table | 55 | (defvar go-ts-mode--syntax-table |
| 50 | (let ((table (make-syntax-table))) | 56 | (let ((table (make-syntax-table))) |
| 51 | (modify-syntax-entry ?+ "." table) | 57 | (modify-syntax-entry ?+ "." table) |
| @@ -242,7 +248,10 @@ | |||
| 242 | (defvar-keymap go-ts-mode-map | 248 | (defvar-keymap go-ts-mode-map |
| 243 | :doc "Keymap used in Go mode, powered by tree-sitter" | 249 | :doc "Keymap used in Go mode, powered by tree-sitter" |
| 244 | :parent prog-mode-map | 250 | :parent prog-mode-map |
| 245 | "C-c C-d" #'go-ts-mode-docstring) | 251 | "C-c C-d" #'go-ts-mode-docstring |
| 252 | "C-c C-t t" #'go-ts-mode-test-function-at-point | ||
| 253 | "C-c C-t f" #'go-ts-mode-test-this-file | ||
| 254 | "C-c C-t p" #'go-ts-mode-test-this-package) | ||
| 246 | 255 | ||
| 247 | ;;;###autoload | 256 | ;;;###autoload |
| 248 | (define-derived-mode go-ts-mode prog-mode "Go" | 257 | (define-derived-mode go-ts-mode prog-mode "Go" |
| @@ -375,6 +384,83 @@ comment already exists, jump to it." | |||
| 375 | (<= (treesit-node-start node) point (treesit-node-end node)) | 384 | (<= (treesit-node-start node) point (treesit-node-end node)) |
| 376 | (string-equal "comment" (treesit-node-type node))))) | 385 | (string-equal "comment" (treesit-node-type node))))) |
| 377 | 386 | ||
| 387 | (defun go-ts-mode--get-build-tags-flag () | ||
| 388 | "Return the compile flag for build tags. | ||
| 389 | This function respects the `go-ts-mode-build-tags' variable for | ||
| 390 | specifying build tags." | ||
| 391 | (if go-ts-mode-build-tags | ||
| 392 | (format "-tags %s" (string-join go-ts-mode-build-tags ",")) | ||
| 393 | "")) | ||
| 394 | |||
| 395 | (defun go-ts-mode--compile-test (regexp) | ||
| 396 | "Compile the tests matching REGEXP. | ||
| 397 | This function respects the `go-ts-mode-build-tags' variable for | ||
| 398 | specifying build tags." | ||
| 399 | (compile (format "go test -v %s -run '%s'" | ||
| 400 | (go-ts-mode--get-build-tags-flag) | ||
| 401 | regexp))) | ||
| 402 | |||
| 403 | (defun go-ts-mode--find-defun-at (start) | ||
| 404 | "Return the first defun node from START." | ||
| 405 | (let ((thing (or treesit-defun-type-regexp 'defun))) | ||
| 406 | (or (treesit-thing-at start thing) | ||
| 407 | (treesit-thing-next start thing)))) | ||
| 408 | |||
| 409 | (defun go-ts-mode--get-function-regexp (name) | ||
| 410 | (if name | ||
| 411 | (format "^%s$" name) | ||
| 412 | (error "No test function found"))) | ||
| 413 | |||
| 414 | (defun go-ts-mode--get-functions-in-range (start end) | ||
| 415 | "Return a list with the names of all defuns in the range START to END." | ||
| 416 | (let* ((node (go-ts-mode--find-defun-at start)) | ||
| 417 | (name (treesit-defun-name node)) | ||
| 418 | (node-start (treesit-node-start node)) | ||
| 419 | (node-end (treesit-node-end node))) | ||
| 420 | (cond ((or (not node) | ||
| 421 | (> start node-end) | ||
| 422 | (< end node-start)) | ||
| 423 | nil) | ||
| 424 | ((or (not (equal (treesit-node-type node) "function_declaration")) | ||
| 425 | (not (string-prefix-p "Test" name))) | ||
| 426 | (go-ts-mode--get-functions-in-range (treesit-node-end node) end)) | ||
| 427 | (t | ||
| 428 | (cons (go-ts-mode--get-function-regexp name) | ||
| 429 | (go-ts-mode--get-functions-in-range (treesit-node-end node) end)))))) | ||
| 430 | |||
| 431 | (defun go-ts-mode--get-test-regexp-at-point () | ||
| 432 | "Return a regular expression for the tests at point. | ||
| 433 | If region is active, the regexp will include all the functions under the | ||
| 434 | region." | ||
| 435 | (if-let ((range (if (region-active-p) | ||
| 436 | (list (region-beginning) (region-end)) | ||
| 437 | (list (point) (point)))) | ||
| 438 | (funcs (apply #'go-ts-mode--get-functions-in-range range))) | ||
| 439 | (string-join funcs "|") | ||
| 440 | (error "No test function found"))) | ||
| 441 | |||
| 442 | (defun go-ts-mode-test-function-at-point () | ||
| 443 | "Run the unit test at point. | ||
| 444 | If the point is anywhere in the test function, that function will be | ||
| 445 | run. If the region is selected, all the functions under the region will | ||
| 446 | be run." | ||
| 447 | (interactive) | ||
| 448 | (go-ts-mode--compile-test (go-ts-mode--get-test-regexp-at-point))) | ||
| 449 | |||
| 450 | (defun go-ts-mode-test-this-file () | ||
| 451 | "Run all the unit tests in the current file." | ||
| 452 | (interactive) | ||
| 453 | (if-let ((defuns (go-ts-mode--get-functions-in-range (point-min) (point-max)))) | ||
| 454 | (go-ts-mode--compile-test (string-join defuns "|")) | ||
| 455 | (error "No test functions found in the current file"))) | ||
| 456 | |||
| 457 | (defun go-ts-mode-test-this-package () | ||
| 458 | "Run all the unit tests under the current package." | ||
| 459 | (interactive) | ||
| 460 | (compile (format "go test -v %s -run %s" | ||
| 461 | (go-ts-mode--get-build-tags-flag) | ||
| 462 | default-directory))) | ||
| 463 | |||
| 378 | ;; go.mod support. | 464 | ;; go.mod support. |
| 379 | 465 | ||
| 380 | (defvar go-mod-ts-mode--syntax-table | 466 | (defvar go-mod-ts-mode--syntax-table |