rubocop-minitest 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +6 -0
- data/CHANGELOG.md +53 -5
- data/Gemfile +2 -1
- data/README.md +2 -1
- data/config/default.yml +71 -11
- data/lib/rubocop-minitest.rb +0 -3
- data/lib/rubocop/cop/minitest/assert_empty.rb +6 -5
- data/lib/rubocop/cop/minitest/assert_empty_literal.rb +36 -0
- data/lib/rubocop/cop/minitest/assert_equal.rb +57 -0
- data/lib/rubocop/cop/minitest/assert_includes.rb +7 -7
- data/lib/rubocop/cop/minitest/assert_instance_of.rb +60 -0
- data/lib/rubocop/cop/minitest/assert_nil.rb +2 -1
- data/lib/rubocop/cop/minitest/assert_respond_to.rb +59 -0
- data/lib/rubocop/cop/minitest/assert_truthy.rb +2 -2
- data/lib/rubocop/cop/minitest/refute_empty.rb +51 -0
- data/lib/rubocop/cop/minitest/refute_equal.rb +69 -0
- data/lib/rubocop/cop/minitest/refute_false.rb +46 -0
- data/lib/rubocop/cop/minitest/refute_includes.rb +60 -0
- data/lib/rubocop/cop/minitest/refute_instance_of.rb +60 -0
- data/lib/rubocop/cop/minitest/refute_nil.rb +2 -1
- data/lib/rubocop/cop/minitest/refute_respond_to.rb +59 -0
- data/lib/rubocop/cop/minitest_cops.rb +10 -0
- data/lib/rubocop/minitest/version.rb +1 -1
- data/manual/cops.md +10 -0
- data/manual/cops_minitest.md +264 -15
- data/relnotes/v0.1.0.md +7 -0
- data/relnotes/v0.2.0.md +9 -0
- data/relnotes/v0.2.1.md +5 -0
- data/relnotes/v0.3.0.md +16 -0
- data/relnotes/v0.4.0.md +14 -0
- data/relnotes/v0.4.1.md +5 -0
- data/relnotes/v0.5.0.md +5 -0
- data/tasks/cut_release.rake +60 -0
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fb2a1153e8f5e4eb37a349fcdfff211a421369606facb6d866fbc4701a60d6c
|
4
|
+
data.tar.gz: 2e258868d43eddc169e142e408e01d52e7d6e63ac5e9f1f53643feca8ff8968e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 466706a3aa3020369c7b855c20ad0619cfd8d2e4c94a6f260287908ce2d5ecefdc8190bc88a60d7cb59d0cdd39a276dc87ebdea91c240a5d820e167d984424c9
|
7
|
+
data.tar.gz: 6aede577f029efa7fb8a2cf89151261c16dfe57f980100b568c8e11252b7652e45cac051f404212411e2cac2a0232d0c4c752322f6781fa3c37297e6a10eae11
|
data/.github/FUNDING.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,22 +1,70 @@
|
|
1
|
+
# Change log
|
2
|
+
|
1
3
|
## master (unreleased)
|
2
4
|
|
5
|
+
## 0.5.0 (2019-11-24)
|
6
|
+
|
7
|
+
### New features
|
8
|
+
|
9
|
+
* [#32](https://github.com/rubocop-hq/rubocop-minitest/issues/32): Add new `Minitest/AssertEmptyLiteral` cop. ([@tejasbubane][])
|
10
|
+
|
11
|
+
## 0.4.1 (2019-11-10)
|
12
|
+
|
13
|
+
### Bug fixes
|
14
|
+
|
15
|
+
* [#39](https://github.com/rubocop-hq/rubocop-minitest/issues/39): Fix an incorrect autocorrect for `Minitest/AssertRespondTo` and `Minitest/RefuteRespondTo` when using assertion method calling `respond_to` with receiver omitted. ([@koic][])
|
16
|
+
|
17
|
+
## 0.4.0 (2019-11-07)
|
18
|
+
|
19
|
+
### New features
|
20
|
+
|
21
|
+
* [#29](https://github.com/rubocop-hq/rubocop-minitest/pull/29): Add new `Minitest/RefuteRespondTo` cop. ([@herwinw][])
|
22
|
+
* [#31](https://github.com/rubocop-hq/rubocop-minitest/pull/31): Add new `Minitest/AssertEqual` cop. ([@herwinw][])
|
23
|
+
* [#34](https://github.com/rubocop-hq/rubocop-minitest/pull/34): Add new `Minitest/AssertInstanceOf` cop. ([@abhaynikam][])
|
24
|
+
* [#35](https://github.com/rubocop-hq/rubocop-minitest/pull/35): Add new `Minitest/RefuteInstanceOf` cop. ([@abhaynikam][])
|
25
|
+
|
26
|
+
### Bug fixes
|
27
|
+
|
28
|
+
* [#25](https://github.com/rubocop-hq/rubocop-minitest/issues/25): Add `Enabled: true` to `Minitest` department config to suppress `Warning: Minitest does not support Enabled parameter`. ([@koic][])
|
29
|
+
|
30
|
+
## 0.3.0 (2019-10-13)
|
31
|
+
|
32
|
+
### New features
|
33
|
+
|
34
|
+
* [#15](https://github.com/rubocop-hq/rubocop-minitest/pull/15): Add new `Minitest/RefuteIncludes` cop. ([@abhaynikam][])
|
35
|
+
* [#18](https://github.com/rubocop-hq/rubocop-minitest/pull/18): Add new `Minitest/RefuteFalse` cop. ([@duduribeiro][])
|
36
|
+
* [#20](https://github.com/rubocop-hq/rubocop-minitest/pull/20): Add new `Minitest/RefuteEmpty` cop. ([@abhaynikam][])
|
37
|
+
* [#21](https://github.com/rubocop-hq/rubocop-minitest/pull/21): Add new `Minitest/RefuteEqual` cop. ([@duduribeiro][])
|
38
|
+
* [#27](https://github.com/rubocop-hq/rubocop-minitest/pull/27): Add new `Minitest/AssertRespondTo` cop. ([@duduribeiro][])
|
39
|
+
|
40
|
+
### Bug fixes
|
41
|
+
|
42
|
+
* [#19](https://github.com/rubocop-hq/rubocop-minitest/pull/19): Fix a false negative for `Minitest/AssertIncludes` when using `include` method in arguments of `assert` method. ([@abhaynikam][])
|
43
|
+
|
44
|
+
## 0.2.1 (2019-09-24)
|
45
|
+
|
46
|
+
### Bug fixes
|
47
|
+
|
48
|
+
* [#13](https://github.com/rubocop-hq/rubocop-minitest/issues/13): Fix the execution target specified in `Include` parameter. ([@koic][])
|
49
|
+
|
3
50
|
## 0.2.0 (2019-09-21)
|
4
51
|
|
5
52
|
### New features
|
6
53
|
|
7
|
-
* [#11](https://github.com/rubocop-hq/rubocop-minitest/pull/11): Add new `Minitest/RefuteNil` cop. ([@tejasbubane
|
8
|
-
* [#8](https://github.com/rubocop-hq/rubocop-minitest/pull/8): Add new `Minitest/AssertTruthy` cop. ([@abhaynikam
|
9
|
-
* [#9](https://github.com/rubocop-hq/rubocop-minitest/pull/9): Add new `Minitest/AssertIncludes` cop. ([@abhaynikam
|
10
|
-
* [#10](https://github.com/rubocop-hq/rubocop-minitest/pull/10): Add new `Minitest/AssertEmpty` cop. ([@abhaynikam
|
54
|
+
* [#11](https://github.com/rubocop-hq/rubocop-minitest/pull/11): Add new `Minitest/RefuteNil` cop. ([@tejasbubane][])
|
55
|
+
* [#8](https://github.com/rubocop-hq/rubocop-minitest/pull/8): Add new `Minitest/AssertTruthy` cop. ([@abhaynikam][])
|
56
|
+
* [#9](https://github.com/rubocop-hq/rubocop-minitest/pull/9): Add new `Minitest/AssertIncludes` cop. ([@abhaynikam][])
|
57
|
+
* [#10](https://github.com/rubocop-hq/rubocop-minitest/pull/10): Add new `Minitest/AssertEmpty` cop. ([@abhaynikam][])
|
11
58
|
|
12
59
|
## 0.1.0 (2019-09-01)
|
13
60
|
|
14
61
|
### New features
|
15
62
|
|
16
63
|
* Create RuboCop Minitest gem. ([@koic][])
|
17
|
-
* [#6](https://github.com/rubocop-hq/rubocop-minitest/pull/6): Add new `Minitest/AssertNil` cop. ([@duduribeiro
|
64
|
+
* [#6](https://github.com/rubocop-hq/rubocop-minitest/pull/6): Add new `Minitest/AssertNil` cop. ([@duduribeiro][])
|
18
65
|
|
19
66
|
[@koic]: https://github.com/koic
|
20
67
|
[@duduribeiro]: https://github.com/duduribeiro
|
21
68
|
[@tejasbubane]: https://github.com/tejasbubane
|
22
69
|
[@abhaynikam]: https://github.com/abhaynikam
|
70
|
+
[@herwinw]: https://github.com/herwinw
|
data/Gemfile
CHANGED
@@ -6,7 +6,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
6
6
|
|
7
7
|
gemspec
|
8
8
|
|
9
|
+
gem 'bump', require: false
|
9
10
|
gem 'rake'
|
10
11
|
gem 'rubocop', github: 'rubocop-hq/rubocop'
|
11
|
-
gem 'rubocop-performance', '~> 1.
|
12
|
+
gem 'rubocop-performance', '~> 1.5.0'
|
12
13
|
gem 'yard', '~> 0.9'
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
[![CircleCI](https://circleci.com/gh/rubocop-hq/rubocop-minitest.svg?style=svg)](https://circleci.com/gh/rubocop-hq/rubocop-minitest)
|
5
5
|
|
6
6
|
A [RuboCop](https://github.com/rubocop-hq/rubocop) extension focused on enforcing Minitest best practices and coding conventions.
|
7
|
+
The library is based on the guidelines outlined in the community [Minitest Style Guide](https://minitest.rubystyle.guide).
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
|
@@ -61,7 +62,7 @@ end
|
|
61
62
|
|
62
63
|
All cops are located under
|
63
64
|
[`lib/rubocop/cop/minitest`](lib/rubocop/cop/minitest), and contain
|
64
|
-
examples/documentation.
|
65
|
+
examples/documentation. The documentation is published [here](https://docs.rubocop.org/projects/minitest).
|
65
66
|
|
66
67
|
In your `.rubocop.yml`, you may treat the Minitest cops just like any other
|
67
68
|
cop. For example:
|
data/config/default.yml
CHANGED
@@ -1,33 +1,93 @@
|
|
1
|
-
|
1
|
+
Minitest:
|
2
|
+
Enabled: true
|
2
3
|
Include:
|
3
4
|
- '**/test/**/*'
|
4
5
|
|
5
|
-
Minitest/AssertNil:
|
6
|
-
Description: 'Check if your test uses `assert_nil` instead of `assert_equal(nil, something)`.'
|
7
|
-
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-nil'
|
8
|
-
Enabled: true
|
9
|
-
VersionAdded: '0.1'
|
10
|
-
|
11
6
|
Minitest/AssertEmpty:
|
12
|
-
Description: '
|
7
|
+
Description: 'This cop enforces the test to use `assert_empty` instead of using `assert(object.empty?)`.'
|
13
8
|
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-empty'
|
14
9
|
Enabled: true
|
15
10
|
VersionAdded: '0.2'
|
16
11
|
|
12
|
+
Minitest/AssertEmptyLiteral:
|
13
|
+
Description: 'This cop enforces the test to use `assert_empty` instead of using `assert([], object)` or `assert({}, object)`.'
|
14
|
+
Enabled: true
|
15
|
+
VersionAdded: '0.5'
|
16
|
+
|
17
|
+
Minitest/AssertEqual:
|
18
|
+
Description: 'This cop enforces the test to use `assert_equal` instead of using `assert(expected == actual)`.'
|
19
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-equal-arguments-order'
|
20
|
+
Enabled: true
|
21
|
+
VersionAdded: '0.4'
|
22
|
+
|
17
23
|
Minitest/AssertIncludes:
|
18
|
-
Description: '
|
24
|
+
Description: 'This cop enforces the test to use `assert_includes` instead of using `assert(collection.include?(object))`.'
|
19
25
|
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-includes'
|
20
26
|
Enabled: true
|
21
27
|
VersionAdded: '0.2'
|
22
28
|
|
29
|
+
Minitest/AssertInstanceOf:
|
30
|
+
Description: 'This cop enforces the test to use `assert_instance_of(Class, object)` over `assert(object.instance_of?(Class))`'
|
31
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-instance-of'
|
32
|
+
Enabled: true
|
33
|
+
VersionAdded: '0.4'
|
34
|
+
|
35
|
+
Minitest/AssertNil:
|
36
|
+
Description: 'This cop enforces the test to use `assert_nil` instead of using `assert_equal(nil, something)`.'
|
37
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-nil'
|
38
|
+
Enabled: true
|
39
|
+
VersionAdded: '0.1'
|
40
|
+
|
41
|
+
Minitest/AssertRespondTo:
|
42
|
+
Description: 'This cop enforces the test to use `assert_respond_to(object, :some_method)` over `assert(object.respond_to?(:some_method))`.'
|
43
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-responds-to-method'
|
44
|
+
Enabled: true
|
45
|
+
VersionAdded: '0.3'
|
46
|
+
|
23
47
|
Minitest/AssertTruthy:
|
24
|
-
Description: '
|
48
|
+
Description: 'This cop enforces the test to use `assert(actual)` instead of using `assert_equal(true, actual)`.'
|
25
49
|
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#assert-truthy'
|
26
50
|
Enabled: true
|
27
51
|
VersionAdded: '0.2'
|
28
52
|
|
53
|
+
Minitest/RefuteEmpty:
|
54
|
+
Description: 'This cop enforces to use `refute_empty` instead of using `refute(object.empty?)`.'
|
55
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-empty'
|
56
|
+
Enabled: true
|
57
|
+
VersionAdded: '0.3'
|
58
|
+
|
59
|
+
Minitest/RefuteEqual:
|
60
|
+
Description: 'Check if your test uses `refute_equal` instead of `assert(expected != object)` or `assert(! expected == object))`.'
|
61
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-equal'
|
62
|
+
Enabled: true
|
63
|
+
VersionAdded: '0.3'
|
64
|
+
|
65
|
+
Minitest/RefuteFalse:
|
66
|
+
Description: 'Check if your test uses `refute(actual)` instead of `assert_equal(false, actual)`.'
|
67
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-false'
|
68
|
+
Enabled: true
|
69
|
+
VersionAdded: '0.3'
|
70
|
+
|
71
|
+
Minitest/RefuteIncludes:
|
72
|
+
Description: 'This cop enforces the test to use `refute_includes` instead of using `refute(collection.include?(object))`.'
|
73
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-includes'
|
74
|
+
Enabled: true
|
75
|
+
VersionAdded: '0.3'
|
76
|
+
|
77
|
+
Minitest/RefuteInstanceOf:
|
78
|
+
Description: 'This cop enforces the test to use `refute_instance_of(Class, object)` over `refute(object.instance_of?(Class))`.'
|
79
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-instance-of'
|
80
|
+
Enabled: true
|
81
|
+
VersionAdded: '0.4'
|
82
|
+
|
29
83
|
Minitest/RefuteNil:
|
30
|
-
Description: '
|
84
|
+
Description: 'This cop enforces the test to use `refute_nil` instead of using `refute_equal(nil, something)`.'
|
31
85
|
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-nil'
|
32
86
|
Enabled: true
|
33
87
|
VersionAdded: '0.2'
|
88
|
+
|
89
|
+
Minitest/RefuteRespondTo:
|
90
|
+
Description: 'This cop enforces the test to use `refute_respond_to(object, :some_method)` over `refute(object.respond_to?(:some_method))`.'
|
91
|
+
StyleGuide: 'https://github.com/rubocop-hq/minitest-style-guide#refute-respond-to'
|
92
|
+
Enabled: true
|
93
|
+
VersionAdded: '0.4'
|
data/lib/rubocop-minitest.rb
CHANGED
@@ -3,16 +3,17 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Minitest
|
6
|
-
#
|
6
|
+
# This cop enforces the test to use `assert_empty`
|
7
|
+
# instead of using `assert(object.empty?)`.
|
7
8
|
#
|
8
9
|
# @example
|
9
10
|
# # bad
|
10
|
-
# assert(
|
11
|
-
# assert(
|
11
|
+
# assert(object.empty?)
|
12
|
+
# assert(object.empty?, 'the message')
|
12
13
|
#
|
13
14
|
# # good
|
14
|
-
# assert_empty(
|
15
|
-
# assert_empty(
|
15
|
+
# assert_empty(object)
|
16
|
+
# assert_empty(object, 'the message')
|
16
17
|
#
|
17
18
|
class AssertEmpty < Cop
|
18
19
|
MSG = 'Prefer using `assert_empty(%<arguments>s)` over ' \
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Minitest
|
6
|
+
# This cop enforces the test to use `assert_empty`
|
7
|
+
# instead of using `assert([], object)`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# assert([], object)
|
12
|
+
# assert({}, object)
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# assert_empty(object)
|
16
|
+
#
|
17
|
+
class AssertEmptyLiteral < Cop
|
18
|
+
MSG = 'Prefer using `assert_empty(%<arguments>s)` over ' \
|
19
|
+
'`assert(%<literal>s, %<arguments>s)`.'
|
20
|
+
|
21
|
+
def_node_matcher :assert_with_empty_literal, <<~PATTERN
|
22
|
+
(send nil? :assert ${hash array} $...)
|
23
|
+
PATTERN
|
24
|
+
|
25
|
+
def on_send(node)
|
26
|
+
assert_with_empty_literal(node) do |literal, matchers|
|
27
|
+
args = matchers.map(&:source).join(', ')
|
28
|
+
|
29
|
+
message = format(MSG, literal: literal.source, arguments: args)
|
30
|
+
add_offense(node, message: message)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Minitest
|
6
|
+
# This cop enforces the use of `assert_equal(expected, actual)`
|
7
|
+
# over `assert(expected == actual)`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# assert("rubocop-minitest" == actual)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# assert_equal("rubocop-minitest", actual)
|
15
|
+
#
|
16
|
+
class AssertEqual < Cop
|
17
|
+
MSG = 'Prefer using `assert_equal(%<preferred>s)` over ' \
|
18
|
+
'`assert(%<over>s)`.'
|
19
|
+
|
20
|
+
def_node_matcher :assert_equal, <<~PATTERN
|
21
|
+
(send nil? :assert $(send $_ :== $_) $...)
|
22
|
+
PATTERN
|
23
|
+
|
24
|
+
def on_send(node)
|
25
|
+
assert_equal(node) do
|
26
|
+
|first_receiver_arg, expected, actual, rest_receiver_arg|
|
27
|
+
|
28
|
+
message = rest_receiver_arg.first
|
29
|
+
preferred = [expected.source, actual.source, message&.source]
|
30
|
+
.compact.join(', ')
|
31
|
+
over = [first_receiver_arg.source, message&.source].compact.join(', ')
|
32
|
+
|
33
|
+
offense_message = format(MSG, preferred: preferred, over: over)
|
34
|
+
|
35
|
+
add_offense(node, message: offense_message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def autocorrect(node)
|
40
|
+
lambda do |corrector|
|
41
|
+
assert_equal(node) do |_receiver, expected, actual, rest_receiver_arg|
|
42
|
+
message = rest_receiver_arg.first
|
43
|
+
replacement = node_arguments(expected, actual, message)
|
44
|
+
corrector.replace(node.loc.expression, "assert_equal(#{replacement})")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def node_arguments(expected, actual, message)
|
52
|
+
[expected.source, actual.source, message&.source].compact.join(', ')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -3,24 +3,24 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Minitest
|
6
|
-
#
|
7
|
-
# instead of `assert(collection.
|
6
|
+
# This cop enforces the test to use `assert_includes`
|
7
|
+
# instead of using `assert(collection.include?(object))`.
|
8
8
|
#
|
9
9
|
# @example
|
10
10
|
# # bad
|
11
|
-
# assert(collection.
|
12
|
-
# assert(collection.
|
11
|
+
# assert(collection.include?(object))
|
12
|
+
# assert(collection.include?(object), 'the message')
|
13
13
|
#
|
14
14
|
# # good
|
15
|
-
# assert_includes(collection,
|
16
|
-
# assert_includes(collection,
|
15
|
+
# assert_includes(collection, object)
|
16
|
+
# assert_includes(collection, object, 'the message')
|
17
17
|
#
|
18
18
|
class AssertIncludes < Cop
|
19
19
|
MSG = 'Prefer using `assert_includes(%<arguments>s)` over ' \
|
20
20
|
'`assert(%<receiver>s)`.'
|
21
21
|
|
22
22
|
def_node_matcher :assert_with_includes, <<~PATTERN
|
23
|
-
(send nil? :assert $(send $_ :
|
23
|
+
(send nil? :assert $(send $_ :include? $_) $...)
|
24
24
|
PATTERN
|
25
25
|
|
26
26
|
def on_send(node)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Minitest
|
6
|
+
# This cop enforces the test to use `assert_instance_of(Class, object)`
|
7
|
+
# over `assert(object.instance_of?(Class))`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# assert(object.instance_of?(Class))
|
12
|
+
# assert(object.instance_of?(Class), 'the message')
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# assert_instance_of(Class, object)
|
16
|
+
# assert_instance_of(Class, object, 'the message')
|
17
|
+
#
|
18
|
+
class AssertInstanceOf < Cop
|
19
|
+
MSG = 'Prefer using `assert_instance_of(%<arguments>s)` over ' \
|
20
|
+
'`assert(%<receiver>s)`.'
|
21
|
+
|
22
|
+
def_node_matcher :assert_with_instance_of, <<~PATTERN
|
23
|
+
(send nil? :assert $(send $_ :instance_of? $_) $...)
|
24
|
+
PATTERN
|
25
|
+
|
26
|
+
def on_send(node)
|
27
|
+
assert_with_instance_of(node) do
|
28
|
+
|first_receiver_arg, object, method, rest_args|
|
29
|
+
|
30
|
+
message = rest_args.first
|
31
|
+
arguments = node_arguments(object, method, message)
|
32
|
+
receiver = [first_receiver_arg.source, message&.source].compact.join(', ')
|
33
|
+
|
34
|
+
offense_message = format(MSG, arguments: arguments, receiver: receiver)
|
35
|
+
|
36
|
+
add_offense(node, message: offense_message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def autocorrect(node)
|
41
|
+
lambda do |corrector|
|
42
|
+
assert_with_instance_of(node) do |_, object, method, rest_args|
|
43
|
+
message = rest_args.first
|
44
|
+
arguments = node_arguments(object, method, message)
|
45
|
+
|
46
|
+
replacement = "assert_instance_of(#{arguments})"
|
47
|
+
corrector.replace(node.loc.expression, replacement)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def node_arguments(object, method, message)
|
55
|
+
[method, object, message].compact.map(&:source).join(', ')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|