3 // $Id: suite.cpp,v 1.7 2010/03/26 04:38:25 hartwork Exp $
5 // CppTest - A C++ Unit Testing Framework
6 // Copyright (c) 2003 Niklas Lundell
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the
22 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 // Boston, MA 02111-1307, USA.
33 #if (defined(__WIN32__) || defined(WIN32))
34 # include "winconfig.h"
39 #include "cpptest-output.h"
40 #include "cpptest-source.h"
41 #include "cpptest-suite.h"
49 // Destroys all dynamically allocated objects within the given range.
51 template <class FwdIter
>
53 destroy_range(FwdIter first
, FwdIter last
)
59 } // anonymous namespace
61 /// Constructs an empty test suite.
69 /// Destroys this suite object.
73 destroy_range(_suites
.begin(), _suites
.end());
76 /// Starts the testing. All tests in this suite and embedded suites will
79 /// \param output Progress report destination.
80 /// \param cont_after_fail Continue functions despite failures.
82 /// \return True if no test failed; false otherwise.
85 Suite::run(Output
& output
, bool cont_after_fail
)
87 int ntests
= total_tests();
88 output
.initialize(ntests
);
89 do_run(&output
, cont_after_fail
);
90 output
.finished(ntests
, total_time(true));
94 /// \fn void Suite::setup()
96 /// Setups a test fixture. This function is called before each test,
97 /// in this suite, is executed.
99 /// This function should be overloaded by derived classes to provide
100 /// specialized behavior.
104 /// \fn void Suite::tear_down()
106 /// Tears down a test fixture. This function is called after each test,
107 /// in this suite, have been executed.
109 /// This function should be overloaded by derived classes to provide
110 /// specialized behavior.
114 /// Adds a suite to this suite. Tests in added suites will be executed
115 /// when run() of the top-level suite is called.
117 /// \param suite %Test suite to add.
120 Suite::add(auto_ptr
<Suite
> suite
)
122 _suites
.push_back(suite
.release());
125 /// Registers a test function.
127 /// \b Note: Do not call this function directly, use the TEST_ADD(func)
130 /// \param func Pointer to a test function.
131 /// \param name Class and function name of the function. The format \b must
132 /// equal \e class::func.
135 Suite::register_test(Func func
, const string
& name
)
137 string::size_type pos
= name
.find_first_of(':');
138 assert(!name
.empty() && name
[pos
+ 1] == ':' && name
[pos
+ 2] != '\0');
140 _name
.assign(name
, 0, pos
);
141 _tests
.push_back(Data(func
, name
.substr(pos
+ 2)));
144 /// Issues an assertment to the output handler.
146 /// Do not call this function directly, use one of the available assertment
147 /// macros instead, see \ref asserts.
149 /// \param s Assert point information.
152 Suite::assertment(Source s
)
155 s
._test
= *_cur_test
;
156 _output
->assertment(s
);
157 _result
= _success
= false;
160 // Functor to execute tests for the given suite.
162 struct Suite::ExecTests
166 ExecTests(Suite
& s
) : _suite(s
) {}
168 void operator()(Data
& data
)
170 _suite
._cur_test
= &data
._name
;
171 _suite
._result
= true; // assume success, assert will set to false
172 _suite
._output
->test_start(data
._name
);
175 Time
start(Time::current());
176 // FIXME Also feedback exception to user
179 (_suite
.*data
._func
)();
181 _suite
._result
= _suite
._success
= false;
183 Time
end(Time::current());
186 data
._time
= end
- start
;
187 _suite
._output
->test_end(data
._name
, _suite
._result
, data
._time
);
191 // Functor to execute a suite.
198 DoRun(Output
* output
, bool cont
) : _continue(cont
), _output(output
) {}
199 void operator()(Suite
* suite
) { suite
->do_run(_output
, _continue
); }
202 // Execute all tests in this and added suites.
205 Suite::do_run(Output
* os
, bool cont_after_fail
)
207 _continue
= cont_after_fail
;
210 _output
->suite_start(_tests
.size(), _name
);
211 for_each(_tests
.begin(), _tests
.end(), ExecTests(*this));
212 _output
->suite_end(_tests
.size(), _name
, total_time(false));
214 for_each(_suites
.begin(), _suites
.end(), DoRun(_output
, _continue
));
216 // FIXME Find a cleaner way
217 Suites::const_iterator iter
= _suites
.begin();
218 while (iter
!= _suites
.end())
220 if (!(*iter
)->_success
)
229 // Functor to count all tests in a suite.
231 struct Suite::SubSuiteTests
233 int operator()(size_t value
, const Suite
* s
) const
235 return value
+ s
->total_tests();
239 // Counts all tests in this and all its embedded suites.
242 Suite::total_tests() const
244 return accumulate(_suites
.begin(), _suites
.end(),
245 _tests
.size(), SubSuiteTests());
248 // Functor to accumulate execution time for tests.
250 struct Suite::SuiteTime
252 Time
operator()(const Time
& time
, const Data
& data
)
254 return time
+ data
._time
;
258 // Functor to accumulate execution time for suites.
260 struct Suite::SubSuiteTime
262 Time
operator()(Time time
, const Suite
* s
) const
264 return time
+ s
->total_time(true);
268 // Counts time accumulated execution time for all tests in this and all
269 // its embedded suites.
272 Suite::total_time(bool recursive
) const
274 Time time
= accumulate(_tests
.begin(), _tests
.end(),
275 Time(), SuiteTime());
277 return !recursive
? time
: accumulate(_suites
.begin(), _suites
.end(),
278 time
, SubSuiteTime());