📄 testdb.c
字号:
/*
* CUnit - A Unit testing framework library for C.
* Copyright (C) 2001 Anil Kumar
* Copyright (C) 2004,2005,2006 Anil Kumar, Jerry St.Clair
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Implementation of Registry/TestGroup/Testcase management Routines.
*
* Aug 2001 Initial implementation (AK)
*
* 09/Aug/2001 Added startup initialize/cleanup registry functions. (AK)
*
* 29/Aug/2001 Added Test and Group Add functions. (AK)
*
* 02/Oct/2001 Added Proper Error codes and Messages on the failure conditions. (AK)
*
* 13/Oct/2001 Added Code to Check for the Duplicate Group name and test name. (AK)
*
* 15-Jul-2004 Added doxygen comments, new interface, added assertions to
* internal functions, moved error handling code to CUError.c,
* added assertions to make sure no modification of registry
* during a run, bug fixes, changed CU_set_registry() so that it
* doesn't require cleaning the existing registry. (JDS)
*/
/** @file
* Management functions for tests, suites, and the test registry (implementation).
*/
/** @addtogroup Framework
@{
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include "CUnit.h"
#include "MyMem.h"
#include "TestDB.h"
#include "TestRun.h"
#include "Util.h"
/*
* Global/Static Definitions
*/
static CU_pTestRegistry f_pTestRegistry = NULL; /**< The active internal Test Registry. */
/*
* Private function forward declarations
*/
static void cleanup_test_registry(CU_pTestRegistry pRegistry);
static CU_pSuite create_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean);
static void cleanup_suite(CU_pSuite pSuite);
static void insert_suite(CU_pTestRegistry pRegistry, CU_pSuite pSuite);
static CU_pTest create_test(const char* strName, CU_TestFunc pTestFunc);
static void cleanup_test(CU_pTest pTest);
static void insert_test(CU_pSuite pSuite, CU_pTest pTest);
static CU_BOOL suite_exists(CU_pTestRegistry pRegistry, const char* szSuiteName);
static CU_BOOL test_exists(CU_pSuite pSuite, const char* szTestName);
/*
* Public Interface functions
*/
/*------------------------------------------------------------------------*/
/** Initialize the test registry.
* Any existing registry is freed, including all stored suites and
* associated tests. The most recent stored test results are also cleared.
* <P><B>This function must not be called during a test run (checked
* by assertion)</B></P>.
* @return CUE_NOMEMORY if memory for the new registry cannot be allocated,
* CUE_SUCCESS otherwise.
* @see CU_cleanup_registry
* @see CU_get_registry
* @see CU_set_registry
* @see CU_registry_initialized
*/
CU_ErrorCode CU_initialize_registry(void)
{
CU_ErrorCode result;
assert(CU_FALSE == CU_is_test_running());
CU_set_error(result = CUE_SUCCESS);
if (NULL != f_pTestRegistry) {
CU_cleanup_registry();
}
f_pTestRegistry = CU_create_new_registry();
if (NULL == f_pTestRegistry) {
CU_set_error(result = CUE_NOMEMORY);
}
return result;
}
/*------------------------------------------------------------------------*/
/** Check whether the test registry has been initialized.
* @return CU_TRUE if the registry has been initialized,
* CU_FALSE otherwise.
* @see CU_initialize_registry
* @see CU_cleanup_registry
*/
CU_BOOL CU_registry_initialized(void)
{
return (NULL == f_pTestRegistry) ? CU_FALSE : CU_TRUE;
}
/*------------------------------------------------------------------------*/
/** Clear the test registry.
* The active test registry is freed, including all stored suites and
* associated tests. The most recent stored test results are also cleared.
* After calling this function, CUnit suites cannot be added until
* CU_initialize_registry() or CU_set_registry() is called. Further, any
* pointers to suites or test cases held by the user will be invalidated
* by calling this function.
* <P>This function may be called multiple times without generating an
* error condition. However, <B>this function must not be called during
* a test run (checked by assertion)</B></P>.
* @see CU_initialize_registry
* @see CU_get_registry
* @see CU_set_registry
*/
void CU_cleanup_registry(void)
{
assert(CU_FALSE == CU_is_test_running());
CU_set_error(CUE_SUCCESS);
CU_destroy_existing_registry(&f_pTestRegistry); /* supposed to handle NULL ok */
CU_clear_previous_results();
CU_CREATE_MEMORY_REPORT(NULL);
}
/*------------------------------------------------------------------------*/
/** Retrieve a pointer to the current test registry.
* Returns NULL if the registry has not been initialized using
* CU_initialize_registry(). Directly accessing the registry
* should not be necessary for most users. This function is
* provided primarily for internal and testing purposes.
* @return A pointer to the current registry (NULL if uninitialized).
* @see CU_initialize_registry
* @see CU_set_registry
*/
CU_pTestRegistry CU_get_registry(void)
{
return f_pTestRegistry;
}
/*------------------------------------------------------------------------*/
/** Set the registry to an existing CU_pTestRegistry instance.
* A pointer to the original registry is returned. Note that the
* original registry is not freed, and it becomes the caller's
* responsibility to do so. Directly accessing the registry
* should not be necessary for most users. This function is
* provided primarily for internal and testing purposes.
* <P><B>This function must not be called during a test run (checked
* by assertion)</B></P>.
* @return A pointer to the original registry that was replaced.
* @see CU_initialize_registry
* @see CU_cleanup_registry
* @see CU_get_registry
*/
CU_pTestRegistry CU_set_registry(CU_pTestRegistry pRegistry)
{
CU_pTestRegistry pOldRegistry = f_pTestRegistry;
assert(CU_FALSE == CU_is_test_running());
CU_set_error(CUE_SUCCESS);
f_pTestRegistry = pRegistry;
return pOldRegistry;
}
/*------------------------------------------------------------------------*/
/** Create a new test suite and add it to the test registry.
* This function creates a new test suite having the specified
* name and initialization/cleanup functions and adds it to the
* test registry. It returns a pointer to the newly-created suite,
* which will be NULL if there was a problem with the suite creation
* or addition.<br /><br />
* CU_add_suite() sets the following error codes:
* -CUE_NOREGISTRY if the registry hasn't been initialized.
* -CUE_NO_SUITENAME if strName is NULL.
* -CUE_DUP_SUITE if a suite having strName is already registered.
* -CUE_NOMEMORY if a memory allocation failed.<BR /><BR />
* NOTE - the CU_pSuite pointer returned should NOT BE FREED BY
* THE USER. The suite is freed by the CUnit system when
* CU_cleanup_registry() is called.
* <P><B>This function must not be called during a test run (checked
* by assertion)</B></P>.
* @param strName Name for the new test suite (unique, non-NULL).
* @param pInit Initialization function to call before running suite.
* @param pClean Cleanup function to call after running suite.
* @return A pointer to the newly-created suite (NULL if creation failed)
*/
CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean)
{
CU_pSuite pRetValue = NULL;
CU_ErrorCode error = CUE_SUCCESS;
assert(CU_FALSE == CU_is_test_running());
if (NULL == f_pTestRegistry) {
error = CUE_NOREGISTRY;
}
else if (NULL == strName) {
error = CUE_NO_SUITENAME;
}
else if (CU_TRUE == suite_exists(f_pTestRegistry, strName)) {
error = CUE_DUP_SUITE;
}
else {
pRetValue = create_suite(strName, pInit, pClean);
if (NULL == pRetValue) {
error = CUE_NOMEMORY;
}
else {
insert_suite(f_pTestRegistry, pRetValue);
}
}
CU_set_error(error);
return pRetValue;
}
/*------------------------------------------------------------------------*/
/** Create a new test case and add it to a test suite.
* This function creates a new test having the specified name and
* function, and adds it to the specified suite. At present, there is
* no mechanism for creating a test case independent of a suite, although
* this function does return a pointer to the newly-created test.<br /><br />
* CU_add_test() sets the following error codes:
* -CUE_NOSUITE if pSuite is NULL.
* -CUE_NO_TESTNAME if strName is NULL.
* -CUE_DUP_TEST if a test having strName is already registered to pSuite.
* -CUE_NOMEMORY if a memory allocation failed.<BR /><BR />
* NOTE - the CU_pTest pointer returned should NOT BE FREED BY
* THE USER. The test is freed by the CUnit system when
* CU_cleanup_registry() is called.
* <P><B>This function must not be called during a test run (checked
* by assertion)</B></P>.
* @param pSuite Test suite to which to add new test.
* @param strName Name for the new test case (unique to pSuite, non-NULL).
* @param pTest Function to call when running the test.
* @return A pointer to the newly-created test (NULL if creation failed)
*/
CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc)
{
CU_pTest pRetValue = NULL;
CU_ErrorCode error = CUE_SUCCESS;
assert(CU_FALSE == CU_is_test_running());
if (NULL == f_pTestRegistry) {
error = CUE_NOREGISTRY;
}
else if (NULL == pSuite) {
error = CUE_NOSUITE;
}
else if (NULL == strName) {
error = CUE_NO_TESTNAME;
}
else if(NULL == pTestFunc) {
error = CUE_NOTEST;
}
else if (CU_TRUE == test_exists(pSuite, strName)) {
error = CUE_DUP_TEST;
}
else {
pRetValue = create_test(strName, pTestFunc);
if (NULL == pRetValue) {
error = CUE_NOMEMORY;
}
else {
f_pTestRegistry->uiNumberOfTests++;
insert_test(pSuite, pRetValue);
}
}
CU_set_error(error);
return pRetValue;
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/* This section is based conceptually on code
* Copyright (C) 2004 Aurema Pty Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Derived from code contributed by K. Cheung and Aurema Pty Ltd. (thanks!)
* int test_group_register(test_group_t *tg)
* int test_suite_register(test_suite_t *ts)
*/
/*------------------------------------------------------------------------*/
/** Registers multiple suite arrays in CU_SuiteInfo format.
* The function accepts a variable number of suite arrays to
* be registered. The number of arrays is indicated by
* the value of the 1st argument, suite_count. Each suite
* in each array is registered with the CUnit test registry,
* along with all of the associated tests.
* @param suite_count The number of CU_SuiteInfo* arguments to follow.
* @param ... suite_count number of CU_SuiteInfo* arguments. NULLs are ignored.
* @return A CU_ErrorCode indicating the error status.
* @see CU_register_suites()
*/
CU_ErrorCode CU_register_nsuites(int suite_count, ...)
{
CU_SuiteInfo *pSuiteItem = NULL;
CU_TestInfo *pTestItem = NULL;
CU_pSuite pSuite = NULL;
va_list argptr;
int i;
va_start(argptr, suite_count);
for (i=0 ; i<suite_count ; ++i) {
pSuiteItem = va_arg(argptr, CU_pSuiteInfo);
if (NULL != pSuiteItem) {
for ( ; NULL != pSuiteItem->pName; pSuiteItem++) {
if (NULL != (pSuite = CU_add_suite(pSuiteItem->pName, pSuiteItem->pInitFunc, pSuiteItem->pCleanupFunc))) {
for (pTestItem = pSuiteItem->pTests; NULL != pTestItem->pName; pTestItem++) {
if (NULL == CU_add_test(pSuite, pTestItem->pName, pTestItem->pTestFunc)) {
return CU_get_error();
}
}
}
else {
return CU_get_error();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -