[gjs] test: Refactor the unit test framework



commit c4bd39e392ae5936f74f00c92d3eaf023cd89c19
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Jan 7 13:52:12 2013 -0500

    test: Refactor the unit test framework
    
    Rather than fight with a system which autogenerates a gtest for about
    ten tests, simply put tests manually in the file for now.
    
    By putting these tests in separate files, it also means that we won't
    have strange dual symbol issues by compiling the same source file twice.
    A test framework should represent usage in the real world, after all.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=691108

 .gitignore              |    4 -
 Makefile-test.am        |   29 +-----
 Makefile.am             |    2 -
 gjs/context.c           |   32 ------
 gjs/jsapi-util-array.c  |   44 --------
 gjs/jsapi-util-error.c  |   67 ------------
 gjs/jsapi-util-string.c |   29 ------
 gjs/stack.c             |   17 ---
 gjs/unit-test-utils.c   |   50 ---------
 gjs/unit-test-utils.h   |   42 --------
 scripts/make-tests      |  168 -------------------------------
 test/gjs-tests.c        |  255 +++++++++++++++++++++++++++++++++++++++++++++-
 test/test.h             |   44 --------
 util/glib.c             |   42 --------
 14 files changed, 250 insertions(+), 575 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 5597c9f..d8dc1df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,10 +26,6 @@ gjs-internals-1.0.pc
 gjs-gi-1.0.pc
 gjs-tests
 gjs-unit
-gjstest.c
-gjstest.c.stamp
-gjstest.h
-gjstest.h.stamp
 gjs/gjs.stp
 gjs_gi_probes.h
 install-sh
diff --git a/Makefile-test.am b/Makefile-test.am
index 9c3efcb..8b36024 100644
--- a/Makefile-test.am
+++ b/Makefile-test.am
@@ -7,7 +7,6 @@ TEST_PROGS += gjs-tests
 endif
 
 gjs_tests_CFLAGS =				\
-	-include $(top_srcdir)/test/test.h	\
 	$(AM_CFLAGS)				\
 	-DGJS_COMPILATION			\
 	$(GJSTESTS_CFLAGS)			\
@@ -21,23 +20,7 @@ gjs_tests_LDADD =		\
 	$(GJSTESTS_LIBS)
 
 gjs_tests_SOURCES =		\
-	test/gjs-tests.c	\
-	test/test.h		\
-	$(gjstest_files_with_tests)
-
-nodist_gjs_tests_SOURCES =	\
-	gjstest.c		\
-	gjstest.h
-
-## make-tests always updates the ".stamp" files, but only modifies the
-## actual gjstest.[hc] if they change. make-tests creates both
-## .h.stamp and .c.stamp but if we listed both, make would run
-## make-tests twice.
-gjstest.h.stamp : scripts/make-tests $(gjstest_files_with_tests)
-	$(TESTS_ENVIRONMENT) $(top_srcdir)/scripts/make-tests . $(gjstest_files_with_tests)
-
-gjstest.h gjstest.c : gjstest.h.stamp
-	@true
+	test/gjs-tests.c
 
 if ENABLE_TESTS
 TEST_PROGS += gjs-unit
@@ -57,16 +40,6 @@ gjs_unit_LDFLAGS=-export-dynamic -rdynamic
 gjs_unit_SOURCES =	\
 	test/gjs-unit.c
 
-
-BUILT_SOURCES += $(nodist_gjs_tests_SOURCES)
-CLEANFILES +=				\
-	$(nodist_gjs_tests_SOURCES)	\
-	gjstest.c.stamp			\
-	gjstest.h.stamp
-
-EXTRA_DIST +=			\
-	scripts/make-tests
-
 # noinst_ always builds a static library
 if ENABLE_TESTS
 testlib_LTLIBRARIES = libregress.la libwarnlib.la libgimarshallingtests.la
diff --git a/Makefile.am b/Makefile.am
index 0083020..d97cd19 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -62,7 +62,6 @@ noinst_HEADERS +=		\
 	gjs/jsapi-private.h	\
 	gjs/profiler.h		\
 	gi/proxyutils.h		\
-	gjs/unit-test-utils.h	\
 	util/crash.h		\
 	util/error.h		\
 	util/glib.h		\
@@ -120,7 +119,6 @@ libgjs_la_SOURCES =		\
 	gjs/profiler.c		\
 	gjs/stack.c		\
 	gjs/type-module.c	\
-	gjs/unit-test-utils.c	\
 	util/error.c		\
 	util/glib.c		\
 	util/crash.c		\
diff --git a/gjs/context.c b/gjs/context.c
index 8894de6..8bb2d24 100644
--- a/gjs/context.c
+++ b/gjs/context.c
@@ -1116,35 +1116,3 @@ gjs_context_define_string_array(GjsContext  *js_context,
 
     return TRUE;
 }
-
-#if GJS_BUILD_TESTS
-
-void
-gjstest_test_func_gjs_context_construct_destroy(void)
-{
-    GjsContext *context;
-
-    /* Construct twice just to possibly a case where global state from
-     * the first leaks.
-     */
-    context = gjs_context_new ();
-    g_object_unref (context);
-
-    context = gjs_context_new ();
-    g_object_unref (context);
-}
-
-void
-gjstest_test_func_gjs_context_construct_eval(void)
-{
-    GjsContext *context;
-    int estatus;
-    GError *error = NULL;
-
-    context = gjs_context_new ();
-    if (!gjs_context_eval (context, "1+1", -1, "<input>", &estatus, &error))
-        g_error ("%s", error->message);
-    g_object_unref (context);
-}
-
-#endif /* GJS_BUILD_TESTS */
diff --git a/gjs/jsapi-util-array.c b/gjs/jsapi-util-array.c
index a5553a6..5aa357e 100644
--- a/gjs/jsapi-util-array.c
+++ b/gjs/jsapi-util-array.c
@@ -285,47 +285,3 @@ gjs_rooted_array_free(JSContext        *context,
 
     return (jsval*) g_array_free(garray, free_segment);
 }
-
-#if GJS_BUILD_TESTS
-#include "unit-test-utils.h"
-#include <string.h>
-
-#define N_ELEMS 15
-
-void
-gjstest_test_func_gjs_jsapi_util_array(void)
-{
-    GjsUnitTestFixture fixture;
-    JSContext *context;
-    GjsRootedArray *array;
-    int i;
-    jsval value;
-
-    _gjs_unit_test_fixture_begin(&fixture);
-    context = fixture.context;
-
-    array = gjs_rooted_array_new();
-
-    for (i = 0; i < N_ELEMS; i++) {
-        value = STRING_TO_JSVAL(JS_NewStringCopyZ(context, "abcdefghijk"));
-        gjs_rooted_array_append(context, array, value);
-    }
-
-    JS_GC(context);
-
-    for (i = 0; i < N_ELEMS; i++) {
-        char *ascii;
-
-        value = gjs_rooted_array_get(context, array, i);
-        g_assert(JSVAL_IS_STRING(value));
-        gjs_string_to_utf8(context, value, &ascii);
-        g_assert(strcmp(ascii, "abcdefghijk") == 0);
-        g_free(ascii);
-    }
-
-    gjs_rooted_array_free(context, array, TRUE);
-
-    _gjs_unit_test_fixture_finish(&fixture);
-}
-
-#endif /* GJS_BUILD_TESTS */
diff --git a/gjs/jsapi-util-error.c b/gjs/jsapi-util-error.c
index a4b1c61..cb8dc67 100644
--- a/gjs/jsapi-util-error.c
+++ b/gjs/jsapi-util-error.c
@@ -187,70 +187,3 @@ gjs_throw_g_error (JSContext       *context,
 
     JS_EndRequest(context);
 }
-
-#if GJS_BUILD_TESTS
-#include "unit-test-utils.h"
-
-void
-gjstest_test_func_gjs_jsapi_util_error_throw(void)
-{
-    GjsUnitTestFixture fixture;
-    JSContext *context;
-    jsval exc, value, previous;
-    char *s = NULL;
-    int strcmp_result;
-
-    _gjs_unit_test_fixture_begin(&fixture);
-    context = fixture.context;
-
-    /* Test that we can throw */
-
-    gjs_throw(context, "This is an exception %d", 42);
-
-    g_assert(JS_IsExceptionPending(context));
-
-    exc = JSVAL_VOID;
-    JS_GetPendingException(context, &exc);
-    g_assert(!JSVAL_IS_VOID(exc));
-
-    value = JSVAL_VOID;
-    JS_GetProperty(context, JSVAL_TO_OBJECT(exc), "message",
-                   &value);
-
-    g_assert(JSVAL_IS_STRING(value));
-
-    gjs_string_to_utf8(context, value, &s);
-    g_assert(s != NULL);
-    strcmp_result = strcmp(s, "This is an exception 42");
-    free(s);
-    if (strcmp_result != 0)
-        g_error("Exception has wrong message '%s'", s);
-
-    /* keep this around before we clear it */
-    previous = exc;
-    JS_AddValueRoot(context, &previous);
-
-    JS_ClearPendingException(context);
-
-    g_assert(!JS_IsExceptionPending(context));
-
-    /* Check that we don't overwrite a pending exception */
-    JS_SetPendingException(context, previous);
-
-    g_assert(JS_IsExceptionPending(context));
-
-    gjs_throw(context, "Second different exception %s", "foo");
-
-    g_assert(JS_IsExceptionPending(context));
-
-    exc = JSVAL_VOID;
-    JS_GetPendingException(context, &exc);
-    g_assert(!JSVAL_IS_VOID(exc));
-    g_assert(JSVAL_TO_OBJECT(exc) == JSVAL_TO_OBJECT(previous));
-
-    JS_RemoveValueRoot(context, &previous);
-
-    _gjs_unit_test_fixture_finish(&fixture);
-}
-
-#endif /* GJS_BUILD_TESTS */
diff --git a/gjs/jsapi-util-string.c b/gjs/jsapi-util-string.c
index e627da0..d72bf7f 100644
--- a/gjs/jsapi-util-string.c
+++ b/gjs/jsapi-util-string.c
@@ -240,32 +240,3 @@ gjs_unichar_from_string (JSContext *context,
     }
     return FALSE;
 }
-
-#if GJS_BUILD_TESTS
-#include "unit-test-utils.h"
-#include <string.h>
-
-void
-gjstest_test_func_gjs_jsapi_util_string_js_string_utf8(void)
-{
-    GjsUnitTestFixture fixture;
-    JSContext *context;
-    const char *utf8_string = "\303\211\303\226 foobar \343\203\237";
-    char *utf8_result;
-    jsval js_string;
-
-    _gjs_unit_test_fixture_begin(&fixture);
-    context = fixture.context;
-
-    g_assert(gjs_string_from_utf8(context, utf8_string, -1, &js_string) == JS_TRUE);
-    g_assert(JSVAL_IS_STRING(js_string));
-    g_assert(gjs_string_to_utf8(context, js_string, &utf8_result) == JS_TRUE);
-
-    _gjs_unit_test_fixture_finish(&fixture);
-
-    g_assert(g_str_equal(utf8_string, utf8_result));
-
-    g_free(utf8_result);
-}
-
-#endif /* GJS_BUILD_TESTS */
diff --git a/gjs/stack.c b/gjs/stack.c
index 230fb38..54317d6 100644
--- a/gjs/stack.c
+++ b/gjs/stack.c
@@ -245,20 +245,3 @@ gjs_dumpstack(void)
   }
   g_list_free(contexts);
 }
-
-#if GJS_BUILD_TESTS
-void
-gjstest_test_func_gjs_stack_dump(void)
-{
-  GjsContext *context;
-
-  /* TODO this test could be better - maybe expose dumpstack as a JS API
-   * so that we have a JS stack to dump?  At least here we're getting some
-   * coverage.
-   */
-  context = gjs_context_new();
-  gjs_dumpstack();
-  g_object_unref(context);
-  gjs_dumpstack();
-}
-#endif /* GJS_BUILD_TESTS */
diff --git a/test/gjs-tests.c b/test/gjs-tests.c
index ddd5734..b92b33e 100644
--- a/test/gjs-tests.c
+++ b/test/gjs-tests.c
@@ -24,14 +24,250 @@
 #include <config.h>
 #include <glib.h>
 #include <glib-object.h>
+#include <gjs/gjs-module.h>
+#include <util/glib.h>
 #include <util/crash.h>
 
-#include "test.h"
+typedef struct _GjsUnitTestFixture GjsUnitTestFixture;
+
+struct _GjsUnitTestFixture {
+    JSRuntime *runtime;
+    JSContext *context;
+
+    GjsContext *gjs_context;
+};
+
+static void
+test_error_reporter(JSContext     *context,
+                    const char    *message,
+                    JSErrorReport *report)
+{
+    g_printerr("error reported by test: %s\n", message);
+}
+
+static void
+_gjs_unit_test_fixture_begin (GjsUnitTestFixture *fixture)
+{
+    fixture->gjs_context = gjs_context_new ();
+    fixture->context = (JSContext *) gjs_context_get_native_context (fixture->gjs_context);
+    fixture->runtime = JS_GetRuntime(fixture->context);
+    JS_BeginRequest(fixture->context);
+    JS_SetErrorReporter(fixture->context, test_error_reporter);
+}
+
+static void
+_gjs_unit_test_fixture_finish (GjsUnitTestFixture *fixture)
+{
+    JS_EndRequest(fixture->context);
+    g_object_unref(fixture->gjs_context);
+}
+
+static void
+gjstest_test_func_gjs_context_construct_destroy(void)
+{
+    GjsContext *context;
+
+    /* Construct twice just to possibly a case where global state from
+     * the first leaks.
+     */
+    context = gjs_context_new ();
+    g_object_unref (context);
+
+    context = gjs_context_new ();
+    g_object_unref (context);
+}
+
+static void
+gjstest_test_func_gjs_context_construct_eval(void)
+{
+    GjsContext *context;
+    int estatus;
+    GError *error = NULL;
+
+    context = gjs_context_new ();
+    if (!gjs_context_eval (context, "1+1", -1, "<input>", &estatus, &error))
+        g_error ("%s", error->message);
+    g_object_unref (context);
+}
+
+#define N_ELEMS 15
+
+static void
+gjstest_test_func_gjs_jsapi_util_array(void)
+{
+    GjsUnitTestFixture fixture;
+    JSContext *context;
+    GjsRootedArray *array;
+    int i;
+    jsval value;
+
+    _gjs_unit_test_fixture_begin(&fixture);
+    context = fixture.context;
+
+    array = gjs_rooted_array_new();
+
+    for (i = 0; i < N_ELEMS; i++) {
+        value = STRING_TO_JSVAL(JS_NewStringCopyZ(context, "abcdefghijk"));
+        gjs_rooted_array_append(context, array, value);
+    }
+
+    JS_GC(context);
+
+    for (i = 0; i < N_ELEMS; i++) {
+        char *ascii;
+
+        value = gjs_rooted_array_get(context, array, i);
+        g_assert(JSVAL_IS_STRING(value));
+        gjs_string_to_utf8(context, value, &ascii);
+        g_assert(strcmp(ascii, "abcdefghijk") == 0);
+        g_free(ascii);
+    }
+
+    gjs_rooted_array_free(context, array, TRUE);
+
+    _gjs_unit_test_fixture_finish(&fixture);
+}
+
+#undef N_ELEMS
+
+static void
+gjstest_test_func_gjs_jsapi_util_string_js_string_utf8(void)
+{
+    GjsUnitTestFixture fixture;
+    JSContext *context;
+    const char *utf8_string = "\303\211\303\226 foobar \343\203\237";
+    char *utf8_result;
+    jsval js_string;
+
+    _gjs_unit_test_fixture_begin(&fixture);
+    context = fixture.context;
+
+    g_assert(gjs_string_from_utf8(context, utf8_string, -1, &js_string) == JS_TRUE);
+    g_assert(JSVAL_IS_STRING(js_string));
+    g_assert(gjs_string_to_utf8(context, js_string, &utf8_result) == JS_TRUE);
+
+    _gjs_unit_test_fixture_finish(&fixture);
+
+    g_assert(g_str_equal(utf8_string, utf8_result));
+
+    g_free(utf8_result);
+}
+
+static void
+gjstest_test_func_gjs_stack_dump(void)
+{
+  GjsContext *context;
+
+  /* TODO this test could be better - maybe expose dumpstack as a JS API
+   * so that we have a JS stack to dump?  At least here we're getting some
+   * coverage.
+   */
+  context = gjs_context_new();
+  gjs_dumpstack();
+  g_object_unref(context);
+  gjs_dumpstack();
+}
+
+static void
+gjstest_test_func_gjs_jsapi_util_error_throw(void)
+{
+    GjsUnitTestFixture fixture;
+    JSContext *context;
+    jsval exc, value, previous;
+    char *s = NULL;
+    int strcmp_result;
+
+    _gjs_unit_test_fixture_begin(&fixture);
+    context = fixture.context;
+
+    /* Test that we can throw */
+
+    gjs_throw(context, "This is an exception %d", 42);
+
+    g_assert(JS_IsExceptionPending(context));
+
+    exc = JSVAL_VOID;
+    JS_GetPendingException(context, &exc);
+    g_assert(!JSVAL_IS_VOID(exc));
+
+    value = JSVAL_VOID;
+    JS_GetProperty(context, JSVAL_TO_OBJECT(exc), "message",
+                   &value);
+
+    g_assert(JSVAL_IS_STRING(value));
+
+    gjs_string_to_utf8(context, value, &s);
+    g_assert(s != NULL);
+    strcmp_result = strcmp(s, "This is an exception 42");
+    free(s);
+    if (strcmp_result != 0)
+        g_error("Exception has wrong message '%s'", s);
+
+    /* keep this around before we clear it */
+    previous = exc;
+    JS_AddValueRoot(context, &previous);
+
+    JS_ClearPendingException(context);
+
+    g_assert(!JS_IsExceptionPending(context));
+
+    /* Check that we don't overwrite a pending exception */
+    JS_SetPendingException(context, previous);
+
+    g_assert(JS_IsExceptionPending(context));
+
+    gjs_throw(context, "Second different exception %s", "foo");
+
+    g_assert(JS_IsExceptionPending(context));
+
+    exc = JSVAL_VOID;
+    JS_GetPendingException(context, &exc);
+    g_assert(!JSVAL_IS_VOID(exc));
+    g_assert(JSVAL_TO_OBJECT(exc) == JSVAL_TO_OBJECT(previous));
+
+    JS_RemoveValueRoot(context, &previous);
+
+    _gjs_unit_test_fixture_finish(&fixture);
+}
+
+static void
+gjstest_test_func_util_glib_strv_concat_null(void)
+{
+    char **ret;
+
+    ret = gjs_g_strv_concat(NULL, 0);
+    g_assert(ret != NULL);
+    g_assert(ret[0] == NULL);
+
+    g_strfreev(ret);
+}
+
+static void
+gjstest_test_func_util_glib_strv_concat_pointers(void)
+{
+    char  *strv0[2] = {"foo", NULL};
+    char  *strv1[1] = {NULL};
+    char **strv2    = NULL;
+    char  *strv3[2] = {"bar", NULL};
+    char **stuff[4];
+    char **ret;
+
+    stuff[0] = strv0;
+    stuff[1] = strv1;
+    stuff[2] = strv2;
+    stuff[3] = strv3;
+
+    ret = gjs_g_strv_concat(stuff, 4);
+    g_assert(ret != NULL);
+    g_assert_cmpstr(ret[0], ==, strv0[0]);  /* same string */
+    g_assert(ret[0] != strv0[0]);           /* different pointer */
+    g_assert_cmpstr(ret[1], ==, strv3[0]);
+    g_assert(ret[1] != strv3[0]);
+    g_assert(ret[2] == NULL);
+
+    g_strfreev(ret);
+}
 
-/* we redefine main in test.h so we can include files with tests that have a main();
- * here we actually want main, so we have to kill that off
- */
-#undef main
 int
 main(int    argc,
      char **argv)
@@ -40,7 +276,14 @@ main(int    argc,
 
     g_test_init(&argc, &argv, NULL);
 
-    gjstest_add_all_tests();
+    g_test_add_func("/gjs/context/construct/destroy", gjstest_test_func_gjs_context_construct_destroy);
+    g_test_add_func("/gjs/context/construct/eval", gjstest_test_func_gjs_context_construct_eval);
+    g_test_add_func("/gjs/jsapi/util/array", gjstest_test_func_gjs_jsapi_util_array);
+    g_test_add_func("/gjs/jsapi/util/error/throw", gjstest_test_func_gjs_jsapi_util_error_throw);
+    g_test_add_func("/gjs/jsapi/util/string/js/string/utf8", gjstest_test_func_gjs_jsapi_util_string_js_string_utf8);
+    g_test_add_func("/gjs/stack/dump", gjstest_test_func_gjs_stack_dump);
+    g_test_add_func("/util/glib/strv/concat/null", gjstest_test_func_util_glib_strv_concat_null);
+    g_test_add_func("/util/glib/strv/concat/pointers", gjstest_test_func_util_glib_strv_concat_pointers);
 
     g_test_run();
 
diff --git a/util/glib.c b/util/glib.c
index b79e75f..3e4452d 100644
--- a/util/glib.c
+++ b/util/glib.c
@@ -166,45 +166,3 @@ _gjs_g_utf8_make_valid (const gchar *name)
 
   return g_string_free (string, FALSE);
 }
-
-#if GJS_BUILD_TESTS
-
-void
-gjstest_test_func_util_glib_strv_concat_null(void)
-{
-    char **ret;
-
-    ret = gjs_g_strv_concat(NULL, 0);
-    g_assert(ret != NULL);
-    g_assert(ret[0] == NULL);
-
-    g_strfreev(ret);
-}
-
-void
-gjstest_test_func_util_glib_strv_concat_pointers(void)
-{
-    char  *strv0[2] = {"foo", NULL};
-    char  *strv1[1] = {NULL};
-    char **strv2    = NULL;
-    char  *strv3[2] = {"bar", NULL};
-    char **stuff[4];
-    char **ret;
-
-    stuff[0] = strv0;
-    stuff[1] = strv1;
-    stuff[2] = strv2;
-    stuff[3] = strv3;
-
-    ret = gjs_g_strv_concat(stuff, 4);
-    g_assert(ret != NULL);
-    g_assert_cmpstr(ret[0], ==, strv0[0]);  /* same string */
-    g_assert(ret[0] != strv0[0]);           /* different pointer */
-    g_assert_cmpstr(ret[1], ==, strv3[0]);
-    g_assert(ret[1] != strv3[0]);
-    g_assert(ret[2] == NULL);
-
-    g_strfreev(ret);
-}
-
-#endif /* GJS_BUILD_TESTS */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]