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 #include "catch.hpp"
14
15 #ifdef __clang__
16 #pragma clang diagnostic ignored "-Wc++98-compat"
17 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
18 #endif
19
20 namespace Catch
21 {
22 template<>
toString(const std::pair<int,int> & value)23 std::string toString<std::pair<int, int> >( const std::pair<int, int>& value )
24 {
25 std::ostringstream oss;
26 oss << "std::pair( " << value.first << ", " << value.second << " )";
27 return oss.str();
28
29 }
30 }
31
32 ///////////////////////////////////////////////////////////////////////////////
33 TEST_CASE
34 (
35 "Parsing a std::pair",
36 "[Tricky][std::pair]"
37 )
38 {
39 std::pair<int, int> aNicePair( 1, 2 );
40
41 REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
42 }
43
44 ///////////////////////////////////////////////////////////////////////////////
45 TEST_CASE
46 (
47 "Where there is more to the expression after the RHS",
48 "[Tricky][failing][.]"
49 )
50 {
51 // int a = 1, b = 2;
52 // REQUIRE( a == 2 || b == 2 );
53 WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
54 }
55 ///////////////////////////////////////////////////////////////////////////////
56 TEST_CASE
57 (
58 "Where the LHS is not a simple value",
59 "[Tricky][failing][.]"
60 )
61 {
62 /*
63 int a = 1;
64 int b = 2;
65
66 // This only captures part of the expression, but issues a warning about the rest
67 REQUIRE( a+1 == b-1 );
68 */
69 WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
70 }
71
72 struct Opaque
73 {
74 int val;
operator ==Opaque75 bool operator ==( const Opaque& o ) const
76 {
77 return val == o.val;
78 }
79 };
80
81 ///////////////////////////////////////////////////////////////////////////////
82 TEST_CASE
83 (
84 "A failing expression with a non streamable type is still captured",
85 "[Tricky][failing][.]"
86 )
87 {
88
89 Opaque o1, o2;
90 o1.val = 7;
91 o2.val = 8;
92
93 CHECK( &o1 == &o2 );
94 CHECK( o1 == o2 );
95 }
96
97 ///////////////////////////////////////////////////////////////////////////////
98 TEST_CASE
99 (
100 "string literals of different sizes can be compared",
101 "[Tricky][failing][.]"
102 )
103 {
104 REQUIRE( std::string( "first" ) == "second" );
105
106 }
107
108 ///////////////////////////////////////////////////////////////////////////////
109 TEST_CASE
110 (
111 "An expression with side-effects should only be evaluated once",
112 "[Tricky]"
113 )
114 {
115 int i = 7;
116
117 REQUIRE( i++ == 7 );
118 REQUIRE( i++ == 8 );
119
120 }
121
122 namespace A {
123 struct X
124 {
XA::X125 X() : a(4), b(2), c(7) {}
XA::X126 X(int v) : a(v), b(2), c(7) {}
127 int a;
128 int b;
129 int c;
130 };
131 }
132
133 namespace B {
134 struct Y
135 {
YB::Y136 Y() : a(4), b(2), c(7) {}
YB::Y137 Y(int v) : a(v), b(2), c(7) {}
138 int a;
139 int b;
140 int c;
141 };
142 }
143
operator ==(const A::X & lhs,const B::Y & rhs)144 inline bool operator==(const A::X& lhs, const B::Y& rhs)
145 {
146 return (lhs.a == rhs.a);
147 }
148
operator ==(const B::Y & lhs,const A::X & rhs)149 inline bool operator==(const B::Y& lhs, const A::X& rhs)
150 {
151 return (lhs.a == rhs.a);
152 }
153
154
155 ///////////////////////////////////////////////////////////////////////////////
156 /* This, currently, does not compile with LLVM
157 TEST_CASE
158 (
159 "Operators at different namespace levels not hijacked by Koenig lookup"
160 "[Tricky]"
161 )
162 {
163 A::X x;
164 B::Y y;
165 REQUIRE( x == y );
166 }
167 */
168
169 namespace ObjectWithConversions
170 {
171 struct Object
172 {
operator unsigned intObjectWithConversions::Object173 operator unsigned int() {return 0xc0000000;}
174 };
175
176 ///////////////////////////////////////////////////////////////////////////////
177 TEST_CASE
178 (
179 "Operators at different namespace levels not hijacked by Koenig lookup",
180 "[Tricky]"
181 )
182 {
183 Object o;
184 REQUIRE(0xc0000000 == o );
185 }
186 }
187
188 namespace ObjectWithNonConstEqualityOperator
189 {
190 struct Test
191 {
TestObjectWithNonConstEqualityOperator::Test192 Test( unsigned int v )
193 : m_value(v)
194 {}
195
operator ==ObjectWithNonConstEqualityOperator::Test196 bool operator==( const Test&rhs )
197 {
198 return (m_value == rhs.m_value);
199 }
operator ==ObjectWithNonConstEqualityOperator::Test200 bool operator==( const Test&rhs ) const
201 {
202 return (m_value != rhs.m_value);
203 }
204 unsigned int m_value;
205 };
206
207 TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" )
208 {
209 Test t( 1 );
210 REQUIRE( t == 1u );
211 }
212 }
213
214 namespace EnumBitFieldTests
215 {
216 enum Bits {bit0 = 0x0001, bit1 = 0x0002, bit2 = 0x0004, bit3 = 0x0008, bit1and2 = 0x0006,
217 bit30 = 0x40000000, bit31 = 0x80000000,
218 bit30and31 = 0xc0000000};
219
220 TEST_CASE( "Test enum bit values", "[Tricky]" )
221 {
222 REQUIRE( 0xc0000000 == bit30and31 );
223 }
224 }
225
226 struct Obj
227 {
ObjObj228 Obj():prop(&p){}
229
230 int p;
231 int* prop;
232 };
233
234 TEST_CASE("boolean member", "[Tricky]")
235 {
236 Obj obj;
237 REQUIRE( obj.prop != CATCH_NULL );
238 }
239
240 // Tests for a problem submitted by Ralph McArdell
241 //
242 // The static bool value should not need to be defined outside the
243 // struct it is declared in - but when evaluating it in a deduced
244 // context it appears to require the extra definition.
245 // The issue was fixed by adding bool overloads to bypass the
246 // templates that were there to deduce it.
247 template <bool B>
248 struct is_true
249 {
250 static const bool value = B;
251 };
252
253 TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
254 {
255 SECTION("compare to true","")
256 {
257 REQUIRE( is_true<true>::value == true );
258 REQUIRE( true == is_true<true>::value );
259 }
260 SECTION("compare to false","")
261 {
262 REQUIRE( is_true<false>::value == false );
263 REQUIRE( false == is_true<false>::value );
264 }
265
266 SECTION("negation", "")
267 {
268 REQUIRE( !is_true<false>::value );
269 }
270
271 SECTION("double negation","")
272 {
273 REQUIRE( !!is_true<true>::value );
274 }
275
276 SECTION("direct","")
277 {
278 REQUIRE( is_true<true>::value );
279 REQUIRE_FALSE( is_true<false>::value );
280 }
281 }
282
283 // Uncomment these tests to produce an error at test registration time
284 /*
285 TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
286 {
287
288 }
289 TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
290 {
291
292 }
293 */
294
295 struct Boolable
296 {
BoolableBoolable297 explicit Boolable( bool value ) : m_value( value ) {}
298
operator Catch::SafeBool::typeBoolable299 operator Catch::SafeBool::type() const {
300 return Catch::SafeBool::makeSafe( m_value );
301 }
302
303 bool m_value;
304 };
305
306 TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" )
307 {
308 Boolable True( true );
309 Boolable False( false );
310
311 CHECK( True );
312 CHECK( !False );
313 CHECK_FALSE( False );
314 }
315
316 TEST_CASE( "Assertions then sections", "[Tricky]" )
317 {
318 // This was causing a failure due to the way the console reporter was handling
319 // the current section
320
321 REQUIRE( Catch::alwaysTrue() );
322
323 SECTION( "A section", "" )
324 {
325 REQUIRE( Catch::alwaysTrue() );
326
327 SECTION( "Another section", "" )
328 {
329 REQUIRE( Catch::alwaysTrue() );
330 }
331 SECTION( "Another other section", "" )
332 {
333 REQUIRE( Catch::alwaysTrue() );
334 }
335 }
336 }
337
338 struct Awkward
339 {
operator intAwkward340 operator int() const { return 7; }
341 };
342
343 TEST_CASE( "non streamable - with conv. op", "[Tricky]" )
344 {
345 Awkward awkward;
346 std::string s = Catch::toString( awkward );
347 REQUIRE( s == "7" );
348 }
349
foo()350 inline void foo() {}
351
352 typedef void (*fooptr_t)();
353
354 TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" )
355 {
356 // This was giving a warning in VS2010
357 // #179
358 fooptr_t a = foo;
359
360 REQUIRE( a );
361 REQUIRE( a == &foo );
362 }
363
364 struct S
365 {
fS366 void f() {}
367 };
368
369
370 TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer]" )
371 {
372 typedef void (S::*MF)();
373 MF m = &S::f;
374
375 CHECK( m == &S::f );
376 }
377
378 class ClassName {};
379
380 TEST_CASE( "pointer to class", "[Tricky]" )
381 {
382 ClassName *p = 0;
383 REQUIRE( p == 0 );
384 }
385
386 #ifdef CATCH_CONFIG_CPP11_NULLPTR
387
388 #include <memory>
389
390 TEST_CASE( "null_ptr", "[Tricky][c++11][.]" )
391 {
392 std::unique_ptr<int> ptr;
393 REQUIRE(ptr.get() == nullptr);
394 }
395
396 #endif
397
398 TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); }
399 TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); }
400 TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); }
401 TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); }
402