Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add support for comparing std::vector to std::initializer_list #640

Closed
TorstenRobitzki opened this issue Apr 15, 2016 · 11 comments
Closed
Labels

Comments

@TorstenRobitzki
Copy link

Hello,
I would like to have support for expressions, like this in Catch:

CHECK( std::vector< char >() == { 0 } );

Could some of you give me some advice, how to add comparison of containers with std::initializer_list? (beside using CHECK_THAT and a custom matcher).

As comparison of std::vector< T > with other std::vector< char >() works, I was looking for tests to find out how this works. Are there any unit tests in Catch?

cheers,
Torsten

@refi64
Copy link

refi64 commented Apr 15, 2016

Can't you just do:

CHECK( std::vector< char >() == std::vector< char >{ 0 } );

@TorstenRobitzki
Copy link
Author

Sure, but that would add overhead (in terms of code to read) that I would like to eliminate.

CHECK( a == { 0x01, 0x02 } );

just reads nicer.

@refi64
Copy link

refi64 commented Apr 15, 2016

Unfortunately, there's no other way. C++11 just doesn't allow an initializer list on the right-hand-side of ==, no matter whether or not there's an overload. So it's impossible for Catch to do anything...

...without metaprogramming. You could create a function and then call it like:

CHECK( a == mkv(0x1, 0x2) );

Working on an implementation right now...

@refi64
Copy link

refi64 commented Apr 15, 2016

template <typename... Args>
std::vector<typename std::common_type<Args...>::type> mkv(Args&&... args) {
    return {args...};
}

You can technically name it whatever you want.

@TorstenRobitzki
Copy link
Author

TorstenRobitzki commented Apr 15, 2016

Nice, thank you. What would be the usual ways to add support for custom type comparison operators? Does the std::vector support only based on Catch::toString()? I ask, because I could change std::vector in my tests to something else.

In case I test with larger amounts of data, it could be handy if the comparison makes a diff between the two data sets and reports the difference instead of the content of both sets.

@horenmar
Copy link
Member

horenmar commented Mar 3, 2017

This is rather old issue, but here we go:

  • To add support for comparing with new types, you just need to add proper bool operator== overload where the compiler finds it.
  • To change how the results are displayed, you need to either give your type overload for operator<<, or specialize Catch::StringMaker for your type.

@horenmar horenmar added the Resolved - pending review Issue waiting for feedback from the original author label Mar 3, 2017
@philsquared
Copy link
Collaborator

I missed this one the first time around, sorry.
Reading through now it seems this would be a good fit for matchers (which I've just revamped and added vector matchers for).
At the moment you can do Equals matchers between vector and another vector - or Contains matchers between two vectors or a vector and an element.
Adding versions that compare against initialiser_lists (if detected to be available) should be easy to do (in fact I just tested this theory in a local proof-of-concept.
I'll have look at adding these. That will mean you'll be able to do:

REQUIRE_THAT( myVec, EqualsVector( { 1, 2, 3 } ) );

But also:

REQUIRE_THAT( myVec, ContainsVector( { 1, 2 } ) );

How does that sound?

@TorstenRobitzki
Copy link
Author

That sounds perfect! What do you think about having a diff in output of the error case, in case that the containers becomes larger?

@horenmar horenmar added Revisit and removed Resolved - pending review Issue waiting for feedback from the original author labels Mar 22, 2017
@DanielSWolf
Copy link

Has there been any progress? I have a lot of Google Test unit tests that I'd like to migrate to Catch2. But I got blocked on the very first test suite, which heavily relies on std::initializer_lists for expected values.

Google Test's EXPECT_THAT(value, ElementsAreArray(...)) supports initializer lists.

@horenmar
Copy link
Member

horenmar commented Jun 3, 2019

@DanielSWolf

	std::vector<int> values{ 1, 2, 3 };
	REQUIRE_THAT(values, Catch::Equals<int>({1, 2, 3}));

@DanielSWolf
Copy link

Thank you! I didn't realize I needed to specify the generic type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants