lib/reek/smells.rb in reek-0.2.2 vs lib/reek/smells.rb in reek-0.2.3

- old
+ new

@@ -16,16 +16,13 @@ @context = context end def self.check(exp, context, arg=nil) smell = new(context, arg) - if smell.recognise?(exp) - context.report(smell) - true - else - false - end + return false unless smell.recognise?(exp) + context.report(smell) + true end def recognise?(stuff) @context != nil end @@ -97,51 +94,43 @@ "#{@context} has approx #{@num_stmts} statements" end end class FeatureEnvy < Smell - - # TODO - # Should be moved to Hash; but Hash has 58 methods, and there's currently - # no way to turn off that report; which would therefore make the tests fail - def self.max_keys(calls) - max = calls.values.max or return [:self] - calls.keys.select { |key| calls[key] == max } - end - def initialize(context, *receivers) - super(context) - @receivers = receivers + def recognise?(refs) + @refs = refs + !refs.self_is_max? end - def recognise?(calls) - @receivers = FeatureEnvy.max_keys(calls) - return !(@receivers.include?(:self)) - end - def detailed_report - receiver = @receivers.map {|r| Printer.print(r)}.sort.join(' and ') + receiver = @refs.max_keys.map {|r| Printer.print(r)}.sort.join(' and ') "#{@context} uses #{receiver} more than self" end end class UtilityFunction < Smell - def recognise?(calls) - calls[:self] == 0 + def recognise?(depends_on_self) + !depends_on_self end def detailed_report "#{@context} doesn't depend on instance state" end end class LargeClass < Smell MAX_ALLOWED = 25 + def self.non_inherited_methods(klass) + return klass.instance_methods if klass.superclass.nil? + klass.instance_methods - klass.superclass.instance_methods + end + def recognise?(name) klass = Object.const_get(name) rescue return - @num_methods = klass.instance_methods.length - klass.superclass.instance_methods.length + @num_methods = LargeClass.non_inherited_methods(klass).length @num_methods > MAX_ALLOWED end def detailed_report "#{@context} has #{@num_methods} methods" @@ -152,14 +141,18 @@ def initialize(context, symbol_type) super @symbol_type = symbol_type end + def self.effective_length(name) + return 500 if name == '*' + name = name[1..-1] while /^@/ === name + name.length + end + def recognise?(symbol) @symbol = symbol.to_s - return false if @symbol == '*' - min_len = (/^@/ === @symbol) ? 3 : 2; - @symbol.length < min_len + UncommunicativeName.effective_length(@symbol) < 2 end def detailed_report "#{@context} uses the #{@symbol_type} name '#{@symbol}'" end