Understanding rspec predicates

I know I can do:

blah.should be_empty

or

blah.should have_key(:to_my_house)

But, is there a way to do:

str = “lmaonade omg rotfcopter!”

str.should start_with(“lmao”)

Or is it just best to do:

str.starts_with?(“lmao”).should be_true

?

Patrick J. Collins
http://collinatorstudios.com

See

https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/be-matchers

and

https://www.relishapp.com/rspec/rspec-expectations/docs/custom-matchers/define-matcher

I see… So, the question I have now is, would some argue that defining
custom
matchers is not the best thing to do because it results in obfuscated
test
behavior which could result in false positives / funky breakage where
one might
not think to look?

For example, one of my models has a method:

def alert_flag?
flag == FLAG_VALUES[:alert]
end

Having a spec that does:

@my_model.alert_flag?.should be_true

Seemed a little goofy to me… So I did:

RSpec::Matchers.define :have_alert_flag do
match do |actual|
actual.alert_flag?
end
end

So that I can do:

@my_model.should have_alert_flag

… But then I got a little worried about the fact that this creates
more
magic in my test, makes things less clear for other developers who might
not
know what custom matchers are, etc…

Are these valid concerns? Or should I just keep making custom machers
like this?

As always, thanks for the guidance!

Patrick J. Collins
http://collinatorstudios.com

On Oct 11, 2011, at 5:22 PM, Patrick J. Collins wrote:

Having a spec that does:

@my_model.alert_flag?.should be_true

Seemed a little goofy to me… So I did:

You can do

@my_model.should be_alert_flag

A custom matcher isn’t worth it in this case, in my opinion.

Pat

On Oct 10, 2011, at 8:17 PM, Patrick J. Collins wrote:

But, is there a way to do:

str = “lmaonade omg rotfcopter!”

str.should start_with(“lmao”)

Or is it just best to do:

str.starts_with?(“lmao”).should be_true

See

https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/be-matchers

and

https://www.relishapp.com/rspec/rspec-expectations/docs/custom-matchers/define-matcher

On Oct 11, 2011, at 6:19 PM, David C. wrote:

@my_model.should be_alert_flag

That name feels odd to me. The model is not an alert flag, it has one. This is
actually a good thing! One point of be_xxx is to make you ask if “xxx?” is a good
predicate name. If you wouldn’t say “should be xxx” then you shouldnt be asking
“xxx?”.

I’d rename it to something like “has_alert_flag?” or “flagged_for_alert?” so I
could say “model.should have_alert_flag” or “model.should be_flagged_for_alert”.

Totally agree. I was going to let him come to that conclusion on his own
:wink:

Pat

I’d rename it to something like “has_alert_flag?” or “flagged_for_alert?”
so I could say “model.should have_alert_flag” or “model.should
be_flagged_for_alert”.

Ok, for whatever reason I wasn’t 100% clear on this… So the rule is,
any
predicate method that starts with “has_” can be replaced with “have_”,
and all
others would begin with “be_”.

Got it… Thanks!

Patrick J. Collins
http://collinatorstudios.com

On Oct 11, 2011, at 7:38 PM, Pat M. [email protected] wrote:

On Oct 11, 2011, at 5:22 PM, Patrick J. Collins wrote:

Having a spec that does:

@my_model.alert_flag?.should be_true

Seemed a little goofy to me… So I did:

You can do

@my_model.should be_alert_flag

That name feels odd to me. The model is not an alert flag, it has one.
This is actually a good thing! One point of be_xxx is to make you ask if
“xxx?” is a good predicate name. If you wouldn’t say “should be xxx”
then you shouldnt be asking “xxx?”.

I’d rename it to something like “has_alert_flag?” or
“flagged_for_alert?” so I could say “model.should have_alert_flag” or
“model.should be_flagged_for_alert”.

A custom matcher isn’t worth it in this case, in my opinion.

Agreed, as long as the name changes :slight_smile: