class RuboCop::Cop::Minitest::SkipEnsure
end
do_teardown
ensure
skip ‘This test is skipped.’
rescue
assert do_something
do_setup
def test_skip_is_used_in_rescue
# good
end
end
do_teardown
if condition
ensure
assert do_something
skip ‘This test is skipped.’ if condition
def test_conditional_skip
# good
end
end
do_something
ensure
assert ‘foo’.present?
begin
skip ‘This test is skipped.’
def test_skip
# good
end
do_teardown
ensure
assert do_something
skip ‘This test is skipped.’ if condition
def test_conditional_skip
# bad
end
do_something
ensure
assert ‘foo’.present?
skip ‘This test is skipped.’
def test_skip
# bad
@example
setup process.
On the other hand, it accepts ‘skip` used in `rescue` because `ensure` may be teardown process to `begin`
If conditional `skip` is used, it checks that `ensure` is also called conditionally.
Checks that `ensure` call even if `skip`. It is unexpected that `ensure` will be called when skipping test.
def find_skip(node)
def find_skip(node) return unless (body = node.node_parts.first) body.descendants.detect { |n| n.send_type? && n.receiver.nil? && n.method?(:skip) } end
def on_ensure(node)
def on_ensure(node) skip = find_skip(node) return if skip.nil? || use_skip_in_rescue?(skip) || valid_conditional_skip?(skip, node) add_offense(node.loc.keyword) end
def use_skip_in_rescue?(skip_method)
def use_skip_in_rescue?(skip_method) skip_method.ancestors.detect(&:rescue_type?) end
def valid_conditional_skip?(skip_method, ensure_node)
def valid_conditional_skip?(skip_method, ensure_node) if_node = skip_method.ancestors.detect(&:if_type?) return false unless ensure_node.body.if_type? match_keyword = ensure_node.body.if? ? if_node.if? : if_node.unless? match_keyword && ensure_node.body.condition == if_node.condition end