mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-18 19:05:40 +02:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a56609569 | ||
![]() |
81159838a5 | ||
![]() |
78a2866dc7 | ||
![]() |
9acc6b9673 | ||
![]() |
c4b5057094 | ||
![]() |
d38b9266e7 | ||
![]() |
227598af47 | ||
![]() |
cfaf906417 | ||
![]() |
ee0ca512ea | ||
![]() |
b71a06cf98 | ||
![]() |
531d26739f | ||
![]() |
2e87f8e328 | ||
![]() |
afe46ff270 | ||
![]() |
c65aeaf25f | ||
![]() |
750b52b814 | ||
![]() |
e12fc4aca0 | ||
![]() |
99cdc62fef | ||
![]() |
e6ef60a2c4 | ||
![]() |
e1c4a4bd9b | ||
![]() |
25d017763b | ||
![]() |
b634e592da | ||
![]() |
e3659cdddd | ||
![]() |
b3907a78e1 | ||
![]() |
d5360e8e29 | ||
![]() |
9062ebe390 | ||
![]() |
e6aa1f4e4e | ||
![]() |
1ff0acfe22 | ||
![]() |
713ec400e8 |
@@ -155,7 +155,7 @@ install:
|
||||
before_script:
|
||||
- export CXX=${COMPILER}
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
- cmake -H. -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -Wdev
|
||||
- cd Build
|
||||
|
||||
script:
|
||||
|
@@ -13,30 +13,65 @@ if(USE_CPP11)
|
||||
## We can't turn this on by default, since it breaks on travis
|
||||
message(STATUS "Enabling C++11")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||
elseif(USE_CPP14)
|
||||
message(STATUS "Enabling C++14")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
#checks that the given hard-coded list contains all headers + sources in the given folder
|
||||
function(CheckFileList LIST_VAR FOLDER)
|
||||
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
||||
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
||||
file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
|
||||
"${FOLDER}/*.hpp"
|
||||
"${FOLDER}/*.h")
|
||||
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
||||
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
||||
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
||||
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(CheckFileListRec LIST_VAR FOLDER)
|
||||
set(MESSAGE " should be added to the variable ${LIST_VAR}")
|
||||
set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
|
||||
file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
|
||||
"${FOLDER}/*.hpp"
|
||||
"${FOLDER}/*.h")
|
||||
list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
|
||||
foreach(EXTRA_ITEM ${GLOBBED_LIST})
|
||||
string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
|
||||
message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# define the sources of the self test
|
||||
# Please keep these ordered alphabetically
|
||||
set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/ApproxTests.cpp
|
||||
${SELF_TEST_DIR}/BDDTests.cpp
|
||||
${SELF_TEST_DIR}/ClassTests.cpp
|
||||
${SELF_TEST_DIR}/CmdLineTests.cpp
|
||||
${SELF_TEST_DIR}/ConditionTests.cpp
|
||||
${SELF_TEST_DIR}/EnumToString.cpp
|
||||
${SELF_TEST_DIR}/ExceptionTests.cpp
|
||||
${SELF_TEST_DIR}/GeneratorTests.cpp
|
||||
${SELF_TEST_DIR}/MessageTests.cpp
|
||||
${SELF_TEST_DIR}/MiscTests.cpp
|
||||
${SELF_TEST_DIR}/PartTrackerTests.cpp
|
||||
${SELF_TEST_DIR}/TagAliasTests.cpp
|
||||
${SELF_TEST_DIR}/TestMain.cpp
|
||||
${SELF_TEST_DIR}/TrickyTests.cpp
|
||||
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
||||
${SELF_TEST_DIR}/EnumToString.cpp
|
||||
${SELF_TEST_DIR}/ToStringPair.cpp
|
||||
${SELF_TEST_DIR}/ToStringTuple.cpp
|
||||
${SELF_TEST_DIR}/ToStringVector.cpp
|
||||
${SELF_TEST_DIR}/ToStringWhich.cpp
|
||||
${SELF_TEST_DIR}/ToStringTuple.cpp
|
||||
${SELF_TEST_DIR}/CmdLineTests.cpp
|
||||
${SELF_TEST_DIR}/TagAliasTests.cpp
|
||||
${SELF_TEST_DIR}/TrickyTests.cpp
|
||||
${SELF_TEST_DIR}/VariadicMacrosTests.cpp
|
||||
)
|
||||
CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
|
||||
|
||||
# A set of impl files that just #include a single header
|
||||
# Please keep these ordered alphabetically
|
||||
set(IMPL_SOURCES
|
||||
${SELF_TEST_DIR}/SurrogateCpps/catch_common.cpp
|
||||
${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
|
||||
@@ -57,12 +92,27 @@ set(IMPL_SOURCES
|
||||
${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
|
||||
${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
|
||||
)
|
||||
CheckFileList(IMPL_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
|
||||
|
||||
# Specify the headers, too, so CLion recognises them as project files
|
||||
set(HEADERS
|
||||
|
||||
# Please keep these ordered alphabetically
|
||||
set(TOP_LEVEL_HEADERS
|
||||
${HEADER_DIR}/catch.hpp
|
||||
${HEADER_DIR}/catch_session.hpp
|
||||
${HEADER_DIR}/catch_with_main.hpp
|
||||
)
|
||||
CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
|
||||
|
||||
# Please keep these ordered alphabetically
|
||||
set(EXTERNAL_HEADERS
|
||||
${HEADER_DIR}/external/clara.h
|
||||
${HEADER_DIR}/external/tbc_text_format.h
|
||||
)
|
||||
CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
|
||||
|
||||
|
||||
# Please keep these ordered alphabetically
|
||||
set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_approx.hpp
|
||||
${HEADER_DIR}/internal/catch_assertionresult.h
|
||||
${HEADER_DIR}/internal/catch_assertionresult.hpp
|
||||
@@ -144,9 +194,13 @@ set(HEADERS
|
||||
${HEADER_DIR}/internal/catch_version.h
|
||||
${HEADER_DIR}/internal/catch_version.hpp
|
||||
${HEADER_DIR}/internal/catch_wildcard_pattern.hpp
|
||||
${HEADER_DIR}/internal/catch_windows_h_proxy.h
|
||||
${HEADER_DIR}/internal/catch_xmlwriter.hpp
|
||||
${HEADER_DIR}/external/clara.h
|
||||
${HEADER_DIR}/external/tbc_text_format.h
|
||||
)
|
||||
CheckFileList(INTERNAL_HEADERS ${HEADER_DIR}/internal)
|
||||
|
||||
# Please keep these ordered alphabetically
|
||||
set(REPORTER_HEADERS
|
||||
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_compact.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_console.hpp
|
||||
@@ -155,7 +209,18 @@ set(HEADERS
|
||||
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
|
||||
${HEADER_DIR}/reporters/catch_reporter_xml.hpp
|
||||
)
|
||||
CheckFileList(REPORTER_HEADERS ${HEADER_DIR}/reporters)
|
||||
|
||||
# Specify the headers, too, so CLion recognises them as project files
|
||||
set(HEADERS
|
||||
${TOP_LEVEL_HEADERS}
|
||||
${EXTERNAL_HEADERS}
|
||||
${INTERNAL_HEADERS}
|
||||
${REPORTER_HEADERS}
|
||||
)
|
||||
|
||||
|
||||
# Provide some groupings for IDEs
|
||||
SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
|
||||
SOURCE_GROUP("Surrogates" FILES ${IMPL_SOURCES})
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
*v1.6.0*
|
||||
*v1.6.1*
|
||||
|
||||
Build status (on Travis CI) [](https://travis-ci.org/philsquared/Catch)
|
||||
|
||||
|
BIN
catch-logo-tiny.png
Normal file
BIN
catch-logo-tiny.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
@@ -17,4 +17,4 @@ Other
|
||||
|
||||
* [Why Catch?](why-catch.md)
|
||||
* [Contributing](contributing.md)
|
||||
* [Release Nodes](release-notes.md)
|
||||
* [Release Notes](release-notes.md)
|
@@ -66,6 +66,8 @@ A series of tags form an AND expression wheras a comma-separated sequence forms
|
||||
<pre>[one][two],[three]</pre>
|
||||
This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]`
|
||||
|
||||
Test names containing special characters, such as `,` or `[` can specify them on the command line using `\`.
|
||||
`\` also escapes itself.
|
||||
|
||||
<a id="choosing-a-reporter-to-use"></a>
|
||||
## Choosing a reporter to use
|
||||
|
@@ -69,6 +69,13 @@ You may also suppress any of these features by using the `_NO_` form, e.g. `CATC
|
||||
|
||||
All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
|
||||
|
||||
# Windows header clutter
|
||||
|
||||
On Windows Catch includes `windows.h`. To minimize global namespace clutter in the implementation file, it defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including it. You can control this behaviour via two macros:
|
||||
|
||||
CATCH_CONFIG_NO_NOMINMAX // Stops Catch from using NOMINMAX macro
|
||||
CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN // Stops Catch from using WIN32_LEAN_AND_MEAN macro
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md)
|
||||
[Home](Readme.md)
|
||||
|
@@ -16,7 +16,7 @@ If you just need to have code that executes before and/ or after Catch this is t
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.hpp"
|
||||
|
||||
int main( int argc, char* const argv[] )
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
// global setup...
|
||||
|
||||
@@ -36,7 +36,7 @@ If you still want Catch to process the command line, but you want to programatic
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.hpp"
|
||||
|
||||
int main( int argc, char* const argv[] )
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
Catch::Session session; // There must be exactly one instance
|
||||
|
||||
|
@@ -1,25 +1,47 @@
|
||||
# 1.6.0
|
||||
# 1.6.1
|
||||
|
||||
### Features/ Changes:
|
||||
* Catch now supports breaking into debugger on Linux
|
||||
|
||||
### Fixes:
|
||||
* Generators no longer leak memory (generators are still unsupported in general)
|
||||
* JUnit reporter now reports UTC timestamps, instead of "tbd"
|
||||
* `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros
|
||||
|
||||
### Other:
|
||||
* Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro.
|
||||
* The use of `__COUNTER__` is supressed when Catch is parsed by CLion
|
||||
* This change is not active when compiling a binary
|
||||
* Approval tests can now be run on Windows
|
||||
* CMake will now warn if a file is present in the `include` folder but not is not enumerated as part of the project
|
||||
* Catch now defines `NOMINMAX` and `WIN32_LEAN_AND_MEAN` before including `windows.h`
|
||||
* This can be disabled if needed, see [documentation](docs/configuration.md) for details.
|
||||
|
||||
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
## 1.6.0
|
||||
|
||||
### Cmake/ projects:
|
||||
* Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects.
|
||||
|
||||
### Features/ Changes:
|
||||
* Approx now supports >= and <=
|
||||
* Can now use \ to escape chars in test names on command line
|
||||
* Approx now supports `>=` and `<=`
|
||||
* Can now use `\` to escape chars in test names on command line
|
||||
* Standardize C++11 feature toggles
|
||||
|
||||
### Fixes:
|
||||
* Blue shell colour
|
||||
* Missing argument to CATCH_CHECK_THROWS
|
||||
* Missing argument to `CATCH_CHECK_THROWS`
|
||||
* Don't encode extended ASCII in XML
|
||||
* use std::shuffle on more compilers (fixes deprecation warning/error)
|
||||
* Use __COUNTER__ more consistently (where available)
|
||||
* use `std::shuffle` on more compilers (fixes deprecation warning/error)
|
||||
* Use `__COUNTER__` more consistently (where available)
|
||||
|
||||
### Other:
|
||||
* Tweaks and changes to scripts - particularly for Approval test - to make them more portable
|
||||
|
||||
# Older versions
|
||||
Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
|
||||
|
||||
---
|
||||
|
||||
|
@@ -86,7 +86,7 @@
|
||||
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
|
||||
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
|
||||
|
||||
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
|
||||
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
|
@@ -40,7 +40,7 @@
|
||||
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
|
||||
} \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
} while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
||||
|
@@ -116,9 +116,8 @@ namespace Catch {
|
||||
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
|
||||
|
||||
// This is just here to avoid compiler warnings with macro constants and boolean literals
|
||||
inline bool isTrue( bool value ){ return value; }
|
||||
inline bool alwaysTrue() { return true; }
|
||||
inline bool alwaysFalse() { return false; }
|
||||
inline bool alwaysTrue( std::size_t = 0 ) { return true; }
|
||||
inline bool alwaysFalse( std::size_t = 0 ) { return false; }
|
||||
|
||||
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
|
||||
|
||||
|
@@ -215,7 +215,10 @@
|
||||
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
|
||||
#endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
||||
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
|
||||
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
|
||||
// This does not affect compilation
|
||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
|
||||
# define CATCH_CONFIG_COUNTER
|
||||
#endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
|
@@ -41,15 +41,7 @@ namespace Catch {
|
||||
|
||||
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "catch_windows_h_proxy.h"
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "catch_context.h"
|
||||
#include "catch_stream.hpp"
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -21,6 +22,11 @@ namespace Catch {
|
||||
Context( Context const& );
|
||||
void operator=( Context const& );
|
||||
|
||||
public:
|
||||
virtual ~Context() {
|
||||
deleteAllValues( m_generatorsByTestName );
|
||||
}
|
||||
|
||||
public: // IContext
|
||||
virtual IResultCapture* getResultCapture() {
|
||||
return m_resultCapture;
|
||||
|
@@ -25,25 +25,36 @@ namespace Catch{
|
||||
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
||||
#ifdef DEBUG
|
||||
#if defined(__ppc64__) || defined(__ppc__)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() \
|
||||
if( Catch::isDebuggerActive() ) { \
|
||||
#define CATCH_TRAP() \
|
||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ); \
|
||||
}
|
||||
: : : "memory","r0","r3","r4" )
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
|
||||
#define CATCH_TRAP() _asm__("int $3\n" : : )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
// If we can use inline assembler, do it because this allows us to break
|
||||
// directly at the location of the failing check instead of breaking inside
|
||||
// raise() called from it, i.e. one stack frame below.
|
||||
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
|
||||
#define CATCH_TRAP() asm volatile ("int $3")
|
||||
#else // Fall back to the generic way.
|
||||
#include <signal.h>
|
||||
|
||||
#define CATCH_TRAP() raise(SIGTRAP)
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
|
||||
#define CATCH_TRAP() __debugbreak()
|
||||
#elif defined(__MINGW32__)
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
|
||||
#define CATCH_TRAP() DebugBreak()
|
||||
#endif
|
||||
|
||||
#ifndef CATCH_BREAK_INTO_DEBUGGER
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
|
||||
#ifdef CATCH_TRAP
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
||||
|
@@ -61,6 +61,33 @@
|
||||
}
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace Catch{
|
||||
// The standard POSIX way of detecting a debugger is to attempt to
|
||||
// ptrace() the process, but this needs to be done from a child and not
|
||||
// this process itself to still allow attaching to this process later
|
||||
// if wanted, so is rather heavy. Under Linux we have the PID of the
|
||||
// "debugger" (which doesn't need to be gdb, of course, it could also
|
||||
// be strace, for example) in /proc/$PID/status, so just get it from
|
||||
// there instead.
|
||||
bool isDebuggerActive(){
|
||||
std::ifstream in("/proc/self/status");
|
||||
for( std::string line; std::getline(in, line); ) {
|
||||
static const int PREFIX_LEN = 11;
|
||||
if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
|
||||
// We're traced if the PID is not 0 and no other PID starts
|
||||
// with 0 digit, so it's enough to check for just a single
|
||||
// character.
|
||||
return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace Catch
|
||||
#elif defined(_MSC_VER)
|
||||
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
|
||||
namespace Catch {
|
||||
|
@@ -10,11 +10,19 @@
|
||||
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
||||
|
||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
#define CATCH_PLATFORM_MAC
|
||||
# define CATCH_PLATFORM_MAC
|
||||
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#define CATCH_PLATFORM_IPHONE
|
||||
# define CATCH_PLATFORM_IPHONE
|
||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define CATCH_PLATFORM_LINUX
|
||||
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
|
||||
#define CATCH_PLATFORM_WINDOWS
|
||||
# define CATCH_PLATFORM_WINDOWS
|
||||
# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
|
||||
# define CATCH_DEFINES_NOMINMAX
|
||||
# endif
|
||||
# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
|
||||
# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
||||
|
@@ -15,7 +15,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#include <windows.h>
|
||||
#include "catch_windows_h_proxy.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 6, 0, "", 0 );
|
||||
Version libraryVersion( 1, 6, 1, "", 0 );
|
||||
|
||||
}
|
||||
|
||||
|
32
include/internal/catch_windows_h_proxy.h
Normal file
32
include/internal/catch_windows_h_proxy.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Created by Martin on 16/01/2017.
|
||||
*
|
||||
* 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_WINDOWS_H_PROXY_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
@@ -18,6 +18,35 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
std::string getCurrentTimestamp() {
|
||||
// Beware, this is not reentrant because of backward compatibility issues
|
||||
// Also, UTC only, again because of backward compatibility (%z is C++11)
|
||||
time_t rawtime;
|
||||
std::time(&rawtime);
|
||||
const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
std::tm timeInfo = {};
|
||||
gmtime_s(&timeInfo, &rawtime);
|
||||
#else
|
||||
std::tm* timeInfo;
|
||||
timeInfo = std::gmtime(&rawtime);
|
||||
#endif
|
||||
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
#endif
|
||||
return std::string(timeStamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JunitReporter : public CumulativeReporterBase {
|
||||
public:
|
||||
JunitReporter( ReporterConfig const& _config )
|
||||
@@ -82,7 +111,7 @@ namespace Catch {
|
||||
xml.writeAttribute( "time", "" );
|
||||
else
|
||||
xml.writeAttribute( "time", suiteTime );
|
||||
xml.writeAttribute( "timestamp", "tbd" ); // !TBD
|
||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||
|
||||
// Write test cases
|
||||
for( TestGroupNode::ChildNodes::const_iterator
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8"?>
|
||||
<testsuites>
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="912" hostname="tbd" time="{duration}" timestamp="tbd">
|
||||
<testsuite name="<exe-name>" errors="13" failures="68" tests="912" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testcase classname="global" name="# A test name that starts with a #" time="{duration}"/>
|
||||
<testcase classname="global" name="'Not' checks that should fail" time="{duration}">
|
||||
<failure message="false != false" type="CHECK">
|
||||
|
@@ -1,30 +0,0 @@
|
||||
SOURCES = ApproxTests.cpp \
|
||||
ClassTests.cpp \
|
||||
ConditionTests.cpp \
|
||||
ExceptionTests.cpp \
|
||||
GeneratorTests.cpp \
|
||||
MessageTests.cpp \
|
||||
MiscTests.cpp \
|
||||
TestMain.cpp \
|
||||
TrickyTests.cpp \
|
||||
BDDTests.cpp \
|
||||
VariadicMacrosTests.cpp \
|
||||
EnumToString.cpp \
|
||||
ToStringPair.cpp \
|
||||
ToStringVector.cpp \
|
||||
ToStringWhich.cpp
|
||||
|
||||
|
||||
OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES))
|
||||
CXX = g++
|
||||
CXXFLAGS = -I../../include -std=c++11
|
||||
|
||||
CatchSelfTest: $(OBJECTS)
|
||||
$(CXX) -o $@ $^
|
||||
|
||||
test: CatchSelfTest
|
||||
./CatchSelfTest
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) CatchSelfTest
|
||||
|
@@ -1,78 +1,95 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import re
|
||||
import difflib
|
||||
|
||||
import scriptCommon
|
||||
from scriptCommon import catchPath
|
||||
|
||||
rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines')
|
||||
|
||||
filenameParser = re.compile(r'(.*)/(.*\..pp:)(.*)')
|
||||
filelineParser = re.compile(r'(.*\..pp:)([0-9]*)(.*)')
|
||||
pathParser = re.compile(r'(.*?)/(.*\..pp)(.*)')
|
||||
lineNumberParser = re.compile(r'(.*)line="[0-9]*"(.*)')
|
||||
hexParser = re.compile(r'(.*)\b(0[xX][0-9a-fA-F]+)\b(.*)')
|
||||
durationsParser = re.compile(r'(.*)time="[0-9]*\.[0-9]*"(.*)')
|
||||
versionParser = re.compile(r'(.*?)Catch v[0-9]*\.[0-9]*\.[0-9]*(.*)')
|
||||
devVersionParser = re.compile(r'(.*?)Catch v[0-9]*\.[0-9]*\.[0-9]*-develop\.[0-9]*(.*)')
|
||||
nullParser = re.compile(r'(.*?)\b(__null|nullptr)\b(.*)')
|
||||
exeNameParser = re.compile(r'(.*?)\b(CatchSelfTest|SelfTest)\b(.*)')
|
||||
|
||||
filelocParser = re.compile(r'''
|
||||
.*/
|
||||
(.+\.[ch]pp) # filename
|
||||
(?::|\() # : is starting separator between filename and line number on Linux, ( on Windows
|
||||
([0-9]*) # line number
|
||||
\)? # Windows also has an ending separator, )
|
||||
''', re.VERBOSE)
|
||||
lineNumberParser = re.compile(r' line="[0-9]*"')
|
||||
hexParser = re.compile(r'\b(0[xX][0-9a-fA-F]+)\b')
|
||||
durationsParser = re.compile(r' time="[0-9]*\.[0-9]*"')
|
||||
timestampsParser = re.compile(r' timestamp="\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z"')
|
||||
versionParser = re.compile(r'Catch v[0-9]+\.[0-9]+\.[0-9]+(-develop\.[0-9]+)?')
|
||||
nullParser = re.compile(r'\b(__null|nullptr)\b')
|
||||
exeNameParser = re.compile(r'''
|
||||
\b
|
||||
(CatchSelfTest|SelfTest) # Expected executable name
|
||||
(?:.exe)? # Executable name contains .exe on Windows.
|
||||
\b
|
||||
''', re.VERBOSE)
|
||||
# This is a hack until something more reasonable is figured out
|
||||
specialCaseParser = re.compile(r'file\((\d+)\)')
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
cmdPath = sys.argv[1]
|
||||
else:
|
||||
cmdPath = scriptCommon.getBuildExecutable()
|
||||
|
||||
if not cmdPath.startswith("/"):
|
||||
cmdPath = os.path.join(catchPath, cmdPath)
|
||||
cmdPath = os.path.join(catchPath, scriptCommon.getBuildExecutable())
|
||||
|
||||
overallResult = 0
|
||||
|
||||
def diffFiles(fileA, fileB):
|
||||
with open(fileA, 'r') as file:
|
||||
aLines = file.readlines()
|
||||
with open(fileB, 'r') as file:
|
||||
bLines = file.readlines()
|
||||
|
||||
shortenedFilenameA = fileA.rsplit(os.sep, 1)[-1]
|
||||
shortenedFilenameB = fileB.rsplit(os.sep, 1)[-1]
|
||||
|
||||
diff = difflib.unified_diff(aLines, bLines, fromfile=shortenedFilenameA, tofile=shortenedFilenameB, n=0)
|
||||
return [line for line in diff if line[0] in ('+', '-')]
|
||||
|
||||
|
||||
def filterLine(line):
|
||||
m = filenameParser.match(line)
|
||||
if catchPath in line:
|
||||
# make paths relative to Catch root
|
||||
line = line.replace(catchPath + os.sep, '')
|
||||
# go from \ in windows paths to /
|
||||
line = line.replace('\\', '/')
|
||||
|
||||
|
||||
# strip source line numbers
|
||||
m = filelocParser.match(line)
|
||||
if m:
|
||||
line = m.group(2) + m.group(3)
|
||||
m2 = filelineParser.match(line)
|
||||
if m2:
|
||||
line = m2.group(1) + "<line number>" + m2.group(3)
|
||||
# note that this also strips directories, leaving only the filename
|
||||
filename, lnum = m.groups()
|
||||
lnum = ":<line number>" if lnum else ""
|
||||
line = filename + lnum + line[m.end():]
|
||||
else:
|
||||
m2 = lineNumberParser.match(line)
|
||||
if m2:
|
||||
line = m2.group(1) + m2.group(2)
|
||||
m = pathParser.match(line)
|
||||
if m:
|
||||
path = "/" + m.group(2)
|
||||
if path.startswith(catchPath):
|
||||
path = path[1 + len(catchPath):]
|
||||
line = m.group(1) + path + m.group(3)
|
||||
m = devVersionParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + "<version>" + m.group(2)
|
||||
else:
|
||||
m = versionParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + "<version>" + m.group(2)
|
||||
line = lineNumberParser.sub(" ", line)
|
||||
|
||||
m = nullParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + "0" + m.group(3)
|
||||
# strip Catch version number
|
||||
line = versionParser.sub("<version>", line)
|
||||
|
||||
m = exeNameParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + "<exe-name>" + m.group(3)
|
||||
# replace *null* with 0
|
||||
line = nullParser.sub("0", line)
|
||||
|
||||
while True:
|
||||
m = hexParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + "0x<hex digits>" + m.group(3)
|
||||
else:
|
||||
break
|
||||
m = durationsParser.match(line)
|
||||
if m:
|
||||
line = m.group(1) + 'time="{duration}"' + m.group(2)
|
||||
# strip executable name
|
||||
line = exeNameParser.sub("<exe-name>", line)
|
||||
|
||||
# strip hexadecimal numbers (presumably pointer values)
|
||||
line = hexParser.sub("0x<hex digits>", line)
|
||||
|
||||
# strip durations and timestamps
|
||||
line = durationsParser.sub(' time="{duration}"', line)
|
||||
line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line)
|
||||
line = specialCaseParser.sub('file:\g<1>', line)
|
||||
return line
|
||||
|
||||
|
||||
@@ -100,14 +117,15 @@ def approve(baseName, args):
|
||||
print()
|
||||
print(baseName + ":")
|
||||
if os.path.exists(baselinesPath):
|
||||
diffResult = subprocess.call(["diff", baselinesPath, filteredResultsPath])
|
||||
if diffResult == 0:
|
||||
diffResult = diffFiles(baselinesPath, filteredResultsPath)
|
||||
if diffResult:
|
||||
print(''.join(diffResult))
|
||||
print(" \n****************************\n \033[91mResults differed")
|
||||
if len(diffResult) > overallResult:
|
||||
overallResult = len(diffResult)
|
||||
else:
|
||||
os.remove(filteredResultsPath)
|
||||
print(" \033[92mResults matched")
|
||||
else:
|
||||
print(" \n****************************\n \033[91mResults differed")
|
||||
if diffResult > overallResult:
|
||||
overallResult = diffResult
|
||||
print("\033[0m")
|
||||
else:
|
||||
print(" first approval")
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from releaseCommon import Version
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
import os
|
||||
from scriptCommon import catchPath
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from releaseCommon import Version
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from releaseCommon import Version
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from releaseCommon import Version
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import re
|
||||
import urllib2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v1.6.0
|
||||
* Generated: 2017-01-11 16:38:09.405017
|
||||
* Catch v1.6.1
|
||||
* Generated: 2017-01-20 12:33:53.497767
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||
@@ -266,7 +266,10 @@
|
||||
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
|
||||
#endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
|
||||
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
|
||||
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
|
||||
// This does not affect compilation
|
||||
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
|
||||
# define CATCH_CONFIG_COUNTER
|
||||
#endif
|
||||
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
|
||||
@@ -411,9 +414,8 @@ namespace Catch {
|
||||
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
|
||||
|
||||
// This is just here to avoid compiler warnings with macro constants and boolean literals
|
||||
inline bool isTrue( bool value ){ return value; }
|
||||
inline bool alwaysTrue() { return true; }
|
||||
inline bool alwaysFalse() { return false; }
|
||||
inline bool alwaysTrue( std::size_t = 0 ) { return true; }
|
||||
inline bool alwaysFalse( std::size_t = 0 ) { return false; }
|
||||
|
||||
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
|
||||
|
||||
@@ -2005,11 +2007,19 @@ namespace Catch {
|
||||
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
|
||||
|
||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
#define CATCH_PLATFORM_MAC
|
||||
# define CATCH_PLATFORM_MAC
|
||||
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#define CATCH_PLATFORM_IPHONE
|
||||
# define CATCH_PLATFORM_IPHONE
|
||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define CATCH_PLATFORM_LINUX
|
||||
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
|
||||
#define CATCH_PLATFORM_WINDOWS
|
||||
# define CATCH_PLATFORM_WINDOWS
|
||||
# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
|
||||
# define CATCH_DEFINES_NOMINMAX
|
||||
# endif
|
||||
# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
|
||||
# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
@@ -2026,25 +2036,36 @@ namespace Catch{
|
||||
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
||||
#ifdef DEBUG
|
||||
#if defined(__ppc64__) || defined(__ppc__)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() \
|
||||
if( Catch::isDebuggerActive() ) { \
|
||||
#define CATCH_TRAP() \
|
||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ); \
|
||||
}
|
||||
: : : "memory","r0","r3","r4" )
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
|
||||
#define CATCH_TRAP() _asm__("int $3\n" : : )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
// If we can use inline assembler, do it because this allows us to break
|
||||
// directly at the location of the failing check instead of breaking inside
|
||||
// raise() called from it, i.e. one stack frame below.
|
||||
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
|
||||
#define CATCH_TRAP() asm volatile ("int $3")
|
||||
#else // Fall back to the generic way.
|
||||
#include <signal.h>
|
||||
|
||||
#define CATCH_TRAP() raise(SIGTRAP)
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
|
||||
#define CATCH_TRAP() __debugbreak()
|
||||
#elif defined(__MINGW32__)
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
|
||||
#define CATCH_TRAP() DebugBreak()
|
||||
#endif
|
||||
|
||||
#ifndef CATCH_BREAK_INTO_DEBUGGER
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
|
||||
#ifdef CATCH_TRAP
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
|
||||
#endif
|
||||
|
||||
// #included from: catch_interfaces_runner.h
|
||||
@@ -2080,7 +2101,7 @@ namespace Catch {
|
||||
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
|
||||
} \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
} while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
|
||||
@@ -6981,6 +7002,11 @@ namespace Catch {
|
||||
Context( Context const& );
|
||||
void operator=( Context const& );
|
||||
|
||||
public:
|
||||
virtual ~Context() {
|
||||
deleteAllValues( m_generatorsByTestName );
|
||||
}
|
||||
|
||||
public: // IContext
|
||||
virtual IResultCapture* getResultCapture() {
|
||||
return m_resultCapture;
|
||||
@@ -7094,8 +7120,15 @@ namespace Catch {
|
||||
|
||||
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
// #included from: catch_windows_h_proxy.h
|
||||
|
||||
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
@@ -7104,6 +7137,13 @@ namespace Catch {
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINES_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
namespace {
|
||||
|
||||
@@ -7619,7 +7659,7 @@ namespace Catch {
|
||||
return os;
|
||||
}
|
||||
|
||||
Version libraryVersion( 1, 6, 0, "", 0 );
|
||||
Version libraryVersion( 1, 6, 1, "", 0 );
|
||||
|
||||
}
|
||||
|
||||
@@ -7790,7 +7830,6 @@ namespace Catch
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
@@ -8030,6 +8069,33 @@ namespace Catch {
|
||||
}
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(CATCH_PLATFORM_LINUX)
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace Catch{
|
||||
// The standard POSIX way of detecting a debugger is to attempt to
|
||||
// ptrace() the process, but this needs to be done from a child and not
|
||||
// this process itself to still allow attaching to this process later
|
||||
// if wanted, so is rather heavy. Under Linux we have the PID of the
|
||||
// "debugger" (which doesn't need to be gdb, of course, it could also
|
||||
// be strace, for example) in /proc/$PID/status, so just get it from
|
||||
// there instead.
|
||||
bool isDebuggerActive(){
|
||||
std::ifstream in("/proc/self/status");
|
||||
for( std::string line; std::getline(in, line); ) {
|
||||
static const int PREFIX_LEN = 11;
|
||||
if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
|
||||
// We're traced if the PID is not 0 and no other PID starts
|
||||
// with 0 digit, so it's enough to check for just a single
|
||||
// character.
|
||||
return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace Catch
|
||||
#elif defined(_MSC_VER)
|
||||
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
|
||||
namespace Catch {
|
||||
@@ -9390,6 +9456,35 @@ namespace Catch {
|
||||
|
||||
namespace Catch {
|
||||
|
||||
namespace {
|
||||
std::string getCurrentTimestamp() {
|
||||
// Beware, this is not reentrant because of backward compatibility issues
|
||||
// Also, UTC only, again because of backward compatibility (%z is C++11)
|
||||
time_t rawtime;
|
||||
std::time(&rawtime);
|
||||
const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
std::tm timeInfo = {};
|
||||
gmtime_s(&timeInfo, &rawtime);
|
||||
#else
|
||||
std::tm* timeInfo;
|
||||
timeInfo = std::gmtime(&rawtime);
|
||||
#endif
|
||||
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
#endif
|
||||
return std::string(timeStamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JunitReporter : public CumulativeReporterBase {
|
||||
public:
|
||||
JunitReporter( ReporterConfig const& _config )
|
||||
@@ -9454,7 +9549,7 @@ namespace Catch {
|
||||
xml.writeAttribute( "time", "" );
|
||||
else
|
||||
xml.writeAttribute( "time", suiteTime );
|
||||
xml.writeAttribute( "timestamp", "tbd" ); // !TBD
|
||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||
|
||||
// Write test cases
|
||||
for( TestGroupNode::ChildNodes::const_iterator
|
||||
@@ -10442,7 +10537,7 @@ int main (int argc, char * const argv[]) {
|
||||
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
|
||||
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
|
||||
|
||||
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
|
||||
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
|
Reference in New Issue
Block a user