mirror of
https://github.com/catchorg/Catch2.git
synced 2025-04-29 04:03:51 +00:00
Compare commits
17 Commits
0b2874b6b1
...
b2a6523d85
Author | SHA1 | Date | |
---|---|---|---|
|
b2a6523d85 | ||
|
b009d190bf | ||
|
ac83087bc2 | ||
|
123b449f8d | ||
|
6ad743a62b | ||
|
0f47fe16bd | ||
|
82baef62e2 | ||
|
0fbf4f3e15 | ||
|
ad3f50bbc1 | ||
|
13e01d273a | ||
|
2788897051 | ||
|
2945b80f61 | ||
|
63b7d6f98e | ||
|
c50ba09cde | ||
|
c165bd15c5 | ||
|
4f0de7bbad | ||
|
21b24e8326 |
@ -164,7 +164,7 @@ Note that it is not possible to simply use the same instance for different runs
|
|||||||
and resetting it between each run since that would pollute the measurements with
|
and resetting it between each run since that would pollute the measurements with
|
||||||
the resetting code.
|
the resetting code.
|
||||||
|
|
||||||
It is also possible to just provide an argument name to the simple `BENCHMARK` macro to get
|
It is also possible to just provide an argument name to the simple `BENCHMARK` macro to get
|
||||||
the same semantics as providing a callable to `meter.measure` with `int` argument:
|
the same semantics as providing a callable to `meter.measure` with `int` argument:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@ -185,19 +185,17 @@ construct and destroy objects without dynamic allocation and in a way that lets
|
|||||||
you measure construction and destruction separately.
|
you measure construction and destruction separately.
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
BENCHMARK_ADVANCED("construct")(Catch::Benchmark::Chronometer meter)
|
BENCHMARK_ADVANCED("construct")(Catch::Benchmark::Chronometer meter) {
|
||||||
{
|
|
||||||
std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
|
std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
|
||||||
meter.measure([&](int i) { storage[i].construct("thing"); });
|
meter.measure([&](int i) { storage[i].construct("thing"); });
|
||||||
})
|
};
|
||||||
|
|
||||||
BENCHMARK_ADVANCED("destroy", [](Catch::Benchmark::Chronometer meter)
|
BENCHMARK_ADVANCED("destroy")(Catch::Benchmark::Chronometer meter) {
|
||||||
{
|
|
||||||
std::vector<Catch::Benchmark::destructable_object<std::string>> storage(meter.runs());
|
std::vector<Catch::Benchmark::destructable_object<std::string>> storage(meter.runs());
|
||||||
for(auto&& o : storage)
|
for(auto&& o : storage)
|
||||||
o.construct("thing");
|
o.construct("thing");
|
||||||
meter.measure([&](int i) { storage[i].destruct(); });
|
meter.measure([&](int i) { storage[i].destruct(); });
|
||||||
})
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
`Catch::Benchmark::storage_for<T>` objects are just pieces of raw storage suitable for `T`
|
`Catch::Benchmark::storage_for<T>` objects are just pieces of raw storage suitable for `T`
|
||||||
|
@ -78,7 +78,7 @@ type, making their usage much nicer. These are
|
|||||||
|
|
||||||
> `from_range` has been introduced in Catch 2.10.0
|
> `from_range` has been introduced in Catch 2.10.0
|
||||||
|
|
||||||
> `range()` for floating point numbers has been introduced in Catch X.Y.Z
|
> `range()` for floating point numbers has been introduced in Catch 2.11.0
|
||||||
|
|
||||||
And can be used as shown in the example below to create a generator
|
And can be used as shown in the example below to create a generator
|
||||||
that returns 100 odd random number:
|
that returns 100 odd random number:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
**Contents**<br>
|
**Contents**<br>
|
||||||
|
[2.11.0](#2110)<br>
|
||||||
[2.10.2](#2102)<br>
|
[2.10.2](#2102)<br>
|
||||||
[2.10.1](#2101)<br>
|
[2.10.1](#2101)<br>
|
||||||
[2.10.0](#2100)<br>
|
[2.10.0](#2100)<br>
|
||||||
@ -62,6 +63,23 @@
|
|||||||
* `CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER` no longer exists.
|
* `CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER` no longer exists.
|
||||||
* `StringMaker` specializations for <chrono> are always provided
|
* `StringMaker` specializations for <chrono> are always provided
|
||||||
|
|
||||||
|
## 2.11.0
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
* JUnit reporter output now contains more details in case of failure (#1347, #1719)
|
||||||
|
* Added SonarQube Test Data reporter (#1738)
|
||||||
|
* It is in a separate header, just like the TAP, Automake, and TeamCity reporters
|
||||||
|
* `range` generator now allows floating point numbers (#1776)
|
||||||
|
* Reworked part of internals to increase throughput
|
||||||
|
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* The single header version should contain full benchmarking support (#1800)
|
||||||
|
* `[.foo]` is now properly parsed as `[.][foo]` when used on the command line (#1798)
|
||||||
|
* Fixed compilation of benchmarking on platforms where `steady_clock::period` is not `std::nano` (#1794)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 2.10.2
|
## 2.10.2
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
@ -55,7 +55,6 @@ set(INTERNAL_HEADERS
|
|||||||
${SOURCES_DIR}/catch_enum_values_registry.h
|
${SOURCES_DIR}/catch_enum_values_registry.h
|
||||||
${SOURCES_DIR}/catch_errno_guard.h
|
${SOURCES_DIR}/catch_errno_guard.h
|
||||||
${SOURCES_DIR}/catch_exception_translator_registry.h
|
${SOURCES_DIR}/catch_exception_translator_registry.h
|
||||||
${SOURCES_DIR}/catch_external_interfaces.h
|
|
||||||
${SOURCES_DIR}/catch_fatal_condition.h
|
${SOURCES_DIR}/catch_fatal_condition.h
|
||||||
${SOURCES_DIR}/catch_generators.hpp
|
${SOURCES_DIR}/catch_generators.hpp
|
||||||
${SOURCES_DIR}/catch_generators_generic.hpp
|
${SOURCES_DIR}/catch_generators_generic.hpp
|
||||||
|
@ -79,7 +79,7 @@ namespace Catch {
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
|
auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
|
||||||
BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
|
BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
|
||||||
getResultCapture().benchmarkEnded(stats);
|
getResultCapture().benchmarkEnded(stats);
|
||||||
|
|
||||||
} CATCH_CATCH_ALL{
|
} CATCH_CATCH_ALL{
|
||||||
|
@ -14,60 +14,66 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace Detail {
|
namespace Benchmark {
|
||||||
template <typename T, bool Destruct>
|
namespace Detail {
|
||||||
struct ObjectStorage
|
template <typename T, bool Destruct>
|
||||||
{
|
struct ObjectStorage
|
||||||
using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
|
|
||||||
|
|
||||||
ObjectStorage() : data() {}
|
|
||||||
|
|
||||||
ObjectStorage(const ObjectStorage& other)
|
|
||||||
{
|
{
|
||||||
new(&data) T(other.stored_object());
|
using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStorage(ObjectStorage&& other)
|
ObjectStorage() : data() {}
|
||||||
{
|
|
||||||
new(&data) T(std::move(other.stored_object()));
|
|
||||||
}
|
|
||||||
|
|
||||||
~ObjectStorage() { destruct_on_exit<T>(); }
|
ObjectStorage(const ObjectStorage& other)
|
||||||
|
{
|
||||||
|
new(&data) T(other.stored_object());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
ObjectStorage(ObjectStorage&& other)
|
||||||
void construct(Args&&... args)
|
{
|
||||||
{
|
new(&data) T(std::move(other.stored_object()));
|
||||||
new (&data) T(std::forward<Args>(args)...);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <bool AllowManualDestruction = !Destruct>
|
~ObjectStorage() { destruct_on_exit<T>(); }
|
||||||
typename std::enable_if<AllowManualDestruction>::type destruct()
|
|
||||||
{
|
|
||||||
stored_object().~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
template <typename... Args>
|
||||||
// If this is a constructor benchmark, destruct the underlying object
|
void construct(Args&&... args)
|
||||||
template <typename U>
|
{
|
||||||
void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
|
new (&data) T(std::forward<Args>(args)...);
|
||||||
// Otherwise, don't
|
}
|
||||||
template <typename U>
|
|
||||||
void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
|
|
||||||
|
|
||||||
T& stored_object()
|
template <bool AllowManualDestruction = !Destruct>
|
||||||
{
|
typename std::enable_if<AllowManualDestruction>::type destruct()
|
||||||
return *static_cast<T*>(static_cast<void*>(&data));
|
{
|
||||||
}
|
stored_object().~T();
|
||||||
|
}
|
||||||
|
|
||||||
TStorage data;
|
private:
|
||||||
};
|
// If this is a constructor benchmark, destruct the underlying object
|
||||||
}
|
template <typename U>
|
||||||
|
void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
|
||||||
|
// Otherwise, don't
|
||||||
|
template <typename U>
|
||||||
|
void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
|
||||||
|
|
||||||
template <typename T>
|
T& stored_object() {
|
||||||
using storage_for = Detail::ObjectStorage<T, true>;
|
return *static_cast<T*>(static_cast<void*>(&data));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
T const& stored_object() const {
|
||||||
using destructable_object = Detail::ObjectStorage<T, false>;
|
return *static_cast<T*>(static_cast<void*>(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TStorage data;
|
||||||
|
};
|
||||||
|
} // namespace Detail
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using storage_for = Detail::ObjectStorage<T, true>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using destructable_object = Detail::ObjectStorage<T, false>;
|
||||||
|
} // namespace Benchmark
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
|
||||||
|
@ -40,8 +40,6 @@
|
|||||||
#include <catch2/catch_objc.hpp>
|
#include <catch2/catch_objc.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <catch2/catch_external_interfaces.h>
|
|
||||||
|
|
||||||
#endif // ! CATCH_CONFIG_IMPL_ONLY
|
#endif // ! CATCH_CONFIG_IMPL_ONLY
|
||||||
|
|
||||||
#if !defined(CATCH_CONFIG_IMPL_ONLY)
|
#if !defined(CATCH_CONFIG_IMPL_ONLY)
|
||||||
|
@ -149,9 +149,12 @@
|
|||||||
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
||||||
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
||||||
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
|
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
|
||||||
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
|
# if !defined(__clang__) // Handle Clang masquerading for msvc
|
||||||
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
|
||||||
# endif
|
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||||
|
# endif // MSVC_TRADITIONAL
|
||||||
|
# endif // __clang__
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if defined(_REENTRANT) || defined(_MSC_VER)
|
#if defined(_REENTRANT) || defined(_MSC_VER)
|
||||||
|
@ -167,7 +167,7 @@ namespace {
|
|||||||
|
|
||||||
bool useColourOnPlatform() {
|
bool useColourOnPlatform() {
|
||||||
return
|
return
|
||||||
#ifdef CATCH_PLATFORM_MAC
|
#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
|
||||||
!isDebuggerActive() &&
|
!isDebuggerActive() &&
|
||||||
#endif
|
#endif
|
||||||
#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
|
#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <catch2/catch_stream.h>
|
#include <catch2/catch_stream.h>
|
||||||
#include <catch2/catch_platform.h>
|
#include <catch2/catch_platform.h>
|
||||||
|
|
||||||
#ifdef CATCH_PLATFORM_MAC
|
#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
|
||||||
|
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
# include <stdbool.h>
|
# include <stdbool.h>
|
||||||
|
@ -19,6 +19,17 @@ namespace Catch {
|
|||||||
|
|
||||||
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
|
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
|
||||||
|
|
||||||
|
#elif defined(CATCH_PLATFORM_IPHONE)
|
||||||
|
|
||||||
|
// use inline assembler
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
#define CATCH_TRAP() __asm__("int $3")
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined(CATCH_PLATFORM_LINUX)
|
#elif defined(CATCH_PLATFORM_LINUX)
|
||||||
// If we can use inline assembler, do it because this allows us to break
|
// 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
|
// directly at the location of the failing check instead of breaking inside
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Created by Martin on 17/08/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_EXTERNAL_INTERFACES_H_INCLUDED
|
|
||||||
#define TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED
|
|
||||||
|
|
||||||
#include <catch2/reporters/catch_reporter_bases.hpp>
|
|
||||||
#include <catch2/catch_console_colour.h>
|
|
||||||
#include <catch2/catch_reporter_registrars.hpp>
|
|
||||||
|
|
||||||
// Allow users to base their work off existing reporters
|
|
||||||
#include <catch2/reporters/catch_reporter_compact.h>
|
|
||||||
#include <catch2/reporters/catch_reporter_console.h>
|
|
||||||
#include <catch2/reporters/catch_reporter_junit.h>
|
|
||||||
#include <catch2/reporters/catch_reporter_xml.h>
|
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED
|
|
@ -49,7 +49,6 @@ namespace Generators {
|
|||||||
class SingleValueGenerator final : public IGenerator<T> {
|
class SingleValueGenerator final : public IGenerator<T> {
|
||||||
T m_value;
|
T m_value;
|
||||||
public:
|
public:
|
||||||
SingleValueGenerator(T const& value) : m_value( value ) {}
|
|
||||||
SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
|
SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
|
||||||
|
|
||||||
T const& get() const override {
|
T const& get() const override {
|
||||||
@ -112,21 +111,21 @@ namespace Generators {
|
|||||||
m_generators.emplace_back(std::move(generator));
|
m_generators.emplace_back(std::move(generator));
|
||||||
}
|
}
|
||||||
void populate(T&& val) {
|
void populate(T&& val) {
|
||||||
m_generators.emplace_back(value(std::move(val)));
|
m_generators.emplace_back(value(std::forward<T>(val)));
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
void populate(U&& val) {
|
void populate(U&& val) {
|
||||||
populate(T(std::move(val)));
|
populate(T(std::forward<U>(val)));
|
||||||
}
|
}
|
||||||
template<typename U, typename... Gs>
|
template<typename U, typename... Gs>
|
||||||
void populate(U&& valueOrGenerator, Gs... moreGenerators) {
|
void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
|
||||||
populate(std::forward<U>(valueOrGenerator));
|
populate(std::forward<U>(valueOrGenerator));
|
||||||
populate(std::forward<Gs>(moreGenerators)...);
|
populate(std::forward<Gs>(moreGenerators)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename... Gs>
|
template <typename... Gs>
|
||||||
Generators(Gs... moreGenerators) {
|
Generators(Gs &&... moreGenerators) {
|
||||||
m_generators.reserve(sizeof...(Gs));
|
m_generators.reserve(sizeof...(Gs));
|
||||||
populate(std::forward<Gs>(moreGenerators)...);
|
populate(std::forward<Gs>(moreGenerators)...);
|
||||||
}
|
}
|
||||||
@ -158,7 +157,7 @@ namespace Generators {
|
|||||||
struct as {};
|
struct as {};
|
||||||
|
|
||||||
template<typename T, typename... Gs>
|
template<typename T, typename... Gs>
|
||||||
auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
|
auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
|
||||||
return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
|
return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -166,11 +165,11 @@ namespace Generators {
|
|||||||
return Generators<T>(std::move(generator));
|
return Generators<T>(std::move(generator));
|
||||||
}
|
}
|
||||||
template<typename T, typename... Gs>
|
template<typename T, typename... Gs>
|
||||||
auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
|
auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
|
||||||
return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
|
return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
|
||||||
}
|
}
|
||||||
template<typename T, typename U, typename... Gs>
|
template<typename T, typename U, typename... Gs>
|
||||||
auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
|
auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
|
||||||
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
|
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +195,10 @@ namespace Generators {
|
|||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
#define GENERATE( ... ) \
|
#define GENERATE( ... ) \
|
||||||
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
|
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||||
#define GENERATE_COPY( ... ) \
|
#define GENERATE_COPY( ... ) \
|
||||||
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
|
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||||
#define GENERATE_REF( ... ) \
|
#define GENERATE_REF( ... ) \
|
||||||
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
|
Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||||
|
|
||||||
|
#include "catch_common.h"
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@ -28,7 +30,7 @@ namespace Catch {
|
|||||||
|
|
||||||
auto makeStream( StringRef const &filename ) -> IStream const*;
|
auto makeStream( StringRef const &filename ) -> IStream const*;
|
||||||
|
|
||||||
class ReusableStringStream {
|
class ReusableStringStream : NonCopyable {
|
||||||
std::size_t m_index;
|
std::size_t m_index;
|
||||||
std::ostream* m_oss;
|
std::ostream* m_oss;
|
||||||
public:
|
public:
|
||||||
|
@ -22,17 +22,7 @@ namespace Catch {
|
|||||||
CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
|
CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
|
||||||
return m_start;
|
return m_start;
|
||||||
}
|
}
|
||||||
auto StringRef::data() const noexcept -> char const* {
|
|
||||||
return m_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
|
|
||||||
if (start < m_size) {
|
|
||||||
return StringRef(m_start + start, (std::min)(m_size - start, size));
|
|
||||||
} else {
|
|
||||||
return StringRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
|
auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
|
||||||
return m_size == other.m_size
|
return m_size == other.m_size
|
||||||
&& (std::memcmp( m_start, other.m_start, m_size ) == 0);
|
&& (std::memcmp( m_start, other.m_start, m_size ) == 0);
|
||||||
|
@ -74,12 +74,21 @@ namespace Catch {
|
|||||||
|
|
||||||
public: // substrings and searches
|
public: // substrings and searches
|
||||||
// Returns a substring of [start, start + length).
|
// Returns a substring of [start, start + length).
|
||||||
// If start + length > size(), then the substring is [start, size()).
|
// If start + length > size(), then the substring is [start, start + size()).
|
||||||
// If start > size(), then the substring is empty.
|
// If start > size(), then the substring is empty.
|
||||||
auto substr( size_type start, size_type length ) const noexcept -> StringRef;
|
constexpr StringRef substr(size_type start, size_type length) const noexcept {
|
||||||
|
if (start < m_size) {
|
||||||
|
const auto shortened_size = m_size - start;
|
||||||
|
return StringRef(m_start + start, (shortened_size < length) ? shortened_size : length);
|
||||||
|
} else {
|
||||||
|
return StringRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the current start pointer. May not be null-terminated.
|
// Returns the current start pointer. May not be null-terminated.
|
||||||
auto data() const noexcept -> char const*;
|
constexpr char const* data() const noexcept {
|
||||||
|
return m_start;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr auto isNullTerminated() const noexcept -> bool {
|
constexpr auto isNullTerminated() const noexcept -> bool {
|
||||||
return m_start[m_size] == '\0';
|
return m_start[m_size] == '\0';
|
||||||
|
@ -113,9 +113,9 @@ namespace Catch {
|
|||||||
switch( m_mode ) {
|
switch( m_mode ) {
|
||||||
case Name:
|
case Name:
|
||||||
case QuotedName:
|
case QuotedName:
|
||||||
return addPattern<TestSpec::NamePattern>();
|
return addNamePattern();
|
||||||
case Tag:
|
case Tag:
|
||||||
return addPattern<TestSpec::TagPattern>();
|
return addTagPattern();
|
||||||
case EscapedName:
|
case EscapedName:
|
||||||
revertBackToLastMode();
|
revertBackToLastMode();
|
||||||
return;
|
return;
|
||||||
@ -175,6 +175,63 @@ namespace Catch {
|
|||||||
return true; //success
|
return true; //success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string TestSpecParser::preprocessPattern() {
|
||||||
|
std::string token = m_patternName;
|
||||||
|
for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
|
||||||
|
token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
|
||||||
|
m_escapeChars.clear();
|
||||||
|
if (startsWith(token, "exclude:")) {
|
||||||
|
m_exclusion = true;
|
||||||
|
token = token.substr(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_patternName.clear();
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSpecParser::addNamePattern() {
|
||||||
|
auto token = preprocessPattern();
|
||||||
|
|
||||||
|
if (!token.empty()) {
|
||||||
|
if (m_exclusion) {
|
||||||
|
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::NamePattern>(token, m_substring));
|
||||||
|
} else {
|
||||||
|
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::NamePattern>(token, m_substring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_substring.clear();
|
||||||
|
m_exclusion = false;
|
||||||
|
m_mode = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSpecParser::addTagPattern() {
|
||||||
|
auto token = preprocessPattern();
|
||||||
|
|
||||||
|
if (!token.empty()) {
|
||||||
|
// If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
|
||||||
|
// we have to create a separate hide tag and shorten the real one
|
||||||
|
if (token.size() > 1 && token[0] == '.') {
|
||||||
|
token.erase(token.begin());
|
||||||
|
if (m_exclusion) {
|
||||||
|
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(".", m_substring));
|
||||||
|
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||||
|
} else {
|
||||||
|
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(".", m_substring));
|
||||||
|
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_exclusion) {
|
||||||
|
m_currentFilter.m_forbidden.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||||
|
} else {
|
||||||
|
m_currentFilter.m_required.emplace_back(std::make_unique<TestSpec::TagPattern>(token, m_substring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_substring.clear();
|
||||||
|
m_exclusion = false;
|
||||||
|
m_mode = None;
|
||||||
|
}
|
||||||
|
|
||||||
TestSpec parseTestSpec( std::string const& arg ) {
|
TestSpec parseTestSpec( std::string const& arg ) {
|
||||||
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
|
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
|
||||||
}
|
}
|
||||||
|
@ -54,28 +54,12 @@ namespace Catch {
|
|||||||
void addFilter();
|
void addFilter();
|
||||||
bool separate();
|
bool separate();
|
||||||
|
|
||||||
template<typename T>
|
// Handles common preprocessing of the pattern for name/tag patterns
|
||||||
void addPattern() {
|
std::string preprocessPattern();
|
||||||
std::string token = m_patternName;
|
// Adds the current pattern as a test name
|
||||||
for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
|
void addNamePattern();
|
||||||
token = token.substr( 0, m_escapeChars[i] - i ) + token.substr( m_escapeChars[i] -i +1 );
|
// Adds the current pattern as a tag
|
||||||
m_escapeChars.clear();
|
void addTagPattern();
|
||||||
if( startsWith( token, "exclude:" ) ) {
|
|
||||||
m_exclusion = true;
|
|
||||||
token = token.substr( 8 );
|
|
||||||
}
|
|
||||||
if( !token.empty() ) {
|
|
||||||
if (m_exclusion) {
|
|
||||||
m_currentFilter.m_forbidden.emplace_back(std::make_unique<T>(token, m_substring));
|
|
||||||
} else {
|
|
||||||
m_currentFilter.m_required.emplace_back(std::make_unique<T>(token, m_substring));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_substring.clear();
|
|
||||||
m_patternName.clear();
|
|
||||||
m_exclusion = false;
|
|
||||||
m_mode = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void addCharToPattern(char c) {
|
inline void addCharToPattern(char c) {
|
||||||
m_substring += c;
|
m_substring += c;
|
||||||
|
@ -28,14 +28,6 @@ TEST_CASE("Benchmark factorial", "[benchmark]") {
|
|||||||
BENCHMARK("factorial 14") {
|
BENCHMARK("factorial 14") {
|
||||||
return factorial(14);
|
return factorial(14);
|
||||||
};
|
};
|
||||||
//
|
|
||||||
// BENCHMARK("factorial 20") {
|
|
||||||
// return factorial(20);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// BENCHMARK("factorial 35") {
|
|
||||||
// return factorial(35);
|
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Benchmark containers", "[.][benchmark]") {
|
TEST_CASE("Benchmark containers", "[.][benchmark]") {
|
||||||
|
@ -1028,6 +1028,12 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( " aardvar
|
|||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( " aardvark " ) ) for: true
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( " aardvark " ) ) for: true
|
||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( "aardvark " ) ) for: true
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( "aardvark " ) ) for: true
|
||||||
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( "aardvark" ) ) for: true
|
CmdLine.tests.cpp:<line number>: passed: spec.matches( *fakeTestCase( "aardvark" ) ) for: true
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")) for: true
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: !(spec.matches(*fakeTestCase("only foo", "[foo]"))) for: !false
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: !(spec.matches(*fakeTestCase("hidden and foo", "[.][foo]"))) for: !false
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: !(spec.matches(*fakeTestCase("only foo", "[foo]"))) for: !false
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: !(spec.matches(*fakeTestCase("only hidden", "[.]"))) for: !false
|
||||||
|
CmdLine.tests.cpp:<line number>: passed: spec.matches(*fakeTestCase("neither foo nor hidden", "[bar]")) for: true
|
||||||
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
|
||||||
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
|
||||||
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
|
||||||
@ -1187,6 +1193,7 @@ String.tests.cpp:<line number>: passed: s.data() == s2.data() for: "hello world!
|
|||||||
String.tests.cpp:<line number>: passed: s.data() == ss.data() for: "hello world!" == "hello world!"
|
String.tests.cpp:<line number>: passed: s.data() == ss.data() for: "hello world!" == "hello world!"
|
||||||
String.tests.cpp:<line number>: passed: s.substr(s.size() + 1, 123).empty() for: true
|
String.tests.cpp:<line number>: passed: s.substr(s.size() + 1, 123).empty() for: true
|
||||||
String.tests.cpp:<line number>: passed: std::strcmp(ss.c_str(), "world!") == 0 for: 0 == 0
|
String.tests.cpp:<line number>: passed: std::strcmp(ss.c_str(), "world!") == 0 for: 0 == 0
|
||||||
|
String.tests.cpp:<line number>: passed: s.substr(1'000'000, 1).empty() for: true
|
||||||
String.tests.cpp:<line number>: passed: (char*)buffer1 != (char*)buffer2 for: "Hello" != "Hello"
|
String.tests.cpp:<line number>: passed: (char*)buffer1 != (char*)buffer2 for: "Hello" != "Hello"
|
||||||
String.tests.cpp:<line number>: passed: left == right for: Hello == Hello
|
String.tests.cpp:<line number>: passed: left == right for: Hello == Hello
|
||||||
String.tests.cpp:<line number>: passed: left != left.substr(0, 3) for: Hello != Hel
|
String.tests.cpp:<line number>: passed: left != left.substr(0, 3) for: Hello != Hel
|
||||||
@ -1200,11 +1207,20 @@ String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringre
|
|||||||
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
||||||
String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
|
String.tests.cpp:<line number>: passed: stdStr == "a stringref" for: "a stringref" == "a stringref"
|
||||||
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
String.tests.cpp:<line number>: passed: stdStr.size() == sr.size() for: 11 == 11
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{}.size() == 0'
|
String.tests.cpp:<line number>: passed: with 1 message: 'empty.size() == 0'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 3 }.size() == 3'
|
String.tests.cpp:<line number>: passed: with 1 message: 'empty.begin() == empty.end()'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 3 }.isNullTerminated()'
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.size() == 3'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'StringRef{ "abc", 2 }.size() == 2'
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.isNullTerminated()'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: '!(StringRef{ "abc", 2 }.isNullTerminated())'
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.data() == abc'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.begin() == abc'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.begin() != stringref.end()'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.substr(10, 0).empty()'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'stringref.substr(2, 1).data() == abc + 2'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'shortened.size() == 2'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'shortened.data() == abc'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: 'shortened.begin() != shortened.end()'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: '!(shortened.isNullTerminated())'
|
||||||
|
String.tests.cpp:<line number>: passed: with 1 message: '!(shortened.substr(1, 3).isNullTerminated())'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: '!(sr1.empty())'
|
String.tests.cpp:<line number>: passed: with 1 message: '!(sr1.empty())'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'sr1.size() == 3'
|
String.tests.cpp:<line number>: passed: with 1 message: 'sr1.size() == 3'
|
||||||
String.tests.cpp:<line number>: passed: with 1 message: 'sr1.isNullTerminated()'
|
String.tests.cpp:<line number>: passed: with 1 message: 'sr1.isNullTerminated()'
|
||||||
|
@ -1381,5 +1381,5 @@ due to unexpected exception with message:
|
|||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 320 | 246 passed | 70 failed | 4 failed as expected
|
test cases: 320 | 246 passed | 70 failed | 4 failed as expected
|
||||||
assertions: 1776 | 1624 passed | 131 failed | 21 failed as expected
|
assertions: 1792 | 1640 passed | 131 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -7370,6 +7370,50 @@ CmdLine.tests.cpp:<line number>: PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
true
|
true
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Parse test names and tags
|
||||||
|
Shortened hide tags are split apart when parsing
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
CmdLine.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK( spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")) )
|
||||||
|
with expansion:
|
||||||
|
true
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK_FALSE( spec.matches(*fakeTestCase("only foo", "[foo]")) )
|
||||||
|
with expansion:
|
||||||
|
!false
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Parse test names and tags
|
||||||
|
Shortened hide tags also properly handle exclusion
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
CmdLine.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK_FALSE( spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")) )
|
||||||
|
with expansion:
|
||||||
|
!false
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK_FALSE( spec.matches(*fakeTestCase("only foo", "[foo]")) )
|
||||||
|
with expansion:
|
||||||
|
!false
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK_FALSE( spec.matches(*fakeTestCase("only hidden", "[.]")) )
|
||||||
|
with expansion:
|
||||||
|
!false
|
||||||
|
|
||||||
|
CmdLine.tests.cpp:<line number>: PASSED:
|
||||||
|
CHECK( spec.matches(*fakeTestCase("neither foo nor hidden", "[bar]")) )
|
||||||
|
with expansion:
|
||||||
|
true
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Pointers can be compared to null
|
Pointers can be compared to null
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -8671,6 +8715,19 @@ String.tests.cpp:<line number>: PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
0 == 0
|
0 == 0
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
StringRef
|
||||||
|
Substrings
|
||||||
|
substring start after the end is empty
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
String.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
REQUIRE( s.substr(1'000'000, 1).empty() )
|
||||||
|
with expansion:
|
||||||
|
true
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
StringRef
|
StringRef
|
||||||
Comparisons are deep
|
Comparisons are deep
|
||||||
@ -8792,23 +8849,59 @@ String.tests.cpp:<line number>
|
|||||||
|
|
||||||
String.tests.cpp:<line number>: PASSED:
|
String.tests.cpp:<line number>: PASSED:
|
||||||
with message:
|
with message:
|
||||||
StringRef{}.size() == 0
|
empty.size() == 0
|
||||||
|
|
||||||
String.tests.cpp:<line number>: PASSED:
|
String.tests.cpp:<line number>: PASSED:
|
||||||
with message:
|
with message:
|
||||||
StringRef{ "abc", 3 }.size() == 3
|
empty.begin() == empty.end()
|
||||||
|
|
||||||
String.tests.cpp:<line number>: PASSED:
|
String.tests.cpp:<line number>: PASSED:
|
||||||
with message:
|
with message:
|
||||||
StringRef{ "abc", 3 }.isNullTerminated()
|
stringref.size() == 3
|
||||||
|
|
||||||
String.tests.cpp:<line number>: PASSED:
|
String.tests.cpp:<line number>: PASSED:
|
||||||
with message:
|
with message:
|
||||||
StringRef{ "abc", 2 }.size() == 2
|
stringref.isNullTerminated()
|
||||||
|
|
||||||
String.tests.cpp:<line number>: PASSED:
|
String.tests.cpp:<line number>: PASSED:
|
||||||
with message:
|
with message:
|
||||||
!(StringRef{ "abc", 2 }.isNullTerminated())
|
stringref.data() == abc
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
stringref.begin() == abc
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
stringref.begin() != stringref.end()
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
stringref.substr(10, 0).empty()
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
stringref.substr(2, 1).data() == abc + 2
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
shortened.size() == 2
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
shortened.data() == abc
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
shortened.begin() != shortened.end()
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
!(shortened.isNullTerminated())
|
||||||
|
|
||||||
|
String.tests.cpp:<line number>: PASSED:
|
||||||
|
with message:
|
||||||
|
!(shortened.substr(1, 3).isNullTerminated())
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
StringRef at compilation time
|
StringRef at compilation time
|
||||||
@ -13961,5 +14054,5 @@ Misc.tests.cpp:<line number>: PASSED:
|
|||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 320 | 230 passed | 86 failed | 4 failed as expected
|
test cases: 320 | 230 passed | 86 failed | 4 failed as expected
|
||||||
assertions: 1793 | 1624 passed | 148 failed | 21 failed as expected
|
assertions: 1809 | 1640 passed | 148 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<testsuitesloose text artifact
|
||||||
>
|
>
|
||||||
<testsuite name="<exe-name>" errors="17" failures="132" tests="1794" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="17" failures="132" tests="1810" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
|
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
@ -983,6 +983,8 @@ Message.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/quoted string followed by tag exclusion" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Parse test names and tags/quoted string followed by tag exclusion" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test spec" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test spec" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test name" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Parse test names and tags/Leading and trailing spaces in test name" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Parse test names and tags/Shortened hide tags are split apart when parsing" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Parse test names and tags/Shortened hide tags also properly handle exclusion" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Floats" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Floats" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Double" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Precision of floating point stringification can be set/Double" time="{duration}"/>
|
||||||
@ -1112,6 +1114,7 @@ Matchers.tests.cpp:<line number>
|
|||||||
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of substring refs should also match" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Pointer values of substring refs should also match" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Past the end substring" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Past the end substring" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Substring off the end are trimmed" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/Substrings/Substring off the end are trimmed" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="StringRef/Substrings/substring start after the end is empty" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/Comparisons are deep" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/Comparisons are deep" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/from std::string/implicitly constructed" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/from std::string/implicitly constructed" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="StringRef/from std::string/explicitly constructed" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="StringRef/from std::string/explicitly constructed" time="{duration}"/>
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
<testCase name="Parse test names and tags/quoted string followed by tag exclusion" duration="{duration}"/>
|
<testCase name="Parse test names and tags/quoted string followed by tag exclusion" duration="{duration}"/>
|
||||||
<testCase name="Parse test names and tags/Leading and trailing spaces in test spec" duration="{duration}"/>
|
<testCase name="Parse test names and tags/Leading and trailing spaces in test spec" duration="{duration}"/>
|
||||||
<testCase name="Parse test names and tags/Leading and trailing spaces in test name" duration="{duration}"/>
|
<testCase name="Parse test names and tags/Leading and trailing spaces in test name" duration="{duration}"/>
|
||||||
|
<testCase name="Parse test names and tags/Shortened hide tags are split apart when parsing" duration="{duration}"/>
|
||||||
|
<testCase name="Parse test names and tags/Shortened hide tags also properly handle exclusion" duration="{duration}"/>
|
||||||
<testCase name="Process can be configured on command line/empty args don't cause a crash" duration="{duration}"/>
|
<testCase name="Process can be configured on command line/empty args don't cause a crash" duration="{duration}"/>
|
||||||
<testCase name="Process can be configured on command line/default - no arguments" duration="{duration}"/>
|
<testCase name="Process can be configured on command line/default - no arguments" duration="{duration}"/>
|
||||||
<testCase name="Process can be configured on command line/test lists/Specify one test case using" duration="{duration}"/>
|
<testCase name="Process can be configured on command line/test lists/Specify one test case using" duration="{duration}"/>
|
||||||
@ -140,6 +142,7 @@
|
|||||||
<testCase name="StringRef/Substrings/Pointer values of substring refs should also match" duration="{duration}"/>
|
<testCase name="StringRef/Substrings/Pointer values of substring refs should also match" duration="{duration}"/>
|
||||||
<testCase name="StringRef/Substrings/Past the end substring" duration="{duration}"/>
|
<testCase name="StringRef/Substrings/Past the end substring" duration="{duration}"/>
|
||||||
<testCase name="StringRef/Substrings/Substring off the end are trimmed" duration="{duration}"/>
|
<testCase name="StringRef/Substrings/Substring off the end are trimmed" duration="{duration}"/>
|
||||||
|
<testCase name="StringRef/Substrings/substring start after the end is empty" duration="{duration}"/>
|
||||||
<testCase name="StringRef/Comparisons are deep" duration="{duration}"/>
|
<testCase name="StringRef/Comparisons are deep" duration="{duration}"/>
|
||||||
<testCase name="StringRef/from std::string/implicitly constructed" duration="{duration}"/>
|
<testCase name="StringRef/from std::string/implicitly constructed" duration="{duration}"/>
|
||||||
<testCase name="StringRef/from std::string/explicitly constructed" duration="{duration}"/>
|
<testCase name="StringRef/from std::string/explicitly constructed" duration="{duration}"/>
|
||||||
|
@ -37,7 +37,7 @@ ok {test-number} -
|
|||||||
# #1403
|
# #1403
|
||||||
ok {test-number} - h1 == h2 for: [1403 helper] == [1403 helper]
|
ok {test-number} - h1 == h2 for: [1403 helper] == [1403 helper]
|
||||||
# #1455 - INFO and WARN can start with a linebreak
|
# #1455 - INFO and WARN can start with a linebreak
|
||||||
warning 20 - '
|
warning {test-number} - '
|
||||||
This info message starts with a linebreak' with 1 message: '
|
This info message starts with a linebreak' with 1 message: '
|
||||||
This warning message starts with a linebreak'
|
This warning message starts with a linebreak'
|
||||||
This would not be caught previously
|
This would not be caught previously
|
||||||
@ -795,7 +795,7 @@ not ok {test-number} - explicitly
|
|||||||
# FAIL_CHECK does not abort the test
|
# FAIL_CHECK does not abort the test
|
||||||
not ok {test-number} - explicitly with 1 message: 'This is a failure'
|
not ok {test-number} - explicitly with 1 message: 'This is a failure'
|
||||||
# FAIL_CHECK does not abort the test
|
# FAIL_CHECK does not abort the test
|
||||||
warning 397 - 'This message appears in the output'
|
warning {test-number} - 'This message appears in the output'
|
||||||
# Factorials are computed
|
# Factorials are computed
|
||||||
ok {test-number} - Factorial(0) == 1 for: 1 == 1
|
ok {test-number} - Factorial(0) == 1 for: 1 == 1
|
||||||
# Factorials are computed
|
# Factorials are computed
|
||||||
@ -1443,7 +1443,7 @@ ok {test-number} - !(d >= Approx( 1.24 )) for: !(1.23 >= Approx( 1.24 ))
|
|||||||
# Greater-than inequalities with different epsilons
|
# Greater-than inequalities with different epsilons
|
||||||
ok {test-number} - d >= Approx( 1.24 ).epsilon(0.1) for: 1.23 >= Approx( 1.24 )
|
ok {test-number} - d >= Approx( 1.24 ).epsilon(0.1) for: 1.23 >= Approx( 1.24 )
|
||||||
# INFO and WARN do not abort tests
|
# INFO and WARN do not abort tests
|
||||||
warning 721 - 'this is a message' with 1 message: 'this is a warning'
|
warning {test-number} - 'this is a message' with 1 message: 'this is a warning'
|
||||||
# INFO gets logged on failure
|
# INFO gets logged on failure
|
||||||
not ok {test-number} - a == 1 for: 2 == 1 with 2 messages: 'this message should be logged' and 'so should this'
|
not ok {test-number} - a == 1 for: 2 == 1 with 2 messages: 'this message should be logged' and 'so should this'
|
||||||
# INFO gets logged on failure, even if captured before successful assertions
|
# INFO gets logged on failure, even if captured before successful assertions
|
||||||
@ -1569,7 +1569,7 @@ ok {test-number} - values > -6 for: 98 > -6
|
|||||||
# Nested generators and captured variables
|
# Nested generators and captured variables
|
||||||
ok {test-number} - values > -6 for: 99 > -6
|
ok {test-number} - values > -6 for: 99 > -6
|
||||||
# Nice descriptive name
|
# Nice descriptive name
|
||||||
warning 784 - 'This one ran'
|
warning {test-number} - 'This one ran'
|
||||||
# Non-std exceptions can be translated
|
# Non-std exceptions can be translated
|
||||||
not ok {test-number} - unexpected exception with message: 'custom exception'
|
not ok {test-number} - unexpected exception with message: 'custom exception'
|
||||||
# Objects that evaluated in boolean contexts can be checked
|
# Objects that evaluated in boolean contexts can be checked
|
||||||
@ -1978,6 +1978,18 @@ ok {test-number} - spec.matches( *fakeTestCase( " aardvark " ) ) for: true
|
|||||||
ok {test-number} - spec.matches( *fakeTestCase( "aardvark " ) ) for: true
|
ok {test-number} - spec.matches( *fakeTestCase( "aardvark " ) ) for: true
|
||||||
# Parse test names and tags
|
# Parse test names and tags
|
||||||
ok {test-number} - spec.matches( *fakeTestCase( "aardvark" ) ) for: true
|
ok {test-number} - spec.matches( *fakeTestCase( "aardvark" ) ) for: true
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")) for: true
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - !(spec.matches(*fakeTestCase("only foo", "[foo]"))) for: !false
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - !(spec.matches(*fakeTestCase("hidden and foo", "[.][foo]"))) for: !false
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - !(spec.matches(*fakeTestCase("only foo", "[foo]"))) for: !false
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - !(spec.matches(*fakeTestCase("only hidden", "[.]"))) for: !false
|
||||||
|
# Parse test names and tags
|
||||||
|
ok {test-number} - spec.matches(*fakeTestCase("neither foo nor hidden", "[bar]")) for: true
|
||||||
# Pointers can be compared to null
|
# Pointers can be compared to null
|
||||||
ok {test-number} - p == 0 for: 0 == 0
|
ok {test-number} - p == 0 for: 0 == 0
|
||||||
# Pointers can be compared to null
|
# Pointers can be compared to null
|
||||||
@ -2288,6 +2300,8 @@ ok {test-number} - s.substr(s.size() + 1, 123).empty() for: true
|
|||||||
# StringRef
|
# StringRef
|
||||||
ok {test-number} - std::strcmp(ss.c_str(), "world!") == 0 for: 0 == 0
|
ok {test-number} - std::strcmp(ss.c_str(), "world!") == 0 for: 0 == 0
|
||||||
# StringRef
|
# StringRef
|
||||||
|
ok {test-number} - s.substr(1'000'000, 1).empty() for: true
|
||||||
|
# StringRef
|
||||||
ok {test-number} - (char*)buffer1 != (char*)buffer2 for: "Hello" != "Hello"
|
ok {test-number} - (char*)buffer1 != (char*)buffer2 for: "Hello" != "Hello"
|
||||||
# StringRef
|
# StringRef
|
||||||
ok {test-number} - left == right for: Hello == Hello
|
ok {test-number} - left == right for: Hello == Hello
|
||||||
@ -2314,15 +2328,33 @@ ok {test-number} - stdStr == "a stringref" for: "a stringref" == "a stringref"
|
|||||||
# StringRef
|
# StringRef
|
||||||
ok {test-number} - stdStr.size() == sr.size() for: 11 == 11
|
ok {test-number} - stdStr.size() == sr.size() for: 11 == 11
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: 'StringRef{}.size() == 0'
|
ok {test-number} - with 1 message: 'empty.size() == 0'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: 'StringRef{ "abc", 3 }.size() == 3'
|
ok {test-number} - with 1 message: 'empty.begin() == empty.end()'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: 'StringRef{ "abc", 3 }.isNullTerminated()'
|
ok {test-number} - with 1 message: 'stringref.size() == 3'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: 'StringRef{ "abc", 2 }.size() == 2'
|
ok {test-number} - with 1 message: 'stringref.isNullTerminated()'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: '!(StringRef{ "abc", 2 }.isNullTerminated())'
|
ok {test-number} - with 1 message: 'stringref.data() == abc'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'stringref.begin() == abc'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'stringref.begin() != stringref.end()'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'stringref.substr(10, 0).empty()'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'stringref.substr(2, 1).data() == abc + 2'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'shortened.size() == 2'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'shortened.data() == abc'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: 'shortened.begin() != shortened.end()'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: '!(shortened.isNullTerminated())'
|
||||||
|
# StringRef at compilation time
|
||||||
|
ok {test-number} - with 1 message: '!(shortened.substr(1, 3).isNullTerminated())'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
ok {test-number} - with 1 message: '!(sr1.empty())'
|
ok {test-number} - with 1 message: '!(sr1.empty())'
|
||||||
# StringRef at compilation time
|
# StringRef at compilation time
|
||||||
@ -2928,9 +2960,9 @@ not ok {test-number} - unexpected exception with message: 'expected exception';
|
|||||||
# When unchecked exceptions are thrown from sections they are always failures
|
# When unchecked exceptions are thrown from sections they are always failures
|
||||||
not ok {test-number} - unexpected exception with message: 'unexpected exception'
|
not ok {test-number} - unexpected exception with message: 'unexpected exception'
|
||||||
# Where the LHS is not a simple value
|
# Where the LHS is not a simple value
|
||||||
warning 1461 - 'Uncomment the code in this test to check that it gives a sensible compiler error'
|
warning {test-number} - 'Uncomment the code in this test to check that it gives a sensible compiler error'
|
||||||
# Where there is more to the expression after the RHS
|
# Where there is more to the expression after the RHS
|
||||||
warning 1462 - 'Uncomment the code in this test to check that it gives a sensible compiler error'
|
warning {test-number} - 'Uncomment the code in this test to check that it gives a sensible compiler error'
|
||||||
# X/level/0/a
|
# X/level/0/a
|
||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# X/level/0/b
|
# X/level/0/b
|
||||||
@ -3197,9 +3229,9 @@ ok {test-number} - s.result == 17 for: 17 == 17
|
|||||||
# measure
|
# measure
|
||||||
ok {test-number} - s.iterations == 1 for: 1 == 1
|
ok {test-number} - s.iterations == 1 for: 1 == 1
|
||||||
# mix info, unscoped info and warning
|
# mix info, unscoped info and warning
|
||||||
warning 1595 - 'info' with 2 messages: 'unscoped info' and 'and warn may mix'
|
warning {test-number} - 'info' with 2 messages: 'unscoped info' and 'and warn may mix'
|
||||||
# mix info, unscoped info and warning
|
# mix info, unscoped info and warning
|
||||||
warning 1596 - 'info' with 2 messages: 'unscoped info' and 'they are not cleared after warnings'
|
warning {test-number} - 'info' with 2 messages: 'unscoped info' and 'they are not cleared after warnings'
|
||||||
# more nested SECTION tests
|
# more nested SECTION tests
|
||||||
not ok {test-number} - a == b for: 1 == 2
|
not ok {test-number} - a == b for: 1 == 2
|
||||||
# more nested SECTION tests
|
# more nested SECTION tests
|
||||||
@ -3578,5 +3610,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
|||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# xmlentitycheck
|
# xmlentitycheck
|
||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
1..1785
|
1..1801
|
||||||
|
|
||||||
|
@ -8025,7 +8025,7 @@ Nor would this
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="false"/>
|
<OverallResult success="false"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Parse test names and tags" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
<TestCase name="Parse test names and tags" tags="[command-line][test-spec]" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
<Section name="Empty test spec should have no filters" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
<Section name="Empty test spec should have no filters" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@ -9285,6 +9285,60 @@ Nor would this
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResults successes="5" failures="0" expectedFailures="0"/>
|
<OverallResults successes="5" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
<Section name="Shortened hide tags are split apart when parsing" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
spec.matches(*fakeTestCase("hidden and foo", "[.][foo]"))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
true
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
!(spec.matches(*fakeTestCase("only foo", "[foo]")))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
!false
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="2" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<Section name="Shortened hide tags also properly handle exclusion" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
!(spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
!false
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
!(spec.matches(*fakeTestCase("only foo", "[foo]")))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
!false
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK_FALSE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
!(spec.matches(*fakeTestCase("only hidden", "[.]")))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
!false
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
spec.matches(*fakeTestCase("neither foo nor hidden", "[bar]"))
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
true
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="4" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="Pointers can be compared to null" filename="tests/<exe-name>/UsageTests/Condition.tests.cpp" >
|
<TestCase name="Pointers can be compared to null" filename="tests/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
@ -10852,6 +10906,20 @@ Message from section two
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
|
<Section name="Substrings" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Section name="substring start after the end is empty" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
|
<Original>
|
||||||
|
s.substr(1'000'000, 1).empty()
|
||||||
|
</Original>
|
||||||
|
<Expanded>
|
||||||
|
true
|
||||||
|
</Expanded>
|
||||||
|
</Expression>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
|
<OverallResults successes="1" failures="0" expectedFailures="0"/>
|
||||||
|
</Section>
|
||||||
<Section name="Comparisons are deep" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Section name="Comparisons are deep" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@ -10993,7 +11061,7 @@ Message from section two
|
|||||||
</TestCase>
|
</TestCase>
|
||||||
<TestCase name="StringRef at compilation time" tags="[constexpr][StringRef][Strings]" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<TestCase name="StringRef at compilation time" tags="[constexpr][StringRef][Strings]" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<Section name="Simple constructors" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Section name="Simple constructors" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<OverallResults successes="5" failures="0" expectedFailures="0"/>
|
<OverallResults successes="14" failures="0" expectedFailures="0"/>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="UDL construction" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
<Section name="UDL construction" filename="tests/<exe-name>/IntrospectiveTests/String.tests.cpp" >
|
||||||
<OverallResults successes="6" failures="0" expectedFailures="0"/>
|
<OverallResults successes="6" failures="0" expectedFailures="0"/>
|
||||||
@ -16841,7 +16909,7 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="1624" failures="149" expectedFailures="21"/>
|
<OverallResults successes="1640" failures="149" expectedFailures="21"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="1624" failures="148" expectedFailures="21"/>
|
<OverallResults successes="1640" failures="148" expectedFailures="21"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@ -19,7 +19,7 @@ namespace {
|
|||||||
auto fakeTestCase(const char* name, const char* desc = "") { return Catch::makeTestCaseInfo("", { name, desc }, CATCH_INTERNAL_LINEINFO); }
|
auto fakeTestCase(const char* name, const char* desc = "") { return Catch::makeTestCaseInfo("", { name, desc }, CATCH_INTERNAL_LINEINFO); }
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "Parse test names and tags" ) {
|
TEST_CASE( "Parse test names and tags", "[command-line][test-spec]" ) {
|
||||||
|
|
||||||
using Catch::parseTestSpec;
|
using Catch::parseTestSpec;
|
||||||
using Catch::TestSpec;
|
using Catch::TestSpec;
|
||||||
@ -280,7 +280,18 @@ TEST_CASE( "Parse test names and tags" ) {
|
|||||||
CHECK( spec.matches( *fakeTestCase( " aardvark " ) ) );
|
CHECK( spec.matches( *fakeTestCase( " aardvark " ) ) );
|
||||||
CHECK( spec.matches( *fakeTestCase( "aardvark " ) ) );
|
CHECK( spec.matches( *fakeTestCase( "aardvark " ) ) );
|
||||||
CHECK( spec.matches( *fakeTestCase( "aardvark" ) ) );
|
CHECK( spec.matches( *fakeTestCase( "aardvark" ) ) );
|
||||||
|
}
|
||||||
|
SECTION("Shortened hide tags are split apart when parsing") {
|
||||||
|
TestSpec spec = parseTestSpec("[.foo]");
|
||||||
|
CHECK(spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")));
|
||||||
|
CHECK_FALSE(spec.matches(*fakeTestCase("only foo", "[foo]")));
|
||||||
|
}
|
||||||
|
SECTION("Shortened hide tags also properly handle exclusion") {
|
||||||
|
TestSpec spec = parseTestSpec("~[.foo]");
|
||||||
|
CHECK_FALSE(spec.matches(*fakeTestCase("hidden and foo", "[.][foo]")));
|
||||||
|
CHECK_FALSE(spec.matches(*fakeTestCase("only foo", "[foo]")));
|
||||||
|
CHECK_FALSE(spec.matches(*fakeTestCase("only hidden", "[.]")));
|
||||||
|
CHECK(spec.matches(*fakeTestCase("neither foo nor hidden", "[bar]")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,6 +315,21 @@ TEST_CASE("GENERATE capture macros", "[generators][internals][approvals]") {
|
|||||||
REQUIRE(value == value2);
|
REQUIRE(value == value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("#1809 - GENERATE_COPY and SingleValueGenerator does not compile", "[generators][compilation][approvals]") {
|
||||||
|
// Verify Issue #1809 fix, only needs to compile.
|
||||||
|
auto a = GENERATE_COPY(1, 2);
|
||||||
|
(void)a;
|
||||||
|
auto b = GENERATE_COPY(as<long>{}, 1, 2);
|
||||||
|
(void)b;
|
||||||
|
int i = 1;
|
||||||
|
int j = 2;
|
||||||
|
auto c = GENERATE_COPY(i, j);
|
||||||
|
(void)c;
|
||||||
|
auto d = GENERATE_COPY(as<long>{}, i, j);
|
||||||
|
(void)d;
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") {
|
TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") {
|
||||||
SECTION("Integer") {
|
SECTION("Integer") {
|
||||||
auto random1 = Catch::Generators::random(0, 1000);
|
auto random1 = Catch::Generators::random(0, 1000);
|
||||||
|
@ -72,7 +72,9 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
ss = s.substr(6, 123);
|
ss = s.substr(6, 123);
|
||||||
REQUIRE(std::strcmp(ss.c_str(), "world!") == 0);
|
REQUIRE(std::strcmp(ss.c_str(), "world!") == 0);
|
||||||
}
|
}
|
||||||
// TODO: substring into string + size is longer than end
|
SECTION("substring start after the end is empty") {
|
||||||
|
REQUIRE(s.substr(1'000'000, 1).empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION( "Comparisons are deep" ) {
|
SECTION( "Comparisons are deep" ) {
|
||||||
@ -124,15 +126,32 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("StringRef at compilation time", "[Strings][StringRef][constexpr]") {
|
TEST_CASE("StringRef at compilation time", "[Strings][StringRef][constexpr]") {
|
||||||
|
//TODO:
|
||||||
|
// * substr
|
||||||
using Catch::StringRef;
|
using Catch::StringRef;
|
||||||
SECTION("Simple constructors") {
|
SECTION("Simple constructors") {
|
||||||
STATIC_REQUIRE(StringRef{}.size() == 0);
|
constexpr StringRef empty{};
|
||||||
|
STATIC_REQUIRE(empty.size() == 0);
|
||||||
|
STATIC_REQUIRE(empty.begin() == empty.end());
|
||||||
|
|
||||||
STATIC_REQUIRE(StringRef{ "abc", 3 }.size() == 3);
|
constexpr char const* const abc = "abc";
|
||||||
STATIC_REQUIRE(StringRef{ "abc", 3 }.isNullTerminated());
|
|
||||||
|
|
||||||
STATIC_REQUIRE(StringRef{ "abc", 2 }.size() == 2);
|
constexpr StringRef stringref(abc, 3);
|
||||||
STATIC_REQUIRE_FALSE(StringRef{ "abc", 2 }.isNullTerminated());
|
STATIC_REQUIRE(stringref.size() == 3);
|
||||||
|
STATIC_REQUIRE(stringref.isNullTerminated());
|
||||||
|
STATIC_REQUIRE(stringref.data() == abc);
|
||||||
|
STATIC_REQUIRE(stringref.begin() == abc);
|
||||||
|
STATIC_REQUIRE(stringref.begin() != stringref.end());
|
||||||
|
STATIC_REQUIRE(stringref.substr(10, 0).empty());
|
||||||
|
STATIC_REQUIRE(stringref.substr(2, 1).data() == abc + 2);
|
||||||
|
|
||||||
|
|
||||||
|
constexpr StringRef shortened(abc, 2);
|
||||||
|
STATIC_REQUIRE(shortened.size() == 2);
|
||||||
|
STATIC_REQUIRE(shortened.data() == abc);
|
||||||
|
STATIC_REQUIRE(shortened.begin() != shortened.end());
|
||||||
|
STATIC_REQUIRE_FALSE(shortened.isNullTerminated());
|
||||||
|
STATIC_REQUIRE_FALSE(shortened.substr(1, 3).isNullTerminated());
|
||||||
}
|
}
|
||||||
SECTION("UDL construction") {
|
SECTION("UDL construction") {
|
||||||
constexpr auto sr1 = "abc"_catch_sr;
|
constexpr auto sr1 = "abc"_catch_sr;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include <catch2/benchmark/catch_benchmark.hpp>
|
#include <catch2/benchmark/catch_benchmark.hpp>
|
||||||
|
#include <catch2/benchmark/catch_constructor.hpp>
|
||||||
#include <catch2/catch_generators_specific.hpp>
|
#include <catch2/catch_generators_specific.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -127,4 +128,18 @@ TEST_CASE("Benchmark containers", "[!benchmark]") {
|
|||||||
REQUIRE(v[i] == generated);
|
REQUIRE(v[i] == generated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("construct and destroy example") {
|
||||||
|
BENCHMARK_ADVANCED("construct")(Catch::Benchmark::Chronometer meter) {
|
||||||
|
std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
|
||||||
|
meter.measure([&](int i) { storage[i].construct("thing"); });
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_ADVANCED("destroy")(Catch::Benchmark::Chronometer meter) {
|
||||||
|
std::vector<Catch::Benchmark::destructable_object<std::string>> storage(meter.runs());
|
||||||
|
for(auto&& o : storage)
|
||||||
|
o.construct("thing");
|
||||||
|
meter.measure([&](int i) { storage[i].destruct(); });
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ nanParser = re.compile(r'''
|
|||||||
''', re.VERBOSE)
|
''', re.VERBOSE)
|
||||||
|
|
||||||
# The weird OR is there to always have at least empty string for group 1
|
# The weird OR is there to always have at least empty string for group 1
|
||||||
tapTestNumParser = re.compile(r'^(not |)?ok (\d+) -')
|
tapTestNumParser = re.compile(r'^((?:not ok)|(?:ok)|(?:warning)|(?:info)) (\d+) -')
|
||||||
|
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
cmdPath = sys.argv[1]
|
cmdPath = sys.argv[1]
|
||||||
@ -128,7 +128,7 @@ def filterLine(line, isCompact):
|
|||||||
line = line.replace(': PASSED', ': passed')
|
line = line.replace(': PASSED', ': passed')
|
||||||
|
|
||||||
# strip out the test order number in TAP to avoid massive diffs for every change
|
# strip out the test order number in TAP to avoid massive diffs for every change
|
||||||
line = tapTestNumParser.sub("\g<1>ok {test-number} -", line)
|
line = tapTestNumParser.sub("\g<1> {test-number} -", line)
|
||||||
|
|
||||||
# strip Catch version number
|
# strip Catch version number
|
||||||
line = versionParser.sub("<version>", line)
|
line = versionParser.sub("<version>", line)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user