class Cucumber::Formatter::Json

The formatter used for --format json

Public Class Methods

new(config) click to toggle source
# File lib/cucumber/formatter/json.rb, line 14
def initialize(config)
  @io = ensure_io(config.out_stream)
  @feature_hashes = []
  @step_or_hook_hash = {}
  config.on_event :test_case_started, &method(:on_test_case_started)
  config.on_event :test_case_finished, &method(:on_test_case_finished)
  config.on_event :test_step_started, &method(:on_test_step_started)
  config.on_event :test_step_finished, &method(:on_test_step_finished)
  config.on_event :test_run_finished, &method(:on_test_run_finished)
end

Public Instance Methods

embed(src, mime_type, _label) click to toggle source
# File lib/cucumber/formatter/json.rb, line 83
def embed(src, mime_type, _label)
  if File.file?(src)
    content = File.open(src, 'rb', &:read)
    data = encode64(content)
  else
    if mime_type =~ /;base64$/
      mime_type = mime_type[0..-8]
      data = src
    else
      data = encode64(src)
    end
  end
  test_step_embeddings << { mime_type: mime_type, data: data }
end
on_test_case_finished(event) click to toggle source
# File lib/cucumber/formatter/json.rb, line 69
def on_test_case_finished(event)
  _test_case, result = *event.attributes
  result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
  add_failed_around_hook(result) if result.failed? && !@any_step_failed
end
on_test_case_started(event) click to toggle source
# File lib/cucumber/formatter/json.rb, line 25
def on_test_case_started(event)
  test_case = event.test_case
  builder = Builder.new(test_case)
  unless same_feature_as_previous_test_case?(test_case.feature)
    @feature_hash = builder.feature_hash
    @feature_hashes << @feature_hash
  end
  @test_case_hash = builder.test_case_hash
  if builder.background?
    feature_elements << builder.background_hash
    @element_hash = builder.background_hash
  else
    feature_elements << @test_case_hash
    @element_hash = @test_case_hash
  end
  @any_step_failed = false
end
on_test_run_finished(_event) click to toggle source
# File lib/cucumber/formatter/json.rb, line 75
def on_test_run_finished(_event)
  @io.write(MultiJson.dump(@feature_hashes, pretty: true))
end
on_test_step_finished(event) click to toggle source
# File lib/cucumber/formatter/json.rb, line 61
def on_test_step_finished(event)
  test_step, result = *event.attributes
  result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
  return if internal_hook?(test_step)
  add_match_and_result(test_step, result)
  @any_step_failed = true if result.failed?
end
on_test_step_started(event) click to toggle source
# File lib/cucumber/formatter/json.rb, line 43
def on_test_step_started(event)
  test_step = event.test_step
  return if internal_hook?(test_step)
  hook_query = HookQueryVisitor.new(test_step)
  if hook_query.hook?
    @step_or_hook_hash = {}
    hooks_of_type(hook_query) << @step_or_hook_hash
    return
  end
  if first_step_after_background?(test_step)
    feature_elements << @test_case_hash
    @element_hash = @test_case_hash
  end
  @step_or_hook_hash = create_step_hash(test_step.source.last)
  steps << @step_or_hook_hash
  @step_hash = @step_or_hook_hash
end
puts(message) click to toggle source
# File lib/cucumber/formatter/json.rb, line 79
def puts(message)
  test_step_output << message
end

Private Instance Methods

add_failed_around_hook(result) click to toggle source
# File lib/cucumber/formatter/json.rb, line 193
def add_failed_around_hook(result)
  @step_or_hook_hash = {}
  around_hooks << @step_or_hook_hash
  @step_or_hook_hash[:match] = { location: 'unknown_hook_location:1' }

  @step_or_hook_hash[:result] = create_result_hash(result)
end
add_match_and_result(test_step, result) click to toggle source
# File lib/cucumber/formatter/json.rb, line 188
def add_match_and_result(test_step, result)
  @step_or_hook_hash[:match] = create_match_hash(test_step, result)
  @step_or_hook_hash[:result] = create_result_hash(result)
end
after_hooks() click to toggle source
# File lib/cucumber/formatter/json.rb, line 141
def after_hooks
  @element_hash[:after] ||= []
end
after_step_hooks() click to toggle source
# File lib/cucumber/formatter/json.rb, line 149
def after_step_hooks
  @step_hash[:after] ||= []
end
around_hooks() click to toggle source
# File lib/cucumber/formatter/json.rb, line 145
def around_hooks
  @element_hash[:around] ||= []
end
before_hooks() click to toggle source
# File lib/cucumber/formatter/json.rb, line 137
def before_hooks
  @element_hash[:before] ||= []
end
create_data_table_value(data_table) click to toggle source
# File lib/cucumber/formatter/json.rb, line 182
def create_data_table_value(data_table)
  data_table.raw.map do |row|
    { cells: row }
  end
end
create_doc_string_hash(doc_string) click to toggle source
# File lib/cucumber/formatter/json.rb, line 173
def create_doc_string_hash(doc_string)
  content_type = doc_string.content_type ? doc_string.content_type : ''
  {
    value: doc_string.content,
    content_type: content_type,
    line: doc_string.location.line
  }
end
create_error_message(result) click to toggle source
# File lib/cucumber/formatter/json.rb, line 214
def create_error_message(result)
  message_element = result.failed? ? result.exception : result
  message = "#{message_element.message} (#{message_element.class})"
  ([message] + message_element.backtrace).join("\n")
end
create_match_hash(test_step, _result) click to toggle source
# File lib/cucumber/formatter/json.rb, line 201
def create_match_hash(test_step, _result)
  { location: test_step.action_location.to_s }
end
create_result_hash(result) click to toggle source
# File lib/cucumber/formatter/json.rb, line 205
def create_result_hash(result)
  result_hash = {
    status: result.to_sym
  }
  result_hash[:error_message] = create_error_message(result) if result.failed? || result.pending?
  result.duration.tap { |duration| result_hash[:duration] = duration.nanoseconds }
  result_hash
end
create_step_hash(step_source) click to toggle source
# File lib/cucumber/formatter/json.rb, line 161
def create_step_hash(step_source)
  step_hash = {
    keyword: step_source.keyword,
    name: step_source.to_s,
    line: step_source.original_location.line
  }
  step_hash[:comments] = Formatter.create_comments_array(step_source.comments) unless step_source.comments.empty?
  step_hash[:doc_string] = create_doc_string_hash(step_source.multiline_arg) if step_source.multiline_arg.doc_string?
  step_hash[:rows] = create_data_table_value(step_source.multiline_arg) if step_source.multiline_arg.data_table?
  step_hash
end
current_feature() click to toggle source
# File lib/cucumber/formatter/json.rb, line 112
def current_feature
  @feature_hash ||= {}
end
encode64(data) click to toggle source
# File lib/cucumber/formatter/json.rb, line 220
def encode64(data)
  # strip newlines from the encoded data
  Base64.encode64(data).delete("\n")
end
feature_elements() click to toggle source
# File lib/cucumber/formatter/json.rb, line 116
def feature_elements
  @feature_hash[:elements] ||= []
end
first_step_after_background?(test_step) click to toggle source
# File lib/cucumber/formatter/json.rb, line 104
def first_step_after_background?(test_step)
  test_step.source[1].to_s != @element_hash[:name]
end
hooks_of_type(hook_query) click to toggle source
# File lib/cucumber/formatter/json.rb, line 124
def hooks_of_type(hook_query)
  case hook_query.type
  when :before
    return before_hooks
  when :after
    return after_hooks
  when :after_step
    return after_step_hooks
  else
    fail 'Unknown hook type ' + hook_query.type.to_s
  end
end
internal_hook?(test_step) click to toggle source
# File lib/cucumber/formatter/json.rb, line 108
def internal_hook?(test_step)
  test_step.source.last.location.file.include?('lib/cucumber/')
end
same_feature_as_previous_test_case?(feature) click to toggle source
# File lib/cucumber/formatter/json.rb, line 100
def same_feature_as_previous_test_case?(feature)
  current_feature[:uri] == feature.file && current_feature[:line] == feature.location.line
end
steps() click to toggle source
# File lib/cucumber/formatter/json.rb, line 120
def steps
  @element_hash[:steps] ||= []
end
test_step_embeddings() click to toggle source
# File lib/cucumber/formatter/json.rb, line 157
def test_step_embeddings
  @step_or_hook_hash[:embeddings] ||= []
end
test_step_output() click to toggle source
# File lib/cucumber/formatter/json.rb, line 153
def test_step_output
  @step_or_hook_hash[:output] ||= []
end