Class: SixthSense::Guardrail::Baseline
- Inherits:
-
Object
- Object
- SixthSense::Guardrail::Baseline
- Defined in:
- lib/sixth_sense/guardrail/baseline.rb
Constant Summary collapse
- DEFAULT_PATH =
".sixth_sense_baseline.json"
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
Instance Method Summary collapse
- #digest_for(test_file) ⇒ Object
-
#initialize(path:, data:) ⇒ Baseline
constructor
A new instance of Baseline.
- #update(reports, level:, force: false) ⇒ Object
- #violations(reports, current_level:, tolerance:) ⇒ Object
- #warnings(reports, current_level:, tolerance:) ⇒ Object
- #write ⇒ Object
Constructor Details
#initialize(path:, data:) ⇒ Baseline
Returns a new instance of Baseline.
28 29 30 31 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 28 def initialize(path:, data:) @path = path @data = data end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
12 13 14 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 12 def data @data end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
12 13 14 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 12 def path @path end |
Class Method Details
.empty_data ⇒ Object
19 20 21 22 23 24 25 26 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 19 def self.empty_data { "version" => 1, "generated_at" => nil, "level" => 0, "files" => {} } end |
.load(path = DEFAULT_PATH) ⇒ Object
14 15 16 17 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 14 def self.load(path = DEFAULT_PATH) data = File.file?(path) ? JSON.parse(File.read(path)) : empty_data new(path: path, data: data) end |
Instance Method Details
#digest_for(test_file) ⇒ Object
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 103 def digest_for(test_file) digest = Digest::SHA256.new ([test_file.path] + test_file.sut_candidates.map(&:path)).uniq.each do |path| next unless File.file?(path) digest.update(path) digest.update(File.binread(path)) end "sha256:#{digest.hexdigest}" end |
#update(reports, level:, force: false) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 86 def update(reports, level:, force: false) return self if !force && data.fetch("level", 0).to_i > level next_data = self.class.empty_data next_data["generated_at"] = Time.now.utc.iso8601 next_data["level"] = level reports.each do |report| existing = data.fetch("files", {})[report.test_file.path] || {} next_data["files"][report.test_file.path] = updated_entry(report, existing, force: force) end @data = next_data end |
#violations(reports, current_level:, tolerance:) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 33 def violations(reports, current_level:, tolerance:) return [] if current_level < data.fetch("level", 0).to_i reports.flat_map do |report| baseline_file = data.fetch("files", {})[report.test_file.path] next [] unless baseline_file next [] if baseline_file["digest"] == digest_for(report.test_file) report.axis_scores.filter_map do |score| next unless score.measured? baseline_value = baseline_file[score.axis.to_s] next unless baseline_value next unless score.value < baseline_value.to_f - tolerance { path: report.test_file.path, axis: score.axis, current: score.value, baseline: baseline_value.to_f, tolerance: tolerance } end end end |
#warnings(reports, current_level:, tolerance:) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 59 def warnings(reports, current_level:, tolerance:) return [] if current_level < data.fetch("level", 0).to_i reports.flat_map do |report| baseline_file = data.fetch("files", {})[report.test_file.path] next [] unless baseline_file next [] unless baseline_file["digest"] == digest_for(report.test_file) report.axis_scores.filter_map do |score| next unless score.measured? baseline_value = baseline_file[score.axis.to_s] next unless baseline_value next unless (score.value - baseline_value.to_f).abs > tolerance { type: :flaky_measurement, path: report.test_file.path, axis: score.axis, current: score.value, baseline: baseline_value.to_f, tolerance: tolerance } end end end |
#write ⇒ Object
99 100 101 |
# File 'lib/sixth_sense/guardrail/baseline.rb', line 99 def write File.write(path, JSON.pretty_generate(data) + "\n") end |