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 #include "catch.hpp"
10 #include <iostream>
11 
12 TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" ) {
13     INFO( "this is a " << "message" );    // This should output the message if a failure occurs
14     WARN( "this is a " << "warning" );    // This should always output the message but then continue
15 }
16 
17 TEST_CASE( "#1455 - INFO and WARN can start with a linebreak", "[messages][.]" ) {
18     // Previously these would be hidden from the console reporter output,
19     // because it would fail at properly reflowing the text
20     INFO( "\nThis info message starts with a linebreak" );
21     WARN( "\nThis warning message starts with a linebreak" );
22 }
23 
24 TEST_CASE( "SUCCEED counts as a test pass", "[messages]" ) {
25     SUCCEED( "this is a " << "success" );
26 }
27 
28 TEST_CASE( "INFO gets logged on failure", "[failing][messages][.]" ) {
29     INFO( "this message should be logged" );
30     INFO( "so should this" );
31     int a = 2;
32     REQUIRE( a == 1 );
33 }
34 
35 TEST_CASE( "INFO gets logged on failure, even if captured before successful assertions", "[failing][messages][.]" ) {
36     INFO( "this message may be logged later" );
37     int a = 2;
38     CHECK( a == 2 );
39 
40     INFO( "this message should be logged" );
41 
42     CHECK( a == 1 );
43 
44     INFO( "and this, but later" );
45 
46     CHECK( a == 0 );
47 
48     INFO( "but not this" );
49 
50     CHECK( a == 2 );
51 }
52 
53 TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" ) {
54     FAIL( "This is a " << "failure" );    // This should output the message and abort
55     WARN( "We should never see this");
56 }
57 
58 TEST_CASE( "FAIL_CHECK does not abort the test", "[failing][messages][.]" ) {
59     FAIL_CHECK( "This is a " << "failure" );    // This should output the message then continue
60     WARN( "This message appears in the output");
61 }
62 
63 TEST_CASE( "FAIL does not require an argument", "[failing][messages][.]" ) {
64     FAIL();
65 }
66 
67 TEST_CASE( "SUCCEED does not require an argument", "[messages][.]" ) {
68    SUCCEED();
69 }
70 
71 TEST_CASE( "Output from all sections is reported", "[failing][messages][.]" ) {
72     SECTION( "one" ) {
73         FAIL( "Message from section one" );
74     }
75 
76     SECTION( "two" ) {
77         FAIL( "Message from section two" );
78     }
79 }
80 
81 TEST_CASE( "Standard output from all sections is reported", "[messages][.]" ) {
82     SECTION( "one" ) {
83         std::cout << "Message from section one" << std::endl;
84     }
85 
86     SECTION( "two" ) {
87         std::cout << "Message from section two" << std::endl;
88     }
89 }
90 
91 TEST_CASE( "Standard error is reported and redirected", "[messages][.][approvals]" ) {
92     SECTION( "std::cerr" ) {
93         std::cerr << "Write to std::cerr" << std::endl;
94     }
95     SECTION( "std::clog" ) {
96         std::clog << "Write to std::clog" << std::endl;
97     }
98     SECTION( "Interleaved writes to cerr and clog" ) {
99         std::cerr << "Inter";
100         std::clog << "leaved";
101         std::cerr << ' ';
102         std::clog << "writes";
103         std::cerr << " to error";
104         std::clog << " streams" << std::endl;
105     }
106 }
107 
108 TEST_CASE( "INFO is reset for each loop", "[messages][failing][.]" ) {
109     for( int i=0; i<100; i++ )
110     {
111         INFO( "current counter " << i );
112         CAPTURE( i );
113         REQUIRE( i < 10 );
114     }
115 }
116 
117 TEST_CASE( "The NO_FAIL macro reports a failure but does not fail the test", "[messages]" ) {
118     CHECK_NOFAIL( 1 == 2 );
119 }
120 
121 TEST_CASE( "just info", "[info][isolated info][messages]" ) {
122     INFO( "this should never be seen" );
123 }
124 TEST_CASE( "just failure", "[fail][isolated info][.][messages]" ) {
125     FAIL( "Previous info should not be seen" );
126 }
127 
128 
129 TEST_CASE( "sends information to INFO", "[.][failing]" ) {
130     INFO( "hi" );
131     int i = 7;
132     CAPTURE( i );
133     REQUIRE( false );
134 }
135 
136 TEST_CASE( "Pointers can be converted to strings", "[messages][.][approvals]" ) {
137     int p;
138     WARN( "actual address of p: " << &p );
139     WARN( "toString(p): " << ::Catch::Detail::stringify( &p ) );
140 }
141 
142 template <typename T>
unscoped_info(T msg)143 static void unscoped_info( T msg ) {
144     UNSCOPED_INFO( msg );
145 }
146 
147 TEST_CASE( "just unscoped info", "[unscoped][info]" ) {
148     unscoped_info( "this should NOT be seen" );
149     unscoped_info( "this also should NOT be seen" );
150 }
151 
152 TEST_CASE( "just failure after unscoped info", "[failing][.][unscoped][info]" ) {
153     FAIL( "previous unscoped info SHOULD not be seen" );
154 }
155 
156 TEST_CASE( "print unscoped info if passing unscoped info is printed", "[unscoped][info]" ) {
157     unscoped_info( "this MAY be seen IF info is printed for passing assertions" );
158     REQUIRE( true );
159 }
160 
161 TEST_CASE( "prints unscoped info on failure", "[failing][.][unscoped][info]" ) {
162     unscoped_info( "this SHOULD be seen" );
163     unscoped_info( "this SHOULD also be seen" );
164     REQUIRE( false );
165     unscoped_info( "but this should NOT be seen" );
166 }
167 
168 TEST_CASE( "not prints unscoped info from previous failures", "[failing][.][unscoped][info]" ) {
169     unscoped_info( "this MAY be seen only for the FIRST assertion IF info is printed for passing assertions" );
170     REQUIRE( true );
171     unscoped_info( "this MAY be seen only for the SECOND assertion IF info is printed for passing assertions" );
172     REQUIRE( true );
173     unscoped_info( "this SHOULD be seen" );
174     REQUIRE( false );
175 }
176 
177 TEST_CASE( "prints unscoped info only for the first assertion", "[failing][.][unscoped][info]" ) {
178     unscoped_info( "this SHOULD be seen only ONCE" );
179     CHECK( false );
180     CHECK( true );
181     unscoped_info( "this MAY also be seen only ONCE IF info is printed for passing assertions" );
182     CHECK( true );
183     CHECK( true );
184 }
185 
186 TEST_CASE( "stacks unscoped info in loops", "[failing][.][unscoped][info]" ) {
187     UNSCOPED_INFO("Count 1 to 3...");
188     for (int i = 1; i <= 3; i++) {
189         unscoped_info(i);
190     }
191     CHECK( false );
192 
193     UNSCOPED_INFO("Count 4 to 6...");
194     for (int i = 4; i <= 6; i++) {
195         unscoped_info(i);
196     }
197     CHECK( false );
198 }
199 
200 TEST_CASE( "mix info, unscoped info and warning", "[unscoped][info]" ) {
201     INFO("info");
202     unscoped_info("unscoped info");
203     WARN("and warn may mix");
204     WARN("they are not cleared after warnings");
205 }
206 
207 TEST_CASE( "CAPTURE can deal with complex expressions", "[messages][capture]" ) {
208     int a = 1;
209     int b = 2;
210     int c = 3;
211     CAPTURE( a, b, c, a + b, a+b, c > b, a == 1 );
212     SUCCEED();
213 }
214 
215 #ifdef __clang__
216 #pragma clang diagnostic push
217 #pragma clang diagnostic ignored "-Wunused-value" // In (1, 2), the "1" is unused ...
218 #endif
219 #ifdef __GNUC__
220 #pragma GCC diagnostic push
221 #pragma GCC diagnostic ignored "-Wunused-value" // All the comma operators are side-effect free
222 #endif
223 #ifdef _MSC_VER
224 #pragma warning(push)
225 #pragma warning(disable:4709) // comma in indexing operator
226 #endif
227 
228 template <typename T1, typename T2>
229 struct helper_1436 {
helper_1436helper_1436230     helper_1436(T1 t1_, T2 t2_):
231         t1{ t1_ },
232         t2{ t2_ }
233     {}
234     T1 t1;
235     T2 t2;
236 };
237 
238 template <typename T1, typename T2>
operator <<(std::ostream & out,helper_1436<T1,T2> const & helper)239 std::ostream& operator<<(std::ostream& out, helper_1436<T1, T2> const& helper) {
240     out << "{ " << helper.t1 << ", " << helper.t2 << " }";
241     return out;
242 }
243 
244 TEST_CASE("CAPTURE can deal with complex expressions involving commas", "[messages][capture]") {
245     CAPTURE(std::vector<int>{1, 2, 3}[0, 1, 2],
246             std::vector<int>{1, 2, 3}[(0, 1)],
247             std::vector<int>{1, 2, 3}[0]);
248     CAPTURE((helper_1436<int, int>{12, -12}),
249             (helper_1436<int, int>(-12, 12)));
250     CAPTURE( (1, 2), (2, 3) );
251     SUCCEED();
252 }
253 
254 TEST_CASE("CAPTURE parses string and character constants", "[messages][capture]") {
255     CAPTURE(("comma, in string", "escaped, \", "), "single quote in string,',", "some escapes, \\,\\\\");
256     CAPTURE("some, ), unmatched, } prenheses {[<");
257     CAPTURE('"', '\'', ',', '}', ')', '(', '{');
258     SUCCEED();
259 }
260 
261 #ifdef __clang__
262 #pragma clang diagnostic pop
263 #endif
264 #ifdef __GNUC__
265 #pragma GCC diagnostic pop
266 #endif
267 #ifdef _MSC_VER
268 #pragma warning(pop)
269 #endif
270