module RSpec::Core::MemoizedHelpers::ClassMethods

def its(attribute, &block)

end
its(:age) { should eq(25) }
before { subject.age = 25 }
subject { Person.new }
describe Person do

@example

referring to the outer subject.
refer to `subject` in `let` or `before` blocks, you're still
Note that this method does not modify `subject` in any way, so if you

end
its(:count) { should eq(2) }
its(:keys) { should include(:max_users) }
# You can still access to its regular methods this way:

its(['admin']) { should eq(:all_permissions) }
its([:max_users]) { should eq(3) }

end
'admin' => :all_permissions }
{ :max_users => 3,
subject do
describe "a configuration Hash" do

@example

specifying a `Symbol` or `String` in an array.
When the subject is a `Hash`, you can refer to the Hash keys by

end
its("phone_numbers.first") { should eq("555-1212") }

end
end
person.phone_numbers << "555-1212"
Person.new.tap do |person|
subject do
describe Person do

@example

onto the subject in an expression.
with dots, the result is as though you concatenated that `String`
The attribute can be a `Symbol` or a `String`. Given a `String`

end
end
end
subject.size.should eq(0)
it "should eq(0)" do
describe "size" do
describe Array do
# ... generates the same runtime structure as this:

end
its(:size) { should eq(0) }
describe Array do
# This ...

@example

and then generates an example using the submitted block.
Creates a nested example group named by the submitted `attribute`,
def its(attribute, &block)
  describe(attribute) do
    if Array === attribute
      let(:__its_subject) { subject[*attribute] }
    else
      let(:__its_subject) do
        attribute_chain = attribute.to_s.split('.')
        attribute_chain.inject(subject) do |inner_subject, attr|
          inner_subject.send(attr)
        end
      end
    end
    def should(matcher=nil, message=nil)
      RSpec::Expectations::PositiveExpectationHandler.handle_matcher(__its_subject, matcher, message)
    end
    def should_not(matcher=nil, message=nil)
      RSpec::Expectations::NegativeExpectationHandler.handle_matcher(__its_subject, matcher, message)
    end
    example(&block)
  end
end

def let(name, &block)

Other tags:
    Note: - Because `let` is designed to create state that is reset between
    Note: - `let` uses an `||=` conditional that has the potential to
    Note: - `let` _can_ enhance readability when used sparingly (1,2, or
def let(name, &block)
  # We have to pass the block directly to `define_method` to
  # allow it to use method constructs like `super` and `return`.
  raise "#let or #subject called without a block" if block.nil?
  MemoizedHelpers.module_for(self).send(:define_method, name, &block)
  # Apply the memoization. The method has been defined in an ancestor
  # module so we can use `super` here to get the value.
  define_method(name) do
    __memoized.fetch(name) { |k| __memoized[k] = super(&nil) }
  end
end

def let!(name, &block)

end
end
end
Thing.count.should eq(1)
thing
it "returns memoized version on first invocation" do

end
Thing.count.should eq(1)
it "is invoked implicitly" do

let!(:thing) { Thing.new }
context "using let!" do

end
end
Thing.count.should eq(1)
thing
it "can be invoked explicitly" do

end
Thing.count.should eq(0)
it "is not invoked implicitly" do

let(:thing) { Thing.new }
context "using let" do

after(:each) { Thing.reset_count }
describe Thing do

end
end
self.class.count += 1
def initialize

end
@count = 0
def self.reset_count

end
@count += val
def self.count=(val)

end
@count ||= 0
def self.count
class Thing

@example

memoized reference to that state.
hook. This serves a dual purpose of setting up state and providing a
Just like `let`, except the block is invoked by an implicit `before`
def let!(name, &block)
  let(name, &block)
  before { __send__(name) }
end

def should(matcher=nil, message=nil)

def should(matcher=nil, message=nil)
  RSpec::Expectations::PositiveExpectationHandler.handle_matcher(__its_subject, matcher, message)
end

def should_not(matcher=nil, message=nil)

def should_not(matcher=nil, message=nil)
  RSpec::Expectations::NegativeExpectationHandler.handle_matcher(__its_subject, matcher, message)
end

def subject(name=nil, &block)

Other tags:
    See: MemoizedHelpers#should -

Parameters:
  • block () -- defines the value to be returned by `subject` in examples
  • name (String, Symbol) -- used to define an accessor with an
def subject(name=nil, &block)
  if name
    let(name, &block)
    alias_method :subject, name
    self::NamedSubjectPreventSuper.send(:define_method, name) do
      raise NotImplementedError, "`super` in named subjects is not supported"
    end
  else
    let(:subject, &block)
  end
end

def subject!(name=nil, &block)

end
end
end
Thing.count.should eq(1)
subject
it "returns memoized version on first invocation" do

end
Thing.count.should eq(1)
it "is invoked implicitly" do

subject!(:thing) { Thing.new }
context "using subject!" do

end
end
Thing.count.should eq(1)
subject
it "can be invoked explicitly" do

end
Thing.count.should eq(0)
it "is not invoked implicitly" do

subject { Thing.new }
context "using subject" do

after(:each) { Thing.reset_count }
describe Thing do

end
end
self.class.count += 1
def initialize

end
@count = 0
def self.reset_count

end
@count += val
def self.count=(val)

end
@count ||= 0
def self.count
class Thing

@example

memoized reference to that state.
hook. This serves a dual purpose of setting up state and providing a
Just like `subject`, except the block is invoked by an implicit `before`
def subject!(name=nil, &block)
  subject(name, &block)
  before { subject }
end