123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Core::FilterableItemRepository::QueryOptimized Private

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: RSpec::Core::FilterableItemRepository::UpdateOptimized
Defined in: rspec-core/lib/rspec/core/metadata_filter.rb

Overview

This implementation is much more complex, and is optimized for rare (or hopefully no) updates once the queries start. Updates incur a cost as it has to clear the memoization and keep track of applicable keys. Queries will be O(N) the first time an item is provided with a given set of applicable metadata; subsequent queries with items with the same set of applicable metadata will be O(1) due to internal memoization.

This is ideal for use by config, where filterable items (e.g. hooks) are typically added at the start of the process (e.g. in ‘spec_helper`) and then repeatedly queried as example groups and examples are defined.

Class Method Summary

UpdateOptimized - Inherited

Instance Attribute Summary

Instance Method Summary

UpdateOptimized - Inherited

#append, #delete,
#items_for

See additional method definition at line 118.

#prepend

Instance Method Details

#append(item, metadata)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 164

def append(item, )
  super
  handle_mutation()
end

#applicable_metadata_from(metadata) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 217

def ()
  MetadataFilter. do
    @applicable_keys.inject({}) do |hash, key|
      # :example_group is treated special here because...
      # - In RSpec 2, example groups had an `:example_group` key
      # - In RSpec 3, that key is deprecated (it was confusing!).
      # - The key is not technically present in an example group metadata hash
      #   (and thus would fail the `metadata.key?(key)` check) but a value
      #   is provided when accessed via the hash's `default_proc`
      # - Thus, for backwards compatibility, we have to explicitly check
      #   for `:example_group` here if it is one of the keys being used to
      #   filter.
      hash[key] = [key] if .key?(key) || key == :example_group
      hash
    end
  end
end

#delete(item, metadata)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 174

def delete(item, )
  super
  reconstruct_caches
end

#find_items_for(request_meta) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 152

alias find_items_for items_for

#handle_mutation(metadata) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 211

def handle_mutation()
  @applicable_keys.merge(.keys)
  @proc_keys.merge(proc_keys_from )
  @memoized_lookups.clear
end

#items_for(metadata)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 179

def items_for()
  # The filtering of `metadata` to `applicable_metadata` is the key thing
  # that makes the memoization actually useful in practice, since each
  # example and example group have different metadata (e.g. location and
  # description). By filtering to the metadata keys our items care about,
  # we can ignore extra metadata keys that differ for each example/group.
  # For example, given `config.include DBHelpers, :db`, example groups
  # can be split into these two sets: those that are tagged with `:db` and those
  # that are not. For each set, this method for the first group in the set is
  # still an `O(N)` calculation, but all subsequent groups in the set will be
  # constant time lookups when they call this method.
   = ()

  if .any? { |k, _| @proc_keys.include?(k) }
    # It's unsafe to memoize lookups involving procs (since they can
    # be non-deterministic), so we skip the memoization in this case.
    find_items_for()
  else
    @memoized_lookups[]
  end
end

#prepend(item, metadata)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 169

def prepend(item, )
  super
  handle_mutation()
end

#proc_keys_from(metadata) (private)

See additional method definition at line 235.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 244

def proc_keys_from()
  .each_with_object([]) do |(key, value), to_return|
    to_return << key if Proc === value
  end
end

#reconstruct_caches (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/metadata_filter.rb', line 203

def reconstruct_caches
  @applicable_keys.clear
  @proc_keys.clear
  @items_and_filters.each do |_item, |
    handle_mutation()
  end
end