Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:07

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
0008 #ifndef CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
0009 #define CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED
0010 
0011 #include <catch2/reporters/catch_reporter_common_base.hpp>
0012 #include <catch2/internal/catch_move_and_forward.hpp>
0013 #include <catch2/internal/catch_unique_ptr.hpp>
0014 #include <catch2/internal/catch_optional.hpp>
0015 
0016 #include <string>
0017 #include <vector>
0018 
0019 namespace Catch {
0020 
0021     namespace Detail {
0022 
0023         //! Represents either an assertion or a benchmark result to be handled by cumulative reporter later
0024         class AssertionOrBenchmarkResult {
0025             // This should really be a variant, but this is much faster
0026             // to write and the data layout here is already terrible
0027             // enough that we do not have to care about the object size.
0028             Optional<AssertionStats> m_assertion;
0029             Optional<BenchmarkStats<>> m_benchmark;
0030         public:
0031             AssertionOrBenchmarkResult(AssertionStats const& assertion);
0032             AssertionOrBenchmarkResult(BenchmarkStats<> const& benchmark);
0033 
0034             bool isAssertion() const;
0035             bool isBenchmark() const;
0036 
0037             AssertionStats const& asAssertion() const;
0038             BenchmarkStats<> const& asBenchmark() const;
0039         };
0040     }
0041 
0042     /**
0043      * Utility base for reporters that need to handle all results at once
0044      *
0045      * It stores tree of all test cases, sections and assertions, and after the
0046      * test run is finished, calls into `testRunEndedCumulative` to pass the
0047      * control to the deriving class.
0048      *
0049      * If you are deriving from this class and override any testing related
0050      * member functions, you should first call into the base's implementation to
0051      * avoid breaking the tree construction.
0052      *
0053      * Due to the way this base functions, it has to expand assertions up-front,
0054      * even if they are later unused (e.g. because the deriving reporter does
0055      * not report successful assertions, or because the deriving reporter does
0056      * not use assertion expansion at all). Derived classes can use two
0057      * customization points, `m_shouldStoreSuccesfulAssertions` and
0058      * `m_shouldStoreFailedAssertions`, to disable the expansion and gain extra
0059      * performance. **Accessing the assertion expansions if it wasn't stored is
0060      * UB.**
0061      */
0062     class CumulativeReporterBase : public ReporterBase {
0063     public:
0064         template<typename T, typename ChildNodeT>
0065         struct Node {
0066             explicit Node( T const& _value ) : value( _value ) {}
0067 
0068             using ChildNodes = std::vector<Detail::unique_ptr<ChildNodeT>>;
0069             T value;
0070             ChildNodes children;
0071         };
0072         struct SectionNode {
0073             explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
0074 
0075             bool operator == (SectionNode const& other) const {
0076                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
0077             }
0078 
0079             bool hasAnyAssertions() const;
0080 
0081             SectionStats stats;
0082             std::vector<Detail::unique_ptr<SectionNode>> childSections;
0083             std::vector<Detail::AssertionOrBenchmarkResult> assertionsAndBenchmarks;
0084             std::string stdOut;
0085             std::string stdErr;
0086         };
0087 
0088 
0089         using TestCaseNode = Node<TestCaseStats, SectionNode>;
0090         using TestRunNode = Node<TestRunStats, TestCaseNode>;
0091 
0092         // GCC5 compat: we cannot use inherited constructor, because it
0093         //              doesn't implement backport of P0136
0094         CumulativeReporterBase(ReporterConfig&& _config):
0095             ReporterBase(CATCH_MOVE(_config))
0096         {}
0097         ~CumulativeReporterBase() override;
0098 
0099         void benchmarkPreparing( StringRef ) override {}
0100         void benchmarkStarting( BenchmarkInfo const& ) override {}
0101         void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
0102         void benchmarkFailed( StringRef ) override {}
0103 
0104         void noMatchingTestCases( StringRef ) override {}
0105         void reportInvalidTestSpec( StringRef ) override {}
0106         void fatalErrorEncountered( StringRef /*error*/ ) override {}
0107 
0108         void testRunStarting( TestRunInfo const& ) override {}
0109 
0110         void testCaseStarting( TestCaseInfo const& ) override {}
0111         void testCasePartialStarting( TestCaseInfo const&, uint64_t ) override {}
0112         void sectionStarting( SectionInfo const& sectionInfo ) override;
0113 
0114         void assertionStarting( AssertionInfo const& ) override {}
0115 
0116         void assertionEnded( AssertionStats const& assertionStats ) override;
0117         void sectionEnded( SectionStats const& sectionStats ) override;
0118         void testCasePartialEnded( TestCaseStats const&, uint64_t ) override {}
0119         void testCaseEnded( TestCaseStats const& testCaseStats ) override;
0120         void testRunEnded( TestRunStats const& testRunStats ) override;
0121         //! Customization point: called after last test finishes (testRunEnded has been handled)
0122         virtual void testRunEndedCumulative() = 0;
0123 
0124         void skipTest(TestCaseInfo const&) override {}
0125 
0126     protected:
0127         //! Should the cumulative base store the assertion expansion for successful assertions?
0128         bool m_shouldStoreSuccesfulAssertions = true;
0129         //! Should the cumulative base store the assertion expansion for failed assertions?
0130         bool m_shouldStoreFailedAssertions = true;
0131 
0132         // We need lazy construction here. We should probably refactor it
0133         // later, after the events are redone.
0134         //! The root node of the test run tree.
0135         Detail::unique_ptr<TestRunNode> m_testRun;
0136 
0137     private:
0138         // Note: We rely on pointer identity being stable, which is why
0139         //       we store pointers to the nodes rather than the values.
0140         std::vector<Detail::unique_ptr<TestCaseNode>> m_testCases;
0141         // Root section of the _current_ test case
0142         Detail::unique_ptr<SectionNode> m_rootSection;
0143         // Deepest section of the _current_ test case
0144         SectionNode* m_deepestSection = nullptr;
0145         // Stack of _active_ sections in the _current_ test case
0146         std::vector<SectionNode*> m_sectionStack;
0147     };
0148 
0149 } // end namespace Catch
0150 
0151 #endif // CATCH_REPORTER_CUMULATIVE_BASE_HPP_INCLUDED