Skip to content

Instantly share code, notes, and snippets.

@dvrensk
Created January 29, 2013 22:58
Show Gist options
  • Save dvrensk/4668781 to your computer and use it in GitHub Desktop.
Save dvrensk/4668781 to your computer and use it in GitHub Desktop.
gotest-me is part of the upcoming kata-minor-mode, designed to do TDD katas in Emacs with feedback as overlays in the code, mostly making compilation buffers unnecessary.
(defun gotest-me ()
"Run `go test' on the current file. Requires output in stretchrcom/testify format.
Install with `go get github.com/stretchrcom/testify'"
(interactive)
(when (buffer-modified-p) (save-buffer))
(remove-overlays)
(let*
((out (make-temp-file "gotest-out"))
(errbuf (get-buffer-create "*go test*"))
(ignore (with-current-buffer errbuf
(setq buffer-read-only nil)
(erase-buffer)))
(status
(call-process "go" nil errbuf nil "test" "-v" (buffer-file-name)))
popup-errbuf
(examples (with-current-buffer errbuf
(goto-char (point-min))
;; testify hides output with ^M
(replace-regexp "^.*\r" "")
(goto-char (point-min))
(let (example examples beg line-number)
(while (re-search-forward "^=== RUN \\(.*\\)" nil t)
(setq example (list (cons 'name (match-string-no-properties 1))))
(when (equalp "fail" (progn (re-search-forward "^--- \\([A-Z]+\\)") (match-string 1)))
(beginning-of-line 2)
(re-search-forward "[0-9]+$")
(setq line-number (string-to-number (match-string 0)))
(while (looking-at "\\s-") (forward-char 1))
(setq beg (point))
(re-search-forward "^$")
(push (cons 'failure
(list (cons 'message (buffer-substring-no-properties beg (point)))
(cons 'line line-number)))
example))
(setq examples (cons example examples)))
examples))))
(if (not examples)
(setq popup-errbuf t)
(save-excursion
(dolist (example examples)
(let*
((test-name (cdr (assoc 'name example)))
(failure (assoc 'failure example))
(end (progn (goto-char (point-min))
(re-search-forward (concat "^\\( *func +\\)" test-name "("))
(match-end 1)))
(beg (progn (beginning-of-line) (point)))
(colour (if failure "#f83" "#8f3"))
(status-overlay (make-overlay beg end (current-buffer) t)))
(overlay-put status-overlay 'face (cons 'background-color colour))
(overlay-put status-overlay 'evaporate t)
(when failure
(setq failure (cdr failure))
(let* ((e-msg (cdr (assoc 'message failure)))
(line (cdr (assoc 'line failure)))
exception-overlay beg end)
(if (zerop (length e-msg))
(setq popup-errbuf t)
(goto-char (point-min))
(beginning-of-line line)
(setq beg (point)
end (progn (beginning-of-line 2) (point)))
(setq exception-overlay (make-overlay beg end (current-buffer) t))
(overlay-put exception-overlay 'after-string e-msg))))))))
(if popup-errbuf
(progn (pop-to-buffer errbuf) (compilation-mode) (setq truncate-lines nil)))
(message "%s tests, %s failures"
(length examples)
(length (remove-if-not (lambda (e) (assoc 'failure e)) examples)))))
(global-set-key (kbd "<f12>") 'gotest-me)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment