Skip to content
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

Support it/test testing blocks as test cases #238

Merged
merged 1 commit into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/new_accept_it_test_block_as_testcase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#238](https://github.com/rubocop/rubocop-minitest/pull/238): Support `it`/`test` testing blocks as test cases. ([@fatkodima][])
3 changes: 1 addition & 2 deletions lib/rubocop/cop/minitest/assert_output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ def on_gvasgn(node)
private

def find_test_case(node)
def_ancestor = node.each_ancestor(:def).first
def_ancestor if test_case?(def_ancestor)
node.each_ancestor.find { |ancestor| test_case?(ancestor) }
end

def references_gvar?(assertion, gvar_name)
Expand Down
13 changes: 9 additions & 4 deletions lib/rubocop/cop/mixin/minitest_exploration_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,23 @@ def test_class?(class_node)
end

def test_case?(node)
return false unless node&.def_type? && test_method?(node)
return false unless (node&.def_type? && test_method?(node)) ||
(node&.block_type? && test_block?(node))

class_ancestor = node.each_ancestor(:class).first
test_class?(class_ancestor)
end

def test_cases(class_node, visibility_check: true)
test_cases = class_def_nodes(class_node).select do |def_node|
test_methods = class_def_nodes(class_node).select do |def_node|
test_method?(def_node, visibility_check: visibility_check)
end

# Support Active Support's `test 'example' { ... }` method.
# https://api.rubyonrails.org/classes/ActiveSupport/Testing/Declarative.html
test_blocks = class_node.each_descendant(:block).select { |block| block.method?(:test) || block.method?(:it) }
test_blocks = class_node.each_descendant(:block).select { |block_node| test_block?(block_node) }

test_cases + test_blocks
test_methods + test_blocks
end

def test_method?(def_node, visibility_check: true)
Expand All @@ -52,6 +53,10 @@ def test_method?(def_node, visibility_check: true)
test_case_name?(def_node.method_name) && !def_node.arguments?
end

def test_block?(block_node)
block_node.method?(:test) || block_node.method?(:it)
end

def lifecycle_hooks(class_node)
class_def_nodes(class_node)
.select { |def_node| lifecycle_hook_method?(def_node) }
Expand Down
16 changes: 16 additions & 0 deletions test/rubocop/cop/minitest/assert_output_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ def test_do_something
RUBY
end

def test_registers_offense_when_mutating_output_global_variable_in_it_block_form
assert_offense(<<~RUBY)
class FooTest < Minitest::Test
describe Foo do
it "does something" do
$stdout = StringIO.new
puts object.method
$stdout.rewind
assert_match expected, $stdout.read
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `assert_output` instead of mutating $stdout.
end
end
end
RUBY
end

def test_does_not_register_offense_when_not_inside_test_case
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
Expand Down