forked from rubocop/rubocop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request rubocop#1205 from jonas054/835_percent_q_case_cop
Add cop PercentQLiterals
- Loading branch information
Showing
10 changed files
with
199 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# encoding: utf-8 | ||
|
||
module RuboCop | ||
module Cop | ||
module Style | ||
# This cop checks for usage of the %Q() syntax when %q() would do. | ||
class PercentQLiterals < Cop | ||
include PercentLiteral | ||
include ConfigurableEnforcedStyle | ||
|
||
def on_str(node) | ||
process(node, '%Q', '%q') | ||
end | ||
|
||
private | ||
|
||
def on_percent_literal(node) | ||
if style == :lower_case_q | ||
if type(node) == '%Q' | ||
check(node, | ||
'Do not use `%Q` unless interpolation is needed. ' \ | ||
'Use `%q`.') | ||
end | ||
elsif type(node) == '%q' | ||
check(node, 'Use `%Q` instead of `%q`.') | ||
end | ||
end | ||
|
||
def check(node, msg) | ||
src = node.loc.expression.source | ||
# Report offense only if changing case doesn't change semantics, | ||
# i.e., if the string would become dynamic or has special characters. | ||
return if node.children != | ||
ProcessedSource.new(corrected(src)).ast.children | ||
|
||
add_offense(node, :begin, msg) | ||
end | ||
|
||
def autocorrect(node) | ||
src = node.loc.expression.source | ||
|
||
@corrections << lambda do |corrector| | ||
corrector.replace(node.loc.expression, corrected(src)) | ||
end | ||
end | ||
|
||
def corrected(src) | ||
src.sub(src[1], src[1].swapcase) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# encoding: utf-8 | ||
|
||
require 'spec_helper' | ||
|
||
describe RuboCop::Cop::Style::PercentQLiterals, :config do | ||
subject(:cop) { described_class.new(config) } | ||
|
||
shared_examples 'accepts quote characters' do | ||
it 'accepts single quotes' do | ||
inspect_source(cop, ["'hi'"]) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'accepts double quotes' do | ||
inspect_source(cop, ['"hi"']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
end | ||
|
||
shared_examples 'accepts any q string with backslash t' do | ||
context 'with special characters' do | ||
it 'accepts %q' do | ||
inspect_source(cop, ['%q(\t)']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'accepts %Q' do | ||
inspect_source(cop, ['%Q(\t)']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
end | ||
end | ||
|
||
context 'when EnforcedStyle is lower_case_q' do | ||
let(:cop_config) { { 'EnforcedStyle' => 'lower_case_q' } } | ||
|
||
context 'without interpolation' do | ||
it 'accepts %q' do | ||
inspect_source(cop, ['%q(hi)']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'registers offense for %Q' do | ||
inspect_source(cop, ['%Q(hi)']) | ||
expect(cop.messages) | ||
.to eq(['Do not use `%Q` unless interpolation is needed. Use `%q`.']) | ||
expect(cop.highlights).to eq(['%Q(']) | ||
end | ||
|
||
it 'auto-corrects' do | ||
new_source = autocorrect_source(cop, '%Q(hi)') | ||
expect(new_source).to eq('%q(hi)') | ||
end | ||
|
||
include_examples 'accepts quote characters' | ||
include_examples 'accepts any q string with backslash t' | ||
end | ||
|
||
context 'with interpolation' do | ||
it 'accepts %Q' do | ||
inspect_source(cop, ['%Q(#{1 + 2})']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'accepts %q' do | ||
# This is most probably a mistake, but not this cop's responisibility. | ||
inspect_source(cop, ['%q(#{1 + 2})']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
include_examples 'accepts quote characters' | ||
end | ||
end | ||
|
||
context 'when EnforcedStyle is upper_case_q' do | ||
let(:cop_config) { { 'EnforcedStyle' => 'upper_case_q' } } | ||
|
||
context 'without interpolation' do | ||
it 'registers offense for %q' do | ||
inspect_source(cop, ['%q(hi)']) | ||
expect(cop.messages).to eq(['Use `%Q` instead of `%q`.']) | ||
expect(cop.highlights).to eq(['%q(']) | ||
end | ||
|
||
it 'accepts %Q' do | ||
inspect_source(cop, ['%Q(hi)']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'auto-corrects' do | ||
new_source = autocorrect_source(cop, '%q[hi]') | ||
expect(new_source).to eq('%Q[hi]') | ||
end | ||
|
||
include_examples 'accepts quote characters' | ||
include_examples 'accepts any q string with backslash t' | ||
end | ||
|
||
context 'with interpolation' do | ||
it 'accepts %Q' do | ||
inspect_source(cop, ['%Q(#{1 + 2})']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'accepts %q' do | ||
# It's strange if interpolation syntax appears inside a static string, | ||
# but we can't be sure if it's a mistake or not. Changing it to %Q | ||
# would alter semantics, so we leave it as it is. | ||
inspect_source(cop, ['%q(#{1 + 2})']) | ||
expect(cop.offenses).to be_empty | ||
end | ||
|
||
it 'does not auto-correct' do | ||
source = '%q(#{1 + 2})' | ||
new_source = autocorrect_source(cop, source) | ||
expect(new_source).to eq(source) | ||
end | ||
|
||
include_examples 'accepts quote characters' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters