Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMartin Hořeňovský2018-03-07 11:01:06 +0100
committerMartin Hořeňovský2018-03-07 11:06:15 +0100
commitd14b7563c2f493ad1e1113e18b98409f91b6cde2 (patch)
treea86831300e387774cb1e84ad09274c29ebcfe258
parenta3d3a633b2367e134049486acbc6cbf6f1d3a4d8 (diff)
downloadcatch3-2.2.0.tar.gz
v2.2.0v2.2.0
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md4
-rw-r--r--conanfile.py2
-rw-r--r--docs/release-notes.md20
-rw-r--r--include/catch.hpp4
-rw-r--r--include/internal/catch_version.cpp2
-rw-r--r--single_include/catch.hpp325
-rw-r--r--single_include/catch_reporter_tap.hpp2
-rw-r--r--test_package/conanfile.py2
9 files changed, 219 insertions, 144 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4bb365ef..f42f57e0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()
-project(Catch2 LANGUAGES CXX VERSION 2.1.2)
+project(Catch2 LANGUAGES CXX VERSION 2.2.0)
include(GNUInstallDirs)
diff --git a/README.md b/README.md
index fa2dba5c..e07f26e7 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/6O2wo5BOvVeUeKQe)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/vOtfjd7LKmcj4JqD)
-<a href="https://github.com/catchorg/Catch2/releases/download/v2.1.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
+<a href="https://github.com/catchorg/Catch2/releases/download/v2.2.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released!
diff --git a/conanfile.py b/conanfile.py
index ea66ccb1..6d24a73c 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,7 +4,7 @@ from conans import ConanFile
class CatchConan(ConanFile):
name = "Catch"
- version = "2.1.2"
+ version = "2.2.0"
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
author = "philsquared"
generators = "cmake"
diff --git a/docs/release-notes.md b/docs/release-notes.md
index dc9f435c..ca9330db 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,5 +1,25 @@
<a id="top"></a>
+# 2.2.0
+
+## Fixes
+* Hidden tests are not listed by default when listing tests (#1175)
+ * This makes `catch_discover_tests` CMake script work better
+* Fixed regression that meant `<windows.h>` could potentially not be included properly (#1197)
+* Fixed installing `Catch2ConfigVersion.cmake` when Catch2 is a subproject.
+
+## Improvements
+* Added an option to warn (+ exit with error) when no tests were ran (#1158)
+ * Use as `-w NoTests`
+* Added provisional support for Emscripten (#1114)
+* [Added a way to override the fallback stringifier](https://github.com/catchorg/Catch2/blob/master/docs/configuration.md#fallback-stringifier) (#1024)
+ * This allows project's own stringification machinery to be easily reused for Catch
+* `Catch::Session::run()` now accepts `char const * const *`, allowing it to accept array of string literals (#1031, #1178)
+ * The embedded version of Clara was bumped to v1.1.3
+* Various minor performance improvements
+* Added support for DJGPP DOS crosscompiler (#1206)
+
+
# 2.1.2
## Fixes
diff --git a/include/catch.hpp b/include/catch.hpp
index a6f8d3ba..ebad166e 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -10,8 +10,8 @@
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 1
-#define CATCH_VERSION_PATCH 2
+#define CATCH_VERSION_MINOR 2
+#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
diff --git a/include/internal/catch_version.cpp b/include/internal/catch_version.cpp
index ab50285a..aab90cf0 100644
--- a/include/internal/catch_version.cpp
+++ b/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 1, 2, "", 0 );
+ static Version version( 2, 2, 0, "", 0 );
return version;
}
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index 882699ea..c36a9878 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v2.1.2
- * Generated: 2018-02-09 17:05:21.506253
+ * Catch v2.2.0
+ * Generated: 2018-03-07 10:56:32.217228
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 1
-#define CATCH_VERSION_PATCH 2
+#define CATCH_VERSION_MINOR 2
+#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
@@ -148,13 +148,15 @@ namespace Catch {
#endif // __clang__
////////////////////////////////////////////////////////////////////////////////
-// We know some environments not to support full POSIX signals
-#if defined(__CYGWIN__) || defined(__QNX__)
-
-# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
-# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
-# endif
+// Assume that non-Windows platforms support posix signals by default
+#if !defined(CATCH_PLATFORM_WINDOWS)
+ #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// We know some environments not to support full POSIX signals
+#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
+ #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
#endif
#ifdef __OS400__
@@ -192,6 +194,13 @@ namespace Catch {
////////////////////////////////////////////////////////////////////////////////
+// DJGPP
+#ifdef __DJGPP__
+# define CATCH_INTERNAL_CONFIG_NO_WCHAR
+#endif // __DJGPP__
+
+////////////////////////////////////////////////////////////////////////////////
+
// Use of __COUNTER__ is suppressed during code analysis in
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
// handled by it.
@@ -208,11 +217,15 @@ namespace Catch {
# define CATCH_CONFIG_WINDOWS_SEH
#endif
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
-#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
# define CATCH_CONFIG_POSIX_SIGNALS
#endif
+// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
+#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
+# define CATCH_CONFIG_WCHAR
+#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_INTERNAL_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif
@@ -443,16 +456,20 @@ namespace Catch {
public: // substrings and searches
auto substr( size_type start, size_type size ) const noexcept -> StringRef;
+ // Returns the current start pointer.
+ // Note that the pointer can change when if the StringRef is a substring
+ auto currentData() const noexcept -> char const*;
+
private: // ownership queries - may not be consistent between calls
auto isOwned() const noexcept -> bool;
auto isSubstring() const noexcept -> bool;
- auto data() const noexcept -> char const*;
};
auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
+ auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
@@ -484,13 +501,13 @@ auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
}
struct NameAndTags {
- NameAndTags( StringRef name_ = StringRef(), StringRef tags_ = StringRef() ) noexcept;
+ NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
StringRef name;
StringRef tags;
};
struct AutoReg : NonCopyable {
- AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
+ AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
~AutoReg();
};
@@ -753,8 +770,13 @@ namespace Catch {
std::string convertUnknownEnumToString( E e );
template<typename T>
- typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& ) {
+ typename std::enable_if<!std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
+#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
+ (void)value;
return Detail::unprintableString;
+#else
+ return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
+#endif
}
template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::string>::type convertUnstreamable( T const& value ) {
@@ -805,10 +827,12 @@ namespace Catch {
struct StringMaker<std::string> {
static std::string convert(const std::string& str);
};
+#ifdef CATCH_CONFIG_WCHAR
template<>
struct StringMaker<std::wstring> {
static std::string convert(const std::wstring& wstr);
};
+#endif
template<>
struct StringMaker<char const *> {
@@ -818,6 +842,7 @@ namespace Catch {
struct StringMaker<char *> {
static std::string convert(char * str);
};
+#ifdef CATCH_CONFIG_WCHAR
template<>
struct StringMaker<wchar_t const *> {
static std::string convert(wchar_t const * str);
@@ -826,6 +851,7 @@ namespace Catch {
struct StringMaker<wchar_t *> {
static std::string convert(wchar_t * str);
};
+#endif
template<int SZ>
struct StringMaker<char[SZ]> {
@@ -1739,6 +1765,7 @@ namespace Catch {
Totals delta( Totals const& prevTotals ) const;
+ int error = 0;
Counts assertions;
Counts testCases;
};
@@ -2696,7 +2723,7 @@ namespace Catch {
class TestCase : public TestCaseInfo {
public:
- TestCase( ITestInvoker* testCase, TestCaseInfo const& info );
+ TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
TestCase withName( std::string const& _newName ) const;
@@ -2713,8 +2740,7 @@ namespace Catch {
TestCase makeTestCase( ITestInvoker* testCase,
std::string const& className,
- std::string const& name,
- std::string const& description,
+ NameAndTags const& nameAndTags,
SourceLineInfo const& lineInfo );
}
@@ -3144,7 +3170,8 @@ namespace Catch {
struct WarnAbout { enum What {
Nothing = 0x00,
- NoAssertions = 0x01
+ NoAssertions = 0x01,
+ NoTests = 0x02
}; };
struct ShowDurations { enum OrNot {
@@ -3181,10 +3208,12 @@ namespace Catch {
virtual bool includeSuccessfulResults() const = 0;
virtual bool shouldDebugBreak() const = 0;
virtual bool warnAboutMissingAssertions() const = 0;
+ virtual bool warnAboutNoTests() const = 0;
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0;
+ virtual bool hasTestFilters() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual int benchmarkResolutionMultiple() const = 0;
@@ -3262,9 +3291,11 @@ namespace Catch {
std::string getProcessName() const;
std::vector<std::string> const& getReporterNames() const;
+ std::vector<std::string> const& getTestsOrTags() const;
std::vector<std::string> const& getSectionsToRun() const override;
virtual TestSpec const& testSpec() const override;
+ bool hasTestFilters() const override;
bool showHelp() const;
@@ -3274,6 +3305,7 @@ namespace Catch {
std::string name() const override;
bool includeSuccessfulResults() const override;
bool warnAboutMissingAssertions() const override;
+ bool warnAboutNoTests() const override;
ShowDurations::OrNot showDurations() const override;
RunTests::InWhatOrder runOrder() const override;
unsigned int rngSeed() const override;
@@ -3291,6 +3323,7 @@ namespace Catch {
std::unique_ptr<IStream const> m_stream;
TestSpec m_testSpec;
+ bool m_hasTestFilters = false;
};
} // end namespace Catch
@@ -4638,9 +4671,6 @@ namespace Catch {
// start catch_fatal_condition.h
-#include <string>
-
-#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
// start catch_windows_h_proxy.h
@@ -4671,16 +4701,7 @@ namespace Catch {
#endif // defined(CATCH_PLATFORM_WINDOWS)
// end catch_windows_h_proxy.h
-
-# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
- };
-}
-
-# else // CATCH_CONFIG_WINDOWS_SEH is defined
+#if defined( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
@@ -4699,19 +4720,7 @@ namespace Catch {
} // namespace Catch
-# endif // CATCH_CONFIG_WINDOWS_SEH
-
-#else // Not Windows - assumed to be POSIX compatible //////////////////////////
-
-# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
-
-namespace Catch {
- struct FatalConditionHandler {
- void reset();
- };
-}
-
-# else // CATCH_CONFIG_POSIX_SIGNALS is defined
+#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
#include <signal.h>
@@ -4720,7 +4729,7 @@ namespace Catch {
struct FatalConditionHandler {
static bool isSet;
- static struct sigaction oldSigActions[];// [sizeof(signalDefs) / sizeof(SignalDefs)];
+ static struct sigaction oldSigActions[];
static stack_t oldSigStack;
static char altStackMem[];
@@ -4733,9 +4742,15 @@ namespace Catch {
} // namespace Catch
-# endif // CATCH_CONFIG_POSIX_SIGNALS
+#else
+
+namespace Catch {
+ struct FatalConditionHandler {
+ void reset();
+ };
+}
-#endif // not Windows
+#endif
// end catch_fatal_condition.h
#include <string>
@@ -5016,9 +5031,9 @@ namespace Catch {
expr = m_info.capturedExpression;
else {
expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
- expr += m_info.macroName.c_str();
+ expr += m_info.macroName;
expr += "( ";
- expr += m_info.capturedExpression.c_str();
+ expr += m_info.capturedExpression;
expr += " )";
}
return expr;
@@ -5081,7 +5096,7 @@ namespace Catch {
using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
// This is the general overload that takes a any string matcher
- // There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers
+ // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
// the Equals matcher (so the header does not mention matchers)
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) {
std::string exceptionMessage = Catch::translateActiveException();
@@ -5119,7 +5134,7 @@ namespace Catch {
//
// See https://github.com/philsquared/Clara for more details
-// Clara v1.1.2
+// Clara v1.1.3
#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
@@ -5130,6 +5145,14 @@ namespace Catch {
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
#endif
+#ifndef CLARA_CONFIG_OPTIONAL_TYPE
+#ifdef __has_include
+#if __has_include(<optional>) && __cplusplus >= 201703L
+#define CLARA_CONFIG_OPTIONAL_TYPE std::optional
+#endif
+#endif
+#endif
+
// ----------- #included from clara_textflow.hpp -----------
// TextFlowCpp
@@ -5495,11 +5518,9 @@ namespace detail {
std::vector<std::string> m_args;
public:
- Args( int argc, char *argv[] ) {
- m_exeName = argv[0];
- for( int i = 1; i < argc; ++i )
- m_args.push_back( argv[i] );
- }
+ Args( int argc, char const* const* argv )
+ : m_exeName(argv[0]),
+ m_args(argv + 1, argv + argc) {}
Args( std::initializer_list<std::string> args )
: m_exeName( *args.begin() ),
@@ -5685,15 +5706,13 @@ namespace detail {
protected:
void enforceOk() const override {
- // !TBD: If no exceptions, std::terminate here or something
- switch( m_type ) {
- case ResultBase::LogicError:
- throw std::logic_error( m_errorMessage );
- case ResultBase::RuntimeError:
- throw std::runtime_error( m_errorMessage );
- case ResultBase::Ok:
- break;
- }
+
+ // Errors shouldn't reach this point, but if they do
+ // the actual error message will be in m_errorMessage
+ assert( m_type != ResultBase::LogicError );
+ assert( m_type != ResultBase::RuntimeError );
+ if( m_type != ResultBase::Ok )
+ std::abort();
}
std::string m_errorMessage; // Only populated if resultType is an error
@@ -5763,6 +5782,16 @@ namespace detail {
return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
return ParserResult::ok( ParseResultType::Matched );
}
+#ifdef CLARA_CONFIG_OPTIONAL_TYPE
+ template<typename T>
+ inline auto convertInto( std::string const &source, std::optional<T>& target ) -> ParserResult {
+ T temp;
+ auto result = convertInto( source, temp );
+ if( result )
+ target = temp;
+ return result;
+ }
+#endif // CLARA_CONFIG_OPTIONAL_TYPE
struct NonCopyable {
NonCopyable() = default;
@@ -6366,9 +6395,19 @@ namespace Catch {
using namespace clara;
auto const setWarning = [&]( std::string const& warning ) {
- if( warning != "NoAssertions" )
+ auto warningSet = [&]() {
+ if( warning == "NoAssertions" )
+ return WarnAbout::NoAssertions;
+
+ if ( warning == "NoTests" )
+ return WarnAbout::NoTests;
+
+ return WarnAbout::Nothing;
+ }();
+
+ if (warningSet == WarnAbout::Nothing)
return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
- config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
return ParserResult::ok( ParseResultType::Matched );
};
auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
@@ -6569,10 +6608,9 @@ namespace Catch {
// start catch_enforce.h
#include <stdexcept>
-#include <iosfwd>
#define CATCH_PREPARE_EXCEPTION( type, msg ) \
- type( static_cast<std::ostringstream&&>( Catch::ReusableStringStream().get() << msg ).str() )
+ type( ( Catch::ReusableStringStream() << msg ).str() )
#define CATCH_INTERNAL_ERROR( msg ) \
throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
#define CATCH_ERROR( msg ) \
@@ -6587,12 +6625,16 @@ namespace Catch {
: m_data( data ),
m_stream( openStream() )
{
- if( !data.testsOrTags.empty() ) {
- TestSpecParser parser( ITagAliasRegistry::get() );
+ TestSpecParser parser(ITagAliasRegistry::get());
+ if (data.testsOrTags.empty()) {
+ parser.parse("~[.]"); // All not hidden tests
+ }
+ else {
+ m_hasTestFilters = true;
for( auto const& testOrTags : data.testsOrTags )
parser.parse( testOrTags );
- m_testSpec = parser.testSpec();
}
+ m_testSpec = parser.testSpec();
}
std::string const& Config::getFilename() const {
@@ -6607,9 +6649,11 @@ namespace Catch {
std::string Config::getProcessName() const { return m_data.processName; }
std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; }
+ std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
TestSpec const& Config::testSpec() const { return m_testSpec; }
+ bool Config::hasTestFilters() const { return m_hasTestFilters; }
bool Config::showHelp() const { return m_data.showHelp; }
@@ -6618,7 +6662,8 @@ namespace Catch {
std::ostream& Config::stream() const { return m_stream->stream(); }
std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
- bool Config::warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
+ bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
unsigned int Config::rngSeed() const { return m_data.rngSeed; }
@@ -6802,7 +6847,12 @@ namespace {
#ifdef CATCH_PLATFORM_MAC
!isDebuggerActive() &&
#endif
- isatty(STDOUT_FILENO);
+#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
+ isatty(STDOUT_FILENO)
+#else
+ false
+#endif
+ ;
}
IColourImpl* platformColourInstance() {
ErrnoGuard guard;
@@ -6936,13 +6986,16 @@ namespace Catch {
::OutputDebugStringA( text.c_str() );
}
}
+
#else
+
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
// !TBD: Need a version for Mac/ XCode and other IDEs
Catch::cout() << text;
}
}
+
#endif // Platform
// end catch_debug_console.cpp
// start catch_debugger.cpp
@@ -7165,24 +7218,18 @@ namespace Catch {
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
-#if (defined(CATCH_PLATFORM_WINDOWS) && defined(CATCH_CONFIG_WINDOWS_SEH)) || defined(CATCH_CONFIG_POSIX_SIGNALS)
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
+
namespace {
// Report the error condition
void reportFatal( char const * const message ) {
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
}
}
-#endif
-#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+#endif // signals/SEH handling
-# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-# else // CATCH_CONFIG_WINDOWS_SEH is defined
+#if defined( CATCH_CONFIG_WINDOWS_SEH )
namespace Catch {
struct SignalDefs { DWORD id; const char* name; };
@@ -7222,7 +7269,6 @@ namespace Catch {
void FatalConditionHandler::reset() {
if (isSet) {
- // Unregister handler and restore the old guarantee
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
SetThreadStackGuarantee(&guaranteeSize);
exceptionHandlerHandle = nullptr;
@@ -7240,19 +7286,7 @@ PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
} // namespace Catch
-# endif // CATCH_CONFIG_WINDOWS_SEH
-
-#else // Not Windows - assumed to be POSIX compatible //////////////////////////
-
-# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
-
-namespace Catch {
- void FatalConditionHandler::reset() {}
-}
-
-# else // CATCH_CONFIG_POSIX_SIGNALS is defined
-
-#include <signal.h>
+#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
namespace Catch {
@@ -7321,9 +7355,13 @@ namespace Catch {
} // namespace Catch
-# endif // CATCH_CONFIG_POSIX_SIGNALS
+#else
+
+namespace Catch {
+ void FatalConditionHandler::reset() {}
+}
-#endif // not Windows
+#endif // signals/SEH handling
#if defined(__GNUC__)
# pragma GCC diagnostic pop
@@ -7605,11 +7643,10 @@ namespace Catch {
std::size_t listTests( Config const& config ) {
TestSpec testSpec = config.testSpec();
- if( config.testSpec().hasFilters() )
+ if( config.hasTestFilters() )
Catch::cout() << "Matching test cases:\n";
else {
Catch::cout() << "All available test cases:\n";
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
@@ -7631,7 +7668,7 @@ namespace Catch {
Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
}
- if( !config.testSpec().hasFilters() )
+ if( !config.hasTestFilters() )
Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
else
Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
@@ -7640,8 +7677,6 @@ namespace Catch {
std::size_t listTestsNamesOnly( Config const& config ) {
TestSpec testSpec = config.testSpec();
- if( !config.testSpec().hasFilters() )
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( auto const& testCaseInfo : matchedTestCases ) {
@@ -7671,11 +7706,10 @@ namespace Catch {
std::size_t listTags( Config const& config ) {
TestSpec testSpec = config.testSpec();
- if( config.testSpec().hasFilters() )
+ if( config.hasTestFilters() )
Catch::cout() << "Tags for matching test cases:\n";
else {
Catch::cout() << "All available tags:\n";
- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
std::map<std::string, TagInfo> tagCounts;
@@ -8151,7 +8185,7 @@ namespace Catch {
void invoke() const override;
};
- std::string extractClassName( std::string const& classOrQualifiedMethodName );
+ std::string extractClassName( StringRef const& classOrQualifiedMethodName );
///////////////////////////////////////////////////////////////////////////
@@ -8422,7 +8456,7 @@ namespace Catch {
m_context(getCurrentMutableContext()),
m_config(_config),
m_reporter(std::move(reporter)),
- m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal },
+ m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
{
m_context.setRunner(this);
@@ -8449,7 +8483,7 @@ namespace Catch {
std::string redirectedCout;
std::string redirectedCerr;
- TestCaseInfo testInfo = testCase.getTestCaseInfo();
+ auto const& testInfo = testCase.getTestCaseInfo();
m_reporter->testCaseStarting(testInfo);
@@ -8656,7 +8690,7 @@ namespace Catch {
Counts prevAssertions = m_totals.assertions;
double duration = 0;
m_shouldReportUnexpected = true;
- m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal };
+ m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
seedRng(*m_config);
@@ -8891,12 +8925,12 @@ namespace Catch {
void showHelp() const;
void libIdentify();
- int applyCommandLine( int argc, char* argv[] );
+ int applyCommandLine( int argc, char const * const * argv );
void useConfigData( ConfigData const& configData );
int run( int argc, char* argv[] );
- #if defined(WIN32) && defined(UNICODE)
+ #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int run( int argc, wchar_t* const argv[] );
#endif
int run();
@@ -8997,8 +9031,6 @@ namespace Catch {
context.testGroupStarting(config->name(), 1, 1);
TestSpec testSpec = config->testSpec();
- if (!testSpec.hasFilters())
- testSpec = TestSpecParser(ITagAliasRegistry::get()).parse("~[.]").testSpec(); // All not hidden tests
auto const& allTestCases = getAllTestCasesSorted(*config);
for (auto const& testCase : allTestCases) {
@@ -9008,6 +9040,20 @@ namespace Catch {
context.reporter().skipTest(testCase);
}
+ if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
+ ReusableStringStream testConfig;
+
+ bool first = true;
+ for (const auto& input : config->getTestsOrTags()) {
+ if (!first) { testConfig << ' '; }
+ first = false;
+ testConfig << input;
+ }
+
+ context.reporter().noMatchingTestCases(testConfig.str());
+ totals.error = -1;
+ }
+
context.testGroupEnded(config->name(), totals, 1, 1);
return totals;
}
@@ -9047,7 +9093,7 @@ namespace Catch {
if ( !exceptions.empty() ) {
m_startupExceptions = true;
Colour colourGuard( Colour::Red );
- Catch::cerr() << "Errors occured during startup!" << '\n';
+ Catch::cerr() << "Errors occurred during startup!" << '\n';
// iterate over all exceptions and notify user
for ( const auto& ex_ptr : exceptions ) {
try {
@@ -9079,7 +9125,7 @@ namespace Catch {
<< std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
}
- int Session::applyCommandLine( int argc, char* argv[] ) {
+ int Session::applyCommandLine( int argc, char const * const * argv ) {
if( m_startupExceptions )
return 1;
@@ -9116,7 +9162,7 @@ namespace Catch {
return returnCode;
}
-#if defined(WIN32) && defined(UNICODE)
+#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int Session::run( int argc, wchar_t* const argv[] ) {
char **utf8Argv = new char *[ argc ];
@@ -9187,10 +9233,11 @@ namespace Catch {
if( Option<std::size_t> listed = list( config() ) )
return static_cast<int>( *listed );
+ auto totals = runTests( m_config );
// Note that on unices only the lower 8 bits are usually used, clamping
// the return value to 255 prevents false negative when some multiple
// of 256 tests has failed
- return (std::min)( MaxExitCode, static_cast<int>( runTests( m_config ).assertions.failed ) );
+ return (std::min)( { MaxExitCode, totals.error, static_cast<int>( totals.assertions.failed ) } );
}
catch( std::exception& ex ) {
Catch::cerr() << ex.what() << std::endl;
@@ -9525,7 +9572,7 @@ namespace Catch {
const_cast<StringRef*>( this )->takeOwnership();
return m_start;
}
- auto StringRef::data() const noexcept -> char const* {