@api private
Gets the named constant or yields. On 1.8, const_defined? / const_get do not take into account the inheritance hierarchy.
# File lib/rspec/core/memoized_helpers.rb, line 475 def self.get_constant_or_yield(example_group, name) if example_group.const_defined?(name) example_group.const_get(name) else yield end end
# File lib/rspec/core/memoized_helpers.rb, line 141 def self.included(mod) mod.extend(ClassMethods) # This logic defines an implicit subject mod.subject do described = described_class || self.class.description Class === described ? described.new : described end end
@api 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 450 def self.module_for(example_group) get_constant_or_yield(example_group, :LetDefinitions) do mod = Module.new do include Module.new { public_class_method :define_method example_group.const_set(:NamedSubjectPreventSuper, self) } # Expose `define_method` as a public method, so we can # easily use it below. public_class_method :define_method end example_group.__send__(:include, mod) example_group.const_set(:LetDefinitions, mod) mod end 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
# File lib/rspec/core/memoized_helpers.rb, line 56 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
# File lib/rspec/core/memoized_helpers.rb, line 70 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 { 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 - should is invoked on subject describe Person do it { should be_eligible_to_vote } end
@see should
# File lib/rspec/core/memoized_helpers.rb, line 40 def subject raise NotImplementedError, 'This definition is here for documentation purposes only' ' - it is overriden anyway below when this module gets included.' end
@private
# File lib/rspec/core/memoized_helpers.rb, line 77 def __memoized @__memoized ||= {} end