Compare commits

...

12 Commits

Author SHA1 Message Date
Martin Hořeňovský
e1c9d5569d v2.11.0 2019-11-15 15:06:17 +01:00
Martin Hořeňovský
d512decaac Mention the sonarqube reporter in release process 2019-11-15 14:59:35 +01:00
Martin Hořeňovský
f23f96883a Ensure the full benchmarking support is present in the single header
Fixes #1800
2019-11-15 11:59:43 +01:00
Martin Hořeňovský
d7b8c3ace3 Minor cleanup in the benchmarking tests 2019-11-15 11:59:35 +01:00
Martin Hořeňovský
32733e08c0 Use newer version of Python on AppVeyor 2019-11-13 20:58:15 +01:00
Martin Hořeňovský
930f49a641 Split [.foo] into [.][foo] when parsing test specs
b77cec05c0 fixed this problem for tagging tests, so that a test
case tagged with `[.foo]` would be parsed as tagged with `[.][foo]`.
This does the same for the test spec parsing.

Fixes #1798
2019-11-05 23:28:47 +01:00
Martin Hořeňovský
c409dccee5 Cleanup tests for C++20 2019-11-04 10:42:34 +01:00
Martin Hořeňovský
95bfb33167 Forbid copying ReusableStringStream
Copying a `ReusableStringStream` would lead to "double free" of
the stream, and thus it could be used in multiple places at the
same time, breaking the output.
2019-11-04 00:05:35 +01:00
Martin Hořeňovský
59d2d08c0f Merge pull request #1794 from cericks0n/patch-1
Fix error when period of steady_clock is not nano
2019-11-03 18:22:56 +01:00
cericks0n
fa6d52e2a3 Fix error when period of steady_clock is not nano
On systems where std::chrono::steady_clock::period is not std::nano, benchmark tests fail to compile due to trying to convert analysis.samples from a vector of duration<double, clock::period> to a vector of std::chrono::duration<double, std::nano>.
2019-11-01 15:52:38 -05:00
Martin Hořeňovský
5ac348cd6e Fix compilation error in examples 2019-10-31 16:08:37 +01:00
Martin Hořeňovský
776a4686c7 Warning fixes in examples and tests 2019-10-31 14:29:59 +01:00
28 changed files with 909 additions and 1068 deletions

View File

@@ -14,7 +14,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2 LANGUAGES CXX VERSION 2.10.2)
project(Catch2 LANGUAGES CXX VERSION 2.11.0)
# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")

View File

@@ -5,11 +5,11 @@
[![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
[![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
[![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/LzYWgcPrcy9yQmed)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/HU1MkiBgFetFQJU4)
[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
<a href="https://github.com/catchorg/Catch2/releases/download/v2.10.2/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
<a href="https://github.com/catchorg/Catch2/releases/download/v2.11.0/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
## Catch2 is released!

View File

@@ -1,6 +1,11 @@
# version string format -- This will be overwritten later anyway
version: "{build}"
# We need a more up to date pip because Python 2.7 is EOL soon
init:
- set PATH=C:\Python35\Scripts;%PATH%
branches:
except:
- /dev-travis.+/
@@ -62,7 +67,7 @@ matrix:
install:
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { python -m pip --disable-pip-version-check install codecov }
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { pip --disable-pip-version-check install codecov }
- ps: if (($env:CONFIGURATION) -eq "Debug" -And ($env:coverage) -eq "1" ) { .\misc\installOpenCppCoverage.ps1 }
# Win32 and x64 are CMake-compatible solution platform names.

View File

@@ -78,7 +78,7 @@ type, making their usage much nicer. These are
> `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
that returns 100 odd random number:

View File

@@ -2,6 +2,7 @@
# Release notes
**Contents**<br>
[2.11.0](#2110)<br>
[2.10.2](#2102)<br>
[2.10.1](#2101)<br>
[2.10.0](#2100)<br>
@@ -31,6 +32,23 @@
[Even Older versions](#even-older-versions)<br>
## 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
### Improvements

View File

@@ -67,6 +67,7 @@ $ gpg2 --armor --output catch.hpp.asc --detach-sig catch.hpp
$ gpg2 --armor --output catch_reporter_automake.hpp.asc --detach-sig catch_reporter_automake.hpp
$ gpg2 --armor --output catch_reporter_teamcity.hpp.asc --detach-sig catch_reporter_teamcity.hpp
$ gpg2 --armor --output catch_reporter_tap.hpp.asc --detach-sig catch_reporter_tap.hpp
$ gpg2 --armor --output catch_reporter_sonarqube.hpp.asc --detach-sig catch_reporter_sonarqube.hpp
```
_GPG does not support signing multiple files in single invocation._

View File

@@ -10,11 +10,12 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
class out_buff : public std::stringbuf {
std::FILE* m_stream;
public:
out_buff(std::FILE* stream) :m_stream(stream) {}
~out_buff() { pubsync(); }
out_buff(std::FILE* stream):m_stream(stream) {}
~out_buff();
int sync() {
int ret = 0;
for (unsigned char c : str()) {
@@ -29,6 +30,12 @@ public:
}
};
out_buff::~out_buff() { pubsync(); }
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wexit-time-destructors" // static variables in cout/cerr/clog
#endif
namespace Catch {
std::ostream& cout() {
static std::ostream ret(new out_buff(stdout));

View File

@@ -22,15 +22,17 @@ public:
}
}
std::string const& get() const override {
return m_line;
}
std::string const& get() const override;
bool next() override {
return !!std::getline(m_stream, m_line);
}
};
std::string const& LineGenerator::get() const {
return m_line;
}
// This helper function provides a nicer UX when instantiating the generator
// Notice that it returns an instance of GeneratorWrapper<std::string>, which
// is a value-wrapper around std::unique_ptr<IGenerator<std::string>>.

View File

@@ -10,8 +10,8 @@
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 10
#define CATCH_VERSION_PATCH 2
#define CATCH_VERSION_MINOR 11
#define CATCH_VERSION_PATCH 0
#ifdef __clang__
# pragma clang system_header
@@ -80,7 +80,7 @@
#endif
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
#include "internal/benchmark/catch_benchmark.hpp"
#include "internal/benchmark/catch_benchmarking_all.hpp"
#endif
#endif // ! CATCH_CONFIG_IMPL_ONLY

View File

@@ -79,7 +79,7 @@ namespace Catch {
});
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);
} CATCH_CATCH_ALL{

View File

@@ -0,0 +1,29 @@
/*
* 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)
*/
// A proxy header that includes all of the benchmarking headers to allow
// concise include of the benchmarking features. You should prefer the
// individual includes in standard use.
#include "catch_benchmark.hpp"
#include "catch_chronometer.hpp"
#include "catch_clock.hpp"
#include "catch_constructor.hpp"
#include "catch_environment.hpp"
#include "catch_estimate.hpp"
#include "catch_execution_plan.hpp"
#include "catch_optimizer.hpp"
#include "catch_outlier_classification.hpp"
#include "catch_sample_analysis.hpp"
#include "detail/catch_analyse.hpp"
#include "detail/catch_benchmark_function.hpp"
#include "detail/catch_complete_invoke.hpp"
#include "detail/catch_estimate_clock.hpp"
#include "detail/catch_measure.hpp"
#include "detail/catch_repeat.hpp"
#include "detail/catch_run_for_at_least.hpp"
#include "detail/catch_stats.hpp"
#include "detail/catch_timing.hpp"

View File

@@ -9,6 +9,8 @@
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
#include "catch_common.h"
#include <iosfwd>
#include <cstddef>
#include <ostream>
@@ -28,7 +30,7 @@ namespace Catch {
auto makeStream( StringRef const &filename ) -> IStream const*;
class ReusableStringStream {
class ReusableStringStream : NonCopyable {
std::size_t m_index;
std::ostream* m_oss;
public:

View File

@@ -20,10 +20,10 @@ namespace Catch {
m_substring.reserve(m_arg.size());
m_patternName.reserve(m_arg.size());
m_realPatternPos = 0;
for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
//if visitChar fails
if( !visitChar( m_arg[m_pos] ) ){
if( !visitChar( m_arg[m_pos] ) ){
m_testSpec.m_invalidArgs.push_back(arg);
break;
}
@@ -113,9 +113,9 @@ namespace Catch {
switch( m_mode ) {
case Name:
case QuotedName:
return addPattern<TestSpec::NamePattern>();
return addNamePattern();
case Tag:
return addPattern<TestSpec::TagPattern>();
return addTagPattern();
case EscapedName:
revertBackToLastMode();
return;
@@ -156,12 +156,12 @@ namespace Catch {
void TestSpecParser::saveLastMode() {
lastMode = m_mode;
}
void TestSpecParser::revertBackToLastMode() {
m_mode = lastMode;
}
bool TestSpecParser::separate() {
bool TestSpecParser::separate() {
if( (m_mode==QuotedName) || (m_mode==Tag) ){
//invalid argument, signal failure to previous scope.
m_mode = None;
@@ -174,7 +174,63 @@ namespace Catch {
addFilter();
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()) {
TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
if (m_exclusion)
pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
m_currentFilter.m_patterns.push_back(pattern);
}
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());
TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
if (m_exclusion) {
pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
}
m_currentFilter.m_patterns.push_back(pattern);
}
TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
if (m_exclusion) {
pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
}
m_currentFilter.m_patterns.push_back(pattern);
}
m_substring.clear();
m_exclusion = false;
m_mode = None;
}
TestSpec parseTestSpec( std::string const& arg ) {
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
}

View File

@@ -53,35 +53,20 @@ namespace Catch {
void revertBackToLastMode();
void addFilter();
bool separate();
template<typename T>
void addPattern() {
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 );
}
if( !token.empty() ) {
TestSpec::PatternPtr pattern = std::make_shared<T>( token, m_substring );
if( m_exclusion )
pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
m_currentFilter.m_patterns.push_back( pattern );
}
m_substring.clear();
m_patternName.clear();
m_exclusion = false;
m_mode = None;
}
// Handles common preprocessing of the pattern for name/tag patterns
std::string preprocessPattern();
// Adds the current pattern as a test name
void addNamePattern();
// Adds the current pattern as a tag
void addTagPattern();
inline void addCharToPattern(char c) {
m_substring += c;
m_patternName += c;
m_realPatternPos++;
}
};
TestSpec parseTestSpec( std::string const& arg );

View File

@@ -37,7 +37,7 @@ namespace Catch {
}
Version const& libraryVersion() {
static Version version( 2, 10, 2, "", 0 );
static Version version( 2, 11, 0, "", 0 );
return version;
}

View File

@@ -26,14 +26,6 @@ TEST_CASE("Benchmark factorial", "[benchmark]") {
BENCHMARK("factorial 14") {
return factorial(14);
};
//
// BENCHMARK("factorial 20") {
// return factorial(20);
// };
//
// BENCHMARK("factorial 35") {
// return factorial(35);
// };
}
TEST_CASE("Benchmark containers", "[.][benchmark]") {

View File

@@ -1027,6 +1027,12 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( fakeTestCase( " aardvark
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 == pNULL for: 0 == 0
Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
@@ -1186,7 +1192,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.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: buffer1 != 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 != left.substr(0, 3) for: Hello != Hel
String.tests.cpp:<line number>: passed: sr == "a standard string" for: a standard string == "a standard string"
@@ -1561,48 +1567,6 @@ Xml.tests.cpp:<line number>: passed: encode( stringWithQuotes, Catch::XmlEncode:
"don't &quot;quote&quot; me on that"
Xml.tests.cpp:<line number>: passed: encode( "[\x01]" ) == "[\\x01]" for: "[\x01]" == "[\x01]"
Xml.tests.cpp:<line number>: passed: encode( "[\x7F]" ) == "[\\x7F]" for: "[\x7F]" == "[\x7F]"
Xml.tests.cpp:<line number>: passed: encode(u8"Here be 👾") == u8"Here be 👾" for: "Here be 👾" == "Here be 👾"
Xml.tests.cpp:<line number>: passed: encode(u8"šš") == u8"šš" for: "šš" == "šš"
Xml.tests.cpp:<line number>: passed: encode("\xDF\xBF") == "\xDF\xBF" for: "߿" == "߿"
Xml.tests.cpp:<line number>: passed: encode("\xE0\xA0\x80") == "\xE0\xA0\x80" for: "ࠀ" == "ࠀ"
Xml.tests.cpp:<line number>: passed: encode("\xED\x9F\xBF") == "\xED\x9F\xBF" for: "퟿" == "퟿"
Xml.tests.cpp:<line number>: passed: encode("\xEE\x80\x80") == "\xEE\x80\x80" for: "" == ""
Xml.tests.cpp:<line number>: passed: encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF" for: "￿" == "￿"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80" for: "𐀀" == "𐀀"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF" for: "􏿿" == "􏿿"
Xml.tests.cpp:<line number>: passed: encode("Here \xFF be 👾") == u8"Here \\xFF be 👾" for: "Here \xFF be 👾" == "Here \xFF be 👾"
Xml.tests.cpp:<line number>: passed: encode("\xFF") == "\\xFF" for: "\xFF" == "\xFF"
Xml.tests.cpp:<line number>: passed: encode("\xC5\xC5\xA0") == u8"\\xC5Š" for: "\xC5Š" == "\xC5Š"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80" for: "\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xC0\x80") == u8"\\xC0\\x80" for: "\xC0\x80" == "\xC0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80" for: "\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xC1\xBF") == u8"\\xC1\\xBF" for: "\xC1\xBF" == "\xC1\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF" for: "\xE0\x9F\xBF" == "\xE0\x9F\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF" for: "\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xED\xA0\x80") == "\xED\xA0\x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xAF\xBF") == "\xED\xAF\xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xB0\x80") == "\xED\xB0\x80" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\xED\xBF\xBF") == "\xED\xBF\xBF" for: "<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: passed: encode("\x80") == u8"\\x80" for: "\x80" == "\x80"
Xml.tests.cpp:<line number>: passed: encode("\x81") == u8"\\x81" for: "\x81" == "\x81"
Xml.tests.cpp:<line number>: passed: encode("\xBC") == u8"\\xBC" for: "\xBC" == "\xBC"
Xml.tests.cpp:<line number>: passed: encode("\xBF") == u8"\\xBF" for: "\xBF" == "\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80" for: "\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80" for: "\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80" for: "\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xDE") == u8"\\xDE" for: "\xDE" == "\xDE"
Xml.tests.cpp:<line number>: passed: encode("\xDF") == u8"\\xDF" for: "\xDF" == "\xDF"
Xml.tests.cpp:<line number>: passed: encode("\xE0") == u8"\\xE0" for: "\xE0" == "\xE0"
Xml.tests.cpp:<line number>: passed: encode("\xEF") == u8"\\xEF" for: "\xEF" == "\xEF"
Xml.tests.cpp:<line number>: passed: encode("\xF0") == u8"\\xF0" for: "\xF0" == "\xF0"
Xml.tests.cpp:<line number>: passed: encode("\xF4") == u8"\\xF4" for: "\xF4" == "\xF4"
Xml.tests.cpp:<line number>: passed: encode("\xE0\x80") == u8"\\xE0\\x80" for: "\xE0\x80" == "\xE0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xE0\xBF") == u8"\\xE0\\xBF" for: "\xE0\xBF" == "\xE0\xBF"
Xml.tests.cpp:<line number>: passed: encode("\xE1\x80") == u8"\\xE1\\x80" for: "\xE1\x80" == "\xE1\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80") == u8"\\xF0\\x80" for: "\xF0\x80" == "\xF0\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x80") == u8"\\xF4\\x80" for: "\xF4\x80" == "\xF4\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80" for: "\xF0\x80\x80" == "\xF0\x80\x80"
Xml.tests.cpp:<line number>: passed: encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80" for: "\xF4\x80\x80" == "\xF4\x80\x80"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( empty ) == "{ }" for: "{ }" == "{ }"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( oneValue ) == "{ 42 }" for: "{ 42 }" == "{ 42 }"
ToStringVector.tests.cpp:<line number>: passed: Catch::Detail::stringify( twoValues ) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }"

View File

@@ -1380,6 +1380,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 305 | 231 passed | 70 failed | 4 failed as expected
assertions: 1695 | 1543 passed | 131 failed | 21 failed as expected
test cases: 304 | 230 passed | 70 failed | 4 failed as expected
assertions: 1659 | 1507 passed | 131 failed | 21 failed as expected

View File

@@ -7361,6 +7361,50 @@ CmdLine.tests.cpp:<line number>: PASSED:
with expansion:
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
-------------------------------------------------------------------------------
@@ -8670,7 +8714,7 @@ String.tests.cpp:<line number>
...............................................................................
String.tests.cpp:<line number>: PASSED:
CHECK( buffer1 != buffer2 )
CHECK( (char*)buffer1 != (char*)buffer2 )
with expansion:
"Hello" != "Hello"
@@ -11421,263 +11465,6 @@ Xml.tests.cpp:<line number>: PASSED:
with expansion:
"[\x7F]" == "[\x7F]"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Valid utf-8 strings
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode(u8"Here be 👾") == u8"Here be 👾" )
with expansion:
"Here be 👾" == "Here be 👾"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode(u8"šš") == u8"šš" )
with expansion:
"šš" == "šš"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xDF\xBF") == "\xDF\xBF" )
with expansion:
"߿" == "߿"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE0\xA0\x80") == "\xE0\xA0\x80" )
with expansion:
"ࠀ" == "ࠀ"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xED\x9F\xBF") == "\xED\x9F\xBF" )
with expansion:
"퟿" == "퟿"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xEE\x80\x80") == "\xEE\x80\x80" )
with expansion:
"" == ""
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF" )
with expansion:
"￿" == "￿"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80" )
with expansion:
"𐀀" == "𐀀"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF" )
with expansion:
"􏿿" == "􏿿"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Invalid utf-8 strings
Various broken strings
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("Here \xFF be 👾") == u8"Here \\xFF be 👾" )
with expansion:
"Here \xFF be 👾" == "Here \xFF be 👾"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xFF") == "\\xFF" )
with expansion:
"\xFF" == "\xFF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xC5\xC5\xA0") == u8"\\xC5Š" )
with expansion:
"\xC5Š" == "\xC5Š"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80" )
with expansion:
"\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Invalid utf-8 strings
Overlong encodings
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xC0\x80") == u8"\\xC0\\x80" )
with expansion:
"\xC0\x80" == "\xC0\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80" )
with expansion:
"\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xC1\xBF") == u8"\\xC1\\xBF" )
with expansion:
"\xC1\xBF" == "\xC1\xBF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF" )
with expansion:
"\xE0\x9F\xBF" == "\xE0\x9F\xBF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF" )
with expansion:
"\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Invalid utf-8 strings
Surrogate pairs
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xED\xA0\x80") == "\xED\xA0\x80" )
with expansion:
"<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xED\xAF\xBF") == "\xED\xAF\xBF" )
with expansion:
"<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xED\xB0\x80") == "\xED\xB0\x80" )
with expansion:
"<22><><EFBFBD>" == "<22><><EFBFBD>"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xED\xBF\xBF") == "\xED\xBF\xBF" )
with expansion:
"<22><><EFBFBD>" == "<22><><EFBFBD>"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Invalid utf-8 strings
Invalid start byte
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\x80") == u8"\\x80" )
with expansion:
"\x80" == "\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\x81") == u8"\\x81" )
with expansion:
"\x81" == "\x81"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xBC") == u8"\\xBC" )
with expansion:
"\xBC" == "\xBC"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xBF") == u8"\\xBF" )
with expansion:
"\xBF" == "\xBF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80" )
with expansion:
"\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80" )
with expansion:
"\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80" )
with expansion:
"\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
-------------------------------------------------------------------------------
XmlEncode: UTF-8
Invalid utf-8 strings
Missing continuation byte(s)
-------------------------------------------------------------------------------
Xml.tests.cpp:<line number>
...............................................................................
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xDE") == u8"\\xDE" )
with expansion:
"\xDE" == "\xDE"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xDF") == u8"\\xDF" )
with expansion:
"\xDF" == "\xDF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE0") == u8"\\xE0" )
with expansion:
"\xE0" == "\xE0"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xEF") == u8"\\xEF" )
with expansion:
"\xEF" == "\xEF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0") == u8"\\xF0" )
with expansion:
"\xF0" == "\xF0"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF4") == u8"\\xF4" )
with expansion:
"\xF4" == "\xF4"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE0\x80") == u8"\\xE0\\x80" )
with expansion:
"\xE0\x80" == "\xE0\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE0\xBF") == u8"\\xE0\\xBF" )
with expansion:
"\xE0\xBF" == "\xE0\xBF"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xE1\x80") == u8"\\xE1\\x80" )
with expansion:
"\xE1\x80" == "\xE1\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0\x80") == u8"\\xF0\\x80" )
with expansion:
"\xF0\x80" == "\xF0\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF4\x80") == u8"\\xF4\\x80" )
with expansion:
"\xF4\x80" == "\xF4\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80" )
with expansion:
"\xF0\x80\x80" == "\xF0\x80\x80"
Xml.tests.cpp:<line number>: PASSED:
CHECK( encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80" )
with expansion:
"\xF4\x80\x80" == "\xF4\x80\x80"
-------------------------------------------------------------------------------
array<int, N> -> toString
-------------------------------------------------------------------------------
@@ -13464,6 +13251,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 305 | 215 passed | 86 failed | 4 failed as expected
assertions: 1712 | 1543 passed | 148 failed | 21 failed as expected
test cases: 304 | 214 passed | 86 failed | 4 failed as expected
assertions: 1676 | 1507 passed | 148 failed | 21 failed as expected

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="132" tests="1713" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="132" tests="1677" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
<property name="random-seed" value="1"/>
@@ -982,6 +982,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/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/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="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}"/>
@@ -1402,12 +1404,6 @@ Exception.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="XmlEncode/string with quotes" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode/string with control char (1)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode/string with control char (x7F)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Valid utf-8 strings" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Various broken strings" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Overlong encodings" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Surrogate pairs" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Invalid start byte" time="{duration}"/>
<testcase classname="<exe-name>.global" name="XmlEncode: UTF-8/Invalid utf-8 strings/Missing continuation byte(s)" time="{duration}"/>
<testcase classname="<exe-name>.global" name="array&lt;int, N> -> toString" time="{duration}"/>
<testcase classname="<exe-name>.global" name="atomic if" time="{duration}"/>
<testcase classname="<exe-name>.global" name="boolean member" time="{duration}"/>

View File

@@ -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/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/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/default - no arguments" duration="{duration}"/>
<testCase name="Process can be configured on command line/test lists/Specify one test case using" duration="{duration}"/>
@@ -157,12 +159,6 @@
<testCase name="XmlEncode/string with quotes" duration="{duration}"/>
<testCase name="XmlEncode/string with control char (1)" duration="{duration}"/>
<testCase name="XmlEncode/string with control char (x7F)" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Valid utf-8 strings" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Invalid utf-8 strings/Various broken strings" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Invalid utf-8 strings/Overlong encodings" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Invalid utf-8 strings/Surrogate pairs" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Invalid utf-8 strings/Invalid start byte" duration="{duration}"/>
<testCase name="XmlEncode: UTF-8/Invalid utf-8 strings/Missing continuation byte(s)" duration="{duration}"/>
</file>
<file path="projects/<exe-name>/UsageTests/Approx.tests.cpp">
<testCase name="A comparison that uses literals instead of the normal constructor" duration="{duration}"/>

View File

@@ -8019,7 +8019,7 @@ Nor would this
</Section>
<OverallResult success="false"/>
</TestCase>
<TestCase name="Parse test names and tags" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<TestCase name="Parse test names and tags" tags="[command-line][test-spec]" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Section name="Empty test spec should have no filters" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
@@ -9279,6 +9279,60 @@ Nor would this
</Expression>
<OverallResults successes="5" failures="0" expectedFailures="0"/>
</Section>
<Section name="Shortened hide tags are split apart when parsing" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<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="projects/<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="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="CHECK_FALSE" filename="projects/<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="projects/<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="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
!(spec.matches(fakeTestCase("only hidden", "[.]")))
</Original>
<Expanded>
!false
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<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"/>
</TestCase>
<TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
@@ -10849,7 +10903,7 @@ Message from section two
<Section name="Comparisons are deep" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/String.tests.cpp" >
<Original>
buffer1 != buffer2
(char*)buffer1 != (char*)buffer2
</Original>
<Expanded>
"Hello" != "Hello"
@@ -13846,378 +13900,6 @@ There is no extra whitespace here
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="XmlEncode: UTF-8" tags="[UTF-8][XML]" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Valid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode(u8"Here be 👾") == u8"Here be 👾"
</Original>
<Expanded>
"Here be 👾" == "Here be 👾"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode(u8"šš") == u8"šš"
</Original>
<Expanded>
"šš" == "šš"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xDF\xBF") == "\xDF\xBF"
</Original>
<Expanded>
"߿" == "߿"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE0\xA0\x80") == "\xE0\xA0\x80"
</Original>
<Expanded>
"ࠀ" == "ࠀ"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xED\x9F\xBF") == "\xED\x9F\xBF"
</Original>
<Expanded>
"퟿" == "퟿"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xEE\x80\x80") == "\xEE\x80\x80"
</Original>
<Expanded>
"" == ""
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF"
</Original>
<Expanded>
"￿" == "￿"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80"
</Original>
<Expanded>
"𐀀" == "𐀀"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF"
</Original>
<Expanded>
"􏿿" == "􏿿"
</Expanded>
</Expression>
<OverallResults successes="9" failures="0" expectedFailures="0"/>
</Section>
<Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Various broken strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("Here \xFF be 👾") == u8"Here \\xFF be 👾"
</Original>
<Expanded>
"Here \xFF be 👾" == "Here \xFF be 👾"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xFF") == "\\xFF"
</Original>
<Expanded>
"\xFF" == "\xFF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xC5\xC5\xA0") == u8"\\xC5Š"
</Original>
<Expanded>
"\xC5Š" == "\xC5Š"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80"
</Original>
<Expanded>
"\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"
</Expanded>
</Expression>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Overlong encodings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xC0\x80") == u8"\\xC0\\x80"
</Original>
<Expanded>
"\xC0\x80" == "\xC0\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80"
</Original>
<Expanded>
"\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xC1\xBF") == u8"\\xC1\\xBF"
</Original>
<Expanded>
"\xC1\xBF" == "\xC1\xBF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF"
</Original>
<Expanded>
"\xE0\x9F\xBF" == "\xE0\x9F\xBF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF"
</Original>
<Expanded>
"\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"
</Expanded>
</Expression>
<OverallResults successes="5" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="5" failures="0" expectedFailures="0"/>
</Section>
<Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Surrogate pairs" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xED\xA0\x80") == "\xED\xA0\x80"
</Original>
<Expanded>
"<22><><EFBFBD>" == "<22><><EFBFBD>"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xED\xAF\xBF") == "\xED\xAF\xBF"
</Original>
<Expanded>
"<22><><EFBFBD>" == "<22><><EFBFBD>"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xED\xB0\x80") == "\xED\xB0\x80"
</Original>
<Expanded>
"<22><><EFBFBD>" == "<22><><EFBFBD>"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xED\xBF\xBF") == "\xED\xBF\xBF"
</Original>
<Expanded>
"<22><><EFBFBD>" == "<22><><EFBFBD>"
</Expanded>
</Expression>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="4" failures="0" expectedFailures="0"/>
</Section>
<Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Invalid start byte" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\x80") == u8"\\x80"
</Original>
<Expanded>
"\x80" == "\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\x81") == u8"\\x81"
</Original>
<Expanded>
"\x81" == "\x81"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xBC") == u8"\\xBC"
</Original>
<Expanded>
"\xBC" == "\xBC"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xBF") == u8"\\xBF"
</Original>
<Expanded>
"\xBF" == "\xBF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80"
</Original>
<Expanded>
"\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80"
</Original>
<Expanded>
"\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80"
</Original>
<Expanded>
"\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"
</Expanded>
</Expression>
<OverallResults successes="7" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="7" failures="0" expectedFailures="0"/>
</Section>
<Section name="Invalid utf-8 strings" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Section name="Missing continuation byte(s)" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xDE") == u8"\\xDE"
</Original>
<Expanded>
"\xDE" == "\xDE"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xDF") == u8"\\xDF"
</Original>
<Expanded>
"\xDF" == "\xDF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE0") == u8"\\xE0"
</Original>
<Expanded>
"\xE0" == "\xE0"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xEF") == u8"\\xEF"
</Original>
<Expanded>
"\xEF" == "\xEF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0") == u8"\\xF0"
</Original>
<Expanded>
"\xF0" == "\xF0"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF4") == u8"\\xF4"
</Original>
<Expanded>
"\xF4" == "\xF4"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE0\x80") == u8"\\xE0\\x80"
</Original>
<Expanded>
"\xE0\x80" == "\xE0\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE0\xBF") == u8"\\xE0\\xBF"
</Original>
<Expanded>
"\xE0\xBF" == "\xE0\xBF"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xE1\x80") == u8"\\xE1\\x80"
</Original>
<Expanded>
"\xE1\x80" == "\xE1\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0\x80") == u8"\\xF0\\x80"
</Original>
<Expanded>
"\xF0\x80" == "\xF0\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF4\x80") == u8"\\xF4\\x80"
</Original>
<Expanded>
"\xF4\x80" == "\xF4\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80"
</Original>
<Expanded>
"\xF0\x80\x80" == "\xF0\x80\x80"
</Expanded>
</Expression>
<Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/Xml.tests.cpp" >
<Original>
encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80"
</Original>
<Expanded>
"\xF4\x80\x80" == "\xF4\x80\x80"
</Expanded>
</Expression>
<OverallResults successes="13" failures="0" expectedFailures="0"/>
</Section>
<OverallResults successes="13" failures="0" expectedFailures="0"/>
</Section>
<OverallResult success="true"/>
</TestCase>
<TestCase name="array&lt;int, N> -> toString" tags="[array][containers][toString]" filename="projects/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/ToStringVector.tests.cpp" >
<Original>
@@ -16162,7 +15844,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1543" failures="149" expectedFailures="21"/>
<OverallResults successes="1507" failures="149" expectedFailures="21"/>
</Group>
<OverallResults successes="1543" failures="148" expectedFailures="21"/>
<OverallResults successes="1507" failures="148" expectedFailures="21"/>
</Catch>

View File

@@ -17,7 +17,7 @@
inline Catch::TestCase fakeTestCase(const char* name, const char* desc = "") { return Catch::makeTestCase(nullptr, "", { 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::TestSpec;
@@ -269,7 +269,6 @@ TEST_CASE( "Parse test names and tags" ) {
CHECK( spec.matches( fakeTestCase( " aardvark " ) ) );
CHECK( spec.matches( fakeTestCase( "aardvark " ) ) );
CHECK( spec.matches( fakeTestCase( "aardvark" ) ) );
}
SECTION( "Leading and trailing spaces in test name" ) {
TestSpec spec = parseTestSpec( "aardvark" );
@@ -278,7 +277,18 @@ TEST_CASE( "Parse test names and tags" ) {
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]")));
}
}
@@ -486,7 +496,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
REQUIRE(config.benchmarkSamples == 200);
}
SECTION("resamples") {
CHECK(cli.parse({ "test", "--benchmark-resamples=20000" }));

View File

@@ -79,7 +79,7 @@ TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
SECTION( "Comparisons are deep" ) {
char buffer1[] = "Hello";
char buffer2[] = "Hello";
CHECK(buffer1 != buffer2);
CHECK((char*)buffer1 != (char*)buffer2);
StringRef left(buffer1), right(buffer2);
REQUIRE( left == right );

View File

@@ -40,10 +40,11 @@ TEST_CASE( "XmlEncode", "[XML]" ) {
}
// Thanks to Peter Bindels (dascandy) for some of the tests
TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8][approvals]") {
#define ESC(lit) (char*)(lit)
SECTION("Valid utf-8 strings") {
CHECK(encode(u8"Here be 👾") == u8"Here be 👾");
CHECK(encode(u8"šš") == u8"šš");
CHECK(encode(ESC(u8"Here be 👾")) == ESC(u8"Here be 👾"));
CHECK(encode(ESC(u8"šš")) == ESC(u8"šš"));
CHECK(encode("\xDF\xBF") == "\xDF\xBF"); // 0x7FF
CHECK(encode("\xE0\xA0\x80") == "\xE0\xA0\x80"); // 0x800
@@ -55,18 +56,18 @@ TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
}
SECTION("Invalid utf-8 strings") {
SECTION("Various broken strings") {
CHECK(encode("Here \xFF be 👾") == u8"Here \\xFF be 👾");
CHECK(encode(ESC("Here \xFF be \xF0\x9F\x91\xBE")) == ESC(u8"Here \\xFF be 👾"));
CHECK(encode("\xFF") == "\\xFF");
CHECK(encode("\xC5\xC5\xA0") == u8"\\xC5Š");
CHECK(encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80"); // 0x110000 -- out of unicode range
CHECK(encode("\xC5\xC5\xA0") == ESC(u8"\\xC5Š"));
CHECK(encode("\xF4\x90\x80\x80") == ESC(u8"\\xF4\\x90\\x80\\x80")); // 0x110000 -- out of unicode range
}
SECTION("Overlong encodings") {
CHECK(encode("\xC0\x80") == u8"\\xC0\\x80"); // \0
CHECK(encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80"); // Super-over-long \0
CHECK(encode("\xC1\xBF") == u8"\\xC1\\xBF"); // ASCII char as UTF-8 (0x7F)
CHECK(encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF"); // 0x7FF
CHECK(encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF"); // 0xFFFF
CHECK(encode("\xC0\x80") == "\\xC0\\x80"); // \0
CHECK(encode("\xF0\x80\x80\x80") == "\\xF0\\x80\\x80\\x80"); // Super-over-long \0
CHECK(encode("\xC1\xBF") == "\\xC1\\xBF"); // ASCII char as UTF-8 (0x7F)
CHECK(encode("\xE0\x9F\xBF") == "\\xE0\\x9F\\xBF"); // 0x7FF
CHECK(encode("\xF0\x8F\xBF\xBF") == "\\xF0\\x8F\\xBF\\xBF"); // 0xFFFF
}
// Note that we actually don't modify surrogate pairs, as we do not do strict checking
@@ -78,35 +79,36 @@ TEST_CASE("XmlEncode: UTF-8", "[XML][UTF-8]") {
}
SECTION("Invalid start byte") {
CHECK(encode("\x80") == u8"\\x80");
CHECK(encode("\x81") == u8"\\x81");
CHECK(encode("\xBC") == u8"\\xBC");
CHECK(encode("\xBF") == u8"\\xBF");
CHECK(encode("\x80") == "\\x80");
CHECK(encode("\x81") == "\\x81");
CHECK(encode("\xBC") == "\\xBC");
CHECK(encode("\xBF") == "\\xBF");
// Out of range
CHECK(encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80");
CHECK(encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80");
CHECK(encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80");
CHECK(encode("\xF5\x80\x80\x80") == "\\xF5\\x80\\x80\\x80");
CHECK(encode("\xF6\x80\x80\x80") == "\\xF6\\x80\\x80\\x80");
CHECK(encode("\xF7\x80\x80\x80") == "\\xF7\\x80\\x80\\x80");
}
SECTION("Missing continuation byte(s)") {
// Missing first continuation byte
CHECK(encode("\xDE") == u8"\\xDE");
CHECK(encode("\xDF") == u8"\\xDF");
CHECK(encode("\xE0") == u8"\\xE0");
CHECK(encode("\xEF") == u8"\\xEF");
CHECK(encode("\xF0") == u8"\\xF0");
CHECK(encode("\xF4") == u8"\\xF4");
CHECK(encode("\xDE") == "\\xDE");
CHECK(encode("\xDF") == "\\xDF");
CHECK(encode("\xE0") == "\\xE0");
CHECK(encode("\xEF") == "\\xEF");
CHECK(encode("\xF0") == "\\xF0");
CHECK(encode("\xF4") == "\\xF4");
// Missing second continuation byte
CHECK(encode("\xE0\x80") == u8"\\xE0\\x80");
CHECK(encode("\xE0\xBF") == u8"\\xE0\\xBF");
CHECK(encode("\xE1\x80") == u8"\\xE1\\x80");
CHECK(encode("\xF0\x80") == u8"\\xF0\\x80");
CHECK(encode("\xF4\x80") == u8"\\xF4\\x80");
CHECK(encode("\xE0\x80") == "\\xE0\\x80");
CHECK(encode("\xE0\xBF") == "\\xE0\\xBF");
CHECK(encode("\xE1\x80") == "\\xE1\\x80");
CHECK(encode("\xF0\x80") == "\\xF0\\x80");
CHECK(encode("\xF4\x80") == "\\xF4\\x80");
// Missing third continuation byte
CHECK(encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80");
CHECK(encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80");
CHECK(encode("\xF0\x80\x80") == "\\xF0\\x80\\x80");
CHECK(encode("\xF4\x80\x80") == "\\xF4\\x80\\x80");
}
}
#undef ESC
}

View File

@@ -9,12 +9,12 @@
// We need 2 types with non-trivial copies/moves
struct MyType1 {
MyType1() = default;
MyType1(MyType1 const&) { throw 1; }
[[noreturn]] MyType1(MyType1 const&) { throw 1; }
MyType1& operator=(MyType1 const&) { throw 3; }
};
struct MyType2 {
MyType2() = default;
MyType2(MyType2 const&) { throw 2; }
[[noreturn]] MyType2(MyType2 const&) { throw 2; }
MyType2& operator=(MyType2 const&) { throw 4; }
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
/*
* Created by Daniel Garcia on 2018-12-04.
* Copyright Social Point SL. All rights reserved.
*
* 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 CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
// Don't #include any Catch headers here - we can assume they are already
// included before this header.
// This is not good practice in general but is necessary in this case so this
// file can be distributed as a single header that works with the main
// Catch single header.
#include <map>
namespace Catch {
struct SonarQubeReporter : CumulativeReporterBase<SonarQubeReporter> {
SonarQubeReporter(ReporterConfig const& config)
: CumulativeReporterBase(config)
, xml(config.stream()) {
m_reporterPrefs.shouldRedirectStdOut = true;
m_reporterPrefs.shouldReportAllAssertions = true;
}
~SonarQubeReporter() override;
static std::string getDescription() {
return "Reports test results in the Generic Test Data SonarQube XML format";
}
static std::set<Verbosity> getSupportedVerbosities() {
return { Verbosity::Normal };
}
void noMatchingTestCases(std::string const& /*spec*/) override {}
void testRunStarting(TestRunInfo const& testRunInfo) override {
CumulativeReporterBase::testRunStarting(testRunInfo);
xml.startElement("testExecutions");
xml.writeAttribute("version", "1");
}
void testGroupEnded(TestGroupStats const& testGroupStats) override {
CumulativeReporterBase::testGroupEnded(testGroupStats);
writeGroup(*m_testGroups.back());
}
void testRunEndedCumulative() override {
xml.endElement();
}
void writeGroup(TestGroupNode const& groupNode) {
std::map<std::string, TestGroupNode::ChildNodes> testsPerFile;
for(auto const& child : groupNode.children)
testsPerFile[child->value.testInfo.lineInfo.file].push_back(child);
for(auto const& kv : testsPerFile)
writeTestFile(kv.first.c_str(), kv.second);
}
void writeTestFile(const char* filename, TestGroupNode::ChildNodes const& testCaseNodes) {
XmlWriter::ScopedElement e = xml.scopedElement("file");
xml.writeAttribute("path", filename);
for(auto const& child : testCaseNodes)
writeTestCase(*child);
}
void writeTestCase(TestCaseNode const& testCaseNode) {
// All test cases have exactly one section - which represents the
// test case itself. That section may have 0-n nested sections
assert(testCaseNode.children.size() == 1);
SectionNode const& rootSection = *testCaseNode.children.front();
writeSection("", rootSection, testCaseNode.value.testInfo.okToFail());
}
void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail) {
std::string name = trim(sectionNode.stats.sectionInfo.name);
if(!rootName.empty())
name = rootName + '/' + name;
if(!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) {
XmlWriter::ScopedElement e = xml.scopedElement("testCase");
xml.writeAttribute("name", name);
xml.writeAttribute("duration", static_cast<long>(sectionNode.stats.durationInSeconds * 1000));
writeAssertions(sectionNode, okToFail);
}
for(auto const& childNode : sectionNode.childSections)
writeSection(name, *childNode, okToFail);
}
void writeAssertions(SectionNode const& sectionNode, bool okToFail) {
for(auto const& assertion : sectionNode.assertions)
writeAssertion( assertion, okToFail);
}
void writeAssertion(AssertionStats const& stats, bool okToFail) {
AssertionResult const& result = stats.assertionResult;
if(!result.isOk()) {
std::string elementName;
if(okToFail) {
elementName = "skipped";
}
else {
switch(result.getResultType()) {
case ResultWas::ThrewException:
case ResultWas::FatalErrorCondition:
elementName = "error";
break;
case ResultWas::ExplicitFailure:
elementName = "failure";
break;
case ResultWas::ExpressionFailed:
elementName = "failure";
break;
case ResultWas::DidntThrowException:
elementName = "failure";
break;
// We should never see these here:
case ResultWas::Info:
case ResultWas::Warning:
case ResultWas::Ok:
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
elementName = "internalError";
break;
}
}
XmlWriter::ScopedElement e = xml.scopedElement(elementName);
ReusableStringStream messageRss;
messageRss << result.getTestMacroName() << "(" << result.getExpression() << ")";
xml.writeAttribute("message", messageRss.str());
ReusableStringStream textRss;
if (stats.totals.assertions.total() > 0) {
textRss << "FAILED:\n";
if (result.hasExpression()) {
textRss << "\t" << result.getExpressionInMacro() << "\n";
}
if (result.hasExpandedExpression()) {
textRss << "with expansion:\n\t" << result.getExpandedExpression() << "\n";
}
}
if(!result.getMessage().empty())
textRss << result.getMessage() << "\n";
for(auto const& msg : stats.infoMessages)
if(msg.type == ResultWas::Info)
textRss << msg.message << "\n";
textRss << "at " << result.getSourceInfo();
xml.writeText(textRss.str(), XmlFormatting::Newline);
}
}
private:
XmlWriter xml;
};
#ifdef CATCH_IMPL
SonarQubeReporter::~SonarQubeReporter() {}
#endif
CATCH_REGISTER_REPORTER( "sonarqube", SonarQubeReporter )
} // end namespace Catch
#endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED