Hi,
just a quick question:
If I use a Pointee matcher in an EXPECT_CALL, the output in case of no
matching expectation doesn't show me the value of the pointed to
object, even if there is an operator<< for that type.
As a workaround, I declare
MATCHER_P(EqualsBlah, blah, "is equal to %(blah)s") {
do_not_remember_the_name << "is equal to " << arg;
return arg == blah;
}
Now if I match Pointee(EqualsBlah(blah)) instead of Pointee(blah) it
shows exactly what I want.
Would it be possible to implement the output for the "standard" Pointee case?
Thanks,
/Manuel
Thanks,
/Manuel
Yes, this is a reasonable improvement.
> The problem here is not in the Pointee matcher.
Actually it is. :-)
> The reason for this is that
> our relational matchers such as Eq(), Ne(), Lt(), etc. do not implement
> explanations. Pointee(blah) is in fact compiled as Pointee(Eq(blah)). When
> Pointee() sees that its inner matcher provides no explanation, it omits one
> itself, which is rather natural ("the provided value points to another value
> the properties of which are completely unknown" is not much of the
> explanation).
This is where Pointee() can do better. When the inner matcher fails,
it should print the pointee regardless of whether the inner matcher
provides an explanation.
> In your own matcher, you provide the explanation by streaming
> into the explanation listener.
> As to why explanations for the relational matchers are not implemented, I
> can only speculate. Zhanyong can sure provide a reasonable explanation (pun
> intended) when he returns from his leave next week. Adding explanations is
> trivial so maybe this is a performance issue.
It's not a performance issue. The way a matcher is used (in
EXPECT_CALL() or EXPECT_THAT()) by gmock, when it fails, gmock already
has printed the value being matched, so there's no point printing it
again in the match result explanation. For example,
EXPECT_THAT(Foo(), Eq(42));
may print something like:
Value of: Foo()
Expected: equals 42
Actual: 43
The string "43" is printed by the EXPECT_THAT() macro, not the Eq(42)
matcher. If Eq(42) prints "43" too, the user will see it twice in
the message, which isn't helpful.
Manuel, would you like to make this improvement yourself? I can do it
myself if you can wait. :-) Thanks,
> If you'd like to have them in
> your output, you can try out this patch:
> --- /tmp/g4-84224/gmock/include/gmock/gmock-matchers.h#51 2010-03-11
> 21:06:20.000000000 -0800
> +++ /home/vladl/gmock/include/gmock/gmock-matchers.h 2010-03-11
> 20:45:40.032643000 -0800
> @@ -6664,7 +664,11 @@
> public: \
> explicit Impl(const Rhs& rhs) : rhs_(rhs) {} \
> virtual bool MatchAndExplain(\
> - Lhs lhs, MatchResultListener* /* listener */) const { \
> + Lhs lhs, MatchResultListener* listener) const { \
> + ::std::stringstream ss; \
> + UniversalPrinter<GMOCK_REMOVE_REFERENCE_(Lhs)>::Print(lhs, &ss); \
> + *listener << "is " << ss.str(); \
> return lhs op rhs_; \
> } \
> virtual void DescribeTo(::std::ostream* os) const { \
> <end of patch>
>>>
>>> Thanks,
>>> /Manuel
>>
> Regards,
> Vlad
--
Zhanyong
Yes. We already have a bug tracking Field/Property.
> And then you still have the same problem when one higher order matcher is
> passed to another: the value will be printed by each one.
But each matcher prints a different part of the value, so the
information is still useful.
Example:
EXPECT_THAT(foo, Pointee(Pointee(Eq(42))));
may print:
Value of: foo
Expected: points to a value that points to a value that is equals to 42
Actual: 0x1234abcd (points to 0xabcd1234, which points to 43)
Here:
0x1234abcd is printed by EXPECT_THAT.
0xabcd1234 is printed by the outer Pointee.
43 is printed by the inner Pointee.
No duplicated information in the message.
--
Zhanyong
Some things feel a little strange to me, so please tell me where to put stuff...
Open for discussion :-)
On Fri, Mar 12, 2010 at 7:40 PM, Manuel Klimek <kli...@google.com> wrote:
> On Fri, Mar 12, 2010 at 5:35 PM, Vlad Losev <vlad...@gmail.com> wrote:
>>> This is where Pointee() can do better. When the inner matcher fails,
>>> it should print the pointee regardless of whether the inner matcher
>>> provides an explanation.
>>>
>> If you take this approach, you have to fix gmock other higher order matchers
>> that propagate empty explanations (Field, Property, Key, etc.) to be
>> consistent.
>
> I don't understand that yet:
> struct X { int* f; };
> If I take a Field with a pointer, I just need to use Field(&X::f,
> Pointee(42)) to get
> actual: the given field points to 42
> I think that's exactly what I want, isn't it?
>
> Of course, if I care about matching pointer values, and not what the
> pointer points to, I don't get the content of the Field, but I think
> here Pointee has a different connotation: I use pointee exactly to
> /not/ match the pointer, but what the pointer points to.
>
> Cheers,
> /Manuel
>