├── README.md ├── bats-mode.el └── bin └── batscheck /README.md: -------------------------------------------------------------------------------- 1 | # bats-mode 2 | 3 | ## Synopsis 4 | 5 | `bats-mode` is an Emacs mode for editing and running [Bats tests](https://github.com/bats-core/bats-core). 6 | 7 | `bats-mode` derives from the bash flavor of `sh-mode`, adding font-lock for bats keywords. 8 | 9 | ## Installation 10 | 11 | If you have a recent Emacs with `package.el`, you can install `bats-mode` 12 | from [MELPA](http://melpa.org/). 13 | 14 | Or manually add to your emacs `load-path`. 15 | 16 | ## Usage 17 | 18 | ### bats-run-all 19 | 20 | Run bats in the current directory. 21 | 22 | Keybinding: C-c C-a 23 | 24 | ### bats-run-current-file 25 | 26 | Run bats with the current buffer file. 27 | 28 | Keybinding: C-c C-, 29 | 30 | ### bats-run-current-test 31 | 32 | Run bats with the current test at point. 33 | 34 | Keybinding: C-c M-, 35 | -------------------------------------------------------------------------------- /bats-mode.el: -------------------------------------------------------------------------------- 1 | ;;; bats-mode.el --- Emacs mode for editing and running Bats tests 2 | 3 | ;; Author: Doug MacEachern 4 | ;; URL: https://github.com/dougm/bats-mode 5 | ;; Version: 0.1.0 6 | ;; Keywords: bats, tests 7 | 8 | ;; This program is free software; you can redistribute it and/or 9 | ;; modify it under the terms of the GNU General Public License 10 | ;; as published by the Free Software Foundation; either version 2 11 | ;; of the License, or (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program; if not, write to the Free Software 20 | ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 | ;; 02110-1301, USA. 22 | 23 | ;;; Commentary: 24 | 25 | ;;; Code: 26 | 27 | (require 'compile) 28 | (require 'sh-script) 29 | 30 | (defvar bats-mode-map 31 | (let ((map (make-sparse-keymap))) 32 | (define-key map (kbd "C-c C-a") 'bats-run-all) 33 | (define-key map (kbd "C-c C-,") 'bats-run-current-file) 34 | (define-key map (kbd "C-c M-,") 'bats-run-current-test) 35 | map) 36 | "Keymap used in Bats mode.") 37 | 38 | (defvar bats-check-program (executable-find (concat (file-name-directory 39 | (or load-file-name 40 | buffer-file-name)) 41 | "bin/batscheck")) 42 | "Default batscheck program.") 43 | 44 | ;;;###autoload 45 | (define-derived-mode bats-mode sh-mode "Bats" 46 | "Major mode for editing and running Bats tests. 47 | 48 | See URL `https://github.com/sstephenson/bats'. 49 | 50 | \\{bats-mode-map}" 51 | 52 | (set (make-local-variable 'flycheck-sh-shellcheck-executable) bats-check-program) 53 | (set (make-local-variable 'sh-shell) 'bash) 54 | 55 | ;; bash font-lock + a few bats keywords 56 | (add-to-list 'sh-font-lock-keywords-var 57 | '(bats sh-append bash 58 | ("\\(@test\\)" 1 font-lock-keyword-face) 59 | ("\\(load\\|run\\|skip\\)" 1 font-lock-function-name-face))) 60 | 61 | ;; Match file/line from bats errors in compile-mode. 62 | (add-to-list 'compilation-error-regexp-alist 'bats t) 63 | (add-to-list 'compilation-error-regexp-alist-alist 64 | '(bats . ("file \\([^ \t\r\n(]+\\), line \\([0-9]+\\)" 1 2)) t)) 65 | 66 | (defvar bats-program "bats" 67 | "Default bats program.") 68 | 69 | (defun bats-current-test () 70 | "Find current bats test." 71 | (let (test-name) 72 | (save-excursion 73 | (end-of-line) 74 | (unless (search-backward-regexp "^@test \"\\(.*?\\)\" {" nil t) 75 | (error "Unable to find a @test")) 76 | (setq test-name (match-string 1))) 77 | test-name)) 78 | 79 | (defun bats-run (file &optional name) 80 | "Run bats -t FILE. 81 | NAME if given is used as the bats test pattern." 82 | (let ((cmd (concat bats-program 83 | (when name (format " -f '^%s$'" name)) 84 | " -t " file))) 85 | (compile cmd))) 86 | 87 | (defun bats-run-current-test () 88 | "Run bats with the current test at point." 89 | (interactive) 90 | (bats-run-current-file (bats-current-test))) 91 | 92 | (defun bats-run-current-file (&optional name) 93 | "Run bats with the current buffer file. 94 | NAME if given is used as the bats test pattern." 95 | (interactive) 96 | (bats-run buffer-file-name name)) 97 | 98 | (defun bats-run-all () 99 | "Run bats in the current directory." 100 | (interactive) 101 | (bats-run ".")) 102 | 103 | ;;;###autoload 104 | (progn 105 | (add-to-list 'auto-mode-alist '("\\.bats\\'" . bats-mode))) 106 | 107 | (eval-after-load 'flycheck 108 | '(progn 109 | (flycheck-add-mode 'sh-shellcheck 'bats-mode))) 110 | 111 | (provide 'bats-mode) 112 | 113 | ;;; bats-mode.el ends here 114 | -------------------------------------------------------------------------------- /bin/batscheck: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # default location 4 | bats_preprocess=/usr/local/libexec/bats-preprocess 5 | 6 | if [ ! -x "$bats_preprocess" ] ; then 7 | # bin/bats is a symlink to ../libexec/bats 8 | readlink=$(type -p greadlink readlink | head -1) 9 | bats=$($readlink -nf "$(which bats)") 10 | libexec=$(dirname "$bats") 11 | bats_preprocess="$libexec/bats-preprocess" 12 | fi 13 | 14 | "$bats_preprocess" | sed '1 s,^#!.*$,#!/bin/bash,' | shellcheck "$@" 15 | --------------------------------------------------------------------------------