class InspecRspecJson
def add_profile(profile)
def add_profile(profile) @profiles.push(profile) end
def dump_one_example(example, control)
def dump_one_example(example, control) control[:results] ||= [] example.delete(:id) example.delete(:profile_id) control[:results].push(example) end
def dump_summary(summary)
def dump_summary(summary) super(summary) total = 0 failed = 0 skipped = 0 passed = 0 @profiles_info.each do |_name, profile| total += profile[:controls].length profile[:controls].each do |_control_name, control| next unless control[:results] if control[:results].any? { |r| r[:status] == 'failed' } failed += 1 elsif control[:results].any? { |r| r[:status] == 'skipped' } skipped += 1 else passed += 1 end end end # TODO: provide this information in the output end
def example2control(example, profiles)
def example2control(example, profiles) p = example2profile(example, profiles) p[:controls][example[:id]] if p && p[:controls] end
def example2profile(example, profiles)
this heuristic matching.
by registrying all dependent profiles with the formatter. The we could remove
the profile_id of the top level profile when it is included as a dependency, or
TODO(ssd+vj): We should probably solve this by either ensuring the example has
def example2profile(example, profiles) profiles.values.find { |p| profile_contains_example?(p, example) } end
def format_example(example)
def format_example(example) super(example).tap do |res| res[:run_time] = example.execution_result.run_time res[:start_time] = example.execution_result.started_at.to_s end end
def initialize(*args)
def initialize(*args) super(*args) @profiles = [] # Will be valid after "start" state is reached. @profiles_info = nil @backend = nil end
def profile_contains_example?(profile, example)
def profile_contains_example?(profile, example) # Heuristic for finding the profile an example came from: # Case 1: The profile_id on the example matches the name of the profile # Case 2: The profile contains a control that matches the id of the example if profile[:name] == example[:profile_id] true elsif profile[:controls] && profile[:controls].key?(example[:id]) true else false end end
def profile_info(profile)
def profile_info(profile) info = profile.info.dup [info[:name], info] end
def start(_notification)
Called after all examples have been collected but before rspec
def start(_notification) # Note that the default profile may have no name - therefore # the hash may have a valid nil => entry. @profiles_info ||= Hash[@profiles.map { |x| profile_info(x) }] end
def stop(notification)
def stop(notification) super(notification) examples = @output_hash.delete(:controls) missing = [] examples.each do |example| control = example2control(example, @profiles_info) next missing.push(example) if control.nil? dump_one_example(example, control) end @output_hash[:profiles] = @profiles_info @output_hash[:other_checks] = missing end