Class: Ibex::Coverage::Report
- Inherits:
-
Object
- Object
- Ibex::Coverage::Report
- Defined in:
- lib/ibex/coverage/report.rb
Overview
Versioned, mergeable runtime coverage result.
Constant Summary collapse
- IDENTIFIER =
: String
"runtime-coverage"- SCHEMA_VERSION =
: Integer
1- MAX_DOCUMENT_BYTES =
: Integer
16_777_216- MAX_TOTAL =
: Integer
1_000_000- MAX_COUNT =
: Integer
9_223_372_036_854_775_807- ROOT_KEYS =
%w[events grammar_digest ibex_coverage production_hits schema_version sessions state_hits table_format_version totals].freeze
- TOTAL_KEYS =
: Array
%w[productions states].freeze
- HIT_KEYS =
: Array
%w[count id].freeze
Instance Attribute Summary collapse
-
#event_count ⇒ Object
readonly
: Integer.
-
#grammar_digest ⇒ Object
readonly
: Array.
-
#production_count ⇒ Object
readonly
: Integer.
-
#production_hits ⇒ Object
readonly
: Hash[Integer, Integer].
-
#sessions ⇒ Object
readonly
: Integer.
-
#state_count ⇒ Object
readonly
: Integer.
-
#state_hits ⇒ Object
readonly
: Hash[Integer, Integer].
-
#table_format_version ⇒ Object
readonly
: Integer.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(grammar_digest:, table_format_version:, state_count:, production_count:, sessions:, event_count:, state_hits:, production_hits:) ⇒ Report
constructor
rubocop:disable Layout/LineLength.
- #to_h ⇒ Object
- #to_json ⇒ Object
Constructor Details
#initialize(grammar_digest:, table_format_version:, state_count:, production_count:, sessions:, event_count:, state_hits:, production_hits:) ⇒ Report
rubocop:disable Layout/LineLength
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ibex/coverage/report.rb', line 32 def initialize(grammar_digest:, table_format_version:, state_count:, production_count:, sessions:, event_count:, state_hits:, production_hits:) @grammar_digest = validate_digest(grammar_digest) @table_format_version = positive_integer(table_format_version, "table_format_version") @state_count = total_integer(state_count, "state total", minimum: 1) @production_count = total_integer(production_count, "production total", minimum: 0) @sessions = positive_integer(sessions, "sessions") @event_count = positive_integer(event_count, "events") raise ArgumentError, "events must be at least sessions" if @event_count < @sessions @state_hits = validate_hits(state_hits, @state_count, "state").freeze @production_hits = validate_hits(production_hits, @production_count, "production").freeze validate_event_bounds freeze end |
Instance Attribute Details
#event_count ⇒ Object (readonly)
: Integer
26 27 28 |
# File 'lib/ibex/coverage/report.rb', line 26 def event_count @event_count end |
#grammar_digest ⇒ Object (readonly)
: Array
21 22 23 |
# File 'lib/ibex/coverage/report.rb', line 21 def grammar_digest @grammar_digest end |
#production_count ⇒ Object (readonly)
: Integer
24 25 26 |
# File 'lib/ibex/coverage/report.rb', line 24 def production_count @production_count end |
#production_hits ⇒ Object (readonly)
: Hash[Integer, Integer]
28 29 30 |
# File 'lib/ibex/coverage/report.rb', line 28 def production_hits @production_hits end |
#sessions ⇒ Object (readonly)
: Integer
25 26 27 |
# File 'lib/ibex/coverage/report.rb', line 25 def sessions @sessions end |
#state_count ⇒ Object (readonly)
: Integer
23 24 25 |
# File 'lib/ibex/coverage/report.rb', line 23 def state_count @state_count end |
#state_hits ⇒ Object (readonly)
: Hash[Integer, Integer]
27 28 29 |
# File 'lib/ibex/coverage/report.rb', line 27 def state_hits @state_hits end |
#table_format_version ⇒ Object (readonly)
: Integer
22 23 24 |
# File 'lib/ibex/coverage/report.rb', line 22 def table_format_version @table_format_version end |
Class Method Details
.from_h(value, source:) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/ibex/coverage/report.rb', line 91 def self.from_h(value, source:) document = string_hash(value, source, "coverage document") invalid(source, "coverage object has unknown or missing fields") unless document.keys.sort == ROOT_KEYS valid_schema = document["ibex_coverage"] == IDENTIFIER && document["schema_version"] == SCHEMA_VERSION invalid(source, "unsupported coverage schema") unless valid_schema totals = string_hash(document["totals"], source, "coverage totals") invalid(source, "coverage totals have unknown or missing fields") unless totals.keys.sort == TOTAL_KEYS state_count = totals["states"] production_count = totals["productions"] new( grammar_digest: document["grammar_digest"], table_format_version: document["table_format_version"], state_count: state_count, production_count: production_count, sessions: document["sessions"], event_count: document["events"], state_hits: parse_hits(document["state_hits"], state_count, source, "state"), production_hits: parse_hits(document["production_hits"], production_count, source, "production") ) rescue ArgumentError => e raise Ibex::Error, "#{source}:1:1: #{e.}" end |
.load_file(path) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/ibex/coverage/report.rb', line 70 def self.load_file(path) size = File.size(path) if size > MAX_DOCUMENT_BYTES raise Ibex::Error, "#{path}:1:1: coverage document exceeds #{MAX_DOCUMENT_BYTES} bytes" end source = File.binread(path) if source.bytesize > MAX_DOCUMENT_BYTES raise Ibex::Error, "#{path}:1:1: coverage document exceeds #{MAX_DOCUMENT_BYTES} bytes" end source.force_encoding(Encoding::UTF_8) raise Ibex::Error, "#{path}:1:1: coverage document is not valid UTF-8" unless source.valid_encoding? value = JSON.parse(source, max_nesting: 16, allow_nan: false) from_h(value, source: path) rescue JSON::ParserError => e raise Ibex::Error, "#{path}:1:1: invalid coverage JSON: #{e.}" end |
.merge(reports) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/ibex/coverage/report.rb', line 117 def self.merge(reports) raise ArgumentError, "at least one coverage report is required" if reports.empty? first = reports.first reports.drop(1).each { |report| ensure_compatible(first, report) } new( grammar_digest: first.grammar_digest, table_format_version: first.table_format_version, state_count: first.state_count, production_count: first.production_count, sessions: checked_sum(reports.map(&:sessions), "sessions"), event_count: checked_sum(reports.map(&:event_count), "events"), state_hits: merge_hits(reports.map(&:state_hits), "state"), production_hits: merge_hits(reports.map(&:production_hits), "production") ) end |
Instance Method Details
#to_h ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/ibex/coverage/report.rb', line 50 def to_h { "ibex_coverage" => IDENTIFIER, "schema_version" => SCHEMA_VERSION, "grammar_digest" => @grammar_digest, "table_format_version" => @table_format_version, "totals" => { "states" => @state_count, "productions" => @production_count }, "sessions" => @sessions, "events" => @event_count, "state_hits" => hit_documents(@state_hits), "production_hits" => hit_documents(@production_hits) } end |
#to_json ⇒ Object
65 66 67 |
# File 'lib/ibex/coverage/report.rb', line 65 def to_json(*) "#{JSON.pretty_generate(to_h)}\n" end |