Module: Coatepec::Spec::Result
- Defined in:
- lib/coatepec/spec/result.rb
Overview
Turns a finished RSpec child process's exit status, captured stdout/stderr (each capped at MAX_OUTPUT_BYTES), and RSpec's own JSON formatter output into the flat result hash rails_spec_run returns.
Constant Summary collapse
- MAX_OUTPUT_BYTES =
256 * 1024
Class Method Summary collapse
-
.base(pid, status, stdout_result, stderr_result) ⇒ Object
rubocop:disable Metrics/MethodLength -- one flat hash literal mapping Process::Status/captured-output fields to the result payload's own field names; splitting it would scatter that 1:1 mapping across methods for no readability gain.
- .build(pid:, status:, out_r:, err_r:, json_path:) ⇒ Object
- .example_fields(example) ⇒ Object
- .read_bounded(io) ⇒ Object
-
.read_summary(json_path) ⇒ Object
rubocop:enable Metrics/MethodLength.
- .summary_fields(summary) ⇒ Object
Class Method Details
.base(pid, status, stdout_result, stderr_result) ⇒ Object
rubocop:disable Metrics/MethodLength -- one flat hash literal mapping Process::Status/captured-output fields to the result payload's own field names; splitting it would scatter that 1:1 mapping across methods for no readability gain.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/coatepec/spec/result.rb', line 30 def base(pid, status, stdout_result, stderr_result) { status: status.exited? && status.exitstatus.zero? ? "passed" : "failed", exit_code: status.exitstatus, child_pid: pid, signaled: status.signaled?, termsig: status.termsig, stopsig: status.stopsig, coredump: status.respond_to?(:coredump?) ? status.coredump? : false, stdout: stdout_result[:text], stdout_truncated: stdout_result[:truncated], stderr: stderr_result[:text], stderr_truncated: stderr_result[:truncated] } end |
.build(pid:, status:, out_r:, err_r:, json_path:) ⇒ Object
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/coatepec/spec/result.rb', line 15 def build(pid:, status:, out_r:, err_r:, json_path:) stdout_result = read_bounded(out_r) stderr_result = read_bounded(err_r) summary = read_summary(json_path) base(pid, status, stdout_result, stderr_result).merge( summary: summary && summary_fields(summary), examples: (summary&.fetch("examples", []) || []).first(500).map { |e| example_fields(e) } ) end |
.example_fields(example) ⇒ Object
61 62 63 64 65 66 67 68 69 |
# File 'lib/coatepec/spec/result.rb', line 61 def example_fields(example) { id: example["id"], description: example["full_description"], status: example["status"], file_path: example["file_path"], line_number: example["line_number"] } end |
.read_bounded(io) ⇒ Object
71 72 73 74 75 76 |
# File 'lib/coatepec/spec/result.rb', line 71 def read_bounded(io) data = io.read.to_s truncated = data.bytesize > MAX_OUTPUT_BYTES data = data.byteslice(-MAX_OUTPUT_BYTES, MAX_OUTPUT_BYTES) if truncated { text: data, truncated: truncated } end |
.read_summary(json_path) ⇒ Object
rubocop:enable Metrics/MethodLength
47 48 49 50 51 |
# File 'lib/coatepec/spec/result.rb', line 47 def read_summary(json_path) return nil unless File.exist?(json_path) && !File.empty?(json_path) JSON.parse(File.read(json_path)) end |
.summary_fields(summary) ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/coatepec/spec/result.rb', line 53 def summary_fields(summary) { example_count: summary.dig("summary", "example_count"), failure_count: summary.dig("summary", "failure_count"), duration: summary.dig("summary", "duration") } end |