// 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 #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Catch { class IGeneratorTracker; class IConfig; class IEventListener; using IEventListenerPtr = Detail::unique_ptr; class OutputRedirect; /////////////////////////////////////////////////////////////////////////// class RunContext final : public IResultCapture { public: RunContext( RunContext const& ) = delete; RunContext& operator =( RunContext const& ) = delete; explicit RunContext( IConfig const* _config, IEventListenerPtr&& reporter ); ~RunContext() override; Totals runTest(TestCaseHandle const& testCase); public: // IResultCapture // Assertion handlers void handleExpr ( AssertionInfo const& info, ITransientExpression const& expr, AssertionReaction& reaction ) override; void handleMessage ( AssertionInfo const& info, ResultWas::OfType resultType, std::string&& message, AssertionReaction& reaction ) override; void handleUnexpectedExceptionNotThrown ( AssertionInfo const& info, AssertionReaction& reaction ) override; void handleUnexpectedInflightException ( AssertionInfo const& info, std::string&& message, AssertionReaction& reaction ) override; void handleIncomplete ( AssertionInfo const& info ) override; void handleNonExpr ( AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction ) override; void notifyAssertionStarted( AssertionInfo const& info ) override; bool sectionStarted( StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts& assertions ) override; void sectionEnded( SectionEndInfo&& endInfo ) override; void sectionEndedEarly( SectionEndInfo&& endInfo ) override; IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) override; IGeneratorTracker* createGeneratorTracker( StringRef generatorName, SourceLineInfo lineInfo, Generators::GeneratorBasePtr&& generator ) override; void benchmarkPreparing( StringRef name ) override; void benchmarkStarting( BenchmarkInfo const& info ) override; void benchmarkEnded( BenchmarkStats<> const& stats ) override; void benchmarkFailed( StringRef error ) override; std::string getCurrentTestName() const override; const AssertionResult* getLastResult() const override; void exceptionEarlyReported() override; void handleFatalErrorCondition( StringRef message ) override; public: // !TBD We need to do this another way! bool aborting() const; //! Ends the capture of the running test's output and returns what //! it captured; for a process that ends inside a test, whose end is //! never reported. The standard streams are their own again, so //! flushing them at exit no longer reaches the capture buffers, //! which may be gone by then. std::string endCapture(); private: void assertionPassedFastPath( SourceLineInfo lineInfo ); // Update the non-thread-safe m_totals from the atomic assertion counts. void updateTotalsFromAtomics(); void runCurrentTest(); void invokeActiveTestCase(); bool testForMissingAssertions( Counts& assertions ); void assertionEnded( AssertionResult&& result ); void reportExpr ( AssertionInfo const &info, ResultWas::OfType resultType, ITransientExpression const *expr, bool negated ); void populateReaction( AssertionReaction& reaction, bool has_normal_disposition ) const; // Creates dummy info for unexpected exceptions/fatal errors, // where we do not have the access to one, but we still need // to send one to the reporters. AssertionInfo makeDummyAssertionInfo(); private: void handleUnfinishedSections(); mutable Detail::Mutex m_assertionMutex; TestRunInfo m_runInfo; TestCaseHandle const* m_activeTestCase = nullptr; ITracker* m_testCaseTracker = nullptr; Optional m_lastResult; IConfig const* m_config; Totals m_totals; Detail::AtomicCounts m_atomicAssertionCount; IEventListenerPtr m_reporter; std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; Detail::unique_ptr m_outputRedirect; FatalConditionHandler m_fatalConditionhandler; // Caches m_config->abortAfter() to avoid vptr calls/allow inlining size_t m_abortAfterXFailedAssertions; bool m_shouldReportUnexpected = true; // Caches whether `assertionStarting` events should be sent to the reporter. bool m_reportAssertionStarting; // Caches whether `assertionEnded` events for successful assertions should be sent to the reporter bool m_includeSuccessfulResults; // Caches m_config->shouldDebugBreak() to avoid vptr calls/allow inlining bool m_shouldDebugBreak; }; void seedRng(IConfig const& config); unsigned int rngSeed(); } // end namespace Catch