Compare commits

...

7 Commits

Author SHA1 Message Date
Martin Hořeňovský
5db31e587e WIP: devirtualize RunContext 2023-03-21 11:32:44 +01:00
Martin Hořeňovský
f3960c02ce Devirtualize RegistryHub 2023-03-21 11:30:22 +01:00
Martin Hořeňovský
02ce0a2eec Unify ITestCaseRegistry and TestRegistry
I also made a bunch of refactorings around the headers and includes
to simplify the main include path.
2023-03-21 11:30:19 +01:00
Martin Hořeňovský
cf4d84a349 Unify ITagAliasRegistry and TagAliasRegistry 2023-03-21 11:30:17 +01:00
Martin Hořeňovský
cfe859e0f3 Unify IExceptionTranslatorRegistry and ExceptionTranslatorRegistry 2023-03-21 11:30:12 +01:00
Martin Hořeňovský
31b291ba26 Unify IMutableEnumRegistry and EnumValuesRegistry
This time there was no need for compilation firewall, so we keep
everything inlined.
2023-03-21 11:30:08 +01:00
Martin Hořeňovský
ceb7ab6b20 Unify IReporterRegistry and ReporterRegistry
To keep the compilation firewall effect, the implementations
are hidden behind a PIMPL. In this case it is probably not
worth it, but we can inline it later if needed.
2023-03-21 11:30:06 +01:00
64 changed files with 766 additions and 835 deletions

View File

@@ -55,6 +55,7 @@ set(IMPL_HEADERS
${SOURCES_DIR}/catch_template_test_macros.hpp
${SOURCES_DIR}/catch_test_case_info.hpp
${SOURCES_DIR}/catch_test_macros.hpp
${SOURCES_DIR}/catch_test_run_info.hpp
${SOURCES_DIR}/catch_test_spec.hpp
${SOURCES_DIR}/catch_timer.hpp
${SOURCES_DIR}/catch_tostring.hpp
@@ -63,6 +64,7 @@ set(IMPL_HEADERS
${SOURCES_DIR}/catch_version.hpp
${SOURCES_DIR}/catch_version_macros.hpp
${SOURCES_DIR}/internal/catch_assertion_handler.hpp
${SOURCES_DIR}/internal/catch_benchmark_stats_fwd.hpp
${SOURCES_DIR}/internal/catch_case_insensitive_comparisons.hpp
${SOURCES_DIR}/internal/catch_case_sensitive.hpp
${SOURCES_DIR}/internal/catch_clara.hpp
@@ -106,6 +108,7 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_preprocessor_remove_parens.hpp
${SOURCES_DIR}/internal/catch_random_number_generator.hpp
${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
${SOURCES_DIR}/internal/catch_registry_hub.hpp
${SOURCES_DIR}/internal/catch_reporter_registry.hpp
${SOURCES_DIR}/internal/catch_reporter_spec_parser.hpp
${SOURCES_DIR}/internal/catch_result_type.hpp
@@ -145,7 +148,6 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_config.cpp
${SOURCES_DIR}/catch_get_random_seed.cpp
${SOURCES_DIR}/catch_message.cpp
${SOURCES_DIR}/catch_registry_hub.cpp
${SOURCES_DIR}/catch_session.cpp
${SOURCES_DIR}/catch_tag_alias_autoregistrar.cpp
${SOURCES_DIR}/catch_test_case_info.cpp
@@ -153,6 +155,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_timer.cpp
${SOURCES_DIR}/catch_tostring.cpp
${SOURCES_DIR}/catch_totals.cpp
${SOURCES_DIR}/catch_translate_exception.cpp
${SOURCES_DIR}/catch_version.cpp
${SOURCES_DIR}/internal/catch_assertion_handler.cpp
${SOURCES_DIR}/internal/catch_case_insensitive_comparisons.cpp
@@ -180,6 +183,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/internal/catch_polyfills.cpp
${SOURCES_DIR}/internal/catch_random_number_generator.cpp
${SOURCES_DIR}/internal/catch_random_seed_generation.cpp
${SOURCES_DIR}/internal/catch_registry_hub.cpp
${SOURCES_DIR}/internal/catch_reporter_registry.cpp
${SOURCES_DIR}/internal/catch_reporter_spec_parser.cpp
${SOURCES_DIR}/internal/catch_result_type.cpp
@@ -208,27 +212,19 @@ set(INTERNAL_FILES ${IMPL_SOURCES} ${IMPL_HEADERS})
set(INTERFACE_HEADERS
${SOURCES_DIR}/interfaces/catch_interfaces_all.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_capture.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_config.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_enum_values_registry.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_exception.hpp
${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_tag_alias_registry.hpp
${SOURCES_DIR}/interfaces/catch_interfaces_testcase.hpp
)
set(INTERFACE_SOURCES
${SOURCES_DIR}/interfaces/catch_interfaces_capture.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_config.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_exception.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_generatortracker.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_registry_hub.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_factory.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_reporter_registry.cpp
${SOURCES_DIR}/interfaces/catch_interfaces_testcase.cpp
)
set(INTERFACE_FILES ${INTERFACE_HEADERS} ${INTERFACE_SOURCES})

View File

@@ -11,9 +11,11 @@
#define CATCH_BENCHMARK_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_unique_name.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/benchmark/catch_chronometer.hpp>
@@ -26,6 +28,7 @@
#include <catch2/benchmark/detail/catch_benchmark_function.hpp>
#include <catch2/benchmark/detail/catch_run_for_at_least.hpp>
#include <algorithm>
#include <functional>
#include <string>

View File

@@ -12,8 +12,6 @@
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/internal/catch_meta.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <type_traits>

View File

@@ -36,6 +36,7 @@
#include <catch2/catch_template_test_macros.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_test_run_info.hpp>
#include <catch2/catch_test_spec.hpp>
#include <catch2/catch_timer.hpp>
#include <catch2/catch_tostring.hpp>
@@ -46,6 +47,7 @@
#include <catch2/generators/catch_generators_all.hpp>
#include <catch2/interfaces/catch_interfaces_all.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_benchmark_stats_fwd.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_case_sensitive.hpp>
#include <catch2/internal/catch_clara.hpp>
@@ -89,6 +91,7 @@
#include <catch2/internal/catch_preprocessor_remove_parens.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_reporter_spec_parser.hpp>
#include <catch2/internal/catch_result_type.hpp>

View File

@@ -13,7 +13,7 @@
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_test_spec_parser.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <catch2/internal/catch_tag_alias_registry.hpp>
#include <catch2/internal/catch_getenv.hpp>
#include <fstream>
@@ -123,7 +123,7 @@ namespace Catch {
// Bazel support can modify the test specs, so parsing has to happen
// after reading Bazel env vars.
TestSpecParser parser( ITagAliasRegistry::get() );
TestSpecParser parser( TagAliasRegistry::get() );
if ( !m_data.testsOrTags.empty() ) {
m_hasTestFilters = true;
for ( auto const& testOrTags : m_data.testsOrTags ) {

View File

@@ -6,10 +6,10 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_message.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <cassert>
#include <stack>

View File

@@ -12,7 +12,7 @@
#include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_stream_end_stop.hpp>
#include <catch2/internal/catch_message_info.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/catch_tostring.hpp>
#include <string>
@@ -61,7 +61,7 @@ namespace Catch {
class Capturer {
std::vector<MessageInfo> m_messages;
IResultCapture& m_resultCapture = getResultCapture();
RunContext& m_resultCapture = getResultCapture();
size_t m_captured = 0;
public:
Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );

View File

@@ -1,104 +0,0 @@
// 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 <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_exception_translator_registry.hpp>
#include <catch2/internal/catch_tag_alias_registry.hpp>
#include <catch2/internal/catch_startup_exception_registry.hpp>
#include <catch2/internal/catch_singletons.hpp>
#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>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch {
namespace {
class RegistryHub : public IRegistryHub,
public IMutableRegistryHub,
private Detail::NonCopyable {
public: // IRegistryHub
RegistryHub() = default;
IReporterRegistry const& getReporterRegistry() const override {
return m_reporterRegistry;
}
ITestCaseRegistry const& getTestCaseRegistry() const override {
return m_testCaseRegistry;
}
IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
return m_exceptionTranslatorRegistry;
}
ITagAliasRegistry const& getTagAliasRegistry() const override {
return m_tagAliasRegistry;
}
StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
return m_exceptionRegistry;
}
public: // IMutableRegistryHub
void registerReporter( std::string const& name, IReporterFactoryPtr factory ) override {
m_reporterRegistry.registerReporter( name, CATCH_MOVE(factory) );
}
void registerListener( Detail::unique_ptr<EventListenerFactory> factory ) override {
m_reporterRegistry.registerListener( CATCH_MOVE(factory) );
}
void registerTest( Detail::unique_ptr<TestCaseInfo>&& testInfo, Detail::unique_ptr<ITestInvoker>&& invoker ) override {
m_testCaseRegistry.registerTest( CATCH_MOVE(testInfo), CATCH_MOVE(invoker) );
}
void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator ) override {
m_exceptionTranslatorRegistry.registerTranslator( CATCH_MOVE(translator) );
}
void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
m_tagAliasRegistry.add( alias, tag, lineInfo );
}
void registerStartupException() noexcept override {
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
m_exceptionRegistry.add(std::current_exception());
#else
CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
#endif
}
IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
return m_enumValuesRegistry;
}
private:
TestRegistry m_testCaseRegistry;
ReporterRegistry m_reporterRegistry;
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
TagAliasRegistry m_tagAliasRegistry;
StartupExceptionRegistry m_exceptionRegistry;
Detail::EnumValuesRegistry m_enumValuesRegistry;
};
}
using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
IRegistryHub const& getRegistryHub() {
return RegistryHubSingleton::get();
}
IMutableRegistryHub& getMutableRegistryHub() {
return RegistryHubSingleton::getMutable();
}
void cleanUp() {
cleanupSingletons();
cleanUpContext();
}
std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
}
} // end namespace Catch

View File

@@ -19,11 +19,14 @@
#include <catch2/internal/catch_textflow.hpp>
#include <catch2/internal/catch_windows_h_proxy.hpp>
#include <catch2/reporters/catch_reporter_multi.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_stdstreams.hpp>
#include <catch2/internal/catch_istream.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <algorithm>
#include <cassert>

View File

@@ -8,7 +8,7 @@
#include <catch2/catch_tag_alias_autoregistrar.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
namespace Catch {

View File

@@ -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_TEST_RUN_INFO_HPP_INCLUDED
#define CATCH_TEST_RUN_INFO_HPP_INCLUDED
#include <catch2/internal/catch_stringref.hpp>
namespace Catch {
struct TestRunInfo {
constexpr TestRunInfo(StringRef _name) : name(_name) {}
StringRef name;
};
} // end namespace Catch
#endif // CATCH_TEST_RUN_INFO_HPP_INCLUDED

View File

@@ -8,6 +8,7 @@
#include <catch2/catch_test_spec.hpp>
#include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <algorithm>

View File

@@ -16,9 +16,9 @@
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_config_wchar.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_reusable_string_stream.hpp>
#include <catch2/internal/catch_void_type.hpp>
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
#include <string_view>
@@ -648,7 +648,7 @@ struct ratio_string<std::milli> {
};
}
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
namespace Catch { \

View File

@@ -0,0 +1,20 @@
// 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 <catch2/catch_translate_exception.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
namespace Catch {
namespace Detail {
void registerTranslatorImpl(
Detail::unique_ptr<IExceptionTranslator>&& translator ) {
getMutableRegistryHub().registerTranslator(
CATCH_MOVE( translator ) );
}
} // namespace Detail
} // namespace Catch

View File

@@ -15,6 +15,10 @@
#include <exception>
namespace Catch {
namespace Detail {
void registerTranslatorImpl(
Detail::unique_ptr<IExceptionTranslator>&& translator );
}
class ExceptionTranslatorRegistrar {
template<typename T>
@@ -48,9 +52,8 @@ namespace Catch {
public:
template<typename T>
ExceptionTranslatorRegistrar( std::string(*translateFunction)( T const& ) ) {
getMutableRegistryHub().registerTranslator(
Detail::make_unique<ExceptionTranslator<T>>(translateFunction)
);
Detail::registerTranslatorImpl( Detail::make_unique<ExceptionTranslator<T>>(
translateFunction ) );
}
};

View File

@@ -9,7 +9,7 @@
#include <catch2/generators/catch_generators.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/generators/catch_generator_exception.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_run_context.hpp>
namespace Catch {

View File

@@ -22,16 +22,11 @@
#ifndef CATCH_INTERFACES_ALL_HPP_INCLUDED
#define CATCH_INTERFACES_ALL_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#include <catch2/interfaces/catch_interfaces_exception.hpp>
#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_tag_alias_registry.hpp>
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#endif // CATCH_INTERFACES_ALL_HPP_INCLUDED

View File

@@ -1,13 +0,0 @@
// 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 <catch2/interfaces/catch_interfaces_capture.hpp>
namespace Catch {
IResultCapture::~IResultCapture() = default;
}

View File

@@ -1,110 +0,0 @@
// 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 <string>
#include <chrono>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
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;
template <typename Duration = std::chrono::duration<double, std::nano>>
struct BenchmarkStats;
namespace Generators {
class GeneratorUntypedBase;
using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
}
class IResultCapture {
public:
virtual ~IResultCapture();
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,
StringRef 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

View File

@@ -1,47 +0,0 @@
// 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 <catch2/internal/catch_stringref.hpp>
#include <vector>
namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
std::vector<std::pair<int, StringRef>> 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<int> const& values ) = 0;
template<typename E>
Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
std::vector<int> intValues;
intValues.reserve( values.size() );
for( auto enumValue : values )
intValues.push_back( static_cast<int>( enumValue ) );
return registerEnum( enumName, allEnums, intValues );
}
};
} // Catch
#endif // CATCH_INTERFACES_ENUM_VALUES_REGISTRY_HPP_INCLUDED

View File

@@ -10,5 +10,4 @@
namespace Catch {
IExceptionTranslator::~IExceptionTranslator() = default;
IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
}

View File

@@ -8,15 +8,12 @@
#ifndef CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
#define CATCH_INTERFACES_EXCEPTION_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <vector>
namespace Catch {
using exceptionTranslateFunction = std::string(*)();
class IExceptionTranslator;
using ExceptionTranslators = std::vector<Detail::unique_ptr<IExceptionTranslator const>>;
@@ -26,12 +23,6 @@ namespace Catch {
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

View File

@@ -1,14 +0,0 @@
// 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 <catch2/interfaces/catch_interfaces_registry_hub.hpp>
namespace Catch {
IRegistryHub::~IRegistryHub() = default;
IMutableRegistryHub::~IMutableRegistryHub() = default;
}

View File

@@ -1,66 +0,0 @@
// 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 <catch2/internal/catch_unique_ptr.hpp>
#include <string>
namespace Catch {
class TestCaseHandle;
struct TestCaseInfo;
class ITestCaseRegistry;
class IExceptionTranslatorRegistry;
class IExceptionTranslator;
class IReporterRegistry;
class IReporterFactory;
class ITagAliasRegistry;
class ITestInvoker;
class IMutableEnumValuesRegistry;
struct SourceLineInfo;
class StartupExceptionRegistry;
class EventListenerFactory;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
class IRegistryHub {
public:
virtual ~IRegistryHub(); // = default
virtual IReporterRegistry 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<EventListenerFactory> factory ) = 0;
virtual void registerTest(Detail::unique_ptr<TestCaseInfo>&& testInfo, Detail::unique_ptr<ITestInvoker>&& invoker) = 0;
virtual void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& 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

View File

@@ -9,6 +9,7 @@
#define CATCH_INTERFACES_REPORTER_HPP_INCLUDED
#include <catch2/catch_section_info.hpp>
#include <catch2/catch_test_run_info.hpp>
#include <catch2/catch_totals.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/internal/catch_message_info.hpp>
@@ -17,15 +18,18 @@
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/benchmark/catch_estimate.hpp>
#include <catch2/benchmark/catch_outlier_classification.hpp>
#include <catch2/internal/catch_benchmark_stats_fwd.hpp>
#include <map>
#include <string>
#include <vector>
#include <iosfwd>
#include <chrono>
namespace Catch {
struct BenchmarkInfo;
struct ReporterDescription;
struct ListenerDescription;
struct TagInfo;
@@ -57,11 +61,6 @@ namespace Catch {
std::map<std::string, std::string> m_customOptions;
};
struct TestRunInfo {
constexpr TestRunInfo(StringRef _name) : name(_name) {}
StringRef name;
};
struct AssertionStats {
AssertionStats( AssertionResult const& _assertionResult,
std::vector<MessageInfo> const& _infoMessages,

View File

@@ -1,13 +0,0 @@
// 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 <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
namespace Catch {
IReporterRegistry::~IReporterRegistry() = default;
}

View File

@@ -1,42 +0,0 @@
// 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_REGISTRY_HPP_INCLUDED
#define CATCH_INTERFACES_REPORTER_REGISTRY_HPP_INCLUDED
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <vector>
#include <map>
namespace Catch {
class IConfig;
class IEventListener;
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
class IReporterFactory;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct ReporterConfig;
class EventListenerFactory;
class IReporterRegistry {
public:
using FactoryMap = std::map<std::string, IReporterFactoryPtr, Detail::CaseInsensitiveLess>;
using Listeners = std::vector<Detail::unique_ptr<EventListenerFactory>>;
virtual ~IReporterRegistry(); // = default
virtual IEventListenerPtr create( std::string const& name, ReporterConfig&& 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

@@ -1,29 +0,0 @@
// 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 <string>
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

View File

@@ -10,5 +10,4 @@
namespace Catch {
ITestInvoker::~ITestInvoker() = default;
ITestCaseRegistry::~ITestCaseRegistry() = default;
}

View File

@@ -8,36 +8,14 @@
#ifndef CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
#define CATCH_INTERFACES_TESTCASE_HPP_INCLUDED
#include <vector>
namespace Catch {
class TestSpec;
struct TestCaseInfo;
class ITestInvoker {
public:
virtual void invoke () const = 0;
virtual ~ITestInvoker(); // = default
};
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<TestCaseInfo* > const& getAllInfos() const = 0;
virtual std::vector<TestCaseHandle> const& getAllTests() const = 0;
virtual std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const = 0;
};
bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
}
#endif // CATCH_INTERFACES_TESTCASE_HPP_INCLUDED

View File

@@ -11,7 +11,7 @@
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_debugger.hpp>
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>

View File

@@ -10,14 +10,14 @@
#include <catch2/catch_assertion_info.hpp>
#include <catch2/internal/catch_decomposer.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/internal/catch_lazy_expr.hpp>
#include <string>
namespace Catch {
class IResultCapture;
class RunContext;
struct AssertionReaction {
bool shouldDebugBreak = false;
@@ -29,7 +29,7 @@ namespace Catch {
AssertionInfo m_assertionInfo;
AssertionReaction m_reaction;
bool m_completed = false;
IResultCapture& m_resultCapture;
RunContext& m_resultCapture;
public:
AssertionHandler

View File

@@ -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_BENCHMARK_STATS_FWD_HPP_INCLUDED
#define CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED
#include <chrono>
namespace Catch {
// We cannot forward declare the type with default template argument
// multiple times, so it is split out into a separate header so that
// we can prevent multiple declarations in dependees
template <typename Duration = std::chrono::duration<double, std::nano>>
struct BenchmarkStats;
} // end namespace Catch
#endif // CATCH_BENCHMARK_STATS_FWD_HPP_INCLUDED

View File

@@ -9,8 +9,8 @@
#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/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_console_colour.hpp>
#include <catch2/internal/catch_parse_numbers.hpp>
#include <catch2/internal/catch_reporter_spec_parser.hpp>
@@ -144,7 +144,7 @@ namespace Catch {
auto const& reporterSpec = *parsed;
IReporterRegistry::FactoryMap const& factories =
auto const& factories =
getRegistryHub().getReporterRegistry().getFactories();
auto result = factories.find( reporterSpec.name() );

View File

@@ -27,7 +27,7 @@ namespace Catch {
return *Context::currentContext;
}
void Context::setResultCapture( IResultCapture* resultCapture ) {
void Context::setResultCapture( RunContext* resultCapture ) {
m_resultCapture = resultCapture;
}

View File

@@ -12,12 +12,12 @@
namespace Catch {
class IResultCapture;
class RunContext;
class IConfig;
class Context {
IConfig const* m_config = nullptr;
IResultCapture* m_resultCapture = nullptr;
RunContext* m_resultCapture = nullptr;
CATCH_EXPORT static Context* currentContext;
friend Context& getCurrentMutableContext();
@@ -26,9 +26,9 @@ namespace Catch {
friend void cleanUpContext();
public:
IResultCapture* getResultCapture() const { return m_resultCapture; }
RunContext* getResultCapture() const { return m_resultCapture; }
IConfig const* getConfig() const { return m_config; }
void setResultCapture( IResultCapture* resultCapture );
void setResultCapture( RunContext* resultCapture );
void setConfig( IConfig const* config );
};

View File

@@ -12,44 +12,47 @@
namespace Catch {
IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() = default;
namespace Detail {
namespace {
// Extracts the actual name part of an enum instance
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
StringRef extractInstanceName(StringRef enumInstance) {
// In other words, it returns the Blue part of
// Bikeshed::Colour::Blue
static StringRef extractInstanceName( StringRef enumInstance ) {
// Find last occurrence of ":"
size_t name_start = enumInstance.size();
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
while ( name_start > 0 &&
enumInstance[name_start - 1] != ':' ) {
--name_start;
}
return enumInstance.substr(name_start, enumInstance.size() - name_start);
return enumInstance.substr( name_start,
enumInstance.size() - name_start );
}
}
} // end unnamed namespace
std::vector<StringRef> parseEnums( StringRef enums ) {
auto enumValues = splitStringRef( enums, ',' );
std::vector<StringRef> parsed;
parsed.reserve( enumValues.size() );
for( auto const& enumValue : enumValues ) {
parsed.push_back(trim(extractInstanceName(enumValue)));
for ( auto const& enumValue : enumValues ) {
parsed.push_back( trim( extractInstanceName( enumValue ) ) );
}
return parsed;
}
EnumInfo::~EnumInfo() {}
EnumInfo::~EnumInfo() = default;
StringRef EnumInfo::lookup( int value ) const {
for( auto const& valueToName : m_values ) {
if( valueToName.first == value )
return valueToName.second;
for ( auto const& valueToName : m_values ) {
if ( valueToName.first == value ) { return valueToName.second; }
}
return "{** unexpected enum value **}"_sr;
}
Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
Catch::Detail::unique_ptr<EnumInfo>
makeEnumInfo( StringRef enumName,
StringRef allValueNames,
std::vector<int> const& values ) {
auto enumInfo = Catch::Detail::make_unique<EnumInfo>();
enumInfo->m_name = enumName;
enumInfo->m_values.reserve( values.size() );
@@ -57,17 +60,22 @@ namespace Catch {
const auto valueNames = Catch::Detail::parseEnums( allValueNames );
assert( valueNames.size() == values.size() );
std::size_t i = 0;
for( auto value : values )
enumInfo->m_values.emplace_back(value, valueNames[i++]);
for ( auto value : values ) {
enumInfo->m_values.emplace_back( value, valueNames[i++] );
}
return enumInfo;
}
EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
return *m_enumInfos.back();
}
} // namespace Detail
} // Detail
} // Catch
Detail::EnumInfo const&
EnumValuesRegistry::registerEnum( StringRef enumName,
StringRef allValueNames,
std::vector<int> const& values ) {
m_enumInfos.push_back(
Detail::makeEnumInfo( enumName, allValueNames, values ) );
return *m_enumInfos.back();
}
} // namespace Catch

View File

@@ -8,29 +8,54 @@
#ifndef CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
#define CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_enum_values_registry.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <vector>
namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
std::vector<std::pair<int, StringRef>> m_values;
Catch::Detail::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
~EnumInfo();
class EnumValuesRegistry : public IMutableEnumValuesRegistry {
std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
StringRef lookup( int value ) const;
};
Detail::unique_ptr<EnumInfo>
makeEnumInfo( StringRef enumName,
StringRef allValueNames,
std::vector<int> const& values );
std::vector<StringRef> parseEnums( StringRef enums );
} // Detail
} // namespace Detail
} // Catch
class EnumValuesRegistry {
std::vector<Catch::Detail::unique_ptr<Detail::EnumInfo>> m_enumInfos;
public:
Detail::EnumInfo const& registerEnum( StringRef enumName,
StringRef allEnums,
std::vector<int> const& values );
template <typename E>
Detail::EnumInfo const&
registerEnum( StringRef enumName,
StringRef allEnums,
std::initializer_list<E> values ) {
static_assert( sizeof( int ) >= sizeof( E ),
"Cannot serialize enum to int" );
std::vector<int> intValues;
intValues.reserve( values.size() );
for ( auto enumValue : values ) {
intValues.push_back( static_cast<int>( enumValue ) );
}
return registerEnum( enumName, allEnums, intValues );
}
};
} // namespace Catch
#endif // CATCH_ENUM_VALUES_REGISTRY_HPP_INCLUDED

View File

@@ -6,18 +6,41 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_exception_translator_registry.hpp>
#include <catch2/interfaces/catch_interfaces_exception.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <vector>
namespace Catch {
ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
namespace {
static std::string tryTranslators(
std::vector<Detail::unique_ptr<IExceptionTranslator const>> const&
translators ) {
if ( translators.empty() ) {
std::rethrow_exception( std::current_exception() );
} else {
return translators[0]->translate( translators.begin() + 1,
translators.end() );
}
}
}
struct ExceptionTranslatorRegistry::ExceptionTranslatorRegistryImpl {
std::vector<Detail::unique_ptr<IExceptionTranslator const>>
translators;
};
ExceptionTranslatorRegistry::ExceptionTranslatorRegistry():
m_impl( Detail::make_unique<ExceptionTranslatorRegistryImpl>() ) {}
ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() = default;
void ExceptionTranslatorRegistry::registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator ) {
m_translators.push_back( CATCH_MOVE( translator ) );
m_impl->translators.push_back( CATCH_MOVE( translator ) );
}
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
@@ -37,7 +60,7 @@ namespace Catch {
// First we try user-registered translators. If none of them can
// handle the exception, it will be rethrown handled by our defaults.
try {
return tryTranslators();
return tryTranslators(m_impl->translators);
}
// To avoid having to handle TFE explicitly everywhere, we just
// rethrow it so that it goes back up the caller.
@@ -61,22 +84,10 @@ namespace Catch {
}
}
std::string ExceptionTranslatorRegistry::tryTranslators() const {
if (m_translators.empty()) {
std::rethrow_exception(std::current_exception());
} else {
return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
}
}
#else // ^^ Exceptions are enabled // Exceptions are disabled vv
std::string ExceptionTranslatorRegistry::translateActiveException() const {
CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
}
std::string ExceptionTranslatorRegistry::tryTranslators() const {
CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
}
#endif

View File

@@ -8,23 +8,22 @@
#ifndef CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
#define CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_exception.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <vector>
#include <string>
namespace Catch {
class IExceptionTranslator;
class ExceptionTranslatorRegistry {
struct ExceptionTranslatorRegistryImpl;
Detail::unique_ptr<ExceptionTranslatorRegistryImpl> m_impl;
class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
public:
~ExceptionTranslatorRegistry() override;
ExceptionTranslatorRegistry();
~ExceptionTranslatorRegistry();
void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator );
std::string translateActiveException() const override;
std::string tryTranslators() const;
private:
ExceptionTranslators m_translators;
std::string translateActiveException() const;
};
}

View File

@@ -28,7 +28,7 @@
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/internal/catch_windows_h_proxy.hpp>
#include <catch2/internal/catch_stdstreams.hpp>

View File

@@ -7,7 +7,7 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_leak_detector.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/catch_user_config.hpp>
#ifdef CATCH_CONFIG_WINDOWS_CRTDBG

View File

@@ -7,14 +7,14 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_list.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_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_reporter_registry.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/catch_config.hpp>
#include <catch2/catch_test_spec.hpp>
@@ -54,7 +54,7 @@ namespace Catch {
void listReporters(IEventListener& reporter) {
std::vector<ReporterDescription> descriptions;
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
auto const& factories = getRegistryHub().getReporterRegistry().getFactories();
descriptions.reserve(factories.size());
for (auto const& fac : factories) {
descriptions.push_back({ fac.first, fac.second->getDescription() });

View File

@@ -10,7 +10,7 @@
#include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <string>

View File

@@ -0,0 +1,114 @@
// 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 <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_test_case_registry_impl.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_exception_translator_registry.hpp>
#include <catch2/internal/catch_tag_alias_registry.hpp>
#include <catch2/internal/catch_startup_exception_registry.hpp>
#include <catch2/internal/catch_singletons.hpp>
#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>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
namespace Catch {
struct RegistryHub::RegistryHubImpl {
TestCaseRegistry testCaseRegistry;
ReporterRegistry reporterRegistry;
ExceptionTranslatorRegistry exceptionTranslatorRegistry;
TagAliasRegistry tagAliasRegistry;
StartupExceptionRegistry exceptionRegistry;
EnumValuesRegistry enumValuesRegistry;
};
RegistryHub::RegistryHub():
m_impl( Detail::make_unique<RegistryHubImpl>() ) {}
RegistryHub::~RegistryHub() = default;
ReporterRegistry const&
RegistryHub::getReporterRegistry() const {
return m_impl->reporterRegistry;
}
TestCaseRegistry const&
RegistryHub::getTestCaseRegistry() const {
return m_impl->testCaseRegistry;
}
ExceptionTranslatorRegistry const&
RegistryHub::getExceptionTranslatorRegistry() const {
return m_impl->exceptionTranslatorRegistry;
}
TagAliasRegistry const&
RegistryHub::getTagAliasRegistry() const {
return m_impl->tagAliasRegistry;
}
StartupExceptionRegistry const&
RegistryHub::getStartupExceptionRegistry() const {
return m_impl->exceptionRegistry;
}
void
RegistryHub::registerReporter( std::string const& name,
IReporterFactoryPtr factory ) {
m_impl->reporterRegistry.registerReporter( name, CATCH_MOVE( factory ) );
}
void RegistryHub::registerListener(
Detail::unique_ptr<EventListenerFactory> factory ) {
m_impl->reporterRegistry.registerListener( CATCH_MOVE( factory ) );
}
void RegistryHub::registerTest(
Detail::unique_ptr<TestCaseInfo>&& testInfo,
Detail::unique_ptr<ITestInvoker>&& invoker ) {
m_impl->testCaseRegistry.registerTest( CATCH_MOVE( testInfo ),
CATCH_MOVE( invoker ) );
}
void RegistryHub::registerTranslator(
Detail::unique_ptr<IExceptionTranslator>&& translator ) {
m_impl->exceptionTranslatorRegistry.registerTranslator(
CATCH_MOVE( translator ) );
}
void RegistryHub::registerTagAlias( std::string const& alias,
std::string const& tag,
SourceLineInfo const& lineInfo ) {
m_impl->tagAliasRegistry.add( alias, tag, lineInfo );
}
void RegistryHub::registerStartupException() noexcept {
#if !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS )
m_impl->exceptionRegistry.add( std::current_exception() );
#else
CATCH_INTERNAL_ERROR( "Attempted to register active exception under "
"CATCH_CONFIG_DISABLE_EXCEPTIONS!" );
#endif
}
EnumValuesRegistry& RegistryHub::getMutableEnumValuesRegistry() {
return m_impl->enumValuesRegistry;
}
using RegistryHubSingleton = Singleton<RegistryHub>;
RegistryHub const& getRegistryHub() {
return RegistryHubSingleton::get();
}
RegistryHub& getMutableRegistryHub() {
return RegistryHubSingleton::getMutable();
}
void cleanUp() {
cleanupSingletons();
cleanUpContext();
}
std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
}
} // end namespace Catch

View File

@@ -0,0 +1,67 @@
// 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_REGISTRY_HUB_HPP_INCLUDED
#define CATCH_REGISTRY_HUB_HPP_INCLUDED
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
namespace Catch {
class TestCaseHandle;
struct TestCaseInfo;
class TestCaseRegistry;
class ExceptionTranslatorRegistry;
class IExceptionTranslator;
class ReporterRegistry;
class IReporterFactory;
class TagAliasRegistry;
class ITestInvoker;
class EnumValuesRegistry;
struct SourceLineInfo;
class StartupExceptionRegistry;
class EventListenerFactory;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
class RegistryHub {
struct RegistryHubImpl;
Detail::unique_ptr<RegistryHubImpl> m_impl;
public:
RegistryHub();
~RegistryHub();
ReporterRegistry const& getReporterRegistry() const;
TestCaseRegistry const& getTestCaseRegistry() const;
TagAliasRegistry const& getTagAliasRegistry() const;
ExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const;
StartupExceptionRegistry const& getStartupExceptionRegistry() const;
void registerReporter( std::string const& name,
IReporterFactoryPtr factory );
void registerListener( Detail::unique_ptr<EventListenerFactory> factory );
void registerTest( Detail::unique_ptr<TestCaseInfo>&& testInfo,
Detail::unique_ptr<ITestInvoker>&& invoker );
void registerTranslator( Detail::unique_ptr<IExceptionTranslator>&& translator );
void registerTagAlias( std::string const& alias,
std::string const& tag,
SourceLineInfo const& lineInfo );
void registerStartupException() noexcept;
EnumValuesRegistry& getMutableEnumValuesRegistry();
};
RegistryHub const& getRegistryHub();
RegistryHub& getMutableRegistryHub();
void cleanUp();
std::string translateActiveException();
}
#endif // CATCH_REGISTRY_HUB_HPP_INCLUDED

View File

@@ -5,61 +5,86 @@
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/reporters/catch_reporter_automake.hpp>
#include <catch2/reporters/catch_reporter_compact.hpp>
#include <catch2/reporters/catch_reporter_console.hpp>
#include <catch2/reporters/catch_reporter_junit.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/reporters/catch_reporter_sonarqube.hpp>
#include <catch2/reporters/catch_reporter_tap.hpp>
#include <catch2/reporters/catch_reporter_teamcity.hpp>
#include <catch2/reporters/catch_reporter_xml.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_enforce.hpp>
namespace Catch {
struct ReporterRegistry::ReporterRegistryImpl {
std::vector<Detail::unique_ptr<EventListenerFactory>> listeners;
std::map<std::string, IReporterFactoryPtr, Detail::CaseInsensitiveLess>
factories;
};
ReporterRegistry::ReporterRegistry() {
ReporterRegistry::ReporterRegistry():
m_impl( Detail::make_unique<ReporterRegistryImpl>() ) {
// Because it is impossible to move out of initializer list,
// we have to add the elements manually
m_factories["Automake"] = Detail::make_unique<ReporterFactory<AutomakeReporter>>();
m_factories["compact"] = Detail::make_unique<ReporterFactory<CompactReporter>>();
m_factories["console"] = Detail::make_unique<ReporterFactory<ConsoleReporter>>();
m_factories["JUnit"] = Detail::make_unique<ReporterFactory<JunitReporter>>();
m_factories["SonarQube"] = Detail::make_unique<ReporterFactory<SonarQubeReporter>>();
m_factories["TAP"] = Detail::make_unique<ReporterFactory<TAPReporter>>();
m_factories["TeamCity"] = Detail::make_unique<ReporterFactory<TeamCityReporter>>();
m_factories["XML"] = Detail::make_unique<ReporterFactory<XmlReporter>>();
m_impl->factories["Automake"] =
Detail::make_unique<ReporterFactory<AutomakeReporter>>();
m_impl->factories["compact"] =
Detail::make_unique<ReporterFactory<CompactReporter>>();
m_impl->factories["console"] =
Detail::make_unique<ReporterFactory<ConsoleReporter>>();
m_impl->factories["JUnit"] =
Detail::make_unique<ReporterFactory<JunitReporter>>();
m_impl->factories["SonarQube"] =
Detail::make_unique<ReporterFactory<SonarQubeReporter>>();
m_impl->factories["TAP"] =
Detail::make_unique<ReporterFactory<TAPReporter>>();
m_impl->factories["TeamCity"] =
Detail::make_unique<ReporterFactory<TeamCityReporter>>();
m_impl->factories["XML"] =
Detail::make_unique<ReporterFactory<XmlReporter>>();
}
ReporterRegistry::~ReporterRegistry() = default;
IEventListenerPtr
ReporterRegistry::create( std::string const& name,
ReporterConfig&& config ) const {
auto it = m_impl->factories.find( name );
if ( it == m_impl->factories.end() ) return nullptr;
return it->second->create( CATCH_MOVE( config ) );
IEventListenerPtr ReporterRegistry::create( std::string const& name, ReporterConfig&& config ) const {
auto it = m_factories.find( name );
if( it == m_factories.end() )
return nullptr;
return it->second->create( CATCH_MOVE(config) );
return IEventListenerPtr();
}
void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr factory ) {
void ReporterRegistry::registerReporter( std::string const& name,
IReporterFactoryPtr factory ) {
CATCH_ENFORCE( name.find( "::" ) == name.npos,
"'::' is not allowed in reporter name: '" + name + '\'' );
auto ret = m_factories.emplace(name, CATCH_MOVE(factory));
CATCH_ENFORCE( ret.second, "reporter using '" + name + "' as name was already registered" );
"'::' is not allowed in reporter name: '" + name +
'\'' );
auto ret = m_impl->factories.emplace( name, CATCH_MOVE( factory ) );
CATCH_ENFORCE( ret.second,
"reporter using '" + name +
"' as name was already registered" );
}
void ReporterRegistry::registerListener(
Detail::unique_ptr<EventListenerFactory> factory ) {
m_listeners.push_back( CATCH_MOVE(factory) );
m_impl->listeners.push_back( CATCH_MOVE( factory ) );
}
IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
return m_factories;
}
IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
return m_listeners;
std::map<std::string,
IReporterFactoryPtr,
Detail::CaseInsensitiveLess> const&
ReporterRegistry::getFactories() const {
return m_impl->factories;
}
}
std::vector<Detail::unique_ptr<EventListenerFactory>> const&
ReporterRegistry::getListeners() const {
return m_impl->listeners;
}
} // namespace Catch

View File

@@ -8,31 +8,48 @@
#ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
#define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/interfaces/catch_interfaces_reporter_registry.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <map>
#include <string>
#include <vector>
namespace Catch {
class ReporterRegistry : public IReporterRegistry {
class IEventListener;
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
class IReporterFactory;
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;
struct ReporterConfig;
class EventListenerFactory;
class ReporterRegistry {
struct ReporterRegistryImpl;
Detail::unique_ptr<ReporterRegistryImpl> m_impl;
public:
ReporterRegistry();
~ReporterRegistry() override; // = default, out of line to allow fwd decl
~ReporterRegistry(); // = default;
IEventListenerPtr create( std::string const& name, ReporterConfig&& config ) const override;
IEventListenerPtr create( std::string const& name,
ReporterConfig&& config ) const;
void registerReporter( std::string const& name, IReporterFactoryPtr factory );
void registerListener( Detail::unique_ptr<EventListenerFactory> factory );
void registerReporter( std::string const& name,
IReporterFactoryPtr factory );
FactoryMap const& getFactories() const override;
Listeners const& getListeners() const override;
void
registerListener( Detail::unique_ptr<EventListenerFactory> factory );
private:
FactoryMap m_factories;
Listeners m_listeners;
std::map<std::string,
IReporterFactoryPtr,
Detail::CaseInsensitiveLess> const&
getFactories() const;
std::vector<Detail::unique_ptr<EventListenerFactory>> const&
getListeners() const;
};
}
} // end namespace Catch
#endif // CATCH_REPORTER_REGISTRY_HPP_INCLUDED

View File

@@ -7,7 +7,11 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/catch_user_config.hpp>
#include <catch2/catch_timer.hpp>
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
@@ -15,10 +19,14 @@
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_fatal_condition_handler.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/catch_timer.hpp>
#include <catch2/internal/catch_output_redirect.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_fatal_condition_handler.hpp>
#include <catch2/internal/catch_test_case_tracker.hpp>
#include <catch2/catch_message.hpp>
#include <cassert>
#include <algorithm>
@@ -164,30 +172,44 @@ namespace Catch {
} // namespace
}
RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter)
: m_runInfo(_config->name()),
struct RunContext::RunContextImpl {
Optional<AssertionResult> lastResult;
FatalConditionHandler fatalConditionhandler;
TrackerContext trackerContext;
std::vector<MessageInfo> messages;
// Fake owners for unscoped messages
std::vector<ScopedMessage> messageScopes;
IEventListenerPtr reporter;
std::vector<SectionEndInfo> unfinishedSections;
std::vector<ITracker*> activeSections;
};
RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter):
m_impl( Detail::make_unique<RunContextImpl>() ),
m_runInfo(_config->name()),
m_config(_config),
m_reporter(CATCH_MOVE(reporter)),
m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
m_includeSuccessfulResults( m_config->includeSuccessfulResults() || reporter->getPreferences().shouldReportAllAssertions )
{
getCurrentMutableContext().setResultCapture( this );
m_reporter->testRunStarting(m_runInfo);
getCurrentMutableContext().setResultCapture(this);
m_impl->reporter = CATCH_MOVE( reporter );
m_impl->reporter->testRunStarting(m_runInfo);
}
RunContext::~RunContext() {
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
m_impl->reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
}
Totals RunContext::runTest(TestCaseHandle const& testCase) {
const Totals prevTotals = m_totals;
auto const& testInfo = testCase.getTestCaseInfo();
m_reporter->testCaseStarting(testInfo);
m_impl->reporter->testCaseStarting( testInfo );
m_activeTestCase = &testCase;
ITracker& rootTracker = m_trackerContext.startRun();
ITracker& rootTracker = m_impl->trackerContext.startRun();
assert(rootTracker.isSectionTracker());
static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
@@ -228,10 +250,10 @@ namespace Catch {
std::string redirectedCout;
std::string redirectedCerr;
do {
m_trackerContext.startCycle();
m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocationRef(testInfo.name, testInfo.lineInfo));
m_impl->trackerContext.startCycle();
m_testCaseTracker = &SectionTracker::acquire(m_impl->trackerContext, TestCaseTracking::NameAndLocationRef(testInfo.name, testInfo.lineInfo));
m_reporter->testCasePartialStarting(testInfo, testRuns);
m_impl->reporter->testCasePartialStarting( testInfo, testRuns );
const auto beforeRunTotals = m_totals;
std::string oneRunCout, oneRunCerr;
@@ -242,7 +264,7 @@ namespace Catch {
const auto singleRunTotals = m_totals.delta(beforeRunTotals);
auto statsForOneRun = TestCaseStats(testInfo, singleRunTotals, CATCH_MOVE(oneRunCout), CATCH_MOVE(oneRunCerr), aborting());
m_reporter->testCasePartialEnded(statsForOneRun, testRuns);
m_impl->reporter->testCasePartialEnded( statsForOneRun, testRuns );
++testRuns;
} while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
@@ -253,11 +275,12 @@ namespace Catch {
deltaTotals.testCases.failed++;
}
m_totals.testCases += deltaTotals.testCases;
m_reporter->testCaseEnded(TestCaseStats(testInfo,
deltaTotals,
CATCH_MOVE(redirectedCout),
CATCH_MOVE(redirectedCerr),
aborting()));
m_impl->reporter->testCaseEnded(
TestCaseStats( testInfo,
deltaTotals,
CATCH_MOVE( redirectedCout ),
CATCH_MOVE( redirectedCerr ),
aborting() ) );
m_activeTestCase = nullptr;
m_testCaseTracker = nullptr;
@@ -286,14 +309,15 @@ namespace Catch {
m_lastAssertionPassed = true;
}
m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals));
m_impl->reporter->assertionEnded(AssertionStats(result, m_impl->messages, m_totals));
if (result.getResultType() != ResultWas::Warning)
m_messageScopes.clear();
if ( result.getResultType() != ResultWas::Warning ) {
m_impl->messageScopes.clear();
}
// Reset working state
resetAssertionInfo();
m_lastResult = result;
m_impl->lastResult = result;
}
void RunContext::resetAssertionInfo() {
m_lastAssertionInfo.macroName = StringRef();
@@ -302,18 +326,18 @@ namespace Catch {
bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) {
ITracker& sectionTracker =
SectionTracker::acquire( m_trackerContext,
SectionTracker::acquire( m_impl->trackerContext,
TestCaseTracking::NameAndLocationRef(
sectionName, sectionLineInfo ) );
if (!sectionTracker.isOpen())
return false;
m_activeSections.push_back(&sectionTracker);
m_impl->activeSections.push_back(&sectionTracker);
SectionInfo sectionInfo( sectionLineInfo, static_cast<std::string>(sectionName) );
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
m_reporter->sectionStarting(sectionInfo);
m_impl->reporter->sectionStarting( sectionInfo );
assertions = m_totals.assertions;
@@ -324,7 +348,7 @@ namespace Catch {
SourceLineInfo const& lineInfo ) {
using namespace Generators;
GeneratorTracker* tracker = GeneratorTracker::acquire(
m_trackerContext,
m_impl->trackerContext,
TestCaseTracking::NameAndLocationRef(
generatorName, lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo;
@@ -337,13 +361,13 @@ namespace Catch {
Generators::GeneratorBasePtr&& generator ) {
auto nameAndLoc = TestCaseTracking::NameAndLocation( static_cast<std::string>( generatorName ), lineInfo );
auto& currentTracker = m_trackerContext.currentTracker();
auto& currentTracker = m_impl->trackerContext.currentTracker();
assert(
currentTracker.nameAndLocation() != nameAndLoc &&
"Trying to create tracker for a genreator that already has one" );
auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>(
CATCH_MOVE(nameAndLoc), m_trackerContext, &currentTracker );
CATCH_MOVE(nameAndLoc), m_impl->trackerContext, &currentTracker );
auto ret = newTracker.get();
currentTracker.addChild( CATCH_MOVE( newTracker ) );
@@ -357,7 +381,7 @@ namespace Catch {
return false;
if (!m_config->warnAboutMissingAssertions())
return false;
if (m_trackerContext.currentTracker().hasChildren())
if (m_impl->trackerContext.currentTracker().hasChildren())
return false;
m_totals.assertions.failed++;
assertions.failed++;
@@ -368,50 +392,57 @@ namespace Catch {
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
bool missingAssertions = testForMissingAssertions(assertions);
if (!m_activeSections.empty()) {
m_activeSections.back()->close();
m_activeSections.pop_back();
if (!m_impl->activeSections.empty()) {
m_impl->activeSections.back()->close();
m_impl->activeSections.pop_back();
}
m_reporter->sectionEnded(SectionStats(CATCH_MOVE(endInfo.sectionInfo), assertions, endInfo.durationInSeconds, missingAssertions));
m_messages.clear();
m_messageScopes.clear();
m_impl->reporter->sectionEnded(
SectionStats( CATCH_MOVE( endInfo.sectionInfo ),
assertions,
endInfo.durationInSeconds,
missingAssertions ) );
m_impl->messages.clear();
m_impl->messageScopes.clear();
}
void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) {
if ( m_unfinishedSections.empty() ) {
m_activeSections.back()->fail();
if ( m_impl->unfinishedSections.empty() ) {
m_impl->activeSections.back()->fail();
} else {
m_activeSections.back()->close();
m_impl->activeSections.back()->close();
}
m_activeSections.pop_back();
m_impl->activeSections.pop_back();
m_unfinishedSections.push_back(CATCH_MOVE(endInfo));
m_impl->unfinishedSections.push_back(CATCH_MOVE(endInfo));
}
void RunContext::benchmarkPreparing( StringRef name ) {
m_reporter->benchmarkPreparing(name);
m_impl->reporter->benchmarkPreparing( name );
}
void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
m_reporter->benchmarkStarting( info );
m_impl->reporter->benchmarkStarting( info );
}
void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
m_reporter->benchmarkEnded( stats );
m_impl->reporter->benchmarkEnded( stats );
}
void RunContext::benchmarkFailed( StringRef error ) {
m_reporter->benchmarkFailed( error );
m_impl->reporter->benchmarkFailed( error );
}
void RunContext::pushScopedMessage(MessageInfo const & message) {
m_messages.push_back(message);
m_impl->messages.push_back(message);
}
void RunContext::popScopedMessage(MessageInfo const & message) {
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
m_impl->messages.erase( std::remove( m_impl->messages.begin(),
m_impl->messages.end(),
message ),
m_impl->messages.end() );
}
void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) {
m_messageScopes.emplace_back( CATCH_MOVE(builder) );
m_impl->messageScopes.emplace_back( CATCH_MOVE(builder) );
}
std::string RunContext::getCurrentTestName() const {
@@ -421,7 +452,7 @@ namespace Catch {
}
const AssertionResult * RunContext::getLastResult() const {
return &(*m_lastResult);
return &(*m_impl->lastResult);
}
void RunContext::exceptionEarlyReported() {
@@ -430,7 +461,7 @@ namespace Catch {
void RunContext::handleFatalErrorCondition( StringRef message ) {
// First notify reporter that bad things happened
m_reporter->fatalErrorEncountered(message);
m_impl->reporter->fatalErrorEncountered(message);
// Don't rebuild the result -- the stringification itself can cause more fatal errors
// Instead, fake a result data.
@@ -449,20 +480,20 @@ namespace Catch {
Counts assertions;
assertions.failed = 1;
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, 0, false);
m_reporter->sectionEnded(testCaseSectionStats);
m_impl->reporter->sectionEnded(testCaseSectionStats);
auto const& testInfo = m_activeTestCase->getTestCaseInfo();
Totals deltaTotals;
deltaTotals.testCases.failed = 1;
deltaTotals.assertions.failed = 1;
m_reporter->testCaseEnded(TestCaseStats(testInfo,
m_impl->reporter->testCaseEnded(TestCaseStats(testInfo,
deltaTotals,
std::string(),
std::string(),
false));
m_totals.testCases.failed++;
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
m_impl->reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
}
bool RunContext::lastAssertionPassed() {
@@ -473,7 +504,7 @@ namespace Catch {
m_lastAssertionPassed = true;
++m_totals.assertions.passed;
resetAssertionInfo();
m_messageScopes.clear();
m_impl->messageScopes.clear();
}
bool RunContext::aborting() const {
@@ -483,7 +514,7 @@ namespace Catch {
void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
m_reporter->sectionStarting(testCaseSection);
m_impl->reporter->sectionStarting(testCaseSection);
Counts prevAssertions = m_totals.assertions;
double duration = 0;
m_shouldReportUnexpected = true;
@@ -491,7 +522,7 @@ namespace Catch {
Timer timer;
CATCH_TRY {
if (m_reporter->getPreferences().shouldRedirectStdOut) {
if (m_impl->reporter->getPreferences().shouldRedirectStdOut) {
#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
@@ -524,18 +555,18 @@ namespace Catch {
m_testCaseTracker->close();
handleUnfinishedSections();
m_messages.clear();
m_messageScopes.clear();
m_impl->messages.clear();
m_impl->messageScopes.clear();
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions);
m_reporter->sectionEnded(testCaseSectionStats);
m_impl->reporter->sectionEnded(testCaseSectionStats);
}
void RunContext::invokeActiveTestCase() {
// We need to engage a handler for signals/structured exceptions
// before running the tests themselves, or the binary can crash
// without failed test being reported.
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
FatalConditionHandlerGuard _(&m_impl->fatalConditionhandler);
// We keep having issue where some compilers warn about an unused
// variable, even though the type has non-trivial constructor and
// destructor. This is annoying and ugly, but it makes them stfu.
@@ -547,12 +578,12 @@ namespace Catch {
void RunContext::handleUnfinishedSections() {
// If sections ended prematurely due to an exception we stored their
// infos here so we can tear them down outside the unwind process.
for (auto it = m_unfinishedSections.rbegin(),
itEnd = m_unfinishedSections.rend();
for (auto it = m_impl->unfinishedSections.rbegin(),
itEnd = m_impl->unfinishedSections.rend();
it != itEnd;
++it)
sectionEnded(CATCH_MOVE(*it));
m_unfinishedSections.clear();
m_impl->unfinishedSections.clear();
}
void RunContext::handleExpr(
@@ -560,7 +591,7 @@ namespace Catch {
ITransientExpression const& expr,
AssertionReaction& reaction
) {
m_reporter->assertionStarting( info );
m_impl->reporter->assertionStarting( info );
bool negated = isFalseTest( info.resultDisposition );
bool result = expr.getResult() != negated;
@@ -599,7 +630,7 @@ namespace Catch {
StringRef message,
AssertionReaction& reaction
) {
m_reporter->assertionStarting( info );
m_impl->reporter->assertionStarting( info );
m_lastAssertionInfo = info;
@@ -669,7 +700,7 @@ namespace Catch {
}
IResultCapture& getResultCapture() {
RunContext& getResultCapture() {
if (auto* capture = getCurrentContext().getResultCapture())
return *capture;
else

View File

@@ -8,36 +8,60 @@
#ifndef CATCH_RUN_CONTEXT_HPP_INCLUDED
#define CATCH_RUN_CONTEXT_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_test_registry.hpp>
#include <catch2/internal/catch_fatal_condition_handler.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/catch_message.hpp>
#include <catch2/catch_test_run_info.hpp>
#include <catch2/catch_totals.hpp>
#include <catch2/internal/catch_test_case_tracker.hpp>
#include <catch2/catch_assertion_info.hpp>
#include <catch2/catch_assertion_result.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_benchmark_stats_fwd.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <string>
#include <chrono>
namespace Catch {
class TestCaseHandle;
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<GeneratorUntypedBase>;
}
class IGeneratorTracker;
class IConfig;
// Fixme: Take out the namespace?
namespace TestCaseTracking {
class ITracker;
}
using TestCaseTracking::ITracker;
///////////////////////////////////////////////////////////////////////////
class RunContext final : public IResultCapture {
class IEventListener;
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
class RunContext {
struct RunContextImpl;
Detail::unique_ptr<RunContextImpl> m_impl;
public:
RunContext( RunContext const& ) = delete;
RunContext& operator =( RunContext const& ) = delete;
explicit RunContext( IConfig const* _config, IEventListenerPtr&& reporter );
~RunContext() override;
~RunContext();
Totals runTest(TestCaseHandle const& testCase);
@@ -47,63 +71,63 @@ namespace Catch {
void handleExpr
( AssertionInfo const& info,
ITransientExpression const& expr,
AssertionReaction& reaction ) override;
AssertionReaction& reaction );
void handleMessage
( AssertionInfo const& info,
ResultWas::OfType resultType,
StringRef message,
AssertionReaction& reaction ) override;
AssertionReaction& reaction );
void handleUnexpectedExceptionNotThrown
( AssertionInfo const& info,
AssertionReaction& reaction ) override;
AssertionReaction& reaction );
void handleUnexpectedInflightException
( AssertionInfo const& info,
std::string&& message,
AssertionReaction& reaction ) override;
AssertionReaction& reaction );
void handleIncomplete
( AssertionInfo const& info ) override;
( AssertionInfo const& info );
void handleNonExpr
( AssertionInfo const &info,
ResultWas::OfType resultType,
AssertionReaction &reaction ) override;
AssertionReaction &reaction );
bool sectionStarted( StringRef sectionName,
SourceLineInfo const& sectionLineInfo,
Counts& assertions ) override;
Counts& assertions );
void sectionEnded( SectionEndInfo&& endInfo ) override;
void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
void sectionEnded( SectionEndInfo&& endInfo );
void sectionEndedEarly( SectionEndInfo&& endInfo );
IGeneratorTracker*
acquireGeneratorTracker( StringRef generatorName,
SourceLineInfo const& lineInfo ) override;
SourceLineInfo const& lineInfo );
IGeneratorTracker* createGeneratorTracker(
StringRef generatorName,
SourceLineInfo lineInfo,
Generators::GeneratorBasePtr&& generator ) override;
Generators::GeneratorBasePtr&& generator );
void benchmarkPreparing( StringRef name ) override;
void benchmarkStarting( BenchmarkInfo const& info ) override;
void benchmarkEnded( BenchmarkStats<> const& stats ) override;
void benchmarkFailed( StringRef error ) override;
void benchmarkPreparing( StringRef name );
void benchmarkStarting( BenchmarkInfo const& info );
void benchmarkEnded( BenchmarkStats<> const& stats );
void benchmarkFailed( StringRef error );
void pushScopedMessage( MessageInfo const& message ) override;
void popScopedMessage( MessageInfo const& message ) override;
void pushScopedMessage( MessageInfo const& message );
void popScopedMessage( MessageInfo const& message );
void emplaceUnscopedMessage( MessageBuilder&& builder ) override;
void emplaceUnscopedMessage( MessageBuilder&& builder );
std::string getCurrentTestName() const override;
std::string getCurrentTestName() const;
const AssertionResult* getLastResult() const override;
const AssertionResult* getLastResult() const;
void exceptionEarlyReported() override;
void exceptionEarlyReported();
void handleFatalErrorCondition( StringRef message ) override;
void handleFatalErrorCondition( StringRef message );
bool lastAssertionPassed() override;
bool lastAssertionPassed();
void assertionPassed() override;
void assertionPassed();
public:
// !TBD We need to do this another way!
@@ -133,18 +157,10 @@ namespace Catch {
TestRunInfo m_runInfo;
TestCaseHandle const* m_activeTestCase = nullptr;
ITracker* m_testCaseTracker = nullptr;
Optional<AssertionResult> m_lastResult;
IConfig const* m_config;
Totals m_totals;
IEventListenerPtr m_reporter;
std::vector<MessageInfo> m_messages;
std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
AssertionInfo m_lastAssertionInfo;
std::vector<SectionEndInfo> m_unfinishedSections;
std::vector<ITracker*> m_activeSections;
TrackerContext m_trackerContext;
FatalConditionHandler m_fatalConditionhandler;
bool m_lastAssertionPassed = false;
bool m_shouldReportUnexpected = true;
bool m_includeSuccessfulResults;
@@ -152,6 +168,9 @@ namespace Catch {
void seedRng(IConfig const& config);
unsigned int rngSeed();
RunContext& getResultCapture();
} // end namespace Catch
#endif // CATCH_RUN_CONTEXT_HPP_INCLUDED

View File

@@ -8,16 +8,24 @@
#include <catch2/internal/catch_tag_alias_registry.hpp>
#include <catch2/internal/catch_console_colour.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_string_manip.hpp>
namespace Catch {
#include <map>
TagAliasRegistry::~TagAliasRegistry() {}
namespace Catch {
struct TagAliasRegistry::TagAliasRegistryImpl {
std::map<std::string, TagAlias> registry;
};
TagAliasRegistry::TagAliasRegistry():
m_impl( Detail::make_unique<TagAliasRegistryImpl>() ){}
TagAliasRegistry::~TagAliasRegistry() = default;
TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
auto it = m_registry.find( alias );
if( it != m_registry.end() )
auto it = m_impl->registry.find( alias );
if( it != m_impl->registry.end() )
return &(it->second);
else
return nullptr;
@@ -25,7 +33,7 @@ namespace Catch {
std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
std::string expandedTestSpec = unexpandedTestSpec;
for( auto const& registryKvp : m_registry ) {
for( auto const& registryKvp : m_impl->registry ) {
std::size_t pos = expandedTestSpec.find( registryKvp.first );
if( pos != std::string::npos ) {
expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
@@ -40,15 +48,13 @@ namespace Catch {
CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
"error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
CATCH_ENFORCE( m_impl->registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
"error: tag alias, '" << alias << "' already registered.\n"
<< "\tFirst seen at: " << find(alias)->lineInfo << "\n"
<< "\tRedefined at: " << lineInfo );
}
ITagAliasRegistry::~ITagAliasRegistry() = default;
ITagAliasRegistry const& ITagAliasRegistry::get() {
TagAliasRegistry const& TagAliasRegistry::get() {
return getRegistryHub().getTagAliasRegistry();
}

View File

@@ -8,24 +8,30 @@
#ifndef CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
#define CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <catch2/catch_tag_alias.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <map>
#include <string>
namespace Catch {
struct SourceLineInfo;
class TagAliasRegistry : public ITagAliasRegistry {
class TagAliasRegistry {
struct TagAliasRegistryImpl;
Detail::unique_ptr<TagAliasRegistryImpl> m_impl;
public:
~TagAliasRegistry() override;
TagAlias const* find( std::string const& alias ) const override;
std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
TagAliasRegistry();
~TagAliasRegistry(); // = default;
//! Nullptr if not present
TagAlias const* find( std::string const& alias ) const;
//! Returns the test spec but with expanded aliases
std::string expandAliases( std::string const& unexpandedTestSpec ) const;
void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
static TagAliasRegistry const& get();
private:
std::map<std::string, TagAlias> m_registry;
};
} // end namespace Catch

View File

@@ -10,7 +10,7 @@
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_run_context.hpp>
#include <catch2/internal/catch_sharding.hpp>
@@ -24,6 +24,54 @@
namespace Catch {
namespace {
static bool matchTest( TestCaseHandle const& testCase,
TestSpec const& testSpec,
IConfig const& config ) {
return testSpec.matches( testCase.getTestCaseInfo() ) &&
isThrowSafe( testCase, config );
}
static void enforceNoDuplicateTestCases(
std::vector<TestCaseHandle> const& tests ) {
auto testInfoCmp = []( TestCaseInfo const* lhs,
TestCaseInfo const* rhs ) {
return *lhs < *rhs;
};
std::set<TestCaseInfo const*, decltype( testInfoCmp )&> seenTests(
testInfoCmp );
for ( auto const& test : tests ) {
const auto infoPtr = &test.getTestCaseInfo();
const auto prev = seenTests.insert( infoPtr );
CATCH_ENFORCE( prev.second,
"error: test case \""
<< infoPtr->name << "\", with tags \""
<< infoPtr->tagsAsString()
<< "\" already defined.\n"
<< "\tFirst seen at "
<< ( *prev.first )->lineInfo << "\n"
<< "\tRedefined at " << infoPtr->lineInfo );
}
}
} // namespace
struct TestCaseRegistry::TestCaseRegistryImpl {
std::vector<Detail::unique_ptr<TestCaseInfo>> owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.
// We should get rid of that eventually (see interface note)
std::vector<TestCaseInfo*> viewed_test_infos;
std::vector<Detail::unique_ptr<ITestInvoker>> invokers;
std::vector<TestCaseHandle> handles;
mutable TestRunOrder currentSortOrder = TestRunOrder::Declared;
mutable std::vector<TestCaseHandle> sortedFunctions;
};
TestCaseRegistry::TestCaseRegistry():
m_impl( Detail::make_unique<TestCaseRegistryImpl>() ) {}
TestCaseRegistry ::~TestCaseRegistry() = default;
std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases ) {
switch (config.runOrder()) {
case TestRunOrder::Declared:
@@ -80,29 +128,6 @@ namespace Catch {
return !testCase.getTestCaseInfo().throws() || config.allowThrows();
}
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config ) {
return testSpec.matches( testCase.getTestCaseInfo() ) && isThrowSafe( testCase, config );
}
void
enforceNoDuplicateTestCases( std::vector<TestCaseHandle> const& tests ) {
auto testInfoCmp = []( TestCaseInfo const* lhs,
TestCaseInfo const* rhs ) {
return *lhs < *rhs;
};
std::set<TestCaseInfo const*, decltype(testInfoCmp) &> seenTests(testInfoCmp);
for ( auto const& test : tests ) {
const auto infoPtr = &test.getTestCaseInfo();
const auto prev = seenTests.insert( infoPtr );
CATCH_ENFORCE(
prev.second,
"error: test case \"" << infoPtr->name << "\", with tags \""
<< infoPtr->tagsAsString() << "\" already defined.\n"
<< "\tFirst seen at " << ( *prev.first )->lineInfo << "\n"
<< "\tRedefined at " << infoPtr->lineInfo );
}
}
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
std::vector<TestCaseHandle> filtered;
filtered.reserve( testCases.size() );
@@ -118,29 +143,29 @@ namespace Catch {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
void TestRegistry::registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker) {
m_handles.emplace_back(testInfo.get(), testInvoker.get());
m_viewed_test_infos.push_back(testInfo.get());
m_owned_test_infos.push_back(CATCH_MOVE(testInfo));
m_invokers.push_back(CATCH_MOVE(testInvoker));
void TestCaseRegistry::registerTest(Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker) {
m_impl->handles.emplace_back(testInfo.get(), testInvoker.get());
m_impl->viewed_test_infos.push_back(testInfo.get());
m_impl->owned_test_infos.push_back(CATCH_MOVE(testInfo));
m_impl->invokers.push_back(CATCH_MOVE(testInvoker));
}
std::vector<TestCaseInfo*> const& TestRegistry::getAllInfos() const {
return m_viewed_test_infos;
std::vector<TestCaseInfo*> const& TestCaseRegistry::getAllInfos() const {
return m_impl->viewed_test_infos;
}
std::vector<TestCaseHandle> const& TestRegistry::getAllTests() const {
return m_handles;
std::vector<TestCaseHandle> const& TestCaseRegistry::getAllTests() const {
return m_impl->handles;
}
std::vector<TestCaseHandle> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
if( m_sortedFunctions.empty() )
enforceNoDuplicateTestCases( m_handles );
std::vector<TestCaseHandle> const& TestCaseRegistry::getAllTestsSorted( IConfig const& config ) const {
if( m_impl->sortedFunctions.empty() )
enforceNoDuplicateTestCases( m_impl->handles );
if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
m_sortedFunctions = sortTests( config, m_handles );
m_currentSortOrder = config.runOrder();
if( m_impl->currentSortOrder != config.runOrder() || m_impl->sortedFunctions.empty() ) {
m_impl->sortedFunctions = sortTests( config, m_impl->handles );
m_impl->currentSortOrder = config.runOrder();
}
return m_sortedFunctions;
return m_impl->sortedFunctions;
}
} // end namespace Catch

View File

@@ -8,8 +8,6 @@
#ifndef CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#define CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#include <catch2/interfaces/catch_interfaces_testcase.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/internal/catch_unique_ptr.hpp>
#include <vector>
@@ -19,37 +17,28 @@ namespace Catch {
class TestCaseHandle;
class IConfig;
class TestSpec;
class ITestInvoker;
struct TestCaseInfo;
std::vector<TestCaseHandle> sortTests( IConfig const& config, std::vector<TestCaseHandle> const& unsortedTestCases );
bool isThrowSafe( TestCaseHandle const& testCase, IConfig const& config );
bool matchTest( TestCaseHandle const& testCase, TestSpec const& testSpec, IConfig const& config );
void enforceNoDuplicateTestCases( std::vector<TestCaseHandle> const& functions );
std::vector<TestCaseHandle> filterTests( std::vector<TestCaseHandle> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config );
class TestRegistry : public ITestCaseRegistry {
class TestCaseRegistry {
struct TestCaseRegistryImpl;
Detail::unique_ptr<TestCaseRegistryImpl> m_impl;
public:
~TestRegistry() override = default;
TestCaseRegistry();
~TestCaseRegistry(); // = default;
void registerTest( Detail::unique_ptr<TestCaseInfo> testInfo, Detail::unique_ptr<ITestInvoker> testInvoker );
std::vector<TestCaseInfo*> const& getAllInfos() const override;
std::vector<TestCaseHandle> const& getAllTests() const override;
std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const override;
private:
std::vector<Detail::unique_ptr<TestCaseInfo>> m_owned_test_infos;
// Keeps a materialized vector for `getAllInfos`.
// We should get rid of that eventually (see interface note)
std::vector<TestCaseInfo*> m_viewed_test_infos;
std::vector<Detail::unique_ptr<ITestInvoker>> m_invokers;
std::vector<TestCaseHandle> m_handles;
mutable TestRunOrder m_currentSortOrder = TestRunOrder::Declared;
mutable std::vector<TestCaseHandle> m_sortedFunctions;
std::vector<TestCaseInfo*> const& getAllInfos() const;
std::vector<TestCaseHandle> const& getAllTests() const;
std::vector<TestCaseHandle> const& getAllTestsSorted( IConfig const& config ) const;
};
///////////////////////////////////////////////////////////////////////////

View File

@@ -10,7 +10,6 @@
#include <catch2/catch_user_config.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_source_line_info.hpp>

View File

@@ -8,7 +8,7 @@
#include <catch2/internal/catch_test_registry.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>

View File

@@ -8,13 +8,13 @@
#include <catch2/internal/catch_test_spec_parser.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <catch2/internal/catch_tag_alias_registry.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch {
TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
TestSpecParser::TestSpecParser( TagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
m_mode = None;

View File

@@ -20,7 +20,7 @@
namespace Catch {
class ITagAliasRegistry;
class TagAliasRegistry;
class TestSpecParser {
enum Mode{ None, Name, QuotedName, Tag, EscapedName };
@@ -35,10 +35,10 @@ namespace Catch {
std::vector<std::size_t> m_escapeChars;
TestSpec::Filter m_currentFilter;
TestSpec m_testSpec;
ITagAliasRegistry const* m_tagAliases = nullptr;
TagAliasRegistry const* m_tagAliases = nullptr;
public:
TestSpecParser( ITagAliasRegistry const& tagAliases );
TestSpecParser( TagAliasRegistry const& tagAliases );
TestSpecParser& parse( std::string const& arg );
TestSpec testSpec();

View File

@@ -8,7 +8,7 @@
#include <catch2/matchers/internal/catch_matchers_impl.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch {

View File

@@ -56,18 +56,14 @@ internal_headers = [
'generators/catch_generators_random.hpp',
'generators/catch_generators_range.hpp',
'interfaces/catch_interfaces_all.hpp',
'interfaces/catch_interfaces_capture.hpp',
'interfaces/catch_interfaces_config.hpp',
'interfaces/catch_interfaces_enum_values_registry.hpp',
'interfaces/catch_interfaces_exception.hpp',
'interfaces/catch_interfaces_generatortracker.hpp',
'interfaces/catch_interfaces_registry_hub.hpp',
'interfaces/catch_interfaces_reporter.hpp',
'interfaces/catch_interfaces_reporter_factory.hpp',
'interfaces/catch_interfaces_reporter_registry.hpp',
'interfaces/catch_interfaces_tag_alias_registry.hpp',
'interfaces/catch_interfaces_testcase.hpp',
'internal/catch_assertion_handler.hpp',
'internal/catch_benchmark_stats_fwd.hpp',
'internal/catch_case_insensitive_comparisons.hpp',
'internal/catch_case_sensitive.hpp',
'internal/catch_clara.hpp',
@@ -169,6 +165,7 @@ internal_headers = [
'catch_template_test_macros.hpp',
'catch_test_case_info.hpp',
'catch_test_macros.hpp',
'catch_test_run_info.hpp',
'catch_test_spec.hpp',
'catch_timer.hpp',
'catch_tostring.hpp',
@@ -182,14 +179,11 @@ internal_sources = files(
'generators/catch_generator_exception.cpp',
'generators/catch_generators.cpp',
'generators/catch_generators_random.cpp',
'interfaces/catch_interfaces_capture.cpp',
'interfaces/catch_interfaces_config.cpp',
'interfaces/catch_interfaces_exception.cpp',
'interfaces/catch_interfaces_generatortracker.cpp',
'interfaces/catch_interfaces_registry_hub.cpp',
'interfaces/catch_interfaces_reporter.cpp',
'interfaces/catch_interfaces_reporter_factory.cpp',
'interfaces/catch_interfaces_reporter_registry.cpp',
'interfaces/catch_interfaces_testcase.cpp',
'internal/catch_assertion_handler.cpp',
'internal/catch_case_insensitive_comparisons.cpp',
@@ -217,6 +211,7 @@ internal_sources = files(
'internal/catch_polyfills.cpp',
'internal/catch_random_number_generator.cpp',
'internal/catch_random_seed_generation.cpp',
'internal/catch_registry_hub.cpp',
'internal/catch_reporter_registry.cpp',
'internal/catch_reporter_spec_parser.cpp',
'internal/catch_result_type.cpp',
@@ -254,7 +249,6 @@ internal_sources = files(
'catch_config.cpp',
'catch_get_random_seed.cpp',
'catch_message.cpp',
'catch_registry_hub.cpp',
'catch_session.cpp',
'catch_tag_alias_autoregistrar.cpp',
'catch_test_case_info.cpp',
@@ -262,6 +256,7 @@ internal_sources = files(
'catch_timer.cpp',
'catch_tostring.cpp',
'catch_totals.cpp',
'catch_translate_exception.cpp',
'catch_version.cpp',
)

View File

@@ -9,6 +9,7 @@
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_registry_hub.hpp>
namespace Catch {
namespace Detail {

View File

@@ -8,7 +8,6 @@
#ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#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/internal/catch_compiler_capabilities.hpp>

View File

@@ -12,7 +12,6 @@
#include <catch2/catch_config.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/internal/catch_console_colour.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_list.hpp>

View File

@@ -9,12 +9,12 @@
#include <helpers/parse_test_spec.hpp>
#include <catch2/internal/catch_test_spec_parser.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <catch2/internal/catch_tag_alias_registry.hpp>
namespace Catch {
TestSpec parseTestSpec( std::string const& arg ) {
return TestSpecParser( ITagAliasRegistry::get() )
return TestSpecParser( TagAliasRegistry::get() )
.parse( arg )
.testSpec();
}