mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-03 13:55:39 +02:00
Add --list-listeners option
This commit is contained in:
@@ -111,6 +111,7 @@ namespace Catch {
|
||||
bool Config::listTests() const { return m_data.listTests; }
|
||||
bool Config::listTags() const { return m_data.listTags; }
|
||||
bool Config::listReporters() const { return m_data.listReporters; }
|
||||
bool Config::listListeners() const { return m_data.listListeners; }
|
||||
|
||||
std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
|
||||
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
|
||||
|
@@ -48,6 +48,7 @@ namespace Catch {
|
||||
bool listTests = false;
|
||||
bool listTags = false;
|
||||
bool listReporters = false;
|
||||
bool listListeners = false;
|
||||
|
||||
bool showSuccessfulTests = false;
|
||||
bool shouldDebugBreak = false;
|
||||
@@ -99,6 +100,7 @@ namespace Catch {
|
||||
bool listTests() const;
|
||||
bool listTags() const;
|
||||
bool listReporters() const;
|
||||
bool listListeners() const;
|
||||
|
||||
std::vector<ReporterSpec> const& getReporterSpecs() const;
|
||||
std::vector<ProcessedReporterSpec> const&
|
||||
|
@@ -27,6 +27,7 @@
|
||||
namespace Catch {
|
||||
|
||||
struct ReporterDescription;
|
||||
struct ListenerDescription;
|
||||
struct TagInfo;
|
||||
struct TestCaseInfo;
|
||||
class TestCaseHandle;
|
||||
@@ -249,11 +250,12 @@ namespace Catch {
|
||||
|
||||
//! Writes out information about provided reporters using reporter-specific format
|
||||
virtual void listReporters(std::vector<ReporterDescription> const& descriptions) = 0;
|
||||
//! Writes out the provided listeners descriptions using reporter-specific format
|
||||
virtual void listListeners(std::vector<ListenerDescription> const& descriptions) = 0;
|
||||
//! Writes out information about provided tests using reporter-specific format
|
||||
virtual void listTests(std::vector<TestCaseHandle> const& tests) = 0;
|
||||
//! Writes out information about the provided tags using reporter-specific format
|
||||
virtual void listTags(std::vector<TagInfo> const& tags) = 0;
|
||||
|
||||
};
|
||||
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_unique_ptr.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -34,6 +35,9 @@ namespace Catch {
|
||||
public:
|
||||
virtual ~EventListenerFactory(); // = default
|
||||
virtual IEventListenerPtr create( IConfig const* config ) const = 0;
|
||||
//! Return a meaningful name for the listener, e.g. its type name
|
||||
virtual StringRef getName() const = 0;
|
||||
//! Return listener's description if available
|
||||
virtual std::string getDescription() const = 0;
|
||||
};
|
||||
} // namespace Catch
|
||||
|
@@ -280,7 +280,10 @@ namespace Catch {
|
||||
( "list all/matching tags" )
|
||||
| Opt( config.listReporters )
|
||||
["--list-reporters"]
|
||||
( "list all reporters" )
|
||||
( "list all available reporters" )
|
||||
| Opt( config.listListeners )
|
||||
["--list-listeners"]
|
||||
( "list all listeners" )
|
||||
| Opt( setTestOrder, "decl|lex|rand" )
|
||||
["--order"]
|
||||
( "test case order (defaults to decl)" )
|
||||
|
@@ -63,6 +63,19 @@ namespace Catch {
|
||||
reporter.listReporters(descriptions);
|
||||
}
|
||||
|
||||
void listListeners(IEventListener& reporter) {
|
||||
std::vector<ListenerDescription> descriptions;
|
||||
|
||||
auto const& factories =
|
||||
getRegistryHub().getReporterRegistry().getListeners();
|
||||
descriptions.reserve( factories.size() );
|
||||
for ( auto const& fac : factories ) {
|
||||
descriptions.push_back( { fac->getName(), fac->getDescription() } );
|
||||
}
|
||||
|
||||
reporter.listListeners( descriptions );
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
void TagInfo::add( StringRef spelling ) {
|
||||
@@ -100,6 +113,10 @@ namespace Catch {
|
||||
listed = true;
|
||||
listReporters(reporter);
|
||||
}
|
||||
if ( config.listListeners() ) {
|
||||
listed = true;
|
||||
listListeners( reporter );
|
||||
}
|
||||
return listed;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,10 @@ namespace Catch {
|
||||
struct ReporterDescription {
|
||||
std::string name, description;
|
||||
};
|
||||
struct ListenerDescription {
|
||||
StringRef name;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
struct TagInfo {
|
||||
void add(StringRef spelling);
|
||||
|
@@ -152,6 +152,33 @@ namespace Catch {
|
||||
out << '\n' << std::flush;
|
||||
}
|
||||
|
||||
void defaultListListeners( std::ostream& out,
|
||||
std::vector<ListenerDescription> const& descriptions ) {
|
||||
const auto maxNameLen =
|
||||
std::max_element( descriptions.begin(),
|
||||
descriptions.end(),
|
||||
[]( ListenerDescription const& lhs,
|
||||
ListenerDescription const& rhs ) {
|
||||
return lhs.name.size() < rhs.name.size();
|
||||
} )
|
||||
->name.size();
|
||||
|
||||
out << "Registered listeners:\n";
|
||||
for ( auto const& desc : descriptions ) {
|
||||
out << TextFlow::Column( static_cast<std::string>( desc.name ) +
|
||||
':' )
|
||||
.indent( 2 )
|
||||
.width( maxNameLen + 5 ) +
|
||||
TextFlow::Column( desc.description )
|
||||
.initialIndent( 0 )
|
||||
.indent( 2 )
|
||||
.width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 )
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
out << '\n' << std::flush;
|
||||
}
|
||||
|
||||
void defaultListTags( std::ostream& out,
|
||||
std::vector<TagInfo> const& tags,
|
||||
bool isFiltered ) {
|
||||
@@ -233,6 +260,8 @@ namespace Catch {
|
||||
void EventListenerBase::assertionEnded( AssertionStats const& ) {}
|
||||
void EventListenerBase::listReporters(
|
||||
std::vector<ReporterDescription> const& ) {}
|
||||
void EventListenerBase::listListeners(
|
||||
std::vector<ListenerDescription> const& ) {}
|
||||
void EventListenerBase::listTests( std::vector<TestCaseHandle> const& ) {}
|
||||
void EventListenerBase::listTags( std::vector<TagInfo> const& ) {}
|
||||
void EventListenerBase::noMatchingTestCases( StringRef ) {}
|
||||
|
@@ -29,6 +29,11 @@ namespace Catch {
|
||||
defaultListReporters(m_stream, descriptions, m_config->verbosity());
|
||||
}
|
||||
|
||||
void ReporterBase::listListeners(
|
||||
std::vector<ListenerDescription> const& descriptions ) {
|
||||
defaultListListeners( m_stream, descriptions );
|
||||
}
|
||||
|
||||
void ReporterBase::listTests(std::vector<TestCaseHandle> const& tests) {
|
||||
defaultListTests(m_stream,
|
||||
m_colour.get(),
|
||||
|
@@ -50,6 +50,14 @@ namespace Catch {
|
||||
*/
|
||||
void listReporters(
|
||||
std::vector<ReporterDescription> const& descriptions ) override;
|
||||
/**
|
||||
* Provides a simple default listing of listeners
|
||||
*
|
||||
* Looks similarly to listing of reporters, but with listener type
|
||||
* instead of reporter name.
|
||||
*/
|
||||
void listListeners(
|
||||
std::vector<ListenerDescription> const& descriptions ) override;
|
||||
/**
|
||||
* Provides a simple default listing of tests.
|
||||
*
|
||||
|
@@ -36,6 +36,8 @@ namespace Catch {
|
||||
|
||||
void listReporters(
|
||||
std::vector<ReporterDescription> const& descriptions ) override;
|
||||
void listListeners(
|
||||
std::vector<ListenerDescription> const& descriptions ) override;
|
||||
void listTests( std::vector<TestCaseHandle> const& tests ) override;
|
||||
void listTags( std::vector<TagInfo> const& tagInfos ) override;
|
||||
|
||||
|
@@ -49,6 +49,13 @@ namespace Catch {
|
||||
std::vector<ReporterDescription> const& descriptions,
|
||||
Verbosity verbosity );
|
||||
|
||||
/**
|
||||
* Lists listeners descriptions to the provided stream in user-friendly
|
||||
* format
|
||||
*/
|
||||
void defaultListListeners( std::ostream& out,
|
||||
std::vector<ListenerDescription> const& descriptions );
|
||||
|
||||
/**
|
||||
* Lists tag information to the provided stream in user-friendly format
|
||||
*
|
||||
|
@@ -176,6 +176,13 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
void MultiReporter::listListeners(
|
||||
std::vector<ListenerDescription> const& descriptions ) {
|
||||
for ( auto& reporterish : m_reporterLikes ) {
|
||||
reporterish->listListeners( descriptions );
|
||||
}
|
||||
}
|
||||
|
||||
void MultiReporter::listTests(std::vector<TestCaseHandle> const& tests) {
|
||||
for (auto& reporterish : m_reporterLikes) {
|
||||
reporterish->listTests(tests);
|
||||
|
@@ -60,6 +60,7 @@ namespace Catch {
|
||||
void skipTest( TestCaseInfo const& testInfo ) override;
|
||||
|
||||
void listReporters(std::vector<ReporterDescription> const& descriptions) override;
|
||||
void listListeners(std::vector<ListenerDescription> const& descriptions) override;
|
||||
void listTests(std::vector<TestCaseHandle> const& tests) override;
|
||||
void listTags(std::vector<TagInfo> const& tags) override;
|
||||
|
||||
|
@@ -59,33 +59,36 @@ namespace Catch {
|
||||
class ListenerRegistrar {
|
||||
|
||||
class TypedListenerFactory : public EventListenerFactory {
|
||||
StringRef m_defaultDescription;
|
||||
StringRef m_listenerName;
|
||||
|
||||
std::string getDescriptionImpl( std::true_type ) const {
|
||||
return T::getDescription();
|
||||
}
|
||||
|
||||
std::string getDescriptionImpl( std::false_type ) const {
|
||||
return static_cast<std::string>(m_defaultDescription);
|
||||
return "(No description provided)";
|
||||
}
|
||||
|
||||
public:
|
||||
TypedListenerFactory( StringRef defaultDescription ):
|
||||
m_defaultDescription( defaultDescription ) {}
|
||||
TypedListenerFactory( StringRef listenerName ):
|
||||
m_listenerName( listenerName ) {}
|
||||
|
||||
IEventListenerPtr create( IConfig const* config ) const override {
|
||||
return Detail::make_unique<T>( config );
|
||||
}
|
||||
|
||||
StringRef getName() const override {
|
||||
return m_listenerName;
|
||||
}
|
||||
|
||||
std::string getDescription() const override {
|
||||
return getDescriptionImpl( Detail::has_description<T>{} );
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
ListenerRegistrar(StringRef defaultDescription) {
|
||||
getMutableRegistryHub().registerListener( Detail::make_unique<TypedListenerFactory>(defaultDescription) );
|
||||
ListenerRegistrar(StringRef listenerName) {
|
||||
getMutableRegistryHub().registerListener( Detail::make_unique<TypedListenerFactory>(listenerName) );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user