Ajout de l'ensemble du workspace.
[GPU.git] / WCudaMSE / API_CppTest / SRC / core / suite.cpp
diff --git a/WCudaMSE/API_CppTest/SRC/core/suite.cpp b/WCudaMSE/API_CppTest/SRC/core/suite.cpp
new file mode 100755 (executable)
index 0000000..954b4a2
--- /dev/null
@@ -0,0 +1,281 @@
+// ---
+//
+// $Id: suite.cpp,v 1.7 2010/03/26 04:38:25 hartwork Exp $
+//
+// CppTest - A C++ Unit Testing Framework
+// Copyright (c) 2003 Niklas Lundell
+//
+// ---
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+//
+// ---
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <functional>
+#include <numeric>
+
+#if (defined(__WIN32__) || defined(WIN32))
+# include "winconfig.h"
+#else
+# include "config.h"
+#endif 
+
+#include "cpptest-output.h"
+#include "cpptest-source.h"
+#include "cpptest-suite.h"
+
+using namespace std;
+
+namespace Test
+{
+       namespace
+       {
+               // Destroys all dynamically allocated objects within the given range.
+               //
+               template <class FwdIter>
+               void
+               destroy_range(FwdIter first, FwdIter last)
+               {
+                       while (first != last)
+                               delete *first++;
+               }
+               
+       } // anonymous namespace
+       
+       /// Constructs an empty test suite.
+       ///
+       Suite::Suite()
+       :       _cur_test(0),
+               _output(0),
+               _success(true)
+       {}
+       
+       /// Destroys this suite object.
+       ///
+       Suite::~Suite()
+       {
+               destroy_range(_suites.begin(), _suites.end());
+       }
+       
+       /// Starts the testing. All tests in this suite and embedded suites will
+       /// be executed.
+       ///
+       /// \param output          Progress report destination.
+       /// \param cont_after_fail Continue functions despite failures.
+       ///
+       /// \return True if no test failed; false otherwise.
+       ///
+       bool
+       Suite::run(Output& output, bool cont_after_fail)
+       {
+               int ntests = total_tests();
+               output.initialize(ntests);
+               do_run(&output, cont_after_fail);
+               output.finished(ntests, total_time(true));
+               return _success;
+       }
+               
+       /// \fn void Suite::setup()
+       ///
+       /// Setups a test fixture. This function is called before each test,
+       /// in this suite, is executed.
+       ///
+       /// This function should be overloaded by derived classes to provide
+       /// specialized behavior.
+       ///
+       /// \see tear_down()
+       
+       /// \fn void Suite::tear_down()
+       ///
+       /// Tears down a test fixture. This function is called after each test,
+       /// in this suite, have been executed.
+       ///
+       /// This function should be overloaded by derived classes to provide
+       /// specialized behavior.
+       ///
+       /// \see setup()
+       
+       /// Adds a suite to this suite. Tests in added suites will be executed
+       /// when run() of the top-level suite is called.
+       ///
+       /// \param suite %Test suite to add.
+       ///
+       void
+       Suite::add(auto_ptr<Suite> suite)
+       {
+               _suites.push_back(suite.release());
+       }
+       
+       /// Registers a test function.
+       ///
+       /// \b Note: Do not call this function directly, use the TEST_ADD(func)
+       /// macro instead.
+       ///
+       /// \param func Pointer to a test function.
+       /// \param name Class and function name of the function. The format \b must
+       ///             equal \e class::func.
+       ///
+       void
+       Suite::register_test(Func func, const string& name)
+       {
+               string::size_type pos = name.find_first_of(':');
+               assert(!name.empty() && name[pos + 1] == ':' && name[pos + 2] != '\0');
+               
+               _name.assign(name, 0, pos);
+               _tests.push_back(Data(func, name.substr(pos + 2)));
+       }
+       
+       /// Issues an assertment to the output handler.
+       ///
+       /// Do not call this function directly, use one of the available assertment
+       /// macros instead, see \ref asserts.
+       ///
+       /// \param s Assert point information.
+       ///
+       void
+       Suite::assertment(Source s)
+       {
+               s._suite = _name;
+               s._test  = *_cur_test;
+               _output->assertment(s);
+               _result = _success = false;
+       }
+       
+       // Functor to execute tests for the given suite.
+       //
+       struct Suite::ExecTests
+       {
+               Suite& _suite;
+               
+               ExecTests(Suite& s) : _suite(s) {}
+               
+               void operator()(Data& data)
+               {
+                       _suite._cur_test = &data._name;
+                       _suite._result = true; // assume success, assert will set to false
+                       _suite._output->test_start(data._name);
+                       
+                       _suite.setup();
+                       Time start(Time::current());
+                       // FIXME Also feedback exception to user
+                       try
+                       {
+                               (_suite.*data._func)();
+                       } catch (...) {
+                               _suite._result = _suite._success = false;
+                       }
+                       Time end(Time::current());
+                       _suite.tear_down();
+                       
+                       data._time = end - start;
+                       _suite._output->test_end(data._name, _suite._result, data._time);
+               }
+       };
+
+       // Functor to execute a suite.
+       //
+       struct Suite::DoRun
+       {
+               bool    _continue;
+               Output* _output;
+               
+               DoRun(Output* output, bool cont) : _continue(cont), _output(output) {}
+               void operator()(Suite* suite) { suite->do_run(_output, _continue); }
+       };
+
+       // Execute all tests in this and added suites.
+       //
+       void
+       Suite::do_run(Output* os, bool cont_after_fail)
+       {
+               _continue = cont_after_fail;
+               _output = os;
+               
+               _output->suite_start(_tests.size(), _name);
+               for_each(_tests.begin(), _tests.end(), ExecTests(*this));
+               _output->suite_end(_tests.size(), _name, total_time(false));
+
+               for_each(_suites.begin(), _suites.end(), DoRun(_output, _continue));
+
+               // FIXME Find a cleaner way
+               Suites::const_iterator iter = _suites.begin();
+               while (iter != _suites.end())
+               {
+                       if (!(*iter)->_success)
+                       {
+                               _success = false;
+                               break;
+                       }
+                       iter++;
+               }
+       }
+
+       // Functor to count all tests in a suite.
+       //
+       struct Suite::SubSuiteTests
+       {
+               int operator()(size_t value, const Suite* s) const
+               {
+                       return value + s->total_tests();
+               }
+       };
+       
+       // Counts all tests in this and all its embedded suites.
+       //
+       int
+       Suite::total_tests() const
+       {
+               return accumulate(_suites.begin(), _suites.end(),
+                                                 _tests.size(), SubSuiteTests());
+       }
+       
+       // Functor to accumulate execution time for tests.
+       //
+       struct Suite::SuiteTime
+       {
+               Time operator()(const Time& time, const Data& data)
+               {
+                       return time + data._time;
+               }
+       };
+       
+       // Functor to accumulate execution time for suites.
+       //
+       struct Suite::SubSuiteTime
+       {
+               Time operator()(Time time, const Suite* s) const
+               {
+                       return time + s->total_time(true);
+               }
+       };
+       
+       // Counts time accumulated execution time for all tests in this and all
+       // its embedded suites.
+       //
+       Time
+       Suite::total_time(bool recursive) const
+       {
+               Time time = accumulate(_tests.begin(), _tests.end(),
+                                                          Time(), SuiteTime());
+               
+               return !recursive ? time : accumulate(_suites.begin(), _suites.end(),
+                                                                                         time, SubSuiteTime());
+       }
+       
+} // namespace Test