From 8d8a34aa5b319b2c6dc7df9aeddf541a29a9145a Mon Sep 17 00:00:00 2001 From: Andrey Ognevsky Date: Thu, 9 Aug 2012 10:01:17 +0300 Subject: [PATCH] Introduce LongIdentifiers lint --- lib/pelusa/lint.rb | 2 + lib/pelusa/lint/long_identifiers.rb | 58 +++++++++++++++++++++++ test/pelusa/lint/long_identifiers_test.rb | 41 ++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 lib/pelusa/lint/long_identifiers.rb create mode 100644 test/pelusa/lint/long_identifiers_test.rb diff --git a/lib/pelusa/lint.rb b/lib/pelusa/lint.rb index 8710d8f..5cf40e8 100644 --- a/lib/pelusa/lint.rb +++ b/lib/pelusa/lint.rb @@ -7,6 +7,7 @@ require 'pelusa/lint/properties' require 'pelusa/lint/collection_wrappers' require 'pelusa/lint/short_identifiers' +require 'pelusa/lint/long_identifiers' require 'pelusa/lint/case_statements' require 'pelusa/lint/many_arguments' require 'pelusa/lint/eval_usage' @@ -26,6 +27,7 @@ def self.all Properties, CollectionWrappers, ShortIdentifiers, + LongIdentifiers, ManyArguments, EvalUsage ] diff --git a/lib/pelusa/lint/long_identifiers.rb b/lib/pelusa/lint/long_identifiers.rb new file mode 100644 index 0000000..9bc4be6 --- /dev/null +++ b/lib/pelusa/lint/long_identifiers.rb @@ -0,0 +1,58 @@ +module Pelusa + module Lint + class LongIdentifiers + def initialize + @violations = Set.new + end + + def check(klass) + initialize + iterate_lines!(klass) + + return SuccessfulAnalysis.new(name) if @violations.empty? + + FailedAnalysis.new(name, formatted_violations) do |violations| + "These names are too long: #{violations.join(', ')}" + end + end + + private + + def name + "Uses names of adequate length (less than #{limit})" + end + + def limit + Pelusa.configuration['LongIdentifiers'].fetch('limit', 20) + end + + def iterate_lines!(klass) + iterator = Iterator.new do |node| + if node.respond_to?(:name) + name = node.name.respond_to?(:name) ? node.name.name.to_s : node.name.to_s + if name =~ /[a-z]/ && name.length > limit + next if name =~ /^[A-Z]/ # Ignore constants + @violations << [name, node.line] + end + end + end + Array(klass).each(&iterator) + end + + def formatted_violations + grouped_violations = @violations.inject({}) do |hash, (name, line)| + hash[name] ||= [] + hash[name] << line + hash + end + + violations = [] + + grouped_violations.each_pair do |name, lines| + violations << "#{name} (line #{lines.join(', ')})" + end + violations + end + end + end +end diff --git a/test/pelusa/lint/long_identifiers_test.rb b/test/pelusa/lint/long_identifiers_test.rb new file mode 100644 index 0000000..6dae4b9 --- /dev/null +++ b/test/pelusa/lint/long_identifiers_test.rb @@ -0,0 +1,41 @@ +require 'test_helper' + +module Pelusa + module Lint + describe LongIdentifiers do + before do + @lint = LongIdentifiers.new + end + + describe '#check' do + describe 'when the class contains no long identifiers' do + it 'returns a SuccessAnalysis' do + klass = """ + class Foo + def initialize + not_long_identifier = nil + end + end""".to_ast + + analysis = @lint.check(klass) + analysis.successful?.must_equal true + end + end + + describe 'when the class contains a long identifier' do + it 'returns a FailureAnalysis' do + klass = """ + class Foo + def initialize + it_is_long_identifier = nil + end + end""".to_ast + + analysis = @lint.check(klass) + analysis.failed?.must_equal true + end + end + end + end + end +end