module RSpec::Core::MemoizedHelpers
This module is included in {ExampleGroup}, making the methods available to be called from within example blocks.
@see ClassMethods
Public Class Methods
@private
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 542 def self.define_helpers_on(example_group) example_group.__send__(:include, module_for(example_group)) end
@private
Gets the named constant or yields. On 1.8, const_defined? / const_get do not take into account the inheritance hierarchy. :nocov:
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 553 def self.get_constant_or_yield(example_group, name) if example_group.const_defined?(name) example_group.const_get(name) else yield end end
@private
Gets the LetDefinitions module. The module is mixed into the example group and is used to hold all let definitions. This is done so that the block passed to ‘let` can be forwarded directly on to `define_method`, so that all method constructs (including `super` and `return`) can be used in a `let` block.
The memoization is provided by a method definition on the example group that supers to the LetDefinitions definition in order to get the value to memoize.
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 528 def self.module_for(example_group) get_constant_or_yield(example_group, :LetDefinitions) do mod = Module.new do include(Module.new { example_group.const_set(:NamedSubjectPreventSuper, self) }) end example_group.const_set(:LetDefinitions, mod) mod end end
@private
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 135 def initialize(*) __init_memoized super end
Public Instance Methods
Wraps the ‘subject` in `expect` to make it the target of an expectation. Designed to read nicely for one-liners.
@example
describe [1, 2, 3] do it { is_expected.to be_an Array } it { is_expected.not_to include 4 } end
@see subject
@see should
@see should_not
@note This only works if you are using rspec-expectations.
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 120 def is_expected expect(subject) end
When ‘should` is called with no explicit receiver, the call is delegated to the object returned by `subject`. Combined with an implicit subject this supports very concise expressions.
@example
RSpec.describe Person do it { should be_eligible_to_vote } end
@see subject
@see is_expected
@note This only works if you are using rspec-expectations. @note If you are using RSpec’s newer expect-based syntax you may
want to use `is_expected.to` instead of `should`.
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 80 def should(matcher=nil, message=nil) enforce_value_expectation(matcher, 'should') RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message) end
Just like ‘should`, `should_not` delegates to the subject (implicit or explicit) of the example group.
@example
RSpec.describe Person do it { should_not be_eligible_to_vote } end
@see subject
@see is_expected
@note This only works if you are using rspec-expectations. @note If you are using RSpec’s newer expect-based syntax you may
want to use `is_expected.to_not` instead of `should_not`.
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 100 def should_not(matcher=nil, message=nil) enforce_value_expectation(matcher, 'should_not') RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message) end
@note ‘subject` was contributed by Joe Ferris to support the one-liner
syntax embraced by shoulda matchers: RSpec.describe Widget do it { is_expected.to validate_presence_of(:name) } # or it { should validate_presence_of(:name) } end While the examples below demonstrate how to use `subject` explicitly in examples, we recommend that you define a method with an intention revealing name instead.
@example
# Explicit declaration of subject. RSpec.describe Person do subject { Person.new(:birthdate => 19.years.ago) } it "should be eligible to vote" do subject.should be_eligible_to_vote # ^ ^ explicit reference to subject not recommended end end # Implicit subject => { Person.new }. RSpec.describe Person do it "should be eligible to vote" do subject.should be_eligible_to_vote # ^ ^ explicit reference to subject not recommended end end # One-liner syntax - expectation is set on the subject. RSpec.describe Person do it { is_expected.to be_eligible_to_vote } # or it { should be_eligible_to_vote } end
@note Because ‘subject` is designed to create state that is reset
between each example, and `before(:context)` is designed to setup state that is shared across _all_ examples in an example group, `subject` is _not_ intended to be used in a `before(:context)` hook.
@see should
@see should_not
@see is_expected
# File rspec-core/lib/rspec/core/memoized_helpers.rb, line 57 def subject __memoized.fetch_or_store(:subject) do described = described_class || self.class.metadata.fetch(:description_args).first Class === described ? described.new : described end end