template<class T>
Comparator class
Default comparator implementation.
Contents
See CORRADE_
Subclassing
You can reimplement this class for your own data types and even pseudo types for providing different ways to compare the same type.
You have to implement operator()()
for comparison of two values with arbitrary type and printErrorMessage()
for printing error message when the comparison failed. The reason for having those two separated is allowing the user to use colored output — due to a limitation of Windows console API, where it's only possible to specify text color when writing directly to the output without any intermediate buffer.
Comparing with pseudo-types
Imagine you have two filenames and you want to compare their contents instead of comparing the filename strings. Because you want to also compare strings elsewhere, you cannot override its behavior. The solution is to have some "pseudo type", for which you create the Comparator template specialization, but the actual comparison operator will still take strings as parameters:
class FileContents {}; namespace Corrade { namespace TestSuite { // the namespace is important template<> class Comparator<FileContents> { public: bool operator()(const std::string& actual, const std::string& expected) { _actualContents = ...; _expectedContents = ...; return _actualContents == _expectedContents; } void printErrorMessage(Utility::Error& e, const std::string& actual, const std::string& expected) const { e << "Files" << actual << "and" << expected << "are not the same, actual" << _actualContents << "but expected" << _expectedContents; } private: std::string _actualContents, _expectedContents; }; }}
You can add more overloads for operator()()
in one class, e.g. for comparing file contents with string or input stream etc. The actual use in unit test would be like this:
CORRADE_COMPARE_AS("/path/to/actual.dat", "/path/to/expected.dat", FileContents);
Passing parameters to comparators
Sometimes you need to pass additional parameters to comparator class so you can then use it in CORRADE_comparator()
function in your pseudo-type. Function comparator()
returns reference to existing configured Comparator instance. Example:
class FileContents; namespace Corrade { namespace TestSuite { // the namespace is important template<> class Comparator<FileContents> { public: Comparator(const std::string& pathPrefix = {}); bool operator()(const std::string& actual, const std::string& expected); void printErrorMessage(Utility::Error& e, const std::string& actual, const std::string& expected) const; // ... }; }} class FileContents { public: explicit FileContents(const std::string& pathPrefix = {}): _c{pathPrefix} {} Comparator<FileContents>& comparator() { return _c; } private: Comparator<FileContents> _c; };
Don't forget to allow default construction of Comparator, if you want to be able to use it also with CORRADE_
The actual use in unit test would be like this:
CORRADE_COMPARE_WITH("actual.dat", "expected.dat", FileContents{"/common/path/prefix"});
Public functions
- auto operator()(const T& actual, const T& expected) -> bool
- Compare two values.
-
void printErrorMessage(Utility::
Error& e, const std:: string& actual, const std:: string& expected) const - Print error message, assuming the two values are inequal.