rubocop-minitest 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +18 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +5 -1
  4. data/.rubocop.yml +5 -3
  5. data/.rubocop_todo.yml +8 -7
  6. data/CHANGELOG.md +94 -37
  7. data/CONTRIBUTING.md +3 -3
  8. data/Gemfile +2 -2
  9. data/LICENSE.txt +1 -1
  10. data/README.md +20 -4
  11. data/Rakefile +29 -0
  12. data/bin/console +2 -0
  13. data/config/default.yml +100 -16
  14. data/docs/antora.yml +7 -0
  15. data/docs/modules/ROOT/nav.adoc +6 -0
  16. data/docs/modules/ROOT/pages/cops.adoc +49 -0
  17. data/docs/modules/ROOT/pages/cops_minitest.adoc +1050 -0
  18. data/docs/modules/ROOT/pages/index.adoc +5 -0
  19. data/docs/modules/ROOT/pages/installation.adoc +15 -0
  20. data/docs/modules/ROOT/pages/usage.adoc +32 -0
  21. data/{manual → legacy-docs}/cops.md +0 -0
  22. data/{manual → legacy-docs}/cops_minitest.md +16 -16
  23. data/legacy-docs/index.md +1 -0
  24. data/{manual → legacy-docs}/installation.md +0 -0
  25. data/{manual → legacy-docs}/usage.md +0 -0
  26. data/lib/rubocop/cop/generator.rb +56 -0
  27. data/lib/rubocop/cop/minitest/assert_empty_literal.rb +23 -7
  28. data/lib/rubocop/cop/minitest/assert_in_delta.rb +29 -0
  29. data/lib/rubocop/cop/minitest/assert_kind_of.rb +25 -0
  30. data/lib/rubocop/cop/minitest/assert_nil.rb +1 -0
  31. data/lib/rubocop/cop/minitest/assert_output.rb +49 -0
  32. data/lib/rubocop/cop/minitest/assert_path_exists.rb +59 -0
  33. data/lib/rubocop/cop/minitest/assert_silent.rb +45 -0
  34. data/lib/rubocop/cop/minitest/assert_truthy.rb +1 -0
  35. data/lib/rubocop/cop/minitest/assert_with_expected_argument.rb +38 -0
  36. data/lib/rubocop/cop/minitest/assertion_in_lifecycle_hook.rb +43 -0
  37. data/lib/rubocop/cop/minitest/global_expectations.rb +4 -4
  38. data/lib/rubocop/cop/minitest/literal_as_actual_argument.rb +53 -0
  39. data/lib/rubocop/cop/minitest/multiple_assertions.rb +63 -0
  40. data/lib/rubocop/cop/minitest/refute_equal.rb +2 -1
  41. data/lib/rubocop/cop/minitest/refute_false.rb +1 -0
  42. data/lib/rubocop/cop/minitest/refute_in_delta.rb +29 -0
  43. data/lib/rubocop/cop/minitest/refute_kind_of.rb +25 -0
  44. data/lib/rubocop/cop/minitest/refute_nil.rb +1 -0
  45. data/lib/rubocop/cop/minitest/refute_path_exists.rb +59 -0
  46. data/lib/rubocop/cop/minitest/test_method_name.rb +79 -0
  47. data/lib/rubocop/cop/minitest/unspecified_exception.rb +36 -0
  48. data/lib/rubocop/cop/minitest_cops.rb +16 -0
  49. data/lib/rubocop/cop/mixin/argument_range_helper.rb +10 -0
  50. data/lib/rubocop/cop/mixin/in_delta_mixin.rb +50 -0
  51. data/lib/rubocop/cop/mixin/minitest_cop_rule.rb +2 -1
  52. data/lib/rubocop/cop/mixin/minitest_exploration_helpers.rb +97 -0
  53. data/lib/rubocop/minitest/version.rb +8 -1
  54. data/mkdocs.yml +4 -4
  55. data/relnotes/v0.1.0.md +1 -1
  56. data/relnotes/v0.10.0.md +21 -0
  57. data/relnotes/v0.10.1.md +5 -0
  58. data/relnotes/v0.10.2.md +5 -0
  59. data/relnotes/v0.10.3.md +5 -0
  60. data/relnotes/v0.11.0.md +16 -0
  61. data/relnotes/v0.2.0.md +4 -4
  62. data/relnotes/v0.2.1.md +1 -1
  63. data/relnotes/v0.3.0.md +6 -6
  64. data/relnotes/v0.4.0.md +5 -5
  65. data/relnotes/v0.4.1.md +1 -1
  66. data/relnotes/v0.5.0.md +1 -1
  67. data/relnotes/v0.5.1.md +1 -1
  68. data/relnotes/v0.6.0.md +1 -1
  69. data/relnotes/v0.6.1.md +2 -2
  70. data/relnotes/v0.6.2.md +1 -1
  71. data/relnotes/v0.7.0.md +5 -5
  72. data/relnotes/v0.8.0.md +4 -4
  73. data/relnotes/v0.8.1.md +1 -1
  74. data/relnotes/v0.9.0.md +3 -3
  75. data/rubocop-minitest.gemspec +7 -7
  76. data/tasks/cops_documentation.rake +15 -264
  77. data/tasks/cut_release.rake +16 -0
  78. metadata +55 -20
  79. data/manual/index.md +0 -1
@@ -0,0 +1,5 @@
1
+ = RuboCop Minitest
2
+
3
+ A https://github.com/rubocop/rubocop[RuboCop] extension focused on enforcing Minitest best practices and coding conventions.
4
+
5
+ It's based on the community-driven https://minitest.rubystyle.guide[Minitest style guide].
@@ -0,0 +1,15 @@
1
+ = Installation
2
+
3
+ Just install the `rubocop-minitest` gem
4
+
5
+ [source,sh]
6
+ ----
7
+ gem install rubocop-minitest
8
+ ----
9
+
10
+ or if you use bundler put this in your `Gemfile`
11
+
12
+ [source,ruby]
13
+ ----
14
+ gem 'rubocop-minitest'
15
+ ----
@@ -0,0 +1,32 @@
1
+ = Usage
2
+
3
+ You need to tell RuboCop to load the Minitest extension. There are three
4
+ ways to do this:
5
+
6
+ == RuboCop configuration file
7
+
8
+ Put this into your `.rubocop.yml`.
9
+
10
+ [source,yaml]
11
+ ----
12
+ require: rubocop-minitest
13
+ ----
14
+
15
+ Now you can run `rubocop` and it will automatically load the RuboCop Minitest
16
+ cops together with the standard cops.
17
+
18
+ == Command line
19
+
20
+ [source,sh]
21
+ ----
22
+ rubocop --require rubocop-minitest
23
+ ----
24
+
25
+ == Rake task
26
+
27
+ [source,ruby]
28
+ ----
29
+ RuboCop::RakeTask.new do |task|
30
+ task.requires << 'rubocop-minitest'
31
+ end
32
+ ----
File without changes
@@ -23,7 +23,7 @@ assert_empty(object, 'message')
23
23
 
24
24
  ### References
25
25
 
26
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-empty](https://github.com/rubocop-hq/minitest-style-guide#assert-empty)
26
+ * [https://github.com/rubocop/minitest-style-guide#assert-empty](https://github.com/rubocop/minitest-style-guide#assert-empty)
27
27
 
28
28
  ## Minitest/AssertEmptyLiteral
29
29
 
@@ -66,7 +66,7 @@ assert_equal("rubocop-minitest", actual)
66
66
 
67
67
  ### References
68
68
 
69
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-equal-arguments-order](https://github.com/rubocop-hq/minitest-style-guide#assert-equal-arguments-order)
69
+ * [https://github.com/rubocop/minitest-style-guide#assert-equal-arguments-order](https://github.com/rubocop/minitest-style-guide#assert-equal-arguments-order)
70
70
 
71
71
  ## Minitest/AssertIncludes
72
72
 
@@ -91,7 +91,7 @@ assert_includes(collection, object, 'message')
91
91
 
92
92
  ### References
93
93
 
94
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-includes](https://github.com/rubocop-hq/minitest-style-guide#assert-includes)
94
+ * [https://github.com/rubocop/minitest-style-guide#assert-includes](https://github.com/rubocop/minitest-style-guide#assert-includes)
95
95
 
96
96
  ## Minitest/AssertInstanceOf
97
97
 
@@ -116,7 +116,7 @@ assert_instance_of(Class, object, 'message')
116
116
 
117
117
  ### References
118
118
 
119
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-instance-of](https://github.com/rubocop-hq/minitest-style-guide#assert-instance-of)
119
+ * [https://github.com/rubocop/minitest-style-guide#assert-instance-of](https://github.com/rubocop/minitest-style-guide#assert-instance-of)
120
120
 
121
121
  ## Minitest/AssertMatch
122
122
 
@@ -141,7 +141,7 @@ assert_match(matcher, string, 'message')
141
141
 
142
142
  ### References
143
143
 
144
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-match](https://github.com/rubocop-hq/minitest-style-guide#assert-match)
144
+ * [https://github.com/rubocop/minitest-style-guide#assert-match](https://github.com/rubocop/minitest-style-guide#assert-match)
145
145
 
146
146
  ## Minitest/AssertNil
147
147
 
@@ -166,7 +166,7 @@ assert_nil(actual, 'message')
166
166
 
167
167
  ### References
168
168
 
169
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-nil](https://github.com/rubocop-hq/minitest-style-guide#assert-nil)
169
+ * [https://github.com/rubocop/minitest-style-guide#assert-nil](https://github.com/rubocop/minitest-style-guide#assert-nil)
170
170
 
171
171
  ## Minitest/AssertRespondTo
172
172
 
@@ -193,7 +193,7 @@ assert_respond_to(self, :do_something)
193
193
 
194
194
  ### References
195
195
 
196
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-responds-to-method](https://github.com/rubocop-hq/minitest-style-guide#assert-responds-to-method)
196
+ * [https://github.com/rubocop/minitest-style-guide#assert-responds-to-method](https://github.com/rubocop/minitest-style-guide#assert-responds-to-method)
197
197
 
198
198
  ## Minitest/AssertTruthy
199
199
 
@@ -218,7 +218,7 @@ assert(actual, 'message')
218
218
 
219
219
  ### References
220
220
 
221
- * [https://github.com/rubocop-hq/minitest-style-guide#assert-truthy](https://github.com/rubocop-hq/minitest-style-guide#assert-truthy)
221
+ * [https://github.com/rubocop/minitest-style-guide#assert-truthy](https://github.com/rubocop/minitest-style-guide#assert-truthy)
222
222
 
223
223
  ## Minitest/GlobalExpectations
224
224
 
@@ -266,7 +266,7 @@ refute_empty(object, 'message')
266
266
 
267
267
  ### References
268
268
 
269
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-empty](https://github.com/rubocop-hq/minitest-style-guide#refute-empty)
269
+ * [https://github.com/rubocop/minitest-style-guide#refute-empty](https://github.com/rubocop/minitest-style-guide#refute-empty)
270
270
 
271
271
  ## Minitest/RefuteEqual
272
272
 
@@ -290,7 +290,7 @@ refute_equal("rubocop-minitest", actual)
290
290
 
291
291
  ### References
292
292
 
293
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-equal](https://github.com/rubocop-hq/minitest-style-guide#refute-equal)
293
+ * [https://github.com/rubocop/minitest-style-guide#refute-equal](https://github.com/rubocop/minitest-style-guide#refute-equal)
294
294
 
295
295
  ## Minitest/RefuteFalse
296
296
 
@@ -318,7 +318,7 @@ refute(actual, 'message')
318
318
 
319
319
  ### References
320
320
 
321
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-false](https://github.com/rubocop-hq/minitest-style-guide#refute-false)
321
+ * [https://github.com/rubocop/minitest-style-guide#refute-false](https://github.com/rubocop/minitest-style-guide#refute-false)
322
322
 
323
323
  ## Minitest/RefuteIncludes
324
324
 
@@ -343,7 +343,7 @@ refute_includes(collection, object, 'message')
343
343
 
344
344
  ### References
345
345
 
346
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-includes](https://github.com/rubocop-hq/minitest-style-guide#refute-includes)
346
+ * [https://github.com/rubocop/minitest-style-guide#refute-includes](https://github.com/rubocop/minitest-style-guide#refute-includes)
347
347
 
348
348
  ## Minitest/RefuteInstanceOf
349
349
 
@@ -368,7 +368,7 @@ refute_instance_of(Class, object, 'message')
368
368
 
369
369
  ### References
370
370
 
371
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-instance-of](https://github.com/rubocop-hq/minitest-style-guide#refute-instance-of)
371
+ * [https://github.com/rubocop/minitest-style-guide#refute-instance-of](https://github.com/rubocop/minitest-style-guide#refute-instance-of)
372
372
 
373
373
  ## Minitest/RefuteMatch
374
374
 
@@ -393,7 +393,7 @@ refute_match(matcher, string, 'message')
393
393
 
394
394
  ### References
395
395
 
396
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-match](https://github.com/rubocop-hq/minitest-style-guide#refute-match)
396
+ * [https://github.com/rubocop/minitest-style-guide#refute-match](https://github.com/rubocop/minitest-style-guide#refute-match)
397
397
 
398
398
  ## Minitest/RefuteNil
399
399
 
@@ -418,7 +418,7 @@ refute_nil(actual, 'message')
418
418
 
419
419
  ### References
420
420
 
421
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-nil](https://github.com/rubocop-hq/minitest-style-guide#refute-nil)
421
+ * [https://github.com/rubocop/minitest-style-guide#refute-nil](https://github.com/rubocop/minitest-style-guide#refute-nil)
422
422
 
423
423
  ## Minitest/RefuteRespondTo
424
424
 
@@ -445,4 +445,4 @@ refute_respond_to(self, :do_something)
445
445
 
446
446
  ### References
447
447
 
448
- * [https://github.com/rubocop-hq/minitest-style-guide#refute-respond-to](https://github.com/rubocop-hq/minitest-style-guide#refute-respond-to)
448
+ * [https://github.com/rubocop/minitest-style-guide#refute-respond-to](https://github.com/rubocop/minitest-style-guide#refute-respond-to)
@@ -0,0 +1 @@
1
+ A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing Minitest best practices and coding conventions.
File without changes
File without changes
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Source and test generator for new cops
6
+ #
7
+ # This generator will take a cop name and generate a source file
8
+ # and test file when given a valid qualified cop name.
9
+ class Generator
10
+ TEST_TEMPLATE = <<~TEST
11
+ # frozen_string_literal: true
12
+
13
+ require 'test_helper'
14
+
15
+ class %<cop_name>sTest < Minitest::Test
16
+ def test_registers_offense_when_using_bad_method
17
+ assert_offense(<<~RUBY)
18
+ bad_method
19
+ ^^^^^^^^^^ Use `#good_method` instead of `#bad_method`.
20
+ RUBY
21
+
22
+ assert_correction(<<~RUBY)
23
+ good_method
24
+ RUBY
25
+ end
26
+
27
+ def test_does_not_register_offense_when_using_good_method
28
+ assert_no_offenses(<<~RUBY)
29
+ good_method
30
+ RUBY
31
+ end
32
+ end
33
+ TEST
34
+
35
+ def write_test
36
+ write_unless_file_exists(test_path, generated_test)
37
+ end
38
+
39
+ private
40
+
41
+ def test_path
42
+ File.join(
43
+ 'test',
44
+ 'rubocop',
45
+ 'cop',
46
+ 'minitest',
47
+ "#{snake_case(badge.cop_name.to_s)}_test.rb"
48
+ )
49
+ end
50
+
51
+ def generated_test
52
+ generate(TEST_TEMPLATE)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -4,32 +4,48 @@ 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)`.
7
+ # instead of using `assert_equal([], object)`.
8
8
  #
9
9
  # @example
10
10
  # # bad
11
- # assert([], object)
12
- # assert({}, object)
11
+ # assert_equal([], object)
12
+ # assert_equal({}, object)
13
13
  #
14
14
  # # good
15
15
  # assert_empty(object)
16
16
  #
17
17
  class AssertEmptyLiteral < Cop
18
+ include ArgumentRangeHelper
19
+
18
20
  MSG = 'Prefer using `assert_empty(%<arguments>s)` over ' \
19
- '`assert(%<literal>s, %<arguments>s)`.'
21
+ '`assert_equal(%<literal>s, %<arguments>s)`.'
22
+ RESTRICT_ON_SEND = %i[assert_equal].freeze
20
23
 
21
- def_node_matcher :assert_with_empty_literal, <<~PATTERN
22
- (send nil? :assert ${hash array} $...)
24
+ def_node_matcher :assert_equal_with_empty_literal, <<~PATTERN
25
+ (send nil? :assert_equal ${hash array} $...)
23
26
  PATTERN
24
27
 
25
28
  def on_send(node)
26
- assert_with_empty_literal(node) do |literal, matchers|
29
+ assert_equal_with_empty_literal(node) do |literal, matchers|
30
+ return unless literal.values.empty?
31
+
27
32
  args = matchers.map(&:source).join(', ')
28
33
 
29
34
  message = format(MSG, literal: literal.source, arguments: args)
30
35
  add_offense(node, message: message)
31
36
  end
32
37
  end
38
+
39
+ def autocorrect(node)
40
+ assert_equal_with_empty_literal(node) do |_literal, matchers|
41
+ object = matchers.first
42
+
43
+ lambda do |corrector|
44
+ corrector.replace(node.loc.selector, 'assert_empty')
45
+ corrector.replace(first_and_second_arguments_range(node), object.source)
46
+ end
47
+ end
48
+ end
33
49
  end
34
50
  end
35
51
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # This cop enforces the test to use `assert_in_delta`
7
+ # instead of using `assert_equal` to compare floats.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # assert_equal(0.2, actual)
12
+ # assert_equal(0.2, actual, 'message')
13
+ #
14
+ # # good
15
+ # assert_in_delta(0.2, actual)
16
+ # assert_in_delta(0.2, actual, 0.001, 'message')
17
+ #
18
+ class AssertInDelta < Cop
19
+ include InDeltaMixin
20
+
21
+ RESTRICT_ON_SEND = %i[assert_equal].freeze
22
+
23
+ def_node_matcher :equal_floats_call, <<~PATTERN
24
+ (send nil? :assert_equal $_ $_ $...)
25
+ PATTERN
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # This cop enforces the test to use `assert_kind_of(Class, object)`
7
+ # over `assert(object.kind_of?(Class))`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # assert(object.kind_of?(Class))
12
+ # assert(object.kind_of?(Class), 'message')
13
+ #
14
+ # # good
15
+ # assert_kind_of(Class, object)
16
+ # assert_kind_of(Class, object, 'message')
17
+ #
18
+ class AssertKindOf < Cop
19
+ extend MinitestCopRule
20
+
21
+ define_rule :assert, target_method: :kind_of?, inverse: true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -20,6 +20,7 @@ module RuboCop
20
20
 
21
21
  MSG = 'Prefer using `assert_nil(%<arguments>s)` over ' \
22
22
  '`assert_equal(nil, %<arguments>s)`.'
23
+ RESTRICT_ON_SEND = %i[assert_equal].freeze
23
24
 
24
25
  def_node_matcher :assert_equal_with_nil, <<~PATTERN
25
26
  (send nil? :assert_equal nil $_ $...)
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # This cop checks for opportunities to use `assert_output`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # $stdout = StringIO.new
11
+ # puts object.method
12
+ # $stdout.rewind
13
+ # assert_match expected, $stdout.read
14
+ #
15
+ # # good
16
+ # assert_output(expected) { puts object.method }
17
+ #
18
+ class AssertOutput < Cop
19
+ include MinitestExplorationHelpers
20
+
21
+ MSG = 'Use `assert_output` instead of mutating %<name>s.'
22
+ OUTPUT_GLOBAL_VARIABLES = %i[$stdout $stderr].freeze
23
+
24
+ def on_gvasgn(node)
25
+ test_case_node = find_test_case(node)
26
+ return unless test_case_node
27
+
28
+ gvar_name = node.children.first
29
+ return unless OUTPUT_GLOBAL_VARIABLES.include?(gvar_name)
30
+
31
+ assertions(test_case_node).each do |assertion|
32
+ add_offense(assertion, message: format(MSG, name: gvar_name)) if references_gvar?(assertion, gvar_name)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def find_test_case(node)
39
+ def_ancestor = node.each_ancestor(:def).first
40
+ def_ancestor if test_case?(def_ancestor)
41
+ end
42
+
43
+ def references_gvar?(assertion, gvar_name)
44
+ assertion.each_descendant(:gvar).any? { |d| d.children.first == gvar_name }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Minitest
6
+ # This cop enforces the test to use `assert_path_exists`
7
+ # instead of using `assert(File.exist?(path))`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # assert(File.exist?(path))
12
+ # assert(File.exist?(path), 'message')
13
+ #
14
+ # # good
15
+ # assert_path_exists(path)
16
+ # assert_path_exists(path, 'message')
17
+ #
18
+ class AssertPathExists < Cop
19
+ MSG = 'Prefer using `%<good_method>s` over `%<bad_method>s`.'
20
+ RESTRICT_ON_SEND = %i[assert].freeze
21
+
22
+ def_node_matcher :assert_file_exists, <<~PATTERN
23
+ (send nil? :assert
24
+ (send
25
+ (const _ :File) {:exist? :exists?} $_)
26
+ $...)
27
+ PATTERN
28
+
29
+ def on_send(node)
30
+ assert_file_exists(node) do |path, failure_message|
31
+ failure_message = failure_message.first
32
+ good_method = build_good_method(path, failure_message)
33
+ message = format(MSG, good_method: good_method, bad_method: node.source)
34
+
35
+ add_offense(node, message: message)
36
+ end
37
+ end
38
+
39
+ def autocorrect(node)
40
+ assert_file_exists(node) do |path, failure_message|
41
+ failure_message = failure_message.first
42
+
43
+ lambda do |corrector|
44
+ replacement = build_good_method(path, failure_message)
45
+ corrector.replace(node, replacement)
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def build_good_method(path, message)
53
+ args = [path.source, message&.source].compact.join(', ')
54
+ "assert_path_exists(#{args})"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end