mirror of
https://github.com/libexpat/libexpat.git
synced 2025-04-06 21:55:00 +00:00
minicheck: Add simple subtest support
This will be useful when a test runs through several examples and fails somewhere in the middle. The subtest string replaces the phase_info string (i.e. "during actual test") in the failure output. Added subtest info to various tests where I found for loops.
This commit is contained in:
parent
4811d55b12
commit
c803b93e87
6 changed files with 55 additions and 0 deletions
|
@ -18,6 +18,7 @@
|
|||
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
|
||||
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
|
||||
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
|
||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -384,6 +385,7 @@ START_TEST(test_helper_unsigned_char_to_printable) {
|
|||
// Smoke test
|
||||
unsigned char uc = 0;
|
||||
for (; uc < (unsigned char)-1; uc++) {
|
||||
set_subtest("char %u", (unsigned)uc);
|
||||
const char *const printable = unsignedCharToPrintable(uc);
|
||||
if (printable == NULL)
|
||||
fail("unsignedCharToPrintable returned NULL");
|
||||
|
@ -392,8 +394,10 @@ START_TEST(test_helper_unsigned_char_to_printable) {
|
|||
}
|
||||
|
||||
// Two concrete samples
|
||||
set_subtest("char 'A'");
|
||||
if (strcmp(unsignedCharToPrintable('A'), "A") != 0)
|
||||
fail("unsignedCharToPrintable result mistaken");
|
||||
set_subtest("char '\\'");
|
||||
if (strcmp(unsignedCharToPrintable('\\'), "\\\\") != 0)
|
||||
fail("unsignedCharToPrintable result mistaken");
|
||||
}
|
||||
|
|
|
@ -1212,6 +1212,7 @@ START_TEST(test_ext_entity_invalid_parse) {
|
|||
const ExtFaults *fault = faults;
|
||||
|
||||
for (; fault->parse_text != NULL; fault++) {
|
||||
set_subtest("\"%s\"", fault->parse_text);
|
||||
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
XML_SetExternalEntityRefHandler(g_parser, external_entity_faulter);
|
||||
XML_SetUserData(g_parser, (void *)fault);
|
||||
|
@ -1282,6 +1283,7 @@ START_TEST(test_dtd_attr_handling) {
|
|||
AttTest *test;
|
||||
|
||||
for (test = attr_data; test->definition != NULL; test++) {
|
||||
set_subtest("%s", test->definition);
|
||||
XML_SetAttlistDeclHandler(g_parser, verify_attlist_decl_handler);
|
||||
XML_SetUserData(g_parser, test);
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, prolog, (int)strlen(prolog),
|
||||
|
@ -1670,6 +1672,7 @@ START_TEST(test_bad_cdata) {
|
|||
|
||||
size_t i = 0;
|
||||
for (; i < sizeof(cases) / sizeof(struct CaseData); i++) {
|
||||
set_subtest("%s", cases[i].text);
|
||||
const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES(
|
||||
g_parser, cases[i].text, (int)strlen(cases[i].text), XML_TRUE);
|
||||
const enum XML_Error actualError = XML_GetErrorCode(g_parser);
|
||||
|
@ -1737,6 +1740,7 @@ START_TEST(test_bad_cdata_utf16) {
|
|||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(cases) / sizeof(struct CaseData); i++) {
|
||||
set_subtest("case %lu", (long unsigned)(i + 1));
|
||||
enum XML_Status actual_status;
|
||||
enum XML_Error actual_error;
|
||||
|
||||
|
@ -2336,6 +2340,7 @@ START_TEST(test_ext_entity_invalid_suspended_parse) {
|
|||
ExtFaults *fault;
|
||||
|
||||
for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
|
||||
set_subtest("%s", fault->parse_text);
|
||||
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
XML_SetExternalEntityRefHandler(g_parser,
|
||||
external_entity_suspending_faulter);
|
||||
|
@ -2939,6 +2944,7 @@ START_TEST(test_bad_ignore_section) {
|
|||
ExtFaults *fault;
|
||||
|
||||
for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
|
||||
set_subtest("%s", fault->parse_text);
|
||||
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
XML_SetExternalEntityRefHandler(g_parser, external_entity_faulter);
|
||||
XML_SetUserData(g_parser, fault);
|
||||
|
@ -2982,6 +2988,7 @@ START_TEST(test_external_entity_values) {
|
|||
int i;
|
||||
|
||||
for (i = 0; data_004_2[i].parse_text != NULL; i++) {
|
||||
set_subtest("%s", data_004_2[i].parse_text);
|
||||
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||
XML_SetExternalEntityRefHandler(g_parser, external_entity_valuer);
|
||||
XML_SetUserData(g_parser, &data_004_2[i]);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
|
||||
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
|
||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -41,6 +42,7 @@
|
|||
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
|
@ -136,17 +138,35 @@ srunner_create(Suite *suite) {
|
|||
|
||||
static jmp_buf env;
|
||||
|
||||
#define SUBTEST_LEN (50) // informative, but not too long
|
||||
static char const *_check_current_function = NULL;
|
||||
static char _check_current_subtest[SUBTEST_LEN];
|
||||
static int _check_current_lineno = -1;
|
||||
static char const *_check_current_filename = NULL;
|
||||
|
||||
void
|
||||
_check_set_test_info(char const *function, char const *filename, int lineno) {
|
||||
_check_current_function = function;
|
||||
set_subtest("%s", "");
|
||||
_check_current_lineno = lineno;
|
||||
_check_current_filename = filename;
|
||||
}
|
||||
|
||||
void
|
||||
set_subtest(char const *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(_check_current_subtest, SUBTEST_LEN, fmt, ap);
|
||||
va_end(ap);
|
||||
// replace line feeds with spaces, for nicer error logs
|
||||
for (size_t i = 0; i < SUBTEST_LEN; ++i) {
|
||||
if (_check_current_subtest[i] == '\n') {
|
||||
_check_current_subtest[i] = ' ';
|
||||
}
|
||||
}
|
||||
_check_current_subtest[SUBTEST_LEN - 1] = '\0'; // ensure termination
|
||||
}
|
||||
|
||||
static void
|
||||
handle_success(int verbosity) {
|
||||
if (verbosity >= CK_VERBOSE) {
|
||||
|
@ -158,6 +178,9 @@ static void
|
|||
handle_failure(SRunner *runner, int verbosity, const char *phase_info) {
|
||||
runner->nfailures++;
|
||||
if (verbosity != CK_SILENT) {
|
||||
if (strlen(_check_current_subtest) != 0) {
|
||||
phase_info = _check_current_subtest;
|
||||
}
|
||||
printf("FAIL: %s (%s at %s:%d)\n", _check_current_function, phase_info,
|
||||
_check_current_filename, _check_current_lineno);
|
||||
}
|
||||
|
@ -174,6 +197,7 @@ srunner_run_all(SRunner *runner, int verbosity) {
|
|||
volatile int i;
|
||||
for (i = 0; i < tc->ntests; ++i) {
|
||||
runner->nchecks++;
|
||||
set_subtest("%s", "");
|
||||
|
||||
if (tc->setup != NULL) {
|
||||
/* setup */
|
||||
|
@ -189,6 +213,7 @@ srunner_run_all(SRunner *runner, int verbosity) {
|
|||
continue;
|
||||
}
|
||||
(tc->tests[i])();
|
||||
set_subtest("%s", "");
|
||||
|
||||
/* teardown */
|
||||
if (tc->teardown != NULL) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
Copyright (c) 2004-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||
Copyright (c) 2006-2012 Karl Waclawek <karl@waclawek.net>
|
||||
Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -59,6 +60,19 @@ extern "C" {
|
|||
# define __func__ __FUNCTION__
|
||||
# endif
|
||||
|
||||
/* PRINTF_LIKE has two effects:
|
||||
1. Make clang's -Wformat-nonliteral stop warning about non-literal format
|
||||
strings in annotated functions' code.
|
||||
2. Make both clang and gcc's -Wformat-nonliteral warn about *callers* of
|
||||
the annotated function that use a non-literal format string.
|
||||
*/
|
||||
# if defined(__GNUC__)
|
||||
# define PRINTF_LIKE(fmtpos, argspos) \
|
||||
__attribute__((format(printf, fmtpos, argspos)))
|
||||
# else
|
||||
# define PRINTF_LIKE(fmtpos, argspos)
|
||||
# endif
|
||||
|
||||
# define START_TEST(testname) \
|
||||
static void testname(void) { \
|
||||
_check_set_test_info(__func__, __FILE__, __LINE__); \
|
||||
|
@ -67,6 +81,8 @@ extern "C" {
|
|||
} \
|
||||
}
|
||||
|
||||
void PRINTF_LIKE(1, 2) set_subtest(char const *fmt, ...);
|
||||
|
||||
# define fail(msg) _fail_unless(0, __FILE__, __LINE__, msg)
|
||||
|
||||
typedef void (*tcase_setup_function)(void);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
|
||||
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
|
||||
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
|
||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -328,6 +329,7 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
|
|||
size_t inputIndex = 0;
|
||||
|
||||
for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) {
|
||||
set_subtest("%s", inputs[inputIndex]);
|
||||
XML_Parser parser;
|
||||
enum XML_Status parseResult;
|
||||
int setParamEntityResult;
|
||||
|
|
|
@ -694,6 +694,7 @@ START_TEST(test_ns_separator_in_uri) {
|
|||
size_t i = 0;
|
||||
size_t failCount = 0;
|
||||
for (; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
set_subtest("%s", cases[i].doc);
|
||||
XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep);
|
||||
XML_SetElementHandler(parser, dummy_start_element, dummy_end_element);
|
||||
if (XML_Parse(parser, cases[i].doc, (int)strlen(cases[i].doc),
|
||||
|
|
Loading…
Add table
Reference in a new issue