module RSpec::Core::MemoizedHelpers
This module is included in {ExampleGroup}, making the methods available to be called from within example blocks.
@see ClassMethods
Attributes
@private should just be placed in private section, but Ruby issues warnings on private attributes. and expanding it to the equivalent method upsets Rubocop, b/c it should obviously be a reader
Public Class Methods
@private
# File lib/rspec/core/memoized_helpers.rb, line 133 def initialize(*) __init_memoized super end
Private Class Methods
@private
# File lib/rspec/core/memoized_helpers.rb, line 516 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 lib/rspec/core/memoized_helpers.rb, line 527 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 lib/rspec/core/memoized_helpers.rb, line 502 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
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 lib/rspec/core/memoized_helpers.rb, line 118 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
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 lib/rspec/core/memoized_helpers.rb, line 80 def should(matcher=nil, message=nil) 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
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 lib/rspec/core/memoized_helpers.rb, line 99 def should_not(matcher=nil, message=nil) 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: 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. 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 }. 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. 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 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
Private Instance Methods
@private
# File lib/rspec/core/memoized_helpers.rb, line 139 def __init_memoized @__memoized = if RSpec.configuration.threadsafe? ThreadsafeMemoized.new else NonThreadSafeMemoized.new end end