David Chelimsky wrote in post #1013001:
> On Jul 25, 6:40pm, 7stud -- <[email protected]> wrote:
>>
>> @user.encrypted_password.should_not be_blank
>>
>> Does the definition of should_not check the type of the receiver before
>> executing? I can't find any docs for the definition of should_not().
>
> should and should_not are both added to every object, and pass self
> (the receiver) to the matches?() method on the matcher passed to
> should[_not]. e.g.
>
>   obj.should matcher # => matcher.matches?(obj)
>
> It is the matcher that cares what the object is, not the should[_not]
> method.
>

Thanks for that.  I was able to find some more details based on your
post.  The lambda construct in rspec can be simplified like this:

a_function.should_not( change(User, :count )

The change() method simply returns a Change 'matcher' object:

def change(a_class, message)  #(User, :count)
  Change.new(a_class, message)  #(User, :count)
end

where the Change class is defined something like this:

class Change
  def initialize(a_class, message) #(User, :count)
    @receiver = a_class
    @msg = message
  end

  def matches?(callable)  #(a_function)
    before = @receiver.send(msg)  #same as calling User.count()
    callable.call        #execute a_function()
    after = @receiver.send(msg) #same as calling User.count()

    before == after
  end

  ...
  ...
end


should_not() is defined something like this:

def should_not(obj)
  result = obj.matches?(self)
  ...
  ...
end



For references, see:

1) http://rspec.rubyforge.org/rspec/1.1.9/classes/Spec/Expectations.html

====
Spec::Expectations adds two methods to Object:

  should(matcher=nil)
  should_not(matcher=nil)

Both methods take an optional Expression Matcher (See Spec::Matchers).

When should receives an Expression Matcher, it calls matches?(self)**.
If it returns true, the spec passes and execution continues. If it
returns false, then the spec fails with the message returned by
matcher.failure_message.

Similarly, when should_not receives a matcher, it calls matches?(self).
If it returns false, the spec passes and execution continues. If it
returns true, then the spec fails with the message returned by
matcher.negative_failure_message.

RSpec ships with a standard set of useful matchers, and writing your own
matchers is quite simple. See Spec::Matchers for details.
=====

**That can be made more clear:

When should() receives an Expression Matcher, it calls
expr_matcher.matches?(self):

def should(expr_matcher)
  result = expr_matcher.matches?(self)
  …
  …
end

self is the object calling the should() method.

If matches?() returns true, the spec passes and execution continues. If
it returns false, then the spec fails with the message returned by
expr_matcher.failure_message.


2)
http://www.robertsosinski.com/2008/12/10/up-and-running-with-custom-rspec-matchers/


However, that tutorial contains this passage:

===
3. Within the heart of our matcher is the matches? method. This method
takes one parameter, the actual value of the object that the should or
should_not method is passed to within your RSpec test.
===

That sentence is faulty ruby speak, and therefore doesn't make any
sense.  It should say,

===
3.
…
…
This method takes one parameter, the actual value of the object that the
should or should_not *message* is passed to within your RSpec test.
===

But in ruby, that simply means one thing:

===
This method takes one parameter: the receiver of the should() or
should_not method call() (where the receiver is the 'thing' that is
calling the method).
===

-- 
Posted via http://www.ruby-forum.com/.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to