Class: Evilution::Integration::RSpec::StateGuard::ConfigurationState
- Inherits:
-
Object
- Object
- Evilution::Integration::RSpec::StateGuard::ConfigurationState
- Defined in:
- lib/evilution/integration/rspec/state_guard/configuration_state.rb
Overview
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 =
:@preferred_options- STREAM_IVARS =
%i[@output_stream @error_stream].freeze
- ALL_IVARS =
[PREFERRED_OPTIONS, *STREAM_IVARS].freeze
Instance Method Summary collapse
-
#initialize(configuration: nil) ⇒ ConfigurationState
constructor
configuration is injectable for isolated unit testing; production uses the shared RSpec.configuration singleton.
-
#release(captured) ⇒ Object
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.
- #snapshot ⇒ Object
Constructor Details
#initialize(configuration: nil) ⇒ ConfigurationState
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
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 |
#snapshot ⇒ Object
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 = {} (config, state) STREAM_IVARS.each do |ivar| state[ivar] = config.instance_variable_get(ivar) if config.instance_variable_defined?(ivar) end state end |