1 // Copyright 2013 by Martin Moene
2 //
3 // Distributed under the Boost Software License, Version 1.0:
4 //
5 // Permission is hereby granted, free of charge, to any person or organization
6 // obtaining a copy of the software and accompanying documentation covered by
7 // this license (the "Software") to use, reproduce, display, distribute,
8 // execute, and transmit the Software, and to prepare derivative works of the
9 // Software, and to permit third-parties to whom the Software is furnished to
10 // do so, all subject to the following:
11 //
12 // The copyright notices in the Software and this entire statement, including
13 // the above license grant, this restriction and the following disclaimer,
14 // must be included in all copies of the Software, in whole or in part, and
15 // all derivative works of the Software, unless such copies or derivative
16 // works are solely in the form of machine-executable object code generated by
17 // a source language processor.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 
27 #include "lest.hpp"
28 #include <sstream>
29 
30 using namespace lest;
31 
32 const lest::test specification[] =
33 {
34     "Function to suppress warning \"expression has no effect\" acts as identity function", []
__anon471d1f570102null35     {
36         EXPECT( false == serum( false ) );
37         EXPECT(  true == serum( true  ) );
38     },
39 
40     "Function with_message() returns correct string", []
__anon471d1f570202null41     {
42         std::string msg = "Let writing tests become irresistibly easy and attractive.";
43         EXPECT( "with message \"" + msg + "\"" == with_message( msg ) );
44     },
45 
46     "Function of_type() returns correct string", []
__anon471d1f570302null47     {
48         std::string msg = "this_type";
49         EXPECT( "of type " + msg == of_type( msg ) );
50     },
51 
52     "Function pluralise() adds 's' except for 1 item", []
__anon471d1f570402null53     {
54         std::string word = "hammer";
55         EXPECT( word == pluralise( 1, word ) );
56         for ( auto i : {0,2,3,4,5,6,7,8,9,10,11,12} )
57             EXPECT( word + "s" == pluralise( i, word ) );
58     },
59 
60     "Location constructs properly", []
__anon471d1f570502null61     {
62         char const * file = __FILE__; int line = __LINE__;
63         location where{ file, line };
64         EXPECT( file == where.file );
65         EXPECT( line == where.line );
66     },
67 
68     "Comment constructs properly", []
__anon471d1f570602null69     {
70         std::string text = __FILE__;
71         comment note = text;
72         EXPECT( text == note.text );
73     },
74 
75     "Comment converted to bool indicates absence or presence of comment", []
__anon471d1f570702null76     {
77         EXPECT( false == bool( comment( "") ) );
78         EXPECT(  true == bool( comment("x") ) );
79     },
80 
81     "Failure exception type constructs and prints properly", []
__anon471d1f570802null82     {
83         std::string name = "test-name";
84         failure msg( location{"filename.cpp", 765}, "expression" );
85 
86         std::ostringstream os;
87         report( os, msg, name );
88 
89 #ifndef __GNUG__
90         EXPECT( os.str() == "filename.cpp(765): failed: test-name: expression\n" );
91 #else
92         EXPECT( os.str() == "filename.cpp:765: failed: test-name: expression\n" );
93 #endif
94     },
95 
96     "Expected exception type constructs and prints properly", []
__anon471d1f570902null97     {
98         std::string name = "test-name";
99         expected msg( location{"filename.cpp", 765}, "expression" );
100 
101         std::ostringstream os;
102         report( os, msg, name );
103 
104 #ifndef __GNUG__
105         EXPECT( os.str() == "filename.cpp(765): failed: didn't get exception: test-name: expression\n" );
106 #else
107         EXPECT( os.str() == "filename.cpp:765: failed: didn't get exception: test-name: expression\n" );
108 #endif
109     },
110 
111     "Unexpected exception type constructs and prints properly", []
__anon471d1f570a02null112     {
113         std::string name = "test-name";
114         unexpected msg( location{"filename.cpp", 765}, "expression", "exception-type" );
115 
116         std::ostringstream os;
117         report( os, msg, name );
118 
119 #ifndef __GNUG__
120         EXPECT( os.str() == "filename.cpp(765): failed: got unexpected exception exception-type: test-name: expression\n" );
121 #else
122         EXPECT( os.str() == "filename.cpp:765: failed: got unexpected exception exception-type: test-name: expression\n" );
123 #endif
124     },
125 
126     "Expect generates no message exception for a succeeding test", []
__anon471d1f570b02null127     {
128         test pass = { "P", [] { EXPECT( true  ); } };
129 
130         try { pass.behaviour(); }
131         catch(...) { throw failure(location{__FILE__,__LINE__}, "unexpected error generated"); }
132     },
133 
134     "Expect generates a message exception for a failing test", []
__anon471d1f570d02null135     {
136         test fail = { "F", [] { EXPECT( false ); } };
137 
138         for (;;)
139         {
140             try { fail.behaviour(); } catch ( message & ) { break; }
141             throw failure(location{__FILE__,__LINE__}, "no error generated");
142         }
143     },
144 
145     "Expect succeeds for success (true) and failure (false)", []
__anon471d1f570f02null146     {
147         test pass[] = {{ "P", [] { EXPECT( true  ); } }};
148         test fail[] = {{ "F", [] { EXPECT( false ); } }};
149 
150         std::ostringstream os;
151 
152         EXPECT( 0 == run( pass, os ) );
153         EXPECT( 1 == run( fail, os ) );
154     },
155 
156     "Expect succeeds for integer comparation", []
__anon471d1f571202null157     {
158         test pass  [] = {{ "P" , [] { EXPECT( 7 == 7 ); EXPECT( 7 != 8 );
159                                         EXPECT( 7 >= 6 ); EXPECT( 7 <= 8 );
160                                         EXPECT( 7 >  6 ); EXPECT( 7 <  8 ); } }};
161         test fail_1[] = {{ "F1", [] { EXPECT( 7 == 8 ); } }};
162         test fail_2[] = {{ "F2", [] { EXPECT( 7 != 7 ); } }};
163         test fail_3[] = {{ "F3", [] { EXPECT( 7 <= 6 ); } }};
164         test fail_4[] = {{ "F4", [] { EXPECT( 7 >= 8 ); } }};
165         test fail_5[] = {{ "F5", [] { EXPECT( 7 <  6 ); } }};
166         test fail_6[] = {{ "F6", [] { EXPECT( 7 >  8 ); } }};
167 
168         std::ostringstream os;
169 
170         EXPECT( 0 == run( pass  , os ) );
171         EXPECT( 1 == run( fail_1, os ) );
172         EXPECT( 1 == run( fail_2, os ) );
173         EXPECT( 1 == run( fail_3, os ) );
174         EXPECT( 1 == run( fail_4, os ) );
175         EXPECT( 1 == run( fail_5, os ) );
176         EXPECT( 1 == run( fail_6, os ) );
177     },
178 
179     "Expect succeeds for string comparation", []
__anon471d1f571a02null180     {
181         std::string a("a"); std::string b("b");
182         test pass  [] = {{ "P" , [=]() { EXPECT( a == a ); EXPECT( a != b );
183                                          EXPECT( b >= a ); EXPECT( a <= b );
184                                          EXPECT( b >  a ); EXPECT( a <  b ); } }};
185         test fail_1[] = {{ "F1", [=]() { EXPECT( a == b ); } }};
186         test fail_2[] = {{ "F2", [=]() { EXPECT( a != a ); } }};
187         test fail_3[] = {{ "F3", [=]() { EXPECT( b <= a ); } }};
188         test fail_4[] = {{ "F4", [=]() { EXPECT( a >= b ); } }};
189         test fail_5[] = {{ "F5", [=]() { EXPECT( b <  a ); } }};
190         test fail_6[] = {{ "F6", [=]() { EXPECT( a >  b ); } }};
191 
192         std::ostringstream os;
193 
194         EXPECT( 0 == run( pass  , os ) );
195         EXPECT( 1 == run( fail_1, os ) );
196         EXPECT( 1 == run( fail_2, os ) );
197         EXPECT( 1 == run( fail_3, os ) );
198         EXPECT( 1 == run( fail_4, os ) );
199         EXPECT( 1 == run( fail_5, os ) );
200         EXPECT( 1 == run( fail_6, os ) );
201     },
202 
203     "Function run() returns the right failure count", []
__anon471d1f572202null204     {
205         test pass  [] = {{ "P" , [] { EXPECT( 1==1 ); } }};
206         test fail_1[] = {{ "F1", [] { EXPECT( 0==1 ); } }};
207         test fail_3[] = {{ "F1", [] { EXPECT( 0==1 ); } },
208                          { "F2", [] { EXPECT( 0==1 ); } },
209                          { "F3", [] { EXPECT( 0==1 ); } },};
210 
211         std::ostringstream os;
212 
213         EXPECT( 0 == run( pass  , os ) );
214         EXPECT( 1 == run( fail_1, os ) );
215         EXPECT( 3 == run( fail_3, os ) );
216     },
217 
218     "Expect succeeds with an unexpected standard exception", []
__anon471d1f572802null219     {
220         std::string text = "hello-world";
221         test pass[] = {{ "P", [=]() { EXPECT( (throw std::runtime_error(text), true) ); } }};
222 
223         std::ostringstream os;
224 
225         EXPECT( 1 == run( pass, os ) );
226         EXPECT( std::string::npos != os.str().find(text) );
227     },
228 
229     "Expect succeeds with an unexpected non-standard exception", []
__anon471d1f572a02null230     {
231         test pass[] = {{ "P", [] { EXPECT( (throw 77, true) ); } }};
232 
233         std::ostringstream os;
234 
235         EXPECT( 1 == run( pass, os ) );
236     },
237 
238     "Expect_throws succeeds with an expected standard exception", []
__anon471d1f572c02null239     {
240         std::string text = "hello-world";
241         test pass[] = {{ "P", [=]() { EXPECT_THROWS( (throw std::runtime_error(text), true) ); } }};
242         test fail[] = {{ "F", [ ]() { EXPECT_THROWS(  true ); } }};
243 
244         std::ostringstream os;
245 
246         EXPECT( 0 == run( pass, os ) );
247         EXPECT( 1 == run( fail, os ) );
248     },
249 
250     "Expect_throws succeeds with an expected non-standard exception", []
__anon471d1f572f02null251     {
252         test pass[] = {{ "P", [] { EXPECT_THROWS( (throw 77, true) ); } }};
253         test fail[] = {{ "F", [] { EXPECT_THROWS(  true ); } }};
254 
255         std::ostringstream os;
256 
257         EXPECT( 0 == run( pass, os ) );
258         EXPECT( 1 == run( fail, os ) );
259     },
260 
261     "Expect_throws_as succeeds with a specific expected standard exception", []
__anon471d1f573202null262     {
263         test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::bad_alloc ); } }};
264         test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::runtime_error ); } }};
265 
266         std::ostringstream os;
267 
268         EXPECT( 0 == run( pass, os ) );
269         EXPECT( 1 == run( fail, os ) );
270     },
271 
272     "Expect_throws_as succeeds with a specific expected non-standard exception", []
__anon471d1f573502null273     {
274         test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw 77, true), int ); } }};
275         test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw 77, true), std::runtime_error ); } }};
276 
277         std::ostringstream os;
278 
279         EXPECT( 0 == run( pass, os ) );
280         EXPECT( 1 == run( fail, os ) );
281     },
282 };
283 
main()284 int main()
285 {
286     return lest::run( specification );
287 }
288 
289 // cl -nologo -Wall -EHsc test_lest.cpp && test_lest
290 // g++ -Wall -Wextra -Weffc++ -std=c++11 -o test_lest.exe test_lest.cpp && test_lest
291 
292