Skip to content

Commit 72e1ded

Browse files
author
Sebastiano Merlino
committed
Created a small testing library
1 parent dc7a949 commit 72e1ded

File tree

1 file changed

+283
-0
lines changed

1 file changed

+283
-0
lines changed

test/littletest.hpp

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
/*
2+
This file is part of liblittletest
3+
Copyright (C) 2012 Sebastiano Merlino
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
*/
20+
21+
#ifndef _LITTLETEST_HPP_
22+
#define _LITTLETEST_HPP_
23+
24+
#include <string>
25+
#include <iostream>
26+
#include <sstream>
27+
28+
#define BEGIN_TEST_ENV() int main() {
29+
#define END_TEST_ENV() return 0; }
30+
#define TEST(name) name ## _obj
31+
#define CREATE_RUNNER(suite_name, runner_name) \
32+
std::cout << "** Initializing Runner \"" << #runner_name << "\" for suite \"" << #suite_name << "\" **" << std::endl; \
33+
test_runner<suite_name> runner_name
34+
#define RUNNER(runner_name) runner_name
35+
#define SUITE(name) struct name : public suite<name>
36+
#define BEGIN_TEST(suite_name, test_name) \
37+
struct test_name : public suite_name, test<suite_name, test_name> \
38+
{ \
39+
public: \
40+
static const char* name; \
41+
void operator()(test_runner<suite_name>* tr) \
42+
{
43+
44+
#define END_TEST(test_name) \
45+
} \
46+
}; \
47+
const char* test_name::name = #test_name; \
48+
test_name test_name ## _obj;
49+
50+
#define CHECK_EQ(a, b) \
51+
try \
52+
{ \
53+
check_eq(name, a, b, __FILE__, __LINE__); \
54+
tr->add_success(); \
55+
} \
56+
catch(check_unattended& cu) \
57+
{ \
58+
std::cout << cu.what() << std::endl; \
59+
tr->add_failure(); \
60+
}
61+
62+
//#define CHECK_NEQ((a), (b)) check_eq(a, b);
63+
//#define CHECK_GT((a), (b)) check_eq(a, b);
64+
//#define CHECK_GTE((a), (b)) check_eq(a, b);
65+
//#define CHECK_LT((a), (b)) check_eq(a, b);
66+
//#define CHECK_LTE((a), (b)) check_eq(a, b);
67+
68+
struct check_unattended : public std::exception
69+
{
70+
check_unattended(const std::string& message):
71+
message(message)
72+
{
73+
}
74+
~check_unattended() throw() { }
75+
76+
virtual const char* what() const throw()
77+
{
78+
return message.c_str();
79+
}
80+
81+
private:
82+
std::string message;
83+
};
84+
85+
struct assert_unattended : public std::exception
86+
{
87+
assert_unattended(const std::string& message):
88+
message(message)
89+
{
90+
}
91+
~assert_unattended() throw() { }
92+
virtual const char* what() const throw()
93+
{
94+
return message.c_str();
95+
}
96+
97+
private:
98+
std::string message;
99+
};
100+
101+
template <typename T1, typename T2>
102+
void check_eq(std::string name, T1 a, T2 b, const char* file, short line)
103+
throw(check_unattended)
104+
{
105+
if(a != b)
106+
{
107+
std::stringstream ss;
108+
ss << "(" << file << ":" << line << ") - error in " << "\"" << name << "\": " << a << " != " << b;
109+
throw check_unattended(ss.str());
110+
}
111+
}
112+
113+
/*
114+
template <typename T1, typename T2>
115+
void check_neq(T1 a, T2 b)
116+
throw(check_unattended)
117+
{
118+
if(a == b)
119+
{
120+
std::stringstream ss;
121+
ss << a << "==" << b;
122+
throw check_unattended(ss.str());
123+
}
124+
}
125+
126+
template <typename T1, typename T2>
127+
void check_gt(T1 a, T2 b)
128+
throw(check_unattended)
129+
{
130+
if(a <= b)
131+
{
132+
std::stringstream ss;
133+
ss << a << "<=" << b;
134+
throw check_unattended(ss.str());
135+
}
136+
}
137+
138+
template <typename T1, typename T2>
139+
void check_gte(T1 a, T2 b)
140+
throw(check_unattended)
141+
{
142+
if(a < b)
143+
{
144+
std::stringstream ss;
145+
ss << a << "<" << b;
146+
throw check_unattended(ss.str());
147+
}
148+
}
149+
150+
template <typename T1, typename T2>
151+
void check_lt(T1 a, T2 b)
152+
throw(check_unattended)
153+
{
154+
if(a >= b)
155+
{
156+
std::stringstream ss;
157+
ss << a << ">=" << b;
158+
throw check_unattended(ss.str());
159+
}
160+
}
161+
162+
template <typename T1, typename T2>
163+
void check_lte(T1 a, T2 b)
164+
throw(check_unattended)
165+
{
166+
if(a > b)
167+
{
168+
std::stringstream ss;
169+
ss << a << ">" << b;
170+
throw check_unattended(ss.str());
171+
}
172+
}
173+
*/
174+
175+
template <class suite_impl>
176+
class suite
177+
{
178+
public:
179+
void suite_set_up()
180+
{
181+
static_cast<suite_impl*>(this)->set_up();
182+
}
183+
184+
void suite_tier_down()
185+
{
186+
static_cast<suite_impl*>(this)->tier_down();
187+
}
188+
189+
suite() { }
190+
suite(const suite<suite_impl>& s) { }
191+
};
192+
193+
template <class suite_impl>
194+
struct test_runner;
195+
196+
template <class suite_impl, class test_impl>
197+
class test
198+
{
199+
private:
200+
bool run_test(test_runner<suite_impl>* tr)
201+
{
202+
static_cast<test_impl* >(this)->suite_set_up();
203+
bool result = false;
204+
try
205+
{
206+
(*static_cast<test_impl*>(this))(tr);
207+
result = true;
208+
}
209+
catch(assert_unattended& au)
210+
{
211+
}
212+
catch(std::exception& e)
213+
{
214+
std::cout << "Exception during " << test_impl::name << " run" << std::endl;
215+
std::cout << e.what() << std::endl;
216+
}
217+
catch(...)
218+
{
219+
std::cout << "Exception during " << test_impl::name << " run" << std::endl;
220+
}
221+
static_cast<test_impl* >(this)->suite_tier_down();
222+
return result;
223+
}
224+
protected:
225+
test() { }
226+
test(const test<suite_impl, test_impl>& t) { }
227+
228+
friend class test_runner<suite_impl>;
229+
};
230+
231+
template <class suite_impl>
232+
struct test_runner
233+
{
234+
public:
235+
test_runner() :
236+
test_counter(1),
237+
success_counter(0),
238+
failures_counter(0)
239+
{
240+
}
241+
242+
template <class test_impl>
243+
test_runner& run(test<suite_impl, test_impl>& t)
244+
{
245+
std::cout << "Running test (" <<
246+
test_counter << "): " <<
247+
static_cast<test_impl*>(&t)->name << std::endl;
248+
249+
t.run_test(this);
250+
251+
test_counter++;
252+
return *this;
253+
}
254+
255+
template <class test_impl>
256+
test_runner& operator()(test<suite_impl, test_impl>& t)
257+
{
258+
return run(t);
259+
}
260+
261+
test_runner& operator()()
262+
{
263+
std::cout << "** Runner terminated! **" << std::endl;
264+
}
265+
266+
void add_failure()
267+
{
268+
failures_counter++;
269+
}
270+
271+
void add_success()
272+
{
273+
success_counter++;
274+
}
275+
276+
277+
private:
278+
int test_counter;
279+
int success_counter;
280+
int failures_counter;
281+
};
282+
283+
#endif //_LITTLETEST_HPP_

0 commit comments

Comments
 (0)