module RSpec::Core::MemoizedHelpers

Private Class Methods

define_helpers_on(example_group) click to toggle source

@api private

# File lib/rspec/core/memoized_helpers.rb, line 478
def self.define_helpers_on(example_group)
  example_group.send(:include, module_for(example_group))
end
get_constant_or_yield(example_group, name) { || ... } click to toggle source

@api private

Gets the named constant or yields. On 1.8, const_defined? / const_get do not take into account the inheritance hierarchy.

# File lib/rspec/core/memoized_helpers.rb, line 488
def self.get_constant_or_yield(example_group, name)
  if example_group.const_defined?(name)
    example_group.const_get(name)
  else
    yield
  end
end
included(mod) click to toggle source
# File lib/rspec/core/memoized_helpers.rb, line 153
def self.included(mod)
  mod.extend(ClassMethods)
end
module_for(example_group) click to toggle source

@api private

Gets the LetDefinitions module. The module is mixed into the example group and is used to hold all let definitions. This is done so that the block passed to `let` can be forwarded directly on to `define_method`, so that all method constructs (including `super` and `return`) can be used in a `let` block.

The memoization is provided by a method definition on the example group that supers to the LetDefinitions definition in order to get the value to memoize.

# File lib/rspec/core/memoized_helpers.rb, line 464
def self.module_for(example_group)
  get_constant_or_yield(example_group, :LetDefinitions) do
    mod = Module.new do
      include Module.new {
        example_group.const_set(:NamedSubjectPreventSuper, self)
      }
    end

    example_group.const_set(:LetDefinitions, mod)
    mod
  end
end

Public Instance Methods

should(matcher=nil, message=nil) click to toggle source

When `should` is called with no explicit receiver, the call is delegated to the object returned by `subject`. Combined with an implicit subject this supports very concise expressions.

@example

describe Person do
  it { should be_eligible_to_vote }
end

@see subject

# File lib/rspec/core/memoized_helpers.rb, line 67
def should(matcher=nil, message=nil)
  RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
end
should_not(matcher=nil, message=nil) click to toggle source

Just like `should`, `should_not` delegates to the subject (implicit or explicit) of the example group.

@example

describe Person do
  it { should_not be_eligible_to_vote }
end

@see subject

# File lib/rspec/core/memoized_helpers.rb, line 81
def should_not(matcher=nil, message=nil)
  RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
end
subject() click to toggle source

@note `subject` was contributed by Joe Ferris to support the one-liner

syntax embraced by shoulda matchers:

    describe Widget do
      it { should validate_presence_of(:name) }
    end

While the examples below demonstrate how to use `subject`
explicitly in examples, we recommend that you define a method with
an intention revealing name instead.

@example

# explicit declaration of subject
describe Person do
  subject { Person.new(:birthdate => 19.years.ago) }
  it "should be eligible to vote" do
    subject.should be_eligible_to_vote
    # ^ ^ explicit reference to subject not recommended
  end
end

# implicit subject => { Person.new }
describe Person do
  it "should be eligible to vote" do
    subject.should be_eligible_to_vote
    # ^ ^ explicit reference to subject not recommended
  end
end

# one-liner syntax - should is invoked on subject
describe Person do
  it { should be_eligible_to_vote }
end

@note Because `subject` is designed to create state that is reset between

each example, and `before(:all)` is designed to setup state that is
shared across _all_ examples in an example group, `subject` is _not_
intended to be used in a `before(:all)` hook. RSpec 2.13.1 prints
a warning when you reference a `subject` from `before(:all)` and we plan
to have it raise an error in RSpec 3.

@see should

# File lib/rspec/core/memoized_helpers.rb, line 47
def subject
  __memoized.fetch(:subject) do
    __memoized[:subject] = begin
      described = described_class || self.class.description
      Class === described ? described.new : described
    end
  end
end

Private Instance Methods

__memoized() click to toggle source

@private

# File lib/rspec/core/memoized_helpers.rb, line 88
def __memoized
  @__memoized ||= {}
end