2008-02-02 17:34:25 -06:00
|
|
|
#ifndef MOO_ENABLE_UNIT_TESTS
|
|
|
|
#error "Ooops"
|
|
|
|
#endif
|
|
|
|
|
2008-01-31 01:16:57 -06:00
|
|
|
#ifndef MOO_TEST_MACROS_H
|
|
|
|
#define MOO_TEST_MACROS_H
|
2008-01-20 00:36:06 -06:00
|
|
|
|
2008-01-31 01:16:57 -06:00
|
|
|
#include "moo-test-utils.h"
|
2008-01-20 00:36:06 -06:00
|
|
|
#include <glib.h>
|
|
|
|
#include <string.h>
|
2008-02-18 18:09:26 -06:00
|
|
|
#include <stdlib.h>
|
2008-01-20 00:36:06 -06:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
|
|
|
|
|
2008-01-27 00:04:00 -06:00
|
|
|
#define TEST_FAILED_MSG(format,...) \
|
2008-01-31 01:16:57 -06:00
|
|
|
moo_test_assert_msg (FALSE, __FILE__, __LINE__, \
|
|
|
|
format, __VA_ARGS__)
|
2008-01-27 00:04:00 -06:00
|
|
|
|
2008-01-29 00:51:59 -06:00
|
|
|
#define TEST_FAILED(msg) \
|
2008-01-31 01:16:57 -06:00
|
|
|
moo_test_assert_msg (FALSE, __FILE__, __LINE__, \
|
|
|
|
"%s", msg)
|
2008-01-29 00:51:59 -06:00
|
|
|
|
2008-01-20 00:36:06 -06:00
|
|
|
#define TEST_ASSERT_MSG(cond,format,...) \
|
2008-01-31 01:16:57 -06:00
|
|
|
moo_test_assert_msg (!!(cond), __FILE__, __LINE__, \
|
|
|
|
format, __VA_ARGS__)
|
2008-01-20 00:36:06 -06:00
|
|
|
|
|
|
|
#define TEST_ASSERT(cond) \
|
2008-01-31 01:16:57 -06:00
|
|
|
moo_test_assert_impl (!!(cond), (char*) #cond, \
|
|
|
|
__FILE__, __LINE__)
|
2008-01-20 00:36:06 -06:00
|
|
|
|
|
|
|
#define TEST_ASSERT_CMP__(Type,actual,expected,cmp,fmt_arg,msg) \
|
|
|
|
G_STMT_START { \
|
|
|
|
Type actual__ = actual; \
|
|
|
|
Type expected__ = expected; \
|
|
|
|
gboolean passed__ = cmp (actual__, expected__); \
|
|
|
|
TEST_ASSERT_MSG (passed__, \
|
|
|
|
"%s: expected %s, got %s", msg, \
|
|
|
|
fmt_arg (expected__), \
|
|
|
|
fmt_arg (actual__)); \
|
|
|
|
} G_STMT_END
|
|
|
|
|
|
|
|
#define TEST_ASSERT_CMP(Type,actual,expected,cmp,cmp_sym,fmt_arg) \
|
|
|
|
TEST_ASSERT_CMP__ (Type, actual, expected, cmp, fmt_arg, \
|
|
|
|
#actual " " #cmp_sym " " #expected) \
|
|
|
|
|
|
|
|
#define TEST_ASSERT_CMP_MSG(Type,actual,expected,cmp, \
|
|
|
|
fmt_arg,format,...) \
|
|
|
|
G_STMT_START { \
|
|
|
|
char *msg__ = g_strdup_printf (format, __VA_ARGS__); \
|
|
|
|
TEST_ASSERT_CMP__ (Type, actual, expected, cmp, fmt_arg, \
|
|
|
|
msg__); \
|
|
|
|
g_free (msg__); \
|
|
|
|
} G_STMT_END
|
|
|
|
|
|
|
|
#define TEST_ASSERT_STR_EQ(actual,expected) \
|
|
|
|
TEST_ASSERT_CMP (const char *, actual, expected, \
|
|
|
|
TEST_STR_EQ, =, TEST_FMT_STR)
|
|
|
|
|
|
|
|
#define TEST_ASSERT_STR_NEQ(actual,expected) \
|
|
|
|
TEST_ASSERT_CMP (const char *, actual, expected, \
|
2008-01-20 03:11:24 -06:00
|
|
|
TEST_STR_NEQ, !=, TEST_FMT_STR)
|
2008-01-20 00:36:06 -06:00
|
|
|
|
|
|
|
#define TEST_ASSERT_STR_EQ_MSG(actual,expected,format,...) \
|
|
|
|
TEST_ASSERT_CMP_MSG (const char *, actual, expected, \
|
|
|
|
TEST_STR_EQ, TEST_FMT_STR, \
|
|
|
|
format, __VA_ARGS__)
|
|
|
|
|
|
|
|
#define TEST_ASSERT_STRV_EQ_MSG(actual,expected,format,...) \
|
|
|
|
TEST_ASSERT_CMP_MSG (char**, actual, expected, \
|
|
|
|
TEST_STRV_EQ, TEST_FMT_STRV, \
|
|
|
|
format, __VA_ARGS__)
|
|
|
|
|
2008-02-02 16:54:52 -06:00
|
|
|
#define TEST_ASSERT_INT_EQ(actual,expected) \
|
|
|
|
TEST_ASSERT_CMP (int, actual, expected, \
|
|
|
|
TEST_CMP_EQ, =, TEST_FMT_INT)
|
|
|
|
|
|
|
|
#define TEST_ASSERT_DBL_EQ(actual,expected) \
|
|
|
|
TEST_ASSERT_CMP (double, actual, expected, \
|
|
|
|
TEST_CMP_EQ, =, TEST_FMT_DBL)
|
|
|
|
|
2008-01-20 00:36:06 -06:00
|
|
|
#define TEST_CMP_EQ(a,b) ((a) == (b))
|
|
|
|
#define TEST_CMP_NEQ(a,b) ((a) != (b))
|
|
|
|
#define TEST_CMP_LT(a,b) ((a) < (b))
|
|
|
|
#define TEST_CMP_LE(a,b) ((a) <= (b))
|
|
|
|
#define TEST_CMP_GT(a,b) ((a) > (b))
|
|
|
|
#define TEST_CMP_GE(a,b) ((a) >= (b))
|
|
|
|
|
|
|
|
#define TEST_STR_NEQ(s1,s2) (!TEST_STR_EQ ((s1), (s2)))
|
|
|
|
#define TEST_STRV_NEQ(s1,s2) (!TEST_STRV_EQ ((s1), (s2)))
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static gboolean
|
|
|
|
TEST_STR_EQ (const char *s1, const char *s2)
|
|
|
|
{
|
|
|
|
if (!s1 || !s2)
|
|
|
|
return s1 == s2;
|
|
|
|
else
|
|
|
|
return strcmp (s1, s2) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static gboolean
|
|
|
|
TEST_STRV_EQ (char **ar1, char **ar2)
|
|
|
|
{
|
|
|
|
if (!ar1 || !ar2)
|
|
|
|
return ar1 == ar2;
|
|
|
|
|
|
|
|
while (*ar1 && *ar2)
|
|
|
|
if (strcmp (*ar1++, *ar2++) != 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return *ar1 == *ar2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
test_string_stack_add__ (char *string)
|
|
|
|
{
|
|
|
|
#define STACK_LEN 100
|
|
|
|
static char *stack[STACK_LEN];
|
|
|
|
static guint ptr = STACK_LEN;
|
|
|
|
|
|
|
|
if (ptr == STACK_LEN)
|
|
|
|
ptr = 0;
|
|
|
|
|
|
|
|
g_free (stack[ptr]);
|
|
|
|
stack[ptr++] = string;
|
|
|
|
|
|
|
|
return string;
|
|
|
|
#undef STACK_LEN
|
|
|
|
}
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static const char *
|
|
|
|
TEST_FMT_STR (const char *s)
|
|
|
|
{
|
2008-02-03 02:02:26 -06:00
|
|
|
GString *buf;
|
|
|
|
|
|
|
|
if (!s)
|
2008-01-20 00:36:06 -06:00
|
|
|
return "<null>";
|
2008-02-03 02:02:26 -06:00
|
|
|
|
|
|
|
buf = g_string_new ("\"");
|
|
|
|
|
|
|
|
while (*s)
|
|
|
|
{
|
2008-02-20 18:45:20 -06:00
|
|
|
char c = *s++;
|
|
|
|
|
|
|
|
switch (c)
|
2008-02-03 02:02:26 -06:00
|
|
|
{
|
|
|
|
case '\r':
|
|
|
|
g_string_append (buf, "\\r");
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
g_string_append (buf, "\\n");
|
|
|
|
break;
|
|
|
|
case '\t':
|
|
|
|
g_string_append (buf, "\\t");
|
|
|
|
break;
|
|
|
|
case '\\':
|
|
|
|
g_string_append (buf, "\\\\");
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
g_string_append (buf, "\\\"");
|
|
|
|
break;
|
|
|
|
default:
|
2008-02-20 18:45:20 -06:00
|
|
|
if (g_ascii_isprint (c))
|
|
|
|
g_string_append_c (buf, c);
|
2008-02-03 02:02:26 -06:00
|
|
|
else
|
2008-02-20 18:45:20 -06:00
|
|
|
g_string_append_printf (buf, "\\x%02x", (guchar)c);
|
2008-02-03 02:02:26 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_append (buf, "\"");
|
|
|
|
return test_string_stack_add__ (g_string_free (buf, FALSE));
|
2008-01-20 00:36:06 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static const char *
|
|
|
|
TEST_FMT_STRV (char **array)
|
|
|
|
{
|
|
|
|
GString *s;
|
|
|
|
|
|
|
|
if (!array)
|
|
|
|
return "<null>";
|
|
|
|
|
2008-02-03 02:02:26 -06:00
|
|
|
s = g_string_new ("{");
|
2008-01-20 00:36:06 -06:00
|
|
|
|
|
|
|
while (*array)
|
|
|
|
{
|
2008-02-03 02:02:26 -06:00
|
|
|
if (s->len > 1)
|
|
|
|
g_string_append (s, ", ");
|
2008-01-20 00:36:06 -06:00
|
|
|
g_string_append_printf (s, "\"%s\"", *array++);
|
|
|
|
}
|
|
|
|
|
2008-02-03 02:02:26 -06:00
|
|
|
g_string_append (s, "}");
|
2008-01-20 00:36:06 -06:00
|
|
|
return test_string_stack_add__ (g_string_free (s, FALSE));
|
|
|
|
}
|
|
|
|
|
|
|
|
#define TEST_FMT_INT(a) test_string_stack_add__ (g_strdup_printf ("%d", (int) a))
|
|
|
|
#define TEST_FMT_UINT(a) test_string_stack_add__ (g_strdup_printf ("%u", (guint) a))
|
2008-02-02 16:54:52 -06:00
|
|
|
#define TEST_FMT_DBL(a) test_string_stack_add__ (g_strdup_printf ("%f", (double) a))
|
2008-01-20 00:36:06 -06:00
|
|
|
|
2008-02-14 21:44:50 -06:00
|
|
|
#define TEST_G_ASSERT(expr) \
|
|
|
|
G_STMT_START { \
|
2008-02-18 18:09:26 -06:00
|
|
|
if (G_UNLIKELY (!(expr))) \
|
|
|
|
{ \
|
|
|
|
char lstr[32]; \
|
|
|
|
char *s; \
|
|
|
|
g_snprintf (lstr, 32, "%d", __LINE__); \
|
|
|
|
s = g_strconcat ("ERROR:(", __FILE__, \
|
|
|
|
":", lstr, "):", \
|
|
|
|
G_STRFUNC, ": ", \
|
|
|
|
"assertion failed: (", \
|
|
|
|
#expr, ")", NULL); \
|
|
|
|
g_printerr ("**\n** %s\n", s); \
|
|
|
|
g_free (s); \
|
|
|
|
abort(); \
|
|
|
|
} \
|
2008-02-14 21:44:50 -06:00
|
|
|
} G_STMT_END
|
2008-01-20 03:38:04 -06:00
|
|
|
|
2008-05-02 09:52:38 -05:00
|
|
|
G_GNUC_UNUSED static struct TestWarningsInfo {
|
2008-01-20 01:15:56 -06:00
|
|
|
int count;
|
|
|
|
int line;
|
|
|
|
char *file;
|
|
|
|
char *msg;
|
|
|
|
} *test_warnings_info;
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_log_handler (const gchar *log_domain,
|
|
|
|
GLogLevelFlags log_level,
|
|
|
|
const gchar *message,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2008-01-20 03:11:24 -06:00
|
|
|
TEST_G_ASSERT (data == test_warnings_info);
|
2008-01-20 01:15:56 -06:00
|
|
|
|
2008-01-20 03:11:24 -06:00
|
|
|
if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING))
|
|
|
|
{
|
|
|
|
test_warnings_info->count -= 1;
|
2008-01-20 01:15:56 -06:00
|
|
|
|
2008-01-20 03:11:24 -06:00
|
|
|
if (test_warnings_info->count < 0)
|
|
|
|
g_log_default_handler (log_domain, log_level, message, NULL);
|
|
|
|
}
|
2008-01-20 01:15:56 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TEST_EXPECT_WARNINGV_ (int howmany,
|
|
|
|
int line,
|
|
|
|
const char *file,
|
|
|
|
const char *fmt,
|
|
|
|
va_list args)
|
|
|
|
{
|
2008-01-20 03:11:24 -06:00
|
|
|
TEST_G_ASSERT (test_warnings_info == NULL);
|
|
|
|
TEST_G_ASSERT (howmany >= 0);
|
2008-01-20 01:15:56 -06:00
|
|
|
|
|
|
|
test_warnings_info = g_new0 (struct TestWarningsInfo, 1);
|
|
|
|
test_warnings_info->count = howmany;
|
|
|
|
test_warnings_info->line = line;
|
|
|
|
test_warnings_info->file = g_strdup (file);
|
|
|
|
test_warnings_info->msg = g_strdup_vprintf (fmt, args);
|
|
|
|
|
|
|
|
g_log_set_default_handler (test_log_handler, test_warnings_info);
|
|
|
|
g_log_set_handler (NULL, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
|
|
test_log_handler, test_warnings_info);
|
|
|
|
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
|
|
test_log_handler, test_warnings_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static void
|
|
|
|
TEST_EXPECT_WARNING_ (int howmany,
|
|
|
|
int line,
|
|
|
|
const char *file,
|
|
|
|
const char *fmt,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start (args, fmt);
|
|
|
|
TEST_EXPECT_WARNINGV_ (howmany, line, file, fmt, args);
|
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define TEST_EXPECT_WARNING(howmany,fmt,...) \
|
|
|
|
TEST_EXPECT_WARNING_ (howmany, __LINE__, __FILE__, \
|
|
|
|
fmt, __VA_ARGS__)
|
|
|
|
|
|
|
|
G_GNUC_UNUSED static void
|
|
|
|
TEST_CHECK_WARNING (void)
|
|
|
|
{
|
2008-01-20 03:11:24 -06:00
|
|
|
TEST_G_ASSERT (test_warnings_info != NULL);
|
2008-01-20 01:15:56 -06:00
|
|
|
|
2008-01-31 01:16:57 -06:00
|
|
|
moo_test_assert_msg (test_warnings_info->count == 0,
|
|
|
|
test_warnings_info->file,
|
|
|
|
test_warnings_info->line,
|
|
|
|
"%s: %d %s warning(s)",
|
|
|
|
test_warnings_info->msg ? test_warnings_info->msg : "",
|
|
|
|
ABS (test_warnings_info->count),
|
|
|
|
test_warnings_info->count < 0 ?
|
|
|
|
"unexpected" : "missing");
|
2008-01-20 01:15:56 -06:00
|
|
|
|
|
|
|
g_free (test_warnings_info->msg);
|
|
|
|
g_free (test_warnings_info->file);
|
|
|
|
g_free (test_warnings_info);
|
|
|
|
test_warnings_info = NULL;
|
|
|
|
|
|
|
|
g_log_set_default_handler (g_log_default_handler, NULL);
|
|
|
|
g_log_set_handler (NULL, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
|
|
g_log_default_handler, test_warnings_info);
|
|
|
|
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
|
|
|
g_log_default_handler, test_warnings_info);
|
|
|
|
}
|
|
|
|
|
2008-01-20 00:36:06 -06:00
|
|
|
|
|
|
|
G_END_DECLS
|
|
|
|
|
2008-01-31 01:16:57 -06:00
|
|
|
#endif /* MOO_TEST_MACROS_H */
|