[PATCH] D33059: Create an shared include directory for gtest helper functions
Pavel Labath via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 13 01:43:27 PDT 2017
labath added a comment.
In https://reviews.llvm.org/D33059#778617, @zturner wrote:
> In https://reviews.llvm.org/D33059#778601, @MatzeB wrote:
>
> > about the directories: 'meh'. I'm fine with whatever works.
> >
> > - Why is a patch that claims to create a shared include directory actually changing so many unit tests?
>
>
> I felt like we needed a motivating example of why this effort is useful. The error macros were copy/pasted amongst many different files, so it was the perfect candidate.
>
> > - `EXPECT_THAT_ERROR(x, Succeeded())` seems bad. SHouldn't this rather be `EXPECT_THAT(x, succeeded())` to look more natural?
>
> You're right, it is bad. But unfortunately there is not a good alternative. `Error` is a move only type, and gmock a) can't handle move only types, and b) can't exhibits undefined behavior if you change the state of an object you're matching inside of a matcher. Because of that, we have to convert the `Error` into something else by basically consuming its failure/success status and error messge and storing them in a different type, and then matching against that type. So we need the macro to convert the `Error / Expected` into the type we actually match against.
>
> It's not ideal, but it seems like the best we can do for this one specific class.
I think it is possible to avoid the explosion of `EXPECT/ASSERT_THAT_<FOO>` macros (I can't think of any right now, but I'm sure something will crop up eventually, which will require specific handling). For example, we could just define a single expect macro, and hide all of the type-specific stuff in the helper function. Then overload resolution should take care of selecting the right behavior.
I'm thinking of something like:
#define EXPECT(Obj, Matcher) EXPECT_THAT(::llvm::detail::gmock_helper(Obj), Matcher)
#define ASSERT(Obj, Matcher) ASSERT_THAT(::llvm::detail::gmock_helper(Obj), Matcher)
template<typename T>
T gmock_helper(T Obj) { return Obj; }
template<typename T>
ExpectedHolder<T> gmock_helper(Expected<T> Obj) { ... }
This way, we could just write `ASSERT(foo, bar)` always (names are just a suggestion, but I would prefer something shorter than ASSERT_THAT_EXPECTED), and if a type needed special handling, we would just specialize `gmock_helper`. What do you think?
(Disclaimer: I haven't tried to actually implement this, but I don't see a reason why it wouldn't work)
https://reviews.llvm.org/D33059
More information about the llvm-commits
mailing list