diff --git a/lib/pelusa/lint.rb b/lib/pelusa/lint.rb index a0de254..a68b30a 100644 --- a/lib/pelusa/lint.rb +++ b/lib/pelusa/lint.rb @@ -8,6 +8,7 @@ require 'pelusa/lint/collection_wrappers' require 'pelusa/lint/short_identifiers' require 'pelusa/lint/case_statements' +require 'pelusa/lint/many_arguments' module Pelusa # Public: A Lint is a quality standard, applicable on a given piece of code to @@ -24,6 +25,7 @@ def self.all Properties, CollectionWrappers, ShortIdentifiers, + ManyArguments ] end end diff --git a/lib/pelusa/lint/many_arguments.rb b/lib/pelusa/lint/many_arguments.rb new file mode 100644 index 0000000..7405e4c --- /dev/null +++ b/lib/pelusa/lint/many_arguments.rb @@ -0,0 +1,42 @@ +module Pelusa + module Lint + class ManyArguments + 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| + "Methods with more than #{limit} arguments: #{violations.join(', ')}" + end + end + + private + + def name + "Methods have short argument lists" + end + + def limit + Pelusa.configuration['ManyArguments'].fetch('limit', 3) + end + + def iterate_lines!(klass) + iterator = Iterator.new do |node| + if node.is_a?(Rubinius::AST::Define) && node.arguments.total_args > limit + @violations << node.name + end + end + Array(klass).each(&iterator) + end + + def formatted_violations + @violations.to_a + end + end + end +end diff --git a/test/pelusa/lint/many_arguments_test.rb b/test/pelusa/lint/many_arguments_test.rb new file mode 100644 index 0000000..5f81fb2 --- /dev/null +++ b/test/pelusa/lint/many_arguments_test.rb @@ -0,0 +1,47 @@ +require 'test_helper' + +module Pelusa + module Lint + describe ManyArguments do + before do + @lint = ManyArguments.new + end + + describe '#check' do + describe 'when the class contains only method definitions with a small number of arguments' do + it 'returns a SuccessAnalysis' do + klass = """ + class Foo + def bar(dog) + return dog + end + def baz(dog, cat) + return dog + cat + end + def bam(dog, cat, fish) + return dog + cat + fish + end + end""".to_ast + + analysis = @lint.check(klass) + analysis.successful?.must_equal true + end + end + + describe 'when the class contains a method definition with many arguments' do + it 'returns a FailureAnalysis' do + klass = """ + class Foo + def bar(dog, cat, fish, lobster) + x = 2 + end + end""".to_ast + + analysis = @lint.check(klass) + analysis.failed?.must_equal true + end + end + end + end + end +end