[the-board/unit-tests] Initial bits for unit tests
- From: Lucas Rocha <lucasr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [the-board/unit-tests] Initial bits for unit tests
- Date: Tue, 8 Feb 2011 17:59:20 +0000 (UTC)
commit 6800e81293919d68365c0fddfebe2f20a2d13831
Author: Lucas Rocha <lucasr gnome org>
Date: Tue Feb 8 17:58:37 2011 +0000
Initial bits for unit tests
Makefile.am | 2 +-
configure.ac | 4 +
test/Makefile.am | 78 ++++++++++++++++++++++
test/js/testMathUtil.js | 12 ++++
test/tb-js-unit.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 260 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 975ac3b..6241857 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-SUBDIRS = data po src
+SUBDIRS = data po src test
EXTRA_DIST = \
autogen.sh
diff --git a/configure.ac b/configure.ac
index f4322db..2a9c609 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,6 +44,9 @@ AC_PROG_LIBTOOL
## don't rerun to this point if we abort
AC_CACHE_SAVE
+GJS_JS_DIR=`$PKG_CONFIG --variable=datadir gjs-1.0`/gjs-1.0
+AC_SUBST(GJS_JS_DIR)
+
CLUTTER_MIN_VERSION=1.6.0
GLIB_MIN_VERSION=2.27.3
GTK_MIN_VERSION=2.91.7
@@ -153,6 +156,7 @@ data/icons/Makefile
data/style/Makefile
data/things/Makefile
po/Makefile.in
+test/Makefile
])
AC_OUTPUT
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..52acdf9
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,78 @@
+GTESTER = $(TESTS_ENVIRONMENT) gtester
+GTESTER_REPORT = gtester-report
+TEST_PROGS_OPTIONS ?= --keep-going
+
+TEST_PROGS = tb-js-unit
+bin_PROGRAMS = tb-js-unit
+
+tb_js_unit_CPPFLAGS = \
+ -DGJS_JS_DIR=\"$(GJS_JS_DIR)\" \
+ $(AM_CPPFLAGS) \
+ $(THE_BOARD_CFLAGS)
+
+tb_js_unit_LDADD = \
+ $(THE_BOARD_LIBS)
+
+## -rdynamic makes backtraces work
+## we -export-dynamic so we can dlopen ourselves and use gobject-introspection
+tb_js_unit_LDFLAGS=-export-dynamic -rdynamic
+tb_js_unit_SOURCES = tb-js-unit.c
+
+THE_BOARD_GJS_PATH = $(abs_top_builddir)/.libs:$(abs_top_srcdir)/src/js
+
+# Default log output, overrideable from environment, thanks to
+# conditional assignment operator '?=' .
+THE_BOARD_TEST_LOGS_OUTPUT ?= $(builddir)/test_user_data/logs/the-board-%u.log
+
+TESTS_ENVIRONMENT = \
+ DISPLAY='' \
+ XDG_DATA_HOME=$(abs_top_builddir)/test_user_data \
+ GJS_DEBUG_OUTPUT=$(THE_BOARD_TEST_LOGS_OUTPUT) \
+ GI_TYPELIB_PATH=$(abs_top_builddir)/src \
+ JS_TEST_DIR=$(abs_top_builddir)/test/js \
+ GJS_PATH=$(THE_BOARD_GJS_PATH)
+
+### gtester testing rules
+
+# run one test only, e.g. test-/js/Array
+test-/%:
+ make test TEST_PROGS_OPTIONS="-p $(@:test-%=%)"
+
+# test: run all tests in cwd
+test: ${TEST_PROGS}
+ @rm -rf test_user_data
+ @mkdir -p test_user_data
+ @test -z "${TEST_PROGS}" || ${GTESTER} --verbose ${TEST_PROGS} ${TEST_PROGS_OPTIONS}
+
+# test-report: run tests in cwd and generate report
+# perf-report: run tests in cwd with -m perf and generate report
+# full-report: like test-report: with -m perf and -m slow
+test-report perf-report full-report: ${TEST_PROGS}
+ @test -z "${TEST_PROGS}" || { \
+ case $@ in \
+ test-report) test_options="-k";; \
+ perf-report) test_options="-k -m=perf";; \
+ full-report) test_options="-k -m=perf -m=slow";; \
+ esac ; \
+ ${GTESTER} --verbose $$test_options -o $ xml ${TEST_PROGS} ${TEST_PROGS_OPTIONS}; \
+ }
+ @${GTESTER_REPORT} --version 2>/dev/null 1>&2 ; test "$$?" != 0 || ${GTESTER_REPORT} $ xml >$ html
+
+test-console:
+ @$(TESTS_ENVIRONMENT) rlwrap gjs-console
+
+CLEANFILES = \
+ unittestdb # Remove this when the tests remove the dbs themselves
+
+.PHONY: test test-report perf-report full-report test-coverage
+
+# run make test as part of make check
+check-local: test
+
+clean-local:
+ -rm -rf test-coverage
+ -rm -f *.gcda *.gcno
+ -rm -rf test_user_data
+
+#noinst_jsdirs = \
+# js
diff --git a/test/js/testMathUtil.js b/test/js/testMathUtil.js
new file mode 100644
index 0000000..4dcc843
--- /dev/null
+++ b/test/js/testMathUtil.js
@@ -0,0 +1,12 @@
+const MathUtil = imports.util.mathUtil;
+
+function testClamp() {
+ assertEquals(5, MathUtil.clamp(7, 0, 5));
+ assertEquals(0, MathUtil.clamp(-3, 0, 5));
+ assertEquals(3, MathUtil.clamp(3, 0, 5));
+ assertEquals(1, MathUtil.clamp(1, 1, 1));
+
+ assertRaises('min greater than max', function() { MathUtil.clamp(0, 5, 0); });
+}
+
+gjstestRun();
diff --git a/test/tb-js-unit.c b/test/tb-js-unit.c
new file mode 100644
index 0000000..580c454
--- /dev/null
+++ b/test/tb-js-unit.c
@@ -0,0 +1,165 @@
+/* Copyright 2008 litl, LLC. All Rights Reserved. */
+
+#include <config.h>
+
+#include <glib.h>
+#include <gjs/gjs.h>
+
+#include <string.h>
+
+typedef struct {
+ GjsContext *context;
+} TbTestJSFixture;
+
+static const char *js_test_dir;
+
+static void
+setup (TbTestJSFixture *fix,
+ gconstpointer test_data)
+{
+ GError *error = NULL;
+ gboolean success;
+ int code;
+
+ g_debug ("------------------------------");
+ g_debug ("setup gjs test file: %s", (const char*) test_data);
+
+ fix->context = gjs_context_new ();
+
+ /* Load jsUnit.js directly into global scope, rather than
+ * requiring each test to import it as a module, among other
+ * things this lets us test importing modules without relying on
+ * importing a module, but also it's just less typing to have
+ * "assert*" without a prefix.
+ */
+ success = gjs_context_eval_file (fix->context, GJS_JS_DIR"/jsUnit.js", &code, &error);
+
+ if (!success)
+ g_error("%s", error->message);
+}
+
+static void
+teardown (TbTestJSFixture *fix,
+ gconstpointer test_data)
+{
+ g_debug ("teardown gjs test file: %s", (const char*) test_data);
+
+ gjs_memory_report ("before destroying context", FALSE);
+ g_object_unref (fix->context);
+
+ gjs_memory_report ("after destroying context", TRUE);
+}
+
+static void
+test (TbTestJSFixture *fix,
+ gconstpointer test_data)
+{
+ char *test_script;
+ GError *error = NULL;
+ gboolean success;
+ int code;
+
+ g_debug ("test gjs test file: %s", (const char*) test_data);
+
+ /* verify that last line of test is either 'gjstestRun();' or 'st;'
+ this ensures that we accurately report the results of the test!
+ otherwise gjstestRun() can fail silently, which is Not Good.
+ Use:
+ let st = gjstestRun();
+ // some other stuff
+ st;
+ if you really want to do cleanup after gjstestRun().
+ */
+ if (!g_file_get_contents (test_data, &test_script, NULL, &error))
+ g_error ("Couldn't read test: %s", (const char *) test_data);
+
+ if (!g_regex_match_simple("(gjstestRun\\s*\\(\\s*\\)|st)\\s*;?\\s*"
+ "(/[*][^*]*[*]/\\s*)?$",
+ test_script, 0, 0))
+ g_error("Return value from gjstestRun() may be being ignored! "
+ "The test case should end in 'gjstestRun()' or 'st'.");
+
+ g_free (test_script);
+
+ /* ok, now run the rest. */
+ success = gjs_context_eval_file (fix->context,
+ (const char*) test_data,
+ &code, &error);
+
+ if (!success)
+ g_error ("%s", error->message);
+
+ g_assert (error == NULL);
+ g_assert_cmpint (code, ==, 0);
+}
+
+static gint
+mystrcmp (gconstpointer a, gconstpointer b)
+{
+ // filenames are not UTF8; we compare using native strcmp order, not
+ // any locale-specific foo.
+ return strcmp(*(char**)a, *(char**)b);
+}
+
+int
+main(int argc, char **argv)
+{
+ GDir *dir;
+ const char *name;
+ GPtrArray *tests;
+ unsigned i;
+
+ g_test_init (&argc, &argv, NULL);
+
+ g_type_init ();
+
+ /* iterate through all 'test*.js' files in $JS_TEST_DIR */
+
+ /* accumulate the results and sort them, so that our test runs
+ * are consistent across machines (otherwise every developer will
+ * run tests in a different order, depending on the whims of their
+ * filesystem. */
+ js_test_dir = g_getenv ("JS_TEST_DIR");
+ dir = g_dir_open (js_test_dir, 0, NULL);
+
+ g_assert (dir != NULL);
+
+ tests = g_ptr_array_new();
+
+ while ((name = g_dir_read_name(dir)) != NULL)
+ {
+ if (!(g_str_has_prefix (name, "test") &&
+ g_str_has_suffix (name, ".js")))
+ continue;
+
+ g_ptr_array_add (tests, g_strdup(name));
+ }
+
+ g_dir_close (dir);
+
+ g_ptr_array_sort (tests, mystrcmp);
+
+ for (i = 0; i < tests->len; i++)
+ {
+ char *name = g_ptr_array_index (tests, i);
+ char *test_name;
+ char *file_name;
+
+ /* pretty print, drop 'test' prefix and '.js' suffix from test name */
+ test_name = g_strconcat ("/js/", name + 4, NULL);
+ test_name[strlen (test_name)-3] = '\0';
+
+ file_name = g_build_filename (js_test_dir, name, NULL);
+
+ g_test_add (test_name, TbTestJSFixture, file_name, setup, test, teardown);
+
+ g_free (test_name);
+ g_free (name);
+
+ /* not freeing file_name as it's needed while running the test */
+ }
+
+ g_ptr_array_free (tests, TRUE);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]