Compare commits

...

12 Commits

Author SHA1 Message Date
Martin Hořeňovský
3dcc923351 v1.9.4 2017-05-16 13:59:29 +02:00
Martin Hořeňovský
589c40077b Typo fix
Somehow I made that in 5ffc8a84cd without noticing
2017-05-16 13:51:17 +02:00
Antonio Di Monaco
b8443e67da Added Win32 UNICODE wmain support (#903)
* Added wmain support
* Added appveyor.yml wmain configuration
* Added wmain configuration flag to CMake
2017-05-11 13:00:03 +02:00
Martin Hořeňovský
5604ec7266 Updated toString documentation
It will need another update when Catch 2 goes live.

Closes #741
2017-05-03 21:09:27 +02:00
Benjamin R. Jack
6f012f2d1d Added warning if source file cannot be found
If source files are defined using relative paths, CMake will compile the tests, but this script will (sometimes) fail to find and parse the tests from the source files.  I have added an explicit warning when ParseAndAddCatchTests fails to find a source file.
2017-05-01 19:55:17 +02:00
Martin Hořeňovský
98e61c31df Approval tests now see different line endings as ok
This is mostly to deal with WSL, where git will checkout file with CRLF,
but code that uses formatted output will be writing LFs.
2017-04-29 18:06:36 +02:00
Martin Hořeňovský
e641485132 Updated approval tests 2017-04-29 17:54:10 +02:00
Martin Hořeňovský
a3ceb8f007 Approval tests now can deal with different expansions of errno 2017-04-29 17:52:12 +02:00
Martin Hořeňovský
b819432271 Don't clear out all messages upon printing an assertion.
Previously, this would not print out any messages for the last CHECK
```cpp
TEST_CASE("Foo") {
INFO("Test case start");
for (int i = 0; i < 2; ++i) {
INFO("The number is " << i);
CHECK(i == 0);
}
CHECK(false);
}
```

now it does.
2017-04-29 17:50:03 +02:00
Martin Hořeňovský
9ceae8f51f CMake binaries are now conditionally enabled
Defining NO_SELFTEST=1 when cmake configuration is being done now turns
off SelfTest and Benchmark executables. This is for projects that
consume Catch using ExternalProject_Add and don't want to build our
selftest binaries for their unit test suite.

Closes #897
2017-04-28 20:27:10 +02:00
Martin Hořeňovský
5ffc8a84cd Fix order of arguments in CATCH_FAIL and nonvariadic INTERNAL_CATCH_MSG
Fixes #896
2017-04-28 18:30:04 +02:00
JayAndCatchFire
6e0fa4be68 Update opensource-users.md
Fixed broken link to LICENSE
2017-04-27 10:29:58 +02:00
20 changed files with 180 additions and 57 deletions

View File

@@ -19,6 +19,10 @@ elseif(USE_CPP14)
set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
endif() endif()
if(USE_WMAIN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
endif()
#checks that the given hard-coded list contains all headers + sources in the given folder #checks that the given hard-coded list contains all headers + sources in the given folder
function(CheckFileList LIST_VAR FOLDER) function(CheckFileList LIST_VAR FOLDER)
set(MESSAGE " should be added to the variable ${LIST_VAR}") set(MESSAGE " should be added to the variable ${LIST_VAR}")
@@ -245,28 +249,35 @@ SOURCE_GROUP("Benchmarks" FILES ${BENCH_SOURCES})
# configure the executable # configure the executable
include_directories(${HEADER_DIR}) include_directories(${HEADER_DIR})
add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
# Add desired warnings # Projects consuming Catch via ExternalProject_Add might want to use install step
if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" ) # without building all of our selftests.
target_compile_options( SelfTest PRIVATE -Wall -Wextra ) if (NOT NO_SELFTEST)
target_compile_options( Benchmark PRIVATE -Wall -Wextra ) add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${HEADERS})
endif() add_executable(Benchmark ${BENCH_SOURCES} ${HEADERS})
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX ) # Add desired warnings
target_compile_options( Benchmark PRIVATE /W4 ) if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
endif() target_compile_options( SelfTest PRIVATE -Wall -Wextra )
target_compile_options( Benchmark PRIVATE -Wall -Wextra )
endif()
if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
target_compile_options( SelfTest PRIVATE /W4 /w44265 /WX )
target_compile_options( Benchmark PRIVATE /W4 )
endif()
# configure unit tests via CTest # configure unit tests via CTest
enable_testing() enable_testing()
add_test(NAME RunTests COMMAND SelfTest) add_test(NAME RunTests COMMAND SelfTest)
add_test(NAME ListTests COMMAND SelfTest --list-tests) add_test(NAME ListTests COMMAND SelfTest --list-tests)
set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases") set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
add_test(NAME ListTags COMMAND SelfTest --list-tags)
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
endif() # !NO_SELFTEST
add_test(NAME ListTags COMMAND SelfTest --list-tags)
set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
install(DIRECTORY "single_include/" DESTINATION "include/catch") install(DIRECTORY "single_include/" DESTINATION "include/catch")

View File

@@ -4,7 +4,7 @@
[![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch) [![Build Status](https://travis-ci.org/philsquared/Catch.svg?branch=master)](https://travis-ci.org/philsquared/Catch)
[![Build status](https://ci.appveyor.com/api/projects/status/hrtk60hv6tw6fght/branch/master?svg=true)](https://ci.appveyor.com/project/philsquared/catch/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/hrtk60hv6tw6fght/branch/master?svg=true)](https://ci.appveyor.com/project/philsquared/catch/branch/master)
<a href="https://github.com/philsquared/Catch/releases/download/v1.9.3/catch.hpp">The latest, single header, version can be downloaded directly using this link</a> <a href="https://github.com/philsquared/Catch/releases/download/v1.9.4/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
## What's the Catch? ## What's the Catch?

View File

@@ -9,7 +9,13 @@ os:
environment: environment:
matrix: matrix:
- additional_flags: "/permissive- /std:c++latest" - additional_flags: "/permissive- /std:c++latest"
wmain: 0
- additional_flags: "" - additional_flags: ""
wmain: 0
- additional_flags: "/D_UNICODE /DUNICODE"
wmain: 1
matrix: matrix:
exclude: exclude:
@@ -42,7 +48,7 @@ configuration:
#Cmake will autodetect the compiler, but we set the arch #Cmake will autodetect the compiler, but we set the arch
before_build: before_build:
- set CXXFLAGS=%additional_flags% - set CXXFLAGS=%additional_flags%
- cmake -H. -BBuild -A%PLATFORM% - cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
# build with MSBuild # build with MSBuild
build: build:

View File

@@ -48,6 +48,7 @@ endfunction()
# Worker function # Worker function
function(ParseFile SourceFile TestTarget) function(ParseFile SourceFile TestTarget)
if(NOT EXISTS ${SourceFile}) if(NOT EXISTS ${SourceFile})
message(WARNING "Cannot find source file: ${SourceFile}")
return() return()
endif() endif()
file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME) file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME)
@@ -111,4 +112,4 @@ function(ParseAndAddCatchTests TestTarget)
foreach(SourceFile ${SourceFiles}) foreach(SourceFile ${SourceFiles})
ParseFile(${SourceFile} ${TestTarget}) ParseFile(${SourceFile} ${TestTarget})
endforeach() endforeach()
endfunction() endfunction()

View File

@@ -1,6 +1,6 @@
# Open Source projects using Catch # Open Source projects using Catch
Catch is great for open source. With it's [liberal license](../LICENSE_1_0.txt) and single-header, dependency-free, distribution Catch is great for open source. With it's [liberal license](../LICENSE.txt) and single-header, dependency-free, distribution
it's easy to just drop the header into your project and start writing tests - what's not to like? it's easy to just drop the header into your project and start writing tests - what's not to like?
As a result Catch is now being used in many Open Source projects, including some quite well known ones. As a result Catch is now being used in many Open Source projects, including some quite well known ones.

View File

@@ -1,3 +1,13 @@
# 1.9.4
### Fixes
* `CATCH_FAIL` macro no longer causes compilation error without variadic macro support
* `INFO` messages are no longer cleared after being reported once
### Improvements and minor changes
* Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined.
* Note that Catch still officially supports only ASCII
# 1.9.3 # 1.9.3
### Fixes ### Fixes

View File

@@ -16,16 +16,7 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function). (where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
You should put this function in the same namespace as your type. You should put this function in the same namespace as your type and it has to be declared before including Catch's header.
Alternatively you may prefer to write it as a member function:
```
std::ostream& T::operator << ( std::ostream& os ) const {
os << convertMyTypeToString( *this );
return os;
}
```
## Catch::toString overload ## Catch::toString overload
@@ -39,11 +30,12 @@ namespace Catch {
} }
``` ```
Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace. Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace and must be declared _before_ Catch's header is included.
**Please note that overloading `Catch::toString` is currently considered legacy and will not be supported in the next major version of Catch.**
## Catch::StringMaker<T> specialisation ## Catch::StringMaker<T> specialisation
Another way of telling Catch how to convert a type to string is specialising `Catch::StringMaker` template. This allows you to have separate way of stringifying types for Catch, than you have for writing it to a stream and also doesn't require you to declare it before including Catch's header.
There are some cases where overloading toString does not work as expected. Specialising StringMaker<T> gives you more precise, and reliable, control - but at the cost of slightly more code and complexity:
``` ```
namespace Catch { namespace Catch {

View File

@@ -136,7 +136,7 @@ LeakDetector leakDetector;
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#else #else

View File

@@ -166,6 +166,32 @@ namespace Catch {
return returnCode; return returnCode;
} }
#if defined(WIN32) && defined(UNICODE)
int run( int argc, wchar_t const* const* const argv ) {
char **utf8Argv = new char *[ argc ];
for ( int i = 0; i < argc; ++i ) {
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
utf8Argv[ i ] = new char[ bufSize ];
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
}
int returnCode = applyCommandLine( argc, utf8Argv );
if( returnCode == 0 )
returnCode = run();
for ( int i = 0; i < argc; ++i )
delete [] utf8Argv[ i ];
delete [] utf8Argv;
return returnCode;
}
#endif
int run() { int run() {
if( m_configData.showHelp ) if( m_configData.showHelp )
return 0; return 0;

View File

@@ -152,7 +152,7 @@
INTERNAL_CATCH_REACT( __catchResult ) \ INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() ) } while( Catch::alwaysFalse() )
#else #else
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
do { \ do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \ __catchResult << log + ::Catch::StreamEndStop(); \

View File

@@ -10,8 +10,14 @@
#ifndef __OBJC__ #ifndef __OBJC__
#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
// Standard C/C++ main entry point // Standard C/C++ main entry point
int main (int argc, char * argv[]) { int main (int argc, char * argv[]) {
#endif
int result = Catch::Session().run( argc, argv ); int result = Catch::Session().run( argc, argv );
return ( result < 0xff ? result : 0xff ); return ( result < 0xff ? result : 0xff );
} }

View File

@@ -145,8 +145,9 @@ namespace Catch {
m_totals.assertions.failed++; m_totals.assertions.failed++;
} }
if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) // We have no use for the return value (whether messages should be cleared), because messages were made scoped
m_messages.clear(); // and should be let to clear themselves out.
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
// Reset working state // Reset working state
m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );

View File

@@ -38,7 +38,7 @@ namespace Catch {
} }
inline Version libraryVersion() { inline Version libraryVersion() {
static Version version( 1, 9, 3, "", 0 ); static Version version( 1, 9, 4, "", 0 );
return version; return version;
} }

View File

@@ -368,7 +368,9 @@ MessageTests.cpp:<line number>: FAILED:
CHECK( a == 0 ) CHECK( a == 0 )
with expansion: with expansion:
2 == 0 2 == 0
with message: with messages:
this message may be logged later
this message should be logged
and this, but later and this, but later
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@@ -119,7 +119,7 @@ with expansion:
MiscTests.cpp:<line number>: MiscTests.cpp:<line number>:
PASSED: PASSED:
REQUIRE( (*__error()) == 1 ) REQUIRE( errno == 1 )
with expansion: with expansion:
1 == 1 1 == 1
@@ -2717,14 +2717,17 @@ MessageTests.cpp:<line number>: FAILED:
CHECK( a == 1 ) CHECK( a == 1 )
with expansion: with expansion:
2 == 1 2 == 1
with message: with messages:
this message may be logged later
this message should be logged this message should be logged
MessageTests.cpp:<line number>: FAILED: MessageTests.cpp:<line number>: FAILED:
CHECK( a == 0 ) CHECK( a == 0 )
with expansion: with expansion:
2 == 0 2 == 0
with message: with messages:
this message may be logged later
this message should be logged
and this, but later and this, but later
MessageTests.cpp:<line number>: MessageTests.cpp:<line number>:
@@ -2732,7 +2735,10 @@ PASSED:
CHECK( a == 2 ) CHECK( a == 2 )
with expansion: with expansion:
2 == 2 2 == 2
with message: with messages:
this message may be logged later
this message should be logged
and this, but later
but not this but not this
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@@ -119,7 +119,7 @@ with expansion:
MiscTests.cpp:<line number>: MiscTests.cpp:<line number>:
PASSED: PASSED:
REQUIRE( (*__error()) == 1 ) REQUIRE( errno == 1 )
with expansion: with expansion:
1 == 1 1 == 1

View File

@@ -237,10 +237,13 @@ MessageTests.cpp:<line number>
</testcase> </testcase>
<testcase classname="global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}"> <testcase classname="global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}">
<failure message="2 == 1" type="CHECK"> <failure message="2 == 1" type="CHECK">
this message may be logged later
this message should be logged this message should be logged
MessageTests.cpp:<line number> MessageTests.cpp:<line number>
</failure> </failure>
<failure message="2 == 0" type="CHECK"> <failure message="2 == 0" type="CHECK">
this message may be logged later
this message should be logged
and this, but later and this, but later
MessageTests.cpp:<line number> MessageTests.cpp:<line number>
</failure> </failure>

View File

@@ -128,7 +128,7 @@
</Expression> </Expression>
<Expression success="true" type="REQUIRE" filename="projects/<exe-name>/MiscTests.cpp" > <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/MiscTests.cpp" >
<Original> <Original>
(*__error()) == 1 errno == 1
</Original> </Original>
<Expanded> <Expanded>
1 == 1 1 == 1
@@ -2744,6 +2744,9 @@
2 == 2 2 == 2
</Expanded> </Expanded>
</Expression> </Expression>
<Info>
this message may be logged later
</Info>
<Info> <Info>
this message should be logged this message should be logged
</Info> </Info>
@@ -2755,6 +2758,12 @@
2 == 1 2 == 1
</Expanded> </Expanded>
</Expression> </Expression>
<Info>
this message may be logged later
</Info>
<Info>
this message should be logged
</Info>
<Info> <Info>
and this, but later and this, but later
</Info> </Info>
@@ -2766,6 +2775,15 @@
2 == 0 2 == 0
</Expanded> </Expanded>
</Expression> </Expression>
<Info>
this message may be logged later
</Info>
<Info>
this message should be logged
</Info>
<Info>
and this, but later
</Info>
<Info> <Info>
but not this but not this
</Info> </Info>

View File

@@ -36,6 +36,13 @@ exeNameParser = re.compile(r'''
# This is a hack until something more reasonable is figured out # This is a hack until something more reasonable is figured out
specialCaseParser = re.compile(r'file\((\d+)\)') specialCaseParser = re.compile(r'file\((\d+)\)')
# errno macro expands into various names depending on platform, so we need to fix them up as well
errnoParser = re.compile(r'''
\(\*__errno_location\ \(\)\)
|
\(\*__error\(\)\)
''', re.VERBOSE)
if len(sys.argv) == 2: if len(sys.argv) == 2:
cmdPath = sys.argv[1] cmdPath = sys.argv[1]
else: else:
@@ -45,9 +52,9 @@ overallResult = 0
def diffFiles(fileA, fileB): def diffFiles(fileA, fileB):
with open(fileA, 'r') as file: with open(fileA, 'r') as file:
aLines = file.readlines() aLines = [line.rstrip() for line in file.readlines()]
with open(fileB, 'r') as file: with open(fileB, 'r') as file:
bLines = file.readlines() bLines = [line.rstrip() for line in file.readlines()]
shortenedFilenameA = fileA.rsplit(os.sep, 1)[-1] shortenedFilenameA = fileA.rsplit(os.sep, 1)[-1]
shortenedFilenameB = fileB.rsplit(os.sep, 1)[-1] shortenedFilenameB = fileB.rsplit(os.sep, 1)[-1]
@@ -90,6 +97,7 @@ def filterLine(line):
line = durationsParser.sub(' time="{duration}"', line) line = durationsParser.sub(' time="{duration}"', line)
line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line) line = timestampsParser.sub(' timestamp="{iso8601-timestamp}"', line)
line = specialCaseParser.sub('file:\g<1>', line) line = specialCaseParser.sub('file:\g<1>', line)
line = errnoParser.sub('errno', line)
return line return line
@@ -119,7 +127,7 @@ def approve(baseName, args):
if os.path.exists(baselinesPath): if os.path.exists(baselinesPath):
diffResult = diffFiles(baselinesPath, filteredResultsPath) diffResult = diffFiles(baselinesPath, filteredResultsPath)
if diffResult: if diffResult:
print(''.join(diffResult)) print('\n'.join(diffResult))
print(" \n****************************\n \033[91mResults differed") print(" \n****************************\n \033[91mResults differed")
if len(diffResult) > overallResult: if len(diffResult) > overallResult:
overallResult = len(diffResult) overallResult = len(diffResult)

View File

@@ -1,6 +1,6 @@
/* /*
* Catch v1.9.3 * Catch v1.9.4
* Generated: 2017-04-25 14:16:29.434734 * Generated: 2017-05-16 13:51:55.506519
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -2272,7 +2272,7 @@ namespace Catch {
INTERNAL_CATCH_REACT( __catchResult ) \ INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() ) } while( Catch::alwaysFalse() )
#else #else
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
do { \ do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \ __catchResult << log + ::Catch::StreamEndStop(); \
@@ -6642,8 +6642,9 @@ namespace Catch {
m_totals.assertions.failed++; m_totals.assertions.failed++;
} }
if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) // We have no use for the return value (whether messages should be cleared), because messages were made scoped
m_messages.clear(); // and should be let to clear themselves out.
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
// Reset working state // Reset working state
m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
@@ -7052,6 +7053,32 @@ namespace Catch {
return returnCode; return returnCode;
} }
#if defined(WIN32) && defined(UNICODE)
int run( int argc, wchar_t const* const* const argv ) {
char **utf8Argv = new char *[ argc ];
for ( int i = 0; i < argc; ++i ) {
int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
utf8Argv[ i ] = new char[ bufSize ];
WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
}
int returnCode = applyCommandLine( argc, utf8Argv );
if( returnCode == 0 )
returnCode = run();
for ( int i = 0; i < argc; ++i )
delete [] utf8Argv[ i ];
delete [] utf8Argv;
return returnCode;
}
#endif
int run() { int run() {
if( m_configData.showHelp ) if( m_configData.showHelp )
return 0; return 0;
@@ -8282,7 +8309,7 @@ namespace Catch {
} }
inline Version libraryVersion() { inline Version libraryVersion() {
static Version version( 1, 9, 3, "", 0 ); static Version version( 1, 9, 4, "", 0 );
return version; return version;
} }
@@ -11268,8 +11295,14 @@ namespace Catch {
#ifndef __OBJC__ #ifndef __OBJC__
#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
// Standard C/C++ main entry point // Standard C/C++ main entry point
int main (int argc, char * argv[]) { int main (int argc, char * argv[]) {
#endif
int result = Catch::Session().run( argc, argv ); int result = Catch::Session().run( argc, argv );
return ( result < 0xff ? result : 0xff ); return ( result < 0xff ? result : 0xff );
} }
@@ -11349,7 +11382,7 @@ int main (int argc, char * const argv[]) {
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#else #else