⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 curses.c

📁 CUNIT c 测试框架,类似大名鼎鼎的junit,很有用的,这里是原代码,可以编译生成lib文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  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 the Curses based Test Interface.
 *
 *  01/Nov/2001   Started Curses based interface for CUnit. (AK)
 *
 *  04/Nov/2001   Added Scrolling Capability to the Details Window. (AK)
 *
 *  24/Nov/2001   Added List and Show Failure Capability to the Details Window.
 *                Also added group initialization failure message handler. (AK)
 *
 *  09-Aug-2004   New interface, made all curses local functions static. (JDS)
 */

/** @file
 * Curses test interface with interactive output (implementation).
 */
/** @addtogroup Curses
 @{
*/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <curses.h>

#include "CUnit.h"
#include "TestDB.h"
#include "Util.h"
#include "TestRun.h"
#include "CUCurses.h"

/*
 * Type Definitions
 */

#ifndef false
#define false   (0)       /**< Local boolean definition for false. */
#endif

#ifndef true
#define true  (~false)    /**< Local boolean definition for true. */
#endif

/** Curses interface status flag. */
typedef enum
{
  CONTINUE = 1,   /**< Continue processing commands in current menu. */
  MOVE_UP,        /**< Move up to the previous menu. */
  STOP            /**< Stop processing (user selected 'Quit'). */
} STATUS;

/** Menu type. */
typedef enum
{
  MAIN_MENU = 1,
  GROUP_MENU
} MENU_TYPE;

/** Pointers to curses interface windows. */
typedef struct
{
  WINDOW* pMainWin;           /**< Main window. */
  WINDOW* pTitleWin;          /**< Title window. */
  WINDOW* pProgressWin;       /**< Progress bar window. */
  WINDOW* pSummaryWin;        /**< Summary window. */
  WINDOW* pRunSummaryWin;     /**< Run Summary window. */
  WINDOW* pDetailsWin;        /**< Details window. */
  WINDOW* pOptionsWin;        /**< Options window. */
} APPWINDOWS;

/** Window elements. */
typedef struct
{
  WINDOW*      pPad;          /**< Pointer to the pad. */
  unsigned int uiRows;        /**< Number of rows in pad. */
  unsigned int uiColumns;     /**< Number of columns in pad. */
  unsigned int uiPadRow;      /**< Current pad row. */
  unsigned int uiPadCol;      /**< Current pad column. */
  unsigned int uiWinLeft;     /**< Left position of containing window. */
  unsigned int uiWinTop;      /**< Top position of containing window. */
  unsigned int uiWinRows;     /**< Number of rows in containing window. */
  unsigned int uiWinColumns;  /**< Number of columns in containing window. */
} APPPAD;

/*
 * Constants definitions
 */
/** Standard string length. */
#define STRING_LENGTH 128
/** String holding main menu run options. */
static const char* MAIN_OPTIONS  = "(R)un  (S)elect Suite  (L)ist  (F)ailures  (Q)uit";
/** String holding suite menu run options. */
static const char* SUITE_OPTIONS = "(R)un  (S)elect Test  (L)ist  (F)ailures  (U)p  (Q)uit";

/*
 * Color Pairs Initialized for the Various Parameter Display
 */
static const int CLEAR_COLOR                = 1;  /**< Clear color.*/
static const int TITLE_COLOR                = 2;  /**< Title color.*/
static const int PROGRESS_BACKGROUND_COLOR  = 3;  /**< progress bar background color.*/
static const int PROGRESS_SUCCESS_COLOR     = 4;  /**< Progress bar success color.*/
static const int PROGRESS_FAILURE_COLOR     = 5;  /**< Progress bar failure color.*/
static const int MENU_COLOR                 = 6;  /**< Menu color.*/

/*
 * Global Definitions
 */
static const char* const f_szProgress = "Progress    "; /**< Test for progress bar. */

static const char*  f_szOptions = NULL;         /**< String containing options. */

static CU_pTest     f_pCurrentTest = NULL;      /**< Pointer to the test currently being run. */
static CU_pSuite    f_pCurrentSuite = NULL;     /**< Pointer to the suite currently being run. */

static unsigned int f_uiTotalTests = 0;         /**< Number of tests in registered suites. */
static unsigned int f_uiTestsRun = 0;           /**< Number of tests actually run. */
static unsigned int f_uiTestsSkipped = 0;       /**< Number of tests skipped during run. */
static unsigned int f_uiTestsFailed = 0;        /**< Number of tests having failed assertions. */
static unsigned int f_uiTestsRunSuccessful = 0; /**< Number of tests run with no failed assertions. */

static unsigned int f_uiTotalSuites = 0;        /**< Number of registered suites. */
static unsigned int f_uiSuitesSkipped = 0;      /**< Number of suites skipped during run. */

static short f_nLeft;                           /**< Left window position. */
static short f_nTop;                            /**< Top window position. */
static short f_nWidth;                          /**< Width of window. */
static short f_nHeight;                         /**< Height of window. */

/** Pointers to curses interface windows. */
static APPWINDOWS application_windows = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
/** Details window definition. */
static APPPAD  details_pad = {NULL, 0, 0, 0, 0, 0, 0, 0, 0};

/*
 * Function Declarations
 */
static bool initialize_windows(void);
static void uninitialize_windows(void);

static void refresh_windows(void);
static void refresh_title_window(void);
static void refresh_progress_window(void);
static void refresh_summary_window(void);
static void refresh_run_summary_window(void);
static void refresh_details_window(void);
static void refresh_options_window(void);

static bool create_pad(APPPAD* pPad, WINDOW* pParent, unsigned int uiRows, unsigned int uiCols);
static void scroll_window(int nCommand, APPPAD* pPad, void (*parent_refresh)(void));

static bool test_initialize(void);

static void show_progress_bar(void);
static const char* get_hotkey(const char* szStr, int* pPos);
static void read_input_string(const char szPropmt[], char szValue[], int nBytes);

static STATUS curses_registry_level_run(CU_pTestRegistry pRegistry);
static STATUS curses_suite_level_run(CU_pSuite pSuite);

static CU_ErrorCode curses_run_all_tests(CU_pTestRegistry pRegistry);
static CU_ErrorCode curses_run_suite_tests(CU_pSuite pSuite);
static CU_ErrorCode curses_run_single_test(CU_pSuite pSuite, CU_pTest pTest);

static void curses_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite);
static void curses_test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite,
                                                 const CU_pFailureRecord pFailure);
static void curses_all_tests_complete_message_handler(const CU_pFailureRecord pFailure);
static void curses_suite_init_failure_message_handler(const CU_pSuite pSuite);

static void list_suites(CU_pTestRegistry pRegistry);
static void list_tests(CU_pSuite pSuite);
static void show_failures(void);

static void reset_run_parameters(void);

/*------------------------------------------------------------------------*/
/** Run registered CUnit tests using the curses interface. */
void CU_curses_run_tests(void)
{
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  f_szOptions = MAIN_OPTIONS;
  if (!initialize_windows()) {
    return;                   
  }

  if (!test_initialize()) {
    goto test_initialize_fail;
  }

  curses_registry_level_run(CU_get_registry());

  /* THIS WAS COMMENTED OUT IN THE 1.1-1 SOURCE
  f_uiTotalTests = 3000;
  {
    int i;
    int iSucc = 0;
    for (i = 0; i < 3000; i++, iSucc++) {
      if (i && !(i%2000))
        iSucc--;

      f_uiTestsRun = i + 1;
      f_uiTestsRunSuccessful = iSucc + 1;
      refresh_progress_window();
      refresh_summary_window();
      refresh_run_summary_window();
    }
  }

  f_uiTestsRunSuccessful = f_uiTestsRun = 0;
  refresh_windows();
  {
    int i;
    int iSucc = -1;
    for (i = 0; i < 3000; i++, iSucc++) {
      if (i && !(i%2000))
        iSucc++;

      f_uiTestsRun = i + 1;
      f_uiTestsRunSuccessful = iSucc + 1;
      refresh_progress_window();
      refresh_summary_window();
      refresh_run_summary_window();
    }
  }
  */

test_initialize_fail:
  uninitialize_windows();
}

/*------------------------------------------------------------------------*/
/** Initialize the curses interface windows. */
static bool initialize_windows(void)
{
  bool bStatus = false;

  if (NULL == (application_windows.pMainWin = initscr())) {
    goto main_fail;
  }

  start_color();

  f_nLeft = application_windows.pMainWin->_begx;
  f_nTop = application_windows.pMainWin->_begy;
  f_nWidth = application_windows.pMainWin->_maxx;
  f_nHeight = application_windows.pMainWin->_maxy;

  if (NULL == (application_windows.pTitleWin = newwin(3, f_nWidth, 0, 0))) {
    goto title_fail;
  }

  if (NULL == (application_windows.pProgressWin = newwin(2, f_nWidth, 3, 0))) {
    goto progress_fail;
  }

  if (NULL == (application_windows.pSummaryWin = newwin(1, f_nWidth, 5, 0))) {
    goto summary_fail;
  }

  if (NULL == (application_windows.pRunSummaryWin = newwin(1, f_nWidth, 6, 0))) {
    goto run_summary_fail;
  }

  if (NULL == (application_windows.pDetailsWin = newwin(f_nHeight - f_nTop - 7 , f_nWidth, 7, 0))) {
    goto details_fail;
  }

  if (NULL == (application_windows.pOptionsWin = newwin(1, f_nWidth, f_nHeight - f_nTop, 0))) {
    goto option_fail;
  }

  curs_set(0);
  noecho();
  cbreak();
  keypad(application_windows.pMainWin, CU_TRUE);
  init_pair(CLEAR_COLOR, COLOR_WHITE, COLOR_BLACK);
  init_pair(TITLE_COLOR, COLOR_WHITE, COLOR_BLACK);
  init_pair(PROGRESS_BACKGROUND_COLOR, COLOR_BLACK, COLOR_WHITE);
  init_pair(PROGRESS_SUCCESS_COLOR, COLOR_WHITE, COLOR_GREEN);
  init_pair(PROGRESS_FAILURE_COLOR, COLOR_WHITE, COLOR_RED);
  init_pair(MENU_COLOR, COLOR_WHITE, COLOR_BLACK);

  refresh_windows();
  bStatus = true;
  goto main_fail;

  /*
   * Error Handlers for all the stages.
   */
option_fail:
  delwin(application_windows.pDetailsWin);

details_fail:
  delwin(application_windows.pRunSummaryWin);

run_summary_fail:
  delwin(application_windows.pSummaryWin);

summary_fail:
  delwin(application_windows.pProgressWin);

progress_fail:
  delwin(application_windows.pTitleWin);

title_fail:
  endwin();

main_fail:
  return bStatus;

}

/*------------------------------------------------------------------------*/
/** Clean up and delete curses interface windows. */
static void uninitialize_windows(void)
{
  curs_set(1);
  echo();
  nocbreak();
  keypad(application_windows.pMainWin, CU_FALSE);

  if (details_pad.pPad) {
    delwin(details_pad.pPad);
  }

  delwin(application_windows.pOptionsWin);
  delwin(application_windows.pDetailsWin);
  delwin(application_windows.pRunSummaryWin);
  delwin(application_windows.pSummaryWin);
  delwin(application_windows.pProgressWin);
  delwin(application_windows.pTitleWin);

  clear();
  refresh();
  endwin();
}


/*------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -