Best way to match several attributes of an object?

When you need to check several properties of an object, what is the
best way to match them all?

I’m using the ‘satisfy’ matcher at the moment but perhaps there’s a
better way than this:
flight.should satisfy { |f|
f.booking_code == @parsed_pnr_data[:pnr_number] &&
f.depart_airport.code == @parsed_pnr_data[:flights][0]
[:depart_airport_code] &&
f.arrive_airport.code == @parsed_pnr_data[:flights][0]
[:arrive_airport_code] &&
f.depart_terminal == @parsed_pnr_data[:flights][0]
[:depart_terminal] &&
f.arrive_terminal == @parsed_pnr_data[:flights][0]
[:arrive_terminal] &&
f.start_date == @parsed_pnr_data[:flights][0]
[:depart_date] &&
f.end_date == @parsed_pnr_data[:flights][0]
[:arrive_date]
}

Many thanks

On Mar 30, 2010, at 9:23 AM, George wrote:

[:arrive_airport_code] &&
f.depart_terminal == @parsed_pnr_data[:flights][0]
[:depart_terminal] &&
f.arrive_terminal == @parsed_pnr_data[:flights][0]
[:arrive_terminal] &&
f.start_date == @parsed_pnr_data[:flights][0]
[:depart_date] &&
f.end_date == @parsed_pnr_data[:flights][0]
[:arrive_date]
}

I don’t know if this is workable in your case or not, but I like to
design objects so you can compare them. Something like:

flight.should == Flight.new :booking_code =>
@parsed_pnr_data[:pnr_number], …

HTH,
David

Yep, that’s a fair point and may improve readability if I set up the
compare object in a before method.
Good idea, thanks David.
George

On Mar 30, 2010, at 7:23 AM, George wrote:

[:arrive_airport_code] &&
Many thanks


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

I use a Comparable object whenever possible, as David said. Other than
that, I just do one expectation per line. That way when one fails, I
know exactly where the failure is.

Pat

When you need to check several properties of an object, what is the
best way to match them all?

In the mail library I use a custom matcher, which lets me do things
like:

it “should handle |Minero A. [email protected]|” do
address = Mail::Address.new(‘Minero A. [email protected]’)
address.should break_down_to({
:display_name => ‘Minero A.’,
:address => ‘[email protected]’,
:local => ‘aamine’,
:domain => ‘loveruby.net’,
:format => ‘Minero A. [email protected]’,
:comments => nil,
:raw => ‘Minero A. [email protected]’})
end

The matcher in question is:

encoding: utf-8

module CustomMatchers
class BreakDownTo
def initialize(expected)
@expected = expected
end

def matches?(target)
  @target   = target
  @failed = false
  @expected.each_pair do |k,v|
    unless @target.send(k) == @expected[k]
      @failed = k
    end
  end
  !@failed
end

def failure_message
  "expected #{@failed} to be |#{@expected[@failed]}| " +
  "but was |#{@target.send(@failed)}|"
end

def megative_failure_message
  "expected #{@failed} not to be |#{@expected[@failed]}| " +
  "and was |#{@target.send(@failed)}|"
end

end

Actual matcher that is exposed.

def break_down_to(expected)
BreakDownTo.new(expected)
end
end