mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 23:46:17 +01:00
GTest framework started.
* glib/gtestframework.h: testing framework API as proposed on gtk-devel-list. includes elaborate assertions, performance report functions, test traps, test timer, test random numbers, teardoiwn garbage collection functions and general test case / test suite management APIs. * glib/gtestframework.c: first test framework implementation. already covers some test suite management APIs and assertion message implementations. * glib/tests/testing.c: test program for the testing framework. * glib/tests/Makefile.am: complie testing.c as test. run all tests as part of make test:. svn path=/trunk/; revision=5877
This commit is contained in:
parent
edfef23665
commit
cc3bf40d26
@ -16,3 +16,386 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "gtestframework.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* --- structures --- */
|
||||||
|
struct GTestCase
|
||||||
|
{
|
||||||
|
gchar *name;
|
||||||
|
guint fixture_size;
|
||||||
|
void (*fixture_setup) (void*);
|
||||||
|
void (*fixture_test) (void*);
|
||||||
|
void (*fixture_teardown) (void*);
|
||||||
|
};
|
||||||
|
struct GTestSuite
|
||||||
|
{
|
||||||
|
gchar *name;
|
||||||
|
GSList *suites;
|
||||||
|
GSList *cases;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --- variables --- */
|
||||||
|
static gboolean test_mode_quick = TRUE;
|
||||||
|
static gboolean test_mode_perf = FALSE;
|
||||||
|
static gboolean test_mode_fatal = TRUE;
|
||||||
|
static gboolean g_test_initialized = FALSE;
|
||||||
|
static gboolean g_test_run_once = TRUE;
|
||||||
|
static gboolean test_run_quiet = FALSE;
|
||||||
|
static gboolean test_run_list = FALSE;
|
||||||
|
static gchar *test_run_output = NULL;
|
||||||
|
static gchar *test_run_seed = NULL;
|
||||||
|
static gchar *test_run_name = "";
|
||||||
|
static GSList *test_paths = NULL;
|
||||||
|
static GTestSuite *test_suite_root = NULL;
|
||||||
|
static GSList *test_run_free_queue = NULL;
|
||||||
|
|
||||||
|
/* --- functions --- */
|
||||||
|
static void
|
||||||
|
parse_args (gint *argc_p,
|
||||||
|
gchar ***argv_p)
|
||||||
|
{
|
||||||
|
guint argc = *argc_p;
|
||||||
|
gchar **argv = *argv_p;
|
||||||
|
guint i, e;
|
||||||
|
/* parse known args */
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (strcmp (argv[i], "--g-fatal-warnings") == 0)
|
||||||
|
{
|
||||||
|
GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
|
||||||
|
fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
|
||||||
|
g_log_set_always_fatal (fatal_mask);
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp (argv[i], "--keep-going") == 0 ||
|
||||||
|
strcmp (argv[i], "-k") == 0)
|
||||||
|
{
|
||||||
|
test_mode_fatal = FALSE;
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
|
||||||
|
{
|
||||||
|
gchar *equal = argv[i] + 2;
|
||||||
|
if (*equal == '=')
|
||||||
|
test_paths = g_slist_prepend (test_paths, equal + 1);
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
{
|
||||||
|
argv[i++] = NULL;
|
||||||
|
test_paths = g_slist_prepend (test_paths, argv[i]);
|
||||||
|
}
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-o", argv[i]) == 0 || strncmp ("-o=", argv[i], 3) == 0)
|
||||||
|
{
|
||||||
|
gchar *equal = argv[i] + 2;
|
||||||
|
if (*equal == '=')
|
||||||
|
test_run_output = equal + 1;
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
{
|
||||||
|
argv[i++] = NULL;
|
||||||
|
test_run_output = argv[i];
|
||||||
|
}
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
|
||||||
|
{
|
||||||
|
gchar *equal = argv[i] + 2;
|
||||||
|
const gchar *mode = "";
|
||||||
|
if (*equal == '=')
|
||||||
|
mode = equal + 1;
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
{
|
||||||
|
argv[i++] = NULL;
|
||||||
|
mode = argv[i];
|
||||||
|
}
|
||||||
|
if (strcmp (mode, "perf") == 0)
|
||||||
|
test_mode_perf = TRUE;
|
||||||
|
else if (strcmp (mode, "slow") == 0)
|
||||||
|
test_mode_quick = FALSE;
|
||||||
|
else if (strcmp (mode, "quick") == 0)
|
||||||
|
{
|
||||||
|
test_mode_quick = TRUE;
|
||||||
|
test_mode_perf = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_error ("unknown test mode: -m %s", mode);
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
test_run_quiet = TRUE;
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-l", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
test_run_list = TRUE;
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp ("-seed", argv[i]) == 0 || strncmp ("-seed=", argv[i], 6) == 0)
|
||||||
|
{
|
||||||
|
gchar *equal = argv[i] + 5;
|
||||||
|
if (*equal == '=')
|
||||||
|
test_run_seed = equal + 1;
|
||||||
|
else if (i + 1 < argc)
|
||||||
|
{
|
||||||
|
argv[i++] = NULL;
|
||||||
|
test_run_seed = argv[i];
|
||||||
|
}
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* collapse argv */
|
||||||
|
e = 1;
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
if (argv[i])
|
||||||
|
{
|
||||||
|
argv[e++] = argv[i];
|
||||||
|
if (i >= e)
|
||||||
|
argv[i] = NULL;
|
||||||
|
}
|
||||||
|
*argc_p = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_test_init (int *argc,
|
||||||
|
char ***argv,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
gpointer vararg1;
|
||||||
|
g_return_if_fail (argc != NULL);
|
||||||
|
g_return_if_fail (argv != NULL);
|
||||||
|
g_return_if_fail (g_test_initialized == FALSE);
|
||||||
|
g_test_initialized = TRUE;
|
||||||
|
|
||||||
|
va_start (args, argv);
|
||||||
|
vararg1 = va_arg (args, gpointer); /* reserved for future extensions */
|
||||||
|
va_end (args);
|
||||||
|
g_return_if_fail (vararg1 == NULL);
|
||||||
|
|
||||||
|
parse_args (argc, argv);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GTestSuite*
|
||||||
|
g_test_get_root (void)
|
||||||
|
{
|
||||||
|
if (!test_suite_root)
|
||||||
|
{
|
||||||
|
test_suite_root = g_test_create_suite ("root");
|
||||||
|
g_free (test_suite_root->name);
|
||||||
|
test_suite_root->name = g_strdup ("");
|
||||||
|
}
|
||||||
|
return test_suite_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
g_test_run (void)
|
||||||
|
{
|
||||||
|
return g_test_run_suite (g_test_get_root());
|
||||||
|
}
|
||||||
|
|
||||||
|
GTestCase*
|
||||||
|
g_test_create_case (const char *test_name,
|
||||||
|
gsize data_size,
|
||||||
|
void (*data_setup) (void),
|
||||||
|
void (*data_test) (void),
|
||||||
|
void (*data_teardown) (void))
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (test_name != NULL, NULL);
|
||||||
|
g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL);
|
||||||
|
g_return_val_if_fail (test_name[0] != 0, NULL);
|
||||||
|
g_return_val_if_fail (data_test != NULL, NULL);
|
||||||
|
GTestCase *tc = g_slice_new0 (GTestCase);
|
||||||
|
tc->name = g_strdup (test_name);
|
||||||
|
tc->fixture_size = data_size;
|
||||||
|
tc->fixture_setup = (void*) data_setup;
|
||||||
|
tc->fixture_test = (void*) data_test;
|
||||||
|
tc->fixture_teardown = (void*) data_teardown;
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
|
||||||
|
GTestSuite*
|
||||||
|
g_test_create_suite (const char *suite_name)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (suite_name != NULL, NULL);
|
||||||
|
g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL);
|
||||||
|
g_return_val_if_fail (suite_name[0] != 0, NULL);
|
||||||
|
GTestSuite *ts = g_slice_new0 (GTestSuite);
|
||||||
|
ts->name = g_strdup (suite_name);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_test_suite_add (GTestSuite *suite,
|
||||||
|
GTestCase *test_case)
|
||||||
|
{
|
||||||
|
g_return_if_fail (suite != NULL);
|
||||||
|
g_return_if_fail (test_case != NULL);
|
||||||
|
suite->cases = g_slist_prepend (suite->cases, test_case);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_test_suite_add_suite (GTestSuite *suite,
|
||||||
|
GTestSuite *nestedsuite)
|
||||||
|
{
|
||||||
|
g_return_if_fail (suite != NULL);
|
||||||
|
g_return_if_fail (nestedsuite != NULL);
|
||||||
|
suite->suites = g_slist_prepend (suite->suites, nestedsuite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_test_queue_free (gpointer gfree_pointer)
|
||||||
|
{
|
||||||
|
if (gfree_pointer)
|
||||||
|
test_run_free_queue = g_slist_prepend (test_run_free_queue, gfree_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
test_case_run (GTestCase *tc)
|
||||||
|
{
|
||||||
|
gchar *old_name = test_run_name;
|
||||||
|
test_run_name = g_strconcat (old_name, "/", tc->name, NULL);
|
||||||
|
void *fixture = g_malloc0 (tc->fixture_size);
|
||||||
|
if (tc->fixture_setup)
|
||||||
|
tc->fixture_setup (fixture);
|
||||||
|
tc->fixture_test (fixture);
|
||||||
|
if (tc->fixture_teardown)
|
||||||
|
tc->fixture_teardown (fixture);
|
||||||
|
while (test_run_free_queue)
|
||||||
|
{
|
||||||
|
gpointer freeme = test_run_free_queue->data;
|
||||||
|
test_run_free_queue = g_slist_delete_link (test_run_free_queue, test_run_free_queue);
|
||||||
|
g_free (freeme);
|
||||||
|
}
|
||||||
|
g_free (fixture);
|
||||||
|
g_free (test_run_name);
|
||||||
|
test_run_name = old_name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_test_run_suite_internal (GTestSuite *suite)
|
||||||
|
{
|
||||||
|
guint n_bad = 0, n_good = 0, bad_suite = 0;
|
||||||
|
gchar *old_name = test_run_name;
|
||||||
|
GSList *slist, *reversed;
|
||||||
|
g_return_val_if_fail (suite != NULL, -1);
|
||||||
|
test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL);
|
||||||
|
reversed = g_slist_reverse (g_slist_copy (suite->cases));
|
||||||
|
for (slist = reversed; slist; slist = slist->next)
|
||||||
|
{
|
||||||
|
GTestCase *tc = slist->data;
|
||||||
|
n_good++;
|
||||||
|
n_bad += test_case_run (tc) != 0;
|
||||||
|
}
|
||||||
|
g_slist_free (reversed);
|
||||||
|
reversed = g_slist_reverse (g_slist_copy (suite->suites));
|
||||||
|
for (slist = reversed; slist; slist = slist->next)
|
||||||
|
{
|
||||||
|
GTestSuite *ts = slist->data;
|
||||||
|
bad_suite += g_test_run_suite_internal (ts) != 0;
|
||||||
|
}
|
||||||
|
g_slist_free (reversed);
|
||||||
|
g_free (test_run_name);
|
||||||
|
test_run_name = old_name;
|
||||||
|
return n_bad || bad_suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
g_test_run_suite (GTestSuite *suite)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (g_test_initialized == TRUE, -1);
|
||||||
|
g_return_val_if_fail (g_test_run_once == TRUE, -1);
|
||||||
|
g_test_run_once = FALSE;
|
||||||
|
return g_test_run_suite_internal (suite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_assertion_message (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *message)
|
||||||
|
{
|
||||||
|
char lstr[32];
|
||||||
|
g_snprintf (lstr, 32, "%d", line);
|
||||||
|
char *s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "",
|
||||||
|
file, ":", lstr, ":",
|
||||||
|
func, func[0] ? ":" : "",
|
||||||
|
" ", message, NULL);
|
||||||
|
g_printerr ("**\n** %s\n", s);
|
||||||
|
g_free (s);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_assertion_message_expr (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr)
|
||||||
|
{
|
||||||
|
char *s = g_strconcat ("assertion failed: (", expr, ")", NULL);
|
||||||
|
g_assertion_message (domain, file, line, func, s);
|
||||||
|
g_free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_assertion_message_cmpnum (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr,
|
||||||
|
long double arg1,
|
||||||
|
const char *cmp,
|
||||||
|
long double arg2,
|
||||||
|
char numtype)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
switch (numtype)
|
||||||
|
{
|
||||||
|
case 'i': s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break;
|
||||||
|
case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break;
|
||||||
|
/* ideally use: floats=%.7g double=%.17g */
|
||||||
|
}
|
||||||
|
g_assertion_message (domain, file, line, func, s);
|
||||||
|
g_free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_assertion_message_cmpstr (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr,
|
||||||
|
const char *arg1,
|
||||||
|
const char *cmp,
|
||||||
|
const char *arg2)
|
||||||
|
{
|
||||||
|
char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
|
||||||
|
a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL");
|
||||||
|
a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL");
|
||||||
|
g_free (t1);
|
||||||
|
g_free (t2);
|
||||||
|
s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
|
||||||
|
g_free (a1);
|
||||||
|
g_free (a2);
|
||||||
|
g_assertion_message (domain, file, line, func, s);
|
||||||
|
g_free (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
g_strcmp0 (const char *str1,
|
||||||
|
const char *str2)
|
||||||
|
{
|
||||||
|
if (!str1)
|
||||||
|
return -(str1 != str2);
|
||||||
|
if (!str2)
|
||||||
|
return str1 != str2;
|
||||||
|
return strcmp (str1, str2);
|
||||||
|
}
|
||||||
|
@ -16,3 +16,126 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
#ifndef __G_TESTFRAMEWORK_H__
|
||||||
|
#define __G_TESTFRAMEWORK_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS;
|
||||||
|
|
||||||
|
typedef struct GTestCase GTestCase;
|
||||||
|
typedef struct GTestSuite GTestSuite;
|
||||||
|
|
||||||
|
/* assertion API */
|
||||||
|
#define g_assert_cmpstr(s1, cmp, s2) do { if (g_strcmp0 (s1, s2) cmp 0) ; else \
|
||||||
|
g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
|
||||||
|
#s1 " " #cmp " " #s2, s1, #cmp, s2); } while (0)
|
||||||
|
#define g_assert_cmpint(n1, cmp, n2) do { if (n1 cmp n2) ; else \
|
||||||
|
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
|
||||||
|
#n1 " " #cmp " " #n2, n1, #cmp, n2, 'i'); } while (0)
|
||||||
|
#define g_assert_cmpfloat(n1,cmp,n2) do { if (n1 cmp n2) ; else \
|
||||||
|
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
|
||||||
|
#n1 " " #cmp " " #n2, n1, #cmp, n2, 'f'); } while (0)
|
||||||
|
int g_strcmp0 (const char *str1,
|
||||||
|
const char *str2);
|
||||||
|
// g_assert(condition) /*...*/
|
||||||
|
// g_assert_not_reached() /*...*/
|
||||||
|
|
||||||
|
/* report performance results */
|
||||||
|
void g_test_minimized_result (double minimized_quantity,
|
||||||
|
const char *format,
|
||||||
|
...) G_GNUC_PRINTF (2, 3);
|
||||||
|
void g_test_maximized_result (double maximized_quantity,
|
||||||
|
const char *format,
|
||||||
|
...) G_GNUC_PRINTF (2, 3);
|
||||||
|
|
||||||
|
/* guards used around forked tests */
|
||||||
|
guint g_test_trap_fork ();
|
||||||
|
void g_test_trap_assert_passed (void);
|
||||||
|
void g_test_trap_assert_failed (void);
|
||||||
|
void g_test_trap_assert_stdout (const char *stdout_pattern);
|
||||||
|
void g_test_trap_assert_stderr (const char *stderr_pattern);
|
||||||
|
|
||||||
|
/* initialize testing framework */
|
||||||
|
void g_test_init (int *argc,
|
||||||
|
char ***argv,
|
||||||
|
...);
|
||||||
|
/* run all tests under toplevel suite (path: /) */
|
||||||
|
int g_test_run (void);
|
||||||
|
/* hook up a simple test function under test path */
|
||||||
|
void g_test_add_func (const char *testpath,
|
||||||
|
void (*test_func) (void));
|
||||||
|
/* hook up a test with fixture under test path */
|
||||||
|
#define g_test_add(testpath, Fixture, fsetup, ftest, fteardown) \
|
||||||
|
((void (*) (const char*, \
|
||||||
|
gsize, \
|
||||||
|
void (*) (Fixture*), \
|
||||||
|
void (*) (Fixture*), \
|
||||||
|
void (*) (Fixture*))) \
|
||||||
|
(void*) g_test_add_vtable) \
|
||||||
|
(testpath, sizeof (Fixture), fsetup, ftest, fteardown)
|
||||||
|
/* measure test timings */
|
||||||
|
void g_test_timer_start (void);
|
||||||
|
double g_test_timer_elapsed (void); // elapsed seconds
|
||||||
|
double g_test_timer_last (void); // repeat last elapsed() result
|
||||||
|
|
||||||
|
/* automatically g_free or g_object_unref upon teardown */
|
||||||
|
void g_test_queue_free (gpointer gfree_pointer);
|
||||||
|
void g_test_queue_unref (gpointer gobjectunref_pointer);
|
||||||
|
|
||||||
|
/* provide seed-able random numbers for tests */
|
||||||
|
long double g_test_rand_range (long double range_start,
|
||||||
|
long double range_end);
|
||||||
|
|
||||||
|
/* semi-internal API */
|
||||||
|
GTestCase* g_test_create_case (const char *test_name,
|
||||||
|
gsize data_size,
|
||||||
|
void (*data_setup) (void),
|
||||||
|
void (*data_test) (void),
|
||||||
|
void (*data_teardown) (void));
|
||||||
|
GTestSuite* g_test_create_suite (const char *suite_name);
|
||||||
|
GTestSuite* g_test_get_root (void);
|
||||||
|
void g_test_suite_add (GTestSuite *suite,
|
||||||
|
GTestCase *test_case);
|
||||||
|
void g_test_suite_add_suite (GTestSuite *suite,
|
||||||
|
GTestSuite *nestedsuite);
|
||||||
|
int g_test_run_suite (GTestSuite *suite);
|
||||||
|
|
||||||
|
/* internal ABI */
|
||||||
|
void g_assertion_message (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *message);
|
||||||
|
void g_assertion_message_expr (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr);
|
||||||
|
void g_assertion_message_cmpstr (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr,
|
||||||
|
const char *arg1,
|
||||||
|
const char *cmp,
|
||||||
|
const char *arg2);
|
||||||
|
void g_assertion_message_cmpnum (const char *domain,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *expr,
|
||||||
|
long double arg1,
|
||||||
|
const char *cmp,
|
||||||
|
long double arg2,
|
||||||
|
char numtype);
|
||||||
|
void g_test_add_vtable (const char *testpath,
|
||||||
|
gsize data_size,
|
||||||
|
void (*data_setup) (void),
|
||||||
|
void (*data_test) (void),
|
||||||
|
void (*data_teardown) (void));
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS;
|
||||||
|
|
||||||
|
#endif /* __G_TESTFRAMEWORK_H__ */
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
INCLUDES = -g -I$(top_srcdir) -I$(top_srcdir)/glib $(GLIB_DEBUG_FLAGS)
|
||||||
|
|
||||||
|
TESTS =
|
||||||
|
noinst_PROGRAMS = $(TESTS)
|
||||||
|
progs_ldadd = $(top_builddir)/glib/libglib-2.0.la
|
||||||
|
|
||||||
|
|
||||||
|
TESTS += testing
|
||||||
|
testing_SOURCES = testing.c
|
||||||
|
testing_LDADD = $(progs_ldadd)
|
||||||
|
|
||||||
|
|
||||||
|
test:
|
||||||
|
@set -e \
|
||||||
|
&& for tst in ${TESTS} ; do \
|
||||||
|
echo -n "TEST: ./$$tst... " ; \
|
||||||
|
./$$tst ; \
|
||||||
|
echo "OK" ; \
|
||||||
|
done
|
||||||
|
.PHONY: test
|
96
glib/tests/testing.c
Normal file
96
glib/tests/testing.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* GLib testing framework examples and tests
|
||||||
|
* Copyright (C) 2007 Tim Janik
|
||||||
|
*
|
||||||
|
* This work is provided "as is"; redistribution and modification
|
||||||
|
* in whole or in part, in any medium, physical or electronic is
|
||||||
|
* permitted without restriction.
|
||||||
|
*
|
||||||
|
* This work 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.
|
||||||
|
*
|
||||||
|
* In no event shall the authors or contributors be liable for any
|
||||||
|
* direct, indirect, incidental, special, exemplary, or consequential
|
||||||
|
* damages (including, but not limited to, procurement of substitute
|
||||||
|
* goods or services; loss of use, data, or profits; or business
|
||||||
|
* interruption) however caused and on any theory of liability, whether
|
||||||
|
* in contract, strict liability, or tort (including negligence or
|
||||||
|
* otherwise) arising in any way out of the use of this software, even
|
||||||
|
* if advised of the possibility of such damage.
|
||||||
|
*/
|
||||||
|
#include <glib/gtestframework.h>
|
||||||
|
|
||||||
|
/* test assertion variants */
|
||||||
|
static void
|
||||||
|
test_assertions (void)
|
||||||
|
{
|
||||||
|
g_assert_cmpint (1, >, 0);
|
||||||
|
g_assert_cmpint (2, ==, 2);
|
||||||
|
g_assert_cmpfloat (3.3, !=, 7);
|
||||||
|
g_assert_cmpfloat (7, <=, 3 + 4);
|
||||||
|
g_assert (TRUE);
|
||||||
|
g_assert_cmpstr ("foo", !=, "faa");
|
||||||
|
gchar *fuu = g_strdup_printf ("f%s", "uu");
|
||||||
|
g_test_queue_free (fuu);
|
||||||
|
g_assert_cmpstr ("foo", !=, fuu);
|
||||||
|
g_assert_cmpstr ("fuu", ==, fuu);
|
||||||
|
g_assert_cmpstr (NULL, <, "");
|
||||||
|
g_assert_cmpstr (NULL, ==, NULL);
|
||||||
|
g_assert_cmpstr ("", >, NULL);
|
||||||
|
g_assert_cmpstr ("foo", <, "fzz");
|
||||||
|
g_assert_cmpstr ("fzz", >, "faa");
|
||||||
|
g_assert_cmpstr ("fzz", ==, "fzz");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run a test with fixture setup and teardown */
|
||||||
|
typedef struct {
|
||||||
|
guint seed;
|
||||||
|
guint prime;
|
||||||
|
gchar *msg;
|
||||||
|
} Fixturetest;
|
||||||
|
|
||||||
|
static void
|
||||||
|
fixturetest_setup (Fixturetest *fix)
|
||||||
|
{
|
||||||
|
fix->seed = 18;
|
||||||
|
fix->prime = 19;
|
||||||
|
fix->msg = g_strdup_printf ("%d", fix->prime);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fixturetest_test (Fixturetest *fix)
|
||||||
|
{
|
||||||
|
guint prime = g_spaced_primes_closest (fix->seed);
|
||||||
|
g_assert_cmpint (prime, ==, fix->prime);
|
||||||
|
prime = g_ascii_strtoull (fix->msg, NULL, 0);
|
||||||
|
g_assert_cmpint (prime, ==, fix->prime);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fixturetest_teardown (Fixturetest *fix)
|
||||||
|
{
|
||||||
|
g_free (fix->msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
GTestCase *tc;
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
GTestSuite *rootsuite = g_test_create_suite ("root");
|
||||||
|
GTestSuite *miscsuite = g_test_create_suite ("misc");
|
||||||
|
g_test_suite_add_suite (rootsuite, miscsuite);
|
||||||
|
GTestSuite *forksuite = g_test_create_suite ("fork");
|
||||||
|
g_test_suite_add_suite (rootsuite, forksuite);
|
||||||
|
|
||||||
|
tc = g_test_create_case ("assertions", 0, NULL, test_assertions, NULL);
|
||||||
|
g_test_suite_add (miscsuite, tc);
|
||||||
|
tc = g_test_create_case ("primetoul", sizeof (Fixturetest),
|
||||||
|
(void(*)(void)) fixturetest_setup,
|
||||||
|
(void(*)(void)) fixturetest_test,
|
||||||
|
(void(*)(void)) fixturetest_teardown);
|
||||||
|
g_test_suite_add (miscsuite, tc);
|
||||||
|
|
||||||
|
return g_test_run_suite (rootsuite);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user