forked from turboladen/tailor
-
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.
Parentheses around conditional, refs turboladen#91.
- Loading branch information
Andrew Crump
committed
Sep 27, 2013
1 parent
6b645b0
commit 75dfaba
Showing
7 changed files
with
427 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
require_relative '../ruler' | ||
|
||
class Tailor | ||
module Rulers | ||
class AllowConditionalParenthesesRuler < Tailor::Ruler | ||
def initialize(style, options) | ||
super(style, options) | ||
add_lexer_observers :nl | ||
end | ||
|
||
def nl_update(current_lexed_line, lineno, column) | ||
measure(current_lexed_line, lineno) | ||
end | ||
|
||
# Checks to see if a conditional is unnecessarily wrapped in parentheses. | ||
# | ||
# @param [Fixnum] line The current lexed line. | ||
# @param [Fixnum] lineno Line the problem was found on. | ||
def measure(line, lineno) | ||
return if @config | ||
return unless line.any? { |t| conditional?(t) } | ||
if tokens_before_lparen?(line) and ! tokens_after_rparen?(line) | ||
column = lparen_column(line) | ||
@problems << Problem.new('conditional_parentheses', lineno, column, | ||
"Parentheses around conditional expression at column #{column}.", | ||
@options[:level]) | ||
end | ||
end | ||
|
||
private | ||
|
||
def conditional?(token) | ||
token[1] == :on_kw and %w{case if unless while}.include?(token[2]) | ||
end | ||
|
||
def lparen?(token) | ||
token[1] == :on_lparen | ||
end | ||
|
||
def lparen_column(tokens) | ||
tokens.find { |t| lparen?(t) }[0][1] + 1 | ||
end | ||
|
||
def tokens_before_lparen?(tokens) | ||
without_spaces( | ||
tokens.select do |t| | ||
true if (conditional?(t))..(lparen?(t)) | ||
end.tap { |t| t.shift; t.pop } | ||
).empty? | ||
end | ||
|
||
def tokens_after_rparen?(tokens) | ||
without_spaces( | ||
tokens.reverse.tap do |nl| | ||
nl.shift | ||
end.take_while { |t| t[1] != :on_rparen } | ||
).any? | ||
end | ||
|
||
def without_spaces(tokens) | ||
tokens.reject { |t| t[1] == :on_sp } | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
require 'spec_helper' | ||
require_relative '../support/conditional_parentheses_cases' | ||
require 'tailor/critic' | ||
require 'tailor/configuration/style' | ||
|
||
describe 'Conditional parentheses' do | ||
|
||
def file_name | ||
self.class.description | ||
end | ||
|
||
def contents | ||
CONDITIONAL_PARENTHESES[file_name] || begin | ||
raise "Example not found: #{file_name}" | ||
end | ||
end | ||
|
||
before do | ||
Tailor::Logger.stub(:log) | ||
FakeFS.activate! | ||
FileUtils.touch file_name | ||
File.open(file_name, 'w') { |f| f.write contents } | ||
end | ||
|
||
let(:critic) { Tailor::Critic.new } | ||
|
||
let(:style) do | ||
style = Tailor::Configuration::Style.new | ||
style.trailing_newlines 0, level: :off | ||
style.allow_invalid_ruby true, level: :off | ||
style | ||
end | ||
|
||
context :no_parentheses do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :with_parentheses do | ||
it 'warns' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 4, | ||
:message=> 'Parentheses around conditional expression at column 4.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :with_parentheses_no_space do | ||
it 'warns' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 3, | ||
:message=> 'Parentheses around conditional expression at column 3.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :method_call do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :indented_method_call do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :method_call_on_parens do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :double_parens do | ||
it 'warns by default' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 4, | ||
:message=> 'Parentheses around conditional expression at column 4.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :unless_no_parentheses do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :unless_with_parentheses do | ||
it 'warns on parentheses' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 8, | ||
:message=> 'Parentheses around conditional expression at column 8.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :case_no_parentheses do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :case_with_parentheses do | ||
it 'warns on parentheses' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 6, | ||
:message=> 'Parentheses around conditional expression at column 6.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :while_no_parentheses do | ||
it 'does not warn' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
context :while_with_parentheses do | ||
it 'warns on parentheses' do | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to eql [{ | ||
:type => 'conditional_parentheses', | ||
:line => 1, | ||
:column=> 7, | ||
:message=> 'Parentheses around conditional expression at column 7.', | ||
:level=> :error | ||
}] | ||
end | ||
it 'does not warn when parentheses are allowed' do | ||
style.allow_conditional_parentheses true, level: :error | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
it 'does not warn when parentheses are disabled' do | ||
style.allow_conditional_parentheses false, level: :off | ||
critic.check_file(file_name, style.to_hash) | ||
expect(critic.problems[file_name]).to be_empty | ||
end | ||
end | ||
|
||
end |
Oops, something went wrong.