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