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