[glib: 1/2] Remove old test file tests/testglib.c




commit 16f0438bc645219e0dfd410b72909c1e01c33784
Author: Emmanuel Fleury <emmanuel fleury gmail com>
Date:   Tue Feb 22 18:48:01 2022 +0000

    Remove old test file tests/testglib.c

 glib/tests/fileutils.c |  282 ++++++-
 glib/tests/memchunk.c  |   64 ++
 glib/tests/meson.build |    1 +
 glib/tests/node.c      |   10 +
 glib/tests/timer.c     |   54 +-
 glib/tests/tree.c      |  230 ++++++
 tests/meson.build      |    1 -
 tests/testglib.c       | 1925 ------------------------------------------------
 8 files changed, 638 insertions(+), 1929 deletions(-)
---
diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
index 75cac3839..f0ee25b5d 100644
--- a/glib/tests/fileutils.c
+++ b/glib/tests/fileutils.c
@@ -67,6 +67,219 @@ check_string (gchar *str, const gchar *expected)
   g_free (str);
 }
 
+static void
+test_paths (void)
+{
+  struct
+  {
+    gchar *filename;
+    gchar *dirname;
+  } dirname_checks[] = {
+    { "/", "/" },
+    { "////", "/" },
+    { ".////", "." },
+    { "../", ".." },
+    { "..////", ".." },
+    { "a/b", "a" },
+    { "a/b/", "a/b" },
+    { "c///", "c" },
+#ifdef G_OS_WIN32
+    { "\\", "\\" },
+    { ".\\\\\\\\", "." },
+    { "..\\", ".." },
+    { "..\\\\\\\\", ".." },
+    { "a\\b", "a" },
+    { "a\\b/", "a\\b" },
+    { "a/b\\", "a/b" },
+    { "c\\\\/", "c" },
+    { "//\\", "/" },
+#endif
+#ifdef G_WITH_CYGWIN
+    { "//server/share///x", "//server/share" },
+#endif
+    { ".", "." },
+    { "..", "." },
+    { "", "." },
+  };
+  const guint n_dirname_checks = G_N_ELEMENTS (dirname_checks);
+  struct
+  {
+    gchar *filename;
+    gchar *without_root;
+  } skip_root_checks[] = {
+    { "/", "" },
+    { "//", "" },
+    { "/foo", "foo" },
+    { "//foo", "foo" },
+    { "a/b", NULL },
+#ifdef G_OS_WIN32
+    { "\\", "" },
+    { "\\foo", "foo" },
+    { "\\\\server\\foo", "" },
+    { "\\\\server\\foo\\bar", "bar" },
+    { "a\\b", NULL },
+#endif
+#ifdef G_WITH_CYGWIN
+    { "//server/share///x", "//x" },
+#endif
+    { ".", NULL },
+    { "", NULL },
+  };
+  const guint n_skip_root_checks = G_N_ELEMENTS (skip_root_checks);
+  struct
+  {
+    gchar *cwd;
+    gchar *relative_path;
+    gchar *canonical_path;
+  } canonicalize_filename_checks[] = {
+#ifndef G_OS_WIN32
+    { "/etc", "../usr/share", "/usr/share" },
+    { "/", "/foo/bar", "/foo/bar" },
+    { "/usr/bin", "../../foo/bar", "/foo/bar" },
+    { "/", "../../foo/bar", "/foo/bar" },
+    { "/double//dash", "../../foo/bar", "/foo/bar" },
+    { "/usr/share/foo", ".././././bar", "/usr/share/bar" },
+    { "/foo/bar", "../bar/./.././bar", "/foo/bar" },
+    { "/test///dir", "../../././foo/bar", "/foo/bar" },
+    { "/test///dir", "../../././/foo///bar", "/foo/bar" },
+    { "/etc", "///triple/slash", "/triple/slash" },
+    { "/etc", "//double/slash", "//double/slash" },
+    { "///triple/slash", ".", "/triple/slash" },
+    { "//double/slash", ".", "//double/slash" },
+    { "/cwd/../with/./complexities/", "./hello", "/with/complexities/hello" },
+    { "/", ".dot-dir", "/.dot-dir" },
+    { "/cwd", "..", "/" },
+    { "/etc", "hello/..", "/etc" },
+    { "/etc", "hello/../", "/etc" },
+    { "/", "..", "/" },
+    { "/", "../", "/" },
+    { "/", "/..", "/" },
+    { "/", "/../", "/" },
+    { "/", ".", "/" },
+    { "/", "./", "/" },
+    { "/", "/.", "/" },
+    { "/", "/./", "/" },
+    { "/", "///usr/../usr", "/usr" },
+#else
+    { "/etc", "../usr/share", "\\usr\\share" },
+    { "/", "/foo/bar", "\\foo\\bar" },
+    { "/usr/bin", "../../foo/bar", "\\foo\\bar" },
+    { "/", "../../foo/bar", "\\foo\\bar" },
+    { "/double//dash", "../../foo/bar", "\\foo\\bar" },
+    { "/usr/share/foo", ".././././bar", "\\usr\\share\\bar" },
+    { "/foo/bar", "../bar/./.././bar", "\\foo\\bar" },
+    { "/test///dir", "../../././foo/bar", "\\foo\\bar" },
+    { "/test///dir", "../../././/foo///bar", "\\foo\\bar" },
+    { "/etc", "///triple/slash", "\\triple\\slash" },
+    { "/etc", "//double/slash", "//double/slash" },
+    { "///triple/slash", ".", "\\triple\\slash" },
+    { "//double/slash", ".", "//double/slash\\" },
+    { "/cwd/../with/./complexities/", "./hello", "\\with\\complexities\\hello" },
+    { "/", ".dot-dir", "\\.dot-dir" },
+    { "/cwd", "..", "\\" },
+    { "/etc", "hello/..", "\\etc" },
+    { "/etc", "hello/../", "\\etc" },
+    { "/", "..", "\\" },
+    { "/", "../", "\\" },
+    { "/", "/..", "\\" },
+    { "/", "/../", "\\" },
+    { "/", ".", "\\" },
+    { "/", "./", "\\" },
+    { "/", "/.", "\\" },
+    { "/", "/./", "\\" },
+    { "/", "///usr/../usr", "\\usr" },
+
+    { "\\etc", "..\\usr\\share", "\\usr\\share" },
+    { "\\", "\\foo\\bar", "\\foo\\bar" },
+    { "\\usr\\bin", "..\\..\\foo\\bar", "\\foo\\bar" },
+    { "\\", "..\\..\\foo\\bar", "\\foo\\bar" },
+    { "\\double\\\\dash", "..\\..\\foo\\bar", "\\foo\\bar" },
+    { "\\usr\\share\\foo", "..\\.\\.\\.\\bar", "\\usr\\share\\bar" },
+    { "\\foo\\bar", "..\\bar\\.\\..\\.\\bar", "\\foo\\bar" },
+    { "\\test\\\\\\dir", "..\\..\\.\\.\\foo\\bar", "\\foo\\bar" },
+    { "\\test\\\\\\dir", "..\\..\\.\\.\\\\foo\\\\\\bar", "\\foo\\bar" },
+    { "\\etc", "\\\\\\triple\\slash", "\\triple\\slash" },
+    { "\\etc", "\\\\double\\slash", "\\\\double\\slash" },
+    { "\\\\\\triple\\slash", ".", "\\triple\\slash" },
+    { "\\\\double\\slash", ".", "\\\\double\\slash\\" },
+    { "\\cwd\\..\\with\\.\\complexities\\", ".\\hello", "\\with\\complexities\\hello" },
+    { "\\", ".dot-dir", "\\.dot-dir" },
+    { "\\cwd", "..", "\\" },
+    { "\\etc", "hello\\..", "\\etc" },
+    { "\\etc", "hello\\..\\", "\\etc" },
+    { "\\", "..", "\\" },
+    { "\\", "..\\", "\\" },
+    { "\\", "\\..", "\\" },
+    { "\\", "\\..\\", "\\" },
+    { "\\", ".", "\\" },
+    { "\\", ".\\", "\\" },
+    { "\\", "\\.", "\\" },
+    { "\\", "\\.\\", "\\" },
+    { "\\", "\\\\\\usr\\..\\usr", "\\usr" },
+#endif
+  };
+  const guint n_canonicalize_filename_checks = G_N_ELEMENTS (canonicalize_filename_checks);
+  gchar *string;
+  guint i;
+
+  string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "dir" G_DIR_SEPARATOR_S);
+  g_assert_cmpstr (string, ==, "dir");
+  g_free (string);
+  string = g_path_get_basename (G_DIR_SEPARATOR_S "foo" G_DIR_SEPARATOR_S "file");
+  g_assert_cmpstr (string, ==, "file");
+  g_free (string);
+
+#ifdef G_OS_WIN32
+  string = g_path_get_basename ("/foo/dir/");
+  g_assert_cmpstr (string, ==, "dir");
+  g_free (string);
+  string = g_path_get_basename ("/foo/file");
+  g_assert_cmpstr (string, ==, "file");
+  g_free (string);
+#endif
+
+  for (i = 0; i < n_dirname_checks; i++)
+    {
+      gchar *dirname = g_path_get_dirname (dirname_checks[i].filename);
+      g_assert_cmpstr (dirname, ==, dirname_checks[i].dirname);
+      g_free (dirname);
+    }
+
+  for (i = 0; i < n_skip_root_checks; i++)
+    {
+      const gchar *skipped = g_path_skip_root (skip_root_checks[i].filename);
+      if ((skipped && !skip_root_checks[i].without_root) ||
+          (!skipped && skip_root_checks[i].without_root) ||
+          ((skipped && skip_root_checks[i].without_root) &&
+           strcmp (skipped, skip_root_checks[i].without_root)))
+        {
+          g_error ("failed for \"%s\"==\"%s\" (returned: \"%s\")",
+                   skip_root_checks[i].filename,
+                   (skip_root_checks[i].without_root ? skip_root_checks[i].without_root : "<NULL>"),
+                   (skipped ? skipped : "<NULL>"));
+        }
+    }
+
+  for (i = 0; i < n_canonicalize_filename_checks; i++)
+    {
+      gchar *canonical_path =
+          g_canonicalize_filename (canonicalize_filename_checks[i].relative_path,
+                                   canonicalize_filename_checks[i].cwd);
+      g_assert_cmpstr (canonical_path, ==,
+                       canonicalize_filename_checks[i].canonical_path);
+      g_free (canonical_path);
+    }
+
+  {
+    const gchar *relative_path = "./";
+    gchar *canonical_path = g_canonicalize_filename (relative_path, NULL);
+    gchar *cwd = g_get_current_dir ();
+    g_assert_cmpstr (canonical_path, ==, cwd);
+    g_free (cwd);
+    g_free (canonical_path);
+  }
+}
+
 static void
 test_build_path (void)
 {
@@ -510,14 +723,14 @@ test_mkdir_with_parents_1 (const gchar *base)
 static void
 test_mkdir_with_parents (void)
 {
-  gchar *cwd;
+  gchar *cwd, *new_path;
   if (g_test_verbose())
     g_printerr ("checking g_mkdir_with_parents() in subdir ./hum/");
   test_mkdir_with_parents_1 ("hum");
   g_remove ("hum");
   if (g_test_verbose())
     g_printerr ("checking g_mkdir_with_parents() in subdir ./hii///haa/hee/");
-  test_mkdir_with_parents_1 ("hii///haa/hee");
+  test_mkdir_with_parents_1 ("./hii///haa/hee///");
   g_remove ("hii/haa/hee");
   g_remove ("hii/haa");
   g_remove ("hii");
@@ -525,8 +738,24 @@ test_mkdir_with_parents (void)
   if (g_test_verbose())
     g_printerr ("checking g_mkdir_with_parents() in cwd: %s", cwd);
   test_mkdir_with_parents_1 (cwd);
+
+  new_path = g_build_filename (cwd, "new", NULL);
+  g_assert_cmpint (g_mkdir_with_parents (new_path, 0), ==, 0);
+  g_assert_cmpint (g_rmdir (new_path), ==, 0);
+  g_free (new_path);
   g_free (cwd);
 
+  g_assert_cmpint (g_mkdir_with_parents ("./test", 0), ==, 0);
+  g_assert_cmpint (g_mkdir_with_parents ("./test", 0), ==, 0);
+  g_remove ("./test");
+
+#ifdef G_OS_WIN32
+  g_assert_cmpint (g_mkdir_with_parents ("\\Windows\\b\\c", 0), ==, -1);
+#else
+  g_assert_cmpint (g_mkdir_with_parents ("/usr/b/c", 0), ==, -1);
+  g_assert_cmpint (errno, ==, EACCES);
+#endif
+
   g_assert_cmpint (g_mkdir_with_parents (NULL, 0), ==, -1);
   g_assert_cmpint (errno, ==, EINVAL);
 }
@@ -992,6 +1221,41 @@ test_file_open_tmp (void)
   g_assert_null (name);
   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
   g_clear_error (&error);
+
+  error = NULL;
+  name = NULL;
+  fd = g_file_open_tmp ("zap" G_DIR_SEPARATOR_S "barXXXXXX", &name, &error);
+  g_assert_cmpint (fd, ==, -1);
+
+  g_clear_error (&error);
+  g_free (name);
+
+#ifdef G_OS_WIN32
+  name = NULL;
+  fd = g_file_open_tmp ("zap/barXXXXXX", &name, &error);
+  g_assert_cmpint (fd, ==, -1);
+
+  g_clear_error (&error);
+  g_free (name);
+#endif
+
+  name = NULL;
+  fd = g_file_open_tmp ("zapXXXXXX", &name, &error);
+  g_assert_cmpint (fd, !=, -1);
+
+  close (fd);
+  g_clear_error (&error);
+  remove (name);
+  g_free (name);
+
+  name = NULL;
+  fd = g_file_open_tmp (NULL, &name, &error);
+  g_assert_cmpint (fd, !=, -1);
+
+  close (fd);
+  g_clear_error (&error);
+  remove (name);
+  g_free (name);
 }
 
 static void
@@ -1005,6 +1269,19 @@ test_mkstemp (void)
   const char hello[] = "Hello, World";
   const gsize hellolen = sizeof (hello) - 1;
 
+  if (g_test_undefined ())
+    {
+      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                             "*assertion*!= NULL*");
+      g_assert_cmpint (g_mkstemp (NULL), ==, -1);
+      g_test_assert_expected_messages ();
+    }
+
+  /* Expect to fail if no 'XXXXXX' is given */
+  name = g_strdup ("test");
+  g_assert_cmpint (g_mkstemp (name), ==, -1);
+  g_free (name);
+
   /* Test normal case */
   name = g_strdup ("testXXXXXXtest"),
   fd = g_mkstemp (name);
@@ -2145,6 +2422,7 @@ main (int   argc,
   g_test_add_func ("/fileutils/stdio-win32-pathstrip", test_win32_pathstrip);
   g_test_add_func ("/fileutils/stdio-win32-zero-terminate-symlink", test_win32_zero_terminate_symlink);
 #endif
+  g_test_add_func ("/fileutils/paths", test_paths);
   g_test_add_func ("/fileutils/build-path", test_build_path);
   g_test_add_func ("/fileutils/build-pathv", test_build_pathv);
   g_test_add_func ("/fileutils/build-filename", test_build_filename);
diff --git a/glib/tests/memchunk.c b/glib/tests/memchunk.c
new file mode 100644
index 000000000..8c13787f2
--- /dev/null
+++ b/glib/tests/memchunk.c
@@ -0,0 +1,64 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/* We are testing some deprecated APIs here */
+#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+#endif
+
+#include <glib.h>
+
+static void
+test_basic (void)
+{
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+  GMemChunk *mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
+  gchar *mem[10000];
+  guint i;
+  for (i = 0; i < 10000; i++)
+    {
+      guint j;
+      mem[i] = g_chunk_new (gchar, mem_chunk);
+      for (j = 0; j < 50; j++)
+       mem[i][j] = i * j;
+    }
+  for (i = 0; i < 10000; i++)
+    g_mem_chunk_free (mem_chunk, mem[i]);
+
+  g_mem_chunk_destroy (mem_chunk);
+
+  G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/memchunk/basic", test_basic);
+
+  return g_test_run ();
+}
diff --git a/glib/tests/meson.build b/glib/tests/meson.build
index 869d5819b..9150f3f44 100644
--- a/glib/tests/meson.build
+++ b/glib/tests/meson.build
@@ -51,6 +51,7 @@ glib_tests = {
   'markup-collect' : {},
   'markup-escape' : {},
   'markup-subparser' : {},
+  'memchunk' : {},
   'mem-overflow' : {
     'link_args' : cc.get_id() == 'gcc' and cc.version().version_compare('> 6')
       ? ['-Wno-alloc-size-larger-than'] : [],
diff --git a/glib/tests/node.c b/glib/tests/node.c
index 69db71d4b..e75821cee 100644
--- a/glib/tests/node.c
+++ b/glib/tests/node.c
@@ -232,6 +232,16 @@ traversal_test (void)
   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data);
   g_assert_cmpstr (data.s->str, ==, "ABFEDCGLMKJIH");
 
+  g_string_set_size (data.s, 0);
+  data.count = -1;
+  g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &data);
+  g_assert_cmpstr (data.s->str, ==, "ELMCKJIH");
+
+  g_string_set_size (data.s, 0);
+  data.count = -1;
+  g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &data);
+  g_assert_cmpstr (data.s->str, ==, "ABDFG");
+
   g_node_destroy (root);
   g_string_free (data.s, TRUE);
 }
diff --git a/glib/tests/timer.c b/glib/tests/timer.c
index e805ef581..102406ef3 100644
--- a/glib/tests/timer.c
+++ b/glib/tests/timer.c
@@ -35,6 +35,24 @@ test_timer_basic (void)
 
   timer = g_timer_new ();
 
+  g_timer_start (timer);
+  elapsed = g_timer_elapsed (timer, NULL);
+  g_timer_stop (timer);
+  g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL));
+
+  g_timer_destroy (timer);
+
+  timer = g_timer_new ();
+
+  g_timer_start (timer);
+  elapsed = g_timer_elapsed (timer, NULL);
+  g_timer_stop (timer);
+  g_assert_cmpfloat (elapsed, <=, g_timer_elapsed (timer, NULL));
+
+  g_timer_destroy (timer);
+
+  timer = g_timer_new ();
+
   elapsed = g_timer_elapsed (timer, &micros);
 
   g_assert_cmpfloat (elapsed, <, 1.0);
@@ -69,6 +87,19 @@ test_timer_continue (void)
   gdouble elapsed, elapsed2;
 
   timer = g_timer_new ();
+
+  /* Continue on a running timer */
+  if (g_test_undefined ())
+    {
+      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                             "*assertion*== FALSE*");
+      g_timer_continue (timer);
+      g_test_assert_expected_messages ();
+    }
+
+  g_timer_reset (timer);
+
+  /* Continue on a stopped timer */
   g_usleep (100);
   g_timer_stop (timer);
 
@@ -164,16 +195,27 @@ test_timeval_from_iso8601 (void)
     { TRUE, "1970-01-01T00:00:17.1234Z", { 17, 123400 } },
     { TRUE, "1970-01-01T00:00:17.123456Z", { 17, 123456 } },
     { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } },
+    { TRUE, "1980-02-22T10:36:00Z", { 320063760, 0 } },
+    { TRUE, "1980-02-22T10:36:00", { 320063760, 0 } },
+    { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } },
+    { TRUE, "19800222T053600-0500", { 320063760, 0 } },
+    { TRUE, "1980-02-22T07:06:00-03:30", { 320063760, 0 } },
+    { TRUE, "1980-02-22T10:36:00.050000Z", { 320063760, 50000 } },
+    { TRUE, "1980-02-22T05:36:00,05-05:00", { 320063760, 50000 } },
+    { TRUE, "19800222T123600.050000000+0200", { 320063760, 50000 } },
+    { TRUE, "19800222T070600,0500-0330", { 320063760, 50000 } },
     { FALSE, "   ", { 0, 0 } },
     { FALSE, "x", { 0, 0 } },
     { FALSE, "123x", { 0, 0 } },
     { FALSE, "2001-10+x", { 0, 0 } },
+    { FALSE, "1980-02-22", { 0, 0 } },
     { FALSE, "1980-02-22T", { 0, 0 } },
     { FALSE, "2001-10-08Tx", { 0, 0 } },
     { FALSE, "2001-10-08T10:11x", { 0, 0 } },
     { FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } },
     { FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } },
     { FALSE, "2T0+819855292164632335", { 0, 0 } },
+    { FALSE, "1980-02-22", { 320063760, 50000 } },
     { TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } },
     { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } },
     { FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } },
@@ -222,7 +264,7 @@ test_timeval_from_iso8601 (void)
       out.tv_sec = 0;
       out.tv_usec = 0;
       success = g_time_val_from_iso8601 (tests[i].in, &out);
-      g_assert (success == tests[i].success);
+      g_assert_cmpint (success, ==, tests[i].success);
       if (tests[i].success)
         {
           g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec);
@@ -230,10 +272,20 @@ test_timeval_from_iso8601 (void)
         }
     }
 
+  /* revert back user defined time zone */
   if (old_tz != NULL)
     g_assert_true (g_setenv ("TZ", old_tz, TRUE));
   else
     g_unsetenv ("TZ");
+  tzset ();
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      out.tv_sec = 0;
+      out.tv_usec = 0;
+      success = g_time_val_from_iso8601 (tests[i].in, &out);
+      g_assert_cmpint (success, ==, tests[i].success);
+    }
 
   g_free (old_tz);
 }
diff --git a/glib/tests/tree.c b/glib/tests/tree.c
index 5174479b9..e882926e6 100644
--- a/glib/tests/tree.c
+++ b/glib/tests/tree.c
@@ -482,6 +482,235 @@ test_tree_insert (void)
   g_tree_unref (tree);
 }
 
+static void
+binary_tree_bound (GTree *tree,
+                   char   c,
+                   char   expected,
+                   int    lower)
+{
+  GTreeNode *node;
+
+  if (lower)
+    node = g_tree_lower_bound (tree, &c);
+  else
+    node = g_tree_upper_bound (tree, &c);
+
+  if (g_test_verbose ())
+    g_test_message ("%c %s: ", c, lower ? "lower" : "upper");
+
+  if (!node)
+    {
+      if (!g_tree_nnodes (tree))
+        {
+          if (g_test_verbose ())
+            g_test_message ("empty tree");
+        }
+      else
+        {
+          GTreeNode *last = g_tree_node_last (tree);
+
+          g_assert (last);
+          if (g_test_verbose ())
+            g_test_message ("past end last %c",
+                            *(char *) g_tree_node_key (last));
+        }
+      g_assert (expected == '\x00');
+    }
+  else
+    {
+      GTreeNode *begin = g_tree_node_first (tree);
+      GTreeNode *last = g_tree_node_last (tree);
+      GTreeNode *prev = g_tree_node_previous (node);
+      GTreeNode *next = g_tree_node_next (node);
+
+      g_assert (expected != '\x00');
+      g_assert (expected == *(char *) g_tree_node_key (node));
+
+      if (g_test_verbose ())
+        g_test_message ("%c", *(char *) g_tree_node_key (node));
+
+      if (node != begin)
+        {
+          g_assert (prev);
+          if (g_test_verbose ())
+            g_test_message (" prev %c", *(char *) g_tree_node_key (prev));
+        }
+      else
+        {
+          g_assert (!prev);
+          if (g_test_verbose ())
+            g_test_message (" no prev, it's the first one");
+        }
+
+      if (node != last)
+        {
+          g_assert (next);
+          if (g_test_verbose ())
+            g_test_message (" next %c", *(char *) g_tree_node_key (next));
+        }
+      else
+        {
+          g_assert (!next);
+          if (g_test_verbose ())
+            g_test_message (" no next, it's the last one");
+        }
+    }
+
+  if (g_test_verbose ())
+    g_test_message ("\n");
+}
+
+static void
+binary_tree_bounds (GTree *tree,
+                    char   c,
+                    int    mode)
+{
+  char expectedl, expectedu;
+  char first = mode == 0 ? '0' : mode == 1 ? 'A' : 'z';
+
+  g_assert (mode >= 0 && mode <= 3);
+
+  if (c < first)
+    expectedl = first;
+  else if (c > 'z')
+    expectedl = '\x00';
+  else
+    expectedl = c;
+
+  if (c < first)
+    expectedu = first;
+  else if (c >= 'z')
+    expectedu = '\x00';
+  else
+    expectedu = c == '9' ? 'A' : c == 'Z' ? 'a' : c + 1;
+
+  if (mode == 3)
+    {
+      expectedl = '\x00';
+      expectedu = '\x00';
+    }
+
+  binary_tree_bound (tree, c, expectedl, 1);
+  binary_tree_bound (tree, c, expectedu, 0);
+}
+
+static void
+binary_tree_bounds_test (GTree *tree,
+                         int    mode)
+{
+  binary_tree_bounds (tree, 'a', mode);
+  binary_tree_bounds (tree, 'A', mode);
+  binary_tree_bounds (tree, 'z', mode);
+  binary_tree_bounds (tree, 'Z', mode);
+  binary_tree_bounds (tree, 'Y', mode);
+  binary_tree_bounds (tree, '0', mode);
+  binary_tree_bounds (tree, '9', mode);
+  binary_tree_bounds (tree, '0' - 1, mode);
+  binary_tree_bounds (tree, 'z' + 1, mode);
+  binary_tree_bounds (tree, '0' - 2, mode);
+  binary_tree_bounds (tree, 'z' + 2, mode);
+}
+
+static void
+test_tree_bounds (void)
+{
+  GQueue queue = G_QUEUE_INIT;
+  GTree *tree;
+  char chars[62];
+  guint i, j;
+
+  tree = g_tree_new (my_compare);
+
+  i = 0;
+  for (j = 0; j < 10; j++, i++)
+    {
+      chars[i] = '0' + j;
+      g_queue_push_tail (&queue, &chars[i]);
+    }
+
+  for (j = 0; j < 26; j++, i++)
+    {
+      chars[i] = 'A' + j;
+      g_queue_push_tail (&queue, &chars[i]);
+    }
+
+  for (j = 0; j < 26; j++, i++)
+    {
+      chars[i] = 'a' + j;
+      g_queue_push_tail (&queue, &chars[i]);
+    }
+
+  if (g_test_verbose ())
+    g_test_message ("tree insert: ");
+
+  while (!g_queue_is_empty (&queue))
+    {
+      gint32 which = g_random_int_range (0, g_queue_get_length (&queue));
+      gpointer elem = g_queue_pop_nth (&queue, which);
+      GTreeNode *node;
+
+      if (g_test_verbose ())
+        g_test_message ("%c ", *(char *) elem);
+
+      node = g_tree_insert_node (tree, elem, elem);
+      g_assert (g_tree_node_key (node) == elem);
+      g_assert (g_tree_node_value (node) == elem);
+    }
+
+  if (g_test_verbose ())
+    g_test_message ("\n");
+
+  g_assert_cmpint (g_tree_nnodes (tree), ==, 10 + 26 + 26);
+  g_assert_cmpint (g_tree_height (tree), >=, 6);
+  g_assert_cmpint (g_tree_height (tree), <=, 8);
+
+  if (g_test_verbose ())
+    {
+      g_test_message ("tree: ");
+      g_tree_foreach (tree, my_traverse, NULL);
+      g_test_message ("\n");
+    }
+
+  binary_tree_bounds_test (tree, 0);
+
+  for (i = 0; i < 10; i++)
+    g_tree_remove (tree, &chars[i]);
+
+  g_assert_cmpint (g_tree_nnodes (tree), ==, 26 + 26);
+  g_assert_cmpint (g_tree_height (tree), >=, 6);
+  g_assert_cmpint (g_tree_height (tree), <=, 8);
+
+  if (g_test_verbose ())
+    {
+      g_test_message ("tree: ");
+      g_tree_foreach (tree, my_traverse, NULL);
+      g_test_message ("\n");
+    }
+
+  binary_tree_bounds_test (tree, 1);
+
+  for (i = 10; i < 10 + 26 + 26 - 1; i++)
+    g_tree_remove (tree, &chars[i]);
+
+  if (g_test_verbose ())
+    {
+      g_test_message ("tree: ");
+      g_tree_foreach (tree, my_traverse, NULL);
+      g_test_message ("\n");
+    }
+
+  binary_tree_bounds_test (tree, 2);
+
+  g_tree_remove (tree, &chars[10 + 26 + 26 - 1]);
+
+  if (g_test_verbose ())
+    g_test_message ("empty tree\n");
+
+  binary_tree_bounds_test (tree, 3);
+
+  g_tree_unref (tree);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -492,6 +721,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/tree/destroy", test_tree_destroy);
   g_test_add_func ("/tree/traverse", test_tree_traverse);
   g_test_add_func ("/tree/insert", test_tree_insert);
+  g_test_add_func ("/tree/bounds", test_tree_bounds);
   g_test_add_func ("/tree/remove-all", test_tree_remove_all);
 
   return g_test_run ();
diff --git a/tests/meson.build b/tests/meson.build
index 52b64d1c0..190f3a2e1 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -16,7 +16,6 @@ subdir('gobject')
 subdir('refcount')
 
 tests = {
-  'testglib' : {'tap' : true},
   'gio-test' : {},
   'mainloop-test' : {},
   'mapping-test' : {},


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