module SimpleCov::CoverageViolations

def compute_drop(criterion, result, last_run)

def compute_drop(criterion, result, last_run)
  stats_key = SimpleCov.coverage_statistics_key(criterion)
  last_coverage_percent = last_run.dig(:result, stats_key)
  last_coverage_percent ||= last_run.dig(:result, :covered_percent) if stats_key == :line
  return unless last_coverage_percent
  current = percent_for(result, criterion) or return
  (last_coverage_percent - current).floor(10)
end

def effective_per_file_thresholds(file, defaults, overrides)

the defaults Hash unchanged when nothing matches.
most-specific or latest-declared override wins per criterion). Returns
the file's project path into the running effective threshold (so the
Walk the overrides in declaration order, merging each one that matches
def effective_per_file_thresholds(file, defaults, overrides)
  return defaults if overrides.empty?
  path = file.project_filename
  overrides.reduce(defaults) do |acc, (pattern, criterion_thresholds)|
    path_matches?(path, pattern) ? acc.merge(criterion_thresholds) : acc
  end
end

def file_minimum_violation(file, criterion, expected)

def file_minimum_violation(file, criterion, expected)
  actual = percent_for(file, criterion) or return
  return unless actual < expected
  {
    criterion: criterion,
    expected: expected,
    actual: actual,
    filename: file.filename,
    project_filename: file.project_filename
  }
end

def group_minimum_violations(group_name, group, minimums)

def group_minimum_violations(group_name, group, minimums)
  minimums.filter_map do |criterion, expected|
    actual = percent_for(group, criterion) or next
    {group_name: group_name, criterion: criterion, expected: expected, actual: actual} if actual < expected
  end
end

def lookup_group(result, group_name)

def lookup_group(result, group_name)
  group = result.groups[group_name]
  unless group
    warn "minimum_coverage_by_group: no group named '#{group_name}' exists. " \
         "Available groups: #{result.groups.keys.join(', ')}"
  end
  group
end

def maximum_drop(result, thresholds, last_run: SimpleCov::LastRun.read)

Returns:
  • (Array) - {:criterion, :maximum, :actual} where `actual`
def maximum_drop(result, thresholds, last_run: SimpleCov::LastRun.read)
  return [] unless last_run
  thresholds.filter_map do |criterion, maximum|
    actual = compute_drop(criterion, result, last_run)
    {criterion: criterion, maximum: maximum, actual: actual} if actual && actual > maximum
  end
end

def maximum_overall(result, thresholds)

Returns:
  • (Array) - {:criterion, :expected, :actual}
def maximum_overall(result, thresholds)
  thresholds.filter_map do |criterion, expected|
    actual = percent_for(result, criterion) or next
    {criterion: criterion, expected: expected, actual: actual} if actual > expected
  end
end

def minimum_by_file(result, defaults, overrides = {})

Returns:
  • (Array) - {:criterion, :expected, :actual, :filename, :project_filename}
def minimum_by_file(result, defaults, overrides = {})
  result.files.flat_map do |file|
    effective = effective_per_file_thresholds(file, defaults, overrides)
    effective.filter_map { |criterion, expected| file_minimum_violation(file, criterion, expected) }
  end
end

def minimum_by_group(result, thresholds)

Returns:
  • (Array) - {:group_name, :criterion, :expected, :actual}
def minimum_by_group(result, thresholds)
  thresholds.flat_map do |group_name, minimums|
    group = lookup_group(result, group_name)
    none = [] # : Array[Hash[Symbol, untyped]]
    group ? group_minimum_violations(group_name, group, minimums) : none
  end
end

def minimum_overall(result, thresholds)

Returns:
  • (Array) - {:criterion, :expected, :actual}
def minimum_overall(result, thresholds)
  thresholds.filter_map do |criterion, expected|
    actual = percent_for(result, criterion) or next
    {criterion: criterion, expected: expected, actual: actual} if actual < expected
  end
end

def path_matches?(project_filename, pattern)

so no dead `else` branch is needed here.
The configuration setter rejects anything other than String/Regexp,
match `project_filename` exactly. Regexps are tested via `match?`.
ending in `/` are treated as directory prefixes; otherwise they must
Per-path matching for `minimum_coverage_by_file` overrides. Strings
def path_matches?(project_filename, pattern)
  return project_filename.match?(pattern) if pattern.is_a?(Regexp)
  return project_filename.start_with?(pattern) if pattern.end_with?("/")
  project_filename == pattern
end

def percent_for(stats_source, criterion)

"forgot to enable the criterion" mistake before we ever get here.
`raise_if_criterion_disabled` check still catches the genuine
module doesn't emit branch data). The config-time
100` under the "strict" profile on JRuby, where the Coverage
actually measured by the runtime (e.g. `minimum_coverage branch:
caller silently skips — when the criterion was configured but not
object (Result, SourceFile, FileList). Returns nil — and the
Look up a criterion's percent on any coverage_statistics-bearing
def percent_for(stats_source, criterion)
  stats = stats_source.coverage_statistics[SimpleCov.coverage_statistics_key(criterion)]
  round(stats.percent) if stats
end

def round(percent)

def round(percent)
  SimpleCov.round_coverage(percent)
end