module RSpec::Core::MemoizedHelpers::ClassMethods
def its(attribute, &block)
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)
- 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
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)
- 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
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