rubocop-rspec icon indicating copy to clipboard operation
rubocop-rspec copied to clipboard

RSpec/ChangeByZero auto-correct creates syntax errors

Open masuyama13 opened this issue 2 years ago • 2 comments

I'm using & matcher, which doesn't work with negative form. https://github.com/rspec/rspec-expectations/blob/main/lib/rspec/matchers/composable.rb#L25

In this case, auto-correct can be unsafe.

Example:

expect { subject }.to change { Task.count }.by(0) & change { TaskUser.count }.by(0)

running rubocop -a

Creates:

expect { subject }.to change { Task.count } not_to change { TaskUser.count }

This is syntactically incorrect.

Versions: rubocop-rspec: 2.11.1

% bundle exec rubocop -v
1.27.0
% bundle exec ruby -v   
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [aarch64-linux]

masuyama13 avatar Aug 04 '22 00:08 masuyama13

That is the issue, but I believe it has been resolved by ~https://github.com/rubocop/rubocop-rspec/issues/1353~ https://github.com/rubocop/rubocop-rspec/pull/1324 . Please wait for the next release.

ydah avatar Aug 04 '22 01:08 ydah

For test cases, we are creating patches to be added: https://github.com/rubocop/rubocop-rspec/pull/1355 It appears to be working fine, so I think it's fine.


Additional information: #1353 will no longer automatically correct the problem. This is because a negation matcher must be used for compound cases.

However, if a chage negation matcher is specified in the options added by #1349, it will be auto-modified. (so that syntax errors do not occur.)

ydah avatar Aug 04 '22 01:08 ydah

@masuyama13 A new version has been released😀 Please check if it works and if it works as expected, please close this Issue.

ydah avatar Sep 12 '22 21:09 ydah

I confirm that with 2.13.1 this is either not being corrected, of if NegatedMatcher: not_change is configured, corrected to

 expect { subject }.to not_change { Task.count } & not_change { TaskUser.count }

(edit: the original comment had all the auto-corrections applied, not just by this cop)

Darhazer avatar Sep 13 '22 13:09 Darhazer

This is a different Issue from this one, but there seems to be a case where a fix to Layout/LineLength and Style/BlockDelimiters causes a SyntaxError.

original

    expect { subject }.to change { Task.count }.by(0) & change { TaskUser.count }.by(0)

bundle exec rubocop -A --only Layout/LineLength

    expect { subject }.to change { Task.count }.by(0) & change {
 TaskUser.count }.by(0)

bundle exec rubocop -A --only Style/BlockDelimiters

    expect { subject }.to change { Task.count }.by(0) & change do
 TaskUser.count end.by(0)

The following syntax error occurs

     Failure/Error:
          expect { subject }.to change { Task.count }.by(0) & change do
       TaskUser.count end.by(0)
     
     TypeError:
       nil is not a symbol nor a string

ydah avatar Sep 13 '22 14:09 ydah

That have to be reported in rubocop itself, as it's issue with the BlockDelimiters autocorrect (the LineLength is not important, it just produced the code that would cause BlockDelimiters to incorrectly auto-correct, but you can type such code yourself)

Darhazer avatar Sep 13 '22 15:09 Darhazer

Indeed, I probably shouldn't have brought it up here. Sorry for going off topic.

ydah avatar Sep 14 '22 05:09 ydah

@ydah I confirmed that it works as expected. Thank you for fixing it.

masuyama13 avatar Sep 14 '22 15:09 masuyama13