Skip to content

Commit

Permalink
Fix: verify single when mutiple test styles are in same file (#47)
Browse files Browse the repository at this point in the history
- rename `minitest--extract-str` to `minitest--extract-test-name`
  - new defvar `minitest--test-regexps` for list of patterns to match
  - remove `cmd` parameter of `minitest--post-command`

  This makes it so we find the nearest match and evaluate the right test when
  calling the verify-single command. However, it appears that `it` style tests
  will not work, due to the way their test names are generated internally (?).
  • Loading branch information
Grant Shangreaux authored Feb 2, 2020
1 parent 6d9f623 commit dc308b2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 38 deletions.
40 changes: 27 additions & 13 deletions minitest.el
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,31 @@ The current directory is assumed to be the project's root otherwise."
(cond (minitest-use-spring (concat "TESTOPTS=" flag))
(t flag))))

(defun minitest--extract-str ()
(defvar minitest--test-regexps
'("\\(test\\) ['\"]\\([^\"]+?\\)['\"]"
"def \\(test\\)_\\([_A-Za-z0-9]+\\)"
"\\(it\\) \"\\([^\"]+?\\)\""
"\\(it\\) '\\([^\"]+?\\)'")
"List of regular expressions for minitest test definition patterns.")

(defun minitest--match-point (re)
"Searches for a regular expression backwards from end of the current line.
Sets the match-string and returns the location of point where the match begins or nil"
(save-excursion
(save-restriction
(widen)
(end-of-line)
(or (re-search-backward "\\(test\\) ['\"]\\([^\"]+?\\)['\"]" nil t)
(re-search-backward "def \\(test\\)_\\([_A-Za-z0-9]+\\)" nil t)
(re-search-backward "\\(it\\) '\\([^\"]+?\\)'" nil t)
(re-search-backward "\\(it\\) \"\\([^\"]+?\\)\"" nil t)))))
(re-search-backward re nil t))))

(defun minitest--extract-test-name ()
"Finds the nearest test name matching one of the `minitest--test-regexps'.
Returns a string or nil."
(let* ((matches (delete nil (mapcar 'minitest--match-point minitest--test-regexps)))
(distances (mapcar (lambda (pos) (- (point) pos)) matches)))
(if distances
(let ((closest (cl-position (apply 'min distances) distances)))
(minitest--match-point (nth closest minitest--test-regexps))
(match-string 2)))))

(defun minitest-verify-all ()
"Run all tests."
Expand All @@ -160,14 +176,12 @@ The current directory is assumed to be the project's root otherwise."
(defun minitest-verify-single ()
"Run on current file."
(interactive)
(if (minitest--extract-str)
(let* ((cmd (match-string 1))
(str (match-string 2))
(post_command (minitest--post-command cmd str)))
(minitest--file-command (minitest--test-name-flag post_command)))
(error "No test found. Make sure you are on a file that has `def test_foo` or `test \"foo\"`")))

(defun minitest--post-command (cmd str)
(let ((test-name (minitest--extract-test-name)))
(if test-name
(minitest--file-command (minitest--test-name-flag (minitest--post-command test-name)))
(error "No test found. Make sure you are on a file that has `def test_foo` or `test \"foo\"`"))))

(defun minitest--post-command (str)
(format "%s" (replace-regexp-in-string "[\s#:]" "_" str)))

(defun minitest-rerun ()
Expand Down
45 changes: 20 additions & 25 deletions test/minitest-unit-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,35 @@
(mock (minitest--run-command "bundle exec bin/rails test foo.rb" "foo.rb"))
(minitest--file-command)))

(ert-deftest test-minitest-test-extract-str-with-method ()
(with-temp-buffer
(insert "def test_hello\nend")
(goto-char (point-max))
(minitest--extract-str)
(should (equal (match-string 2) "hello"))))

(ert-deftest test-minitest--post-command ()
(defvar test-description "#method_name behavior of Module::Class")
(defvar test-name "#method_name behavior of Module::Class")
(defvar method-name "_method_name_behavior_of_Module__Class")
(should (equal method-name (minitest--post-command "test" test-description)))
(should (equal method-name (minitest--post-command "it" test-description))))
(should (equal method-name (minitest--post-command test-name)))
(should (equal method-name (minitest--post-command test-name))))

(ert-deftest test-minitest-test-extract-str-with-block ()
(ert-deftest test-minitest--extract-test-name ()
"Tests extracting the test name for verify single command."
;; standard minitest method
(with-temp-buffer
(insert "def test_hello\nend")
(goto-char (point-max))
(should (equal (minitest--extract-test-name) "hello")))
;; rails minitest style
(with-temp-buffer
(insert "test \"hello\" do\nend")
(goto-char (point-max))
(minitest--extract-str)
(should (equal (match-string 2) "hello")))
(should (equal (minitest--extract-test-name) "hello")))
;; different quote styles in the same file
(with-temp-buffer
(insert "test \"foo\" do\nend\ntest \'bar\' do\nend")
(goto-char (point-max))
(minitest--extract-str)
(should (equal (match-string 2) "bar")))
(should (equal (minitest--extract-test-name) "bar")))
(with-temp-buffer
(insert "test \'foo\' do\nend\ntest \"bar\" do\nend")
(goto-char (point-max))
(minitest--extract-str)
(should (equal (match-string 2) "bar"))))

;; TODO
;;(ert-deftest test-minitest-test-extract-str-with-block-and-method ()
;; (with-temp-buffer
;; (insert "test \"foo\" do\nend\ndef test_bar\nend")
;; (goto-char (point-max))
;; (minitest--extract-str)
;; (should (equal (match-string 2) "bar"))))
(should (equal (minitest--extract-test-name) "bar")))
;; with different test styles in the same buffer.
(with-temp-buffer
(insert "test \"foo\" do\nend\n\ndef test_bar\nend\nit 'is rad'\nend\nit \"is cool\"")
(goto-char (point-max))
(should (equal (minitest--extract-test-name) "is cool"))))

0 comments on commit dc308b2

Please sign in to comment.