2010-11-29 20:40:44 +01:00
/*
* Created by Phil on 29 / 11 / 2010.
* Copyright 2010 Two Blue Cubes Ltd . 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)
*/
2012-08-16 19:47:41 +02:00
2011-04-26 09:32:40 +02:00
# include "catch.hpp"
2010-11-29 20:40:44 +01:00
2014-05-19 19:57:14 +02:00
# ifdef __clang__
2015-08-07 09:20:56 +02:00
# pragma clang diagnostic ignored "-Wc++98-compat"
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
2014-05-19 19:57:14 +02:00
# endif
2015-08-07 09:20:56 +02:00
# include <iostream>
2017-03-06 22:07:33 +01:00
# include <cerrno>
2017-07-28 15:11:05 +02:00
# include <limits>
2017-11-07 19:01:10 +01:00
# include <sstream>
2015-08-07 09:20:56 +02:00
2017-11-15 08:48:21 +01:00
namespace { namespace MiscTests {
# ifndef MISC_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
# define MISC_TEST_HELPERS_INCLUDED
inline const char * makeString ( bool makeNull ) {
return makeNull ? nullptr : " valid string " ;
}
inline bool testCheckedIf ( bool flag ) {
CHECKED_IF ( flag )
return true ;
else
return false ;
}
inline bool testCheckedElse ( bool flag ) {
CHECKED_ELSE ( flag )
return false ;
return true ;
}
inline unsigned int Factorial ( unsigned int number ) {
return number > 1 ? Factorial ( number - 1 ) * number : 1 ;
}
static int f ( ) {
return 1 ;
}
inline void manuallyRegisteredTestFunction ( ) {
SUCCEED ( " was called " ) ;
}
struct AutoTestReg {
AutoTestReg ( ) {
REGISTER_TEST_CASE ( manuallyRegisteredTestFunction , " ManuallyRegistered " ) ;
}
} ;
2017-11-29 17:14:33 +01:00
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
2017-11-15 08:48:21 +01:00
static AutoTestReg autoTestReg ;
2017-11-29 17:14:33 +01:00
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
2017-11-15 08:48:21 +01:00
Template tests: added TEMPLATE_PRODUCT_TEST_CASE
support for generating test cases based on multiple template template
types combined with template arguments for each of the template template
types specified
e.g.
```
TEMPLATE_PRODUCT_TEST_CASE("template product","[template]",
(std::tuple, std::pair, std::map),
((int,float),(char,double),(int,char)))
```
will effectively create 9 test cases with types:
std::tuple<int,float>
std::tuple<char,double>
std::tuple<int,char>
std::pair<int,float>
std::pair<char, double>
std::pair<int,char>
std::map<int,float>
std::map<char,double>
std::map<int,char>
Tested type is accessible in test case body as TestType
Unique name is created by appending ` - <index>` to test name
since preprocessor has some limitations in recursions
Closes #1454
2018-12-06 19:27:33 +01:00
template < typename T >
struct Foo {
size_t size ( ) { return 0 ; }
} ;
2017-11-15 08:48:21 +01:00
# endif
2017-07-13 10:20:37 +02:00
TEST_CASE ( " random SECTION tests " , " [.][sections][failing] " ) {
2010-11-29 20:40:44 +01:00
int a = 1 ;
int b = 2 ;
2015-11-04 19:01:28 +01:00
2018-06-25 20:04:29 +02:00
SECTION ( " doesn't equal " ) {
2010-12-14 10:00:09 +01:00
REQUIRE ( a ! = b ) ;
REQUIRE ( b ! = a ) ;
2010-11-29 20:40:44 +01:00
}
2010-11-30 07:48:21 +01:00
2018-06-25 20:04:29 +02:00
SECTION ( " not equal " ) {
2011-02-17 21:15:20 +01:00
REQUIRE ( a ! = b ) ;
2010-11-29 20:40:44 +01:00
}
}
2010-11-30 07:48:21 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " nested SECTION tests " , " [.][sections][failing] " ) {
2010-12-15 20:36:39 +01:00
int a = 1 ;
int b = 2 ;
2015-11-04 19:01:28 +01:00
2018-06-25 20:04:29 +02:00
SECTION ( " doesn't equal " ) {
2010-12-28 18:21:29 +01:00
REQUIRE ( a ! = b ) ;
2010-12-15 20:36:39 +01:00
REQUIRE ( b ! = a ) ;
2018-06-25 20:04:29 +02:00
SECTION ( " not equal " ) {
2011-02-17 21:15:20 +01:00
REQUIRE ( a ! = b ) ;
}
}
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " more nested SECTION tests " , " [sections][failing][.] " ) {
2011-02-17 21:15:20 +01:00
int a = 1 ;
int b = 2 ;
2015-11-04 19:01:28 +01:00
2018-06-25 20:04:29 +02:00
SECTION ( " doesn't equal " ) {
SECTION ( " equal " ) {
2011-02-21 09:50:05 +01:00
REQUIRE ( a = = b ) ;
2011-02-17 21:15:20 +01:00
}
2018-06-25 20:04:29 +02:00
SECTION ( " not equal " ) {
2011-02-21 09:50:05 +01:00
REQUIRE ( a ! = b ) ;
}
2018-06-25 20:04:29 +02:00
SECTION ( " less than " ) {
2011-02-28 09:18:52 +01:00
REQUIRE ( a < b ) ;
2010-12-15 20:36:39 +01:00
}
}
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " even more nested SECTION tests " , " [sections] " ) {
SECTION ( " c " ) {
SECTION ( " d (leaf) " ) {
2018-06-25 20:04:29 +02:00
SUCCEED ( ) ; // avoid failing due to no tests
2012-05-04 08:55:11 +02:00
}
2015-11-04 19:01:28 +01:00
2017-07-13 10:20:37 +02:00
SECTION ( " e (leaf) " ) {
2018-06-25 20:04:29 +02:00
SUCCEED ( ) ; // avoid failing due to no tests
2012-05-04 08:55:11 +02:00
}
}
2017-07-13 10:20:37 +02:00
SECTION ( " f (leaf) " ) {
2018-06-25 20:04:29 +02:00
SUCCEED ( ) ; // avoid failing due to no tests
2012-05-04 08:55:11 +02:00
}
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " looped SECTION tests " , " [.][failing][sections] " ) {
2010-12-28 15:41:57 +01:00
int a = 1 ;
2015-11-04 19:01:28 +01:00
2017-07-13 10:20:37 +02:00
for ( int b = 0 ; b < 10 ; + + b ) {
2018-06-25 20:19:21 +02:00
DYNAMIC_SECTION ( " b is currently: " < < b ) {
2015-11-04 19:01:28 +01:00
CHECK ( b > a ) ;
2010-12-28 15:41:57 +01:00
}
}
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " looped tests " , " [.][failing] " ) {
2010-12-28 15:41:57 +01:00
static const int fib [ ] = { 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 } ;
2015-11-04 19:01:28 +01:00
2017-09-18 18:13:17 +02:00
for ( std : : size_t i = 0 ; i < sizeof ( fib ) / sizeof ( int ) ; + + i ) {
2010-12-28 15:41:57 +01:00
INFO ( " Testing if fib[ " < < i < < " ] ( " < < fib [ i ] < < " ) is even " ) ;
2015-11-04 19:01:28 +01:00
CHECK ( ( fib [ i ] % 2 ) = = 0 ) ;
2010-12-28 15:41:57 +01:00
}
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " Sends stuff to stdout and stderr " , " [.] " ) {
2013-12-19 09:07:33 +01:00
std : : cout < < " A string sent directly to stdout " < < std : : endl ;
std : : cerr < < " A string sent directly to stderr " < < std : : endl ;
2017-12-05 18:48:15 +01:00
std : : clog < < " A string sent to stderr via clog " < < std : : endl ;
2010-12-28 15:41:57 +01:00
}
2011-02-23 21:02:18 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " null strings " ) {
2017-04-25 12:41:30 +02:00
REQUIRE ( makeString ( false ) ! = static_cast < char * > ( nullptr ) ) ;
REQUIRE ( makeString ( true ) = = static_cast < char * > ( nullptr ) ) ;
2011-02-23 21:02:18 +01:00
}
2011-03-09 20:45:05 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " checkedIf " ) {
2012-02-10 09:30:13 +01:00
REQUIRE ( testCheckedIf ( true ) ) ;
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " checkedIf, failing " , " [failing][.] " ) {
2012-02-10 09:30:13 +01:00
REQUIRE ( testCheckedIf ( false ) ) ;
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " checkedElse " ) {
2012-02-10 09:30:13 +01:00
REQUIRE ( testCheckedElse ( true ) ) ;
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " checkedElse, failing " , " [failing][.] " ) {
2012-02-10 09:30:13 +01:00
REQUIRE ( testCheckedElse ( false ) ) ;
}
2012-02-10 19:58:06 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " xmlentitycheck " ) {
2018-06-25 20:04:29 +02:00
SECTION ( " embedded xml: <test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test> " ) {
SUCCEED ( ) ; // We need this here to stop it failing due to no tests
2012-02-10 19:58:06 +01:00
}
2018-06-25 20:04:29 +02:00
SECTION ( " encoded chars: these should all be encoded: &&& \" \" \" <<<& \" <<& \" " ) {
SUCCEED ( ) ; // We need this here to stop it failing due to no tests
2012-02-10 19:58:06 +01:00
}
}
2012-02-28 21:04:25 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " send a single char to INFO " , " [failing][.] " ) {
2012-02-28 21:04:25 +01:00
INFO ( 3 ) ;
2015-11-04 19:01:28 +01:00
REQUIRE ( false ) ;
2012-02-28 21:04:25 +01:00
}
2012-02-29 09:39:22 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " atomic if " , " [failing][0] " ) {
2017-09-18 18:13:17 +02:00
std : : size_t x = 0 ;
2015-11-04 19:01:28 +01:00
2012-02-29 09:39:22 +01:00
if ( x )
REQUIRE ( x > 0 ) ;
else
REQUIRE ( x = = 0 ) ;
}
2012-03-04 12:14:21 +01:00
2012-05-31 20:40:26 +02:00
2013-06-04 09:37:28 +02:00
TEST_CASE ( " Factorials are computed " , " [factorial] " ) {
2012-05-31 20:40:26 +02:00
REQUIRE ( Factorial ( 0 ) = = 1 ) ;
REQUIRE ( Factorial ( 1 ) = = 1 ) ;
REQUIRE ( Factorial ( 2 ) = = 2 ) ;
REQUIRE ( Factorial ( 3 ) = = 6 ) ;
REQUIRE ( Factorial ( 10 ) = = 3628800 ) ;
}
2012-08-31 09:10:36 +02:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " An empty test with no assertions " , " [empty] " ) { }
2012-09-15 18:53:27 +02:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " Nice descriptive name " , " [tag1][tag2][tag3][.] " ) {
2012-09-15 18:53:27 +02:00
WARN ( " This one ran " ) ;
}
2017-07-13 10:20:37 +02:00
TEST_CASE ( " first tag " , " [tag1] " ) { }
TEST_CASE ( " second tag " , " [tag2] " ) { }
2012-10-04 09:19:09 +02:00
//
2013-06-28 17:05:13 +02:00
//TEST_CASE( "spawn a new process", "[.]" )
2012-10-04 09:19:09 +02:00
//{
// // !TBD Work in progress
// char line[200];
// FILE* output = popen("./CatchSelfTest ./failing/matchers/StartsWith", "r");
// while ( fgets(line, 199, output) )
// std::cout << line;
//}
2013-03-25 09:47:36 +01:00
TEST_CASE ( " vectors can be sized and resized " , " [vector] " ) {
std : : vector < int > v ( 5 ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
2015-11-04 19:01:28 +01:00
2017-07-13 10:20:37 +02:00
SECTION ( " resizing bigger changes size and capacity " ) {
2013-03-25 09:47:36 +01:00
v . resize ( 10 ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . size ( ) = = 10 ) ;
REQUIRE ( v . capacity ( ) > = 10 ) ;
}
2017-07-13 10:20:37 +02:00
SECTION ( " resizing smaller changes size but not capacity " ) {
2013-03-25 09:47:36 +01:00
v . resize ( 0 ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . size ( ) = = 0 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
2015-11-04 19:01:28 +01:00
2017-07-13 10:20:37 +02:00
SECTION ( " We can use the 'swap trick' to reset the capacity " ) {
2013-03-25 09:47:36 +01:00
std : : vector < int > empty ;
empty . swap ( v ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . capacity ( ) = = 0 ) ;
}
}
2017-07-13 10:20:37 +02:00
SECTION ( " reserving bigger changes capacity but not size " ) {
2013-03-25 09:47:36 +01:00
v . reserve ( 10 ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 10 ) ;
}
2017-07-13 10:20:37 +02:00
SECTION ( " reserving smaller does not change size or capacity " ) {
2018-11-08 07:26:39 +01:00
v . reserve ( 0 ) ;
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
}
}
TEMPLATE_TEST_CASE ( " TemplateTest: vectors can be sized and resized " , " [vector][template] " , int , float , std : : string , ( std : : tuple < int , float > ) ) {
std : : vector < TestType > v ( 5 ) ;
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
SECTION ( " resizing bigger changes size and capacity " ) {
v . resize ( 10 ) ;
REQUIRE ( v . size ( ) = = 10 ) ;
REQUIRE ( v . capacity ( ) > = 10 ) ;
}
SECTION ( " resizing smaller changes size but not capacity " ) {
v . resize ( 0 ) ;
REQUIRE ( v . size ( ) = = 0 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
SECTION ( " We can use the 'swap trick' to reset the capacity " ) {
std : : vector < TestType > empty ;
empty . swap ( v ) ;
REQUIRE ( v . capacity ( ) = = 0 ) ;
}
}
SECTION ( " reserving bigger changes capacity but not size " ) {
v . reserve ( 10 ) ;
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 10 ) ;
}
SECTION ( " reserving smaller does not change size or capacity " ) {
2013-03-25 09:47:36 +01:00
v . reserve ( 0 ) ;
2015-11-04 19:01:28 +01:00
2013-03-25 09:47:36 +01:00
REQUIRE ( v . size ( ) = = 5 ) ;
REQUIRE ( v . capacity ( ) > = 5 ) ;
}
}
2013-05-13 09:20:45 +02:00
Template tests: added TEMPLATE_PRODUCT_TEST_CASE
support for generating test cases based on multiple template template
types combined with template arguments for each of the template template
types specified
e.g.
```
TEMPLATE_PRODUCT_TEST_CASE("template product","[template]",
(std::tuple, std::pair, std::map),
((int,float),(char,double),(int,char)))
```
will effectively create 9 test cases with types:
std::tuple<int,float>
std::tuple<char,double>
std::tuple<int,char>
std::pair<int,float>
std::pair<char, double>
std::pair<int,char>
std::map<int,float>
std::map<char,double>
std::map<int,char>
Tested type is accessible in test case body as TestType
Unique name is created by appending ` - <index>` to test name
since preprocessor has some limitations in recursions
Closes #1454
2018-12-06 19:27:33 +01:00
TEMPLATE_PRODUCT_TEST_CASE ( " A Template product test case " , " [template][product] " , ( std : : vector , Foo ) , ( int , float ) ) {
TestType x ;
REQUIRE ( x . size ( ) = = 0 ) ;
}
TEMPLATE_PRODUCT_TEST_CASE ( " Product with differing arities " , " [template][product] " , std : : tuple , ( int , ( int , double ) , ( int , double , float ) ) ) {
REQUIRE ( std : : tuple_size < TestType > : : value > = 1 ) ;
}
2013-05-13 09:20:45 +02:00
// https://github.com/philsquared/Catch/issues/166
2017-07-13 10:20:37 +02:00
TEST_CASE ( " A couple of nested sections followed by a failure " , " [failing][.] " ) {
2018-06-25 20:04:29 +02:00
SECTION ( " Outer " )
SECTION ( " Inner " )
2013-07-24 20:13:08 +02:00
SUCCEED ( " that's not flying - that's failing in style " ) ;
FAIL ( " to infinity and beyond " ) ;
}
2014-04-15 19:44:37 +02:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " not allowed " , " [!throws] " ) {
2014-04-15 19:44:37 +02:00
// This test case should not be included if you run with -e on the command line
2018-06-25 20:04:29 +02:00
SUCCEED ( ) ;
2014-04-15 19:44:37 +02:00
}
2014-04-22 09:19:11 +02:00
//TEST_CASE( "Is big endian" ) {
// CHECK( Catch::Detail::Endianness::which() == Catch::Detail::Endianness::Little );
//}
2014-04-23 08:07:27 +02:00
TEST_CASE ( " Tabs and newlines show in output " , " [.][whitespace][failing] " ) {
// Based on issue #242
std : : string s1 = " if ($b == 10) { \n \t \t $a \t = 20; \n } " ;
std : : string s2 = " if ($b == 10) { \n \t $a = 20; \n } \n " ;
CHECK ( s1 = = s2 ) ;
}
2014-08-14 13:28:23 +02:00
2018-03-01 18:41:17 +01:00
# ifdef CATCH_CONFIG_WCHAR
2014-08-14 13:28:23 +02:00
TEST_CASE ( " toString on const wchar_t const pointer returns the string contents " , " [toString] " ) {
2016-08-24 16:38:24 +02:00
const wchar_t * const s = L " wide load " ;
2017-05-02 23:51:03 +02:00
std : : string result = : : Catch : : Detail : : stringify ( s ) ;
2016-08-24 16:38:24 +02:00
CHECK ( result = = " \" wide load \" " ) ;
2014-08-14 13:28:23 +02:00
}
TEST_CASE ( " toString on const wchar_t pointer returns the string contents " , " [toString] " ) {
2016-08-24 16:38:24 +02:00
const wchar_t * s = L " wide load " ;
2017-05-02 23:51:03 +02:00
std : : string result = : : Catch : : Detail : : stringify ( s ) ;
2016-08-24 16:38:24 +02:00
CHECK ( result = = " \" wide load \" " ) ;
2014-08-14 13:28:23 +02:00
}
TEST_CASE ( " toString on wchar_t const pointer returns the string contents " , " [toString] " ) {
2018-05-05 10:39:55 +02:00
auto const s = const_cast < wchar_t * > ( L " wide load " ) ;
2017-05-02 23:51:03 +02:00
std : : string result = : : Catch : : Detail : : stringify ( s ) ;
2016-08-24 16:38:24 +02:00
CHECK ( result = = " \" wide load \" " ) ;
2014-08-14 13:28:23 +02:00
}
TEST_CASE ( " toString on wchar_t returns the string contents " , " [toString] " ) {
2017-12-07 01:02:19 +01:00
auto s = const_cast < wchar_t * > ( L " wide load " ) ;
2017-05-02 23:51:03 +02:00
std : : string result = : : Catch : : Detail : : stringify ( s ) ;
2016-08-24 16:38:24 +02:00
CHECK ( result = = " \" wide load \" " ) ;
2014-08-19 09:16:44 +02:00
}
2018-03-01 18:41:17 +01:00
# endif
2014-08-22 09:07:39 +02:00
2017-07-13 09:52:51 +02:00
TEST_CASE ( " long long " ) {
2015-07-23 20:03:33 +02:00
long long l = std : : numeric_limits < long long > : : max ( ) ;
2015-11-04 19:01:28 +01:00
2015-07-23 20:03:33 +02:00
REQUIRE ( l = = std : : numeric_limits < long long > : : max ( ) ) ;
}
2014-08-22 09:13:15 +02:00
//TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) {
// int i = 0;
// int x = 10/i; // This should cause the signal to fire
// CHECK( x == 0 );
//}
2016-03-14 20:13:34 +01:00
2017-07-13 10:20:37 +02:00
TEST_CASE ( " This test 'should' fail but doesn't " , " [.][failing][!shouldfail] " ) {
2016-03-14 20:13:34 +01:00
SUCCEED ( " oops! " ) ;
}
2016-09-27 11:27:28 +02:00
TEST_CASE ( " # A test name that starts with a # " ) {
SUCCEED ( " yay " ) ;
}
2017-03-06 22:07:33 +01:00
2017-08-11 11:38:29 +02:00
TEST_CASE ( " #835 -- errno should not be touched by Catch " , " [.][failing][!shouldfail] " ) {
2017-03-07 10:17:59 +01:00
errno = 1 ;
CHECK ( f ( ) = = 0 ) ;
2017-05-27 14:42:54 +02:00
REQUIRE ( errno = = 1 ) ; // Check that f() doesn't touch errno.
2017-03-06 22:07:33 +01:00
}
2017-08-10 21:38:07 +02:00
TEST_CASE ( " #961 -- Dynamically created sections should all be reported " , " [.] " ) {
for ( char i = ' 0 ' ; i < ' 5 ' ; + + i ) {
SECTION ( std : : string ( " Looped section " ) + i ) {
SUCCEED ( " Everything is OK " ) ;
}
}
}
2017-11-13 17:03:27 +01:00
2018-02-08 23:18:32 +01:00
TEST_CASE ( " #1175 - Hidden Test " , " [.] " ) {
// Just for checking that hidden test is not listed by default
SUCCEED ( ) ;
}
2017-11-15 08:48:21 +01:00
} } // namespace MiscTests