Class: Evilution::Integration::RSpec::StateGuard::ConfigurationState Private

Inherits:
Object
  • Object
show all
Defined in:
lib/evilution/integration/rspec/state_guard/configuration_state.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Restores the RSpec.configuration state that ::RSpec::Core::Runner.run mutates on the shared singleton during an in-process mutation run (EV-dwqw / GH #1343).

The visible symptom was every SUBSEQUENT host example rendering its progress dots without color (white instead of green). Root cause: the run's args carry "--no-color", and ConfigurationOptions#configure applies it via Configuration#force, which does @preferred_options.merge!(:color_mode => :off) IN PLACE. Configuration#color_mode reads @preferred_options.fetch(:color_mode) first, so the host's color setting stays :off for the rest of the process. Separately, Runner#setup points output_stream/error_stream (attr_writers, i.e. the @output_stream/@error_stream ivars) at the run's throwaway StringIOs.

Forked runs never leak these (the mutation happens in a child that dies); only the in-process isolation path mutates the host's own configuration.

back by replacing the ivar; the stream ivars are reassigned during the run, so capturing the original references is enough.

Constant Summary collapse

PREFERRED_OPTIONS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

:@preferred_options
STREAM_IVARS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

%i[@output_stream @error_stream].freeze
ALL_IVARS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

[PREFERRED_OPTIONS, *STREAM_IVARS].freeze

Instance Method Summary collapse

Constructor Details

#initialize(configuration: nil) ⇒ ConfigurationState

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

configuration is injectable for isolated unit testing; production uses the shared RSpec.configuration singleton.



30
31
32
# File 'lib/evilution/integration/rspec/state_guard/configuration_state.rb', line 30

def initialize(configuration: nil)
  @configuration = configuration
end

Instance Method Details

#release(captured) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Restore exactly the pre-run state: ivars present at snapshot get their value back; ivars created by the run but absent before are removed, so nothing the run introduced can leak into the host either.



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/evilution/integration/rspec/state_guard/configuration_state.rb', line 47

def release(captured)
  return unless captured

  config = configuration
  ALL_IVARS.each do |ivar|
    if captured.key?(ivar)
      config.instance_variable_set(ivar, captured[ivar])
    elsif config.instance_variable_defined?(ivar)
      config.remove_instance_variable(ivar)
    end
  end
end

#snapshotObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



34
35
36
37
38
39
40
41
42
# File 'lib/evilution/integration/rspec/state_guard/configuration_state.rb', line 34

def snapshot
  config = configuration
  state = {}
  capture_preferred_options(config, state)
  STREAM_IVARS.each do |ivar|
    state[ivar] = config.instance_variable_get(ivar) if config.instance_variable_defined?(ivar)
  end
  state
end