rubocop/rubocop-rspec

`RSpec/ChangeByZero`'s autocorrection causes syntax error if `by(0)` is split into separate lines

r7kamura opened this issue · 0 comments

I found that if by(0) is split into separate lines, the autocorrection result contains an unnecessary empty line, resulting in a syntax error:

# before
expect { foo }
  .to change(Foo, :bar)
  .by(0)
  .and change(Foo, :baz)

# after
expect { foo }
  .to not_change(Foo, :bar)

  .and change(Foo, :baz)

This can be confirmed by the following test code:

diff --git a/spec/rubocop/cop/rspec/change_by_zero_spec.rb b/spec/rubocop/cop/rspec/change_by_zero_spec.rb
index a6789409..d8e0bc84 100644
--- a/spec/rubocop/cop/rspec/change_by_zero_spec.rb
+++ b/spec/rubocop/cop/rspec/change_by_zero_spec.rb
@@ -258,6 +258,22 @@ RSpec.describe RuboCop::Cop::RSpec::ChangeByZero do
         end
       RUBY
     end
+
+    it do
+      expect_offense(<<~RUBY)
+        expect { foo }
+          .to change(Foo, :bar)
+              ^^^^^^^^^^^^^^^^^ Prefer `not_change` with compound expectations over `change.by(0)`.
+          .by(0)
+          .and change(Foo, :baz)
+      RUBY
+
+      expect_correction(<<~RUBY)
+        expect { foo }
+          .to not_change(Foo, :bar)
+          .and change(Foo, :baz)
+      RUBY
+    end
   end
 
   it 'does not register an offense when the argument to `by` is not zero' do
Failures:

  1) RuboCop::Cop::RSpec::ChangeByZero with `NegatedMatcher: 'not_change'` is expected to eq "expect { foo }\n  .to not_change(Foo, :bar)\n  .and change(Foo, :baz)\n"
     Failure/Error:
       expect_correction(<<~RUBY)
         expect { foo }
           .to not_change(Foo, :bar)
           .and change(Foo, :baz)
       RUBY
     
       expected: "expect { foo }\n  .to not_change(Foo, :bar)\n  .and change(Foo, :baz)\n"
            got: "expect { foo }\n  .to not_change(Foo, :bar)\n  \n  .and change(Foo, :baz)\n"
     
       (compared using ==)
     
       Diff:
       @@ -1,4 +1,5 @@
        expect { foo }
          .to not_change(Foo, :bar)
       +  
          .and change(Foo, :baz)
       
     # ./spec/rubocop/cop/rspec/change_by_zero_spec.rb:271:in `block (3 levels) in <top (required)>'