From 24005149003ad3e5179ae41ec791880953c10514 Mon Sep 17 00:00:00 2001 From: fatkodima Date: Tue, 17 Jan 2023 16:56:25 +0200 Subject: [PATCH] Change what is considered a test case by `rubocop-minitest` --- .../change_what_is_considered_a_test_case.md | 1 + .../cop/mixin/minitest_exploration_helpers.rb | 9 +++- lib/rubocop/minitest/assert_offense.rb | 1 + .../minitest_exploration_helpers_test.rb | 50 +++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 changelog/change_what_is_considered_a_test_case.md create mode 100644 test/rubocop/cop/mixin/minitest_exploration_helpers_test.rb diff --git a/changelog/change_what_is_considered_a_test_case.md b/changelog/change_what_is_considered_a_test_case.md new file mode 100644 index 00000000..120c40e5 --- /dev/null +++ b/changelog/change_what_is_considered_a_test_case.md @@ -0,0 +1 @@ +* [#231](https://github.com/rubocop/rubocop-minitest/pull/231): Change what is considered a test case by `rubocop-minitest` (`public` method without arguments with `test_` name prefix). ([@fatkodima][]) diff --git a/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb b/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb index 323524ac..d0a16054 100644 --- a/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +++ b/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb @@ -7,6 +7,7 @@ module Cop # Helper methods for different explorations against test files and test cases. # @api private module MinitestExplorationHelpers + include DefNode extend NodePattern::Macros ASSERTION_PREFIXES = %w[assert refute].freeze @@ -27,14 +28,14 @@ def test_class?(class_node) end def test_case?(node) - return false unless node&.def_type? && test_case_name?(node.method_name) + return false unless node&.def_type? && test_method?(node) class_ancestor = node.each_ancestor(:class).first test_class?(class_ancestor) end def test_cases(class_node) - test_cases = class_def_nodes(class_node).select { |def_node| test_case_name?(def_node.method_name) } + test_cases = class_def_nodes(class_node).select { |def_node| test_method?(def_node) } # Support Active Support's `test 'example' { ... }` method. # https://api.rubyonrails.org/classes/ActiveSupport/Testing/Declarative.html @@ -43,6 +44,10 @@ def test_cases(class_node) test_cases + test_blocks end + def test_method?(def_node) + test_case_name?(def_node.method_name) && !def_node.arguments? && !non_public?(def_node) + end + def lifecycle_hooks(class_node) class_def_nodes(class_node) .select { |def_node| lifecycle_hook_method?(def_node) } diff --git a/lib/rubocop/minitest/assert_offense.rb b/lib/rubocop/minitest/assert_offense.rb index be818dcf..e6ed160f 100644 --- a/lib/rubocop/minitest/assert_offense.rb +++ b/lib/rubocop/minitest/assert_offense.rb @@ -77,6 +77,7 @@ module AssertOffense def setup cop_name = self.class.to_s.delete_suffix('Test') + return unless RuboCop::Cop::Minitest.const_defined?(cop_name) @cop = RuboCop::Cop::Minitest.const_get(cop_name).new end diff --git a/test/rubocop/cop/mixin/minitest_exploration_helpers_test.rb b/test/rubocop/cop/mixin/minitest_exploration_helpers_test.rb new file mode 100644 index 00000000..b37b0ddf --- /dev/null +++ b/test/rubocop/cop/mixin/minitest_exploration_helpers_test.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'test_helper' + +class MinitestExplorationHelpersTest < Minitest::Test + module Helper + extend RuboCop::Cop::MinitestExplorationHelpers + class << self + public :test_case? + end + end + + SOURCE = <<~RUBY + class FooTest < Minitest::Test + def not_test_case; end + def test_with_arguments(arg); end + def test_public; end + + protected + def test_protected; end + + private + def test_private; end + end + RUBY + + def test_test_case_returns_true_for_test_case + assert Helper.test_case?(method_node(:test_public)) + end + + def test_test_case_returns_false_for_hidden_test_methods + refute Helper.test_case?(method_node(:test_protected)) + refute Helper.test_case?(method_node(:test_private)) + end + + def test_test_case_returns_false_for_non_test_methods + refute Helper.test_case?(method_node(:non_test_case)) + end + + def test_test_case_returns_false_for_test_methods_with_arguments + refute Helper.test_case?(method_node(:test_with_arguments)) + end + + private + + def method_node(method_name) + class_node = parse_source!(SOURCE).ast + class_node.body.each_child_node(:def).find { |def_node| def_node.method?(method_name) } + end +end