module RSpec::Core::MemoizedHelpers::ClassMethods
def let(name, &block)
- Note: - Because `let` is designed to create state that is reset between
Note: - `let` can be configured to be threadsafe or not.
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? raise( "#let or #subject called with a reserved name #initialize" ) if :initialize == name our_module = MemoizedHelpers.module_for(self) # If we have a module clash in our helper module # then we need to remove it to prevent a warning. # # Note we do not check ancestor modules (see: `instance_methods(false)`) # as we can override them. if our_module.instance_methods(false).include?(name) our_module.__send__(:remove_method, name) end our_module.__send__(:define_method, name, &block) # If we have a module clash in the example module # then we need to remove it to prevent a warning. # # Note we do not check ancestor modules (see: `instance_methods(false)`) # as we can override them. if instance_methods(false).include?(name) remove_method(name) end # Apply the memoization. The method has been defined in an ancestor # module so we can use `super` here to get the value. if block.arity == 1 define_method(name) { __memoized.fetch_or_store(name) { super(RSpec.current_example, &nil) } } else define_method(name) { __memoized.fetch_or_store(name) { super(&nil) } } end end
def let!(name, &block)
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(:example) { Thing.reset_count }
RSpec.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 subject(name=nil, &block)
- See: MemoizedHelpers#is_expected -
See: MemoizedHelpers#should_not -
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
Other tags:
- Note: - `subject` can be configured to be threadsafe or not.
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
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(:example) { Thing.reset_count }
RSpec.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
providing a memoized reference to that state.
`before` hook. This serves a dual purpose of setting up state and
Just like `subject`, except the block is invoked by an implicit
def subject!(name=nil, &block) subject(name, &block) before { subject } end