Add more spellcheck selftests
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 15 Jun 2016 00:12:16 +0000 (00:12 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Wed, 15 Jun 2016 00:12:16 +0000 (00:12 +0000)
gcc/ChangeLog:
* selftest-run-tests.c (selftest::run_tests): Call
selftest::spellcheck_tree_c_tests.
* selftest.h (selftest::spellcheck_tree_c_tests): New decl.
* spellcheck-tree.c: Include selftest.h and stringpool.h.
(selftest::test_find_closest_identifier): New function.
(selftest::spellcheck_tree_c_tests): New function.
* spellcheck.c (selftest::test_find_closest_string): Verify that
the order of the vec does not affect the results for this case.
(selftest::test_data): New array.
(selftest::test_metric_conditions): New function.
(selftest::spellcheck_c_tests): Add a test of case-comparison.
Call selftest::test_metric_conditions.

From-SVN: r237466

gcc/ChangeLog
gcc/selftest-run-tests.c
gcc/selftest.h
gcc/spellcheck-tree.c
gcc/spellcheck.c

index e0a7987f8145d5db8dff6f0e7e26cd64de40f97b..9bf0db86a7738ba8dee94107e4970b48d041e5f6 100644 (file)
@@ -1,3 +1,18 @@
+2016-06-14  David Malcolm  <dmalcolm@redhat.com>
+
+       * selftest-run-tests.c (selftest::run_tests): Call
+       selftest::spellcheck_tree_c_tests.
+       * selftest.h (selftest::spellcheck_tree_c_tests): New decl.
+       * spellcheck-tree.c: Include selftest.h and stringpool.h.
+       (selftest::test_find_closest_identifier): New function.
+       (selftest::spellcheck_tree_c_tests): New function.
+       * spellcheck.c (selftest::test_find_closest_string): Verify that
+       the order of the vec does not affect the results for this case.
+       (selftest::test_data): New array.
+       (selftest::test_metric_conditions): New function.
+       (selftest::spellcheck_c_tests): Add a test of case-comparison.
+       Call selftest::test_metric_conditions.
+
 2016-06-14  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000-builtin.def (commentary): Typo.
index 934e700b2e1385b06a58d03412da2be9203d6633..d4a9c0b26b891a3aba90f81b6a18ebb616238991 100644 (file)
@@ -61,6 +61,7 @@ selftest::run_tests ()
   diagnostic_show_locus_c_tests ();
   fold_const_c_tests ();
   spellcheck_c_tests ();
+  spellcheck_tree_c_tests ();
   tree_cfg_c_tests ();
 
   /* This one relies on most of the above.  */
index e719f5f9a7c65d0f013aadec83f6bd2f4b56c58d..2bc7316c990eaa2e27e11f9d544a1655d9f02bd3 100644 (file)
@@ -84,6 +84,7 @@ extern void input_c_tests ();
 extern void pretty_print_c_tests ();
 extern void rtl_tests_c_tests ();
 extern void spellcheck_c_tests ();
+extern void spellcheck_tree_c_tests ();
 extern void tree_c_tests ();
 extern void tree_cfg_c_tests ();
 extern void vec_c_tests ();
index eb6e72a6750f06a4083ff992b423747df8466626..2d73b7740bad9a6655673f1a9f08b021a0d6e300 100644 (file)
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "spellcheck.h"
+#include "selftest.h"
+#include "stringpool.h"
 
 /* Calculate Levenshtein distance between two identifiers.  */
 
@@ -78,3 +80,50 @@ find_closest_identifier (tree target, const auto_vec<tree> *candidates)
 
   return best_identifier;
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Selftests.  */
+
+/* Verify that find_closest_identifier is sane.  */
+
+static void
+test_find_closest_identifier ()
+{
+  auto_vec<tree> candidates;
+
+  /* Verify that it can handle an empty vec.  */
+  ASSERT_EQ (NULL, find_closest_identifier (get_identifier (""), &candidates));
+
+  /* Verify that it works sanely for non-empty vecs.  */
+  tree apple = get_identifier ("apple");
+  tree banana = get_identifier ("banana");
+  tree cherry = get_identifier ("cherry");
+  candidates.safe_push (apple);
+  candidates.safe_push (banana);
+  candidates.safe_push (cherry);
+
+  ASSERT_EQ (apple, find_closest_identifier (get_identifier ("app"),
+                                            &candidates));
+  ASSERT_EQ (banana, find_closest_identifier (get_identifier ("banyan"),
+                                             &candidates));;
+  ASSERT_EQ (cherry, find_closest_identifier (get_identifier ("berry"),
+                                             &candidates));
+  ASSERT_EQ (NULL,
+            find_closest_identifier (get_identifier ("not like the others"),
+                                     &candidates));
+}
+
+/* Run all of the selftests within this file.  */
+
+void
+spellcheck_tree_c_tests ()
+{
+  test_find_closest_identifier ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
index 11018f0710eac2ee3c773d1fb30a6a1e2ff87136..e03f484d621aedaf5828ceaa354db5de24a55901 100644 (file)
@@ -217,6 +217,69 @@ test_find_closest_string ()
   ASSERT_STREQ ("banana", find_closest_string ("banyan", &candidates));
   ASSERT_STREQ ("cherry", find_closest_string ("berry", &candidates));
   ASSERT_EQ (NULL, find_closest_string ("not like the others", &candidates));
+
+  /* The order of the vec can matter, but it should not matter for these
+     inputs.  */
+  candidates.truncate (0);
+  candidates.safe_push ("cherry");
+  candidates.safe_push ("banana");
+  candidates.safe_push ("apple");
+  ASSERT_STREQ ("apple", find_closest_string ("app", &candidates));
+  ASSERT_STREQ ("banana", find_closest_string ("banyan", &candidates));
+  ASSERT_STREQ ("cherry", find_closest_string ("berry", &candidates));
+  ASSERT_EQ (NULL, find_closest_string ("not like the others", &candidates));
+}
+
+/* Test data for test_metric_conditions.  */
+
+static const char * const test_data[] = {
+  "",
+  "foo"
+  "food",
+  "boo",
+  "1234567890123456789012345678901234567890123456789012345678901234567890"
+};
+
+/* Verify that levenshtein_distance appears to be a sane distance function,
+   i.e. the conditions for being a metric.  This is done directly for a
+   small set of examples, using test_data above.  This is O(N^3) in the size
+   of the array, due to the test for the triangle inequality, so we keep the
+   array small.  */
+
+static void
+test_metric_conditions ()
+{
+  const int num_test_cases = sizeof (test_data) / sizeof (test_data[0]);
+
+  for (int i = 0; i < num_test_cases; i++)
+    {
+      for (int j = 0; j < num_test_cases; j++)
+       {
+         edit_distance_t dist_ij
+           = levenshtein_distance (test_data[i], test_data[j]);
+
+         /* Identity of indiscernibles: d(i, j) > 0 iff i == j.  */
+         if (i == j)
+           ASSERT_EQ (dist_ij, 0);
+         else
+           ASSERT_TRUE (dist_ij > 0);
+
+         /* Symmetry: d(i, j) == d(j, i).  */
+         edit_distance_t dist_ji
+           = levenshtein_distance (test_data[j], test_data[i]);
+         ASSERT_EQ (dist_ij, dist_ji);
+
+         /* Triangle inequality.  */
+         for (int k = 0; k < num_test_cases; k++)
+           {
+             edit_distance_t dist_ik
+               = levenshtein_distance (test_data[i], test_data[k]);
+             edit_distance_t dist_jk
+               = levenshtein_distance (test_data[j], test_data[k]);
+             ASSERT_TRUE (dist_ik <= dist_ij + dist_jk);
+           }
+       }
+    }
 }
 
 /* Verify levenshtein_distance for a variety of pairs of pre-canned
@@ -239,8 +302,10 @@ spellcheck_c_tests ()
     ("Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
      "All your base are belong to us",
      44);
+  levenshtein_distance_unit_test ("foo", "FOO", 3);
 
   test_find_closest_string ();
+  test_metric_conditions ();
 }
 
 } // namespace selftest