123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /*
- * Created by Phil on 08/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)
- */
- #ifdef __clang__
- # pragma clang diagnostic push
- # pragma clang diagnostic ignored "-Wpadded"
- // Wdouble-promotion is not supported until 3.8
- # if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7)
- # pragma clang diagnostic ignored "-Wdouble-promotion"
- # endif
- #endif
- #include "catch.hpp"
- #include <string>
- #include <limits>
- #include <cstdint>
- namespace { namespace ConditionTests {
- #ifndef CONDITION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
- #define CONDITION_TEST_HELPERS_INCLUDED
- struct TestData {
- int int_seven = 7;
- std::string str_hello = "hello";
- float float_nine_point_one = 9.1f;
- double double_pi = 3.1415926535;
- };
- struct TestDef {
- TestDef& operator + ( const std::string& ) {
- return *this;
- }
- TestDef& operator[]( const std::string& ) {
- return *this;
- }
- };
- inline const char* returnsConstNull(){ return nullptr; }
- inline char* returnsNull(){ return nullptr; }
- #endif
- // The "failing" tests all use the CHECK macro, which continues if the specific test fails.
- // This allows us to see all results, even if an earlier check fails
- // Equality tests
- TEST_CASE( "Equality checks that should succeed" )
- {
- TestDef td;
- td + "hello" + "hello";
- TestData data;
- REQUIRE( data.int_seven == 7 );
- REQUIRE( data.float_nine_point_one == Approx( 9.1f ) );
- REQUIRE( data.double_pi == Approx( 3.1415926535 ) );
- REQUIRE( data.str_hello == "hello" );
- REQUIRE( "hello" == data.str_hello );
- REQUIRE( data.str_hello.size() == 5 );
- double x = 1.1 + 0.1 + 0.1;
- REQUIRE( x == Approx( 1.3 ) );
- }
- TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
- {
- TestData data;
- CHECK( data.int_seven == 6 );
- CHECK( data.int_seven == 8 );
- CHECK( data.int_seven == 0 );
- CHECK( data.float_nine_point_one == Approx( 9.11f ) );
- CHECK( data.float_nine_point_one == Approx( 9.0f ) );
- CHECK( data.float_nine_point_one == Approx( 1 ) );
- CHECK( data.float_nine_point_one == Approx( 0 ) );
- CHECK( data.double_pi == Approx( 3.1415 ) );
- CHECK( data.str_hello == "goodbye" );
- CHECK( data.str_hello == "hell" );
- CHECK( data.str_hello == "hello1" );
- CHECK( data.str_hello.size() == 6 );
- double x = 1.1 + 0.1 + 0.1;
- CHECK( x == Approx( 1.301 ) );
- }
- TEST_CASE( "Inequality checks that should succeed" )
- {
- TestData data;
- REQUIRE( data.int_seven != 6 );
- REQUIRE( data.int_seven != 8 );
- REQUIRE( data.float_nine_point_one != Approx( 9.11f ) );
- REQUIRE( data.float_nine_point_one != Approx( 9.0f ) );
- REQUIRE( data.float_nine_point_one != Approx( 1 ) );
- REQUIRE( data.float_nine_point_one != Approx( 0 ) );
- REQUIRE( data.double_pi != Approx( 3.1415 ) );
- REQUIRE( data.str_hello != "goodbye" );
- REQUIRE( data.str_hello != "hell" );
- REQUIRE( data.str_hello != "hello1" );
- REQUIRE( data.str_hello.size() != 6 );
- }
- TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" )
- {
- TestData data;
- CHECK( data.int_seven != 7 );
- CHECK( data.float_nine_point_one != Approx( 9.1f ) );
- CHECK( data.double_pi != Approx( 3.1415926535 ) );
- CHECK( data.str_hello != "hello" );
- CHECK( data.str_hello.size() != 5 );
- }
- // Ordering comparison tests
- TEST_CASE( "Ordering comparison checks that should succeed" )
- {
- TestData data;
- REQUIRE( data.int_seven < 8 );
- REQUIRE( data.int_seven > 6 );
- REQUIRE( data.int_seven > 0 );
- REQUIRE( data.int_seven > -1 );
- REQUIRE( data.int_seven >= 7 );
- REQUIRE( data.int_seven >= 6 );
- REQUIRE( data.int_seven <= 7 );
- REQUIRE( data.int_seven <= 8 );
- REQUIRE( data.float_nine_point_one > 9 );
- REQUIRE( data.float_nine_point_one < 10 );
- REQUIRE( data.float_nine_point_one < 9.2 );
- REQUIRE( data.str_hello <= "hello" );
- REQUIRE( data.str_hello >= "hello" );
- REQUIRE( data.str_hello < "hellp" );
- REQUIRE( data.str_hello < "zebra" );
- REQUIRE( data.str_hello > "hellm" );
- REQUIRE( data.str_hello > "a" );
- }
- TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
- {
- TestData data;
- CHECK( data.int_seven > 7 );
- CHECK( data.int_seven < 7 );
- CHECK( data.int_seven > 8 );
- CHECK( data.int_seven < 6 );
- CHECK( data.int_seven < 0 );
- CHECK( data.int_seven < -1 );
- CHECK( data.int_seven >= 8 );
- CHECK( data.int_seven <= 6 );
- CHECK( data.float_nine_point_one < 9 );
- CHECK( data.float_nine_point_one > 10 );
- CHECK( data.float_nine_point_one > 9.2 );
- CHECK( data.str_hello > "hello" );
- CHECK( data.str_hello < "hello" );
- CHECK( data.str_hello > "hellp" );
- CHECK( data.str_hello > "z" );
- CHECK( data.str_hello < "hellm" );
- CHECK( data.str_hello < "a" );
- CHECK( data.str_hello >= "z" );
- CHECK( data.str_hello <= "a" );
- }
- #ifdef __clang__
- # pragma clang diagnostic pop
- #endif
- // Comparisons with int literals
- TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigned" )
- {
- int i = 1;
- unsigned int ui = 2;
- long l = 3;
- unsigned long ul = 4;
- char c = 5;
- unsigned char uc = 6;
- REQUIRE( i == 1 );
- REQUIRE( ui == 2 );
- REQUIRE( l == 3 );
- REQUIRE( ul == 4 );
- REQUIRE( c == 5 );
- REQUIRE( uc == 6 );
- REQUIRE( 1 == i );
- REQUIRE( 2 == ui );
- REQUIRE( 3 == l );
- REQUIRE( 4 == ul );
- REQUIRE( 5 == c );
- REQUIRE( 6 == uc );
- REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul );
- }
- // Disable warnings about sign conversions for the next two tests
- // (as we are deliberately invoking them)
- // - Currently only disabled for GCC/ LLVM. Should add VC++ too
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wsign-compare"
- #pragma GCC diagnostic ignored "-Wsign-conversion"
- #endif
- #ifdef _MSC_VER
- #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
- #endif
- TEST_CASE( "comparisons between int variables" )
- {
- long long_var = 1L;
- unsigned char unsigned_char_var = 1;
- unsigned short unsigned_short_var = 1;
- unsigned int unsigned_int_var = 1;
- unsigned long unsigned_long_var = 1L;
- REQUIRE( long_var == unsigned_char_var );
- REQUIRE( long_var == unsigned_short_var );
- REQUIRE( long_var == unsigned_int_var );
- REQUIRE( long_var == unsigned_long_var );
- }
- TEST_CASE( "comparisons between const int variables" )
- {
- const unsigned char unsigned_char_var = 1;
- const unsigned short unsigned_short_var = 1;
- const unsigned int unsigned_int_var = 1;
- const unsigned long unsigned_long_var = 1L;
- REQUIRE( unsigned_char_var == 1 );
- REQUIRE( unsigned_short_var == 1 );
- REQUIRE( unsigned_int_var == 1 );
- REQUIRE( unsigned_long_var == 1 );
- }
- TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" )
- {
- CHECK( ( -1 > 2u ) );
- CHECK( -1 > 2u );
- CHECK( ( 2u < -1 ) );
- CHECK( 2u < -1 );
- const int minInt = (std::numeric_limits<int>::min)();
- CHECK( ( minInt > 2u ) );
- CHECK( minInt > 2u );
- }
- TEST_CASE( "Comparisons between ints where one side is computed" )
- {
- CHECK( 54 == 6*9 );
- }
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
- TEST_CASE( "Pointers can be compared to null" )
- {
- TestData* p = nullptr;
- TestData* pNULL = nullptr;
- REQUIRE( p == nullptr );
- REQUIRE( p == pNULL );
- TestData data;
- p = &data;
- REQUIRE( p != nullptr );
- const TestData* cp = p;
- REQUIRE( cp != nullptr );
- const TestData* const cpc = p;
- REQUIRE( cpc != nullptr );
- REQUIRE( returnsNull() == nullptr );
- REQUIRE( returnsConstNull() == nullptr );
- REQUIRE( nullptr != p );
- }
- // Not (!) tests
- // The problem with the ! operator is that it has right-to-left associativity.
- // This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore,
- // cannot have the operand value extracted. The test will work correctly, and the situation
- // is detected and a warning issued.
- // An alternative form of the macros (CHECK_FALSE and REQUIRE_FALSE) can be used instead to capture
- // the operand value.
- TEST_CASE( "'Not' checks that should succeed" )
- {
- bool falseValue = false;
- REQUIRE( false == false );
- REQUIRE( true == true );
- REQUIRE( !false );
- REQUIRE_FALSE( false );
- REQUIRE( !falseValue );
- REQUIRE_FALSE( falseValue );
- REQUIRE( !(1 == 2) );
- REQUIRE_FALSE( 1 == 2 );
- }
- TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
- {
- bool trueValue = true;
- CHECK( false != false );
- CHECK( true != true );
- CHECK( !true );
- CHECK_FALSE( true );
- CHECK( !trueValue );
- CHECK_FALSE( trueValue );
- CHECK( !(1 == 1) );
- CHECK_FALSE( 1 == 1 );
- }
- }} // namespace ConditionTests
|