Skip to content

Commit d860600

Browse files
committed
Fix RSpec/ExampleWording autocorrection to correctly escape quotes on str node case
1 parent df5d398 commit d860600

File tree

3 files changed

+107
-7
lines changed

3 files changed

+107
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- Fix a false positive for `RSpec/ExpectActual` when used with rspec-rails routing matchers. ([@naveg])
1515
- Add new `RSpec/RepeatedSubjectCall` cop. ([@drcapulet])
1616
- Add configuration option `ResponseMethods` to `RSpec/Rails/HaveHttpStatus`. ([@ydah])
17+
- Fix `RSpec/ExampleWording` in escaping and `%` string literals. ([@r7kamura])
1718

1819
## 2.26.1 (2024-01-05)
1920

lib/rubocop/cop/rspec/example_wording.rb

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,27 @@ def add_wording_offense(node, message)
9292
add_offense(docstring, message: message) do |corrector|
9393
next if node.heredoc?
9494

95-
corrector.replace(docstring, replacement_text(node))
95+
if node.str_type? && needs_escape?(node)
96+
corrector.replace(node, replacement_text(node).inspect)
97+
else
98+
corrector.replace(docstring, replacement_text(node))
99+
end
96100
end
97101
end
98102

99103
def docstring(node)
100-
expr = node.source_range
104+
if node.str_type? && !node.heredoc?
105+
node.source_range.with(
106+
begin_pos: node.loc.begin.end_pos,
107+
end_pos: node.loc.end.begin_pos
108+
)
109+
else
110+
node.source_range.adjust(begin_pos: 1, end_pos: -1)
111+
end
112+
end
101113

102-
Parser::Source::Range.new(
103-
expr.source_buffer,
104-
expr.begin_pos + 1,
105-
expr.end_pos - 1
106-
)
114+
def needs_escape?(node)
115+
node.value.include?(node.loc.end.source)
107116
end
108117

109118
def replacement_text(node)

spec/rubocop/cop/rspec/example_wording_spec.rb

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,94 @@
352352
RUBY
353353
end
354354
end
355+
356+
context "when message includes `'` in `'...'`" do
357+
it 'corrects message with `String#inspect`' do
358+
expect_offense(<<~'RUBY')
359+
it 'should return foo\'s bar' do
360+
^^^^^^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
361+
end
362+
RUBY
363+
364+
expect_correction(<<~RUBY)
365+
it "returns foo's bar" do
366+
end
367+
RUBY
368+
end
369+
end
370+
371+
context 'when message includes `"` in `"..."`' do
372+
it 'corrects message with `String#inspect`' do
373+
expect_offense(<<~'RUBY')
374+
it "should return \"foo\"" do
375+
^^^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
376+
end
377+
RUBY
378+
379+
expect_correction(<<~'RUBY')
380+
it "returns \"foo\"" do
381+
end
382+
RUBY
383+
end
384+
end
385+
386+
context 'when message includes `!` in `%!...!`' do
387+
it 'corrects message with `String#inspect`' do
388+
expect_offense(<<~'RUBY')
389+
it %!should return foo\!! do
390+
^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
391+
end
392+
RUBY
393+
394+
expect_correction(<<~RUBY)
395+
it "returns foo!" do
396+
end
397+
RUBY
398+
end
399+
end
400+
401+
context 'when message includes `)` in `%q(...)`' do
402+
it 'corrects message with `String#inspect`' do
403+
expect_offense(<<~RUBY)
404+
it %q(should return foo (bar)) do
405+
^^^^^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
406+
end
407+
RUBY
408+
409+
expect_correction(<<~RUBY)
410+
it "returns foo (bar)" do
411+
end
412+
RUBY
413+
end
414+
end
415+
416+
context 'when message includes `"` in `%q(...)`' do
417+
it 'corrects message with direct substring replacement' do
418+
expect_offense(<<~RUBY)
419+
it %q(should return "foo") do
420+
^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
421+
end
422+
RUBY
423+
424+
expect_correction(<<~RUBY)
425+
it %q(returns "foo") do
426+
end
427+
RUBY
428+
end
429+
end
430+
431+
context 'when message includes `"` and `)` in `%q(...)`' do
432+
it 'corrects message with `String#inspect`' do
433+
expect_offense(<<~RUBY)
434+
it %q(should return "foo (bar)") do
435+
^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use should when describing your tests.
436+
end
437+
RUBY
438+
439+
expect_correction(<<~'RUBY')
440+
it "returns \"foo (bar)\"" do
441+
end
442+
RUBY
443+
end
444+
end
355445
end

0 commit comments

Comments
 (0)