├── 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 |
--------------------------------------------------------------------------------