mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 03:43:28 +01:00
Add stringification for std::chrono::{duration,time_point}
Also hides std::chrono, std::pair and std::chrono::* behind new configuration macros, CATCH_CONFIG_ENABLE_*_STRINGMAKER to avoid dragging in <utility>, <tuple> and <chrono> in common path, unless requested.
This commit is contained in:
parent
f972732737
commit
79b405fd3f
@ -68,6 +68,7 @@ set(TEST_SOURCES
|
||||
${SELF_TEST_DIR}/PartTrackerTests.cpp
|
||||
${SELF_TEST_DIR}/TagAliasTests.cpp
|
||||
${SELF_TEST_DIR}/TestMain.cpp
|
||||
${SELF_TEST_DIR}/ToStringChrono.cpp
|
||||
${SELF_TEST_DIR}/ToStringGeneralTests.cpp
|
||||
${SELF_TEST_DIR}/ToStringPair.cpp
|
||||
${SELF_TEST_DIR}/ToStringTuple.cpp
|
||||
|
@ -1,14 +1,15 @@
|
||||
<a id="top"></a>
|
||||
# Compile-time configuration
|
||||
|
||||
**Contents**
|
||||
[main()/ implementation](#main-implementation)
|
||||
[Prefixing Catch macros](#prefixing-catch-macros)
|
||||
[Terminal colour](#terminal-colour)
|
||||
[Console width](#console-width)
|
||||
[stdout](#stdout)
|
||||
[Other toggles](#other-toggles)
|
||||
[Windows header clutter](#windows-header-clutter)
|
||||
**Contents**
|
||||
[main()/ implementation](#main-implementation)
|
||||
[Prefixing Catch macros](#prefixing-catch-macros)
|
||||
[Terminal colour](#terminal-colour)
|
||||
[Console width](#console-width)
|
||||
[stdout](#stdout)
|
||||
[Other toggles](#other-toggles)
|
||||
[Windows header clutter](#windows-header-clutter)
|
||||
[Enabling stringification](#enabling-stringification)
|
||||
|
||||
Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
|
||||
|
||||
@ -121,6 +122,17 @@ On Windows Catch includes `windows.h`. To minimize global namespace clutter in t
|
||||
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
|
||||
|
||||
|
||||
## Enabling stringification
|
||||
|
||||
By default, Catch does not stringify some types from the standard library. This is done to avoid dragging in various standard library headers by default. However, Catch does contain these and can be configured to provide them, using these macros:
|
||||
|
||||
CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER // Provide StringMaker specialization for std::pair
|
||||
CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER // Provide StringMaker specialization for std::tuple
|
||||
CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER // Provide StringMaker specialization for std::chrono::duration, std::chrono::timepoint
|
||||
CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS // Defines all of the above
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@ -22,7 +22,9 @@
|
||||
* Removed support for non-const comparison operators
|
||||
* Non-const comparison operators are an abomination that should not exist
|
||||
* They were breaking support for comparing function to function pointer
|
||||
|
||||
* `std::pair` and `std::tuple` are no longer stringified by default
|
||||
* This is done to avoid dragging in `<tuple>` and `<utility>` headers in common path
|
||||
* Their stringification can be enabled per-file via new configuration macros
|
||||
|
||||
## Improvements
|
||||
* Reporters and Listeners can be defined in files different from the main file
|
||||
@ -53,7 +55,8 @@
|
||||
* Reporters/Listeners are now notified of fatal errors
|
||||
* This means specific signals or structured exceptions
|
||||
* The Reporter/Listener interface provides default, empty, implementation to preserve backward compatibility
|
||||
|
||||
* Stringification of `std::chrono::duration` and `std::chrono::time_point` is now supported
|
||||
* Needs to be enabled by a per-file compile time configuration option
|
||||
|
||||
## Fixes
|
||||
* Don't use console colour if running in XCode
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
|
||||
@ -57,7 +56,7 @@ namespace Catch {
|
||||
public:
|
||||
static const bool value = decltype(test<std::ostream, const T&>(0))::value;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
// If we decide for C++14, change these to enable_if_ts
|
||||
@ -241,7 +240,53 @@ namespace Catch {
|
||||
}
|
||||
};
|
||||
|
||||
// === Pair ===
|
||||
template<typename T>
|
||||
struct EnumStringMaker {
|
||||
static std::string convert(const T& t) {
|
||||
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<T>::type>(t));
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __OBJC__
|
||||
template<>
|
||||
struct StringMaker<NSString*> {
|
||||
static std::string convert(NSString * nsstring) {
|
||||
if (!nsstring)
|
||||
return "nil";
|
||||
return std::string("@") + [nsstring UTF8String];
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<NSObject*> {
|
||||
static std::string convert(NSObject* nsObject) {
|
||||
return ::Catch::Detail::stringify([nsObject description]);
|
||||
}
|
||||
|
||||
};
|
||||
namespace Detail {
|
||||
inline std::string stringify( NSString* nsstring ) {
|
||||
return StringMaker<NSString*>::convert( nsstring );
|
||||
}
|
||||
|
||||
} // namespace Detail
|
||||
#endif // __OBJC__
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Separate std-lib types stringification, so it can be selectively enabled
|
||||
// This means that we do not bring in
|
||||
|
||||
#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
|
||||
# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
|
||||
# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
|
||||
# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
|
||||
#endif
|
||||
|
||||
// Separate std::pair specialization
|
||||
#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
|
||||
#include <utility>
|
||||
namespace Catch {
|
||||
template<typename T1, typename T2>
|
||||
struct StringMaker<std::pair<T1, T2> > {
|
||||
static std::string convert(const std::pair<T1, T2>& pair) {
|
||||
@ -254,9 +299,13 @@ namespace Catch {
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
|
||||
|
||||
|
||||
|
||||
// Separate std::tuple specialization
|
||||
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
|
||||
#include <tuple>
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
template<
|
||||
typename Tuple,
|
||||
@ -292,40 +341,126 @@ namespace Catch {
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct EnumStringMaker {
|
||||
static std::string convert(const T& t) {
|
||||
return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<T>::type>(t));
|
||||
// Separate std::chrono::duration specialization
|
||||
#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
|
||||
#include <chrono>
|
||||
|
||||
#include <ratio>
|
||||
|
||||
template <class Ratio>
|
||||
struct ratio_string {
|
||||
static std::string symbol();
|
||||
};
|
||||
|
||||
template <class Ratio>
|
||||
std::string ratio_string<Ratio>::symbol() {
|
||||
std::ostringstream oss;
|
||||
oss << '[' << Ratio::num << '/'
|
||||
<< Ratio::den << ']';
|
||||
return oss.str();
|
||||
}
|
||||
template <>
|
||||
struct ratio_string<std::atto> {
|
||||
static std::string symbol() { return "a"; }
|
||||
};
|
||||
template <>
|
||||
struct ratio_string<std::femto> {
|
||||
static std::string symbol() { return "f"; }
|
||||
};
|
||||
template <>
|
||||
struct ratio_string<std::pico> {
|
||||
static std::string symbol() { return "p"; }
|
||||
};
|
||||
template <>
|
||||
struct ratio_string<std::nano> {
|
||||
static std::string symbol() { return "n"; }
|
||||
};
|
||||
template <>
|
||||
struct ratio_string<std::micro> {
|
||||
static std::string symbol() { return "u"; }
|
||||
};
|
||||
template <>
|
||||
struct ratio_string<std::milli> {
|
||||
static std::string symbol() { return "m"; }
|
||||
};
|
||||
|
||||
namespace Catch {
|
||||
////////////
|
||||
// std::chrono::duration specializations
|
||||
template<typename Value, typename Ratio>
|
||||
struct StringMaker<std::chrono::duration<Value, Ratio>> {
|
||||
static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " s";
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " m";
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
template<typename Value>
|
||||
struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
|
||||
static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
|
||||
std::ostringstream oss;
|
||||
oss << duration.count() << " h";
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __OBJC__
|
||||
template<>
|
||||
struct StringMaker<NSString*> {
|
||||
static std::string convert(NSString * nsstring) {
|
||||
if (!nsstring)
|
||||
return "nil";
|
||||
return std::string("@") + [nsstring UTF8String];
|
||||
////////////
|
||||
// std::chrono::time_point specialization
|
||||
// Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
|
||||
template<typename Clock, typename Duration>
|
||||
struct StringMaker<std::chrono::time_point<Clock, Duration>> {
|
||||
static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
|
||||
return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<NSObject*> {
|
||||
static std::string convert(NSObject* nsObject) {
|
||||
return ::Catch::Detail::stringify([nsObject description]);
|
||||
}
|
||||
// std::chrono::time_point<system_clock> specialization
|
||||
template<typename Duration>
|
||||
struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
|
||||
static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
|
||||
auto converted = std::chrono::system_clock::to_time_t(time_point);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::tm timeInfo = {};
|
||||
gmtime_s(&timeInfo, &converted);
|
||||
#else
|
||||
std::tm* timeInfo = std::gmtime(&converted);
|
||||
#endif
|
||||
|
||||
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
|
||||
char timeStamp[timeStampSize];
|
||||
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
#ifdef _MSC_VER
|
||||
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
#endif
|
||||
return std::string(timeStamp);
|
||||
}
|
||||
};
|
||||
namespace Detail {
|
||||
inline std::string stringify( NSString* nsstring ) {
|
||||
return StringMaker<NSString*>::convert( nsstring );
|
||||
}
|
||||
}
|
||||
#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
|
||||
|
||||
} // namespace Detail
|
||||
#endif // __OBJC__
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
@ -1003,6 +1003,6 @@ with expansion:
|
||||
"{?}" == "1"
|
||||
|
||||
===============================================================================
|
||||
test cases: 176 | 125 passed | 47 failed | 4 failed as expected
|
||||
assertions: 878 | 761 passed | 96 failed | 21 failed as expected
|
||||
test cases: 180 | 129 passed | 47 failed | 4 failed as expected
|
||||
assertions: 886 | 769 passed | 96 failed | 21 failed as expected
|
||||
|
||||
|
@ -4613,6 +4613,84 @@ PASSED:
|
||||
with expansion:
|
||||
11 == 11
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Stringifying std::chrono::duration helpers
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringChrono.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( minute == seconds )
|
||||
with expansion:
|
||||
1 m == 60 s
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( hour != seconds )
|
||||
with expansion:
|
||||
1 h != 60 s
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( micro != milli )
|
||||
with expansion:
|
||||
1 us != 1 ms
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( nano != micro )
|
||||
with expansion:
|
||||
1 ns != 1 us
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Stringifying std::chrono::duration with weird ratios
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringChrono.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( half_minute != femto_second )
|
||||
with expansion:
|
||||
1 [30/1]s != 1 fs
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Stringifying std::chrono::time_point<Clock>
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringChrono.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( now != later )
|
||||
with expansion:
|
||||
{iso8601-timestamp}
|
||||
!=
|
||||
{iso8601-timestamp}
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( now2 != later2 )
|
||||
with expansion:
|
||||
{since-epoch-report}
|
||||
!=
|
||||
{since-epoch-report}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Stringifying std::chrono::time_point<system_clock>
|
||||
-------------------------------------------------------------------------------
|
||||
ToStringChrono.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringChrono.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE( now != later )
|
||||
with expansion:
|
||||
{iso8601-timestamp}
|
||||
!=
|
||||
{iso8601-timestamp}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Tabs and newlines show in output
|
||||
-------------------------------------------------------------------------------
|
||||
@ -7434,6 +7512,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 176 | 123 passed | 49 failed | 4 failed as expected
|
||||
assertions: 877 | 757 passed | 99 failed | 21 failed as expected
|
||||
test cases: 180 | 127 passed | 49 failed | 4 failed as expected
|
||||
assertions: 885 | 765 passed | 99 failed | 21 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="878" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="886" 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="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
|
||||
@ -519,6 +519,10 @@ StringRef.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/implicitly constructed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/explicitly constructed" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="StringRef/to std::string/assigned" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration helpers" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::duration with weird ratios" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point<Clock>" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Stringifying std::chrono::time_point<system_clock>" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="Tabs and newlines show in output" time="{duration}">
|
||||
<failure message=""if ($b == 10) {
|
||||
$a = 20;
|
||||
|
@ -5250,6 +5250,88 @@ Message from section two
|
||||
</Section>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="Stringifying std::chrono::duration helpers" tags="[chrono][toString]" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
minute == seconds
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 m == 60 s
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
hour != seconds
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 h != 60 s
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
micro != milli
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 us != 1 ms
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
nano != micro
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 ns != 1 us
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Stringifying std::chrono::duration with weird ratios" tags="[chrono][toString]" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
half_minute != femto_second
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 [30/1]s != 1 fs
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Stringifying std::chrono::time_point<Clock>" tags="[chrono][toString]" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
now != later
|
||||
</Original>
|
||||
<Expanded>
|
||||
{iso8601-timestamp}
|
||||
!=
|
||||
{iso8601-timestamp}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
now2 != later2
|
||||
</Original>
|
||||
<Expanded>
|
||||
{since-epoch-report}
|
||||
!=
|
||||
{since-epoch-report}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Stringifying std::chrono::time_point<system_clock>" tags="[chrono][toString]" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/ToStringChrono.cpp" >
|
||||
<Original>
|
||||
now != later
|
||||
</Original>
|
||||
<Expanded>
|
||||
{iso8601-timestamp}
|
||||
!=
|
||||
{iso8601-timestamp}
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="Tabs and newlines show in output" tags="[.][failing][whitespace]" filename="projects/<exe-name>/MiscTests.cpp" >
|
||||
<Expression success="false" type="CHECK" filename="projects/<exe-name>/MiscTests.cpp" >
|
||||
<Original>
|
||||
@ -8209,7 +8291,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="757" failures="100" expectedFailures="21"/>
|
||||
<OverallResults successes="765" failures="100" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="757" failures="99" expectedFailures="21"/>
|
||||
<OverallResults successes="765" failures="99" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
41
projects/SelfTest/ToStringChrono.cpp
Normal file
41
projects/SelfTest/ToStringChrono.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
TEST_CASE("Stringifying std::chrono::duration helpers", "[toString][chrono]") {
|
||||
// No literals because we still support c++11
|
||||
auto hour = std::chrono::hours(1);
|
||||
auto minute = std::chrono::minutes(1);
|
||||
auto seconds = std::chrono::seconds(60);
|
||||
auto micro = std::chrono::microseconds(1);
|
||||
auto milli = std::chrono::milliseconds(1);
|
||||
auto nano = std::chrono::nanoseconds(1);
|
||||
REQUIRE(minute == seconds);
|
||||
REQUIRE(hour != seconds);
|
||||
REQUIRE(micro != milli);
|
||||
REQUIRE(nano != micro);
|
||||
}
|
||||
|
||||
TEST_CASE("Stringifying std::chrono::duration with weird ratios", "[toString][chrono]") {
|
||||
std::chrono::duration<int64_t, std::ratio<30>> half_minute(1);
|
||||
std::chrono::duration<int64_t, std::ratio<1, 1000000000000000>> femto_second(1);
|
||||
REQUIRE(half_minute != femto_second);
|
||||
}
|
||||
|
||||
TEST_CASE("Stringifying std::chrono::time_point<system_clock>", "[toString][chrono]") {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto later = now + std::chrono::minutes(2);
|
||||
REQUIRE(now != later);
|
||||
}
|
||||
|
||||
TEST_CASE("Stringifying std::chrono::time_point<Clock>", "[toString][chrono]") {
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
auto later = now + std::chrono::minutes(2);
|
||||
REQUIRE(now != later);
|
||||
|
||||
auto now2 = std::chrono::steady_clock::now();
|
||||
auto later2 = now2 + std::chrono::minutes(2);
|
||||
REQUIRE(now2 != later2);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE( "std::pair<int,std::string> -> toString", "[toString][pair]" ) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <tuple>
|
||||
|
@ -24,7 +24,7 @@ filelocParser = re.compile(r'''
|
||||
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"')
|
||||
timestampsParser = re.compile(r'\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'''
|
||||
@ -44,6 +44,7 @@ errnoParser = re.compile(r'''
|
||||
|
|
||||
\(\*_errno\(\)\)
|
||||
''', re.VERBOSE)
|
||||
sinceEpochParser = re.compile(r'\d+ .+ since epoch')
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
cmdPath = sys.argv[1]
|
||||
@ -97,9 +98,10 @@ def filterLine(line):
|
||||
|
||||
# strip durations and timestamps
|
||||
line = durationsParser.sub(' time="{duration}"', line)
|
||||
line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line)
|
||||
line = timestampsParser.sub('{iso8601-timestamp}', line)
|
||||
line = specialCaseParser.sub('file:\g<1>', line)
|
||||
line = errnoParser.sub('errno', line)
|
||||
line = sinceEpochParser.sub('{since-epoch-report}', line)
|
||||
return line
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user