Class: RSpecTracer::Tracker::EnvSnapshot Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec_tracer/tracker/env_snapshot.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.

Observer #5 in the 2.0 tracker pipeline (WholeSuiteInvalidators is #4). Owns the per-run snapshot of environment-variable values that the per-example ‘tracks: { env: … }` metadata declares.

Watch list is caller-provided - unlike WholeSuiteInvalidators, which hard-codes Gemfile.lock / .ruby-version / .rspec-tracer, env names come from user metadata and are only known once RSpec has discovered every example. The engine unions every example’s declared env names and hands the set to ‘digest_snapshot` at finalize time.

Digest algorithm: ‘Digest::MD5.hexdigest(ENV.to_s)`. Missing env var digests the same as empty string - absent is a valid state. ENV is process-stable within a single run (we never mutate it mid-run), so one snapshot per run is enough.

Graceful degradation: the observer never raises on malformed input. Non-String env names are coerced via #to_s; nil / empty names are skipped silently.

Instance Method Summary collapse

Constructor Details

#initialize(env: ::ENV) ⇒ EnvSnapshot

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.

ENV source is injectable for testability - specs can pass a Hash double without poking the real process env.



32
33
34
# File 'lib/rspec_tracer/tracker/env_snapshot.rb', line 32

def initialize(env: ::ENV)
  @env = env
end

Instance Method Details

#digest_snapshot(names) ⇒ 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.

Snapshot the current ENV values for ‘names`. Returns `Hash[name => md5_hex]`. Idempotent; callers may invoke it repeatedly without side effects.



39
40
41
42
43
44
45
46
47
48
# File 'lib/rspec_tracer/tracker/env_snapshot.rb', line 39

def digest_snapshot(names)
  snapshot = {}
  names.each do |raw|
    key = raw.to_s
    next if key.empty?

    snapshot[key] = Digest::MD5.hexdigest(@env[key].to_s)
  end
  snapshot
end

#invalidated_keys(previous_snapshot, names) ⇒ 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.

Return the set of env names whose digest differs between ‘previous_snapshot` and the current ENV. Keys in either snapshot participate:

- present in both, digests differ  => invalidated
- present in previous, absent now  => invalidated
- absent previously, present now   => invalidated

‘previous_snapshot` may be nil (first run, no cache); in that case every currently-tracked key is considered invalidated so the examples declaring them get a mandatory cold re-run on first sighting. `names` scopes the check: only keys in `names` are considered, which means one example adding a new `tracks: env: …` doesn’t cascade-invalidate examples that declared different env keys previously.



65
66
67
68
69
70
71
72
73
74
# File 'lib/rspec_tracer/tracker/env_snapshot.rb', line 65

def invalidated_keys(previous_snapshot, names)
  previous = previous_snapshot || {}
  current = digest_snapshot(names)
  invalidated = Set.new

  current.each do |key, digest|
    invalidated << key if digest != previous[key]
  end
  invalidated
end