class Gry::Congress

Public Class Methods

new(max_count:, min_difference:, metrics_percentile:) click to toggle source
# File lib/gry/congress.rb, line 3
def initialize(max_count:, min_difference:, metrics_percentile:)
  @max_count = max_count
  @min_difference = min_difference
  @metrics_percentile = metrics_percentile
end

Public Instance Methods

discuss(name, bill) click to toggle source

@param name [String] cop name @param bill [Hash{Hash => Array}] rubocop results

{
  {config1} => [offenses],
  {config2} => [offenses],
  {config3} => [offenses],
}

@return [Law]

# File lib/gry/congress.rb, line 17
def discuss(name, bill)
  letter = letter(name, bill)
  Law.new(name, bill, letter)
end

Private Instance Methods

letter(name, bill) click to toggle source
# File lib/gry/congress.rb, line 25
def letter(name, bill)
  if RubocopAdapter.metrics_cop?(name)
    letter_for_metrics(name, bill)
  else
    letter_for_enforced_style(bill)
  end
end
letter_for_enforced_style(bill) click to toggle source
# File lib/gry/congress.rb, line 55
def letter_for_enforced_style(bill)
  # [[conf, offenses], ...]
  sorted = bill.sort_by{|_conf, offenses| offenses.size}
  min_count = sorted[0].last.size
  return nil if min_count > @max_count

  second_count = sorted[1].last.size
  return nil if second_count - min_count < @min_difference

  sorted.first.first
end
letter_for_metrics(name, bill) click to toggle source
# File lib/gry/congress.rb, line 33
def letter_for_metrics(name, bill)
  raise "bill.size is not 1, got #{bill.size}" unless bill.size == 1
  values = bill
    .values[0]
    .map{|offense| offense['message']}
    .map{|message| message[%r!\[([0-9.]+)/[0-9.]+\]$!, 1]}
    .map(&:to_i)
    .sort

  max = percentile(values)
  if name == 'Metrics/AbcSize'
    max = max.round(2)
  else
    max = max.round
  end

  {
    'Enabled' => true,
    'Max' => max,
  }
end
percentile(values) click to toggle source

@param values [Array<Numeric>] @return [Numeric]

# File lib/gry/congress.rb, line 69
def percentile(values)
  size = values.size
  index = size.to_f / 100 * @metrics_percentile - 1
  v1 = values[index.floor]
  v2 = values[index.ceil]

  v1 + (index - index.ceil) * (v2 - v1)
end