Home | History | Annotate | Download | only in UsageTests
      1 /*
      2  *  Created by Phil on 09/11/2010.
      3  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
      4  *
      5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
      6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      7  */
      8 
      9 #ifdef __clang__
     10 #pragma clang diagnostic ignored "-Wpadded"
     11 #endif
     12 
     13 #ifdef _MSC_VER
     14 #pragma warning (disable : 4702) // Disable unreachable code warning for the last test
     15                                  // that is triggered when compiling as Win32|Release
     16 #endif
     17 
     18 #include "catch.hpp"
     19 
     20 #include <stdio.h>
     21 #include <sstream>
     22 #include <iostream>
     23 
     24 ///////////////////////////////////////////////////////////////////////////////
     25 TEST_CASE
     26 (
     27     "Where there is more to the expression after the RHS",
     28     "[Tricky][failing][.]"
     29 )
     30 {
     31 //    int a = 1, b = 2;
     32 //    REQUIRE( a == 2 || b == 2 );
     33     WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
     34 }
     35 ///////////////////////////////////////////////////////////////////////////////
     36 TEST_CASE
     37 (
     38     "Where the LHS is not a simple value",
     39     "[Tricky][failing][.]"
     40 )
     41 {
     42     /*
     43     int a = 1;
     44     int b = 2;
     45 
     46     // This only captures part of the expression, but issues a warning about the rest
     47     REQUIRE( a+1 == b-1 );
     48     */
     49     WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
     50 }
     51 
     52 struct Opaque
     53 {
     54     int val;
     55     bool operator ==( const Opaque& o ) const
     56     {
     57         return val == o.val;
     58     }
     59 };
     60 
     61 ///////////////////////////////////////////////////////////////////////////////
     62 TEST_CASE
     63 (
     64     "A failing expression with a non streamable type is still captured",
     65     "[Tricky][failing][.]"
     66 )
     67 {
     68 
     69     Opaque o1, o2;
     70     o1.val = 7;
     71     o2.val = 8;
     72 
     73     CHECK( &o1 == &o2 );
     74     CHECK( o1 == o2 );
     75 }
     76 
     77 ///////////////////////////////////////////////////////////////////////////////
     78 TEST_CASE
     79 (
     80     "string literals of different sizes can be compared",
     81     "[Tricky][failing][.]"
     82 )
     83 {
     84     REQUIRE( std::string( "first" ) == "second" );
     85 
     86 }
     87 
     88 ///////////////////////////////////////////////////////////////////////////////
     89 TEST_CASE
     90 (
     91     "An expression with side-effects should only be evaluated once",
     92     "[Tricky]"
     93 )
     94 {
     95     int i = 7;
     96 
     97     REQUIRE( i++ == 7 );
     98     REQUIRE( i++ == 8 );
     99 
    100 }
    101 
    102 namespace A {
    103     struct X
    104     {
    105         X() : a(4), b(2), c(7) {}
    106         X(int v) : a(v), b(2), c(7) {}
    107         int a;
    108         int b;
    109         int c;
    110     };
    111 }
    112 
    113 namespace B {
    114     struct Y
    115     {
    116         Y() : a(4), b(2), c(7) {}
    117         Y(int v) : a(v), b(2), c(7) {}
    118         int a;
    119         int b;
    120         int c;
    121     };
    122 }
    123 
    124 inline bool operator==(const A::X& lhs, const B::Y& rhs)
    125 {
    126     return (lhs.a == rhs.a);
    127 }
    128 
    129 inline bool operator==(const B::Y& lhs, const A::X& rhs)
    130 {
    131     return (lhs.a == rhs.a);
    132 }
    133 
    134 
    135 ///////////////////////////////////////////////////////////////////////////////
    136 /* This, currently, does not compile with LLVM
    137 TEST_CASE
    138 (
    139     "Operators at different namespace levels not hijacked by Koenig lookup"
    140     "[Tricky]"
    141 )
    142 {
    143     A::X x;
    144     B::Y y;
    145     REQUIRE( x == y );
    146 }
    147 */
    148 
    149 namespace ObjectWithConversions
    150 {
    151     struct Object
    152     {
    153         operator unsigned int() const {return 0xc0000000;}
    154     };
    155 
    156     ///////////////////////////////////////////////////////////////////////////////
    157     TEST_CASE
    158     (
    159         "Implicit conversions are supported inside assertion macros",
    160         "[Tricky][approvals]"
    161     )
    162     {
    163         Object o;
    164         REQUIRE(0xc0000000 == o );
    165     }
    166 }
    167 
    168 namespace EnumBitFieldTests
    169 {
    170     enum Bits : uint32_t {
    171         bit0 = 0x0001,
    172         bit1 = 0x0002,
    173         bit2 = 0x0004,
    174         bit3 = 0x0008,
    175         bit1and2 = bit1 | bit2,
    176         bit30 = 0x40000000,
    177         bit31 = 0x80000000,
    178         bit30and31 = bit30 | bit31
    179     };
    180 
    181     TEST_CASE( "Test enum bit values", "[Tricky]" )
    182     {
    183         REQUIRE( 0xc0000000 == bit30and31 );
    184     }
    185 }
    186 
    187 struct Obj
    188 {
    189     Obj():prop(&p){}
    190 
    191     int p;
    192     int* prop;
    193 };
    194 
    195 TEST_CASE("boolean member", "[Tricky]")
    196 {
    197     Obj obj;
    198     REQUIRE( obj.prop != nullptr );
    199 }
    200 
    201 // Tests for a problem submitted by Ralph McArdell
    202 //
    203 // The static bool value should not need to be defined outside the
    204 // struct it is declared in - but when evaluating it in a deduced
    205 // context it appears to require the extra definition.
    206 // The issue was fixed by adding bool overloads to bypass the
    207 // templates that were there to deduce it.
    208 template <bool B>
    209 struct is_true
    210 {
    211     static const bool value = B;
    212 };
    213 
    214 TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
    215 {
    216     SECTION("compare to true")
    217     {
    218         REQUIRE( is_true<true>::value == true );
    219         REQUIRE( true == is_true<true>::value );
    220     }
    221     SECTION("compare to false")
    222     {
    223         REQUIRE( is_true<false>::value == false );
    224         REQUIRE( false == is_true<false>::value );
    225     }
    226 
    227     SECTION("negation")
    228     {
    229         REQUIRE( !is_true<false>::value );
    230     }
    231 
    232     SECTION("double negation")
    233     {
    234         REQUIRE( !!is_true<true>::value );
    235     }
    236 
    237     SECTION("direct")
    238     {
    239         REQUIRE( is_true<true>::value );
    240         REQUIRE_FALSE( is_true<false>::value );
    241     }
    242 }
    243 
    244 // Uncomment these tests to produce an error at test registration time
    245 /*
    246 TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
    247 {
    248 
    249 }
    250 TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
    251 {
    252 
    253 }
    254 */
    255 
    256 struct Boolable
    257 {
    258     explicit Boolable( bool value ) : m_value( value ) {}
    259 
    260     explicit operator bool() const {
    261         return m_value;
    262     }
    263 
    264     bool m_value;
    265 };
    266 
    267 TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" )
    268 {
    269     Boolable True( true );
    270     Boolable False( false );
    271 
    272     CHECK( True );
    273     CHECK( !False );
    274     CHECK_FALSE( False );
    275 }
    276 
    277 TEST_CASE( "Assertions then sections", "[Tricky]" )
    278 {
    279     // This was causing a failure due to the way the console reporter was handling
    280     // the current section
    281 
    282     REQUIRE( true );
    283 
    284     SECTION( "A section" )
    285     {
    286         REQUIRE( true );
    287 
    288         SECTION( "Another section" )
    289         {
    290             REQUIRE( true );
    291         }
    292         SECTION( "Another other section" )
    293         {
    294             REQUIRE( true );
    295         }
    296     }
    297 }
    298 
    299 struct Awkward
    300 {
    301     operator int() const { return 7; }
    302 };
    303 
    304 TEST_CASE( "non streamable - with conv. op", "[Tricky]" )
    305 {
    306     Awkward awkward;
    307     std::string s = ::Catch::Detail::stringify( awkward );
    308     REQUIRE( s == "7" );
    309 }
    310 
    311 inline void foo() {}
    312 
    313 typedef void (*fooptr_t)();
    314 
    315 TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" )
    316 {
    317     // This was giving a warning in VS2010
    318     // #179
    319     fooptr_t a = foo;
    320 
    321     REQUIRE( a );
    322     REQUIRE( a == &foo );
    323 }
    324 
    325 struct S
    326 {
    327     void f() {}
    328 };
    329 
    330 
    331 TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer][approvals]" )
    332 {
    333     typedef void (S::*MF)();
    334     MF m = &S::f;
    335 
    336     CHECK( m == &S::f );
    337 }
    338 
    339 class ClassName {};
    340 
    341 TEST_CASE( "pointer to class", "[Tricky]" )
    342 {
    343    ClassName *p = 0;
    344    REQUIRE( p == 0 );
    345 }
    346 
    347 #include <memory>
    348 
    349 TEST_CASE( "null_ptr", "[Tricky]" )
    350 {
    351     std::unique_ptr<int> ptr;
    352     REQUIRE(ptr.get() == nullptr);
    353 }
    354 
    355 TEST_CASE( "X/level/0/a", "[Tricky]" )      { SUCCEED(""); }
    356 TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); }
    357 TEST_CASE( "X/level/1/a", "[Tricky]" )      { SUCCEED(""); }
    358 TEST_CASE( "X/level/1/b", "[Tricky]" )      { SUCCEED(""); }
    359 
    360 TEST_CASE( "has printf" ) {
    361 
    362     // This can cause problems as, currently, stdout itself is not redirected - only the cout (and cerr) buffer
    363     printf( "loose text artifact\n" );
    364 }
    365 
    366 namespace {
    367 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    368     struct constructor_throws {
    369         [[noreturn]] constructor_throws() {
    370             throw 1;
    371         }
    372     };
    373 #endif
    374 }
    375 
    376 TEST_CASE("Commas in various macros are allowed") {
    377 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
    378     REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} );
    379     CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} );
    380 #endif
    381     REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} );
    382     CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} );
    383 
    384     REQUIRE(std::vector<int>{1, 2} == std::vector<int>{1, 2});
    385     CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} );
    386     REQUIRE_FALSE(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3});
    387     CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} );
    388 
    389     CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} );
    390     CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} ) {
    391         REQUIRE(true);
    392     } CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} ) {
    393         CHECK(true);
    394     }
    395 }
    396 
    397 TEST_CASE( "null deref", "[.][failing][!nonportable]" ) {
    398     CHECK( false );
    399     int *x = NULL;
    400     *x = 1;
    401 }
    402 
    403 TEST_CASE( "non-copyable objects", "[.][failing]" ) {
    404 #if CHECK_CONFIG_USE_RTTI
    405     // Thanks to Agustin Berg (@k-ballo on the cpplang Slack) for raising this
    406     std::type_info const& ti = typeid(int);
    407     CHECK( ti == typeid(int) );
    408 #endif
    409 }
    410 
    411 // #925
    412 using signal_t = void (*) (void*);
    413 
    414 struct TestClass {
    415     signal_t testMethod_uponComplete_arg = nullptr;
    416 };
    417 
    418 namespace utility {
    419     inline static void synchronizing_callback( void * ) { }
    420 }
    421 
    422 TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
    423 
    424     TestClass test;
    425     REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
    426 }
    427 
    428 TEST_CASE( "Bitfields can be captured (#1027)" ) {
    429     struct Y {
    430         uint32_t v : 1;
    431     };
    432     Y y{ 0 };
    433     REQUIRE( y.v == 0 );
    434     REQUIRE( 0 == y.v );
    435 }
    436 
    437 TEST_CASE("#1514: stderr/stdout is not captured in tests aborted by an exception", "[output-capture][regression][.]") {
    438     std::cout << "This would not be caught previously\n" << std::flush;
    439     std::clog << "Nor would this\n" << std::flush;
    440     // FAIL aborts the test by throwing a Catch exception
    441     FAIL("1514");
    442 }
    443