proposal: construct for converting a single-parameter matcher to a 2-tuple matcher (was: Checking if floating-point arrays are nearly equal)

481 views
Skip to first unread message

Zhanyong Wan (λx.x x)

unread,
Jul 7, 2013, 7:16:58 PM7/7/13
to Google C++ Mocking Framework
Google Mock users,

I noticed that it's a very common pattern that people want to match two containers pointwise using a custom matcher.  The Pointwise() matcher was designed for this:

  Pointwise(m, expected_container)

returns a matcher that matches a container whose size is the same as expected_container and the inner matcher m matches (the i-th element in the actual container, the i-th element in the expected container) for all i.  Here m must be a matcher for a 2-tuple.

For example, given that Lt() is a matcher that matches a 2-tuple of numbers where the first number is less than the second,

  Pointwise(Lt(), upperbounds)

is a matcher that matches a container whose i-th element is less than the i-th element of upperbounds.

Google Mock provides some frequently used 2-tuple matchers: https://code.google.com/p/googlemock/wiki/CheatSheet#Multiargument_Matchers

However, often the custom matcher one needs falls out of this small set, and the user is expected to define the custom matcher himself.

In a lot of such cases, there is already an existing one-parameter matcher that does what we want, except that we need a no-parameter matcher.  For example, in Daniel's case he needs

  DoubleTupleEq()

which matches a 2-tuple (x, y) iff the one-parameter matcher DoubleEq(y) matches x.

I think it would be very useful to provide a construct that turns a one-parameter matcher into a no-parameter matcher for 2-tuples, e.g.

TUPLE2_MATCHER(DoubleTupleEq, DoubleEq);

This macro will define a new matcher DoubleTupleEq() from DoubleEq, and it will take care of defining the description of the new matcher in terms of the description of DoubleEq.

Thoughts?


---------- Forwarded message ----------
From: Zhanyong Wan (λx.x x) <w...@google.com>
Date: Sun, Jul 7, 2013 at 3:52 PM
Subject: Re: [googlemock: 1901] Checking if floating-point arrays are nearly equal
To: "Daniel P. Volpato" <danielp...@gmail.com>
Cc: Google C++ Mocking Framework <googl...@googlegroups.com>





On Fri, Jul 5, 2013 at 6:40 AM, Daniel P. Volpato <danielp...@gmail.com> wrote:
Hi everyone,

I couldn't find a way to check if two floating-point arrays matches (they don't need to be exactly equal, just nearly equal each other). For integer arrays and other sorts of arrays that can use operator ==, I was successfull using ElementsAreArray() like this:

const int expected_array[kArraySize] = { ... };
int actual_array[kArraySize];
// call method that fills actual_array
EXPECT_THAT(expected_array, ::testing::ElementsAreArray(actual_array, array_size));

But if the arrays are floating-point (float or double), ElementsAreArray also uses matcher Eq(), so my test fails. How can I check if two FP arrays are nearly equal? Is there any built-in way to apply matcher FloatEq() to all elements of an array?

You can give ElementsAreArray() an array of matchers instead of an array of values, so one way to do it is:

const Matcher<double> expected_array[kArraySize] = {
  DoubleEq(1.0),
  ...
  DoubleEq(4.2)
};
...
EXPECT_THAT(expected_array, ElementsAreArray(expected_array));

Another way is to define a Matcher<tr1::tuple<double, double> > that succeeds when the argument is a pair of almost equal doubles (you can define it in terms of DoubleEq(x)).  You can then use it in Pointwise():

const double expected_array[kArraySize] = { 1.0, ..., 4.2 };
...
EXPECT_THAT(actual_array, Pointwise(DoubleEqual(), expected_array));

Thanks,
Daniel P. Volpato

--
 
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Zhanyong



--
Zhanyong

Brian Ferris

unread,
Sep 3, 2013, 10:17:24 AM9/3/13
to gmock...@google.com, Google C++ Mocking Framework
+1

I found this message after running into the same problem as Daniel.

Brian

Thanks,
Daniel P. Volpato
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Zhanyong



--
Zhanyong

--
 
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+unsubscribe@googlegroups.com.

Alex Shtof

unread,
May 8, 2014, 10:17:43 AM5/8/14
to googl...@googlegroups.com, gmock...@google.com, bdfe...@google.com
+1 for that too.

Thanks,
Daniel P. Volpato
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Zhanyong



--
Zhanyong

--
 
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.

ste...@interaxon.ca

unread,
Jun 3, 2015, 3:38:26 PM6/3/15
to googl...@googlegroups.com, gmock...@google.com, bdfe...@google.com
Has anything like this emerged yet? Any examples to work from? I'd find it pretty useful.
Reply all
Reply to author
Forward
0 new messages