mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +01:00
Merge branch 'master' into dev-modernize
This commit is contained in:
commit
aa42dd92d1
16
conanfile.py
Normal file
16
conanfile.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from conans import ConanFile
|
||||||
|
|
||||||
|
|
||||||
|
class CatchConan(ConanFile):
|
||||||
|
name = "Catch"
|
||||||
|
version = "1.9.6"
|
||||||
|
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
||||||
|
author = "philsquared"
|
||||||
|
generators = "cmake"
|
||||||
|
exports_sources = "single_include/*"
|
||||||
|
url = "https://github.com/philsquared/Catch"
|
||||||
|
license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
|
||||||
|
|
||||||
|
def package(self):
|
||||||
|
self.copy(pattern="catch.hpp", src="single_include", dst="include")
|
@ -13,6 +13,7 @@ which consists of either a single matcher or one or more matchers combined using
|
|||||||
For example, to assert that a string ends with a certain substring:
|
For example, to assert that a string ends with a certain substring:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
|
using Catch::Matchers::EndsWith; // or Catch::EndsWith
|
||||||
std::string str = getStringFromSomewhere();
|
std::string str = getStringFromSomewhere();
|
||||||
REQUIRE_THAT( str, EndsWith( "as a service" ) );
|
REQUIRE_THAT( str, EndsWith( "as a service" ) );
|
||||||
```
|
```
|
||||||
@ -34,7 +35,7 @@ REQUIRE_THAT( str,
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Built in matchers
|
## Built in matchers
|
||||||
Currently Catch has some string matchers and some vector matchers.
|
Currently Catch has some string matchers and some vector matchers. They are in the `Catch::Matchers` and `Catch` namespaces.
|
||||||
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||||
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
||||||
|
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
# 1.9.6
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
* Catch's runtime overhead has been significantly decreased (#937, #939)
|
||||||
|
* Added `--list-extra-info` cli option (#934).
|
||||||
|
* It lists all tests together with extra information, ie filename, line number and description.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 1.9.5
|
# 1.9.5
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
@ -2,43 +2,62 @@
|
|||||||
|
|
||||||
When enough changes have accumulated, it is time to release new version of Catch. This document describes the proces in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory.
|
When enough changes have accumulated, it is time to release new version of Catch. This document describes the proces in doing so, that no steps are forgotten. Note that all referenced scripts can be found in the `scripts/` directory.
|
||||||
|
|
||||||
|
## Neccessary steps
|
||||||
|
|
||||||
## Approval testing
|
These steps are neccessary and have to be performed before each new release. They serve to make sure that the new release is correct and linked-to from the standard places.
|
||||||
|
|
||||||
|
|
||||||
|
### Approval testing
|
||||||
|
|
||||||
Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py <path/to/SelfTest>`.
|
Catch's releases are primarily validated against output from previous release, stored in `projects/SelfTest/Baselines`. To validate current sources, build the SelfTest binary and pass it to the `approvalTests.py` script: `approvalTests.py <path/to/SelfTest>`.
|
||||||
|
|
||||||
There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes.
|
There should be no differences, as Approval tests should be updated when changes to Catch are made, but if there are, then they need to be manually reviewed and either approved (using `approve.py`) or Catch requires other fixes.
|
||||||
|
|
||||||
|
|
||||||
## Incrementing version number
|
### Incrementing version number
|
||||||
|
|
||||||
Catch uses a variant of [semantic versioning](http://semver.org/), with breaking API changes (and thus major version increments) being very rare. Thus, the release will usually increment the patch version, when it only contains couple of bugfixes, or minor version, when it contains new functionality, or larger changes in implementation of current functionality.
|
Catch uses a variant of [semantic versioning](http://semver.org/), with breaking API changes (and thus major version increments) being very rare. Thus, the release will usually increment the patch version, when it only contains couple of bugfixes, or minor version, when it contains new functionality, or larger changes in implementation of current functionality.
|
||||||
|
|
||||||
After deciding which part of version number should be incremented, you can use one of the `*Release.py` scripts to perform the required changes to Catch.
|
After deciding which part of version number should be incremented, you can use one of the `*Release.py` scripts to perform the required changes to Catch.
|
||||||
|
|
||||||
|
|
||||||
## Generate updated single-include header
|
### Generate updated single-include header
|
||||||
|
|
||||||
After updating version number, regenerate single-include header using `generateSingleHeader.py`.
|
After updating version number, regenerate single-include header using `generateSingleHeader.py`.
|
||||||
|
|
||||||
|
|
||||||
## Release notes
|
### Release notes
|
||||||
|
|
||||||
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`.
|
Once a release is ready, release notes need to be written. They should summarize changes done since last release. For rough idea of expected notes see previous releases. Once written, release notes should be placed in `docs/release-notes.md`.
|
||||||
|
|
||||||
|
|
||||||
## Commit and push update to GitHub
|
### Commit and push update to GitHub
|
||||||
|
|
||||||
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub.
|
After version number is incremented, single-include header is regenerated and release notes are updated, changes should be commited and pushed to GitHub.
|
||||||
|
|
||||||
|
|
||||||
## Release on GitHub
|
### Release on GitHub
|
||||||
|
|
||||||
After pushing changes to GitHub, GitHub release *needs* to be created. Tag version and release title should be same as the new version, description should contain the release notes for the current release. Single header version of `catch.hpp` *needs* to be attached as a binary, as that is where the official download link links to. Preferably it should use linux line endings.
|
After pushing changes to GitHub, GitHub release *needs* to be created. Tag version and release title should be same as the new version, description should contain the release notes for the current release. Single header version of `catch.hpp` *needs* to be attached as a binary, as that is where the official download link links to. Preferably it should use linux line endings.
|
||||||
|
|
||||||
|
## Optional steps
|
||||||
|
|
||||||
## vcpkg update
|
The following steps are optional, and do not have to be performed when releasing new version of Catch. However, they are *should* happen, but they can happen the next day without losing anything significant.
|
||||||
|
|
||||||
As a last step, optionally update Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg) with Catch's new version. `updateVcpkgPackage.py` can do a lot of neccessary work for you, but it assumes that you have your fork of vcpkg checked out in a directory next to the directory, where you have checked out Catch.
|
|
||||||
|
|
||||||
It creates a branch and commits neccessary changes, that you then should review, synchronize and open a PR against.
|
### vcpkg update
|
||||||
|
|
||||||
|
Catch is maintaining its own port in Microsoft's package manager [vcpkg](https://github.com/Microsoft/vcpkg). This means that when new version of Catch is released, it should be posted there as well. `updateVcpkgPackage.py` can do a lot of neccessary work for you, it creates a branch and commits neccessary changes. You should review these changes, push and open a PR against vcpkg's upstream.
|
||||||
|
|
||||||
|
Note that the script assumes you have your fork of vcpkg checked out in a directory next to the directory where you have checked out Catch, like so:
|
||||||
|
```
|
||||||
|
GitHub
|
||||||
|
Catch
|
||||||
|
vcpkg
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Wandbox update
|
||||||
|
|
||||||
|
Recently we also included a link to wandbox with preloaded Catch on the main page. Strictly speaking it is unneccessary to update this after every release, Catch usually does not change that much between versions, but it should be kept up to date anyway.
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ namespace Catch {
|
|||||||
if( lastDot != std::string::npos )
|
if( lastDot != std::string::npos )
|
||||||
filename = filename.substr( 0, lastDot );
|
filename = filename.substr( 0, lastDot );
|
||||||
|
|
||||||
tags.push_back( "#" + filename );
|
tags.push_back( '#' + filename );
|
||||||
setTags( testCase, tags );
|
setTags( testCase, tags );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,19 @@ namespace Catch {
|
|||||||
m_stream.rdbuf(m_prevBuf);
|
m_stream.rdbuf(m_prevBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StdErrRedirect::StdErrRedirect(std::string & targetString)
|
||||||
|
:m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()),
|
||||||
|
m_targetString(targetString) {
|
||||||
|
cerr().rdbuf(m_oss.rdbuf());
|
||||||
|
clog().rdbuf(m_oss.rdbuf());
|
||||||
|
}
|
||||||
|
|
||||||
|
StdErrRedirect::~StdErrRedirect() {
|
||||||
|
m_targetString += m_oss.str();
|
||||||
|
cerr().rdbuf(m_cerrBuf);
|
||||||
|
clog().rdbuf(m_clogBuf);
|
||||||
|
}
|
||||||
|
|
||||||
RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
|
RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
|
||||||
: m_runInfo(_config->name()),
|
: m_runInfo(_config->name()),
|
||||||
m_context(getCurrentMutableContext()),
|
m_context(getCurrentMutableContext()),
|
||||||
@ -256,7 +269,7 @@ namespace Catch {
|
|||||||
timer.start();
|
timer.start();
|
||||||
if (m_reporter->getPreferences().shouldRedirectStdOut) {
|
if (m_reporter->getPreferences().shouldRedirectStdOut) {
|
||||||
StreamRedirect coutRedir(cout(), redirectedCout);
|
StreamRedirect coutRedir(cout(), redirectedCout);
|
||||||
StreamRedirect cerrRedir(cerr(), redirectedCerr);
|
StdErrRedirect errRedir(redirectedCerr);
|
||||||
invokeActiveTestCase();
|
invokeActiveTestCase();
|
||||||
} else {
|
} else {
|
||||||
invokeActiveTestCase();
|
invokeActiveTestCase();
|
||||||
@ -318,5 +331,4 @@ namespace Catch {
|
|||||||
else
|
else
|
||||||
CATCH_INTERNAL_ERROR("No result capture instance");
|
CATCH_INTERNAL_ERROR("No result capture instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -40,6 +40,20 @@ namespace Catch {
|
|||||||
std::string& m_targetString;
|
std::string& m_targetString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// StdErr has two constituent streams in C++, std::cerr and std::clog
|
||||||
|
// This means that we need to redirect 2 streams into 1 to keep proper
|
||||||
|
// order of writes and cannot use StreamRedirect on its own
|
||||||
|
class StdErrRedirect {
|
||||||
|
public:
|
||||||
|
StdErrRedirect(std::string& targetString);
|
||||||
|
~StdErrRedirect();
|
||||||
|
private:
|
||||||
|
std::streambuf* m_cerrBuf;
|
||||||
|
std::streambuf* m_clogBuf;
|
||||||
|
std::ostringstream m_oss;
|
||||||
|
std::string& m_targetString;
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class RunContext : public IResultCapture, public IRunner {
|
class RunContext : public IResultCapture, public IRunner {
|
||||||
|
@ -20,6 +20,7 @@ namespace Catch {
|
|||||||
|
|
||||||
std::ostream& cout();
|
std::ostream& cout();
|
||||||
std::ostream& cerr();
|
std::ostream& cerr();
|
||||||
|
std::ostream& clog();
|
||||||
|
|
||||||
|
|
||||||
struct IStream {
|
struct IStream {
|
||||||
|
@ -101,6 +101,9 @@ namespace Catch {
|
|||||||
std::ostream& cerr() {
|
std::ostream& cerr() {
|
||||||
return std::cerr;
|
return std::cerr;
|
||||||
}
|
}
|
||||||
|
std::ostream& clog() {
|
||||||
|
return std::clog;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ struct AutoReg : NonCopyable {
|
|||||||
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||||
static void TestName(); \
|
static void TestName(); \
|
||||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } \
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||||
static void TestName()
|
static void TestName()
|
||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||||
@ -60,7 +60,7 @@ struct AutoReg : NonCopyable {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||||
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } \
|
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -70,7 +70,7 @@ struct AutoReg : NonCopyable {
|
|||||||
struct TestName : ClassName{ \
|
struct TestName : ClassName{ \
|
||||||
void test(); \
|
void test(); \
|
||||||
}; \
|
}; \
|
||||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); \
|
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||||
} \
|
} \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
|
||||||
void TestName::test()
|
void TestName::test()
|
||||||
@ -80,7 +80,7 @@ struct AutoReg : NonCopyable {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
|
||||||
Catch::AutoReg( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); \
|
Catch::AutoReg( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||||
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||||
|
|
||||||
|
|
||||||
|
@ -671,6 +671,9 @@ with messages:
|
|||||||
|
|
||||||
A string sent directly to stdout
|
A string sent directly to stdout
|
||||||
A string sent directly to stderr
|
A string sent directly to stderr
|
||||||
|
Write to std::cerr
|
||||||
|
Write to std::clog
|
||||||
|
Interleaved writes to error streams
|
||||||
Message from section one
|
Message from section one
|
||||||
Message from section two
|
Message from section two
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -1016,6 +1019,6 @@ with expansion:
|
|||||||
"{?}" == "1"
|
"{?}" == "1"
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 182 | 131 passed | 47 failed | 4 failed as expected
|
test cases: 183 | 132 passed | 47 failed | 4 failed as expected
|
||||||
assertions: 896 | 779 passed | 96 failed | 21 failed as expected
|
assertions: 896 | 779 passed | 96 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -4177,6 +4177,39 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
Approx( 1.23 ) != 1.24
|
Approx( 1.23 ) != 1.24
|
||||||
|
|
||||||
|
Write to std::cerr
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Standard error is reported and redirected
|
||||||
|
std::cerr
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in section 'std::cerr'
|
||||||
|
|
||||||
|
Write to std::clog
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Standard error is reported and redirected
|
||||||
|
std::clog
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in section 'std::clog'
|
||||||
|
|
||||||
|
Interleaved writes to error streams
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Standard error is reported and redirected
|
||||||
|
Interleaved writes to cerr and clog
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
MessageTests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
|
||||||
|
No assertions in section 'Interleaved writes to cerr and clog'
|
||||||
|
|
||||||
Message from section one
|
Message from section one
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Standard output from all sections is reported
|
Standard output from all sections is reported
|
||||||
@ -7590,6 +7623,6 @@ MiscTests.cpp:<line number>:
|
|||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 182 | 130 passed | 48 failed | 4 failed as expected
|
test cases: 183 | 130 passed | 49 failed | 4 failed as expected
|
||||||
assertions: 898 | 779 passed | 98 failed | 21 failed as expected
|
assertions: 901 | 779 passed | 101 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesspanner>
|
<testsuitesspanner>
|
||||||
<testsuite name="<exe-name>" errors="15" failures="84" tests="899" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="15" failures="87" tests="902" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
||||||
<error type="TEST_CASE">
|
<error type="TEST_CASE">
|
||||||
@ -486,6 +486,13 @@ A string sent directly to stderr
|
|||||||
</system-err>
|
</system-err>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Some simple comparisons between doubles" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Some simple comparisons between doubles" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Standard error is reported and redirected/Interleaved writes to cerr and clog" time="{duration}">
|
||||||
|
<system-err>
|
||||||
|
Write to std::cerr
|
||||||
|
Write to std::clog
|
||||||
|
Interleaved writes to error streams
|
||||||
|
</system-err>
|
||||||
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Standard output from all sections is reported/two" time="{duration}">
|
<testcase classname="<exe-name>.global" name="Standard output from all sections is reported/two" time="{duration}">
|
||||||
<system-out>
|
<system-out>
|
||||||
Message from section one
|
Message from section one
|
||||||
@ -792,6 +799,9 @@ Message from section two
|
|||||||
</system-out>
|
</system-out>
|
||||||
<system-err>
|
<system-err>
|
||||||
A string sent directly to stderr
|
A string sent directly to stderr
|
||||||
|
Write to std::cerr
|
||||||
|
Write to std::clog
|
||||||
|
Interleaved writes to error streams
|
||||||
</system-err>
|
</system-err>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
@ -4817,6 +4817,24 @@ A string sent directly to stderr
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Standard error is reported and redirected" tags="[.][hide][messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
|
<Section name="std::cerr" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
|
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="std::clog" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
|
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="Interleaved writes to cerr and clog" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
|
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResult success="false">
|
||||||
|
<StdErr>
|
||||||
|
Write to std::cerr
|
||||||
|
Write to std::clog
|
||||||
|
Interleaved writes to error streams
|
||||||
|
</StdErr>
|
||||||
|
</OverallResult>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Standard output from all sections is reported" tags="[.][hide][messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
<TestCase name="Standard output from all sections is reported" tags="[.][hide][messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
<Section name="one" filename="projects/<exe-name>/MessageTests.cpp" >
|
<Section name="one" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||||
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
<OverallResults successes="0" failures="1" expectedFailures="0"/>
|
||||||
@ -8441,7 +8459,7 @@ spanner <OverallResult success="true"/>
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="779" failures="99" expectedFailures="21"/>
|
<OverallResults successes="779" failures="102" expectedFailures="21"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="779" failures="98" expectedFailures="21"/>
|
<OverallResults successes="779" failures="101" expectedFailures="21"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@ -85,6 +85,23 @@ TEST_CASE( "Standard output from all sections is reported", "[messages][.]" ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Standard error is reported and redirected", "[messages][.]" ) {
|
||||||
|
SECTION( "std::cerr" ) {
|
||||||
|
std::cerr << "Write to std::cerr" << std::endl;
|
||||||
|
}
|
||||||
|
SECTION( "std::clog" ) {
|
||||||
|
std::clog << "Write to std::clog" << std::endl;
|
||||||
|
}
|
||||||
|
SECTION( "Interleaved writes to cerr and clog" ) {
|
||||||
|
std::cerr << "Inter";
|
||||||
|
std::clog << "leaved";
|
||||||
|
std::cerr << ' ';
|
||||||
|
std::clog << "writes";
|
||||||
|
std::cerr << " to error";
|
||||||
|
std::clog << " streams\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "SCOPED_INFO is reset for each loop", "[messages][failing][.]" ) {
|
TEST_CASE( "SCOPED_INFO is reset for each loop", "[messages][failing][.]" ) {
|
||||||
for( int i=0; i<100; i++ )
|
for( int i=0; i<100; i++ )
|
||||||
{
|
{
|
||||||
|
@ -7,5 +7,7 @@ v = Version()
|
|||||||
v.incrementBuildNumber()
|
v.incrementBuildNumber()
|
||||||
v.updateVersionFile()
|
v.updateVersionFile()
|
||||||
v.updateReadmeFile()
|
v.updateReadmeFile()
|
||||||
|
v.updateConanFile()
|
||||||
|
v.updateConanTestFile()
|
||||||
|
|
||||||
print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
|
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
|
||||||
|
@ -7,5 +7,7 @@ v = Version()
|
|||||||
v.incrementMajorVersion()
|
v.incrementMajorVersion()
|
||||||
v.updateVersionFile()
|
v.updateVersionFile()
|
||||||
v.updateReadmeFile()
|
v.updateReadmeFile()
|
||||||
|
v.updateConanFile()
|
||||||
|
v.updateConanTestFile()
|
||||||
|
|
||||||
print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
|
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
|
||||||
|
@ -7,5 +7,7 @@ v = Version()
|
|||||||
v.incrementMinorVersion()
|
v.incrementMinorVersion()
|
||||||
v.updateVersionFile()
|
v.updateVersionFile()
|
||||||
v.updateReadmeFile()
|
v.updateReadmeFile()
|
||||||
|
v.updateConanFile()
|
||||||
|
v.updateConanTestFile()
|
||||||
|
|
||||||
print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
|
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
|
||||||
|
@ -7,5 +7,7 @@ v = Version()
|
|||||||
v.incrementPatchNumber()
|
v.incrementPatchNumber()
|
||||||
v.updateVersionFile()
|
v.updateVersionFile()
|
||||||
v.updateReadmeFile()
|
v.updateReadmeFile()
|
||||||
|
v.updateConanFile()
|
||||||
|
v.updateConanTestFile()
|
||||||
|
|
||||||
print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
|
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
|
||||||
|
@ -11,6 +11,8 @@ versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.
|
|||||||
rootPath = os.path.join( catchPath, 'include/' )
|
rootPath = os.path.join( catchPath, 'include/' )
|
||||||
versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
|
versionPath = os.path.join( rootPath, "internal/catch_version.cpp" )
|
||||||
readmePath = os.path.join( catchPath, "README.md" )
|
readmePath = os.path.join( catchPath, "README.md" )
|
||||||
|
conanPath = os.path.join(catchPath, 'conanfile.py')
|
||||||
|
conanTestPath = os.path.join(catchPath, 'test_package', 'conanfile.py')
|
||||||
|
|
||||||
class Version:
|
class Version:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -86,3 +88,32 @@ class Version:
|
|||||||
line = downloadParser.sub( r'<a href="https://github.com/philsquared/Catch/releases/download/v{0}/catch.hpp">'.format(self.getVersionString()) , line)
|
line = downloadParser.sub( r'<a href="https://github.com/philsquared/Catch/releases/download/v{0}/catch.hpp">'.format(self.getVersionString()) , line)
|
||||||
f.write( line + "\n" )
|
f.write( line + "\n" )
|
||||||
|
|
||||||
|
def updateConanFile(self):
|
||||||
|
conanParser = re.compile( r' version = "\d+\.\d+\.\d+.*"')
|
||||||
|
f = open( conanPath, 'r' )
|
||||||
|
lines = []
|
||||||
|
for line in f:
|
||||||
|
m = conanParser.match( line )
|
||||||
|
if m:
|
||||||
|
lines.append( ' version = "{0}"'.format(format(self.getVersionString())) )
|
||||||
|
else:
|
||||||
|
lines.append( line.rstrip() )
|
||||||
|
f.close()
|
||||||
|
f = open( conanPath, 'w' )
|
||||||
|
for line in lines:
|
||||||
|
f.write( line + "\n" )
|
||||||
|
|
||||||
|
def updateConanTestFile(self):
|
||||||
|
conanParser = re.compile( r' requires = \"Catch\/\d+\.\d+\.\d+.*@%s\/%s\" % \(username, channel\)')
|
||||||
|
f = open( conanTestPath, 'r' )
|
||||||
|
lines = []
|
||||||
|
for line in f:
|
||||||
|
m = conanParser.match( line )
|
||||||
|
if m:
|
||||||
|
lines.append( ' requires = "Catch/{0}@%s/%s" % (username, channel)'.format(format(self.getVersionString())) )
|
||||||
|
else:
|
||||||
|
lines.append( line.rstrip() )
|
||||||
|
f.close()
|
||||||
|
f = open( conanTestPath, 'w' )
|
||||||
|
for line in lines:
|
||||||
|
f.write( line + "\n" )
|
||||||
|
@ -57,24 +57,21 @@ def update_portfile(path, header_hash, licence_hash):
|
|||||||
for line in f:
|
for line in f:
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
with open(portfile_path, 'w') as f:
|
with open(portfile_path, 'w') as f:
|
||||||
# Two things we need to change/update
|
# There are three things we need to change/update
|
||||||
# 1) Link and hash of releaseCommon
|
# 1) CATCH_VERSION cmake variable
|
||||||
# 2) Link and hash of licence
|
# 2) Hash of header
|
||||||
|
# 3) Hash of licence
|
||||||
# We could assume licence never changes, but where is the fun in that?
|
# We could assume licence never changes, but where is the fun in that?
|
||||||
first_hash = True
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
# Check what we are updating
|
# Update the version
|
||||||
|
if 'set(CATCH_VERSION' in line:
|
||||||
|
line = 'set(CATCH_VERSION v{})'.format(v.getVersionString())
|
||||||
|
|
||||||
|
# Determine which file we are updating
|
||||||
if 'vcpkg_download_distfile' in line:
|
if 'vcpkg_download_distfile' in line:
|
||||||
kind = line.split('(')[-1].strip()
|
kind = line.split('(')[-1].strip()
|
||||||
print(kind)
|
|
||||||
|
|
||||||
# Deal with URLS
|
# Update the hashes
|
||||||
if 'URLS' in line and kind == 'HEADER':
|
|
||||||
line = ' URLS "https://github.com/philsquared/Catch/releases/download/v{}/catch.hpp"\n'.format(v.getVersionString())
|
|
||||||
if 'URLS' in line and kind == 'LICENSE':
|
|
||||||
line = ' URLS "https://raw.githubusercontent.com/philsquared/Catch/v{}/LICENSE.txt"\n'.format(v.getVersionString())
|
|
||||||
|
|
||||||
# Deal with hashes
|
|
||||||
if 'SHA512' in line and kind == 'HEADER':
|
if 'SHA512' in line and kind == 'HEADER':
|
||||||
line = ' SHA512 {}\n'.format(header_hash)
|
line = ' SHA512 {}\n'.format(header_hash)
|
||||||
if 'SHA512' in line and kind == 'LICENSE':
|
if 'SHA512' in line and kind == 'LICENSE':
|
||||||
@ -86,8 +83,6 @@ def git_push(path_to_repo):
|
|||||||
v = Version()
|
v = Version()
|
||||||
ver_string = v.getVersionString()
|
ver_string = v.getVersionString()
|
||||||
|
|
||||||
# Move to the repo dir
|
|
||||||
old_path = os.getcwd()
|
|
||||||
os.chdir(path_to_repo)
|
os.chdir(path_to_repo)
|
||||||
|
|
||||||
# Work with git
|
# Work with git
|
||||||
|
7
test_package/CMakeLists.txt
Normal file
7
test_package/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(CatchTest CXX)
|
||||||
|
|
||||||
|
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||||
|
conan_basic_setup()
|
||||||
|
|
||||||
|
add_executable(${CMAKE_PROJECT_NAME} MainTest.cpp)
|
21
test_package/MainTest.cpp
Normal file
21
test_package/MainTest.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Created by Phil on 22/10/2010.
|
||||||
|
* Copyright 2010 Two Blue Cubes Ltd
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
unsigned int Factorial( unsigned int number ) {
|
||||||
|
return number > 1 ? Factorial(number-1)*number : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Factorials are computed", "[factorial]" ) {
|
||||||
|
REQUIRE( Factorial(0) == 1 );
|
||||||
|
REQUIRE( Factorial(1) == 1 );
|
||||||
|
REQUIRE( Factorial(2) == 2 );
|
||||||
|
REQUIRE( Factorial(3) == 6 );
|
||||||
|
REQUIRE( Factorial(10) == 3628800 );
|
||||||
|
}
|
21
test_package/conanfile.py
Normal file
21
test_package/conanfile.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from os import getenv
|
||||||
|
from os import path
|
||||||
|
from conans import ConanFile
|
||||||
|
from conans import CMake
|
||||||
|
|
||||||
|
|
||||||
|
class CatchConanTest(ConanFile):
|
||||||
|
generators = "cmake"
|
||||||
|
settings = "os", "compiler", "arch", "build_type"
|
||||||
|
username = getenv("CONAN_USERNAME", "philsquared")
|
||||||
|
channel = getenv("CONAN_CHANNEL", "testing")
|
||||||
|
requires = "Catch/1.9.5@%s/%s" % (username, channel)
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.configure(build_dir="./")
|
||||||
|
cmake.build()
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
self.run(path.join("bin", "CatchTest"))
|
Loading…
Reference in New Issue
Block a user