Module: RSpec::Core::MemoizedHelpers::ClassMethods
- Defined in:
- lib/rspec/core/memoized_helpers.rb
Instance Method Summary collapse
-
#its(attribute, &block) ⇒ Object
Creates a nested example group named by the submitted
attribute
, and then generates an example using the submitted block. -
#let(name, &block) ⇒ Object
Generates a method whose return value is memoized after the first call.
-
#let!(name, &block) ⇒ Object
Just like
let
, except the block is invoked by an implicitbefore
hook. -
#subject(name = nil, &block) ⇒ Object
Declares a
subject
for an example group which can then be wrapped withexpect
usingis_expected
to make it the target of an expectation in a concise, one-line example. -
#subject!(name = nil, &block) ⇒ Object
Just like
subject
, except the block is invoked by an implicitbefore
hook.
Instance Method Details
#its(attribute, &block) ⇒ Object
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.
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'lib/rspec/core/memoized_helpers.rb', line 491 def its(attribute, &block) RSpec.deprecate("Use of rspec-core's `its` method", :replacement => 'the rspec-its gem') describe(attribute.to_s) 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 |
#let(name, &block) ⇒ Object
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.
252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/rspec/core/memoized_helpers.rb', line 252 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. if block.arity == 1 define_method(name) { __memoized.fetch(name) { |k| __memoized[k] = super(RSpec.current_example, &nil) } } else define_method(name) { __memoized.fetch(name) { |k| __memoized[k] = super(&nil) } } end end |
#let!(name, &block) ⇒ Object
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.
320 321 322 323 |
# File 'lib/rspec/core/memoized_helpers.rb', line 320 def let!(name, &block) let(name, &block) before { __send__(name) } end |
#subject(name = nil, &block) ⇒ Object
Declares a subject
for an example group which can then be wrapped
with expect
using is_expected
to make it the target of an expectation
in a concise, one-line example.
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.
355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/rspec/core/memoized_helpers.rb', line 355 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 |
#subject!(name = nil, &block) ⇒ Object
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.
421 422 423 424 |
# File 'lib/rspec/core/memoized_helpers.rb', line 421 def subject!(name=nil, &block) subject(name, &block) before { subject } end |