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

Add new Minitest/TestCaseName cop #89

Merged
merged 1 commit into from
Jul 9, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

* [#92](https://github.com/rubocop-hq/rubocop-minitest/pull/92): Add new `Minitest/LiteralAsActualArgument` cop. ([@fatkodima][])
* [#91](https://github.com/rubocop-hq/rubocop-minitest/pull/91): Add new `Minitest/AssertInDelta` and `Minitest/RefuteInDelta` cops. ([@fatkodima][])
* [#89](https://github.com/rubocop-hq/rubocop-minitest/pull/89): Add new `Minitest/TestMethodName` cop. ([@fatkodima][])
* [#83](https://github.com/rubocop-hq/rubocop-minitest/pull/83): New cops `AssertPathExists` and `RefutePathExists` check for use of `assert_path_exists`/`refute_path_exists` instead of `assert(File.exist?(path))`/`refute(File.exist?(path))`. ([@fatkodima][])
* [#88](https://github.com/rubocop-hq/rubocop-minitest/pull/88): Add new `Minitest/MultipleAssertions` cop. ([@fatkodima][])
* [#87](https://github.com/rubocop-hq/rubocop-minitest/pull/87): Add new `Minitest/AssertSilent` cop. ([@fatkodima][])
Expand Down
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ Minitest/RefuteRespondTo:
Enabled: true
VersionAdded: '0.4'

Minitest/TestMethodName:
Description: 'This cop enforces that test method names start with `test_` prefix.'
Enabled: 'pending'
VersionAdded: '0.10'

Minitest/UnspecifiedException:
Description: 'This cop checks for a specified error in `assert_raises`.'
StyleGuide: 'https://minitest.rubystyle.guide#unspecified-exception'
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* xref:cops_minitest.adoc#minitestrefutenil[Minitest/RefuteNil]
* xref:cops_minitest.adoc#minitestrefutepathexists[Minitest/RefutePathExists]
* xref:cops_minitest.adoc#minitestrefuterespondto[Minitest/RefuteRespondTo]
* xref:cops_minitest.adoc#minitesttestmethodname[Minitest/TestMethodName]
* xref:cops_minitest.adoc#minitestunspecifiedexception[Minitest/UnspecifiedException]

// END_COP_LIST
33 changes: 33 additions & 0 deletions docs/modules/ROOT/pages/cops_minitest.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,39 @@ refute_respond_to(self, :do_something)

* https://minitest.rubystyle.guide#refute-respond-to

== Minitest/TestMethodName

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| Yes
| 0.10
| -
|===

This cop enforces that test method names start with `test_` prefix.

=== Examples

[source,ruby]
----
# bad
class FooTest < Minitest::Test
def does_something
assert_equal 42, do_something
end
end

# good
class FooTest < Minitest::Test
def test_does_something
assert_equal 42, do_something
end
end
----

== Minitest/UnspecifiedException

|===
Expand Down
70 changes: 70 additions & 0 deletions lib/rubocop/cop/minitest/test_method_name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Minitest
# This cop enforces that test method names start with `test_` prefix.
#
# @example
# # bad
# class FooTest < Minitest::Test
# def does_something
# assert_equal 42, do_something
# end
# end
#
# # good
# class FooTest < Minitest::Test
# def test_does_something
# assert_equal 42, do_something
# end
# end
#
class TestMethodName < Cop
include MinitestExplorationHelpers
include DefNode

MSG = 'Test method name should start with `test_` prefix.'

def on_class(class_node)
return unless test_class?(class_node)

class_elements(class_node).each do |node|
add_offense(node, location: :name) if offense?(node)
end
end

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.name, "test_#{node.method_name}")
end
end

private

def class_elements(class_node)
class_def = class_node.body
return [] unless class_def

if class_def.def_type?
[class_def]
else
class_def.each_child_node(:def).to_a
end
end

def offense?(node)
public?(node) && !test_method_name?(node) && !lifecycle_hook_method?(node)
end

def public?(node)
!non_public?(node)
end

def test_method_name?(node)
node.method_name.to_s.start_with?('test_')
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/minitest_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
require_relative 'minitest/refute_instance_of'
require_relative 'minitest/refute_path_exists'
require_relative 'minitest/refute_respond_to'
require_relative 'minitest/test_method_name'
require_relative 'minitest/unspecified_exception'
13 changes: 13 additions & 0 deletions lib/rubocop/cop/mixin/minitest_exploration_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ module MinitestExplorationHelpers
refute_same
].to_set.freeze

LIFECYCLE_HOOK_METHODS = %i[
before_setup
setup
after_setup
before_teardown
teardown
after_teardown
].to_set.freeze

private

def test_class?(class_node)
Expand All @@ -70,6 +79,10 @@ def test_cases(class_node)
def assertion?(node)
node.send_type? && ASSERTIONS.include?(node.method_name)
end

def lifecycle_hook_method?(node)
node.def_type? && LIFECYCLE_HOOK_METHODS.include?(node.method_name)
end
end
end
end
2 changes: 1 addition & 1 deletion test/rubocop/cop/minitest/refute_empty_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_do_something
RUBY
end

def refute_empty_method
def test_refute_empty_method
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
Expand Down
2 changes: 1 addition & 1 deletion test/rubocop/cop/minitest/refute_instance_of_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def test_do_something
RUBY
end

def refute_instance_of_method
def test_refute_instance_of_method
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
Expand Down
57 changes: 57 additions & 0 deletions test/rubocop/cop/minitest/test_method_name_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

require 'test_helper'

class TestMethodNameTest < Minitest::Test
def test_registers_offense_when_test_method_without_prefix
assert_offense(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
end

def do_something_else
^^^^^^^^^^^^^^^^^ Test method name should start with `test_` prefix.
end
end
RUBY

assert_correction(<<~RUBY)
class FooTest < Minitest::Test
def test_do_something
end

def test_do_something_else
end
end
RUBY
end

def test_checks_only_test_classes
assert_no_offenses(<<~RUBY)
class FooTest
def do_something
end
end
RUBY
end

def test_does_not_register_offense_when_hook_method
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
def setup
end
end
RUBY
end

def test_does_not_register_offense_when_non_public_method
assert_no_offenses(<<~RUBY)
class FooTest < Minitest::Test
private

def do_something
end
end
RUBY
end
end