module RSpec::Core::SharedExampleGroup::Registry

@private

Used internally to manage the shared example groups and constants. We want to limit the number of methods we add to objects we don't own (main and Module) so this allows us to have helper methods that don't get added to those objects.

Public Class Methods

created_from_caller(other_caller) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 84
def self.created_from_caller(other_caller)
  @caller_line == other_caller.last
end
included(kls) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 88
def self.included(kls)
  kls.describe(&@shared_block)
  kls.children.first.metadata[:shared_group_name] = name
end

Public Instance Methods

add_const(name, &block) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 74
def add_const(name, &block)
  if Object.const_defined?(name)
    mod = Object.const_get(name)
    raise_name_error unless mod.created_from_caller(caller)
  end

  mod = Module.new do
    @shared_block = block
    @caller_line = caller.last

    def self.created_from_caller(other_caller)
      @caller_line == other_caller.last
    end

    def self.included(kls)
      kls.describe(&@shared_block)
      kls.children.first.metadata[:shared_group_name] = name
    end
  end

  shared_const = Object.const_set(name, mod)
  RSpec.world.shared_example_groups[shared_const] = block
end
add_group(*args, &block) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 56
def add_group(*args, &block)
  ensure_block_has_source_location(block, caller[1])

  if key? args.first
    key = args.shift
    warn_if_key_taken key, block
    RSpec.world.shared_example_groups[key] = block
  end

  unless args.empty?
    mod = Module.new
    (class << mod; self; end).send :define_method, :extended  do |host|
      host.class_eval(&block)
    end
    RSpec.configuration.extend mod, *args
  end
end

Private Instance Methods

ensure_block_has_source_location(block, caller_line) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 128
def ensure_block_has_source_location(block, caller_line)
  return if block.respond_to?(:source_location)

  block.extend Module.new {
    define_method :source_location do
      caller_line.split(':')
    end
  }
end
example_block_for(key) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 124
def example_block_for key
  RSpec.world.shared_example_groups[key]
end
formatted_location(block) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 120
def formatted_location block
  block.source_location.join ":"
end
key?(candidate) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 100
def key? candidate
  [String, Symbol, Module].any? { |cls| cls === candidate }
end
raise_name_error() click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 104
def raise_name_error
  raise NameError, "The first argument (#{name}) to share_as must be a legal name for a constant not already in use."
end
warn_if_key_taken(key, new_block) click to toggle source
# File lib/rspec/core/shared_example_group.rb, line 108
        def warn_if_key_taken key, new_block
          return unless existing_block = example_block_for(key)

          Kernel.warn "            |WARNING: Shared example group '#{key}' has been previously defined at:
            |  #{formatted_location existing_block}
            |...and you are now defining it at:
            |  #{formatted_location new_block}
            |The new definition will overwrite the original one.
".gsub(/^ +\|/, '')
        end