module SandiMeter class Calculator def initialize @data = {classes: [], methods: {}, method_calls: []} @output = {} end def push(data) data.each_pair do |key, value| if value.kind_of?(Array) @data[key] ||= [] @data[key] += value elsif value.kind_of?(Hash) @data[key] ||= {} @data[key].merge!(value) end end end def calculate!(store_details = false) @store_details = store_details check_first_rule check_second_rule check_third_rule check_fourth_rule @output end private def log_first_rule @output[:first_rule][:log] ||= {} @output[:first_rule][:log][:classes] = @data[:classes].inject([]) do |log, klass| log << [klass.name, klass.size, klass.path] if klass.last_line && !klass.small? log end @output[:first_rule][:log][:misindented_classes] = @data[:classes].select { |c| c.last_line.nil? }.inject([]) do |log, klass| log << [klass.name, nil, klass.path] log end end def log_second_rule @output[:second_rule][:log] ||= {} @output[:second_rule][:log][:methods] ||= [] @output[:second_rule][:log][:misindented_methods] ||= [] @data[:methods].each_pair do |klass, methods| methods.select { |m| !m.misindented? && !m.small? }.each do |method| @output[:second_rule][:log][:methods] << [klass, method.name, method.size, method.path] end end @data[:methods].each_pair do |klass, methods| methods.each do |method| next unless method.misindented? @output[:second_rule][:log][:misindented_methods] << [klass, method.name, method.size, method.path] end end end def log_third_rule @output[:third_rule][:log] ||={} @output[:third_rule][:log][:method_calls] ||= [] # TODO # add name of method being called proper_method_calls = @data[:method_calls].inject(0) do |sum, method_call| @output[:third_rule][:log][:method_calls] << [method_call.number_of_arguments, method_call.path] if method_call.number_of_arguments > 4 end end def log_fourth_rule @output[:fourth_rule][:log] ||={} @output[:fourth_rule][:log][:controllers] ||= [] controllers.each do |controller| methods_for(controller).select { |m| m.ivars.length > 1 }.each do |method| @output[:fourth_rule][:log][:controllers] << [controller.name, method.name, method.ivars.uniq] end end end def controllers @data[:classes].select { |c| c.controller? } end def methods_for(controller) @data[:methods].fetch(controller.name) { [] } end def check_first_rule total_classes_amount = @data[:classes].size small_classes_amount = @data[:classes].select(&:small?).size misindented_classes_amount = @data[:classes].select { |c| c.last_line.nil? }.size @output[:first_rule] ||= {} @output[:first_rule][:small_classes_amount] = small_classes_amount @output[:first_rule][:total_classes_amount] = total_classes_amount @output[:first_rule][:misindented_classes_amount] = misindented_classes_amount log_first_rule if @store_details end def check_second_rule total_methods_amount = 0 small_methods_amount = 0 @data[:methods].each_pair do |klass, methods| small_methods_amount += methods.select { |m| m.small? }.size total_methods_amount += methods.size end misindented_methods_amount = 0 @data[:methods].each_pair do |klass, methods| misindented_methods_amount += methods.select { |m| m.last_line.nil? }.size end @output[:second_rule] ||= {} @output[:second_rule][:small_methods_amount] = small_methods_amount @output[:second_rule][:total_methods_amount] = total_methods_amount @output[:second_rule][:misindented_methods_amount] = misindented_methods_amount log_second_rule if @store_details end # TODO # count method definitions argumets too def check_third_rule total_method_calls = @data[:method_calls].size proper_method_calls = @data[:method_calls].inject(0) do |sum, method_call| sum += 1 unless method_call.number_of_arguments > 4 sum end @output[:third_rule] ||= {} @output[:third_rule][:proper_method_calls] = proper_method_calls @output[:third_rule][:total_method_calls] = total_method_calls log_third_rule if @store_details end def check_fourth_rule proper_controllers_amount = 0 total_controllers_amount = 0 @data[:classes].select { |c| c.controller? }.each do |klass| total_controllers_amount += 1 proper_controllers_amount += 1 unless @data[:methods][klass.name] && @data[:methods][klass.name].select { |m| m.ivars.uniq.size > 1 }.any? end @output[:fourth_rule] ||= {} @output[:fourth_rule][:proper_controllers_amount] = proper_controllers_amount @output[:fourth_rule][:total_controllers_amount] = total_controllers_amount log_fourth_rule if @store_details end end end