mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-17 11:12:25 +01:00
Fix output for different versions of VS
This commit is contained in:
parent
8774268140
commit
f52050c336
@ -192,11 +192,11 @@ namespace CatchOverrides {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct ConfigReset
|
struct ConfigReset
|
||||||
{
|
{
|
||||||
ConfigReset( const std::string& file, int c )
|
ConfigReset( const std::string& file, int c, int defaultAbortAfter )
|
||||||
{
|
{
|
||||||
Config<T>::instance().insertSuccessfulResults(file, c, false);
|
Config<T>::instance().insertSuccessfulResults(file, c, false);
|
||||||
Config<T>::instance().insertMissingAssertions(file, c, false);
|
Config<T>::instance().insertMissingAssertions(file, c, false);
|
||||||
Config<T>::instance().insertAbortAfter(file, c, -1);
|
Config<T>::instance().insertAbortAfter(file, c, defaultAbortAfter);
|
||||||
Config<T>::instance().insertTest(file, c, "");
|
Config<T>::instance().insertTest(file, c, "");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -193,7 +193,7 @@ private:
|
|||||||
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( #Category, Tag, __COUNTER__ )
|
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( #Category, Tag, __COUNTER__ )
|
||||||
|
|
||||||
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST( Category ) \
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST( Category ) \
|
||||||
INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( #Category, __COUNTER__ )
|
INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( #Category, #Category, __COUNTER__ )
|
||||||
|
|
||||||
#define FAIL_STRING( str ) _T( str )
|
#define FAIL_STRING( str ) _T( str )
|
||||||
|
|
||||||
@ -241,8 +241,8 @@ private:
|
|||||||
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG( Category, Tag ) \
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG( Category, Tag ) \
|
||||||
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, __COUNTER__ )
|
INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, __COUNTER__ )
|
||||||
|
|
||||||
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST( Category, List ) \
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST( Category ) \
|
||||||
INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( Category, List, __COUNTER__ )
|
INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( Category, #Category, __COUNTER__ )
|
||||||
|
|
||||||
#define FAIL_STRING( str ) WIDEN( str )
|
#define FAIL_STRING( str ) WIDEN( str )
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ private:
|
|||||||
static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(); \
|
static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(); \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc) ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc) ); \
|
||||||
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, 1); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
@ -314,7 +314,7 @@ private:
|
|||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & QualifiedMethod, "&" # QualifiedMethod, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc), CATCH_INTERNAL_LINEINFO ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & QualifiedMethod, "&" # QualifiedMethod, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(Name), Desc), CATCH_INTERNAL_LINEINFO ); \
|
||||||
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, 1); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
@ -330,7 +330,7 @@ private:
|
|||||||
}; \
|
}; \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )::invoke, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(TestName), Desc) ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )::invoke, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(CATCH_INTERNAL_HANDLE_EMPTY_PARAM(TestName), Desc) ); \
|
||||||
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, 1); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
@ -363,7 +363,7 @@ private:
|
|||||||
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, Count ) \
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_TAG2( Category, Tag, Count ) \
|
||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, -1); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
@ -387,10 +387,10 @@ private:
|
|||||||
}; \
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( Category, Count ) \
|
#define INTERNAL_CATCH_MAP_CATEGORY_TO_LIST2( Category, CategoryName, Count ) \
|
||||||
CHECK_FOR_TEST_CASE_CLASH \
|
CHECK_FOR_TEST_CASE_CLASH \
|
||||||
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
namespace CATCH_INTERNAL_NAMESPACE( INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) { \
|
||||||
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count); \
|
CatchOverrides::ConfigReset<Catch::IConfig const*> INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_O_N_F_I_G___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) )(__FILE__, Count, -1); \
|
||||||
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, INTERNAL_CATCH_CONCAT_LINE_COUNTER( Count ) ) ) \
|
||||||
{ \
|
{ \
|
||||||
INTERNAL_CATCH_CLASS_CONTEXT \
|
INTERNAL_CATCH_CLASS_CONTEXT \
|
||||||
@ -401,7 +401,7 @@ private:
|
|||||||
cd.warnings = (CatchOverrides::Config<Catch::IConfig const*>::instance().warnAboutMissingAssertions(__FILE__, Count ) ? Catch::WarnAbout::NoAssertions : Catch::WarnAbout::Nothing); \
|
cd.warnings = (CatchOverrides::Config<Catch::IConfig const*>::instance().warnAboutMissingAssertions(__FILE__, Count ) ? Catch::WarnAbout::NoAssertions : Catch::WarnAbout::Nothing); \
|
||||||
cd.abortAfter = CatchOverrides::Config<Catch::IConfig const*>::instance().abortAfter(__FILE__, Count ); \
|
cd.abortAfter = CatchOverrides::Config<Catch::IConfig const*>::instance().abortAfter(__FILE__, Count ); \
|
||||||
cd.reporterName = "vs_reporterlf"; \
|
cd.reporterName = "vs_reporterlf"; \
|
||||||
cd.name = "Batch run using category : " Category; \
|
cd.name = "Batch run using category : " CategoryName; \
|
||||||
std::vector<std::string> stringNames = CatchOverrides::Config<Catch::IConfig const*>::instance().listOfTests(__FILE__, Count ); \
|
std::vector<std::string> stringNames = CatchOverrides::Config<Catch::IConfig const*>::instance().listOfTests(__FILE__, Count ); \
|
||||||
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
|
||||||
Catch::ReporterRegistrar<Catch::MSTestReporterLineFeed> reporterReg("vs_reporterlf"); \
|
Catch::ReporterRegistrar<Catch::MSTestReporterLineFeed> reporterReg("vs_reporterlf"); \
|
||||||
|
@ -119,7 +119,11 @@ namespace Catch {
|
|||||||
: VSStreamingReporterBase( _config ),
|
: VSStreamingReporterBase( _config ),
|
||||||
m_prevCout( std::cout.rdbuf() ),
|
m_prevCout( std::cout.rdbuf() ),
|
||||||
m_prevCerr( std::cerr.rdbuf() ),
|
m_prevCerr( std::cerr.rdbuf() ),
|
||||||
|
#if defined(INTERNAL_CATCH_VS_NATIVE) || _MSC_VER >= 1700
|
||||||
|
m_addLineFeeds(false),
|
||||||
|
#else
|
||||||
m_addLineFeeds(true),
|
m_addLineFeeds(true),
|
||||||
|
#endif
|
||||||
m_headerPrinted( false ),
|
m_headerPrinted( false ),
|
||||||
m_atLeastOneTestCasePrinted( false )
|
m_atLeastOneTestCasePrinted( false )
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,14 @@
|
|||||||
|
|
||||||
namespace AllTestsRunner {
|
namespace AllTestsRunner {
|
||||||
|
|
||||||
|
// VS2010
|
||||||
// mstest /TestContainer:Debug\ManagedTestCatch.dll /category:"all"
|
// mstest /TestContainer:Debug\ManagedTestCatch.dll /category:"all"
|
||||||
|
//
|
||||||
|
// VS2012 managed
|
||||||
|
// vstest.console.exe /Logger:Trx Debug\ManagedTestCatch.dll /TestCaseFilter:"TestCategory=all"
|
||||||
|
//
|
||||||
|
// VS2012 native
|
||||||
|
// vstest.console.exe /Logger:Trx Debug\NativeTestCatch.dll /TestCaseFilter:"Owner=all"
|
||||||
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
|
||||||
CATCH_MAP_CATEGORY_TO_TAG(all, "~[vs]");
|
CATCH_MAP_CATEGORY_TO_TAG(all, "~[vs]");
|
||||||
|
|
||||||
|
@ -22,8 +22,13 @@ if len(sys.argv) == 2:
|
|||||||
else:
|
else:
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
cmdPath = os.path.join( catchPath, 'projects\\VS2010\\TestCatch\\Release\\TestCatch.exe' )
|
cmdPath = os.path.join( catchPath, 'projects\\VS2010\\TestCatch\\Release\\TestCatch.exe' )
|
||||||
|
# VS2010
|
||||||
#dllPath = os.path.join( catchPath, 'projects\\VS2010\\ManagedTestCatch\\Release\\ManagedTestCatch.dll' )
|
#dllPath = os.path.join( catchPath, 'projects\\VS2010\\ManagedTestCatch\\Release\\ManagedTestCatch.dll' )
|
||||||
dllPath = os.path.join( catchPath, 'projects\\VS2010\\ManagedTestCatch\\Debug\\ManagedTestCatch.dll' )
|
dllPath = os.path.join( catchPath, 'projects\\VS2010\\ManagedTestCatch\\Debug\\ManagedTestCatch.dll' )
|
||||||
|
# VS2012 managed
|
||||||
|
#dllPath = os.path.join( catchPath, 'projects\\VS2012\\ManagedTestCatch\\Debug\\ManagedTestCatch.dll' )
|
||||||
|
# VS2012 native
|
||||||
|
#dllPath = os.path.join( catchPath, 'projects\\VS2012\\NativeTestCatch\\Debug\\NativeTestCatch.dll' )
|
||||||
else:
|
else:
|
||||||
cmdPath = os.path.join( catchPath, 'projects/XCode4/CatchSelfTest/DerivedData/CatchSelfTest/Build/Products/Debug/CatchSelfTest' )
|
cmdPath = os.path.join( catchPath, 'projects/XCode4/CatchSelfTest/DerivedData/CatchSelfTest/Build/Products/Debug/CatchSelfTest' )
|
||||||
|
|
||||||
@ -705,9 +710,24 @@ def approveMsTest( baseName, filter ):
|
|||||||
raise Exception("Managed DLL does not exist: '" + dllPath + "'")
|
raise Exception("Managed DLL does not exist: '" + dllPath + "'")
|
||||||
|
|
||||||
args = []
|
args = []
|
||||||
|
# Options for VS2010
|
||||||
args.append("MSTest.exe")
|
args.append("MSTest.exe")
|
||||||
args.append("/testcontainer:" + dllPath)
|
args.append("/testcontainer:" + dllPath)
|
||||||
args.append("/category:\"" + filter + "\"")
|
args.append("/category:\"" + filter + "\"")
|
||||||
|
|
||||||
|
# Options for VS2012 managed
|
||||||
|
#args.append("vstest.console.exe")
|
||||||
|
#args.append("/Logger:Trx")
|
||||||
|
#args.append(dllPath)
|
||||||
|
#args.append("/TestCaseFilter:TestCategory=" + filter)
|
||||||
|
|
||||||
|
# Options for VS2012 native
|
||||||
|
#args.append("vstest.console.exe")
|
||||||
|
#args.append("/Logger:Trx")
|
||||||
|
#args.append(dllPath)
|
||||||
|
#args.append("/TestCaseFilter:Owner=" + filter)
|
||||||
|
|
||||||
|
#print args
|
||||||
f = open( rawResultsPath, 'w' )
|
f = open( rawResultsPath, 'w' )
|
||||||
subprocess.call( args, stdout=f, stderr=f )
|
subprocess.call( args, stdout=f, stderr=f )
|
||||||
f.close()
|
f.close()
|
||||||
@ -715,9 +735,7 @@ def approveMsTest( baseName, filter ):
|
|||||||
if os.path.exists( rawResultsPath ):
|
if os.path.exists( rawResultsPath ):
|
||||||
f = open( rawResultsPath, 'r' )
|
f = open( rawResultsPath, 'r' )
|
||||||
for line in f:
|
for line in f:
|
||||||
#line = "Results file: c:\Projects\Catch\TestResults\NoyesMa_SACHDEW7 2013-12-09 11_43_57.trx"
|
if line.startswith("Results file:") or line.startswith("Results File:"):
|
||||||
|
|
||||||
if line.startswith("Results file:"):
|
|
||||||
trxFile = line[13:].strip()
|
trxFile = line[13:].strip()
|
||||||
parseTrxFile(baseName, trxFile)
|
parseTrxFile(baseName, trxFile)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user