2

I've already enhanced my googletest environment to handle a handful of Qt Types, like QString (for more details see this question).

inline void PrintTo(const QString& str, ::std::ostream* os)
{
    *os << "<" << qUtf8Printable(str) << ">";
}

This works fine for most gtest macros like EXPECT_EQ etc.

However when I try to directly pipe a QString into a e.g. ADD_FAILURE() macro the compiler complaints...

//...
ADD_FAILURE() << QString("Test!");
//...    

gtest-message.h(131): error C2679: Binary Operator "<<": Could not find an operator that accepts "const QString" (...)

Is there a way to enhance my gtest further to be able to directly use QStrings, or is there no way to avoid wrapping those QStrings in qUtf8Printable()?

To Clarify:
Writing ADD_FAILURE() << qUtf8Printable(QString("Test!")); works, as does ADD_FAILURE() << QString("Test!").toStdString();.
But it would be much nicer if those explicit conversions/calls could be avoided, e.g. by enabling ADD_FAILURE() to directly handle QString. (Code duplication is bad - even if this only is only one additional short function call to write each time, you can expect to repeat the construct across thousands of tests...)

Here an excerpt of the raw (untranslated) error message (the entire error message consists of 132 lines listing what the compiler could not match the function to)

2>c:\development\external\googletest\include\gtest\gtest-message.h(131): error C2679: Binärer Operator "<<": Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ "const QString" akzeptiert (oder keine geeignete Konvertierung möglich)  
2>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(495): note: kann "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)"  
2>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(475): note: oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)"  
2>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(455): note: oder "std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(long double)" sein  
 ... **(snip)** ...  
2>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(981): note: oder "std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>,T>(std::basic_ostream<char,std::char_traits<char>> &&,const _Ty &)"  
2>          with  
2>          [  
2>              T=QString,  
2>              _Ty=QString  
2>          ]  
2>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(1019): note: oder "std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const std::error_code &)"  
2>  c:\development\external\googletest\include\gtest\gtest-message.h(131): note: bei Anpassung der Argumentliste "(std::stringstream, const QString)"  
2>  c:\development\test\src\codetest.cpp(390): note: Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "testing::Message &testing::Message::operator <<<QString>(const T &)".  
2>          with  
2>          [  
2>              T=QString  
2>          ] 
CharonX
  • 2,130
  • 11
  • 33
  • 1
    Could you show the entire error message? Usually it says the two types... – Yakk - Adam Nevraumont Sep 12 '18 at 11:12
  • Please try with `QString("text here").toUtf8().constData();` and let me know if it works! You could also check the `.toStdString().c_str()`. There is also the toStdString() method, but more info: http://doc.qt.io/qt-5/qstring.html – Alberto Miola Sep 12 '18 at 11:16
  • @AlbertoMiola Thanks. `ADD_FAILURE() << `QString("Test!").toUtf8().constData()` works of course (it is - in essence - what the `qUtf8Printable()` macro does) as does `.toStdString()` - but the intent is to be able to **directly** use `QString` and avoiding having to write `ADD_FAILURE() << QString("blablabla").toUtf8().constData()` each and every time I want to use `ADD_FAILURE()`, i.e. so that it is enough to write `ADD_FAILURE() << QString("blablabla")` – CharonX Sep 12 '18 at 11:40
  • @Yakk-AdamNevraumont Here ya go, but the original error message is in German (which is why I put the translated version there)... `googletest\include\gtest\gtest-message.h(131): error C2679: Binärer Operator "<<": Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ "const QString" akzeptiert (oder keine geeignete Konvertierung möglich)` The compiler tries to look for a match for the "<<" operator but can't find one (nor a conversion of QString - which I had hoped the `PrintTo()` function might perform, like it does for Printing `QString` in `EXPECT_EQ()` etc.) – CharonX Sep 12 '18 at 12:00
  • @CharonX When a compiler cannot match an operator, it tells you what the types on the left and right are that it cannot match. Are you looking at some kind of summary view, and not the actual output of the compiler? – Yakk - Adam Nevraumont Sep 12 '18 at 12:37
  • @Yakk-AdamNevraumont I fear adding the entire raw compiler message to the question would be not very productive as it encompasses 132 lines of errors listing the things it tried to use as match, but failed... – CharonX Sep 12 '18 at 15:23

1 Answers1

1

QString does not provide a related non member for streaming insertion, that is the cause of your problem. (the compiler does not find any binary operator function accepting a const QString& as parameter)

See this Question that is related to your problem : Operator << for QString

I guess that you have in your Qt config file

 DEFINES += QT_NO_CAST_TO_ASCII 

that prevents the compiler for converting your QString to a char*

In this case you can write somewhere this global operator

std::ostream & operator<<(std::ostream & stream, const QString & str)
{
    const QByteArray data = str.toUtf8();
    stream << std::string(data.constData(), data.size());
    return stream;
}
sandwood
  • 2,038
  • 20
  • 38
  • Thanks, that is exactly what I was looking for! I can extend the gtest header that contains the PrintTo() extensions for Qt and directly use QStrings with gtest's Macros that invoke `::testing::internal::AssertHelper()` (like `ADD_FAILURE()`) – CharonX Sep 13 '18 at 08:48