Modulo [B]asico para prueba [unit]aria de programas:
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Valores de enumeraciones Amigas 'defines'
BUnit.h
Ir a la documentación de este archivo.
00001 // BUnit.h (C) 2008  adolfo@di-mare.com
00002 
00003 /*
00004    THIS IS FREE SOFWTWARE.
00005    - Use at your own risk; acknowledge authorship, please.
00006    - You can never blame the author for your use of this software.
00007    - Released to the world under LGPLv3:
00008      http://www.gnu.org/licenses/lgpl-3.0.html
00009    ESTE PROGRAMA ES LIBRE.
00010    - Uselo baja su propia responsabilidad; reconozca la autoría, por favor.
00011    - Usted nunca podrá culpar al autor por su propio uso de este software.
00012    - Entregado al mundo bajo LGPLv3:
00013      http://www.gnu.org/licenses/lgpl-3.0.html
00014 */
00015 /*
00016     Version 0: No TestSuite<>
00017     Version 1: English Doxygen
00018     Version 2: English+Spanish Doxygen
00019 */
00020 
00021 #ifdef English_dox
00022 /** \file  BUnit.h
00023     \brief [B]asic module for [unit] program testing.
00024 
00025     \author Adolfo Di Mare <adolfo@di-mare.com>
00026     \date   2008
00027 */
00028 #endif
00029 #ifdef Spanish_dox
00030 /** \file  BUnit.h
00031     \brief Módulo [B]ásico para prueba [unit]aria de programas.
00032 
00033     \author Adolfo Di Mare <adolfo@di-mare.com>
00034     \date   2008
00035 */
00036 #endif
00037 
00038 #ifdef English_dox
00039     /// Doxygen English documentation.
00040     #define English_dox   "Doxygen English documentation"
00041    /// \def English_dox  ///< Marks English documentation blocks.
00042    /// \def BUnit_h      ///< Avoids multiple inclusion.
00043 #endif
00044 #ifdef Spanish_dox
00045     /// Documentación en español.
00046     #define Spanish_dox "Documentación en español"
00047    /// \def Spanish_dox  ///< Macro usado para que Doxygen genere documentación
00048    /// \def BUnit_h      ///< Evita la inclusión múltiple.
00049 #endif
00050 
00051 #ifndef BUnit_h
00052 #define BUnit_h      // avoid multiple inclusion
00053 
00054 #include <list>      // std::list
00055 #include <string>    // class std::string
00056 #include <sstream>   // class basic_ostringstream<T,Ch>
00057 #include <cstring>   // memcpy()+strlen()
00058 #include <typeinfo>  // class std::type_info ==> char* typeid().name();
00059 #include <algorithm> // find()
00060 
00061 namespace std {} // using namespace std;
00062 
00063 /// Escuela de Ciencias de la Computación e Informática.
00064 /// \see http://www.ecci.ucr.ac.cr
00065 namespace ECCI { }
00066 
00067 // Private class to hold test cases that didn´t succeed.
00068 class TestCaseFailure {
00069 private:
00070     const char * m_fname;  // file where the failure ocurred
00071     int          m_lineno; // line for the failure
00072     const char * m_label;  // descriptive message for the failure
00073     bool m_destroy_label;  // true when "m_label" requires destruction
00074 private:
00075     TestCaseFailure() : // almost never used
00076         m_fname(""), m_lineno(0), m_label(""), m_destroy_label(false)
00077     { } // always sets "m_destroy_label" to "false"
00078     TestCaseFailure(const char * fname, int line, const char * label, bool destroy )
00079         : m_fname(fname), m_lineno(line), m_label(label), m_destroy_label(destroy)
00080     { }
00081 public:
00082     ~TestCaseFailure() { if (m_destroy_label) { delete [] m_label; } }
00083     TestCaseFailure( const TestCaseFailure& o ) {
00084         m_fname = o.m_fname; m_lineno = o.m_lineno; m_label = o.m_label;
00085         m_destroy_label = o.m_destroy_label;
00086         // avoid double destruction of "m_label"
00087         const_cast<TestCaseFailure*>(&o)->m_destroy_label = false;
00088     //  const_cast<bool>(o.m_destroy_label) = false; // won't compile
00089     }
00090     void operator = ( TestCaseFailure& o ) {
00091         m_fname = o.m_fname; m_lineno = o.m_lineno; m_label = o.m_label;
00092         m_destroy_label = o.m_destroy_label;
00093         o.m_destroy_label = false; // evita doble destrucción de "m_label"
00094     }
00095     template <class TestCase> friend void do_toXML(
00096         const TestCase * tc , std::basic_ostringstream<char> & ost );
00097     template <class TestCase> friend void do_toString(
00098         const TestCase * tc , std::basic_ostringstream<char> & ost );
00099     #ifdef English_dox
00100          /// Test case.
00101     #endif
00102     #ifdef Spanish_dox
00103          /// Caso de prueba.
00104     #endif
00105     friend class TestCase;
00106 }; // TestCaseFailure
00107 
00108 
00109 // Abstract base class for every test case ==>
00110 // - It's always mandatory to reimplement \c TestCase::run().
00111 class TestCase {
00112 protected:
00113     int          m_pass;    // number successful tests
00114     int          m_failure; // number of non successful tests [broken assert_XXX()]
00115     const char * m_name;    // name for the test case
00116     bool         m_test_suite_destroy; // true means destroy from dynamic memory
00117     std::list<TestCaseFailure> m_failureList; // container for al non successful tests
00118 public:
00119     TestCase(const char * name=0);
00120     virtual ~TestCase() { }
00121     virtual bool run() = 0; // must implement in derived class
00122     void runBare();
00123     bool Run()     { return run(); } // same as run()
00124     bool runTest() { return run(); }
00125     virtual void setUp();
00126     virtual void tearDown();
00127     int  countTestCases() const { return 1; } // more than 1 for TestSuite<>
00128     // errorCount() == 0 ==> "error" means "wrong exception"
00129     int  runCount() const { return successCount()+failureCount()+errorCount(); }
00130     virtual int failureCount() const { return m_failure; }
00131     int  errorCount() const { return 0; }
00132     virtual int successCount() const { return m_pass; }
00133     // true when all runs have been a success
00134     bool wasSuccessful() const { return successCount() == runCount(); }
00135     virtual void reset(); // resets al counter back to 0
00136 public:
00137     std::string getName() const;
00138     void setName( const char * name=0 );
00139     virtual const std::string toString() const;
00140     virtual const std::string summary() const;
00141     virtual const std::string toXML() const;
00142     const std::string report() const { return summary() + '\n' + toString(); }
00143     const std::string failureString() const { return toString(); }
00144     template <class T> static std::string toString( const T & val );
00145 protected:
00146     void recordSuccess() { ++m_pass; } // record another successful test
00147     void recordFailure( // (char*) version
00148         const char* label, const char* fname, int lineno,
00149         bool must_copy=false );
00150     void recordFailure( // std::string version
00151         const std::string& label, const char* fname, int lineno );
00152     void testThis( // (char*) version ==> don't destroy label
00153         bool cond, const char*        label, const char* fname, long lineno,
00154         bool must_copy=false );
00155     void testThis( // string<> version ==> create copy of "label" in dynamic memory
00156         bool cond, const std::string& label, const char* fname, long lineno );
00157     template <class TestCase> friend
00158     void do_toXML( const TestCase * tc , std::basic_ostringstream<char> & ost );
00159     template <class TestCase> friend
00160     void do_toString( const TestCase * tc , std::basic_ostringstream<char> & ost );
00161     template <class TestCase> friend class TestSuite; ///< Colección de pruebas.
00162     int  nPass()  const { return m_pass; }    // Deprecated: it's here for
00163     int  nError() const { return m_failure; } // compatibility with Allison's work
00164 private:
00165     virtual bool iAmTestSuite() const { return false; } // I am NOT a TestSuite<>
00166     TestCase(const TestCase&);            // trick to prevent copy on init
00167     TestCase& operator=(const TestCase&); // trick to prevent copying
00168     #ifdef English_dox
00169          /// Test case class for \c BUnit.h
00170     #endif
00171     #ifdef Spanish_dox
00172           /// Clase de prueba para \c BUnit.h
00173     #endif
00174     friend class test_BUnit;
00175 }; // TestCase
00176 
00177 #ifdef Spanish_dox
00178 /// Sinónimo de \c TestCase.
00179 #endif
00180 #ifdef English_dox
00181 /// Synonym for \c TestCase.
00182 #endif
00183 typedef TestCase TestCase_is_base_for_TestSuite;
00184 
00185 // Test collection.
00186 template <class TestCase>
00187 class TestSuite : public TestCase_is_base_for_TestSuite {
00188 public:
00189     typedef std::list<TestCase_is_base_for_TestSuite*> container_type;
00190     typedef container_type::iterator iterator;
00191     typedef const container_type::iterator cons_iterator;
00192     typedef const container_type const_container_type;
00193 private:
00194     container_type m_allTest; // holds [pointers to] failed tests
00195 public:
00196     TestSuite(const char * name=0): TestCase(name), m_allTest() { }
00197     virtual ~TestSuite();
00198     bool addTest(TestCase& T);
00199     bool addTest(TestCase* T);
00200     void addSuite( TestSuite& SSS );
00201     bool run(); // implemented: TestSuite<> is not an abstract class
00202     void runBare();
00203     int  countTestCases() const { return int(m_allTest.size()); }
00204     int  failureCount() const;
00205     int  successCount() const;
00206     void reset();
00207     const_container_type& allTests() const { return m_allTest; }
00208     const std::string toString() const;
00209     const std::string summary() const;
00210     const std::string toXML() const;
00211 private:
00212     bool iAmTestSuite() const { return true; }
00213     TestSuite(const TestSuite& DONTcopy);
00214     TestSuite& operator=(const TestSuite& DONTcopy); // forbid copying
00215 }; // TestSuite
00216 
00217 /************************\
00218 **************************
00219 **                      **
00220 **       BUnit.h        **
00221 **                      **
00222 **************************
00223 \************************/
00224 
00225 #ifdef English_dox
00226     /// Doxygen English documentation.
00227     #define English_dox   "Doxygen English documentation"
00228    /// \def English_dox  ///< Marks English documentation blocks.
00229 #endif
00230 #ifdef Spanish_dox
00231     /// Documentación en español.
00232     #define Spanish_dox "Documentación en español"
00233    /// \def Spanish_dox  ///< Macro usado para que Doxygen genere documentación
00234 #endif
00235 
00236 #ifdef English_dox
00237 /** \mainpage
00238 
00239 \section sec-01 [B]asic module for [unit] program testing.
00240 
00241 Header file \c BUnit.h supports writing modules for unit program testing.
00242 The model used for this implementation is similar to that described in
00243 the article "The Simplest Automated Unit Test Framework That Could
00244 Possibly Work "by Chuck Allison, which you can get here:
00245 - http://www.stickyminds.com/getfile.asp?ot=XML&id=3129&fn=XDD3129filelistfilename1.pdf
00246 - http://www.google.com/search?num=100&as_q=Simplest+Unit+Test+Allison
00247 - http://search.yahoo.com/search?n=100&p=Simplest+Unit+Test+Allison
00248 
00249 - To simplify to a minimum the task of writing test cases, the full
00250   implementation of \c BUnit is contained within the single header
00251   file \c BUnit.h, so testing requieres only this directive:
00252   - <strong>\#include "BUnit.h"</strong>
00253 - This framework is similar to JUnit, because it is presumed that
00254   in the future students will use Java as their primary language
00255   to develop programs (as C++ is used only for deep training in
00256   programming techniques).
00257   \see http://search.yahoo.com/search?n=100&p=JUnit+Java
00258 - As C++ does not have a mechanism similar to Java's "reflection",
00259   for each failed test the exact test condition is recorded
00260   using an invocation to macro \c BUnit_TEST() that also records
00261   the filename \c __FILE__ and the line \c __LINE__ for that test.
00262   \see http://search.yahoo.com/search?n=100&p=reflection+Java
00263 - In JUnit class \c TestCase is a subclass of \c Assert; in BUnit no
00264   \c Assert class exist but to maintain compatibility with JUnit similar
00265   functionality is provided with macros whose names begin with "assert".
00266   \see http://search.yahoo.com/search?n=100&p=JUnit+Java+Assert+method
00267 - To simplify this framework no difference is made between a test that
00268   is not successfull and one that didn´t succeed because the correct
00269   exception was not raised. This is a contrast with JUnit where an
00270   "error" is a test case that raised the wrong exception. This
00271   explains why \c TestCase::errorCount() always returns zero \c 0.
00272     \code
00273     // Failure vs Error in JUnit
00274     public void test_Fail () {
00275         try {
00276             new ArrayList(10).get( 11 );
00277             fail("Error if IndexOutOfBoundsException is not thrown" ); // error
00278         }
00279         catch (IndexOutOfBoundsException success) { } // Ok
00280     }
00281     public void test_Failure() {
00282         assertTrue( 1 == 2 ); // failure
00283     }
00284     \endcode
00285 - In \c BUnit.h no difference is made between "failures" and "errors".
00286   - En \c JUnit an "error" means that the wrong exception was raised.
00287   - En \c JUnit a "failure" means that an assertion was false.
00288   - \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00289   - \see http://search.yahoo.com/search?n=100&p=junit+difference+failure+error
00290 - In JUnit, what's the difference between a failure and an error?
00291   - Assertions are used to check for the possibility of failures,
00292     therefore failures are anticipated with invokations similar to \c assertTrue().
00293   - Errors are unanticipated problems resulting in uncaught exceptions
00294     being propagated from a JUnit test method.
00295   - \see http://www.cs.waikato.ac.nz/~bernhard/314/junit3.8.1/doc/faq/faq.htm#tests_9
00296   - \see http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#tests_9
00297 
00298 \dontinclude test_BUnit.cpp
00299 \skipline    test::Allison()
00300 \until       }}
00301 \see         test_BUnit::test_Allison()
00302 */
00303 #endif
00304 #ifdef Spanish_dox
00305 /** \mainpage
00306 
00307 \section sec-01 Módulo [B]ásico para prueba [unit]aria de programas.
00308 
00309 El archivo de encabezado \c BUnit.h apoya la escritura de módulos de prueba de
00310 unitaria programas. El modelo que se usa para esta implementación es
00311 similar al expuesto en este artículo "The Simplest Automated Unit
00312 Test Framework That Could Possibly Work" de Chuck Allison, que se
00313 puede obtener aquí:
00314 - http://www.stickyminds.com/getfile.asp?ot=XML&id=3129&fn=XDD3129filelistfilename1.pdf
00315 - http://www.google.com/search?num=100&as_q=Simplest+Unit+Test+Allison
00316 - http://search.yahoo.com/search?n=100&p=Simplest+Unit+Test+Allison
00317 
00318 - Para simplificar al mínimo la tarea de programar los casos de prueba,
00319   la implementación completa de \c BUnit está contenida en el archivo
00320   de encabezado \c BUnit.h, por lo que para hacer pruebas basta poner
00321   esta directiva:
00322   - <strong>\#include "BUnit.h"</strong>
00323 - Este marco de pruebas es similar a JUnit, pues se presume que en
00324   el futuro los estudiantes usarán Java como su lenguaje principal
00325   para desarrollo de programas (pues usan C++ sólo para adiestrarse
00326   profundamente en técnicas de programación).
00327   \see http://search.yahoo.com/search?n=100&p=JUnit+Java
00328 - Como el lenguaje C++ no tiene un mecanismo similar al de "reflexión"
00329   de Java, en cada prueba fallida se registra la condición de prueba
00330   exacta, obtenida a través de una invocación de la macro \c BUnit_TEST()
00331   que registra el nombre del archivo \c __FILE__ y el renglón \c __LINE__
00332   de la prueba.
00333   \see http://search.yahoo.com/search?n=100&p=reflection+Java
00334 - En JUnit la clase \c TestCase es una subclase de \c Assert; en BUnit no
00335   existe la clase \c Assert pero para mantener compatibilidad con JUnit
00336   sí se provée funcionalidad similar usando macros cuyos nombres comienzan
00337   con "assert".
00338   \see http://search.yahoo.com/search?n=100&p=JUnit+Java+Assert+method
00339 - Para simplificar este marco de pruebas no se usa la clase \c TestResult
00340   que sirve para acumular resultados de las pruebas. En su lugar, se puede
00341   obtener una hilera enorme \c std::string que contiene el registro de
00342   todas las pruebas que no tuvieron éxito invocando el método
00343   \c TestCase::toString() o \c TestCase::toXML().
00344 - Para simplificar esta plataforma de pruebas no se hace diferencia entre
00345   un caso de prueba de prueba no existoso y uno que no tiene éxito porque no
00346   se ha levantado la excepción adecuada. Esto contrasta con JUnit, que
00347   llama "error" a un caso de prueba que ha levantado la excepción equivocada.
00348   Por eso \c TestCase::errorCount() siempre retorna cero \c 0.
00349     \code
00350     // Falla vs Error en JUnit
00351     public void test_Error() {
00352         try {
00353             new ArrayList(10).get( 11 );
00354             fail("Error si no tira IndexOutOfBoundsException" ); // error
00355         }
00356         catch (IndexOutOfBoundsException success) { } // Ok
00357     }
00358     public void test_Failure() {
00359         assertTrue( 1 == 2 ); // falla
00360     }
00361     \endcode
00362 - En \c BUnit.h no se hace diferencia entre "fallas" y "errores".
00363   - En \c JUnit un "error" se produce cuando no se levanta la excepción adecuada.
00364   - En \c JUnit una "falla" se produce cuando una aserción resulta falsa.
00365   - \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00366   - \see http://www.cs.waikato.ac.nz/~bernhard/314/junit3.8.1/doc/faq/faq.htm#tests_9
00367   - \see http://search.yahoo.com/search?n=100&p=junit+difference+failure+error
00368 - In JUnit, ¿cuál es la diferencia entre fallas y errores?
00369   - Las aseveraciones son usadas para verificar si existen fallas, y por eso las
00370     fallas son previstas con invocaciones similares a \c assertTrue().
00371   - Los errores son problemas no previstos que resultan de excepciones no captadas
00372     por los método de prueba JUnit.
00373   - \see http://www.cs.waikato.ac.nz/~bernhard/314/junit3.8.1/doc/faq/faq.htm#tests_9
00374   - \see http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#tests_9
00375 
00376 \dontinclude test_BUnit.cpp
00377 \skipline    test::Allison()
00378 \until       }}
00379 \see         test_BUnit::test_Allison()
00380 */
00381 #endif
00382 
00383 #ifdef Spanish_dox
00384     // using namespace std;
00385     /// Definido por la biblioteca C++ estándar.
00386     namespace std {} // It's here for Doxygen to document it
00387 #endif
00388 #ifdef English_dox
00389     // using namespace std;
00390     /// Defined by the C++ estándar library.
00391     namespace std {} // Está acá para que Doxygen lo documente
00392 #endif
00393 
00394 /// Escuela de Ciencias de la Computación e Informática.
00395 /// \see http://www.ecci.ucr.ac.cr
00396 namespace ECCI { }
00397 
00398 /************************\
00399 **************************
00400 **                      **
00401 **   TestCaseFailure    **
00402 **                      **
00403 **************************
00404 \************************/
00405 
00406 #ifdef English_dox
00407 /** \class TestCaseFailure
00408     \brief Private class to hold test cases that didn´t succeed.
00409 */
00410 /** \var   const char * TestCaseFailure::m_fname;
00411     \brief Name of the file where the failure was produced.
00412 */
00413 /** \var   int TestCaseFailure::m_lineno;
00414     \brief Line number in the file where the failure was produced.
00415 */
00416 /** \var   const char * TestCaseFailure::m_label;
00417     \brief Descriptive message for the failure.
00418 */
00419 /** \var   bool TestCaseFailure::m_destroy_label;
00420     \brief Holds \c "true" if the destructor should return the dynamic memory for \c m_label.
00421 */
00422 /** \fn    TestCaseFailure::TestCaseFailure();
00423     \brief Default constructor.
00424 */
00425 /** \fn    TestCaseFailure::TestCaseFailure(const char * fname, int line, const char * label, bool destroy );
00426     \brief Private constructor that can set \c m_label to \c true.
00427 */
00428 #endif
00429 #ifdef Spanish_dox
00430 /** \class TestCaseFailure
00431     \brief Clase privada que contiene los datos de cada prueba no exitosa.
00432 */
00433 /** \var   const char * TestCaseFailure::m_fname;
00434     \brief Nombre del archivo en donde se produjo el error.
00435 */
00436 /** \var   int TestCaseFailure::m_lineno;
00437     \brief Número de línea del archivo en donde se produjo el error.
00438 */
00439 /** \var   const char * TestCaseFailure::m_label;
00440     \brief Mensaje descriptivo del error.
00441 */
00442 /** \var   bool TestCaseFailure::m_destroy_label;
00443     \brief Contiene \c "true" si el destructor debe retornar la memoria dinámica de \c m_label.
00444 */
00445 /** \fn    TestCaseFailure::TestCaseFailure();
00446     \brief Constructor por defecto.
00447 */
00448 /** \fn    TestCaseFailure::TestCaseFailure(const char * fname, int line, const char * label, bool destroy );
00449     \brief Constructor Privado que puede inicializar \c m_label en \c true.
00450 */
00451 #endif
00452 
00453 #ifdef English_dox
00454 /** \fn    TestCaseFailure::~TestCaseFailure();
00455     \brief Destructor.
00456 */
00457 /** \fn    TestCaseFailure::TestCaseFailure( const TestCaseFailure& o );
00458     \brief Copy constructor.
00459 */
00460 /** \fn    void TestCaseFailure::operator = ( TestCaseFailure& o );
00461     \brief Copy operator used to insert into contanier.
00462 */
00463 #endif
00464 
00465 #ifdef Spanish_dox
00466 /** \fn    TestCaseFailure::~TestCaseFailure()
00467     \brief Destructor.
00468 */
00469 /** \fn    TestCaseFailure::TestCaseFailure( const TestCaseFailure& o );
00470     \brief Constructor de copia.
00471 */
00472 /** \fn    void TestCaseFailure::operator = ( TestCaseFailure& o )
00473     \brief Copiador usado al insertar en el contenedor.
00474 */
00475 #endif
00476 
00477 /************************\
00478 **************************
00479 **                      **
00480 **      TestCase        **
00481 **                      **
00482 **************************
00483 \************************/
00484 
00485 #ifdef English_dox
00486 /** \class TestCase
00487     \brief Every test case is an instance derived from this abstract class.
00488      - It's always mandatory to reimplement \c TestCase::run().
00489 */
00490 /** \fn    int TestCase::m_pass;
00491     \brief Number of successful tests.
00492 */
00493 /** \fn    int TestCase::m_failure;
00494     \brief Number of test that produced failed.
00495 */
00496 /** \fn    const char * TestCase::m_name;
00497     \brief Test case name.
00498 */
00499 /** \fn    bool TestCase::m_test_suite_destroy;
00500     \brief Holds \c "true" if the test case is stored in dynamic memory.
00501 */
00502 /** \fn    std::list<TestCaseFailure> TestCase::m_failureList;
00503     \brief Container where test cases that produced failures are stored.
00504 */
00505 #endif
00506 
00507 #ifdef Spanish_dox
00508 /** \class TestCase
00509     \brief Cada caso de prueba es una instancia derivada de esta clase abstracta.
00510      - Siempre es obligatorio reimplementar \c TestCase::run().
00511 */
00512 /** \fn    int TestCase::m_pass;
00513     \brief Cantidad de pruebas exitosas.
00514 */
00515 /** \fn    int TestCase::m_failure;
00516     \brief Cantidad de pruebas que han fallado.
00517 */
00518 /** \fn    const char * TestCase::m_name;
00519     \brief Nombre del caso de prueba.
00520 */
00521 /** \fn    bool TestCase::m_test_suite_destroy;
00522     \brief Contiene \c "true" si la prueba está almacenada en memoria dinámica.
00523 */
00524 /** \fn    std::list<TestCaseFailure> TestCase::m_failureList;
00525     \brief Contenedor para almacenar las pruebas que han producido fallas.
00526 */
00527 #endif
00528 
00529 #ifdef English_dox
00530 /** \fn    virtual TestCase::~TestCase();
00531     \brief Destructor.
00532 */
00533 /** \fn    virtual bool TestCase::run() = 0;
00534     \brief <strong>[virtual]</strong> ==> Executes test and returns \c "false" if not successful.
00535     <strong>[***]</strong> It is always mandatory to redefine method \c run().
00536     \see runBare().
00537 */
00538 /** \fn    bool TestCase::Run();
00539     \brief Synonym for \c run().
00540 */
00541 /** \fn    bool TestCase::runTest();
00542     \brief Synonym for \c run().
00543 */
00544 /** \fn    int  TestCase::countTestCases() const;
00545     \brief 1 == Number of test cases.
00546     The value returned always is one \c 1 because class \c TestCase
00547     represents a single test case. For the container \c TestSuite<>
00548     the value returned can be bigger than \c 1.
00549     - A "test case" is a class, derived from class \c TestCase.
00550     - A "test run" gets counted when either a specific test succeeds or fails.
00551     - A "test run" gets counted when protected method TestCase::testThis() is
00552       executed, either directly or through any BUnit \c "assert()" macro, as
00553       \c assertTrue(), \c fail_Msg(), \c assertEquals_Delta(), or others like
00554       \c BUnit_SUCCESS() or \c BUnit_TEST().
00555     - A "test case" ussually has many "test runs". A collection of "test cases"
00556       resided within an instance derived from class \c TestSuite<>.
00557 */
00558 /** \fn    int  TestCase::runCount() const;
00559     \brief Number of test runs.
00560     - Synonym for <code>successCount()+failureCount()+errorCount()</code>.
00561     \see reset().
00562 */
00563 /** \fn    virtual int TestCase::failureCount() const;
00564     \brief Number of test runs that failed. \see reset().
00565 */
00566 /** \fn    int  TestCase::errorCount() const;
00567     \brief Always returns \c 0 (cero): "Number of errors".
00568     - BUnit does not maintain separate counts for "errors" and "failures".
00569     \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00570 */
00571 /** \fn    virtual int TestCase::successCount() const;
00572     \brief Number of successful test runs. \see reset().
00573 */
00574 /** \fn    bool TestCase::wasSuccessful() const;
00575     \brief Returns \c "true" when all test runs where successful.
00576     - Synonym for <code>(successCount() == runCount())</code>
00577 */
00578 /** \fn    std::string TestCase::getName() const;
00579     \brief Gets the test case name. \see setName().
00580 */
00581 /** \fn    const std::string TestCase::report() const;
00582     \brief Returns string \c summary() followed by \c toString().
00583 */
00584 /** \fn    const std::string TestCase::failureString() const;
00585     \brief Synonym for \c toString().
00586 */
00587 /** \fn    void TestCase::recordSuccess();
00588     \brief Records the test run as a success.
00589 */
00590 /** \fn    int  TestCase::nPass()  const;
00591     \brief Synonym for \c successCount() [OBSOLETE]. \deprecated
00592 */
00593 /** \fn    int  TestCase::nError() const;
00594     \brief Synonym for \c failureCount() [OBSOLETE]. \deprecated
00595 */
00596 /** \fn    virtual bool TestCase::iAmTestSuite() const;
00597     \brief Returns \c false for \c TestCase.
00598 */
00599 /** \fn    TestCase::TestCase(const TestCase&);
00600     \brief This \c "private" declaration forbids test case copying.
00601 */
00602 /** \fn    TestCase& TestCase::operator=(const TestCase&);
00603     \brief This \c "private" declaration forbids test case copying.
00604 */
00605 #endif
00606 #ifdef Spanish_dox
00607 /** \fn    virtual TestCase::~TestCase();
00608     \brief Destructor.
00609 */
00610 /** \fn    virtual bool TestCase::run() = 0;
00611     \brief <strong>[virtual]</strong> ==> Ejecuta la prueba y retorna \c "false" si produce error.
00612     <strong>[***]</strong> Siempre es necesario redefinir el método \c run().
00613     \see runBare().
00614 */
00615 /** \fn    bool TestCase::Run();
00616     \brief Sinónimo de \c run().
00617 */
00618 /** \fn    bool TestCase::runTest();
00619     \brief Sinónimo de \c run().
00620 */
00621 /** \fn    int  TestCase::countTestCases() const;
00622     \brief 1 == Cantidad de casos de prueba.
00623     El valor retornado siempre es uno \c 1 porque la clase \c TestCase
00624     representa un único caso de pruebas. Para el contenedor
00625     \c TestSuite<> el valor retornado puede ser mayor a \c 1.
00626     - Un "caso de prueba" es una clase derivada de la clase \c TestCase.
00627     - Una "prueba" se cuenta cuando tiene éxito o fracasa.
00628     - Una "prueba" se cuenta cuando el método protegido TestCase::testThis() es
00629       ejecutado, ya sea directamente o a través de cualquiera de los macros
00630       \c "assert()" de BUnit, como lo son \c assertTrue(), \c fail_Msg(),
00631       \c assertEquals_Delta(), u otros como \c BUnit_SUCCESS() or \c BUnit_TEST().
00632     - Un "caso de prueba" generalmente incluye muchas "pruebas". Una colección de
00633       "casos de prueba" reside en una instancia derivada de la clase \c TestSuite<>.
00634 */
00635 /** \fn    int  TestCase::runCount() const;
00636     \brief Cantidad total de pruebas realizadas.
00637     - Sinónimo de <code>successCount()+failureCount()+errorCount()</code>.
00638     \see reset().
00639 */
00640 /** \fn    virtual int TestCase::failureCount() const;
00641     \brief Cantidad de pruebas que fallaron. \see reset().
00642 */
00643 /** \fn    int  TestCase::errorCount() const;
00644     \brief Siempre retorna \c 0 (cero): "Cantidad de errores".
00645     - BUnit no se contabilizan aparte los "errores" de las "fallas".
00646     \see http://osdir.com/ml/java.junit.user/2002-06/msg00114.html
00647 */
00648 /** \fn    virtual int TestCase::successCount() const;
00649     \brief Cantidad de pruebas exitosas. \see reset().
00650 */
00651 /** \fn    bool TestCase::wasSuccessful() const;
00652     \brief Retorna \c "true" si todas las pruebas han sido exitosas.
00653     - Sinónimo de <code>(successCount() == runCount())</code>
00654 */
00655 /** \fn    std::string TestCase::getName() const;
00656     \brief Obtiene el nombre de la prueba. \see setName().
00657 */
00658 /** \fn    const std::string TestCase::report() const;
00659     \brief Retorna la hilera encabezado \c summary() seguido \c toString().
00660 */
00661 /** \fn    const std::string TestCase::failureString() const;
00662     \brief Sinónimo de \c toString().
00663 */
00664 /** \fn    void TestCase::recordSuccess();
00665     \brief Registra como exitoso el resultado de una prueba.
00666 */
00667 /** \fn    int  TestCase::nPass()  const;
00668     \brief Sinónimo de \c successCount() [OBSOLETO]. \deprecated
00669 */
00670 /** \fn    int  TestCase::nError() const;
00671     \brief Sinónimo de \c failureCount() [OBSOLETO]. \deprecated
00672 */
00673 /** \fn    virtual bool TestCase::iAmTestSuite() const;
00674     \brief Retorna \c false para \c TestCase.
00675 */
00676 /** \fn    TestCase::TestCase(const TestCase&);
00677     \brief Esta declaración \c "private" prohibe la copia de casos de prueba.
00678 */
00679 /** \fn    TestCase& TestCase::operator=(const TestCase&);
00680     \brief Esta declaración \c "private" prohibe la copia de casos de prueba.
00681 */
00682 #endif
00683 
00684 #ifdef Spanish_dox
00685 /** Constructor.
00686     Si no se indica el nombre en \c "name", después el nombre se obtiene
00687     invocando <code>typeid(*this).name()</code>.
00688 */
00689 #endif
00690 #ifdef English_dox
00691 /** Constructor.
00692     If no name is given to this constructor in \c "name", later the
00693     name will be obtained invoking <code>typeid(*this).name()</code>.
00694 */
00695 #endif
00696 /** \dontinclude test_BUnit.cpp
00697     \skipline    test::constructor()
00698     \until       }}
00699     \see         test_BUnit::test_constructor()
00700 */
00701 inline TestCase::TestCase(const char * name) :
00702     m_pass(0), m_failure(0), m_name(name),
00703     m_test_suite_destroy(false), m_failureList() { }
00704 
00705 #ifdef Spanish_dox
00706 /** Elimina todas las pruebas realizadas.
00707     - Anula los contadores de pruebas porque deja la clase en el estado
00708       inicial que tuvo al ser construida.
00709     - Borra el registro de pruebas no exitosas.
00710     - No borra el nombre de la prueba.
00711 */
00712 #endif
00713 #ifdef English_dox
00714 /** Discards all test runs.
00715     - Resets to cero al counters because the test case is left in
00716       the state it had when initially contructed.
00717     - Deletes the record for not successful tests.
00718     - Does not change the test case name.
00719 */
00720 #endif
00721 /** \dontinclude test_BUnit.cpp
00722     \skipline    test::reset()
00723     \until       }}
00724     \see         test_BUnit::test_reset()
00725 */
00726 inline void TestCase::reset() {
00727     m_pass =  m_failure = 0;
00728     m_failureList.clear();
00729 }
00730 
00731 inline std::string TestCase::getName() const {
00732     return ( m_name != 0 ? m_name : typeid(*this).name() );
00733 }
00734 
00735 #ifdef Spanish_dox
00736 /** Le cambia el nombre a la prueba por \c "name".
00737     - Si \c "name" es una hilera o puntero nulo, después
00738       usa <code>typeid(*this).name()</code> para obtener
00739       el nombre de la prueba.
00740 */
00741 #endif
00742 #ifdef English_dox
00743 /** Sets the test case name to \c "name".
00744     - When \c "name" is a null string or pointer, later
00745       <code>typeid(*this).name()</code> will be invoked
00746       to get the test´s name.
00747 */
00748 #endif
00749 /** \dontinclude test_BUnit.cpp
00750     \skipline    test::setName()
00751     \until       }}
00752     \see         test_BUnit::test_setName()
00753 */
00754 inline void TestCase::setName( const char * name ) {
00755     m_name = name;
00756 }
00757 
00758 #ifdef Spanish_dox
00759 /** Ejecuta la prueba <code>setUp(); run(); tearDown();</code>.
00760     - A diferencia de \c run(), este método sí establece el ambiente
00761       de prueba invocando \c setUp() y \c tearDown() antes y después
00762       de hacer la prueba.
00763 */
00764 #endif
00765 #ifdef English_dox
00766 /** Excecutes the test run <code>setUp(); run(); tearDown();</code>.
00767     - In contrast to \c run(), this method will setup the environment
00768       for the test run invoking \c setUp() and \c tearDown() before and
00769       after the test.
00770 */
00771 #endif
00772 /** \dontinclude test_BUnit.cpp
00773     \skipline    test::run()
00774     \until       }}
00775     \see         test_BUnit::test_run()
00776 */
00777 inline void TestCase::runBare( ) { setUp(); run(); tearDown(); }
00778 
00779 #ifdef Spanish_dox
00780 /** Establece el ambiente para la ejecución de la prueba.
00781     Esta clase existe para mejorar la compatibilidad con JUnit.
00782     \see TestCase::setUp()
00783 */
00784 #endif
00785 #ifdef English_dox
00786 /** Sets the environment for the test run.
00787     This clase exists to improve compatibility with JUnit.
00788     \see TestCase::setUp()
00789 */
00790 #endif
00791 typedef TestCase TestFixture;
00792 
00793 #ifdef Spanish_dox
00794 /** Establece el ambiente en que se realizará la prueba.
00795     - Como \c TestCase::run() es un método abstracto, para facilitar la
00796       programación lo usual es que el programador no incluya invocaciones
00797       a \c TestCase::setUp() y \c TestCase::tearDown() pues es más fácil
00798       dejar que lo haga \c TestSuite<TestCase>::runBare().
00799     - A diferencia de \c TestCase::runBare(), el método \c TestCase::run()
00800       no establece el ambiente de prueba porque no invoca ni a
00801       \c TestCase::setUp() antes de la prueba ni a \c TestCase::tearDown()
00802       después de la prueba.
00803     - \c TestSuite<TestCase>::runBare() invoca los métodos
00804       \c TestCase::setUp() y \c TestCase::tearDown() cuando ejecuta cada
00805       prueba.
00806     - Si el programador cliente quiere que cada prueba se ejecute luego de
00807       establecer el ambiente de la prueba, lo más práctico es que agregue
00808       sus pruebas a una colección de pruebas \c TestSuite para ejecutarlas
00809       con \c TestSuite<TestCase>::runBare().
00810 */
00811 #endif
00812 #ifdef English_dox
00813 /** Sets the environment for the test run.
00814     - As \c TestCase::run() is an abstract method, to facilitate
00815       programming it is usual for the programmer not to invoke
00816       \c TestCase::setUp() and \c TestCase::tearDown() because it is
00817       easier to have \c TestSuite<TestCase>::runBare() do it.
00818     - In contrast with \c TestCase::runBare(), method  \c TestCase::run()
00819       will not establish the test environment because it does not
00820       invoke neither \c TestCase::setUp() before the test run nor
00821       \c TestCase::tearDown() after the test run.
00822     - \c TestSuite<TestCase>::runBare() invokes methods
00823       \c TestCase::setUp() and \c TestCase::tearDown() when the test run
00824       is executed.
00825     - If the client programmer wants each test run  to stablish it test
00826       environment, it is easier to put all test cases into a test collection
00827       \c TestSuite and execute all of them invoking
00828       \c TestSuite<TestCase>::runBare().
00829 */
00830 #endif
00831 inline void TestCase::setUp() { }
00832 
00833 #ifdef Spanish_dox
00834 /// Destruye el ambiente de prueba.
00835 #endif
00836 #ifdef English_dox
00837 /// Destroys the test environment.
00838 #endif
00839 inline void TestCase::tearDown() {}
00840 
00841 #ifdef Spanish_dox
00842 /** Efectúa la prueba y registra su resultado.
00843     - Si la prueba fue exitosa sólo incrementa la cantidad de éxitos
00844       \c successCount().
00845     - Si la prueba no tuvo éxito reporta en \c toString() ese hecho.
00846     - El resultado de la prueba es \c "cond".
00847     - Los valores \c "fname" y \c "lineno" indican el archivo y el renglón
00848       en donde se ejecuta la prueba.
00849     - Usualmente los valores de \c "fname" y \c "lineno" se obtienen con
00850       las macros globales \c "__FILE__" y \c "__LINE__".
00851     - El valor \c "must_copy" indica que es necesario hacer una copia de la
00852       hilera \c "label", copia que será destruida cuando el registro de
00853       pruebas no exitosas sea borrado.
00854     - En la mayor parte de los casos, la hilera \c "label" es una constante
00855       generada por el preprocesador al usar la macro \c \#cond y por eso su
00856       memoria no debe ser retornada.
00857     Este método es invocado usando la macro \c BUnit_TEST().
00858 */
00859 #endif
00860 #ifdef English_dox
00861 /** Executes the test and records its result.
00862     - If the test is successful only increases the numbero of success
00863       \c successCount().
00864     - If the test is not successful reports in \c toString() this fact.
00865     - The result of the test is \c "cond".
00866     - Values \c "fname" and \c "lineno" show the file and line of the
00867       executed test.
00868     - Usuallyy \c "fname" and \c "lineno" are values obtained with global
00869       macros \c "__FILE__" and \c "__LINE__".
00870     - The value for \c "must_copy" indicates whether it is necessary to
00871       make a copy of string \c "label"; this copy will be destroyed when
00872       the record of not successful test is deleted.
00873     - Most of the time string \c "label" is a constant genertated by the
00874       preprocessor when using macro \c \#cond its memory must not be
00875       returned.
00876     This method is invoked using macro \c BUnit_TEST().
00877 */
00878 #endif
00879 /** \dontinclude test_BUnit.cpp
00880     \skipline    test::testThis()
00881     \until       }}
00882     \see         test_BUnit::test_testThis()
00883 */
00884 inline void TestCase::testThis(
00885     bool cond, const char * label, const char* fname, long lineno, bool must_copy )
00886 {
00887     if (cond) {
00888         recordSuccess();
00889     }
00890     else {
00891         recordFailure( label, fname, lineno, must_copy );
00892     }
00893 }
00894 
00895 #ifdef Spanish_dox
00896 /// Sinónimo de \c testThis().
00897 #endif
00898 #ifdef English_dox
00899 /// Synonym for \c testThis().
00900 #endif
00901 inline void TestCase::testThis(
00902     bool cond, const std::string& label, const char* fname, long lineno )
00903 {
00904     testThis( cond, label.c_str(), fname, lineno, true /* must_copy == true */ );
00905 /*  NOTE: In the class instance the name for the test case is stored as
00906     a (char*). If a std::string is used for "label", it must be converted to
00907     a (char*) that will have to be destroyed when the test instance gets
00908     destroyed. This is why parameter "must_copy" must be set to "true".
00909 */
00910 }
00911 
00912 #ifdef Spanish_dox
00913 /** Registra que la prueba no tuvo éxito.
00914     - Los valores \c "fname" y \c "lineno" indican el archivo y el renglón
00915       en donde se ejecuta la prueba.
00916     - Usualmente los valores de \c "fname" y \c "lineno" se obtienen invocando
00917       las macros globales \c "__FILE__" y \c "__LINE__".
00918     - El valor \c "must_copy" indica que es necesario hacer una copia de la
00919       hilera \c "label" en memoria dinámica. Este memoria dinámica será destruida
00920       cuando el caso de prueba sea destruido o cuando el método \c TestCase::reset()
00921       sea invocado.
00922     - En la mayor parte de los casos, la hilera \c "label" es una constante
00923       generada por el preprocesador al usar la macro \c \#cond; como esta hilera
00924       constante no está almacenada en la memoria dinámica no debe ser destruida.
00925 
00926     Este método es invocado usando la macro \c BUnit_FAILURE().
00927 */
00928 #endif
00929 #ifdef English_dox
00930 /**  Records that the test run did not succeed.
00931     - Values \c "fname" and \c "lineno" indicate the file and line where
00932       the test run is executed.
00933     - The values form \c "fname" and \c "lineno" are usuallly obtained
00934       invoking global macros \c "__FILE__" and \c "__LINE__".
00935     - \c "must_copy" forces a copy of string label to be created in dynamic
00936       memory. This dynamic memory will be destroyed when the test case gets
00937       destroyed or when method \c TestCase::reset() gets invoked.
00938     - Oftentimes string \c "label" is a constant string generated by the
00939       preprocessor macro using \c \#cond; this string constant is not stored
00940       in dynamic memory and it must not be destroyed.
00941 
00942     This method is invoked using macro \c BUnit_FAILURE().
00943 */
00944 #endif
00945 inline void TestCase::recordFailure(
00946     const char* label, const char* fname, int lineno, bool must_copy )
00947 {
00948     if ( must_copy ) {
00949         size_t len = strlen(label)+1;
00950         char* str = new char[ len ]; // copies the failure message
00951         memcpy( str, label, len );
00952         label = str;
00953     }
00954     m_failureList.push_back( TestCaseFailure ( fname, lineno, label, must_copy ) );
00955     m_failure++;
00956 /*  NOTE: When this method is invoked directly it is because "label" is a
00957     constant (char*) string, produced by one of the BUnit_TEST() macro using
00958     operator "#" (as in #cond). As this is a constant string, it it not
00959     necessary to return its memory when the instance of "TestCase" gets
00960     destroyed and, as result of this, field "m_destroy_label" in the
00961     corresponding "TestCaseFailure" instance must be false.
00962 
00963     In contrast, when "label" is generated from std::string, the method
00964     recordFailure() to be invoked is not this. Intead the method invoked will be
00965     the other version of recordFailure() where parameter "label" is a std::string.
00966     That other version always uses "true" for "must_copy", because a (char*) copy
00967     of the original std::string is stored in the "TestCaseFailure" instance, and
00968     that value should be destroyed when that instance gets destroyed. This fact
00969     gets recorded in field "TestCaseFailure::m_destroy_label."
00970 
00971     This means that no extra work is necessary to handle the two different cases
00972     (char*) vs std::string, as the compiler chooses correctly which version of
00973     recordFailure() to use.
00974 */
00975 /*  NOTA: Cuando este método es invocado directamente es porque "label" es una
00976     hilera constante (char*), producida por alguna de las macro BUnit_TEST()
00977     mediante el operador "#" (como en #cond). Como esa hilera es constante, no
00978     hace falta retornar su memoria cuando la instancia de "TestCase" sea destruida
00979     y, en consecuencia, el campo "m_destroy_label" de la instancia de
00980     "TestCaseFailure" correspondiente debe ser "false".
00981 
00982     En contraposición, si la hilera "label" es generada a partir de std::string, el
00983     método recordFailure() que será invocado no es éste. Más bien será la otra
00984     versión de recordFailure() la invocada, pues en esa "label" es de tipo
00985     std::string. Esa otra versión siempre usa "true" para "must_copy", pues una
00986     copia (char*) del valor original std::string queda almacenada en la instancia
00987     "TestCaseFailure" y ese valor debe ser destruido cuando esa instancia sea
00988     destruida. Este hecho quda registrado en el campo "TestCaseFailure::m_destroy_label."
00989 
00990     Esto quiere decir que no hace falta hacer trabajo adicional para manejar los
00991     dos casos diferentes "char*" vs "std::string", pues el compilador escoge
00992     correctamente siempre cuál versión de recordFailure() que hay que usar.
00993 */
00994 }
00995 
00996 #ifdef Spanish_dox
00997 /// Registra que la prueba no tuvo éxito.
00998 /// - En \c BUnit.h no se hace diferencia entre "fallas" y "errores".
00999 #endif
01000 #ifdef English_dox
01001 /// Records that the test did not succeed.
01002 /// - En \c BUnit.h there is no difference between "failures" and "errors".
01003 #endif
01004 inline void TestCase::recordFailure(
01005     const std::string& label, const char* fname, int lineno )
01006 {
01007     recordFailure( label.c_str(), fname, lineno, true /* must_copy == true */ );
01008 /*  NOTE: as in here the (char*) version of recordFailure() is invoked for it to
01009     make a copy of "label.c_str()", argument "must_copy" must be set to "true".
01010     In this way field "TestCaseFailure::m_destroy_label" will be se to "true",
01011     and the (char*) memory for the copy of string  "label.c_str()" will be
01012     returned when the record for the "TestCaseFailure" is destroyed.
01013 */
01014 /*  NOTA: como aquí se invoca a la versión (char*) de recordFailure() para que
01015     haga una copia de "label.c_str()", el argumento "must_copy" debe ser "true".
01016     De esta manera el campo "TestCaseFailure::m_destroy_label" tomará el valor
01017     "true" y, en consecuencia, la memoria (char*) en donde quedó la copia de la
01018     hilera "label.c_str()" será retornada cuando el registro de la prueba
01019     "TestCaseFailure" sea destruido.
01020 */
01021 }
01022 
01023 #ifdef Spanish_dox
01024 /// Hilera "enooorme" que contiene copia del registro de pruebas no exitosas, separados por \c "\n".
01025 #endif
01026 /// Huuuge string that holds a copy of non successfull test, separated by \c "\n".
01027 #ifdef English_dox
01028 #endif
01029 /** \code
01030     =\_fail: 1 == 0
01031     =/ (125) X:/DIR/SubDir/test_BUnit.cpp
01032     =\_fail: 4 == 0
01033     =/ (128) X:/DIR/SubDir/test_BUnit.cpp
01034     \endcode
01035 */
01036 inline const std::string TestCase::toString() const {
01037 //  typedef basic_ostringstream<char> ostringstream;
01038     std::basic_ostringstream<char> ost; // ostringstream ost;
01039     do_toString( this , ost );
01040     return ost.str();
01041 }
01042 
01043 #ifdef Spanish_dox
01044 /// Le agrega a \c ost la hilera de todas las pruebas no exitosas de \c *tc.
01045 #endif
01046 #ifdef English_dox
01047 /// Adds to \c ost the string of al unsuccessful test from  \c *tc.
01048 #endif
01049 template <class TestCase>
01050 void do_toString( const TestCase * tc , std::basic_ostringstream<char> & ost ) {
01051     std::list<TestCaseFailure>::const_iterator it = tc->m_failureList.begin();
01052     for ( ; it != tc->m_failureList.end(); ++it) {
01053         ost << "=\\_fail: " << it->m_label << " \n=/ ("
01054             << it->m_lineno << ") " << it->m_fname << "\n";
01055     }
01056     return;
01057 /*  NOTA: La implementación de "TestCase::toString()" está hecha invocando esta
01058     función emplantillada para que sea el compilador el responsable de remover
01059     versiones duplicadas de esta misma rutina, las que se producen cuando este
01060     archivo de encabezado ("BUnit.h") es incluido en varios archivos "*.cpp".
01061     Todo esto hay que hacerlo para que "BUnit.h" quepa, completo, en un único
01062     archivo de encabezado.
01063 */
01064 /*  NOTE: the implementation for "TestCase:toString()" is made invoking this
01065     template function for the compiler to be responsible of removing duplicate
01066     versions of this same routine, which would be produced when this header file
01067     ("BUnit.h") gets included in several "*.cpp" files. All this must be done
01068     for "BUnit.h" to fit, completely,  in a single header file.
01069 */
01070 }
01071 
01072 #ifdef Spanish_dox
01073 /// Hilera XML que contiene una copia de las pruebas no exitosas.
01074 #endif
01075 #ifdef English_dox
01076 /// XML string that holds a copy of all unsuccessful tests.
01077 #endif
01078 /** \code
01079     <fail file="X:/DIR/SubDir/test_BUnit.cpp" line="125" message="1 == 0"/>
01080     <fail file="X:/DIR/SubDir/test_BUnit.cpp" line="128" message="4 == 0"/>
01081     \endcode
01082 */
01083 inline const std::string TestCase::toXML() const {
01084 //  typedef basic_ostringstream<char> ostringstream;
01085     std::basic_ostringstream<char> ost; // ostringstream ost;
01086     do_toXML( this , ost );
01087     return ost.str();
01088 }
01089 
01090 #ifdef Spanish_dox
01091 /// Le agrega a \c ost la hilera de todas las pruebas no exitosas de \c *tc en formato XML.
01092 #endif
01093 #ifdef English_dox
01094 /// Adds to \c ost the string of al unsuccessful test from  \c *tc in XML format
01095 #endif
01096 template <class TestCase>
01097 void do_toXML( const TestCase * tc , std::basic_ostringstream<char> & ost ) {
01098     std::list<TestCaseFailure>::const_iterator it = tc->m_failureList.begin();
01099     for ( ; it != tc->m_failureList.end(); ++it ) {
01100         ost << "<fail file=\"" << it->m_fname
01101             << "\" line=\"" << it->m_lineno
01102             << "\" message=\"" << it->m_label  << "\"/>" << std::endl;
01103     }
01104     return;
01105 /*  NOTE: the implementation for "TestCase:toXML()" is made invoking this
01106     template function for the compiler to be responsible of removing duplicate
01107     versions of this same routine, which would be produced when this header file
01108     ("BUnit.h") gets included in several "*.cpp" files.
01109 */
01110 /*  NOTA: La implementación de "TestCase::toXML()" está hecha invocando a la
01111     función emplantillada para que sea el compilador el responsable de remover
01112     versiones duplicadas de esta misma rutina, las que se producen cuando este
01113     archivo de encabezado ("BUnit.h") es incluido en varios archivos "*.cpp".
01114 */
01115 }
01116 
01117 /// [BUnit] ==> BUnit.h
01118 #define TEST_BUnit()
01119 #undef  TEST_BUnit
01120 
01121 #ifdef Spanish_dox
01122 /** [BUnit] Efectúa la prueba \c "cond y registra el resultado.
01123     - Es más elegante usar \c assertTrue() que hace lo mismo.
01124     - Si la prueba \c "cond" tiene éxito invoca el método
01125       \c TestCase::recordSuccess().
01126     - Si la prueba \c "cond" no tiene éxito invoca el método
01127       \c TestCase::recordFailure().
01128 */
01129 #endif
01130 #ifdef English_dox
01131 /** [BUnit] Executes test \c "cond and records its result.
01132     - It is more elegant to use \c assertTrue() for the same purpose.
01133     - If test \c "cond" is successful method \c TestCase::recordSuccess()
01134       is invoked.
01135     - If test \c "cond" is not successful, method\c TestCase::recordFailure()
01136       is invoked.
01137 */
01138 #endif
01139 /** \dontinclude test_BUnit.cpp
01140     \skipline    test::BUnit_macro()
01141     \until       }}
01142     \see         test_BUnit::test_BUnit_macro()
01143 */
01144 #define BUnit_TEST(cond) testThis( cond, #cond, __FILE__, __LINE__ )
01145 
01146 #ifdef Spanish_dox
01147 /// [BUnit] Macro similar a \c BUnit_TEST() que usa el mensaje \c "msg".
01148 /// - El mensaje \c "msg" debe ser una hilera (char*) literal o un objeto
01149 ///   que pueda convertirse en <code>(const char *)</code>.
01150 #endif
01151 #ifdef English_dox
01152 /// [BUnit] Macro similar to \c BUnit_TEST() that uses mesaje \c "msg".
01153 /// - Mensaje \c "msg" must be a literal (char*) string or and object that
01154 ///   can be converted into a <code>(const char *)</code>.
01155 #endif
01156 #define BUnit_TEST_Msg(msg, cond) testThis( cond, msg, __FILE__, __LINE__ )
01157 
01158 #ifdef Spanish_dox
01159 /** [BUnit] Registra como "falla" el resultado de una prueba.
01160     - El programador cliente es quien determinó que la prueba no tuvo éxito
01161       y quiere registrar ese hecho.
01162     - Está implementado comun una macro que sirve de empaque para invocar
01163       el método \c TestCase::recordFailure().
01164 */
01165 #endif
01166 #ifdef English_dox
01167 /** [BUnit] Records as "failure" the result of a test.
01168     - The client programmer determined that the test did not succeed
01169       and wants to record this fact.
01170     - It is implemented as a macro wrapper to invoke method
01171       \c TestCase::recordFailure().
01172 */
01173 #endif
01174 /** \see BUnit_TEST()
01175     \code
01176     if (22==33) {
01177         BUnit_FAILURE("! (22==33)"); // records failure
01178     }
01179     \endcode
01180 */
01181 #define BUnit_FAILURE(msg) recordFailure( msg, __FILE__, __LINE__ )
01182 
01183 #ifdef Spanish_dox
01184 /** [BUnit] Registra como "exitoso" el resultado de una prueba.
01185     - El programador cliente es quien determinó que la prueba
01186       fue exitosa y quiere registrar ese hecho.
01187     - Generalmente se usa después de atrapar una excepción que
01188       se supone debió ser lanzada como resultado de la prueba.
01189     - Está implementado como una macro que invoca el método
01190       \c TestCase::recordSuccess().
01191     \see BUnit_TEST()
01192 */
01193 #endif
01194 #ifdef English_dox
01195 /** [BUnit] Records as "successful" the result of a test.
01196     - The client programmer determined that the test did succeed
01197       and wants to record this fact.
01198     - Usually used after catching an exception that should have
01199       been raised as result of the test.
01200     - It is implemented as a macro wrapper to invoke method
01201       \c TestCase::recordSuccess().
01202     \see BUnit_TEST()
01203 */
01204 #endif
01205 #define BUnit_SUCCESS() recordSuccess()
01206 
01207 #ifdef Spanish_dox
01208 /// [BUnit] Efectúa la prueba para determinar si <code>(expected == actual)</code>.
01209 /// - Si la prueba tiene éxito invoca el método \c TestCase::recordSuccess().
01210 /// - De otra manera invoa \c TestCase::recordFailure().
01211 /// - Esta es una una macro que invoca el método \c TestCase::testThis().
01212 ///  \see BUnit_TEST()
01213 #endif
01214 #ifdef English_dox
01215 /// [BUnit] Executes the test to determine if <code>(expected == actual)</code>.
01216 /// - On success invokes method \c TestCase::recordSuccess().
01217 /// - Otherwise invokes \c TestCase::recordFailure().
01218 /// - This is a macro to invoke method \c TestCase::testThis().
01219 ///  \see BUnit_TEST()
01220 #endif
01221 #define BUnit_EQUAL(expected, actual) \
01222         testThis( (expected) == (actual), #expected " == " #actual, __FILE__, __LINE__ )
01223 
01224 #ifdef Spanish_dox
01225 /// [BUnit] Efectúa la prueba para determinar si <code>expected == actual</code>.
01226 /// - Si la prueba tiene éxito invoca el método
01227 ///   \c TestCase::recordSuccess().
01228 /// - Si la prueba no tiene éxito invoca el método
01229 ///   \c TestCase::recordFailure().
01230 /// - Esta es una una macro que invoca el método
01231 ///   \c TestCase::testThis().
01232 /// - Registra el mensaje \c "MSG" si la prueba no tiene éxito.
01233 /// \see BUnit_TEST()
01234 #endif
01235 #ifdef English_dox
01236 /// [BUnit] Executes the test to determine if <code>(expected == actual)</code>.
01237 /// - On success invokes method \c TestCase::recordSuccess().
01238 /// - Otherwise invokes \c TestCase::recordFailure().
01239 /// - This is a macro to invoke method \c TestCase::testThis().
01240 /// - Records messaje \c "MSG" if the test is not successful.
01241 ///  \see BUnit_TEST()
01242 #endif
01243 #define BUnit_EQUAL_Msg(MSG, expected, actual) \
01244         testThis( (expected) == (actual), MSG, __FILE__, __LINE__ )
01245 
01246 #ifdef Spanish_dox
01247 /// Retorna un hilera que contiene el nombre, cantidad de éxitos y fallas.
01248 #endif
01249 #ifdef English_dox
01250 /// Returns a string with the name, number of successes and failures.
01251 #endif
01252 inline const std::string TestCase::summary() const {
01253     std::string res = "TestCase [" + getName() + ']';
01254     res += " (OK: "   + TestCase::toString( successCount() ) + ')';
01255     res += " (FAIL: " + TestCase::toString( failureCount() ) + ')';
01256     return res;
01257 }
01258 
01259 /************************\
01260 **************************
01261 **                      **
01262 **      TestSuite       **
01263 **                      **
01264 **************************
01265 \************************/
01266 // template <class TestCase> class TestSuite
01267 #ifdef Spanish_dox
01268 /** \class TestSuite
01269     \brief Colección de pruebas.
01270     - Este un contenedor simple con una interfaz similar a la de la clase
01271       \c TestCase.
01272     - Cada una de las pruebas de la colección es ejecutada mediante la
01273       invocación a su método \c TestCase::run().
01274     - El método \c TestSuite<TestCase>::runBare() es similar a
01275       \c TestSuite<TestCase>::run(), pero antes de hacer cada prueba establece
01276       el ambientede ejecución de la prueba invocando a \c TestCase::setUp()
01277       y a \c TestCase::tearDown() después de realizarla.
01278     - Debido al uso de los métodos \c setUp() y \c tearDown() para ejecutar
01279       las pruebas de la colección, cada prueba queda "aisalda" de las demás,
01280       pues para cada una se estable el ambiente de ejecución que promete la
01281       clase \c TestCase.
01282     - Está implementado como una plantilla para evitar usar un archivo
01283       \c "BUnit.cpp", de manera que para probar programas baste incluir
01284       únicamente este archivo \c "BUnit.h".
01285 
01286     \par Truco para evitar usar el archivo \c "BUnit.cpp"
01287 
01288     - Al implementar la plantilla \c TestSuite<> usé como parámetro el identificador
01289       \c TestCase, que también es el nombre de la clase de la que \c TestSuite<> se
01290       deriva. Este doble uso del mismo identificador confunde al compilador, porque
01291       no puede deducir que el parámetro \c TestCase también es el nombre de la clase
01292       base. Por eso, uso un sinónimo para nombrar a la clase base de \c TestSuite<>.
01293       Escogí el identificador \c TestCase_is_base_for_TestSuite  porque es
01294       descriptivo y bastante largo, por lo que es muy poco probable que un
01295       programador cliente de \c BUnit.h necesite usarlo.
01296     - La clase \c TestSuite<> está implementada usando plantillas para evitar
01297       forzar al programador cliente de \c "BUnit" a usar 2 archivos, uno de
01298       encabezado \c "BUnit.h" y otro de implementación \c "BUnit.cpp". Como no
01299       hace falta usar el archivo \c "BUnit.cpp", implementar programas de
01300       prueba es muy sencillo pues al programar las pruebas solo se necesita
01301       agregar este único renglón:
01302       - <code>\#include "BUnit.h"</code>
01303     - Si toda la implementación de \c "BUnit" está contenida en el archivo de
01304       encabezado de \c "BUnit.h", puede ocurrir que algunas rutinas queden
01305       duplicadas en el programa objeto cuando el encabezado \c "BUnit.h" es
01306       incluido en varios archivos \c ".cpp" diferentes en el mismo proyecto.
01307       En estos casos, los métodos que no son <em>"inline"</em> quedan
01308       definidos en varios archivos y, en consecuencia, el editor de
01309       eslabonamiento (<em>"linker"</em>) debe reportar que el mismo módulo
01310       objeto está presente en varios archivos objeto. Cuando se usan
01311       plantillas, el sistema de compilacición se encarga de manejar esta
01312       duplicación, lo que releva al programador de esta engorrosa
01313       responsabilidad. Esto explica por qué \c TestSuite<> es una clase
01314       emplantillada.
01315     - La otra forma de lograr evitar la duplicación de módulos objetos es
01316       obligar a los programadores cliente a incluir en su proyecto el archivo
01317       \c "BUnit.cpp" en donde estarían las definiciones de las funciones que
01318       no son <em>"inline"</em>.
01319 
01320     - En otras palabras, el requerimiento de lograr que todas la
01321       implementación de \c BUnit.h esté metida en un sólo archivo obliga a
01322       implementar \c TestSuite<> con plantillas, lo que a también motiva el
01323       uso de \c TestCase como nombre del parámetro para la plantilla
01324       \c TestSuite<>.
01325     - Dicho de otra manera: la razón por la que \c TestSuite<> está
01326       implementada con plantillas es lograr que la responsabilidad de eliminar
01327       duplicados de métodos y funciones caiga en el sistema de compilación,
01328       pues de lo contrario sería necesario que los programadores cliente incluyan
01329       en su proyecto el archivo de implementación \c "BUnit.cpp", lo que haría
01330       más complicado el uso de \c BUnit. Este truco de programación hace que
01331       sea trabajo del compilador manejar el código de implementación que de
01332       otra manera habria habido que poner dentro de un archivo de
01333       implementación \c "BUnit.cpp".
01334 */
01335 #endif
01336 #ifdef English_dox
01337 /** \class TestSuite;
01338     \brief Test collection.
01339     - This is a container with an interface similar to class \c TestCase.
01340     - Each test case in the collection is executed invoking its \c TestCase::run()
01341       method.
01342     - Method \c TestSuite<TestCase>::runBare() is similar to
01343       \c TestSuite<TestCase>::run(), but before each test the test environment
01344       for the test is established invoking \c TestCase::setUp() and
01345       \c TestCase::tearDown() afterwards.
01346     - Because of the use of methods \c setUp() and \c tearDown() to exectute test
01347       in the collection, each tests becomes "isolated" from the rest, because
01348       each stablishes its execution environment promised by class \c TestCase.
01349     - This implementation uses templates to avoid using a file \c "BUnit.cpp",
01350       to allow program testis using a single include of file \c "BUnit.h".
01351 
01352     \par Trick to avoid using file \c "BUnit.cpp"
01353 
01354     - When implementing the \c TestSuite<> template I used as parameter identifier
01355       \c TestCase, which is also the name for the class from where \c TestSuite<>
01356       is derived. This dual use of the same identifier confuses the compiler,
01357       because it can not figure out that parameter \c TestCase is also the name
01358       for the base class. Therefore, I use a synonym to name the base class for
01359       \c TestSuite<>. I chose identifier \c TestCase_is_base_for_TestSuite
01360       because it is descriptive and quite long, so it is very unlikely that client
01361       programmer of \c BUnit.h would ever need to use it.
01362     - Class \c TestSuite<> is implemented using templates to avoid forcing the
01363       client programmer  of \c "BUnit" to use 2 files, a header file
01364       \c "BUnit.h" and another to hold the implementation \c "BUnit.cpp." As
01365       there is no need to use the file \c "BUnit.cpp",  implementing test
01366       programs is easy because programming test cases only requires adding
01367       this single line:
01368       - <code>\#include "BUnit.h"</code>
01369     - If the entire implementation of \c "BUnit" is contained in  header file
01370       \c "BUnit.h", it may happen that some routines get duplicated in the
01371       object code when header file \c "BUnit.h" is included from several
01372       different \c ".cpp" files in the same project. In these cases, methods
01373       that are not <em>"inline"</em> are defined in several files and,
01374       consequently, the linkage editor (<em>"linker"</em>) should report that
01375       the same  object module is present in several object files. When
01376       templates are used, the compiling system is responsible for managing
01377       this duplicating what relieves the programmer of this cumbersome
01378       responsibility. This explains why \c TestSuite<> is a template class.
01379     - Another way to avoid duplication of object modules it to force the
01380       client programmers to include in their project file \c "BUnit.cpp"
01381       containing all definition for non <em>"inline"</em> functions.
01382 
01383     - In other words, the requirement to make all the implementatation of
01384       \c BUnit.h to fit into a single file forces implementing
01385       \c TestSuite<> with templates, which also motivates the use
01386       \c TestCase as the name name of the parameter template
01387       \c TestSuite<>.
01388     - Put in another way: the reason why \c TestSuite<> is implemented with
01389       templates is to ensure that the responsibility for removing duplicate
01390       functions and methods belongs to the compiling system, as otherwise the
01391       client programmers would be required to include in their proyect
01392       implementation file \c "BUnit.cpp", which would make more complicated
01393       using \c BUnit. This programming trick puts the compiler in charge of
01394       handling the implementation coide that otherwise would have been put in
01395       an implementation file\c "BUnit.cpp."
01396 */
01397 #endif
01398 
01399 #ifdef Spanish_dox
01400 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::container_type;
01401     \brief Tipo del contenedor (escoja el que prefiera).
01402 */
01403 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::iterator;
01404     \brief Iterador del contenedor.
01405 */
01406 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::cons_iterator;
01407     \brief Iterador del contenedor (\c const).
01408 */
01409 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::const_container_type;
01410     \brief Tipo del contenedor (\c const).
01411 */
01412 /** \fn    template <class TestCase> container_type TestSuite<TestCase>::m_allTest;
01413     \brief Contenedor en donde se almacenan los punteros a las pruebas.
01414 */
01415 #endif
01416 #ifdef English_dox
01417 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::container_type;
01418     \brief Container type (choice your preferred).
01419 */
01420 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::iterator;
01421     \brief Container iterador.
01422 */
01423 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::cons_iterator;
01424     \brief Container iterador (\c const).
01425 */
01426 /** \fn    template <class TestCase> typedef TestSuite<TestCase>::const_container_type;
01427     \brief Container type (\c const).
01428 */
01429 /** \fn    template <class TestCase> container_type TestSuite<TestCase>::m_allTest;
01430     \brief Container to store pointers to tests.
01431 */
01432 #endif
01433 
01434 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite(const char * name=0);
01435     \brief Constructor
01436 */
01437 
01438 #ifdef Spanish_dox
01439 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite(const char * name=0);
01440     \brief Constructor.
01441 */
01442 /** \fn    template <class TestCase> int  TestSuite<TestCase>::countTestCases() const;
01443     \brief Cantidad de casos de prueba.
01444 */
01445 /** \fn    template <class TestCase> int TestSuite<TestCase>::failureCount() const;
01446     \brief Cantidad de pruebas que fallaron. \see reset().
01447 */
01448 /** \fn    template <class TestCase> int TestSuite<TestCase>::successCount() const;
01449     \brief Cantidad de pruebas exitosas. \see reset().
01450 */
01451 /** \fn    template <class TestCase> void TestSuite<TestCase>::reset();
01452     \brief Elimina todas las pruebas realizadas.
01453 */
01454 /** \fn    template <class TestCase> TestSuite<TestCase>::const_container_type& TestSuite<TestCase>::allTests() const;
01455     \brief Referencia al contenedor con todos los casos de prueba.
01456 */
01457 /** \fn    template <class TestCase> const std::string TestSuite<TestCase>::toString() const;
01458     \brief Hilera "enooorme" que contiene copia del registro de pruebas no exitosas, separados por \c "\n".
01459 */
01460 /** \fn    template <class TestCase> const std::string TestSuite<TestCase>::toXML() const;
01461     \brief Hilera XML que contiene una copia de las pruebas no exitosas.
01462 */
01463 /** \fn    template <class TestCase> bool TestSuite<TestCase>::iAmTestSuite() const { return true; }
01464     \brief Retorna \c true solo para la clase derivada \c TestSuite<>.
01465 */
01466 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite(const TestSuite& DONTcopy);
01467     \brief Esta declaración \c "private" prohibe la copia de casos de prueba.
01468 */
01469 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite& TestSuite<TestCase>::operator=(const TestSuite& DONTcopy);
01470     \brief Esta declaración \c "private" prohibe la copia de casos de prueba.
01471 */
01472 #endif
01473 #ifdef English_dox
01474 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite(const char * name=0);
01475     \brief Constructor.
01476 */
01477 /** \fn    template <class TestCase> int  TestSuite<TestCase>::countTestCases() const;
01478     \brief Number of test cases.
01479 */
01480 /** \fn    template <class TestCase> int TestSuite<TestCase>::failureCount() const;
01481     \brief Number of test runs that failed. \see reset().
01482 */
01483 /** \fn    template <class TestCase> int TestSuite<TestCase>::successCount() const;
01484     \brief Number of successful test runs. \see reset().
01485 */
01486 /** \fn    template <class TestCase> void TestSuite<TestCase>::reset();
01487     \brief Discards all test runs.
01488 */
01489 /** \fn    template <class TestCase> TestSuite<TestCase>::const_container_type& TestSuite<TestCase>::allTests() const;
01490     \brief Reference to the container where al the test runs are stored.
01491 */
01492 /** \fn    template <class TestCase> const std::string TestSuite<TestCase>::toString() const;
01493     \brief Huuuge string that holds a copy of non successfull test, separated by \c "\n".
01494 */
01495 /** \fn    template <class TestCase> const std::string TestSuite<TestCase>::toXML() const;
01496     \brief XML string that holds a copy of all unsuccessful tests.
01497 */
01498 /** \fn    template <class TestCase> bool TestSuite<TestCase>::iAmTestSuite() const { return true; }
01499     \brief Returns \c true only for derived class \c TestSuite<>.
01500 */
01501 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite(const TestSuite& DONTcopy);
01502     \brief This \c "private" declaration forbids test case copying.
01503 */
01504 /** \fn    template <class TestCase> TestSuite<TestCase>::TestSuite& TestSuite<TestCase>::operator=(const TestSuite& DONTcopy);
01505     \brief This \c "private" declaration forbids test case copying.
01506 */
01507 #endif
01508 
01509 #if 0
01510     #ifdef Spanish_dox
01511     /// Acumula los resultados de pruebas que no tienen éxito.
01512     #endif
01513     #ifdef English_dox
01514     /// Holds results for non successful tests.
01515     #endif
01516     class TestResult { }; // not declared
01517 /*  NOTE
01518     As the class TestSuite<> is derived from TestCase, it also
01519     contains a list of tests that have not been successful. That list
01520     is always empty, because the failure logging is carried out
01521     individually, in each instance of TestCase stored in the
01522     TestSuite<> instance. Should BUnit had a TestResult class it would
01523     not be necessary to keep this empty lista.
01524     - To simplify BUunit it contains no TestResult class.
01525 */
01526 /*  NOTA
01527     Como la clase TestSuite<> está derivada de TestCase, también
01528     contiene una lista de pruebas que no han tenido éxito. Esa lista
01529     siempre está vacía, pues el registro de fallas se lleva
01530     individualmente, en cada una de las instancias de TestCase
01531     almacenadas en la instancia de TestSuite. Si BUnit tuviera una
01532     clase TestResult no sería necesario mantener esta lista vacía.
01533     - Para simplificar BUnit no contiene la clase TestResult.
01534 */
01535 #endif
01536 
01537 #ifdef Spanish_dox
01538 /** Agrega la prueba \c "*pT" a la colección \c "*this" (y luego la destruirá).
01539     - Si <code>(pT == 0)</code> no agrega nada y retorna \c "false".
01540     - Es incorrecto que la misma prueba esté más de una vez en la colección.
01541     - Destruirá \c "*pT" cuando \c "*this" sea destruido.
01542     - El parámetro \c "pT" es un puntero.
01543     - Si \c "pT" es una colección de pruebas el efecto es similar a invocar
01544       \c addSuite(*pT) directamente.
01545 */
01546 #endif
01547 #ifdef English_dox
01548 /** Adds test \c "*pT" to collection \c "*this" (and later it will be destroyed).
01549     - If <code>(pT == 0)</code> nothing is added and returns \c "false".
01550     - It is incorrect for the same test to be in more than one collection.
01551     - Will destroy \c "*pT" when \c "*this" is destroyed.
01552     - The \c "pT" parameter is a pointer.
01553     - If \c "pT" is a test colection the effect is similar to invoking
01554       \c addSuite(*pT) directly.
01555 */
01556 #endif
01557 /** \dontinclude test_BUnit.cpp
01558     \skipline    test::addTest()
01559     \until       }}
01560     \see         test_BUnit::test_addTest()
01561 */
01562 template <class TestCase>
01563 bool TestSuite<TestCase>::addTest(TestCase* pT) {
01564     if (pT == 0) {
01565         return false;
01566     }
01567     if ( pT->iAmTestSuite() ) {  // ==> addSuite()
01568         addSuite( *( reinterpret_cast< TestSuite<TestCase>* > ( pT ) ) );
01569         return true;
01570     }
01571     else if ( m_allTest.end() != std::find(m_allTest.begin(), m_allTest.end(), pT) ) {
01572         return false; // never trust the client programmer
01573     }
01574     else {
01575         m_allTest.push_back( pT );
01576         pT->m_test_suite_destroy = true;
01577         return true;
01578     }
01579 }
01580 
01581 #ifdef Spanish_dox
01582 /** Agrega la prueba \c "T" a la colección  \c "*this" (no la destruirá).
01583     - No destruirá \c "T" cuando \c "*this" sea destruido.
01584     - El parámetro \c "T" es una referencia.
01585     - Si \c "T" es una colección de pruebas el efecto es similar a invocar
01586       \c addSuite(T) directamente.
01587 */
01588 #endif
01589 #ifdef English_dox
01590 /** Adds test \c "T" to collection \c "*this" (and later it will not be destroyed).
01591     - Will not destroy \c "T" when \c "*this" is destroyed.
01592     - The \c "T" parameter is a reference.
01593     - If \c "pT" is a test colection the effect is similar to invoking
01594       \c addSuite(T) directly.
01595 */
01596 #endif
01597 /** \dontinclude test_BUnit.cpp
01598     \skipline    test::addTest()
01599     \until       }}
01600     \see         test_BUnit::test_addTest()
01601 */
01602 template <class TestCase>
01603 bool TestSuite<TestCase>::addTest(TestCase& T) {
01604     if ( T.iAmTestSuite() ) { // ==> addSuite()
01605         addSuite( *( reinterpret_cast< TestSuite<TestCase>* > ( & T ) ) );
01606         return true;
01607     }
01608     else if ( addTest(& T) ) {
01609         T.m_test_suite_destroy = false;
01610         return true;
01611     }
01612     else {
01613         return false;
01614     }
01615 }
01616 
01617 #ifdef Spanish_dox
01618 /** Traslada todas las pruebas de la colección \c "SSS" y las agrega a \c "*this".
01619     - Deja a \c "SSS" vacía.
01620     - No copia las pruebas de \c SSS para evitar los problemas que surgen cuando
01621       tanto \c "SSS" como \c "*this" tratan de destruir la misma prueba.
01622     - No es posible hacer una jerarquía de pruebas pues todas quedan aplanadas
01623       en un sola colección.
01624 */
01625 #endif
01626 #ifdef English_dox
01627 /** Moves all test from collection \c "SSS" and ads them to \c "*this".
01628     - Leaves \c "SSS" empty.
01629     - Will not copy tests form \c SSS to avoid problems that come up when
01630       both \c "SSS" and \c "*this" try to destroy the same test.
01631     - It is not possible to make a test hierarchy because all become
01632       flattened in a single collection.
01633 */
01634 #endif
01635 
01636 template <class TestCase>
01637 inline void TestSuite<TestCase>::addSuite( TestSuite& SSS ) {
01638     if (&SSS == 0) { // SSS = (TestSuite<TestCase>*)(0);
01639         return;
01640     }
01641     if ( this == &SSS ) {
01642         return; // avoid self-copy
01643     }
01644     while ( ! SSS.m_allTest.empty() ) {
01645         iterator it = SSS.m_allTest.begin();
01646         if ( m_allTest.end() == std::find(m_allTest.begin(), m_allTest.end(), *it) ) {
01647             m_allTest.splice( m_allTest.end(), SSS.m_allTest, it );
01648         }
01649         else {
01650             SSS.m_allTest.pop_front(); // discards duplicate
01651         }
01652     }
01653     SSS.reset(); // reset counters
01654 }
01655 
01656 #ifdef Spanish_dox
01657 /** Destructor.
01658     - Solo destruye aquellas pruebas que hayan sido agregadas con
01659       \c TestSuite<TestCase>::addTest(TestCase* T) (puntero).
01660     - No destruye las pruebas que fueron agregadas con
01661       \c TestSuite<TestCase>::addTest(TestCase& T) (referencia).
01662 */
01663 #endif
01664 #ifdef English_dox
01665 /** Destructor.
01666     - Will destroy only those test that where addes with
01667       \c TestSuite<TestCase>::addTest(TestCase* T) (pointer).
01668     - Will not destroy those test that where addes with
01669       \c TestSuite<TestCase>::addTest(TestCase& T) (reference).
01670 */
01671 #endif
01672 template <class TestCase>
01673 TestSuite<TestCase>::~TestSuite() {
01674     container_type::const_iterator it = m_allTest.begin();
01675     while ( it != m_allTest.end() ) {
01676         if ( (*it)->m_test_suite_destroy ) {
01677             delete (*it);
01678         }
01679         ++it;
01680     }
01681     m_allTest.clear();
01682 }
01683 
01684 #ifdef Spanish_dox
01685 /** Invoca \c TestCase::run() para cada prueba en la colección.
01686     - No invoca los métodos \c TestCase::setUp() y \c TestCase::tearDown()
01687       cuando ejecuta cada prueba.
01688     - No invoca \c TestSuite<TestCase>::reset() antes de cada prueba.
01689     - Retorna \c "true" cuando todas las pruebas han tenido éxito (inclusive
01690       aquellas que fueron corridas antes de la invocación actual).
01691 */
01692 #endif
01693 #ifdef English_dox
01694 /** Invokes \c TestCase::run() for each test in the collection.
01695     - Will not invoke methods \c TestCase::setUp() and \c TestCase::tearDown()
01696       when executing each test.
01697     - Will not invoke \c TestSuite<TestCase>::reset() before each test.
01698     - Returns \c "true" when al test have been successful (even those
01699       that were run before this invocation).
01700 */
01701 #endif
01702 template <class TestCase>
01703 bool TestSuite<TestCase>::run() {
01704     bool res = true;
01705     container_type::const_iterator it = m_allTest.begin();
01706     for ( ; it != m_allTest.end(); ++it ) {
01707         (*it)->run(); // hace la prueba
01708     }
01709     return wasSuccessful();
01710 }
01711 
01712 #ifdef Spanish_dox
01713 /** Invoca \c TestCase::runBare() para cada prueba en la colección.
01714     - Si invoca \c TestSuite<TestCase>::reset() antes de hacer cada prueba.
01715     - Si invoca \c TestCase::setUp() antes de cada prueba
01716     - Si invoca \c TestCase::tearDown() después de cada prueba.
01717 */
01718 #endif
01719 #ifdef English_dox
01720 /** Invokes \c TestCase::runBare() for each test in the collection.
01721     - Will invoke \c TestSuite<TestCase>::reset() before each test.
01722     - Will invoke \c TestCase::setUp() before each test.
01723     - Will invoke \c TestCase::tearDown() after each test.
01724 */
01725 #endif
01726 /** \dontinclude test_BUnit.cpp
01727     \skipline    test::run()
01728     \until       }}
01729     \see         test_BUnit::test_run()
01730 */
01731 template <class TestCase>
01732 void TestSuite<TestCase>::runBare() {
01733     bool res = true;
01734     container_type::const_iterator it = m_allTest.begin();
01735     for ( ; it != m_allTest.end(); ++it ) {
01736         (*it)->reset();    // reset counters
01737         (*it)->setUp();    // setup test environment
01738         (*it)->run();      // run test
01739         (*it)->tearDown(); // reset test environment
01740     }
01741 }
01742 
01743 template <class TestCase>
01744 int TestSuite<TestCase>::failureCount() const {
01745     int n;
01746     const_container_type::const_iterator it = m_allTest.begin();
01747     for ( n = 0 ; it != m_allTest.end(); ++it ) {
01748         n += (*it)->failureCount();
01749     }
01750     return n;
01751 /*  NOTE: there is no choice but to count every test, as the client
01752     programmer could have run a test outside the collection, which
01753     would make counter TestSuite<TestCase>:m_failure to be outdated,
01754     because no mechanism is implemented for a "TestCase" to "tell"
01755     its "TestSuite<>" that it just executed "run()":
01756 */
01757 #if 0
01758     class MyTest : public TestCase { ... };
01759     TestSuite<TestCase> SSS;
01760     MyTest thisTest, *ptr_test = new MyTest;
01761     SSS.addTest( thisTest );
01762     SSS.addTest( ptr_test );
01763     SSS.run();      // exec [thisTest] + [*ptr_test]
01764     thisTest.run(); // exec [thisTest] ==> SSS ???
01765 #endif
01766 /*  NOTA: no queda más que contar todas las pruebas actuales, pues
01767     el programador cliente puede ejecutar alguna de las pruebas
01768     fuera de la colección, lo que haría que el contador
01769     TestSuite<TestCase>::m_failure quedara desactualizado, pues
01770     no está implementado un mecanismo para que el "TestCase" le
01771     "avise" a su "TestSuite<>" que acaba de ejecutar "run()".
01772 */
01773 }
01774 
01775 template <class TestCase>
01776 int TestSuite<TestCase>::successCount() const {
01777     int n;
01778     const_container_type::const_iterator it = m_allTest.begin();
01779     for ( n = 0 ; it != m_allTest.end(); ++it ) {
01780         n += (*it)->successCount();
01781     }
01782     return n;
01783 }
01784 
01785 
01786 template <class TestCase>
01787 void TestSuite<TestCase>::reset() {
01788     const_container_type::const_iterator it = m_allTest.begin();
01789     for ( ; it != m_allTest.end(); ++it ) {
01790         (*it)->reset();
01791     }
01792 }
01793 
01794 #ifdef Spanish_dox
01795 /// Retorna un hilera que contiene el nombre, cantidad de éxitos y fallas.
01796 #endif
01797 #ifdef English_dox
01798 /// Returns a string with the name, number of successes and failures.
01799 #endif
01800 template <class TestCase>
01801 inline const std::string TestSuite<TestCase>::summary() const {
01802     typedef TestCase_is_base_for_TestSuite TC;
01803     std::string res = "TestSuite [" + getName() + ']';
01804     res += " (OK: "   + TC::toString( successCount() ) + ')';
01805     res += " (FAIL: " + TC::toString( failureCount() )   + ')';
01806     return res;
01807 }
01808 
01809 template <class TestCase>
01810 const std::string TestSuite<TestCase>::toString() const {
01811     std::string failureString;
01812     TestSuite<TestCase>::container_type::const_iterator it;
01813     it = allTests().begin();
01814     for ( ; it != allTests().end(); ++it ) {
01815         failureString += (*it)->toString() ;
01816     }
01817     return failureString;
01818 }
01819 
01820 template <class TestCase>
01821 const std::string TestSuite<TestCase>::toXML() const {
01822     std::string XMLstring;
01823     TestSuite<TestCase>::container_type::const_iterator it;
01824     it = allTests().begin();
01825     for ( ; it != allTests().end(); ++it ) {
01826         XMLstring += (*it)->toXML() ;
01827     }
01828     return XMLstring;
01829 }
01830 
01831 /************************\
01832 **************************
01833 **                      **
01834 **       Macros         **
01835 **                      **
01836 **************************
01837 \************************/
01838 
01839 
01840 #ifdef Spanish_dox
01841 #endif
01842 #ifdef English_dox
01843 #endif
01844 
01845 #ifdef BUnit_DEFINE_check_ok
01846     /* These are macros used by Adolfo to define the invariant for a
01847        class. Many times the invariant checking function check_ok()
01848        does not exist which makes these functions irrelevant:
01849        - http://www.di-mare.com/adolfo/p/Rep.htm#sc-02
01850     */
01851     /* Estas son las macros usadas por Adolfo al definir la invariante
01852        de una clase. Muchas veces la función check_ok() usada para
01853        verificar invariante no existe, lo que hace irrelevantes estas
01854        definiciones:
01855        - http://www.di-mare.com/adolfo/p/Rep.htm#sc-02
01856     */
01857     #ifdef Spanish_dox
01858         /// Declaración genérica para \c check_ok().
01859     #endif
01860     #ifdef English_dox
01861         /// Generic declaration for \c check_ok().
01862     #endif
01863     template <class T> bool check_ok( const T& );
01864     inline bool check_ok( const double &        ) { return true; } ///< <code>check_ok() == true</code>
01865     inline bool check_ok( const float &         ) { return true; } ///< <code>check_ok() == true</code>
01866     inline bool check_ok( const long double &   ) { return true; } ///< <code>check_ok() == true</code>
01867     inline bool check_ok( const signed char &   ) { return true; } ///< <code>check_ok() == true</code>
01868     inline bool check_ok( const signed int &    ) { return true; } ///< <code>check_ok() == true</code>
01869     inline bool check_ok( const signed long &   ) { return true; } ///< <code>check_ok() == true</code>
01870     inline bool check_ok( const unsigned char & ) { return true; } ///< <code>check_ok() == true</code>
01871     inline bool check_ok( const unsigned int&   ) { return true; } ///< <code>check_ok() == true</code>
01872     inline bool check_ok( const unsigned long & ) { return true; } ///< <code>check_ok() == true</code>
01873 #endif
01874 
01875 #ifndef BUnit_DEFINE_check_ok // trick to make Doxygen document BUnit_DEFINE_check_ok
01876     #ifdef Spanish_dox
01877         /// Si esta macro existe las funciones \c check_ok() quedan definidas para los tipos básicos.
01878     #endif
01879     #ifdef English_dox
01880         /// If this macro exist functions for \c check_ok() will be defined for the basic types.
01881     #endif
01882     #define BUnit_DEFINE_check_ok
01883     #undef  BUnit_DEFINE_check_ok
01884 #endif
01885 
01886 #ifdef Spanish_dox
01887 /// Retorna una hilera \c std::string contruida desde el valor de \c val.
01888 /// - \c toString() with standard C++
01889 #endif
01890 #ifdef English_dox
01891 /// Returns a \c std::string constructed form value \c val.
01892 /// - \c toString() with standard C++
01893 #endif
01894 template <class T>
01895 std::string TestCase::toString( const T & val ) {
01896 //  typedef basic_ostringstream<char> ostringstream;
01897     std::basic_ostringstream<char> temp; // ostringstream temp;
01898     temp << val;
01899     return temp.str( );
01900 }
01901 
01902 /// [CppUnit] Macros propios de \c CppUnit http://cppunit.sourceforge.net/doc/lastest
01903 #define CPPUNIT_BUnit()
01904 #undef  CPPUNIT_BUnit
01905 
01906 /// [CppUnit] Assertions that a condition is true.
01907 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga0
01908 #define CPPUNIT_ASSERT(condition) BUnit_TEST(condition)
01909 
01910 /// [CppUnit] Assertion with a user specified message.
01911 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga1
01912 #define CPPUNIT_ASSERT_MESSAGE(message, condition) assertTrue_Msg(message,condition)
01913 
01914 /// [CppUnit] Fails with the specified message.
01915 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga2
01916 #define CPPUNIT_FAIL(message) BUnit_FAILURE(message)
01917 
01918 /// [CppUnit] Asserts that two values are equals.
01919 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga3
01920 #define CPPUNIT_ASSERT_EQUAL(expected, actual) BUnit_EQUAL(expected, actual)
01921 
01922 /// [CppUnit] Asserts that two values are equals, provides additional messafe on failure.
01923 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga4
01924 #define CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual) \
01925         BUnit_EQUAL_Msg(message, expected, actual)
01926 
01927 /// [CppUnit] Macro for primitive value comparisons.
01928 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga5
01929 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta) \
01930         assertEquals_Delta(expected, actual, delta)
01931 
01932 /// [CppUnit] Asserts that the given expression throws an exception of the specified type.
01933 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga6
01934 #define CPPUNIT_ASSERT_THROW(expression, ExceptionType) \
01935         do {                                            \
01936             bool cpputExceptionThrown_ = false;         \
01937             try {                                       \
01938                 expression;                             \
01939             } catch ( const ExceptionType & ) {         \
01940                 cpputExceptionThrown_ = true;           \
01941             }                                           \
01942                                                         \
01943             if ( cpputExceptionThrown_ ) {              \
01944                 break;                                  \
01945             }                                           \
01946             BUnit_FAILURE(                              \
01947                 "Expected exception: " #ExceptionType ) \
01948         } while ( false )
01949 
01950 /// [CppUnit] Asserts that the given expression does not throw any exceptions.
01951 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga7
01952 #define CPPUNIT_ASSERT_NO_THROW(expression)                   \
01953         do {                                                  \
01954             try {                                             \
01955                 expression;                                   \
01956             } catch ( ... ) {                                 \
01957                 BUnit_FAILURE("Unexpected exception caught"); \
01958             }                                                 \
01959         } while ( false )
01960 
01961 /// [CppUnit] Asserts that an assertion fail.
01962 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga8
01963 #define CPPUNIT_ASSERT_ASSERTION_FAIL(assertion)               \
01964         CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception )
01965 
01966 /// [CppUnit] Asserts that an assertion pass.
01967 /// \see http://cppunit.sourceforge.net/doc/lastest/group___assertions.html#ga9
01968 #define CPPUNIT_ASSERT_ASSERTION_PASS(assertion) \
01969         CPPUNIT_ASSERT_NO_THROW( assertion )
01970 
01971 #define JUnit_BUnit()
01972 #undef  JUnit_BUnit
01973 
01974 /// [JUnit] Macros propios de \c JUnit http://junit.sourceforge.net/javadoc/junit/framework/Assert.html
01975 ///  Asserts that two objects are equal.
01976 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.Object,%20java.lang.Object)
01977 #define assertEquals(          EXPECTED, ACTUAL ) BUnit_EQUAL(EXPECTED, ACTUAL)
01978 ///  Asserts that two objects are equal (with message).
01979 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.String,%20java.lang.Object,%20java.lang.Object)
01980 #define assertEquals_Msg( MSG, EXPECTED, ACTUAL ) BUnit_EQUAL_Msg(MSG, EXPECTED, ACTUAL)
01981 
01982 /// [JUnit] Asserts that a condition is true.
01983 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertTrue(boolean)
01984 #define assertTrue(           CONDITION ) \
01985         testThis( CONDITION, #CONDITION, __FILE__, __LINE__ )
01986 /// [JUnit] Asserts that a condition is true (with message).
01987 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertTrue(java.lang.String,%20boolean)
01988 #define assertTrue_Msg( MSG,  CONDITION ) \
01989         testThis( CONDITION,  MSG,       __FILE__, __LINE__ )
01990 
01991 /// [JUnit] Asserts that a condition is false.
01992 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertFalse(boolean)
01993 #define assertFalse(          CONDITION ) \
01994         testThis( !(CONDITION), "!(" #CONDITION ")", __FILE__, __LINE__ )
01995 /// [JUnit] Asserts that a condition is false (with message).
01996 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertFalse(java.lang.String,%20boolean)
01997 #define assertFalse_Msg( MSG, CONDITION ) \
01998         testThis( !(CONDITION),       MSG,           __FILE__, __LINE__ )
01999 
02000 #include <math.h> // fabs()
02001 /// [JUnit] Asserts that two doubles are equal concerning a delta.
02002 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(double,%20double,%20double)
02003 #define assertEquals_Delta(EXPECTED, ACTUAL, DELTA ) \
02004         testThis( fabs( double(EXPECTED) -  double(ACTUAL) ) < double(DELTA), \
02005         "|"  #EXPECTED "-" #ACTUAL "| < " #DELTA,  __FILE__, __LINE__ )
02006 
02007 /// [JUnit] Asserts that two doubles are equal concerning a delta (with message).
02008 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertEquals(java.lang.String,%20double,%20double,%20double)
02009 #define assertEquals_Delta_Msg( MSG, EXPECTED, ACTUAL, DELTA ) \
02010         testThis( fabs( double(EXPECTED) -  double(ACTUAL) ) < double(DELTA), \
02011         MSG, __FILE__, __LINE__ )
02012 
02013 /// [JUnit] Asserts that an object is null.
02014 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNull(java.lang.Object)
02015 #define assertNull(OBJECT)    \
02016         testThis( 0==&(OBJECT), "assertNull("    #OBJECT ")", __FILE__, __LINE__ )
02017 /// [JUnit] Asserts that an object isn't null.
02018 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNotNull(java.lang.Object)
02019 #define assertNotNull(OBJECT) \
02020         testThis( 0!=&(OBJECT), "assertNotNull(" #OBJECT ")", __FILE__, __LINE__ )
02021 
02022 /// [JUnit] Asserts that two objects refer to the same object.
02023 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertSame(java.lang.Object,%20java.lang.Object)
02024 #define assertSame(THIS, THAT)      \
02025         testThis( &(THIS)==&(THAT), \
02026                    "assertSame("    #THIS ", " #THAT ")", __FILE__, __LINE__ )
02027 ///  Asserts that two objects do not refer to the same object.
02028 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#assertNotSame(java.lang.Object,%20java.lang.Object)
02029 #define assertNotSame(THIS, THAT)   \
02030         testThis( &(THIS)!=&(THAT), \
02031                    "assertNotSame(" #THIS ", " #THAT ")", __FILE__, __LINE__ )
02032 
02033 #if 0
02034 // This breaks code as fail() is a method for streams.
02035 /// [JUnit] Fails a test with no message.
02036 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#fail()
02037 #define fail(     )     BUnit_FAILURE("FAIL")
02038 #endif
02039 
02040 /// [JUnit] Fails a test with the given message.
02041 /// \see http://junit.sourceforge.net/javadoc/junit/framework/Assert.html#fail(java.lang.String)
02042 #define fail_Msg( MSG ) BUnit_FAILURE(MSG)
02043 
02044 #endif // BUnit_h
02045 
02046 // EOF: BUnit.h