mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-08 23:29:53 +01:00
b79a83e4aa
This means that code such as ```cpp TEST_CASE() { SECTION("first") { SUCCEED(); } auto _ = GENERATE(1, 2); SECTION("second") { SUCCEED(); } } ``` will run and report 3 assertions, 1 from section "first" and 2 from section "second". This also applies for greater and potentially more confusing nesting, but fundamentally it is up to the user to avoid overly complex and confusing nestings, just as with `SECTION`s. The old behaviour of `GENERATE` as first thing in a `TEST_CASE`, `GENERATE` not followed by a `SECTION`, etc etc should be unchanged. Closes #1938
177 lines
4.8 KiB
C++
177 lines
4.8 KiB
C++
/*
|
|
* Created by Phil Nash on 23/7/2013
|
|
* Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
|
|
*
|
|
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
|
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
|
|
|
#include "catch_compiler_capabilities.h"
|
|
#include "catch_common.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <memory>
|
|
|
|
namespace Catch {
|
|
namespace TestCaseTracking {
|
|
|
|
struct NameAndLocation {
|
|
std::string name;
|
|
SourceLineInfo location;
|
|
|
|
NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
|
|
friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
|
|
return lhs.name == rhs.name
|
|
&& lhs.location == rhs.location;
|
|
}
|
|
};
|
|
|
|
class ITracker;
|
|
|
|
using ITrackerPtr = std::shared_ptr<ITracker>;
|
|
|
|
class ITracker {
|
|
NameAndLocation m_nameAndLocation;
|
|
|
|
public:
|
|
ITracker(NameAndLocation const& nameAndLoc) :
|
|
m_nameAndLocation(nameAndLoc)
|
|
{}
|
|
|
|
|
|
// static queries
|
|
NameAndLocation const& nameAndLocation() const {
|
|
return m_nameAndLocation;
|
|
}
|
|
|
|
virtual ~ITracker();
|
|
|
|
|
|
// dynamic queries
|
|
virtual bool isComplete() const = 0; // Successfully completed or failed
|
|
virtual bool isSuccessfullyCompleted() const = 0;
|
|
virtual bool isOpen() const = 0; // Started but not complete
|
|
virtual bool hasChildren() const = 0;
|
|
virtual bool hasStarted() const = 0;
|
|
|
|
virtual ITracker& parent() = 0;
|
|
|
|
// actions
|
|
virtual void close() = 0; // Successfully complete
|
|
virtual void fail() = 0;
|
|
virtual void markAsNeedingAnotherRun() = 0;
|
|
|
|
virtual void addChild( ITrackerPtr const& child ) = 0;
|
|
virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
|
|
virtual void openChild() = 0;
|
|
|
|
// Debug/ checking
|
|
virtual bool isSectionTracker() const = 0;
|
|
virtual bool isGeneratorTracker() const = 0;
|
|
};
|
|
|
|
class TrackerContext {
|
|
|
|
enum RunState {
|
|
NotStarted,
|
|
Executing,
|
|
CompletedCycle
|
|
};
|
|
|
|
ITrackerPtr m_rootTracker;
|
|
ITracker* m_currentTracker = nullptr;
|
|
RunState m_runState = NotStarted;
|
|
|
|
public:
|
|
|
|
ITracker& startRun();
|
|
void endRun();
|
|
|
|
void startCycle();
|
|
void completeCycle();
|
|
|
|
bool completedCycle() const;
|
|
ITracker& currentTracker();
|
|
void setCurrentTracker( ITracker* tracker );
|
|
};
|
|
|
|
class TrackerBase : public ITracker {
|
|
protected:
|
|
enum CycleState {
|
|
NotStarted,
|
|
Executing,
|
|
ExecutingChildren,
|
|
NeedsAnotherRun,
|
|
CompletedSuccessfully,
|
|
Failed
|
|
};
|
|
|
|
using Children = std::vector<ITrackerPtr>;
|
|
TrackerContext& m_ctx;
|
|
ITracker* m_parent;
|
|
Children m_children;
|
|
CycleState m_runState = NotStarted;
|
|
|
|
public:
|
|
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
|
|
|
bool isComplete() const override;
|
|
bool isSuccessfullyCompleted() const override;
|
|
bool isOpen() const override;
|
|
bool hasChildren() const override;
|
|
bool hasStarted() const override {
|
|
return m_runState != NotStarted;
|
|
}
|
|
|
|
void addChild( ITrackerPtr const& child ) override;
|
|
|
|
ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
|
|
ITracker& parent() override;
|
|
|
|
void openChild() override;
|
|
|
|
bool isSectionTracker() const override;
|
|
bool isGeneratorTracker() const override;
|
|
|
|
void open();
|
|
|
|
void close() override;
|
|
void fail() override;
|
|
void markAsNeedingAnotherRun() override;
|
|
|
|
private:
|
|
void moveToParent();
|
|
void moveToThis();
|
|
};
|
|
|
|
class SectionTracker : public TrackerBase {
|
|
std::vector<std::string> m_filters;
|
|
std::string m_trimmed_name;
|
|
public:
|
|
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
|
|
|
|
bool isSectionTracker() const override;
|
|
|
|
bool isComplete() const override;
|
|
|
|
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
|
|
|
|
void tryOpen();
|
|
|
|
void addInitialFilters( std::vector<std::string> const& filters );
|
|
void addNextFilters( std::vector<std::string> const& filters );
|
|
};
|
|
|
|
} // namespace TestCaseTracking
|
|
|
|
using TestCaseTracking::ITracker;
|
|
using TestCaseTracking::TrackerContext;
|
|
using TestCaseTracking::SectionTracker;
|
|
|
|
} // namespace Catch
|
|
|
|
#endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|