googletest icon indicating copy to clipboard operation
googletest copied to clipboard

Stream-based alternative to `testing::PrintToString`

Open MikeWeller opened this issue 3 years ago • 5 comments

Does the feature exist in the most recent commit?

No

Why do we need this feature?

When implementing a custom PrintTo that needs to print some generic types, I currently need to call testing::PrintToString(t) which prints a value to a std::string temporary, and then send that to the std::ostream* os via operator<<:

(Full example code at https://godbolt.org/z/hcK53dsjM)

template <typename T>
void PrintTo(const MyMonadicType<T>& t, std::ostream* os)
{
    *os << "<MyMonadicType value=";
    *os << /* prints to a temporary 'std::string' */ testing::PrintToString(t.d_value);
    *os << ">";
}

Going via a std::string is wasteful, especially since the implementation just creates an ostringstream and then calls stream-based PrintTo methods anyway. I would expect a generic PrintTo to be able to call a similar stream-based PrintTo for any inner types it needs to print.

Describe the proposal

I would like a stream-based alternative to testing::PrintToString. This could either be supported by allowing an unqualified call to PrintTo directly (doing ADL lookup), or if there are still some Google Test internals we need to go through to print some generic type, some kind of testing::PrintToStream(t, os) call would be better:

// Unqualified call to 'PrintTo' - this would require a 'PrintTo' to be
// visible in 'testing' (currently it is in 'testing::internal')
template <typename T>
void PrintTo(const MyMonadicType<T>& t, std::ostream* os)
{
    using testing::PrintTo;
    *os << "<MyMonadicType value=";
    // Direct ADL lookup
    PrintTo(t.d_value, os);
    *os << ">";
}

// OR, if we still need to go via some Google Test internals (rather than
// doing ADL lookup directly)
template <typename T>
void PrintTo(const MyMonadicType<T>& t, std::ostream* os)
{
    *os << "<MyMonadicType value=";
    // internally dispatches to 'PrintTo' via ADL
    testing::PrintToStream(t.d_value, os);
    *os << ">";
}

Is the feature specific to an operating system, compiler, or build system version?

No.

MikeWeller avatar May 26 '22 07:05 MikeWeller

Note: I would be interested in working on this myself assuming there is agreement on this being useful.

MikeWeller avatar May 26 '22 08:05 MikeWeller

Maybe I'm missing something, but why not just write an ostream operator << for your types?

derekmauro avatar Jun 06 '22 19:06 derekmauro

Maybe I'm missing something, but why not just write an ostream operator << for your types?

Well, you may want test-specific printing. For example the operator<< for a string just prints the string directly, whereas the PrintTo will display them in double quotes using \ escapes.

MikeWeller avatar Jun 09 '22 10:06 MikeWeller