-
-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cop which detects ensure is called even if it is skipped #169
Comments
Can you provide good example code and bad example code for this new cop? |
Sure.
# frozen_string_literal: true
require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Activate the gem you are reporting the issue against.
gem 'activesupport', '~> 7.0.0'
end
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'minitest/autorun'
# Top level documentation comment
class BugTest < Minitest::Test
# good
def test_good_example
skip 'this test is skipped.'
assert 'zomg'.present?
refute ''.present?
ensure
p 'ensure is called even if it is skipped.'
end
# bad
def test_bad_example
skip 'this test is skipped.'
begin
assert 'zomg'.present?
refute ''.present?
ensure
p 'ensure is not called when it is skipped'
end
end
end
|
My bad the good and bad examples are switched. Here is the correct one. # frozen_string_literal: true
require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# Activate the gem you are reporting the issue against.
gem 'activesupport', '~> 7.0.0'
end
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'minitest/autorun'
# Top level documentation comment
class BugTest < Minitest::Test
# good
def test_good_example
skip 'this test is skipped.'
begin
assert 'zomg'.present?
refute ''.present?
ensure
p 'ensure is not called when it is skipped'
end
end
# bad
def test_bad_example
skip 'this test is skipped.'
assert 'zomg'.present?
refute ''.present?
ensure
p 'ensure is called even if it is skipped.'
end
end |
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in` rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in` rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in` rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in `rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in `rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
@yahonda I've opened #171 and confirmed with rails/rails repo. diff --git a/Gemfile b/Gemfile
index eb755b90d0..1b04faca3c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -37,7 +37,7 @@ gem "json", ">= 2.0.0"
group :rubocop do
gem "rubocop", ">= 1.25.1", require: false
- gem "rubocop-minitest", require: false
+ gem "rubocop-minitest", require: false, github: 'koic/rubocop-minitest', branch: 'add_new_ensure_call_even_if_skip_cop'
gem "rubocop-packaging", require: false
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false % bundle exec rubocop --only Minitest/EnsureCallEvenIfSkip
(snip)
Offenses:
activerecord/test/cases/connection_adapters/connection_handler_test.rb:434:9: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
activerecord/test/cases/query_cache_test.rb:599:3: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
activerecord/test/cases/query_cache_test.rb:628:3: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
railties/test/engine/commands_test.rb:40:3: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
railties/test/engine/commands_test.rb:50:3: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
railties/test/engine/commands_test.rb:60:3: C: Minitest/EnsureCallEvenIfSkip: ensure is called even though the test is skipped.
ensure
^^^^^^
3008 files inspected, 6 offenses detected Maybe these are not false positives and look like the expected detection. Can you confirm it if you like? |
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in `rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
I have confirmed the |
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in `rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
Closes rubocop#169. This cop checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test. If conditional `skip` is used, it checks that `ensure` is also called conditionally. On the other hand, it accepts `skip` used in `rescue` because `ensure` may be teardown process to `begin` setup process. ```ruby # bad def test_skip skip 'This test is skipped.' assert 'foo'.present? ensure do_something end # bad def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure do_teardown end # good def test_skip skip 'This test is skipped.' begin assert 'foo'.present? ensure do_something end end # good def test_conditional_skip skip 'This test is skipped.' if condition assert do_something ensure if condition do_teardown end end # good def test_skip_is_used_in_rescue do_setup assert do_something rescue skip 'This test is skipped.' ensure do_teardown end ```
[Fix #169] Add new `Minitest/SkipEnsure` cop
Is your feature request related to a problem? Please describe.
I want a cop that detects
ensure
is called even if this test hasskip
.Here is an example.
foo.rb
foo.rb
to show ensure is called even if this test is skippedDescribe the solution you'd like
I'd like to have some way to find offenses if test methods have ensure clause when they are skipped.
Describe alternatives you've considered
Change the test code to add some condition in ensure clause.
Additional context
I'm requesting this feature when I reviewed rails/rails#42691 that have a test that is skipped against MariaDB but
ensure
is called that has side effects.The text was updated successfully, but these errors were encountered: