1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

WL#3206 (Adding unit tests):

Moving mytap library into unittest/
Adding 'test' target to make and run unit tests.
Minor fixes.


unittest/mytap/Doxyfile:
  mvdir
unittest/mytap/t/basic.t.c:
  mvdir
unittest/mytap/tap.c:
  mvdir
unittest/mytap/tap.h:
  mvdir
Makefile.am:
  Correcting after moving mytap/
configure.in:
  Correcting after moving mytap/
unittest/Makefile.am:
  Adding 'test' target to build and execute unit tests.
unittest/examples/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/bitmap.t.c:
  Adding copyright notice.
unittest/mytap/Makefile.am:
  Correcting after moving mytap/
unittest/mytap/t/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/base64.t.c:
  New BitKeeper file ``unittest/mysys/base64.t.c''
This commit is contained in:
unknown
2006-04-06 17:18:12 +02:00
parent b0d2b6588b
commit 3f9e35d3f3
13 changed files with 149 additions and 20 deletions

1153
unittest/mytap/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir)
noinst_LIBRARIES = libmytap.a
noinst_HEADERS = tap.h
libmytap_a_SOURCES = tap.c
SUBDIRS = . t

View File

@ -0,0 +1,15 @@
AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include
AM_CPPFLAGS += -I$(srcdir)/..
AM_LDFLAGS = -L$(srcdir)/..
AM_CFLAGS = -Wall -ansi -pedantic
LDADD = -lmytap
noinst_PROGRAMS = basic.t
basic_t_SOURCES = basic.t.c
all: $(noinst_PROGRAMS)

View File

@ -0,0 +1,17 @@
#include <stdlib.h>
#include <tap.h>
int main() {
plan(5);
ok(1 == 1, "testing basic functions");
ok(2 == 2, "");
ok(3 == 3, NULL);
if (1 == 1)
skip(2, "Sensa fragoli");
else {
ok(1 == 2, "Should not be run at all");
ok(1, "This one neither");
}
return exit_status();
}

171
unittest/mytap/tap.c Normal file
View File

@ -0,0 +1,171 @@
#include "tap.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/**
Test data structure.
Data structure containing all information about the test suite.
*/
static TEST_DATA g_test = { 0 };
/**
Output stream for test report message.
The macro is just a temporary solution.
*/
#define tapout stdout
/**
Emit a TAP result and optionally a description.
@param pass 'true' if test passed, 'false' otherwise
@param fmt Description of test in printf() format.
@param ap Vararg list for the description string above.
*/
static int
emit_tap(int pass, char const *fmt, va_list ap)
{
fprintf(tapout, "%sok %d%s",
pass ? "" : "not ",
++g_test.last,
(fmt && *fmt) ? " - " : "");
if (fmt && *fmt)
vfprintf(tapout, fmt, ap);
}
static int
emit_dir(const char *dir, const char *exp)
{
fprintf(tapout, " # %s %s", dir, exp);
}
static int
emit_endl()
{
fprintf(tapout, "\n");
}
void
diag(char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(tapout, "# ");
vfprintf(tapout, fmt, ap);
fprintf(tapout, "\n");
va_end(ap);
}
void
plan(int const count)
{
g_test.plan= count;
switch (count)
{
case NO_PLAN:
case SKIP_ALL:
break;
default:
if (plan > 0)
fprintf(tapout, "1..%d\n", count);
break;
}
}
void
skip_all(char const *reason, ...)
{
va_list ap;
va_start(ap, reason);
fprintf(tapout, "1..0 # skip ");
vfprintf(tapout, reason, ap);
va_end(ap);
exit(0);
}
void
ok(int const pass, char const *fmt, ...)
{
if (!pass && *g_test.todo == '\0')
++g_test.failed;
va_list ap;
va_start(ap, fmt);
emit_tap(pass, fmt, ap);
va_end(ap);
if (*g_test.todo != '\0')
emit_dir("TODO", g_test.todo);
emit_endl();
}
void
skip(int how_many, char const *fmt, ...)
{
char reason[80];
if (fmt && *fmt)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(reason, sizeof(reason), fmt, ap);
va_end(ap);
}
else
reason[0] = '\0';
while (how_many-- > 0)
{
va_list ap;
emit_tap(1, NULL, ap);
emit_dir("SKIP", reason);
emit_endl();
}
}
void
todo_start(char const *message, ...)
{
va_list ap;
va_start(ap, message);
vsnprintf(g_test.todo, sizeof(g_test.todo), message, ap);
va_end(ap);
}
void
todo_end()
{
*g_test.todo = '\0';
}
int exit_status() {
/*
If there were no plan, we write one last instead.
*/
if (g_test.plan == NO_PLAN)
plan(g_test.last);
if (g_test.plan != g_test.last)
{
diag("%d tests planned but only %d executed",
g_test.plan, g_test.last);
return EXIT_FAILURE;
}
if (g_test.failed > 0)
{
diag("Failed %d tests!", g_test.failed);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

187
unittest/mytap/tap.h Normal file
View File

@ -0,0 +1,187 @@
#ifndef TAP_H
#define TAP_H
/*
*/
#define NO_PLAN (0)
#define SKIP_ALL (-1)
/**
Data about test plan.
@internal We are using the "typedef struct X { ... } X" idiom to
create class/struct X both in C and C++.
*/
typedef struct TEST_DATA {
/**
Number of tests that is planned to execute.
Can be zero (<code>NO_PLAN</code>) meaning that the plan string
will be printed at the end of test instead.
*/
int plan;
/** Number of last test that was done or skipped. */
int last;
/** Number of tests that failed. */
int failed;
/** Todo reason. */
char todo[128];
} TEST_DATA;
#ifdef __cplusplus
extern "C" {
#endif
/**
Set number of tests that is planned to execute.
The function also accepts the predefined constants SKIP_ALL and
NO_PLAN.
@param count
The planned number of tests to run. Alternatively, the SKIP_ALL
and NO_PLAN can be supplied.
*/
void plan(int count);
/**
Report test result as a TAP line.
Function used to write status of an individual test. Call this
function in the following manner:
@code
ok(ducks == paddling,
"%d ducks did not paddle", ducks - paddling);
@endcode
@param pass Zero if the test failed, non-zero if it passed.
@param fmt Format string in printf() format. NULL is allowed, in
which case nothing is printed.
*/
void ok(int pass, char const *fmt, ...)
__attribute__ ((format(printf,2,3)));
/**
Skip a determined number of tests.
Function to print that <em>how_many</em> tests have been
skipped. The reason is printed for each skipped test. Observe
that this function does not do the actual skipping for you, it just
prints information that tests have been skipped. It shall be used
in the following manner:
@code
if (ducks == 0) {
skip(2, "No ducks in the pond");
} else {
int i;
for (i = 0 ; i < 2 ; ++i)
ok(duck[i] == paddling, "is duck %d paddling?", i);
}
@endcode
@see SKIP_BLOCK_IF
@param how_many Number of tests that are to be skipped.
@param reason A reason for skipping the tests
*/
void skip(int how_many, char const *reason, ...)
__attribute__ ((format(printf,2,3)));
/**
Helper macro to skip a block of code. The macro can be used to
simplify conditionally skipping a block of code. It is used in the
following manner:
@code
SKIP_BLOCK_IF(ducks == 0, 2, "No ducks in the pond")
{
int i;
for (i = 0 ; i < 2 ; ++i)
ok(duck[i] == paddling, "is duck %d paddling?", i);
}
@see skip
@endcode
*/
#define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \
if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else
/**
Print a diagnostics message.
@param fmt Diagnostics message in printf() format.
*/
void diag(char const *fmt, ...)
__attribute__ ((format(printf,1,2)));
/**
Print summary report and return exit status.
This function will print a summary report of how many tests passed,
how many were skipped, and how many remains to do. The function
should be called after all tests are executed in the following
manner:
@code
return exit_status();
@endcode
@returns EXIT_SUCCESS if all tests passed, EXIT_FAILURE if one or
more tests failed.
*/
int exit_status(void);
/**
Skip entire test suite.
To skip the entire test suite, use this function. It will
automatically call exit(), so there is no need to have checks
around it.
*/
void skip_all(char const *reason, ...)
__attribute__ ((noreturn, format(printf, 1, 2)));
/**
Start section of tests that are not yet ready.
To start a section of tests that are not ready and are expected to
fail, use this function and todo_end() in the following manner:
@code
todo_start("Not ready yet");
ok(is_rocketeering(duck), "Rocket-propelled ducks");
ok(is_kamikaze(duck), "Kamikaze ducks");
todo_end();
@endcode
@see todo_end
@note
It is not possible to nest todo sections.
@param message Message that will be printed before the todo tests.
*/
void todo_start(char const *message, ...)
__attribute__ ((format (printf, 1, 2)));
/**
End a section of tests that are not yet ready.
*/
void todo_end();
#ifdef __cplusplus
}
#endif
#endif /* TAP_H */