Class: RSpecTracer::Tracker::WholeSuiteInvalidators Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec_tracer/tracker/whole_suite_invalidators.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 #4 in the 2.0 tracker pipeline. Emits the binary “blow it all up” signal that runs before any per-example filtering - when any watched file changes, the filter engine treats every example as affected.

Watch list is deliberately hard-coded (not config-overridable): these are the files whose semantics are universal across any rspec-tracer user.

- Gemfile.lock   : dependency changes ripple through every spec
- .ruby-version  : Ruby version changes can shift any behavior
- .rspec-tracer  : tracer config changes (filters, declared
                   globs) affect what the cache considers fresh

Plus a synthetic entry for the rspec-tracer gem identity itself - a gem upgrade that changes invalidation semantics has to invalidate the cache, which lockfile tracking alone doesn’t catch (the gem path is version-stamped but Gemfile.lock only sees the constraint, not the resolved install).

Graceful degradation (CLAUDE.md): absent watch files are skipped silently. Key-presence asymmetry is the invalidation signal (snapshot A has key, snapshot B does not => invalidated).

Constant Summary collapse

WATCH_FILES =

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.

Internal constant.

%w[Gemfile.lock .ruby-version .rspec-tracer].freeze
GEM_IDENTITY_KEY =

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.

Internal constant.

'rspec-tracer-gem'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root:, gem_version: RSpecTracer::VERSION) ⇒ WholeSuiteInvalidators

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.

Internal method on the tracer pipeline.



49
50
51
52
# File 'lib/rspec_tracer/tracker/whole_suite_invalidators.rb', line 49

def initialize(root:, gem_version: RSpecTracer::VERSION)
  @root = File.expand_path(root)
  @gem_version = gem_version
end

Instance Attribute Details

#gem_versionObject (readonly)

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.

Internal attribute.



45
46
47
# File 'lib/rspec_tracer/tracker/whole_suite_invalidators.rb', line 45

def gem_version
  @gem_version
end

#rootObject (readonly)

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.

Internal attribute.



45
46
47
# File 'lib/rspec_tracer/tracker/whole_suite_invalidators.rb', line 45

def root
  @root
end

Instance Method Details

#digest_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.

Fresh snapshot on every call - callers typically take one at boot (stored as the “current” snapshot) and compare against a previously-loaded snapshot (returned by the storage backend). Unlike DeclaredGlobs.walk, this is not memoized: the caller chooses when to sample.



59
60
61
62
63
64
65
66
67
# File 'lib/rspec_tracer/tracker/whole_suite_invalidators.rb', line 59

def digest_snapshot
  snapshot = {}
  WATCH_FILES.each do |rel|
    digest = file_digest(File.join(@root, rel))
    snapshot[rel] = digest unless digest.nil?
  end
  snapshot[GEM_IDENTITY_KEY] = gem_identity_digest
  snapshot
end

#invalidated?(previous_snapshot) ⇒ Boolean

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.

nil previous_snapshot = first-run case (no cache); treat as invalidated so the filter engine runs every example. Any subsequent run with a stored snapshot compares value-equality across the whole Hash, which captures added/removed/changed watch files in one check.

Returns:

  • (Boolean)


74
75
76
77
78
# File 'lib/rspec_tracer/tracker/whole_suite_invalidators.rb', line 74

def invalidated?(previous_snapshot)
  return true if previous_snapshot.nil?

  digest_snapshot != previous_snapshot
end