diff --git a/CHANGELOG.md b/CHANGELOG.md index 63b843d20..23996c01e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Master (Unreleased) +- Add support for `assert_true` and `assert_false` to `RSpec/Rails/MinitestAssertions`. ([@ydah]) - Support asserts with messages in `Rspec/BeEmpty`. ([@G-Rath]) - Add support for `assert_empty`, `assert_not_empty` and `refute_empty` to `RSpec/Rails/MinitestAssertions`. ([@ydah]) - Support correcting some `*_predicate` assertions in `RSpec/Rails/MinitestAssertions`. ([@G-Rath]) diff --git a/config/default.yml b/config/default.yml index e60e75ffd..f96ec72ba 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1172,7 +1172,7 @@ RSpec/Rails/InferredSpecType: views: view RSpec/Rails/MinitestAssertions: - Description: Check if using Minitest matchers. + Description: Check if using Minitest-like matchers. Enabled: pending VersionAdded: '2.17' Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions diff --git a/docs/modules/ROOT/pages/cops_rspec_rails.adoc b/docs/modules/ROOT/pages/cops_rspec_rails.adoc index d9aead83c..5149f60fd 100644 --- a/docs/modules/ROOT/pages/cops_rspec_rails.adoc +++ b/docs/modules/ROOT/pages/cops_rspec_rails.adoc @@ -252,7 +252,10 @@ end | - |=== -Check if using Minitest matchers. +Check if using Minitest-like matchers. + +Check the use of minitest-like matchers +starting with `assert_` or `refute_`. === Examples @@ -265,6 +268,8 @@ assert_not_includes a, b refute_equal(a, b) assert_nil a refute_empty(b) +assert_true(a) +assert_false(a) # good expect(b).to eq(a) @@ -273,6 +278,8 @@ expect(a).not_to include(b) expect(b).not_to eq(a) expect(a).to eq(nil) expect(a).not_to be_empty +expect(a).to be(true) +expect(a).to be(false) ---- === References diff --git a/lib/rubocop/cop/rspec/rails/minitest_assertions.rb b/lib/rubocop/cop/rspec/rails/minitest_assertions.rb index 8f25d47c5..16f64f3a2 100644 --- a/lib/rubocop/cop/rspec/rails/minitest_assertions.rb +++ b/lib/rubocop/cop/rspec/rails/minitest_assertions.rb @@ -4,7 +4,10 @@ module RuboCop module Cop module RSpec module Rails - # Check if using Minitest matchers. + # Check if using Minitest-like matchers. + # + # Check the use of minitest-like matchers + # starting with `assert_` or `refute_`. # # @example # # bad @@ -14,6 +17,8 @@ module Rails # refute_equal(a, b) # assert_nil a # refute_empty(b) + # assert_true(a) + # assert_false(a) # # # good # expect(b).to eq(a) @@ -22,6 +27,8 @@ module Rails # expect(b).not_to eq(a) # expect(a).to eq(nil) # expect(a).not_to be_empty + # expect(a).to be(true) + # expect(a).to be(false) # class MinitestAssertions < Base extend AutoCorrector @@ -215,6 +222,46 @@ def assertion end end + # :nodoc: + class TrueAssertion < BasicAssertion + MATCHERS = %i[ + assert_true + ].freeze + + # @!method self.minitest_assertion(node) + def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective + (send nil? {:assert_true} $_ $_?) + PATTERN + + def self.match(actual, failure_message) + new(nil, actual, failure_message.first) + end + + def assertion + 'be(true)' + end + end + + # :nodoc: + class FalseAssertion < BasicAssertion + MATCHERS = %i[ + assert_false + ].freeze + + # @!method self.minitest_assertion(node) + def_node_matcher 'self.minitest_assertion', <<~PATTERN # rubocop:disable InternalAffairs/NodeMatcherDirective + (send nil? {:assert_false} $_ $_?) + PATTERN + + def self.match(actual, failure_message) + new(nil, actual, failure_message.first) + end + + def assertion + 'be(false)' + end + end + MSG = 'Use `%s`.' # TODO: replace with `BasicAssertion.subclasses` in Ruby 3.1+ diff --git a/spec/rubocop/cop/rspec/rails/minitest_assertions_spec.rb b/spec/rubocop/cop/rspec/rails/minitest_assertions_spec.rb index 0fdbe8af5..de3f81bf9 100644 --- a/spec/rubocop/cop/rspec/rails/minitest_assertions_spec.rb +++ b/spec/rubocop/cop/rspec/rails/minitest_assertions_spec.rb @@ -508,6 +508,100 @@ end end + context 'with boolean assertions' do + it 'registers an offense when using `assert_true`' do + expect_offense(<<~RUBY) + assert_true(a) + ^^^^^^^^^^^^^^ Use `expect(a).to be(true)`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to be(true) + RUBY + end + + it 'registers an offense when using `assert_true` with no parentheses' do + expect_offense(<<~RUBY) + assert_true a + ^^^^^^^^^^^^^ Use `expect(a).to be(true)`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to be(true) + RUBY + end + + it 'registers an offense when using `assert_true` with failure message' do + expect_offense(<<~RUBY) + assert_true a, "must be true" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `expect(a).to(be(true), "must be true")`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to(be(true), "must be true") + RUBY + end + + it 'registers an offense when using `assert_true` with ' \ + 'multi-line arguments' do + expect_offense(<<~RUBY) + assert_true(a, + ^^^^^^^^^^^^^^ Use `expect(a).to(be(true), "must be true")`. + "must be true") + RUBY + + expect_correction(<<~RUBY) + expect(a).to(be(true), "must be true") + RUBY + end + + it 'registers an offense when using `assert_false`' do + expect_offense(<<~RUBY) + assert_false(a) + ^^^^^^^^^^^^^^^ Use `expect(a).to be(false)`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to be(false) + RUBY + end + + it 'registers an offense when using `assert_false` with no parentheses' do + expect_offense(<<~RUBY) + assert_false a + ^^^^^^^^^^^^^^ Use `expect(a).to be(false)`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to be(false) + RUBY + end + + it 'registers an offense when using `assert_false` with failure message' do + expect_offense(<<~RUBY) + assert_false a, "must be false" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `expect(a).to(be(false), "must be false")`. + RUBY + + expect_correction(<<~RUBY) + expect(a).to(be(false), "must be false") + RUBY + end + + it 'registers an offense when using `assert_false` with ' \ + 'multi-line arguments' do + expect_offense(<<~RUBY) + assert_false(a, + ^^^^^^^^^^^^^^^ Use `expect(a).to(be(false), "must be false")`. + "must be false") + RUBY + + expect_correction(<<~RUBY) + expect(a).to(be(false), "must be false") + RUBY + end + end + context 'with predicate assertions' do it 'registers an offense when using `assert_predicate` with ' \ 'an actual predicate' do