Class: Specbandit::RspecAdapter

Inherits:
Object
  • Object
show all
Includes:
Adapter
Defined in:
lib/specbandit/rspec_adapter.rb

Overview

RSpec adapter: runs RSpec programmatically in-process.

Each batch calls RSpec::Core::Runner.run with careful state cleanup between batches. This avoids process startup overhead and is the fastest way to run RSpec batches in a single process.

The adapter injects a JSON formatter writing to a tempfile so the Worker can accumulate structured results. User-provided rspec_opts (e.g. –format documentation) are preserved and prepended.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rspec_opts: [], verbose: false, output: $stdout) ⇒ RspecAdapter

Returns a new instance of RspecAdapter.



30
31
32
33
34
# File 'lib/specbandit/rspec_adapter.rb', line 30

def initialize(rspec_opts: [], verbose: false, output: $stdout)
  @rspec_opts = Array(rspec_opts)
  @verbose = verbose
  @output = output
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



28
29
30
# File 'lib/specbandit/rspec_adapter.rb', line 28

def output
  @output
end

#rspec_optsObject (readonly)

Returns the value of attribute rspec_opts.



28
29
30
# File 'lib/specbandit/rspec_adapter.rb', line 28

def rspec_opts
  @rspec_opts
end

#verboseObject (readonly)

Returns the value of attribute verbose.



28
29
30
# File 'lib/specbandit/rspec_adapter.rb', line 28

def verbose
  @verbose
end

Instance Method Details

#run_batch(files, batch_num) ⇒ Object

Run a batch of spec files via RSpec::Core::Runner.run.

Returns an RspecBatchResult with exit_code, duration, and json_path pointing to a tempfile containing the JSON output. The caller is responsible for reading and cleaning up the tempfile.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/specbandit/rspec_adapter.rb', line 44

def run_batch(files, batch_num)
  reset_rspec_state

  batch_json = Tempfile.new(['specbandit-batch', '.json'])
  args = files + rspec_opts + ['--format', 'json', '--out', batch_json.path]

  err = StringIO.new
  out = StringIO.new

  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  exit_code = RSpec::Core::Runner.run(args, err, out)
  duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time

  result = RspecBatchResult.new(
    batch_num: batch_num,
    files: files,
    exit_code: exit_code,
    duration: duration
  )
  result.json_path = batch_json.path
  result
ensure
  # Print RSpec output through our output stream
  rspec_output = out&.string
  output.print(rspec_output) if verbose && rspec_output && !rspec_output.empty?

  rspec_err = err&.string
  output.print(rspec_err) if verbose && rspec_err && !rspec_err.empty?

  # Don't unlink the tempfile here — the Worker needs to read it.
  # The Worker is responsible for cleanup after accumulation.
  batch_json&.close
end

#setupObject

No-op for RSpec adapter — RSpec is already loaded.



37
# File 'lib/specbandit/rspec_adapter.rb', line 37

def setup; end

#teardownObject

No-op for RSpec adapter.



79
# File 'lib/specbandit/rspec_adapter.rb', line 79

def teardown; end