[glib] Add g_test_build_filename()



commit 0c4806733cb30f56325b0f1c4e95a400e4998c14
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue May 28 12:44:41 2013 -0400

    Add g_test_build_filename()
    
    This function allows testcases to find data files in various situations
    of srcdir == builddir, srcdir != builddir and for installed tests.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=549783

 Makefile.decl                         |    6 +-
 docs/reference/glib/glib-sections.txt |    3 +
 glib/gtestutils.c                     |   98 +++++++++++++++++++++++++++++++++
 glib/gtestutils.h                     |   11 ++++
 4 files changed, 115 insertions(+), 3 deletions(-)
---
diff --git a/Makefile.decl b/Makefile.decl
index 50cf169..067e7e5 100644
--- a/Makefile.decl
+++ b/Makefile.decl
@@ -20,7 +20,7 @@ if OS_UNIX
 
 # test-nonrecursive: run tests only in cwd
 test-nonrecursive: ${TEST_PROGS}
-       @test -z "${TEST_PROGS}" || G_DEBUG=gc-friendly MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 
256)) ${GTESTER} --verbose ${TEST_PROGS}
+       @test -z "${TEST_PROGS}" || G_TEST_SRCDIR="$(abs_srcdir)" G_TEST_BUILDDIR="$(abs_builddir)" 
G_DEBUG=gc-friendly MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${GTESTER} --verbose 
${TEST_PROGS}
 else
 test-nonrecursive:
 endif
@@ -36,9 +36,9 @@ test-report perf-report full-report:  ${TEST_PROGS}
          full-report) test_options="-k -m=perf -m=slow";; \
          esac ; \
          if test -z "$$GTESTER_LOGDIR" ; then  \
-           ${GTESTER} --verbose $$test_options -o test-report.xml ${TEST_PROGS} ; \
+           G_TEST_SRCDIR="$(abs_srcdir)" G_TEST_BUILDDIR="$(abs_builddir)" ${GTESTER} --verbose 
$$test_options -o test-report.xml ${TEST_PROGS} ; \
          elif test -n "${TEST_PROGS}" ; then \
-           ${GTESTER} --verbose $$test_options -o `mktemp "$$GTESTER_LOGDIR/log-XXXXXX"` ${TEST_PROGS} ; \
+           G_TEST_SRCDIR="$(abs_srcdir)" G_TEST_BUILDDIR="$(abs_builddir)" ${GTESTER} --verbose 
$$test_options -o `mktemp "$$GTESTER_LOGDIR/log-XXXXXX"` ${TEST_PROGS} ; \
          fi ; \
        }
        @ ignore_logdir=true ; \
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 8c42bce..298fdef 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2916,6 +2916,9 @@ g_test_add_data_func
 g_test_add_data_func_full
 g_test_add
 
+GTestFileType
+g_test_build_filename
+
 g_test_fail
 g_test_message
 g_test_bug_base
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
index c57b3d9..4841178 100644
--- a/glib/gtestutils.c
+++ b/glib/gtestutils.c
@@ -562,6 +562,9 @@ static char       *test_uri_base = NULL;
 static gboolean    test_debug_log = FALSE;
 static DestroyEntry *test_destroy_queue = NULL;
 static char       *test_argv0 = NULL;
+static char       *test_argv0_dirname;
+static const char *test_disted_files_dir;
+static const char *test_built_files_dir;
 static char       *test_initial_cwd = NULL;
 static gboolean    test_in_subprocess = FALSE;
 static GTestConfig mutable_test_config_vars = {
@@ -1034,6 +1037,25 @@ g_test_init (int    *argc,
   /* report program start */
   g_log_set_default_handler (gtest_default_log_handler, NULL);
   g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL);
+
+  test_argv0_dirname = g_path_get_dirname (test_argv0);
+
+  /* Make sure we get the real dirname that the test was run from */
+  if (g_str_has_suffix (test_argv0_dirname, "/.libs"))
+    {
+      gchar *tmp;
+      tmp = g_path_get_dirname (test_argv0_dirname);
+      g_free (test_argv0_dirname);
+      test_argv0_dirname = tmp;
+    }
+
+  test_disted_files_dir = g_getenv ("G_TEST_SRCDIR");
+  if (!test_disted_files_dir)
+    test_disted_files_dir = test_argv0_dirname;
+
+  test_built_files_dir = g_getenv ("G_TEST_BUILDDIR");
+  if (!test_built_files_dir)
+    test_built_files_dir = test_argv0_dirname;
 }
 
 static void
@@ -2881,6 +2903,82 @@ g_test_log_msg_free (GTestLogMsg *tmsg)
   g_free (tmsg);
 }
 
+/**
+ * g_test_build_filename:
+ * @file_type: the type of file (built vs. disted)
+ * @first_path: the first segment of the pathname
+ * ...: NULL terminated additional path segments
+ *
+ * Creates the pathname to a data file that is required for a test.
+ *
+ * This function is conceptually similar to g_build_filename() except
+ * that the first argument has been replaced with a #GTestFileType
+ * argument.
+ *
+ * The data file should either have been disted with the module
+ * containing the test (%G_TEST_DISTED) or built as part of the build
+ * system of that module (%G_TEST_BUILT).
+ *
+ * In order for this function to work in srcdir != builddir situations,
+ * the G_TEST_SRCDIR and G_TEST_BUILDDIR environment variables need to
+ * have been defined.  As of 2.38, this is done by the Makefile.decl
+ * included in GLib.  Please ensure that your copy is up to date before
+ * using this function.
+ *
+ * In case neither variable is set, this function will fall back to
+ * using the dirname portion of argv[0], possibly removing ".libs".
+ * This allows for casual running of tests directly from the commandline
+ * in the srcdir == builddir case and should also support running of
+ * installed tests, assuming the data files have been installed in the
+ * same relative path as the test binary.
+ *
+ * Returns: the path of the file, to be freed using g_free()
+ *
+ * Since: 2.38
+ **/
+/**
+ * GTestFileType:
+ * @G_TEST_DISTED: a file that was included in the distribution tarball
+ * @G_TEST_BUILT: a file that was built on the compiling machine
+ *
+ * The type of file to return the filename for, when used with
+ * g_test_build_filename().
+ *
+ * Since: 2.38
+ **/
+gchar *
+g_test_build_filename (GTestFileType  file_type,
+                       const gchar   *first_path,
+                       ...)
+{
+  const gchar *pathv[16];
+  gint num_path_segments;
+  va_list ap;
+
+  g_assert (g_test_initialized ());
+
+  if (file_type == G_TEST_DISTED)
+    pathv[0] = test_disted_files_dir;
+  else if (file_type == G_TEST_BUILT)
+    pathv[0] = test_built_files_dir;
+  else
+    g_assert_not_reached ();
+
+  pathv[1] = first_path;
+
+  va_start (ap, first_path);
+  for (num_path_segments = 2; num_path_segments < G_N_ELEMENTS (pathv); num_path_segments++)
+    {
+      pathv[num_path_segments] = va_arg (ap, const char *);
+      if (pathv[num_path_segments] == NULL)
+        break;
+    }
+
+  g_assert_cmpint (num_path_segments, <, G_N_ELEMENTS (pathv));
+
+  return g_build_filenamev ((gchar **) pathv);
+}
+
 /* --- macros docs START --- */
 /**
  * g_test_add:
diff --git a/glib/gtestutils.h b/glib/gtestutils.h
index 0051c41..47ee450 100644
--- a/glib/gtestutils.h
+++ b/glib/gtestutils.h
@@ -372,6 +372,17 @@ void    g_test_assert_expected_messages_internal (const char     *domain,
                                                   int             line,
                                                   const char     *func);
 
+typedef enum
+{
+  G_TEST_DISTED,
+  G_TEST_BUILT
+} GTestFileType;
+
+GLIB_AVAILABLE_IN_2_38
+gchar * g_test_build_filename                    (GTestFileType   file_type,
+                                                  const gchar    *first_path,
+                                                  ...) G_GNUC_NULL_TERMINATED;
+
 #define g_test_assert_expected_messages() g_test_assert_expected_messages_internal (G_LOG_DOMAIN, __FILE__, 
__LINE__, G_STRFUNC)
 
 G_END_DECLS


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