Closed alindeman closed 12 years ago
This could also be written as results.should be_all { |r| r.cost <= 5 }
but we still lose out on diffability ("expected all? to return true, got false") .. and it still reads a little bit oddly IMHO.
I like it.
I think "all_satisfy" would read a bit clearer.
@mortice - the problem with that is it gives off the impression that the expectation is on the collection, and not on each collection item. Basically, people with associate it with the Ruby all?
method.
@justinko fair point, but I don't see the problem with the association with 'all?'. all_satisfy would match whenever all? came back true for the collection.
@mortice - please read the first comment. This matcher aims to set an expectation on each item in the collection, not on the collection as a whole.
@alindeman - with that said, I'm not sure how you're going to "diff" this. Since the blocks return true or false, and don't contain should
, I don't think it is possible. I'm sure there is a reason this type of matcher hasn't been added yet, and I suspect this is why.
@mortice, @justinko My idea for each_satisfy
is very similar to all?
from Enumerable
. I am not tied to the name and welcome more debate/suggestions on it.
@justinko By diffable, I meant we could print out the items that did not satisfy the block (e.g., "expected each item to satisfy the block, but elements ['foo', 'bar', 'baz'] did not")
Great feedback so far. Will wait for a bit more before running with it.
There was a lighthouse ticket for this a few years back and it never got resolved because there were a few tricky parts. We're opening up a bit of a can of worms here, because there are lots of iterators and a single API can't cover them all elegantly. Consider list.any? {|i| i > 3}.should be_true
. each_satisfy
or all_satisfy
wouldn't cover this, and list.should any_satisfy {...}
doesn't read all that well.
I'm open to this, but not 1/2 way.
Thoughts?
Just throwing out an idea here to see if it sticks:
list.all.should satisfy { ... }
list.any.should satisfy { ... }
list.none.should satisfy { ... }
+1 on this idea!
Of course the problem with that ^^ is that it adds methods to collections. How about this:
all_in(list).should satisfy { ... }
any_in(list).should satisfy { ... }
none_in(list).should satisfy { ... }
list.all.should satisfy { ... }
Yeah, the above would conflict with Rails. You'd have to do users.all.all.should ...
I agree with David, this is opening a can of worms, and is best to leave up to Ruby:
list.all? {|item| item < 5 }.should be_true
One can of worms (rspec-mocks's any_instance
) is enough :)
Recently ran across some coworker's code who had written:
While this is pretty readable, I wondered if it would make sense to write an rspec matcher that used
#each
(Enumerable
) so the syntax could be even clearer:The second syntax would also be easier to make diffable.
Let me know thoughts. If agreed, I can make it happen.