From bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Sun, 29 Jun 2025 19:25:29 +0100 Subject: import catch2 3.8.1 --- src/catch2/interfaces/catch_interfaces_all.hpp | 37 ++++ src/catch2/interfaces/catch_interfaces_capture.cpp | 13 ++ src/catch2/interfaces/catch_interfaces_capture.hpp | 109 ++++++++++ src/catch2/interfaces/catch_interfaces_config.cpp | 13 ++ src/catch2/interfaces/catch_interfaces_config.hpp | 100 +++++++++ .../catch_interfaces_enum_values_registry.hpp | 47 +++++ .../interfaces/catch_interfaces_exception.cpp | 14 ++ .../interfaces/catch_interfaces_exception.hpp | 36 ++++ .../catch_interfaces_generatortracker.cpp | 32 +++ .../catch_interfaces_generatortracker.hpp | 90 +++++++++ .../interfaces/catch_interfaces_registry_hub.cpp | 14 ++ .../interfaces/catch_interfaces_registry_hub.hpp | 66 ++++++ .../interfaces/catch_interfaces_reporter.cpp | 93 +++++++++ .../interfaces/catch_interfaces_reporter.hpp | 223 +++++++++++++++++++++ .../catch_interfaces_reporter_factory.cpp | 14 ++ .../catch_interfaces_reporter_factory.hpp | 45 +++++ .../catch_interfaces_tag_alias_registry.hpp | 29 +++ .../interfaces/catch_interfaces_test_invoker.hpp | 23 +++ .../interfaces/catch_interfaces_testcase.cpp | 13 ++ .../interfaces/catch_interfaces_testcase.hpp | 30 +++ 20 files changed, 1041 insertions(+) create mode 100644 src/catch2/interfaces/catch_interfaces_all.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_capture.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_capture.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_config.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_config.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_enum_values_registry.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_exception.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_exception.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_generatortracker.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_generatortracker.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_registry_hub.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_registry_hub.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_reporter.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_reporter.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_reporter_factory.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_reporter_factory.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_tag_alias_registry.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_test_invoker.hpp create mode 100644 src/catch2/interfaces/catch_interfaces_testcase.cpp create mode 100644 src/catch2/interfaces/catch_interfaces_testcase.hpp (limited to 'src/catch2/interfaces') diff --git a/src/catch2/interfaces/catch_interfaces_all.hpp b/src/catch2/interfaces/catch_interfaces_all.hpp new file mode 100644 index 0000000..a99fdcd --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_all.hpp @@ -0,0 +1,37 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +/** \file + * This is a convenience header for Catch2's interfaces. It includes + * **all** of Catch2 headers related to interfaces. + * + * Generally the Catch2 users should use specific includes they need, + * but this header can be used instead for ease-of-experimentation, or + * just plain convenience, at the cost of somewhat increased compilation + * times. + * + * When a new header is added to either the `interfaces` folder, or to + * the corresponding internal subfolder, it should be added here. + */ + + +#ifndef CATCH_INTERFACES_ALL_HPP_INCLUDED +#define CATCH_INTERFACES_ALL_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // CATCH_INTERFACES_ALL_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_capture.cpp b/src/catch2/interfaces/catch_interfaces_capture.cpp new file mode 100644 index 0000000..9b40ee5 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_capture.cpp @@ -0,0 +1,13 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + IResultCapture::~IResultCapture() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_capture.hpp b/src/catch2/interfaces/catch_interfaces_capture.hpp new file mode 100644 index 0000000..9e5431d --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_capture.hpp @@ -0,0 +1,109 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_CAPTURE_HPP_INCLUDED +#define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED + +#include + +#include +#include +#include +#include + +namespace Catch { + + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + struct MessageBuilder; + struct Counts; + struct AssertionReaction; + struct SourceLineInfo; + + class ITransientExpression; + class IGeneratorTracker; + + struct BenchmarkInfo; + + namespace Generators { + class GeneratorUntypedBase; + using GeneratorBasePtr = Catch::Detail::unique_ptr; + } + + + class IResultCapture { + public: + virtual ~IResultCapture(); + + virtual void notifyAssertionStarted( AssertionInfo const& info ) = 0; + virtual bool sectionStarted( StringRef sectionName, + SourceLineInfo const& sectionLineInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0; + + virtual IGeneratorTracker* + acquireGeneratorTracker( StringRef generatorName, + SourceLineInfo const& lineInfo ) = 0; + virtual IGeneratorTracker* + createGeneratorTracker( StringRef generatorName, + SourceLineInfo lineInfo, + Generators::GeneratorBasePtr&& generator ) = 0; + + virtual void benchmarkPreparing( StringRef name ) = 0; + virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; + virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0; + virtual void benchmarkFailed( StringRef error ) = 0; + + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0; + + virtual void handleFatalErrorCondition( StringRef message ) = 0; + + virtual void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) = 0; + virtual void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + std::string&& message, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string&& message, + AssertionReaction& reaction ) = 0; + virtual void handleIncomplete + ( AssertionInfo const& info ) = 0; + virtual void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) = 0; + + + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + + // Deprecated, do not use: + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + virtual void exceptionEarlyReported() = 0; + }; + + IResultCapture& getResultCapture(); +} + +#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_config.cpp b/src/catch2/interfaces/catch_interfaces_config.cpp new file mode 100644 index 0000000..655bc1b --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_config.cpp @@ -0,0 +1,13 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + IConfig::~IConfig() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_config.hpp b/src/catch2/interfaces/catch_interfaces_config.hpp new file mode 100644 index 0000000..eb05480 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_config.hpp @@ -0,0 +1,100 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_CONFIG_HPP_INCLUDED +#define CATCH_INTERFACES_CONFIG_HPP_INCLUDED + +#include +#include + +#include +#include +#include +#include + +namespace Catch { + + enum class Verbosity { + Quiet = 0, + Normal, + High + }; + + struct WarnAbout { enum What { + Nothing = 0x00, + //! A test case or leaf section did not run any assertions + NoAssertions = 0x01, + //! A command line test spec matched no test cases + UnmatchedTestSpec = 0x02, + }; }; + + enum class ShowDurations { + DefaultForReporter, + Always, + Never + }; + enum class TestRunOrder { + Declared, + LexicographicallySorted, + Randomized + }; + enum class ColourMode : std::uint8_t { + //! Let Catch2 pick implementation based on platform detection + PlatformDefault, + //! Use ANSI colour code escapes + ANSI, + //! Use Win32 console colour API + Win32, + //! Don't use any colour + None + }; + struct WaitForKeypress { enum When { + Never, + BeforeStart = 1, + BeforeExit = 2, + BeforeStartAndExit = BeforeStart | BeforeExit + }; }; + + class TestSpec; + class IStream; + + class IConfig : public Detail::NonCopyable { + public: + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual StringRef name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual bool warnAboutUnmatchedTestSpecs() const = 0; + virtual bool zeroTestsCountAsSuccess() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations showDurations() const = 0; + virtual double minDuration() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual bool hasTestFilters() const = 0; + virtual std::vector const& getTestsOrTags() const = 0; + virtual TestRunOrder runOrder() const = 0; + virtual uint32_t rngSeed() const = 0; + virtual unsigned int shardCount() const = 0; + virtual unsigned int shardIndex() const = 0; + virtual ColourMode defaultColourMode() const = 0; + virtual std::vector const& getSectionsToRun() const = 0; + virtual Verbosity verbosity() const = 0; + + virtual bool skipBenchmarks() const = 0; + virtual bool benchmarkNoAnalysis() const = 0; + virtual unsigned int benchmarkSamples() const = 0; + virtual double benchmarkConfidenceInterval() const = 0; + virtual unsigned int benchmarkResamples() const = 0; + virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0; + }; +} + +#endif // CATCH_INTERFACES_CONFIG_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_enum_values_registry.hpp b/src/catch2/interfaces/catch_interfaces_enum_values_registry.hpp new file mode 100644 index 0000000..38b052d --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_enum_values_registry.hpp @@ -0,0 +1,47 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED +#define CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED + +#include + +#include + +namespace Catch { + + namespace Detail { + struct EnumInfo { + StringRef m_name; + std::vector> m_values; + + ~EnumInfo(); + + StringRef lookup( int value ) const; + }; + } // namespace Detail + + class IMutableEnumValuesRegistry { + public: + virtual ~IMutableEnumValuesRegistry(); // = default; + + virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector const& values ) = 0; + + template + Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list values ) { + static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int"); + std::vector intValues; + intValues.reserve( values.size() ); + for( auto enumValue : values ) + intValues.push_back( static_cast( enumValue ) ); + return registerEnum( enumName, allEnums, intValues ); + } + }; + +} // Catch + +#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_exception.cpp b/src/catch2/interfaces/catch_interfaces_exception.cpp new file mode 100644 index 0000000..44c272d --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_exception.cpp @@ -0,0 +1,14 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + IExceptionTranslator::~IExceptionTranslator() = default; + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_exception.hpp b/src/catch2/interfaces/catch_interfaces_exception.hpp new file mode 100644 index 0000000..fcc2a8f --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_exception.hpp @@ -0,0 +1,36 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED +#define CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED + +#include + +#include +#include + +namespace Catch { + using exceptionTranslateFunction = std::string(*)(); + + class IExceptionTranslator; + using ExceptionTranslators = std::vector>; + + class IExceptionTranslator { + public: + virtual ~IExceptionTranslator(); // = default + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + class IExceptionTranslatorRegistry { + public: + virtual ~IExceptionTranslatorRegistry(); // = default + virtual std::string translateActiveException() const = 0; + }; + +} // namespace Catch + +#endif // CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_generatortracker.cpp b/src/catch2/interfaces/catch_interfaces_generatortracker.cpp new file mode 100644 index 0000000..e9fa5dd --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_generatortracker.cpp @@ -0,0 +1,32 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include +#include + +namespace Catch { + namespace Generators { + + bool GeneratorUntypedBase::countedNext() { + auto ret = next(); + if ( ret ) { + m_stringReprCache.clear(); + ++m_currentElementIndex; + } + return ret; + } + + StringRef GeneratorUntypedBase::currentElementAsString() const { + if ( m_stringReprCache.empty() ) { + m_stringReprCache = stringifyImpl(); + } + return m_stringReprCache; + } + + } // namespace Generators +} // namespace Catch diff --git a/src/catch2/interfaces/catch_interfaces_generatortracker.hpp b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp new file mode 100644 index 0000000..d70cb59 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp @@ -0,0 +1,90 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED +#define CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED + +#include +#include + +#include + +namespace Catch { + + namespace Generators { + class GeneratorUntypedBase { + // Caches result from `toStringImpl`, assume that when it is an + // empty string, the cache is invalidated. + mutable std::string m_stringReprCache; + + // Counts based on `next` returning true + std::size_t m_currentElementIndex = 0; + + /** + * Attempts to move the generator to the next element + * + * Returns true iff the move succeeded (and a valid element + * can be retrieved). + */ + virtual bool next() = 0; + + //! Customization point for `currentElementAsString` + virtual std::string stringifyImpl() const = 0; + + public: + GeneratorUntypedBase() = default; + // Generation of copy ops is deprecated (and Clang will complain) + // if there is a user destructor defined + GeneratorUntypedBase(GeneratorUntypedBase const&) = default; + GeneratorUntypedBase& operator=(GeneratorUntypedBase const&) = default; + + virtual ~GeneratorUntypedBase(); // = default; + + /** + * Attempts to move the generator to the next element + * + * Serves as a non-virtual interface to `next`, so that the + * top level interface can provide sanity checking and shared + * features. + * + * As with `next`, returns true iff the move succeeded and + * the generator has new valid element to provide. + */ + bool countedNext(); + + std::size_t currentElementIndex() const { return m_currentElementIndex; } + + /** + * Returns generator's current element as user-friendly string. + * + * By default returns string equivalent to calling + * `Catch::Detail::stringify` on the current element, but generators + * can customize their implementation as needed. + * + * Not thread-safe due to internal caching. + * + * The returned ref is valid only until the generator instance + * is destructed, or it moves onto the next element, whichever + * comes first. + */ + StringRef currentElementAsString() const; + }; + using GeneratorBasePtr = Catch::Detail::unique_ptr; + + } // namespace Generators + + class IGeneratorTracker { + public: + virtual ~IGeneratorTracker(); // = default; + virtual auto hasGenerator() const -> bool = 0; + virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0; + virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0; + }; + +} // namespace Catch + +#endif // CATCH_INTERFACES_GENERATORTRACKER_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_registry_hub.cpp b/src/catch2/interfaces/catch_interfaces_registry_hub.cpp new file mode 100644 index 0000000..cd688a4 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_registry_hub.cpp @@ -0,0 +1,14 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + IRegistryHub::~IRegistryHub() = default; + IMutableRegistryHub::~IMutableRegistryHub() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_registry_hub.hpp b/src/catch2/interfaces/catch_interfaces_registry_hub.hpp new file mode 100644 index 0000000..113f223 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_registry_hub.hpp @@ -0,0 +1,66 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED +#define CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED + +#include + +#include + +namespace Catch { + + class TestCaseHandle; + struct TestCaseInfo; + class ITestCaseRegistry; + class IExceptionTranslatorRegistry; + class IExceptionTranslator; + class ReporterRegistry; + class IReporterFactory; + class ITagAliasRegistry; + class ITestInvoker; + class IMutableEnumValuesRegistry; + struct SourceLineInfo; + + class StartupExceptionRegistry; + class EventListenerFactory; + + using IReporterFactoryPtr = Detail::unique_ptr; + + class IRegistryHub { + public: + virtual ~IRegistryHub(); // = default + + virtual ReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; + virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0; + + + virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; + }; + + class IMutableRegistryHub { + public: + virtual ~IMutableRegistryHub(); // = default + virtual void registerReporter( std::string const& name, IReporterFactoryPtr factory ) = 0; + virtual void registerListener( Detail::unique_ptr factory ) = 0; + virtual void registerTest(Detail::unique_ptr&& testInfo, Detail::unique_ptr&& invoker) = 0; + virtual void registerTranslator( Detail::unique_ptr&& translator ) = 0; + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; + virtual void registerStartupException() noexcept = 0; + virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; + }; + + IRegistryHub const& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +#endif // CATCH_INTERFACES_REGISTRY_HUB_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_reporter.cpp b/src/catch2/interfaces/catch_interfaces_reporter.cpp new file mode 100644 index 0000000..90536bb --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_reporter.cpp @@ -0,0 +1,93 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#include +#include +#include +#include +#include + +#include + +namespace Catch { + + ReporterConfig::ReporterConfig( + IConfig const* _fullConfig, + Detail::unique_ptr _stream, + ColourMode colourMode, + std::map customOptions ): + m_stream( CATCH_MOVE(_stream) ), + m_fullConfig( _fullConfig ), + m_colourMode( colourMode ), + m_customOptions( CATCH_MOVE( customOptions ) ) {} + + Detail::unique_ptr ReporterConfig::takeStream() && { + assert( m_stream ); + return CATCH_MOVE( m_stream ); + } + IConfig const * ReporterConfig::fullConfig() const { return m_fullConfig; } + ColourMode ReporterConfig::colourMode() const { return m_colourMode; } + + std::map const& + ReporterConfig::customOptions() const { + return m_customOptions; + } + + ReporterConfig::~ReporterConfig() = default; + + AssertionStats::AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder.m_info.message = static_cast(assertionResult.getMessage()); + + infoMessages.push_back( CATCH_MOVE(builder.m_info) ); + } + } + + SectionStats::SectionStats( SectionInfo&& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( CATCH_MOVE(_sectionInfo) ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + + + TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string&& _stdOut, + std::string&& _stdErr, + bool _aborting ) + : testInfo( &_testInfo ), + totals( _totals ), + stdOut( CATCH_MOVE(_stdOut) ), + stdErr( CATCH_MOVE(_stdErr) ), + aborting( _aborting ) + {} + + + TestRunStats::TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + IEventListener::~IEventListener() = default; + +} // end namespace Catch diff --git a/src/catch2/interfaces/catch_interfaces_reporter.hpp b/src/catch2/interfaces/catch_interfaces_reporter.hpp new file mode 100644 index 0000000..a052c5d --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_reporter.hpp @@ -0,0 +1,223 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_REPORTER_HPP_INCLUDED +#define CATCH_INTERFACES_REPORTER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace Catch { + + struct ReporterDescription; + struct ListenerDescription; + struct TagInfo; + struct TestCaseInfo; + class TestCaseHandle; + class IConfig; + class IStream; + enum class ColourMode : std::uint8_t; + + struct ReporterConfig { + ReporterConfig( IConfig const* _fullConfig, + Detail::unique_ptr _stream, + ColourMode colourMode, + std::map customOptions ); + + ReporterConfig( ReporterConfig&& ) = default; + ReporterConfig& operator=( ReporterConfig&& ) = default; + ~ReporterConfig(); // = default + + Detail::unique_ptr takeStream() &&; + IConfig const* fullConfig() const; + ColourMode colourMode() const; + std::map const& customOptions() const; + + private: + Detail::unique_ptr m_stream; + IConfig const* m_fullConfig; + ColourMode m_colourMode; + std::map m_customOptions; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ); + + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = delete; + AssertionStats& operator = ( AssertionStats && ) = delete; + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo&& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ); + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string&& _stdOut, + std::string&& _stdErr, + bool _aborting ); + + TestCaseInfo const * testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ); + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + //! By setting up its preferences, a reporter can modify Catch2's behaviour + //! in some regards, e.g. it can request Catch2 to capture writes to + //! stdout/stderr during test execution, and pass them to the reporter. + struct ReporterPreferences { + //! Catch2 should redirect writes to stdout and pass them to the + //! reporter + bool shouldRedirectStdOut = false; + //! Catch2 should call `Reporter::assertionEnded` even for passing + //! assertions + bool shouldReportAllAssertions = false; + }; + + /** + * The common base for all reporters and event listeners + * + * Implementing classes must also implement: + * + * //! User-friendly description of the reporter/listener type + * static std::string getDescription() + * + * Generally shouldn't be derived from by users of Catch2 directly, + * instead they should derive from one of the utility bases that + * derive from this class. + */ + class IEventListener { + protected: + //! Derived classes can set up their preferences here + ReporterPreferences m_preferences; + //! The test run's config as filled in from CLI and defaults + IConfig const* m_config; + + public: + IEventListener( IConfig const* config ): m_config( config ) {} + + virtual ~IEventListener(); // = default; + + // Implementing class must also provide the following static methods: + // static std::string getDescription(); + + ReporterPreferences const& getPreferences() const { + return m_preferences; + } + + //! Called when no test cases match provided test spec + virtual void noMatchingTestCases( StringRef unmatchedSpec ) = 0; + //! Called for all invalid test specs from the cli + virtual void reportInvalidTestSpec( StringRef invalidArgument ) = 0; + + /** + * Called once in a testing run before tests are started + * + * Not called if tests won't be run (e.g. only listing will happen) + */ + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + + //! Called _once_ for each TEST_CASE, no matter how many times it is entered + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + //! Called _every time_ a TEST_CASE is entered, including repeats (due to sections) + virtual void testCasePartialStarting( TestCaseInfo const& testInfo, uint64_t partNumber ) = 0; + //! Called when a `SECTION` is being entered. Not called for skipped sections + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + //! Called when user-code is being probed before the actual benchmark runs + virtual void benchmarkPreparing( StringRef benchmarkName ) = 0; + //! Called after probe but before the user-code is being benchmarked + virtual void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) = 0; + //! Called with the benchmark results if benchmark successfully finishes + virtual void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) = 0; + //! Called if running the benchmarks fails for any reason + virtual void benchmarkFailed( StringRef benchmarkName ) = 0; + + //! Called before assertion success/failure is evaluated + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + //! Called after assertion was fully evaluated + virtual void assertionEnded( AssertionStats const& assertionStats ) = 0; + + //! Called after a `SECTION` has finished running + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + //! Called _every time_ a TEST_CASE is entered, including repeats (due to sections) + virtual void testCasePartialEnded(TestCaseStats const& testCaseStats, uint64_t partNumber ) = 0; + //! Called _once_ for each TEST_CASE, no matter how many times it is entered + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + /** + * Called once after all tests in a testing run are finished + * + * Not called if tests weren't run (e.g. only listings happened) + */ + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + /** + * Called with test cases that are skipped due to the test run aborting. + * NOT called for test cases that are explicitly skipped using the `SKIP` macro. + * + * Deprecated - will be removed in the next major release. + */ + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + //! Called if a fatal error (signal/structured exception) occurred + virtual void fatalErrorEncountered( StringRef error ) = 0; + + //! Writes out information about provided reporters using reporter-specific format + virtual void listReporters(std::vector const& descriptions) = 0; + //! Writes out the provided listeners descriptions using reporter-specific format + virtual void listListeners(std::vector const& descriptions) = 0; + //! Writes out information about provided tests using reporter-specific format + virtual void listTests(std::vector const& tests) = 0; + //! Writes out information about the provided tags using reporter-specific format + virtual void listTags(std::vector const& tags) = 0; + }; + using IEventListenerPtr = Detail::unique_ptr; + +} // end namespace Catch + +#endif // CATCH_INTERFACES_REPORTER_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_reporter_factory.cpp b/src/catch2/interfaces/catch_interfaces_reporter_factory.cpp new file mode 100644 index 0000000..4fe992f --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_reporter_factory.cpp @@ -0,0 +1,14 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + IReporterFactory::~IReporterFactory() = default; + EventListenerFactory::~EventListenerFactory() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp b/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp new file mode 100644 index 0000000..83ddd7b --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp @@ -0,0 +1,45 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED +#define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED + +#include +#include + +#include + +namespace Catch { + + struct ReporterConfig; + class IConfig; + class IEventListener; + using IEventListenerPtr = Detail::unique_ptr; + + + class IReporterFactory { + public: + virtual ~IReporterFactory(); // = default + + virtual IEventListenerPtr + create( ReporterConfig&& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + using IReporterFactoryPtr = Detail::unique_ptr; + + class EventListenerFactory { + 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 + +#endif // CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_tag_alias_registry.hpp b/src/catch2/interfaces/catch_interfaces_tag_alias_registry.hpp new file mode 100644 index 0000000..5da0f8d --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_tag_alias_registry.hpp @@ -0,0 +1,29 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED +#define CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED + +#include + +namespace Catch { + + struct TagAlias; + + class ITagAliasRegistry { + public: + virtual ~ITagAliasRegistry(); // = default + // Nullptr if not present + virtual TagAlias const* find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +#endif // CATCH_INTERFACES_TAG_ALIAS_REGISTRY_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_test_invoker.hpp b/src/catch2/interfaces/catch_interfaces_test_invoker.hpp new file mode 100644 index 0000000..124a7f7 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_test_invoker.hpp @@ -0,0 +1,23 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED +#define CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED + +namespace Catch { + + class ITestInvoker { + public: + virtual void prepareTestCase(); + virtual void tearDownTestCase(); + virtual void invoke() const = 0; + virtual ~ITestInvoker(); // = default + }; + +} // namespace Catch + +#endif // CATCH_INTERFACES_TEST_INVOKER_HPP_INCLUDED diff --git a/src/catch2/interfaces/catch_interfaces_testcase.cpp b/src/catch2/interfaces/catch_interfaces_testcase.cpp new file mode 100644 index 0000000..a543116 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_testcase.cpp @@ -0,0 +1,13 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +namespace Catch { + ITestCaseRegistry::~ITestCaseRegistry() = default; +} diff --git a/src/catch2/interfaces/catch_interfaces_testcase.hpp b/src/catch2/interfaces/catch_interfaces_testcase.hpp new file mode 100644 index 0000000..daee848 --- /dev/null +++ b/src/catch2/interfaces/catch_interfaces_testcase.hpp @@ -0,0 +1,30 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_INTERFACES_TESTCASE_HPP_INCLUDED +#define CATCH_INTERFACES_TESTCASE_HPP_INCLUDED + +#include + +namespace Catch { + + struct TestCaseInfo; + class TestCaseHandle; + class IConfig; + + class ITestCaseRegistry { + public: + virtual ~ITestCaseRegistry(); // = default + // TODO: this exists only for adding filenames to test cases -- let's expose this in a saner way later + virtual std::vector const& getAllInfos() const = 0; + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + +} + +#endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED -- cgit v1.2.3