stringizers
#
Adding Custom StringizersNOTE: code snippets in this article omit #include
directives for brevity. You must remember to include the required header files!
[unsupported type]
displayed in assertion messages#
C++ kata currently use the Igloo testing framework with the Snowhouse assertion library to run kata tests and verify test results. Known headaches related to Snowhouse is that it sometimes produces very unhelpful assertion messages:
Such a situation occurs when your tests perform some assertions on types which have not defined the operation of stringification, which could be used by the Snowhouse framework to conveniently compose the assertion message:
Type Point1d
cannot be stringified, so the assertion message displayed in the test output panel is very confusing:
A similar thing happens when an assertion verifies collections (for example std::vector
) of such types. While the std::vector
template itself can be stringified, elements stored inside might not:
Test output:
Not only your custom types can be affected by this issue. Snowhouse may be not able to stringify many built-in, standard, or 3rd party types. Basically, every type which does not define its version of the output stream operator (operator <<
) is affected, and the std::pair
template is a very common case of such types for Codewars kata.
#
SolutionsTo make a stringification of unsupported types possible, you have to provide one (or both) of code snippets: definition of operator <<
for your type, or specialization of snowhouse::Stringizer<T>
template. Snippets should be located just where your custom types are, usually in Preloaded.
operator <<
#
Stringification with operator <<
is the easiest option to provide stringification, but it can be used only with types you control. You can add operator <<
for types you created for the kata, but not for 3rd party, external, or standard types, like for example std::pair
. For them, you have to use specialized Stringizer<T>
(see below).
Definition of operator <<
for Snowhouse does not differ from the implementation of any other output stream operator for C++ types:
Such definition allows your custom type to now be displayed properly, even if it's an element of a container:
Now your custom types are displayed properly in assertion messages:
Stringizer<T>
#
Stringification with Sometimes, the definition of operator <<
cannot be used for stringification. You cannot add it to types which you do not own and you cannot re-define it for types which already have it defined, but not in a way you'd like to. Or maybe you just prefer this way rather than operator <<
. In such cases, Snowhouse allows you to use a snowhouse::Stringizer<T>
template specialized for the type you want to stringify.
This way you get meaningful output for types which were unsupported:
This way you can also create a universal template which would solve many issues with Codewars kata: a stringizer for any pair!
You can get meaningful assertion messages for any std::pair<F, T>
, as long as types F
and T
can also be stringified, what is usually the case for Codewars kata:
#
Additional info- Getting better output for your types in Snowhouse repository.
- Kumite which illustrates how to use stringification in a kata.