str: Make str_format_26adic() able to use lowercase.
[pspp] / tests / libpspp / stringi-set-test.c
index 16a4e18015eca48e874ae2d8ec222cd36c37838b..2bcc760780c4bde4f78e718582d9fbcdf9f92f03 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010, 2012, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <string.h>
 
 #include "libpspp/compiler.h"
+#include "libpspp/i18n.h"
 #include "libpspp/str.h"
 \f
-/* Currently running test. */
-static const char *test_name;
-
 /* Exit with a failure code.
    (Place a breakpoint on this function while debugging.) */
 static void
@@ -56,8 +54,7 @@ check_func (bool ok, int line)
 {
   if (!ok)
     {
-      printf ("Check failed in %s test at %s, line %d\n",
-              test_name, __FILE__, line);
+      fprintf (stderr, "%s:%d: check failed\n", __FILE__, line);
       check_die ();
     }
 }
@@ -136,7 +133,7 @@ make_string (int value)
   if (*s == NULL)
     {
       *s = xmalloc (16);
-      str_format_26adic (value + 1, *s, 16);
+      str_format_26adic (value + 1, true, *s, 16);
     }
   return *s;
 }
@@ -248,7 +245,7 @@ check_set_contains (struct stringi_set *set, const char *string)
 
   node = stringi_set_find_node (set, string);
   check (node != NULL);
-  check (!strcasecmp (string, stringi_set_node_get_string (node)));
+  check (!utf8_strcasecmp (string, stringi_set_node_get_string (node)));
 }
 
 /* Checks that SET contains the CNT strings in DATA, that its structure is
@@ -283,13 +280,18 @@ check_stringi_set (struct stringi_set *set, const int data[], size_t cnt)
   check (stringi_set_find_node (set, "") == NULL);
 
   if (cnt == 0)
-    check (stringi_set_first (set) == NULL);
+    {
+      check (stringi_set_first (set) == NULL);
+      free (stringi_set_get_array (set));
+    }
   else
     {
       const struct stringi_set_node *node;
+      char **array;
       int *data_copy;
       int left;
 
+      array = stringi_set_get_array (set);
       data_copy = xmemdup (data, cnt * sizeof *data);
       left = cnt;
       for (node = stringi_set_first (set), i = 0; i < cnt;
@@ -298,8 +300,10 @@ check_stringi_set (struct stringi_set *set, const int data[], size_t cnt)
           const char *s = stringi_set_node_get_string (node);
           size_t j;
 
+          check (s == array[i]);
+
           for (j = 0; j < left; j++)
-            if (!strcasecmp (s, make_string (data_copy[j])))
+            if (!utf8_strcasecmp (s, make_string (data_copy[j])))
               {
                 data_copy[j] = data_copy[--left];
                 goto next;
@@ -310,6 +314,16 @@ check_stringi_set (struct stringi_set *set, const int data[], size_t cnt)
         }
       check (node == NULL);
       free (data_copy);
+      free (array);
+
+      array = stringi_set_get_sorted_array (set);
+      for (i = 0; i < cnt; i++)
+        {
+          if (i > 0)
+            check (utf8_strcasecmp (array[i - 1], array[i]) < 0);
+          check (stringi_set_contains (set, array[i]));
+        }
+      free (array);
     }
 }
 
@@ -665,38 +679,115 @@ test_destroy_null (void)
 \f
 /* Main program. */
 
-/* Runs TEST_FUNCTION and prints a message about NAME. */
-static void
-run_test (void (*test_function) (void), const char *name)
-{
-  test_name = name;
-  putchar ('.');
-  fflush (stdout);
-  test_function ();
-}
+struct test
+  {
+    const char *name;
+    const char *description;
+    void (*function) (void);
+  };
+
+static const struct test tests[] =
+  {
+    {
+      "insert-any-remove-any",
+      "insert any order, delete any order",
+      test_insert_any_remove_any
+    },
+    {
+      "insert-any-remove-same",
+      "insert any order, delete same order",
+      test_insert_any_remove_same
+    },
+    {
+      "insert-any-remove-reverse",
+      "insert any order, delete reverse order",
+      test_insert_any_remove_reverse
+    },
+    {
+      "random-sequence",
+      "insert and delete in random sequence",
+      test_random_sequence
+    },
+    {
+      "insert-ordered",
+      "insert in ascending order",
+      test_insert_ordered
+    },
+    {
+      "union",
+      "union",
+      test_union
+    },
+    {
+      "union-and-intersection",
+      "union and intersection",
+      test_union_and_intersection
+    },
+    {
+      "intersect",
+      "intersect",
+      test_intersect
+    },
+    {
+      "subtract",
+      "subtract",
+      test_subtract
+    },
+    {
+      "swap",
+      "swap",
+      test_swap
+    },
+    {
+      "clear",
+      "clear",
+      test_clear
+    },
+    {
+      "clone",
+      "clone",
+      test_clone
+    },
+    {
+      "destroy-null",
+      "destroying null table",
+      test_destroy_null
+    },
+  };
+
+enum { N_TESTS = sizeof tests / sizeof *tests };
 
 int
-main (void)
-{
-  run_test (test_insert_any_remove_any, "insert any order, delete any order");
-  run_test (test_insert_any_remove_same,
-            "insert any order, delete same order");
-  run_test (test_insert_any_remove_reverse,
-            "insert any order, delete reverse order");
-  run_test (test_random_sequence, "insert and delete in random sequence");
-  run_test (test_insert_ordered, "insert in ascending order");
-  run_test (test_union, "union");
-  run_test (test_union_and_intersection, "union and intersection");
-  run_test (test_intersect, "intersect");
-  run_test (test_subtract, "subtract");
-  run_test (test_swap, "swap");
-  run_test (test_clear, "clear");
-  run_test (test_clone, "clone");
-  run_test (test_destroy_null, "destroying null table");
-
-  putchar ('\n');
-
-  free_strings ();
-
-  return 0;
+main (int argc, char *argv[])
+{
+  int i;
+
+  if (argc != 2)
+    {
+      fprintf (stderr, "exactly one argument required; use --help for help\n");
+      return EXIT_FAILURE;
+    }
+  else if (!strcmp (argv[1], "--help"))
+    {
+      printf ("%s: test case-insensitive string set library\n"
+              "usage: %s TEST-NAME\n"
+              "where TEST-NAME is one of the following:\n",
+              argv[0], argv[0]);
+      for (i = 0; i < N_TESTS; i++)
+        printf ("  %s\n    %s\n", tests[i].name, tests[i].description);
+      return 0;
+    }
+  else
+    {
+      for (i = 0; i < N_TESTS; i++)
+        if (!strcmp (argv[1], tests[i].name))
+          {
+            tests[i].function ();
+            free_strings ();
+            return 0;
+          }
+
+      fprintf (stderr, "unknown test %s; use --help for help\n", argv[1]);
+      return EXIT_FAILURE;
+    }
 }