lib/inch/evaluation/proxy.rb in inch-0.5.0.rc3 vs lib/inch/evaluation/proxy.rb in inch-0.5.0.rc4

- old
+ new

@@ -1,26 +1,151 @@ module Inch # The Evaluation module concerns itself with the evaluation of code objects # with regard to their inline code documentation module Evaluation - module Proxy - def self.for(code_object) - class_for(code_object).new(code_object) + # Base class for evaluations. This class provides the evaluation's + # process structure. + # + # @abstract + class Proxy + # Returns a Proxy object for the given +code_object+ + # + # @param language [String,Symbol] + # @param object [Codebase::Object] + # @return [Evaluation::Proxy] + def self.for(language, object) + class_for(language, object.code_object).new(object) end + extend Forwardable + + MIN_SCORE = 0 + MAX_SCORE = 100 + + # @return [Codebase::Object] + attr_reader :object + + # @return [Array<Evaluation::Role::Base>] + attr_reader :roles + + # @param object [Codebase::Object] + def initialize(object) + @object = object + evaluation_config = Config.for(object.language).evaluation + @criteria = eval_criteria(evaluation_config) + @roles = [] + evaluate + end + + # Evaluates the objects and assigns roles + # @note This is its own method so it can be overridden. + # @return [void] + def evaluate + __evaluate(object, relevant_roles) + end + + # @return [Float] the max score that is assignable to +object+ + def max_score + @__max_score = __max_score + end + + # @return [Float] the min score that is assignable to +object+ + def min_score + @__min_score = __min_score + end + + # @return [Fixnum] the final score for +object+ + def score + @__score ||= __score + end + + # @return [Fixnum] the priority for +object+ + def priority + @__priority ||= __priority + end + + protected + + def add_role(role) + @roles << role + end + + # Evaluates a Criteria object with the object so that it can + # give us scores for docstring, return_type, etc. + # + # @param config [Config::Evaluation] + # @return [Evaluation::Criteria] + def eval_criteria(config) + object_type = self.class.to_s.split('::').last + c = config.criteria_for(object_type) + c.evaluate(object) + c + end + + # Returns a key-value pair of Role classes and potential scores for + # each role (can be nil) + # + # @see #evaluate + # @return [Hash] + def relevant_roles + {} + end + + # Returns a score for a given criterion. + # + # @param criterion_name [String] e.g. 'docstring' or 'return_type' + # @return [Float] + def score_for(criterion_name) + @criteria.send(criterion_name) * MAX_SCORE + end + + # Iterates over the given +role_classes+ and assigns the individual + # roles, if applicable. + # + # @param object [Codebase::Object] + # @param role_classes [Hash] + # @return [void] + def __evaluate(object, role_classes) + role_classes.each do |role_class, score| + next unless role_class.applicable?(object) + add_role role_class.new(object, score) + end + end + + # @return [Float] the max score that is assignable to +object+ + def __max_score + arr = @roles.map(&:max_score).compact + [MAX_SCORE].concat(arr).min + end + + # @return [Float] the max score that is assignable to +object+ + def __min_score + arr = @roles.map(&:min_score).compact + [MIN_SCORE].concat(arr).max + end + + # @return [Float] + def __score + value = @roles.reduce(0) { |sum, r| sum + r.score.to_f }.to_i + if value < min_score + min_score + elsif value > max_score + max_score + else + value + end + end + + # @return [Fixnum] + def __priority + @roles.reduce(0) { |sum, r| sum + r.priority.to_i } + end + private - def self.class_for(code_object) - class_name = code_object.class.to_s.split('::').last - const_get(class_name) + def self.class_for(language, code_object) + class_name = code_object.class.to_s.split("::").last + Config.namespace(language, :Evaluation).const_get(class_name) end end end end - -require 'inch/evaluation/proxy/base' -require 'inch/evaluation/proxy/namespace_object' -require 'inch/evaluation/proxy/class_object' -require 'inch/evaluation/proxy/class_variable_object' -require 'inch/evaluation/proxy/constant_object' -require 'inch/evaluation/proxy/method_object' -require 'inch/evaluation/proxy/module_object'