arthurnn / minitest-emacs

A minitest mode for emacs
49 stars 26 forks source link

Tests not detected when they're present inside context blocks #33

Closed jmromer closed 8 years ago

jmromer commented 8 years ago

Bug:

minitest-verify-single doesn't work when the test under the point is nested within a (non-top-level) context block.

Explanation:

When a test is nested within a context block, the block's description string is prepended to the test's generated method name:

context "validation" do
  test "does not require email" do
    org = Organization.new(:login => "ACME")
    assert org.valid?
  end
end

So the above test's corresponding method name is #test_validation_does_not_require_email, and hence the following finds no test when it's running minitest-verify-single:

 script/testrb_or_zt -v test/models/organization_test.rb -n/test_does_not_require_email/

0 tests, 0 assertions, 0 failures, 0 errors, 0 skips

A quick-and-dirty workaround is to modify minitest-verify-single so it doesn't prepend test_ to the -n flag's regex:

(defun minitest-verify-single ()
  "Run on current file."
  (interactive)
  (if (minitest--extract-str)
      (let* ((cmd (match-string 1))
             (str (match-string 2))
             (post_command (cond ((equal "test" cmd) (format "test_%s" (replace-regexp-in-string "[\s#:]" "_" str)))
                                 ((equal "it" 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\"`")))
- (format "test_%s" (replace-regexp-in-string "[\s#:]" "_" str))
+ (format "%s" (replace-regexp-in-string "[\s#:]" "_" str))

That works...

script/testrb_or_zt -v test/models/organization_test.rb -n/does_not_require_email/
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

...but it'll also execute multiple tests in cases where different context blocks each have tests with the same string.

context "validation" do
  test "does not require email" do
    org = Organization.new(:login => "ACME")
    assert org.valid?
  end
end

context "invalidation" do
  test "does not require email" do
    org = Organization.new(:login => "ACME")
    assert org.valid?
  end
end
 script/testrb_or_zt -v test/models/organization_test.rb -n/does_not_require_email/

OrganizationContext#test_invalidation_does_not_require_email_L42 = 1.55 s = .
OrganizationContext#test_validation_does_not_require_email_L33 = 0.02 s = .

2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
arthurnn commented 8 years ago

Yeah. that works for now i guess.. Thanks