Remove gotest-temp

This commit is contained in:
Ivan Malison 2015-11-18 14:24:04 -08:00
parent 8467a9c15c
commit fb8cbc551c

View File

@ -1,502 +0,0 @@
;;; gotest.el --- Launch GO unit tests
;; Author: Nicolas Lamirault <nicolas.lamirault@gmail.com>
;; URL: https://github.com/nlamirault/gotest.el
;; Version: 0.7.0
;; Keywords: languages, go, tests
;; Package-Requires: ((emacs "24.3") (s "1.10.0") (f "0.18.0") (go-mode "1.3.1"))
;; Copyright (C) 2014, 2015 Nicolas Lamirault <nicolas.lamirault@gmail.com>
;; 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 2
;; 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, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.
;;; Commentary:
;;; Code:
(require 'compile)
(require 's)
(require 'f)
(require 'cl-lib)
(require 'go-mode)
(defgroup gotest nil
"GoTest utility"
:group 'go)
(defcustom go-test-verbose nil
"Display debugging information during test execution."
:type 'boolean
:group 'gotest)
(defcustom gb-command "gb"
"The 'gb' command.
A project based build tool for the Go programming language.
See https://getgb.io."
:type 'string
:group 'gotest)
(defvar-local go-test-args nil
"Arguments to pass to go test.
This variable is buffer-local, set using .dir-locals.el for example.")
(defvar-local go-run-args nil
"Arguments to pass to go run.
This variable is buffer-local, set using .dir-locals.el for example.")
(defvar go-test-history nil
"History list for go test command arguments.")
(defvar go-run-history nil
"History list for go run command arguments.")
;; Faces
;; -----------
(defface go-test--ok-face
'((t (:foreground "#00ff00")))
"Ok face"
:group 'go-test)
(defface go-test--error-face
'((t (:foreground "#FF0000")))
"Error face"
:group 'go-test)
(defface go-test--warning-face
'((t (:foreground "#eeee00")))
"Warning face"
:group 'go-test)
(defface go-test--pointer-face
'((t (:foreground "#ff00ff")))
"Pointer face"
:group 'go-test)
(defface go-test--standard-face
'((t (:foreground "#ffa500")))
"Standard face"
:group 'go-test)
;; go-test mode
;; -----------------
(defvar go-test-mode-map
(nconc (make-sparse-keymap) compilation-mode-map)
"Keymap for Go test major mode.")
(defvar go-test-last-command nil
"Command used last for repeating.")
(defconst go-test-font-lock-keywords
'(("error\\:" . 'go-test--error-face)
("testing: warning:.*" . 'go-test--warning-face)
("^\s*\\^\\~*\s*$" . 'go-test--pointer-face)
("^\s*Compilation.*" . 'go-test--standard-face)
("^\s*gb test.*" . 'go-test--standard-face)
("^\s*go test.*" . 'go-test--standard-face)
("^\s*Updating.*" . 'go-test--standard-face)
(".*undefined.*" . 'go-test--warning-face)
("FATAL.*" . 'go-test--error-face)
("FAIL.*" . 'go-test--error-face)
("=== RUN.*" . 'go-test--ok-face)
("--- PASS.*" . 'go-test--ok-face)
("PASS.*" . 'go-test--ok-face)
("ok.*" . 'go-test--ok-face)
)
"Minimal highlighting expressions for go-test mode.")
(define-derived-mode go-test-mode compilation-mode "Go-Test."
"Major mode for the Go-Test compilation buffer."
(use-local-map go-test-mode-map)
(setq major-mode 'go-test-mode)
(setq mode-name "Go-Test")
(setq-local truncate-lines t)
(run-hooks 'go-test-mode-hook)
(font-lock-add-keywords nil go-test-font-lock-keywords))
(defun go-test--compilation-name (mode-name)
"Name of the go test. MODE-NAME is unused."
"*Go Test*")
(defun go-test--finished-sentinel (process event)
"Execute after PROCESS return and EVENT is 'finished'."
(when (equal event "finished\n")
(message "Go Test finished.")))
(defvar go-test-regexp-prefix
"^[[:space:]]*func[[:space:]]\\(([^()]*?)\\)?[[:space:]]*\\("
"The prefix of the go-test regular expression.")
(defvar go-test-regexp-suffix
"[[:alpha:][:digit:]_]*\\)("
"The suffix of the go-test regular expression.")
(defvar go-test-prefixes '("Test" "Example")
"Prefixes to use when searching for tests.")
(defvar go-test-compilation-error-regexp-alist-alist
'((go-test-testing . ("^\t\\([[:alnum:]-_/.]+\\.go\\):\\([0-9]+\\): .*$" 1 2)) ;; stdlib package testing
(go-test-testify . ("^\tLocation:\t\\([[:alnum:]-_/.]+\\.go\\):\\([0-9]+\\)$" 1 2)) ;; testify package assert
(go-test-gopanic . ("^\t\\([[:alnum:]-_/.]+\\.go\\):\\([0-9]+\\) \\+0x\\(?:[0-9a-f]+\\)" 1 2)) ;; panic()
(go-test-compile . ("^\\([[:alnum:]-_/.]+\\.go\\):\\([0-9]+\\):\\([0-9]+\\): .*$" 1 2 3)) ;; go compiler
(go-test-linkage . ("^\\([[:alnum:]-_/.]+\\.go\\):\\([0-9]+\\): undefined: .*$" 1 2))) ;; go linker
"Alist of values for `go-test-compilation-error-regexp-alist'.
See also: `compilation-error-regexp-alist-alist'.")
(defcustom go-test-compilation-error-regexp-alist
'(go-test-testing
go-test-testify
go-test-gopanic
go-test-compile
go-test-linkage)
"Alist that specifies how to match errors in go test output.
The default set of regexps should only match the output of the
standard `go' tool, which includes compile, link, stacktrace (panic)
and package testing. There is support for matching error output
from other packages, such as `testify'.
Only file names ending in `.go' will be matched by default.
Instead of an alist element, you can use a symbol, which is
looked up in `go-testcompilation-error-regexp-alist-alist'.
See also: `compilation-error-regexp-alist'."
:type '(repeat (choice (symbol :tag "Predefined symbol")
(sexp :tag "Error specification")))
:group 'gotest)
;; Commands
;; -----------
(defun go-test--get-program (args)
"Return the command to launch unit test.
`ARGS' corresponds to go command line arguments."
(s-concat go-command " test " args))
(defun go-test--get-arguments (defaults history)
"Get optional arguments for go test or go run.
DEFAULTS will be used when there is no prefix argument.
When a prefix argument of '- is given, use the most recent HISTORY item.
When any other prefix argument is given, prompt for arguments using HISTORY."
(if current-prefix-arg
(if (equal current-prefix-arg '-)
(car (symbol-value history))
(let* ((name (nth 1 (s-split "-" (symbol-name history))))
(prompt (s-concat "go " name " args: ")))
(read-shell-command prompt defaults history)))
defaults))
(defun go-test--gb-get-program (args)
"Return the command to launch unit test using GB..
`ARGS' corresponds to go command line arguments."
(s-concat gb-command " test " args))
(defun go-test--get-root-directory()
"Return the root directory to run tests."
(let ((filename (buffer-file-name)))
(when filename
(file-truename (or (locate-dominating-file filename "Makefile")
"./")))))
(defun go-test--get-current-buffer ()
"Return the test buffer for the current `buffer-file-name'.
If `buffer-file-name' ends with `_test.go', `current-buffer' is returned.
Otherwise, `ff-other-file-name' is used to find the test buffer.
For example, if the current buffer is `foo.go', the buffer for
`foo_test.go' is returned."
(if (string-match "_test\.go$" buffer-file-name)
(current-buffer)
(let ((ff-always-try-to-create nil))
(let ((filename (ff-other-file-name)))
(message "File :%s" filename)
(find-file-noselect filename)))))
(defun go-test--get-current-data (prefix)
"Return the current data: test, example or benchmark.
`PREFIX' defines token to place cursor."
(let ((start (point))
name)
(save-excursion
(end-of-line)
(unless (and
(search-backward-regexp
(s-concat "^[[:space:]]*func[[:space:]]*" prefix) nil t)
(save-excursion (go-end-of-defun) (< start (point))))
(error "Unable to find data"))
(save-excursion
(search-forward prefix)
(setq name (thing-at-point 'word))))
name))
(defun go-test--get-current-test-info ()
"Return the current test and suite name."
(save-excursion
(end-of-line)
(if (cl-loop for test-prefix in go-test-prefixes
thereis (search-backward-regexp
(format "%s%s%s"
go-test-regexp-prefix test-prefix
go-test-regexp-suffix) nil t))
(list (match-string-no-properties 1) (match-string-no-properties 2))
(error "Unable to find a test"))))
(defun go-test--get-current-test ()
"Return the current test name."
(cadr (go-test--get-current-test-info)))
(defun go-test--get-current-benchmark ()
"Return the current benchmark name."
(go-test--get-current-data "Benchmark"))
(defun go-test--get-current-example ()
"Return the current example name."
(go-test--get-current-data "Example"))
(defun go-test--get-current-file-data (prefix)
"Generate regexp to match test, benchmark or example the current buffer.
`PREFIX' defines token to place cursor."
(with-current-buffer (go-test--get-current-buffer)
(save-excursion
(goto-char (point-min))
(if (string-match "\.go$" buffer-file-name)
(let ((regex
(s-concat "^[[:space:]]*func[[:space:]]*\\(" prefix "[^(]+\\)"))
result)
(while
(re-search-forward regex nil t)
(let ((data (buffer-substring-no-properties
(match-beginning 1) (match-end 1))))
(setq result (append result (list data)))))
(mapconcat 'identity result "|"))))))
(defun go-test--get-current-file-tests ()
"Generate regexp to match test in the current buffer."
(go-test--get-current-file-data "Test"))
(defun go-test--get-current-file-benchmarks ()
"Generate regexp to match benchmark in the current buffer."
(go-test--get-current-file-data "Benchmark"))
(defun go-test--get-current-file-examples ()
"Generate regexp to match example in the current buffer."
(go-test--get-current-file-data "Example"))
(defun go-test--arguments (args)
"Make the go test command argurments using `ARGS'."
(let ((opts args))
(when go-test-verbose
(setq opts (s-concat opts " -v")))
(when go-test-args
(setq opts (s-concat opts " " go-test-args)))
(go-test--get-arguments opts 'go-test-history)))
;; (defun go-test-compilation-hook (p)
;; "Add compilation hooks."
;; (set (make-local-variable 'compilation-error-regexp-alist-alist)
;; go-test-compilation-error-regexp-alist-alist)
;; (set (make-local-variable 'compilation-error-regexp-alist)
;; go-test-compilation-error-regexp-alist))
;; (defun go-test-run (args)
;; (add-hook 'compilation-start-hook 'go-test-compilation-hook)
;; (compile (go-test--get-program (go-test--arguments args)))
;; (remove-hook 'compilation-start-hook 'go-test-compilation-hook))
(defun go-test--go-test (args)
"Start the go test command using `ARGS'."
(let ((buffer "*Go Test*")) ; (concat "*go-test " args "*")))
(go-test--cleanup buffer)
(compilation-start (go-test--get-program (go-test--arguments args))
'go-test-mode
'go-test--compilation-name)
(with-current-buffer "*Go Test*"
(rename-buffer buffer))
(set-process-sentinel (get-buffer-process buffer) 'go-test--finished-sentinel)))
(defun go-test--go-run-get-program (args)
"Return the command to launch go run.
`ARGS' corresponds to go command line arguments."
(s-concat go-command " run " args))
(defun go-test--go-run-arguments ()
"Arguments for go run."
(let ((opts (if go-run-args
(s-concat (shell-quote-argument (buffer-file-name)) " " go-run-args)
(shell-quote-argument (buffer-file-name)))))
(go-test--get-arguments opts 'go-run-history)))
;; (defun gb-test-run (args)
;; "Test using GB.
;; `ARGS' corresponds to command line arguments."
;; (add-hook 'compilation-start-hook 'go-test-compilation-hook)
;; (compile (go-test--gb-get-program args))
;; (remove-hook 'compilation-start-hook 'go-test-compilation-hook))
(defun go-test--is-gb-project ()
"Check if project use GB or not."
(let* ((root-dir (go-test--get-root-directory))
(vendor-dir (s-concat root-dir "vendor"))
(manifest (s-concat vendor-dir "/manifest")))
(and (f-dir? vendor-dir)
(f-exists? manifest))))
(defun go-test--cleanup (buffer)
"Clean up the old go-test process BUFFER when a similar process is run."
(when (get-buffer-process (get-buffer buffer))
(delete-process buffer))
(when (get-buffer buffer)
(kill-buffer buffer)))
(defun go-test--gb-start (args)
"Start the GB test command using `ARGS'."
(let ((buffer "*Go Test*")) ;(concat "*go-test " args "*")))
(go-test--cleanup buffer)
(compilation-start (go-test--gb-get-program (go-test--arguments args))
'go-test-mode
'go-test--compilation-name)
(with-current-buffer "*Go Test*"
(rename-buffer buffer))
(set-process-sentinel (get-buffer-process buffer) 'go-test--finished-sentinel)))
; API
;; ----
;; Unit tests
;; ----------------------
;;;###autoload
(defun go-test-current-test ()
"Launch go test on the current test."
(interactive)
(let* ((test-info (go-test--get-current-test-info))
(test-name (cadr test-info))
(test-suite (car test-info))
(test-flag (if (> (length test-suite) 0) "-m " "-run ")))
(when test-name
(if (go-test--is-gb-project)
(go-test--gb-start (s-concat "-test.v=true -test.run=" test-name "$"))
(go-test--go-test (s-concat test-flag test-name "$"))))))
;;;###autoload
(defun go-test-current-file ()
"Launch go test on the current buffer file."
(interactive)
(let* ((tests (go-test--get-current-file-tests))
(examples (go-test--get-current-file-examples))
(data (s-concat tests "|" examples)))
(if (go-test--is-gb-project)
(go-test--gb-start (s-concat "-test.v=true -test.run='" data "'"))
(go-test--go-test (s-concat "-run='" data "'")))))
;;;###autoload
(defun go-test-current-project ()
"Launch go test on the current project."
(interactive)
(if (go-test--is-gb-project)
(go-test--gb-start "all -test.v=true")
(go-test--go-test "./...")))
;; Benchmarks
;; ----------------------
;;;###autoload
(defun go-test-current-benchmark ()
"Launch go benchmark on current benchmark."
(interactive)
(let ((benchmark-name (go-test--get-current-benchmark)))
(when benchmark-name
(go-test--go-test (s-concat "-run ^NOTHING -bench " benchmark-name "$")))))
;;;###autoload
(defun go-test-current-file-benchmarks ()
"Launch go benchmark on current file benchmarks."
(interactive)
(let ((benchmarks (go-test--get-current-file-benchmarks)))
(go-test--go-test (s-concat "-run ^NOTHING -bench '" benchmarks "'"))))
;;;###autoload
(defun go-test-current-project-benchmarks ()
"Launch go benchmark on current project."
(interactive)
(go-test--go-test (s-concat "-run ^NOTHING -bench .")))
;; Coverage
;; -------------
;;;###autoload
(defun go-test-current-coverage ()
"Launch go test coverage on the current project."
(interactive)
(let ((args (s-concat
"--coverprofile="
(expand-file-name
(read-file-name "Coverage file" nil "cover.out")) " ./...")))
(go-test--go-test args)))
;;;###autoload
(defun go-run ()
"Launch go run on current buffer file."
(interactive)
(add-hook 'compilation-start-hook 'go-test-compilation-hook)
(compile (go-test--go-run-get-program (go-test--go-run-arguments)))
(remove-hook 'compilation-start-hook 'go-test-compilation-hook))
(provide 'gotest)
;;; gotest.el ends here