|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +module RuboCop |
| 4 | + module Cop |
| 5 | + module RSpec |
| 6 | + # Checks for usage of explicit subject that could be implicit. |
| 7 | + # |
| 8 | + # This Cop is not safe as it might be confused by what is the subject. |
| 9 | + # |
| 10 | + # # bad |
| 11 | + # subject(:foo) { :bar } |
| 12 | + # it { expect(foo).to eq :bar } |
| 13 | + # it { foo.should eq :bar } |
| 14 | + # |
| 15 | + # # good |
| 16 | + # subject(:foo) { :bar } |
| 17 | + # it { is_expected.to eq :bar } |
| 18 | + # it { should eq :bar } |
| 19 | + # |
| 20 | + # # also good |
| 21 | + # it { expect { foo }.to raise_error } |
| 22 | + # it { expect(foo.to_s).to eq 'bar' } |
| 23 | + # |
| 24 | + class UnusedImplicitSubject < Base |
| 25 | + extend AutoCorrector |
| 26 | + |
| 27 | + MSG = 'Use implicit subject.' |
| 28 | + RESTRICT_ON_SEND = %i[expect should subject subject!].freeze |
| 29 | + |
| 30 | + def_node_matcher :subject_definition, |
| 31 | + '(send #rspec? {:subject :subject!} (sym $_name))' |
| 32 | + def_node_matcher :subject_should?, |
| 33 | + '(send (send nil? %subject) :should ...)' |
| 34 | + def_node_matcher :expect_subject?, |
| 35 | + '(send nil? :expect (send nil? %subject))' |
| 36 | + |
| 37 | + def on_send(node) |
| 38 | + send(node.method_name, node) |
| 39 | + end |
| 40 | + |
| 41 | + private |
| 42 | + |
| 43 | + def subject(node) |
| 44 | + @cur_subject = subject_definition(node) |
| 45 | + end |
| 46 | + alias subject! subject |
| 47 | + |
| 48 | + def should(node) |
| 49 | + return unless subject_should?(node, subject: @cur_subject) |
| 50 | + |
| 51 | + range = node.receiver.loc.expression.join(node.loc.selector) |
| 52 | + add_offense(range) { |c| c.replace(range, 'should') } |
| 53 | + end |
| 54 | + |
| 55 | + def expect(node) |
| 56 | + return unless expect_subject?(node, subject: @cur_subject) |
| 57 | + |
| 58 | + add_offense(node) { |c| c.replace(node, 'is_expected') } |
| 59 | + end |
| 60 | + end |
| 61 | + end |
| 62 | + end |
| 63 | +end |
0 commit comments