1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-01-16 15:18:00 +00:00

Compare commits

...

8 Commits

Author SHA1 Message Date
Martin Hořeňovský
c26693df23
Fix doccomment on shouldShowDuration reporter helper 2020-08-29 19:55:17 +02:00
Martin Hořeňovský
33ad1ee2ac
Split EventListener base from streaming_base.hpp
The base was also renamed from `TestEventListenerBase` to
`EventListenerBase`, and modified to derive directly from the
reporter interface, rather than deriving from `StreamingReporterBase`.
2020-08-29 19:09:54 +02:00
Martin Hořeňovský
f9fdc96cbf
Push LazyStat down into catch_reporter_streaming_base.hpp 2020-08-24 11:27:21 +02:00
Martin Hořeňovský
360b82620e
Refactor serializeFilters implementation 2020-08-24 10:19:26 +02:00
Martin Hořeňovský
2a8e317cfb
Split various reporter helpers out from streaming_base.hpp
Due to also adding a new TU, there is no improvement to the
compilation times of the static library, but it improves the
compilation times of consumer's reporter TUs.
2020-08-24 10:19:24 +02:00
Martin Hořeňovský
6a08d401aa
Split out ReporterFactory out of catch_interfaces_reporter.hpp 2020-08-23 22:35:01 +02:00
Martin Hořeňovský
9677df6d8b
Split IReporterRegistry into its own header file
Doing this removes `<map>` from the include set of the base reporter
interface, and thus from bunch more TUs. This provides about 1.5%
improvements in the debug build of the static library, and 1% in
release build.
2020-08-23 21:01:04 +02:00
Martin Hořeňovský
ed7eaf2df3
Split catch_reporter_bases.hpp into two separate headers
Each of the two reporter bases now has its own header file, and
cpp file. Even though this adds another TU to the compilation,
the total CPU time taken by compilation is reduced by about 1%
for debug build and ~0.5% for optimized build of the main library.
(The improvement would be roughly doubles without splitting the TUs,
but the maintainability hit is not worth it.)

The code size of the static library build has also somewhat decreased.

Follow up: Introduce combined TU for reporters, and further split
apart the catch_reporter_streaming_base.hpp header into its
constituent parts, as it still contains a whole bunch of other stuff.
2020-08-23 07:30:26 +02:00
39 changed files with 486 additions and 319 deletions

View File

@ -114,6 +114,9 @@ new design.
* You should instead include the appropriate headers as needed.
* `CATCH_CONFIG_IMPL` has been removed.
* The implementation is now compiled into a static library.
* Event Listener interface has changed
* `TestEventListenerBase` was renamed to `EventListenerBase`
* `EventListenerBase` now directly derives from `IStreamingReporter`, instead of deriving from `StreamingReporterBase`

View File

@ -6,7 +6,7 @@
// 3. Test cases
#include <catch2/catch_test_macros.hpp>
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/catch_reporter_registrars.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <iostream>
@ -303,9 +303,9 @@ char const * dashed_line =
"--------------------------------------------------------------------------";
struct MyListener : Catch::TestEventListenerBase {
struct MyListener : Catch::EventListenerBase {
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
using EventListenerBase::EventListenerBase; // inherit constructor
// Get rid of Wweak-tables
~MyListener();

View File

@ -72,6 +72,8 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/interfaces/catch_interfaces_generatortracker.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_registry_hub.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_factory.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_registry.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_runner.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_tag_alias_registry.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_testcase.hpp
@ -193,24 +195,29 @@ set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
set(REPORTER_HEADERS
${SOURCES_DIR}/reporters/catch_reporters_all.hpp
${SOURCES_DIR}/reporters/catch_reporter_automake.hpp
${SOURCES_DIR}/reporters/catch_reporter_bases.hpp
${SOURCES_DIR}/reporters/catch_reporter_compact.hpp
${SOURCES_DIR}/reporters/catch_reporter_console.hpp
${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.hpp
${SOURCES_DIR}/reporters/catch_reporter_event_listener.hpp
${SOURCES_DIR}/reporters/catch_reporter_helpers.hpp
${SOURCES_DIR}/reporters/catch_reporter_junit.hpp
${SOURCES_DIR}/reporters/catch_reporter_listening.hpp
${SOURCES_DIR}/reporters/catch_reporter_sonarqube.hpp
${SOURCES_DIR}/reporters/catch_reporter_streaming_base.hpp
${SOURCES_DIR}/reporters/catch_reporter_tap.hpp
${SOURCES_DIR}/reporters/catch_reporter_teamcity.hpp
${SOURCES_DIR}/reporters/catch_reporter_xml.hpp
)
set(REPORTER_SOURCES
${SOURCES_DIR}/reporters/catch_reporter_automake.cpp
${SOURCES_DIR}/reporters/catch_reporter_bases.cpp
${SOURCES_DIR}/reporters/catch_reporter_combined_tu.cpp
${SOURCES_DIR}/reporters/catch_reporter_compact.cpp
${SOURCES_DIR}/reporters/catch_reporter_console.cpp
${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_junit.cpp
${SOURCES_DIR}/reporters/catch_reporter_listening.cpp
${SOURCES_DIR}/reporters/catch_reporter_sonarqube.cpp
${SOURCES_DIR}/reporters/catch_reporter_streaming_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_tap.cpp
${SOURCES_DIR}/reporters/catch_reporter_teamcity.cpp
${SOURCES_DIR}/reporters/catch_reporter_xml.cpp

View File

@ -19,6 +19,7 @@
#include <catch2/internal/catch_enum_values_registry.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/internal/catch_noncopyable.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
namespace Catch {

View File

@ -10,6 +10,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
namespace Catch {

View File

@ -19,6 +19,8 @@
#include <catch2/internal/catch_textflow.hpp>
#include <catch2/internal/catch_windows_h_proxy.hpp>
#include <catch2/reporters/catch_reporter_listening.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <algorithm>
#include <iomanip>

View File

@ -22,6 +22,8 @@
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_runner.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>

View File

@ -77,3 +77,16 @@ namespace Catch {
ITestInvoker::~ITestInvoker() = default;
ITestCaseRegistry::~ITestCaseRegistry() = default;
}
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
namespace Catch {
IReporterRegistry::~IReporterRegistry() = default;
}
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
namespace Catch {
IReporterFactory::~IReporterFactory() = default;
}

View File

@ -186,7 +186,4 @@ namespace Catch {
Catch::cout() << pluralise(tags.size(), "tag") << '\n' << std::endl;
}
IReporterFactory::~IReporterFactory() = default;
IReporterRegistry::~IReporterRegistry() = default;
} // end namespace Catch

View File

@ -13,7 +13,6 @@
#include <catch2/catch_totals.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/internal/catch_message_info.hpp>
#include <catch2/internal/catch_option.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
@ -24,7 +23,6 @@
#include <string>
#include <vector>
#include <iosfwd>
#include <map>
namespace Catch {
@ -33,7 +31,6 @@ namespace Catch {
struct TestCaseInfo;
class TestCaseHandle;
struct IConfig;
class Config;
struct ReporterConfig {
explicit ReporterConfig( IConfig const* _fullConfig );
@ -48,20 +45,6 @@ namespace Catch {
IConfig const* m_fullConfig;
};
template<typename T>
struct LazyStat : Option<T> {
LazyStat& operator=( T const& _value ) {
Option<T>::operator=( _value );
used = false;
return *this;
}
void reset() {
Option<T>::reset();
used = false;
}
bool used = false;
};
struct TestRunInfo {
TestRunInfo( std::string const& _name );
std::string name;
@ -244,23 +227,6 @@ namespace Catch {
};
using IStreamingReporterPtr = Detail::unique_ptr<IStreamingReporter>;
struct IReporterFactory {
virtual ~IReporterFactory();
virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0;
};
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct IReporterRegistry {
using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
using Listeners = std::vector<IReporterFactoryPtr>;
virtual ~IReporterRegistry();
virtual IStreamingReporterPtr create( std::string const& name, IConfig const* config ) const = 0;
virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED

View File

@ -0,0 +1,18 @@
#ifndef CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED
namespace Catch {
struct ReporterConfig;
struct IReporterFactory {
virtual ~IReporterFactory(); // = default
virtual IStreamingReporterPtr
create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0;
};
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
} // namespace Catch
#endif // CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED

View File

@ -0,0 +1,31 @@
#ifndef CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
#define CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <vector>
#include <map>
namespace Catch {
struct IConfig;
struct IStreamingReporter;
using IStreamingReporterPtr = Detail::unique_ptr<IStreamingReporter>;
struct IReporterFactory;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct IReporterRegistry {
using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
using Listeners = std::vector<IReporterFactoryPtr>;
virtual ~IReporterRegistry();
virtual IStreamingReporterPtr create( std::string const& name, IConfig const* config ) const = 0;
virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0;
};
} // end namespace Catch
#endif // CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED

View File

@ -11,6 +11,7 @@
#include <catch2/catch_config.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <fstream>

View File

@ -10,7 +10,9 @@
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/catch_config.hpp>

View File

@ -9,6 +9,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_H_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <map>

View File

@ -17,6 +17,7 @@
#include <catch2/internal/catch_test_case_tracker.hpp>
#include <catch2/catch_assertion_info.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/internal/catch_option.hpp>
#include <string>

View File

@ -5,7 +5,7 @@
#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
namespace Catch {

View File

@ -1,169 +0,0 @@
/*
* Created by Phil on 27/11/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
namespace Catch {
// Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration );
//! Should the reporter show
bool shouldShowDuration( IConfig const& config, double duration );
std::string serializeFilters( std::vector<std::string> const& container );
struct StreamingReporterBase : IStreamingReporter {
StreamingReporterBase( ReporterConfig const& _config ):
m_config( _config.fullConfig() ), stream( _config.stream() ) {
}
~StreamingReporterBase() override;
void noMatchingTestCases(std::string const&) override {}
void reportInvalidArguments(std::string const&) override {}
void testRunStarting(TestRunInfo const& _testRunInfo) override {
currentTestRunInfo = _testRunInfo;
}
void testGroupStarting(GroupInfo const& _groupInfo) override {
currentGroupInfo = _groupInfo;
}
void testCaseStarting(TestCaseInfo const& _testInfo) override {
currentTestCaseInfo = &_testInfo;
}
void sectionStarting(SectionInfo const& _sectionInfo) override {
m_sectionStack.push_back(_sectionInfo);
}
void sectionEnded(SectionStats const& /* _sectionStats */) override {
m_sectionStack.pop_back();
}
void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
currentTestCaseInfo = nullptr;
}
void testGroupEnded( TestGroupStats const& ) override;
void testRunEnded( TestRunStats const& /* _testRunStats */ ) override;
void skipTest(TestCaseInfo const&) override {
// Don't do anything with this by default.
// It can optionally be overridden in the derived class.
}
IConfig const* m_config;
std::ostream& stream;
LazyStat<TestRunInfo> currentTestRunInfo;
LazyStat<GroupInfo> currentGroupInfo;
TestCaseInfo const* currentTestCaseInfo = nullptr;
std::vector<SectionInfo> m_sectionStack;
};
struct CumulativeReporterBase : IStreamingReporter {
template<typename T, typename ChildNodeT>
struct Node {
explicit Node( T const& _value ) : value( _value ) {}
virtual ~Node() {}
using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
T value;
ChildNodes children;
};
struct SectionNode {
explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
bool operator == (SectionNode const& other) const {
return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
}
SectionStats stats;
using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
using Assertions = std::vector<AssertionStats>;
ChildSections childSections;
Assertions assertions;
std::string stdOut;
std::string stdErr;
};
using TestCaseNode = Node<TestCaseStats, SectionNode>;
using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
using TestRunNode = Node<TestRunStats, TestGroupNode>;
CumulativeReporterBase( ReporterConfig const& _config ):
m_config( _config.fullConfig() ), stream( _config.stream() ) {}
~CumulativeReporterBase() override;
void testRunStarting( TestRunInfo const& ) override {}
void testGroupStarting( GroupInfo const& ) override {}
void testCaseStarting( TestCaseInfo const& ) override {}
void sectionStarting( SectionInfo const& sectionInfo ) override;
void assertionStarting( AssertionInfo const& ) override {}
bool assertionEnded( AssertionStats const& assertionStats ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
virtual void testRunEndedCumulative() = 0;
void skipTest(TestCaseInfo const&) override {}
IConfig const* m_config;
std::ostream& stream;
std::vector<AssertionStats> m_assertions;
std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
std::shared_ptr<SectionNode> m_rootSection;
std::shared_ptr<SectionNode> m_deepestSection;
std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
};
struct lineOfChars {
char c;
constexpr lineOfChars(char c):
c(c)
{}
friend std::ostream& operator<< (std::ostream& out, lineOfChars value);
};
struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBase( ReporterConfig const& _config );
void assertionStarting(AssertionInfo const&) override;
bool assertionEnded(AssertionStats const&) override;
// Event listeners should not use the default listing impl
void listReporters(std::vector<ReporterDescription> const&, IConfig const&) override {}
void listTests(std::vector<TestCaseHandle> const&, IConfig const&) override {}
void listTags(std::vector<TagInfo> const&, IConfig const&) override {}
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED

View File

@ -0,0 +1,113 @@
/** \file
* This is a special TU that combines what would otherwise be a very
* small reporter-related TUs into one bigger TU.
*
* The reason for this is compilation performance improvements by
* avoiding reparsing headers for many small TUs, instead having this
* one TU include bit more, but having it all parsed only once.
*
* To avoid heavy-tail problem with compilation times, each "subpart"
* of Catch2 has its own combined TU like this.
*/
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_console_width.hpp>
#include <catch2/internal/catch_errno_guard.hpp>
#include <cfloat>
#include <cstdio>
#include <ostream>
namespace Catch {
// Because formatting using c++ streams is stateful, drop down to C is
// required Alternatively we could use stringstream, but its performance
// is... not good.
std::string getFormattedDuration( double duration ) {
// Max exponent + 1 is required to represent the whole part
// + 1 for decimal point
// + 3 for the 3 decimal places
// + 1 for null terminator
const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
// Save previous errno, to prevent sprintf from overwriting it
ErrnoGuard guard;
#ifdef _MSC_VER
sprintf_s( buffer, "%.3f", duration );
#else
std::sprintf( buffer, "%.3f", duration );
#endif
return std::string( buffer );
}
bool shouldShowDuration( IConfig const& config, double duration ) {
if ( config.showDurations() == ShowDurations::Always ) {
return true;
}
if ( config.showDurations() == ShowDurations::Never ) {
return false;
}
const double min = config.minDuration();
return min >= 0 && duration >= min;
}
std::string serializeFilters( std::vector<std::string> const& filters ) {
// We add a ' ' separator between each filter
size_t serialized_size = filters.size() - 1;
for (auto const& filter : filters) {
serialized_size += filter.size();
}
std::string serialized;
serialized.reserve(serialized_size);
bool first = true;
for (auto const& filter : filters) {
if (!first) {
serialized.push_back(' ');
}
first = false;
serialized.append(filter);
}
return serialized;
}
std::ostream& operator<<( std::ostream& out, lineOfChars value ) {
for ( size_t idx = 0; idx < CATCH_CONFIG_CONSOLE_WIDTH - 1; ++idx ) {
out.put( value.c );
}
return out;
}
} // namespace Catch
#include <catch2/reporters/catch_reporter_event_listener.hpp>
namespace Catch {
void EventListenerBase::assertionStarting( AssertionInfo const& ) {}
bool EventListenerBase::assertionEnded( AssertionStats const& ) {
return false;
}
void
EventListenerBase::listReporters( std::vector<ReporterDescription> const&,
IConfig const& ) {}
void EventListenerBase::listTests( std::vector<TestCaseHandle> const&,
IConfig const& ) {}
void EventListenerBase::listTags( std::vector<TagInfo> const&,
IConfig const& ) {}
void EventListenerBase::noMatchingTestCases( std::string const& ) {}
void EventListenerBase::testRunStarting( TestRunInfo const& ) {}
void EventListenerBase::testGroupStarting( GroupInfo const& ) {}
void EventListenerBase::testCaseStarting( TestCaseInfo const& ) {}
void EventListenerBase::sectionStarting( SectionInfo const& ) {}
void EventListenerBase::sectionEnded( SectionStats const& ) {}
void EventListenerBase::testCaseEnded( TestCaseStats const& ) {}
void EventListenerBase::testGroupEnded( TestGroupStats const& ) {}
void EventListenerBase::testRunEnded( TestRunStats const& ) {}
void EventListenerBase::skipTest( TestCaseInfo const& ) {}
} // namespace Catch

View File

@ -7,6 +7,7 @@
#include <catch2/reporters/catch_reporter_compact.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_console_colour.hpp>

View File

@ -9,7 +9,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_H_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
namespace Catch {

View File

@ -18,6 +18,7 @@
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/internal/catch_console_width.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <cfloat>
#include <cstdio>

View File

@ -8,7 +8,7 @@
#ifndef TWOBLUECUBES_CATCH_REPORTER_CONSOLE_H_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_H_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#if defined(_MSC_VER)

View File

@ -1,23 +1,6 @@
/*
* Created by Phil on 27/11/2013.
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_console_width.hpp>
#include <catch2/internal/catch_errno_guard.hpp>
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/internal/catch_stream.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/reporters/catch_reporter_cumulative_base.hpp>
#include <algorithm>
#include <cstring>
#include <cfloat>
#include <cstdio>
#include <ostream>
#include <cassert>
namespace Catch {
@ -44,74 +27,6 @@ namespace Catch {
}
} // namespace
// Because formatting using c++ streams is stateful, drop down to C is required
// Alternatively we could use stringstream, but its performance is... not good.
std::string getFormattedDuration( double duration ) {
// Max exponent + 1 is required to represent the whole part
// + 1 for decimal point
// + 3 for the 3 decimal places
// + 1 for null terminator
const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
char buffer[maxDoubleSize];
// Save previous errno, to prevent sprintf from overwriting it
ErrnoGuard guard;
#ifdef _MSC_VER
sprintf_s(buffer, "%.3f", duration);
#else
std::sprintf(buffer, "%.3f", duration);
#endif
return std::string(buffer);
}
bool shouldShowDuration( IConfig const& config, double duration ) {
if ( config.showDurations() == ShowDurations::Always ) {
return true;
}
if ( config.showDurations() == ShowDurations::Never ) {
return false;
}
const double min = config.minDuration();
return min >= 0 && duration >= min;
}
std::string serializeFilters( std::vector<std::string> const& container ) {
ReusableStringStream oss;
bool first = true;
for (auto&& filter : container)
{
if (!first)
oss << ' ';
else
first = false;
oss << filter;
}
return oss.str();
}
TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
:StreamingReporterBase(_config) {}
void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
return false;
}
StreamingReporterBase::~StreamingReporterBase() = default;
void StreamingReporterBase::testGroupEnded( TestGroupStats const& ) {
currentGroupInfo.reset();
}
void StreamingReporterBase::testRunEnded( TestRunStats const& ) {
currentTestCaseInfo = nullptr;
currentGroupInfo.reset();
currentTestRunInfo.reset();
}
CumulativeReporterBase::~CumulativeReporterBase() = default;
@ -189,12 +104,4 @@ namespace Catch {
testRunEndedCumulative();
}
std::ostream& operator<<(std::ostream& out, lineOfChars value) {
for (size_t idx = 0; idx < CATCH_CONFIG_CONSOLE_WIDTH - 1; ++idx) {
out.put(value.c);
}
return out;
}
} // end namespace Catch

View File

@ -0,0 +1,82 @@
#ifndef CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
#define CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
namespace Catch {
struct CumulativeReporterBase : IStreamingReporter {
template<typename T, typename ChildNodeT>
struct Node {
explicit Node( T const& _value ) : value( _value ) {}
virtual ~Node() {}
using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
T value;
ChildNodes children;
};
struct SectionNode {
explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
bool operator == (SectionNode const& other) const {
return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
}
SectionStats stats;
using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
using Assertions = std::vector<AssertionStats>;
ChildSections childSections;
Assertions assertions;
std::string stdOut;
std::string stdErr;
};
using TestCaseNode = Node<TestCaseStats, SectionNode>;
using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
using TestRunNode = Node<TestRunStats, TestGroupNode>;
CumulativeReporterBase( ReporterConfig const& _config ):
m_config( _config.fullConfig() ), stream( _config.stream() ) {}
~CumulativeReporterBase() override;
void testRunStarting( TestRunInfo const& ) override {}
void testGroupStarting( GroupInfo const& ) override {}
void testCaseStarting( TestCaseInfo const& ) override {}
void sectionStarting( SectionInfo const& sectionInfo ) override;
void assertionStarting( AssertionInfo const& ) override {}
bool assertionEnded( AssertionStats const& assertionStats ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
virtual void testRunEndedCumulative() = 0;
void skipTest(TestCaseInfo const&) override {}
IConfig const* m_config;
std::ostream& stream;
std::vector<AssertionStats> m_assertions;
std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
std::shared_ptr<SectionNode> m_rootSection;
std::shared_ptr<SectionNode> m_deepestSection;
std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
};
} // end namespace Catch
#endif // CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED

View File

@ -0,0 +1,47 @@
#ifndef CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
#define CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
namespace Catch {
/**
* Base class identifying listeners.
*
* Provides default implementation for all IStreamingReporter member
* functions, so that listeners implementations can pick which
* member functions it actually cares about.
*/
class EventListenerBase : public IStreamingReporter {
IConfig const* m_config;
public:
EventListenerBase( ReporterConfig const& config ):
m_config( config.fullConfig() ) {}
void assertionStarting( AssertionInfo const& assertionInfo ) override;
bool assertionEnded( AssertionStats const& assertionStats ) override;
void
listReporters( std::vector<ReporterDescription> const& descriptions,
IConfig const& config ) override;
void listTests( std::vector<TestCaseHandle> const& tests,
IConfig const& config ) override;
void listTags( std::vector<TagInfo> const& tagInfos,
IConfig const& config ) override;
void noMatchingTestCases( std::string const& spec ) override;
void testRunStarting( TestRunInfo const& testRunInfo ) override;
void testGroupStarting( GroupInfo const& groupInfo ) override;
void testCaseStarting( TestCaseInfo const& testInfo ) override;
void sectionStarting( SectionInfo const& sectionInfo ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
void skipTest( TestCaseInfo const& testInfo ) override;
};
} // end namespace Catch
#endif // CATCH_REPORTER_EVENT_LISTENER_HPP_INCLUDED

View File

@ -0,0 +1,29 @@
#ifndef CATCH_REPORTER_HELPERS_HPP_INCLUDED
#define CATCH_REPORTER_HELPERS_HPP_INCLUDED
#include <iosfwd>
#include <string>
#include <vector>
namespace Catch {
struct IConfig;
// Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration );
//! Should the reporter show duration of test given current configuration?
bool shouldShowDuration( IConfig const& config, double duration );
std::string serializeFilters( std::vector<std::string> const& filters );
struct lineOfChars {
char c;
constexpr lineOfChars( char c ): c( c ) {}
friend std::ostream& operator<<( std::ostream& out, lineOfChars value );
};
} // end namespace Catch
#endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED

View File

@ -6,10 +6,9 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_junit.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/catch_tostring.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_textflow.hpp>

View File

@ -8,7 +8,7 @@
#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_cumulative_base.hpp>
#include <catch2/internal/catch_xmlwriter.hpp>
#include <catch2/catch_timer.hpp>

View File

@ -5,7 +5,7 @@
#ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_cumulative_base.hpp>
#include <catch2/internal/catch_xmlwriter.hpp>

View File

@ -0,0 +1,27 @@
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
namespace Catch {
StreamingReporterBase::~StreamingReporterBase() = default;
void
StreamingReporterBase::testRunStarting( TestRunInfo const& _testRunInfo ) {
currentTestRunInfo = _testRunInfo;
}
void
StreamingReporterBase::testGroupStarting( GroupInfo const& _groupInfo ) {
currentGroupInfo = _groupInfo;
}
void StreamingReporterBase::testGroupEnded( TestGroupStats const& ) {
currentGroupInfo.reset();
}
void StreamingReporterBase::testRunEnded( TestRunStats const& ) {
currentTestCaseInfo = nullptr;
currentGroupInfo.reset();
currentTestRunInfo.reset();
}
} // end namespace Catch

View File

@ -0,0 +1,79 @@
#ifndef CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
#define CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_option.hpp>
#include <iosfwd>
#include <string>
#include <vector>
namespace Catch {
template<typename T>
struct LazyStat : Option<T> {
LazyStat& operator=(T const& _value) {
Option<T>::operator=(_value);
used = false;
return *this;
}
void reset() {
Option<T>::reset();
used = false;
}
bool used = false;
};
struct StreamingReporterBase : IStreamingReporter {
StreamingReporterBase( ReporterConfig const& _config ):
m_config( _config.fullConfig() ), stream( _config.stream() ) {
}
~StreamingReporterBase() override;
void noMatchingTestCases(std::string const&) override {}
void reportInvalidArguments(std::string const&) override {}
void testRunStarting( TestRunInfo const& _testRunInfo ) override;
void testGroupStarting( GroupInfo const& _groupInfo ) override;
void testCaseStarting(TestCaseInfo const& _testInfo) override {
currentTestCaseInfo = &_testInfo;
}
void sectionStarting(SectionInfo const& _sectionInfo) override {
m_sectionStack.push_back(_sectionInfo);
}
void sectionEnded(SectionStats const& /* _sectionStats */) override {
m_sectionStack.pop_back();
}
void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
currentTestCaseInfo = nullptr;
}
void testGroupEnded( TestGroupStats const& ) override;
void testRunEnded( TestRunStats const& /* _testRunStats */ ) override;
void skipTest(TestCaseInfo const&) override {
// Don't do anything with this by default.
// It can optionally be overridden in the derived class.
}
IConfig const* m_config;
std::ostream& stream;
LazyStat<TestRunInfo> currentTestRunInfo;
LazyStat<GroupInfo> currentGroupInfo;
TestCaseInfo const* currentTestCaseInfo = nullptr;
std::vector<SectionInfo> m_sectionStack;
};
} // end namespace Catch
#endif // CATCH_REPORTER_STREAMING_BASE_HPP_INCLUDED

View File

@ -5,7 +5,7 @@
#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
namespace Catch {

View File

@ -5,6 +5,7 @@
#include <catch2/reporters/catch_reporter_teamcity.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_textflow.hpp>

View File

@ -5,8 +5,8 @@
#ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/catch_timer.hpp>
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <cstring>

View File

@ -8,6 +8,7 @@
#include <catch2/reporters/catch_reporter_xml.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/catch_test_spec.hpp>
#include <catch2/internal/catch_string_manip.hpp>

View File

@ -7,7 +7,7 @@
#ifndef TWOBLUECUBES_CATCH_REPORTER_XML_H_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_XML_H_INCLUDED
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/internal/catch_xmlwriter.hpp>
#include <catch2/catch_timer.hpp>

View File

@ -15,12 +15,15 @@
#define CATCH_REPORTERS_ALL_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_automake.hpp>
#include <catch2/reporters/catch_reporter_bases.hpp>
#include <catch2/reporters/catch_reporter_compact.hpp>
#include <catch2/reporters/catch_reporter_console.hpp>
#include <catch2/reporters/catch_reporter_cumulative_base.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/reporters/catch_reporter_junit.hpp>
#include <catch2/reporters/catch_reporter_listening.hpp>
#include <catch2/reporters/catch_reporter_sonarqube.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/reporters/catch_reporter_tap.hpp>
#include <catch2/reporters/catch_reporter_teamcity.hpp>
#include <catch2/reporters/catch_reporter_xml.hpp>

View File

@ -4,6 +4,7 @@
*/
#include <catch2/catch_tag_alias_autoregistrar.hpp>
#include <catch2/reporters/catch_reporter_event_listener.hpp>
// Some example tag aliases
CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
@ -15,10 +16,9 @@ CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" )
# pragma clang diagnostic ignored "-Wc++98-compat"
#endif
#include <catch2/reporters/catch_reporter_bases.hpp>
struct TestListener : Catch::TestEventListenerBase {
using TestEventListenerBase::TestEventListenerBase;
struct TestListener : Catch::EventListenerBase {
using EventListenerBase::EventListenerBase;
};
#include <catch2/catch_reporter_registrars.hpp>