Condition.tests.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Created by Phil on 08/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. #ifdef __clang__
  9. # pragma clang diagnostic push
  10. # pragma clang diagnostic ignored "-Wpadded"
  11. // Wdouble-promotion is not supported until 3.8
  12. # if (__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ > 7)
  13. # pragma clang diagnostic ignored "-Wdouble-promotion"
  14. # endif
  15. #endif
  16. #include "catch.hpp"
  17. #include <string>
  18. #include <limits>
  19. #include <cstdint>
  20. namespace { namespace ConditionTests {
  21. #ifndef CONDITION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
  22. #define CONDITION_TEST_HELPERS_INCLUDED
  23. struct TestData {
  24. int int_seven = 7;
  25. std::string str_hello = "hello";
  26. float float_nine_point_one = 9.1f;
  27. double double_pi = 3.1415926535;
  28. };
  29. struct TestDef {
  30. TestDef& operator + ( const std::string& ) {
  31. return *this;
  32. }
  33. TestDef& operator[]( const std::string& ) {
  34. return *this;
  35. }
  36. };
  37. inline const char* returnsConstNull(){ return nullptr; }
  38. inline char* returnsNull(){ return nullptr; }
  39. #endif
  40. // The "failing" tests all use the CHECK macro, which continues if the specific test fails.
  41. // This allows us to see all results, even if an earlier check fails
  42. // Equality tests
  43. TEST_CASE( "Equality checks that should succeed" )
  44. {
  45. TestDef td;
  46. td + "hello" + "hello";
  47. TestData data;
  48. REQUIRE( data.int_seven == 7 );
  49. REQUIRE( data.float_nine_point_one == Approx( 9.1f ) );
  50. REQUIRE( data.double_pi == Approx( 3.1415926535 ) );
  51. REQUIRE( data.str_hello == "hello" );
  52. REQUIRE( "hello" == data.str_hello );
  53. REQUIRE( data.str_hello.size() == 5 );
  54. double x = 1.1 + 0.1 + 0.1;
  55. REQUIRE( x == Approx( 1.3 ) );
  56. }
  57. TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
  58. {
  59. TestData data;
  60. CHECK( data.int_seven == 6 );
  61. CHECK( data.int_seven == 8 );
  62. CHECK( data.int_seven == 0 );
  63. CHECK( data.float_nine_point_one == Approx( 9.11f ) );
  64. CHECK( data.float_nine_point_one == Approx( 9.0f ) );
  65. CHECK( data.float_nine_point_one == Approx( 1 ) );
  66. CHECK( data.float_nine_point_one == Approx( 0 ) );
  67. CHECK( data.double_pi == Approx( 3.1415 ) );
  68. CHECK( data.str_hello == "goodbye" );
  69. CHECK( data.str_hello == "hell" );
  70. CHECK( data.str_hello == "hello1" );
  71. CHECK( data.str_hello.size() == 6 );
  72. double x = 1.1 + 0.1 + 0.1;
  73. CHECK( x == Approx( 1.301 ) );
  74. }
  75. TEST_CASE( "Inequality checks that should succeed" )
  76. {
  77. TestData data;
  78. REQUIRE( data.int_seven != 6 );
  79. REQUIRE( data.int_seven != 8 );
  80. REQUIRE( data.float_nine_point_one != Approx( 9.11f ) );
  81. REQUIRE( data.float_nine_point_one != Approx( 9.0f ) );
  82. REQUIRE( data.float_nine_point_one != Approx( 1 ) );
  83. REQUIRE( data.float_nine_point_one != Approx( 0 ) );
  84. REQUIRE( data.double_pi != Approx( 3.1415 ) );
  85. REQUIRE( data.str_hello != "goodbye" );
  86. REQUIRE( data.str_hello != "hell" );
  87. REQUIRE( data.str_hello != "hello1" );
  88. REQUIRE( data.str_hello.size() != 6 );
  89. }
  90. TEST_CASE( "Inequality checks that should fail", "[.][failing][!shouldfail]" )
  91. {
  92. TestData data;
  93. CHECK( data.int_seven != 7 );
  94. CHECK( data.float_nine_point_one != Approx( 9.1f ) );
  95. CHECK( data.double_pi != Approx( 3.1415926535 ) );
  96. CHECK( data.str_hello != "hello" );
  97. CHECK( data.str_hello.size() != 5 );
  98. }
  99. // Ordering comparison tests
  100. TEST_CASE( "Ordering comparison checks that should succeed" )
  101. {
  102. TestData data;
  103. REQUIRE( data.int_seven < 8 );
  104. REQUIRE( data.int_seven > 6 );
  105. REQUIRE( data.int_seven > 0 );
  106. REQUIRE( data.int_seven > -1 );
  107. REQUIRE( data.int_seven >= 7 );
  108. REQUIRE( data.int_seven >= 6 );
  109. REQUIRE( data.int_seven <= 7 );
  110. REQUIRE( data.int_seven <= 8 );
  111. REQUIRE( data.float_nine_point_one > 9 );
  112. REQUIRE( data.float_nine_point_one < 10 );
  113. REQUIRE( data.float_nine_point_one < 9.2 );
  114. REQUIRE( data.str_hello <= "hello" );
  115. REQUIRE( data.str_hello >= "hello" );
  116. REQUIRE( data.str_hello < "hellp" );
  117. REQUIRE( data.str_hello < "zebra" );
  118. REQUIRE( data.str_hello > "hellm" );
  119. REQUIRE( data.str_hello > "a" );
  120. }
  121. TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
  122. {
  123. TestData data;
  124. CHECK( data.int_seven > 7 );
  125. CHECK( data.int_seven < 7 );
  126. CHECK( data.int_seven > 8 );
  127. CHECK( data.int_seven < 6 );
  128. CHECK( data.int_seven < 0 );
  129. CHECK( data.int_seven < -1 );
  130. CHECK( data.int_seven >= 8 );
  131. CHECK( data.int_seven <= 6 );
  132. CHECK( data.float_nine_point_one < 9 );
  133. CHECK( data.float_nine_point_one > 10 );
  134. CHECK( data.float_nine_point_one > 9.2 );
  135. CHECK( data.str_hello > "hello" );
  136. CHECK( data.str_hello < "hello" );
  137. CHECK( data.str_hello > "hellp" );
  138. CHECK( data.str_hello > "z" );
  139. CHECK( data.str_hello < "hellm" );
  140. CHECK( data.str_hello < "a" );
  141. CHECK( data.str_hello >= "z" );
  142. CHECK( data.str_hello <= "a" );
  143. }
  144. #ifdef __clang__
  145. # pragma clang diagnostic pop
  146. #endif
  147. // Comparisons with int literals
  148. TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigned" )
  149. {
  150. int i = 1;
  151. unsigned int ui = 2;
  152. long l = 3;
  153. unsigned long ul = 4;
  154. char c = 5;
  155. unsigned char uc = 6;
  156. REQUIRE( i == 1 );
  157. REQUIRE( ui == 2 );
  158. REQUIRE( l == 3 );
  159. REQUIRE( ul == 4 );
  160. REQUIRE( c == 5 );
  161. REQUIRE( uc == 6 );
  162. REQUIRE( 1 == i );
  163. REQUIRE( 2 == ui );
  164. REQUIRE( 3 == l );
  165. REQUIRE( 4 == ul );
  166. REQUIRE( 5 == c );
  167. REQUIRE( 6 == uc );
  168. REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul );
  169. }
  170. // Disable warnings about sign conversions for the next two tests
  171. // (as we are deliberately invoking them)
  172. // - Currently only disabled for GCC/ LLVM. Should add VC++ too
  173. #ifdef __GNUC__
  174. #pragma GCC diagnostic push
  175. #pragma GCC diagnostic ignored "-Wsign-compare"
  176. #pragma GCC diagnostic ignored "-Wsign-conversion"
  177. #endif
  178. #ifdef _MSC_VER
  179. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  180. #endif
  181. TEST_CASE( "comparisons between int variables" )
  182. {
  183. long long_var = 1L;
  184. unsigned char unsigned_char_var = 1;
  185. unsigned short unsigned_short_var = 1;
  186. unsigned int unsigned_int_var = 1;
  187. unsigned long unsigned_long_var = 1L;
  188. REQUIRE( long_var == unsigned_char_var );
  189. REQUIRE( long_var == unsigned_short_var );
  190. REQUIRE( long_var == unsigned_int_var );
  191. REQUIRE( long_var == unsigned_long_var );
  192. }
  193. TEST_CASE( "comparisons between const int variables" )
  194. {
  195. const unsigned char unsigned_char_var = 1;
  196. const unsigned short unsigned_short_var = 1;
  197. const unsigned int unsigned_int_var = 1;
  198. const unsigned long unsigned_long_var = 1L;
  199. REQUIRE( unsigned_char_var == 1 );
  200. REQUIRE( unsigned_short_var == 1 );
  201. REQUIRE( unsigned_int_var == 1 );
  202. REQUIRE( unsigned_long_var == 1 );
  203. }
  204. TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" )
  205. {
  206. CHECK( ( -1 > 2u ) );
  207. CHECK( -1 > 2u );
  208. CHECK( ( 2u < -1 ) );
  209. CHECK( 2u < -1 );
  210. const int minInt = (std::numeric_limits<int>::min)();
  211. CHECK( ( minInt > 2u ) );
  212. CHECK( minInt > 2u );
  213. }
  214. TEST_CASE( "Comparisons between ints where one side is computed" )
  215. {
  216. CHECK( 54 == 6*9 );
  217. }
  218. #ifdef __GNUC__
  219. #pragma GCC diagnostic pop
  220. #endif
  221. TEST_CASE( "Pointers can be compared to null" )
  222. {
  223. TestData* p = nullptr;
  224. TestData* pNULL = nullptr;
  225. REQUIRE( p == nullptr );
  226. REQUIRE( p == pNULL );
  227. TestData data;
  228. p = &data;
  229. REQUIRE( p != nullptr );
  230. const TestData* cp = p;
  231. REQUIRE( cp != nullptr );
  232. const TestData* const cpc = p;
  233. REQUIRE( cpc != nullptr );
  234. REQUIRE( returnsNull() == nullptr );
  235. REQUIRE( returnsConstNull() == nullptr );
  236. REQUIRE( nullptr != p );
  237. }
  238. // Not (!) tests
  239. // The problem with the ! operator is that it has right-to-left associativity.
  240. // This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore,
  241. // cannot have the operand value extracted. The test will work correctly, and the situation
  242. // is detected and a warning issued.
  243. // An alternative form of the macros (CHECK_FALSE and REQUIRE_FALSE) can be used instead to capture
  244. // the operand value.
  245. TEST_CASE( "'Not' checks that should succeed" )
  246. {
  247. bool falseValue = false;
  248. REQUIRE( false == false );
  249. REQUIRE( true == true );
  250. REQUIRE( !false );
  251. REQUIRE_FALSE( false );
  252. REQUIRE( !falseValue );
  253. REQUIRE_FALSE( falseValue );
  254. REQUIRE( !(1 == 2) );
  255. REQUIRE_FALSE( 1 == 2 );
  256. }
  257. TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
  258. {
  259. bool trueValue = true;
  260. CHECK( false != false );
  261. CHECK( true != true );
  262. CHECK( !true );
  263. CHECK_FALSE( true );
  264. CHECK( !trueValue );
  265. CHECK_FALSE( trueValue );
  266. CHECK( !(1 == 1) );
  267. CHECK_FALSE( 1 == 1 );
  268. }
  269. }} // namespace ConditionTests