Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ColoredPrintf in recent googletest

Tags:

c++

googletest

I was using rather obsolete version of GoogleTest and have used hack for custom printing, found here: How to send custom message in Google C++ Testing Framework?

My sources contain the following code from the link above

namespace testing
{
 namespace internal
 {
  enum GTestColor {
      COLOR_DEFAULT,
      COLOR_RED,
      COLOR_GREEN,
      COLOR_YELLOW
  };

  extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
 }
}
#define PRINTF(...)  do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[          ] "); testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } while(0)

I have updated sources of GoogleTest in my project to master version and now I have link errors saying that ColoredPrintf is not defined.

error LNK2019: unresolved external symbol "void __cdecl testing::internal::ColoredPrintf(enum testing::internal::`anonymous namespace'::GTestColor,char const *,...)" (?ColoredPrintf@internal@testing@@YAXW4GTestColor@?A0x313d419f@12@PEBDZZ) referenced in function

Studying fresh gtest.cc shows that they have changed GTestColor to enum class and put it into an anonymous namespace inside the namespace testing::internal: https://github.com/google/googletest/blob/master/googletest/src/gtest.cc#L3138

I've changed the snippet in my sources to:

namespace testing {
    namespace internal
    {
        enum class GTestColor { kDefault, kRed, kGreen, kYellow };

        extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
    }
}

And as a quick fix I have removed namespace { ... } around GTestColor in gtest.cc.

The question: is it possible to avoid editing gtest.cc and still have access to their function?

like image 299
wl2776 Avatar asked Oct 27 '25 04:10

wl2776


2 Answers

You cannot access members in an anonymous namespace outside of the compilation unit. See also this question.

Depending on your use-case alternatives may be:

  • Use event listeners to replace the standard output.
  • Pipe the output through a script that modifies the output.
  • Have Google Test generate an XML or JSON report and generate output based on the XML/JSON report.
like image 98
rveerd Avatar answered Oct 28 '25 18:10

rveerd


I've faced similar issue when switching from gtest built from old sources to a more recent version inside NuGet package, and the trick with modifying gtest.cc isn't possible in this case, because there is no such file in the package distribution.
After some investigation I've finally ended with copy'n'pasted functions from gtest.cc (namely GetColorAttribute, GetBitOffset, GetNewColor and ColoredPrintf), which are then built as a part of my project (don't forget to add #define GTEST_HAS_FILE_SYSTEM 1 at the beginning).
And you'll need an extra header like this one:

namespace testing
{
  namespace internal
  {
    // namespace {
      enum class GTestColor { kDefault, kRed, kGreen, kYellow };
    //}  // namespace

    void ColoredPrintf(GTestColor color, const char* fmt, ...);
    bool ShouldUseColor(bool stdout_is_tty);
  }
}
#define PRINTF(...)  do \
  { \
    testing::internal::ColoredPrintf(testing::internal::GTestColor::kGreen, "[          ] "); \
    testing::internal::ColoredPrintf(testing::internal::GTestColor::kYellow, __VA_ARGS__); \
  } while(0)

static modifier should also be removed from ColoredPrintf definition. The rest of code can be used as is, and it works as expected:
Custom colored output

Hopefully this issue will be properly resolved in the context of FR#4185 :)

like image 39
AntonK Avatar answered Oct 28 '25 17:10

AntonK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!