Catch Unit Test v1.8.1 では、gcc 6.2.0 を使用して、ベクトルをINFO(...)
orに渡すことで、テストが失敗したときにベクトルの内容を便利に出力しようとしていCAPTURE(...)
ます。そのために、ストリーム挿入演算子をオーバーロードしています。
#include <Catch/single_include/catch.hpp>
#include <vector>
#include <iostream>
#define THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
#ifdef THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
namespace std {
#endif
std::ostream& operator<<( std::ostream& os, const std::vector<int>& v ) {
for ( const auto& e : v ) {
os << e << " ";
}
return os;
}
#ifdef THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
} //namespace std
#endif
int some_operation_on_vector( const std::vector<int>& v ) {
return 1;
}
SCENARIO( "some scenario" )
{
GIVEN( "a vector" )
{
const auto the_vector = std::vector<int>{ 1, 2, 3, 4, 5 };
WHEN( "some result is calculated from the vector" )
{
const auto actual_result = some_operation_on_vector( the_vector );
THEN( "the result should be correct. If not, print out the vector." )
{
const auto expected_result = 0;
CAPTURE( the_vector ); // <--------
//^^^^
//How do I legally make this work?
REQUIRE( expected_result == actual_result );
}
}
}
}
上記のように(違法に)名前空間を拡張するstd
と、機能し、目的の出力が表示されます。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
catchtestexample is a Catch v1.8.1 host application.
Run with -? for options
-------------------------------------------------------------------------------
Scenario: some scenario
Given: a vector
When: some result is calculated from the vector
Then: the result should be correct. If not, print out the vector.
-------------------------------------------------------------------------------
ExampleTest.cpp:91
...............................................................................
ExampleTest.cpp:95: FAILED:
REQUIRE( expected_result == actual_result )
with expansion:
0 == 1
with message:
the_vector := 1 2 3 4 5
===============================================================================
test cases: 1 | 1 failed
assertions: 1 | 1 failed
しかし、合法的にしようとするために、operator<<
オーバーロードをstd
名前空間からグローバル名前空間に移動しようとすると ( をコメントアウトすることによって#define THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
)、ベクトルをCAPTURE()
マクロに渡すためにコードがコンパイルされません。
Catch docs に従ってoperator <<
、オーバーロードをオーバーロードに置き換えてみましたCatch::toString
:
#include <string>
#include <sstream>
namespace Catch {
std::string toString( const std::vector<int>& v ) {
std::ostringstream ss;
for ( const auto& e : v ) {
ss << e << " ";
}
return ss.str();
}
}
またはCatch::StringMaker
専門分野で:
#include <string>
#include <sstream>
namespace Catch {
template<> struct StringMaker<std::vector<int>> {
static std::string convert( const std::vector<int>& v ) {
std::ostringstream ss;
for ( const auto& e : v ) {
ss << e << " ";
}
return ss.str();
}
};
}
CAPTURE()
しかし、どちらの場合でも、ベクトルをマクロに渡すため、テストはまだコンパイルされません。
Catch ドキュメントは、operator<<
オーバーロードをあなたの型と同じ名前空間に入れるように言っていますがstd::vector
、私の型ではなく、そのオーバーロードを名前空間に入れることstd
は違法です。
CAPTURE()
しかし、取得(またはINFO()
、または、など) が引数WARN()
を受け入れる唯一の方法は、オーバーロードを不正に namespaceに入れることです。std::vector
operator<<
std
これを行うための適切で合法的な方法はありますか?