2019-06-21 09:33:41 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-06-21 08:59:01 +08:00
|
|
|
module TurboTests
|
|
|
|
# An RSpec formatter used for each subprocess during parallel test execution
|
|
|
|
class JsonRowsFormatter
|
|
|
|
RSpec::Core::Formatters.register(
|
|
|
|
self,
|
|
|
|
:close,
|
|
|
|
:example_failed,
|
|
|
|
:example_passed,
|
|
|
|
:example_pending,
|
2020-06-23 13:34:58 +08:00
|
|
|
:message,
|
2019-06-21 08:59:01 +08:00
|
|
|
:seed,
|
|
|
|
)
|
|
|
|
|
|
|
|
attr_reader :output
|
|
|
|
|
|
|
|
def initialize(output)
|
|
|
|
@output = output
|
|
|
|
end
|
|
|
|
|
|
|
|
def exception_to_json(exception)
|
|
|
|
if exception
|
|
|
|
{
|
2019-06-27 18:43:12 +08:00
|
|
|
class_name: exception.class.name.to_s,
|
2019-06-21 08:59:01 +08:00
|
|
|
backtrace: exception.backtrace,
|
|
|
|
message: exception.message,
|
2019-06-27 18:37:23 +08:00
|
|
|
cause: exception_to_json(exception.cause),
|
2019-06-21 08:59:01 +08:00
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def execution_result_to_json(result)
|
|
|
|
{
|
|
|
|
example_skipped?: result.example_skipped?,
|
|
|
|
pending_message: result.pending_message,
|
|
|
|
status: result.status,
|
|
|
|
pending_fixed?: result.pending_fixed?,
|
2021-12-08 03:07:45 +08:00
|
|
|
exception: exception_to_json(result.exception),
|
|
|
|
pending_exception: exception_to_json(result.pending_exception),
|
2019-06-21 08:59:01 +08:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-08-29 19:40:06 +08:00
|
|
|
def stack_frame_to_json(frame)
|
|
|
|
{ shared_group_name: frame.shared_group_name, inclusion_location: frame.inclusion_location }
|
|
|
|
end
|
|
|
|
|
2019-06-21 08:59:01 +08:00
|
|
|
def example_to_json(example)
|
|
|
|
{
|
|
|
|
execution_result: execution_result_to_json(example.execution_result),
|
|
|
|
location: example.location,
|
|
|
|
full_description: example.full_description,
|
|
|
|
metadata: {
|
|
|
|
shared_group_inclusion_backtrace:
|
2019-08-29 19:40:06 +08:00
|
|
|
example.metadata[:shared_group_inclusion_backtrace].map(&method(:stack_frame_to_json)),
|
2022-12-28 18:47:57 +08:00
|
|
|
extra_failure_lines: example.metadata[:extra_failure_lines],
|
2023-05-30 09:52:46 +08:00
|
|
|
run_duration_ms: example.metadata[:run_duration_ms],
|
2023-07-05 11:47:35 +08:00
|
|
|
process_pid: Process.pid,
|
2019-06-21 08:59:01 +08:00
|
|
|
},
|
|
|
|
location_rerun_argument: example.location_rerun_argument,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def example_passed(notification)
|
|
|
|
output_row(type: :example_passed, example: example_to_json(notification.example))
|
|
|
|
end
|
|
|
|
|
|
|
|
def example_pending(notification)
|
|
|
|
output_row(type: :example_pending, example: example_to_json(notification.example))
|
|
|
|
end
|
|
|
|
|
|
|
|
def example_failed(notification)
|
|
|
|
output_row(type: :example_failed, example: example_to_json(notification.example))
|
|
|
|
end
|
|
|
|
|
|
|
|
def seed(notification)
|
|
|
|
output_row(type: :seed, seed: notification.seed)
|
|
|
|
end
|
|
|
|
|
|
|
|
def close(notification)
|
|
|
|
output_row(type: :close)
|
|
|
|
end
|
|
|
|
|
2020-06-23 13:34:58 +08:00
|
|
|
def message(notification)
|
|
|
|
output_row(type: :message, message: notification.message)
|
|
|
|
end
|
|
|
|
|
2019-06-21 08:59:01 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
def output_row(obj)
|
|
|
|
output.puts(obj.to_json)
|
|
|
|
output.flush
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|