Class: Browsable::Report

Inherits:
Object
  • Object
show all
Defined in:
lib/browsable/report.rb

Overview

The aggregated result of an audit: every Finding produced by every analyzer, plus a record of any analyzer or source that was skipped.

A Report makes no decisions. It tells the user what their code requires and how that compares against their target; the formatters present it and the exit-code policy lives entirely in the caller’s chosen –fail-on value.

Defined Under Namespace

Classes: Skip, Suggestion

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(findings: [], skips: [], notes: [], policies: [], target: nil, root: nil, config_file: nil, pipeline: nil) ⇒ Report

Returns a new instance of Report.

Parameters:

  • notes (Array<String>) (defaults to: [])

    caveats about the run itself (e.g. a target that could not be inferred) — distinct from per-file findings.

  • policies (Array<PolicyScanner::Policy>) (defaults to: [])

    every allow_browser callsite discovered across the app’s controllers — the policy landscape.

  • pipeline (String, nil) (defaults to: nil)

    the detected asset pipeline (“propshaft”, “sprockets”, “sprockets+propshaft”, or “none”).



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/browsable/report.rb', line 26

def initialize(findings: [], skips: [], notes: [], policies: [],
               target: nil, root: nil, config_file: nil, pipeline: nil)
  @findings = findings
  @skips = skips
  @notes = notes
  @policies = policies
  @target = target
  @root = root
  @config_file = config_file
  @pipeline = pipeline
end

Instance Attribute Details

#config_fileObject (readonly)

Returns the value of attribute config_file.



18
19
20
# File 'lib/browsable/report.rb', line 18

def config_file
  @config_file
end

#findingsObject (readonly)

Returns the value of attribute findings.



18
19
20
# File 'lib/browsable/report.rb', line 18

def findings
  @findings
end

#notesObject (readonly)

Returns the value of attribute notes.



18
19
20
# File 'lib/browsable/report.rb', line 18

def notes
  @notes
end

#pipelineObject (readonly)

Returns the value of attribute pipeline.



18
19
20
# File 'lib/browsable/report.rb', line 18

def pipeline
  @pipeline
end

#policiesObject (readonly)

Returns the value of attribute policies.



18
19
20
# File 'lib/browsable/report.rb', line 18

def policies
  @policies
end

#rootObject (readonly)

Returns the value of attribute root.



18
19
20
# File 'lib/browsable/report.rb', line 18

def root
  @root
end

#skipsObject (readonly)

Returns the value of attribute skips.



18
19
20
# File 'lib/browsable/report.rb', line 18

def skips
  @skips
end

#targetObject (readonly)

Returns the value of attribute target.



18
19
20
# File 'lib/browsable/report.rb', line 18

def target
  @target
end

Instance Method Details

#as_jsonObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/browsable/report.rb', line 77

def as_json
  {
    target: target&.as_json,
    pipeline: pipeline,
    notes: notes,
    summary: {
      errors: errors.size,
      warnings: warnings.size,
      infos: infos.size,
      files: findings_by_file.size
    },
    findings: findings.map(&:as_json),
    skips: skips.map { |skip| { kind: skip.kind.to_s, reason: skip.reason } },
    policies: policies.map { |policy| policy_as_json(policy) },
    suggested_policy: suggestion && { line: suggestion.line, bumps: suggestion.bumps }
  }
end

#empty?Boolean

Returns:

  • (Boolean)


42
# File 'lib/browsable/report.rb', line 42

def empty? = findings.empty?

#errorsObject



38
# File 'lib/browsable/report.rb', line 38

def errors   = findings.select(&:error?)

#exit_code(fail_on:) ⇒ Object

Exit code implementing the –fail-on policy.



54
55
56
57
58
59
60
61
62
63
# File 'lib/browsable/report.rb', line 54

def exit_code(fail_on:)
  case fail_on.to_s
  when "warning"
    errors.any? || warnings.any? ? 1 : 0
  when "error"
    errors.any? ? 1 : 0
  else
    0
  end
end

#findings_by_fileObject

Findings grouped by file path, files sorted, findings sorted by position.



45
46
47
48
49
50
51
# File 'lib/browsable/report.rb', line 45

def findings_by_file
  findings
    .group_by(&:file)
    .sort_by(&:first)
    .to_h
    .transform_values { |group| group.sort_by { |f| [f.line, f.column] } }
end

#infosObject



40
# File 'lib/browsable/report.rb', line 40

def infos    = findings.select(&:info?)

#suggestionObject

An allow_browser line that raises the offending browsers just enough to cover every below-target error, leaving the other browsers untouched.

Returns nil when no error carries comparable version data — CSS/JS findings come from stylelint/eslint, which do not expose exact versions, so a suggestion can only be derived from HTML/ERB findings.



71
72
73
74
75
# File 'lib/browsable/report.rb', line 71

def suggestion
  return @suggestion if defined?(@suggestion)

  @suggestion = build_suggestion
end

#warningsObject



39
# File 'lib/browsable/report.rb', line 39

def warnings = findings.select(&:warning?)