Module: RSpec::Core::MemoizedHelpers::ClassMethods
- Defined in:
- lib/rspec/core/memoized_helpers.rb
Instance Method Summary (collapse)
-
- (Object) its(attribute)
Creates a nested example group named by the submitted
attribute
, and then generates an example using the submitted block. -
- (Object) let(name)
Generates a method whose return value is memoized after the first call.
-
- (Object) let!(name)
Just like
let
, except the block is invoked by an implicitbefore
hook. -
- (Object) subject(name = nil)
Declares a
subject
for an example group which can then be the implicit receiver (through delegation) of calls toshould
. -
- (Object) subject!(name = nil)
Just like
subject
, except the block is invoked by an implicitbefore
hook.
Instance Method Details
- (Object) its(attribute)
Creates a nested example group named by the submitted attribute
,
and then generates an example using the submitted block.
The attribute can be a Symbol
or a String
. Given a String
with dots, the result is as though you concatenated that String
onto the subject in an expression.
When the subject is a Hash
, you can refer to the Hash keys by
specifying a Symbol
or String
in an array.
Note that this method does not modify subject
in any way, so if you
refer to subject
in let
or before
blocks, you're still
referring to the outer subject.
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/rspec/core/memoized_helpers.rb', line 426 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, =nil) RSpec::Expectations::PositiveExpectationHandler.handle_matcher(__its_subject, matcher, ) end def should_not(matcher=nil, =nil) RSpec::Expectations::NegativeExpectationHandler.handle_matcher(__its_subject, matcher, ) end example(&block) end end |
- (Object) let(name)
let
can enhance readability when used sparingly (1,2, or
maybe 3 declarations) in any given example group, but that can
quickly degrade with overuse. YMMV.
let
uses an ||=
conditional that has the potential to
behave in surprising ways in examples that spawn separate threads,
though we have yet to see this in practice. You've been warned.
Because let
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, let
is not
intended to be used in a before(:all)
hook. RSpec 2.13.1 prints
a warning when you reference a let
from before(:all)
and we plan
to have it raise an error in RSpec 3.
Generates a method whose return value is memoized after the first call. Useful for reducing duplication between examples that assign values to the same local variable.
190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/rspec/core/memoized_helpers.rb', line 190 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 |
- (Object) let!(name)
Just like let
, except the block is invoked by an implicit before
hook. This serves a dual purpose of setting up state and providing a
memoized reference to that state.
256 257 258 259 |
# File 'lib/rspec/core/memoized_helpers.rb', line 256 def let!(name, &block) let(name, &block) before { __send__(name) } end |
- (Object) subject(name = nil)
Declares a subject
for an example group which can then be the
implicit receiver (through delegation) of calls to should
.
Given a name
, defines a method with that name which returns the
subject
. This lets you declare the subject once and access it
implicitly in one-liners and explicitly using an intention revealing
name.
290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/rspec/core/memoized_helpers.rb', line 290 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 |
- (Object) subject!(name = nil)
Just like subject
, except the block is invoked by an implicit before
hook. This serves a dual purpose of setting up state and providing a
memoized reference to that state.
356 357 358 359 |
# File 'lib/rspec/core/memoized_helpers.rb', line 356 def subject!(name=nil, &block) subject(name, &block) before { subject } end |