diff options
Diffstat (limited to 'src/egg-test.c')
-rw-r--r-- | src/egg-test.c | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/src/egg-test.c b/src/egg-test.c new file mode 100644 index 0000000..996d017 --- /dev/null +++ b/src/egg-test.c @@ -0,0 +1,343 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2007-2008 Richard Hughes <[email protected]> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdlib.h> +#include <glib.h> +#include <string.h> +#include <glib/gi18n.h> +#include <glib-object.h> +#include <glib/gprintf.h> + +#include "egg-test.h" + +struct EggTest { + guint total; + guint succeeded; + gboolean started; + gboolean titled; + gchar *type; + GTimer *timer; + GMainLoop *loop; + guint hang_loop_id; + gpointer user_data; +}; + +/** + * egg_test_init: + **/ +EggTest * +egg_test_init () +{ + EggTest *test; + test = g_new (EggTest, 1); + test->total = 0; + test->succeeded = 0; + test->type = NULL; + test->started = FALSE; + test->titled = FALSE; + test->timer = g_timer_new (); + test->loop = g_main_loop_new (NULL, FALSE); + test->hang_loop_id = 0; + return test; +} + +/** + * egg_test_loop_quit: + **/ +void +egg_test_loop_quit (EggTest *test) +{ + /* disable the loop watch */ + if (test->hang_loop_id != 0) { + g_source_remove (test->hang_loop_id); + test->hang_loop_id = 0; + } + g_main_loop_quit (test->loop); +} + +/** + * egg_test_hang_check: + **/ +static gboolean +egg_test_hang_check (gpointer data) +{ + EggTest *test = (EggTest *) data; + g_main_loop_quit (test->loop); + return FALSE; +} + +/** + * egg_test_loop_wait: + **/ +void +egg_test_loop_wait (EggTest *test, guint timeout) +{ + test->hang_loop_id = g_timeout_add (timeout, egg_test_hang_check, test); + g_main_loop_run (test->loop); +} + +/** + * egg_test_loop_check: + **/ +void +egg_test_loop_check (EggTest *test) +{ + guint elapsed = egg_test_elapsed (test); + egg_test_title (test, "did we timeout out of the loop"); + if (test->hang_loop_id == 0) { + egg_test_success (test, "loop blocked for %ims", elapsed); + } else { + egg_test_failed (test, "hangcheck saved us after %ims", elapsed); + } +} + +/** + * egg_test_set_user_data: + **/ +void +egg_test_set_user_data (EggTest *test, gpointer user_data) +{ + test->user_data = user_data; +} + +/** + * egg_test_get_user_data: + **/ +gpointer +egg_test_get_user_data (EggTest *test) +{ + return test->user_data; +} + +/** + * egg_test_finish: + **/ +gint +egg_test_finish (EggTest *test) +{ + gint retval; + g_print ("test passes (%u/%u) : ", test->succeeded, test->total); + if (test->succeeded == test->total) { + g_print ("ALL OKAY\n"); + retval = 0; + } else { + g_print ("%u FAILURE(S)\n", test->total - test->succeeded); + retval = 1; + } + + g_timer_destroy (test->timer); + g_main_loop_unref (test->loop); + g_free (test); + + return retval; +} + +/** + * egg_test_elapsed: + * + * Returns: time in ms + **/ +guint +egg_test_elapsed (EggTest *test) +{ + gdouble time_s; + time_s = g_timer_elapsed (test->timer, NULL); + return (guint) (time_s * 1000.0f); +} + +/** + * egg_test_start: + **/ +gboolean +egg_test_start (EggTest *test, const gchar *name) +{ + if (test->started) { + g_print ("Not ended test! Cannot start!\n"); + exit (1); + } + test->type = g_strdup (name); + test->started = TRUE; + return TRUE; +} + +/** + * egg_test_end: + **/ +void +egg_test_end (EggTest *test) +{ + if (test->started == FALSE) { + g_print ("Not started test! Cannot finish!\n"); + exit (1); + } + g_print ("OK\n"); + + /* disable hang check */ + if (test->hang_loop_id != 0) { + g_source_remove (test->hang_loop_id); + test->hang_loop_id = 0; + } + + test->started = FALSE; + g_free (test->type); +} + +/** + * egg_test_title: + **/ +void +egg_test_title (EggTest *test, const gchar *format, ...) +{ + va_list args; + gchar *va_args_buffer = NULL; + + /* already titled? */ + if (test->titled) { + g_print ("Already titled!\n"); + exit (1); + } + + /* reset the value egg_test_elapsed replies with */ + g_timer_reset (test->timer); + + va_start (args, format); + g_vasprintf (&va_args_buffer, format, args); + va_end (args); + g_print ("> check #%u\t%s: \t%s...", test->total+1, test->type, va_args_buffer); + g_free (va_args_buffer); + + test->titled = TRUE; + test->total++; +} + +/** + * egg_test_success: + **/ +void +egg_test_success (EggTest *test, const gchar *format, ...) +{ + va_list args; + gchar *va_args_buffer = NULL; + + /* not titled? */ + if (!test->titled) { + g_print ("Not titled!\n"); + exit (1); + } + if (format == NULL) { + g_print ("...OK\n"); + goto finish; + } + va_start (args, format); + g_vasprintf (&va_args_buffer, format, args); + va_end (args); + g_print ("...OK [%s]\n", va_args_buffer); + g_free (va_args_buffer); +finish: + test->titled = FALSE; + test->succeeded++; +} + +/** + * egg_test_failed: + **/ +void +egg_test_failed (EggTest *test, const gchar *format, ...) +{ + va_list args; + gchar *va_args_buffer = NULL; + + /* not titled? */ + if (!test->titled) { + g_print ("Not titled!\n"); + exit (1); + } + if (format == NULL) { + g_print ("FAILED\n"); + goto failed; + } + va_start (args, format); + g_vasprintf (&va_args_buffer, format, args); + va_end (args); + g_print ("FAILED [%s]\n", va_args_buffer); + g_free (va_args_buffer); +failed: + exit (1); +} + +/** + * egg_test_assert: + **/ +void +egg_test_assert (EggTest *test, gboolean value) +{ + if (value) + egg_test_success (test, NULL); + else + egg_test_failed (test, NULL); +} + +/** + * egg_test_title_assert: + **/ +void +egg_test_title_assert (EggTest *test, const gchar *text, gboolean value) +{ + egg_test_title (test, "%s", text); + if (value) + egg_test_success (test, NULL); + else + egg_test_failed (test, NULL); +} + +/** + * egg_test_get_data_file: + **/ +gchar * +egg_test_get_data_file (const gchar *filename) +{ + gboolean ret; + gchar *full; + + /* check to see if we are being run in the build root */ + full = g_build_filename ("..", "data", "tests", filename, NULL); + ret = g_file_test (full, G_FILE_TEST_EXISTS); + if (ret) + return full; + g_free (full); + + /* check to see if we are being run in the build root */ + full = g_build_filename ("..", "..", "data", "tests", filename, NULL); + ret = g_file_test (full, G_FILE_TEST_EXISTS); + if (ret) + return full; + g_free (full); + + /* check to see if we are being run in make check */ + full = g_build_filename ("..", "..", "..", "data", "tests", filename, NULL); + ret = g_file_test (full, G_FILE_TEST_EXISTS); + if (ret) + return full; + g_print ("[WARN] failed to find '%s'\n", full); + g_free (full); + return NULL; +} + |