Class: RSpecTracer::Tracker::ExampleRegistry Private

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

Per-example status + metadata registry. The Filter consults the registry to decide which examples always re-run (failed / flaky / pending / interrupted); the registry also owns duplicate detection via RSpec’s identity-hash surface (the same hash 1.x uses for ‘fail_on_duplicates`).

This module owns the data structure only. ‘update_status` is called by the RSpec integration hooks on example-finished events and by signal handlers on interruption; `Tracker.setup` passes the registry instance through. The registry itself has no opinion about where status comes from.

Statuses


:passed       - completed cleanly
:failed       - example assertion failed
:pending      - RSpec `pending`
:interrupted  - RSpec was killed mid-example (SIGINT / SIGTERM)
:flaky        - passed this run but previously failed
                (detected via retry semantics)
:skipped      - skipped via `skip` or `:skip` metadata; tracked
                for coverage attribution but NOT auto-re-run

‘always_re_run_ids` returns the union of flaky, pending, interrupted - the 1.x invariant that examples with those statuses run on every subsequent suite regardless of whether their input files changed. `:skipped` is deliberately excluded (matches 1.x `skipped_examples.json` which is written but not added to the re-run set).

Constant Summary collapse

STATUSES =

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.

%i[passed failed pending interrupted flaky skipped].freeze
ALWAYS_RE_RUN_STATUSES =

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.

%i[failed flaky pending interrupted].freeze

Instance Method Summary collapse

Constructor Details

#initializeExampleRegistry

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.



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

def initialize
  @examples = {}
  @identity_index = {}
  @duplicates = {}
end

Instance Method Details

#all_example_idsObject

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.



99
100
101
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 99

def all_example_ids
  @examples.keys.to_set
end

#always_re_run_idsObject

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.



119
120
121
122
123
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 119

def always_re_run_ids
  @examples.each_with_object(Set.new) do |(id, entry), acc|
    acc << id if ALWAYS_RE_RUN_STATUSES.include?(entry[:status])
  end
end

#duplicate?(identity_hash) ⇒ 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.

Internal method on the tracer pipeline.

Returns:

  • (Boolean)


134
135
136
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 134

def duplicate?(identity_hash)
  @duplicates.key?(identity_hash)
end

#duplicatesObject

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.

Hash[identity_hash => Array<example_id>] of every collision observed. The array always has >= 2 entries (the first registrant plus every colliding follower).



128
129
130
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 128

def duplicates
  @duplicates.transform_values(&:dup)
end

#ids_with_status(status) ⇒ 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.

Internal method on the tracer pipeline.



111
112
113
114
115
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 111

def ids_with_status(status)
  @examples.each_with_object(Set.new) do |(id, entry), acc|
    acc << id if entry[:status] == status
  end
end

#metadata_of(example_id) ⇒ 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.

Internal method on the tracer pipeline.



84
85
86
87
88
89
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 84

def (example_id)
  entry = @examples[example_id]
  return nil if entry.nil?

  entry[:metadata].dup
end

#register(example_id, metadata: {}, identity_hash: nil) ⇒ 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.

Registers an example id with optional metadata (opaque Hash passed through to Snapshot.all_examples) and optional identity_hash for duplicate detection. First call wins for the identity_hash binding; subsequent calls with the same identity_hash but a different example_id accumulate into ‘@duplicates` and do not re-bind.



60
61
62
63
64
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 60

def register(example_id, metadata: {}, identity_hash: nil)
  @examples[example_id] ||= { metadata: .dup, status: nil }
  track_identity(example_id, identity_hash) if identity_hash
  self
end

#registered?(example_id) ⇒ 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.

Internal method on the tracer pipeline.

Returns:

  • (Boolean)


93
94
95
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 93

def registered?(example_id)
  @examples.key?(example_id)
end

#sizeObject

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.



105
106
107
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 105

def size
  @examples.size
end

#status_of(example_id) ⇒ 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.

Internal method on the tracer pipeline.



78
79
80
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 78

def status_of(example_id)
  @examples[example_id]&.dig(:status)
end

#update_status(example_id, status) ⇒ 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.

Internal method on the tracer pipeline.

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
# File 'lib/rspec_tracer/tracker/example_registry.rb', line 68

def update_status(example_id, status)
  raise ArgumentError, "unknown status: #{status.inspect}" unless STATUSES.include?(status)
  raise ArgumentError, "example not registered: #{example_id.inspect}" unless @examples.key?(example_id)

  @examples[example_id][:status] = status
  self
end