• Página principal
  • Páginas relacionadas
  • Namespaces
  • Clases
  • Archivos

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 <cstdio>    // 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 thi