Back to index

indicator-appmenu  12.10.0
test-distance.c
Go to the documentation of this file.
00001 /*
00002 Test code for distance functions
00003 
00004 Copyright 2011 Canonical Ltd.
00005 
00006 Authors:
00007     Ted Gould <ted@canonical.com>
00008 
00009 This program is free software: you can redistribute it and/or modify it 
00010 under the terms of the GNU General Public License version 3, as published 
00011 by the Free Software Foundation.
00012 
00013 This program is distributed in the hope that it will be useful, but 
00014 WITHOUT ANY WARRANTY; without even the implied warranties of 
00015 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
00016 PURPOSE.  See the GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License along 
00019 with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 */
00021 
00022 #include <glib.h>
00023 #include <glib-object.h>
00024 
00025 #include "hudsettings.h"
00026 #include "hudtoken.h"
00027 
00028 /* hardcode some parameters so the test doesn't fail if the user
00029  * has bogus things in GSettings.
00030  */
00031 HudSettings hud_settings = {
00032        .indicator_penalty = 50,
00033        .add_penalty = 10,
00034        .drop_penalty = 10,
00035        .end_drop_penalty = 1,
00036        .swap_penalty = 15,
00037        .max_distance = 30
00038 };
00039 
00040 static guint
00041 calculate_distance (const gchar *search, GStrv teststrings, gchar ***matches)
00042 {
00043        HudStringList *list = NULL;
00044        HudTokenList *haystack;
00045        HudTokenList *needle;
00046        guint distance;
00047        gint i;
00048 
00049        if (search == NULL || teststrings == NULL) {
00050               return G_MAXINT;
00051        }
00052 
00053        for (i = 0; teststrings[i]; i++) {
00054               HudStringList *tmp;
00055 
00056               tmp = hud_string_list_cons (teststrings[i], list);
00057               hud_string_list_unref (list);
00058               list = tmp;
00059        }
00060 
00061        haystack = hud_token_list_new_from_string_list (list);
00062        hud_string_list_unref (list);
00063 
00064        needle = hud_token_list_new_from_string (search);
00065        distance = hud_token_list_distance (haystack, needle, (const gchar ***) matches);
00066 
00067        if (matches) {
00068               /* These are owned by the tokenlists, so make copies
00069                * before freeing.
00070                */
00071               for (i = 0; (*matches)[i]; i++) {
00072                      (*matches)[i] = g_strdup ((*matches)[i]);
00073               }
00074        }
00075 
00076        hud_token_list_free (haystack);
00077        hud_token_list_free (needle);
00078 
00079        return distance;
00080 }
00081 
00082 /* Ensure the base calculation works */
00083 static void
00084 test_distance_base (void)
00085 {
00086        gchar * testdata1[] = {"foo", NULL};
00087        g_assert(calculate_distance("foo", testdata1, NULL) == 0);
00088 
00089        gchar * testdata2[] = {"bar", NULL};
00090        g_assert(calculate_distance("foo", testdata2, NULL) != 0);
00091 
00092        g_assert(calculate_distance("foo", NULL, NULL) != 0);
00093 
00094        g_assert(calculate_distance(NULL, testdata1, NULL) != 0);
00095 
00096        return;
00097 }
00098 
00099 /* Test a set of strings */
00100 static void
00101 test_set (GStrv * teststrings, int num_tests, const gchar * search, int right)
00102 {
00103        int i;
00104 
00105        for (i = 0; i < num_tests; i++) {
00106               if (i == right)
00107                      continue;
00108 
00109               if (calculate_distance(search, teststrings[i], NULL) < calculate_distance(search, teststrings[right], NULL)) {
00110                      gchar * teststr = g_strjoinv(" > ", teststrings[i]);
00111                      gchar * rightstr = g_strjoinv(" > ", teststrings[right]);
00112 
00113                      g_error("Found '%s' with search string '%s' instead of '%s'", teststr, search, rightstr);
00114 
00115                      g_free(teststr);
00116                      g_free(rightstr);
00117               }
00118        }
00119 
00120        return;
00121 }
00122 
00123 /* Ensure the base calculation works */
00124 static void
00125 test_distance_subfunction (void)
00126 {
00127        GStrv teststrings[4];
00128        gchar * teststrings0[] = {"File", "Open", NULL}; teststrings[0] = teststrings0;
00129        gchar * teststrings1[] = {"File", "New", NULL}; teststrings[1] = teststrings1;
00130        gchar * teststrings2[] = {"File", "Print", NULL}; teststrings[2] = teststrings2;
00131        gchar * teststrings3[] = {"File", "Print Preview", NULL}; teststrings[3] = teststrings3;
00132 
00133        test_set(teststrings, 4, "Print Pre", 3);
00134        return;
00135 }
00136 
00137 /* Ensure that we can handle some misspelling */
00138 static void
00139 test_distance_missspelll (void)
00140 {
00141        GStrv teststrings[4];
00142        gchar * teststrings0[] = {"File", "Open", NULL}; teststrings[0] = teststrings0;
00143        gchar * teststrings1[] = {"File", "New", NULL}; teststrings[1] = teststrings1;
00144        gchar * teststrings2[] = {"File", "Print", NULL}; teststrings[2] = teststrings2;
00145        gchar * teststrings3[] = {"File", "Print Preview", NULL}; teststrings[3] = teststrings3;
00146 
00147        test_set(teststrings, 4, "Prnt Pr", 3);
00148        test_set(teststrings, 4, "Print Preiw", 3);
00149        test_set(teststrings, 4, "Prnt Pr", 3);
00150 
00151        return;
00152 }
00153 
00154 /* Ensure that we can find print with short strings */
00155 static void
00156 test_distance_print_issues (void)
00157 {
00158        GStrv teststrings[6];
00159        gchar * teststrings0[] = {"File", "New", NULL}; teststrings[0] = teststrings0;
00160        gchar * teststrings1[] = {"File", "Open", NULL}; teststrings[1] = teststrings1;
00161        gchar * teststrings2[] = {"Edit", "Undo", NULL}; teststrings[2] = teststrings2;
00162        gchar * teststrings3[] = {"Help", "About", NULL}; teststrings[3] = teststrings3;
00163        gchar * teststrings4[] = {"Help", "Empty", NULL}; teststrings[4] = teststrings4;
00164        gchar * teststrings5[] = {"File", "Print...", NULL}; teststrings[5] = teststrings5;
00165 
00166        test_set(teststrings, 6, "Pr", 5);
00167        test_set(teststrings, 6, "Print", 5);
00168        test_set(teststrings, 6, "Print...", 5);
00169 
00170        return;
00171 }
00172 
00173 /* A variety of strings that should have predictable results */
00174 static void
00175 test_distance_variety (void)
00176 {
00177        GStrv teststrings[4];
00178        gchar * teststrings0[] = {"Date", "House Cleaning", NULL}; teststrings[0] = teststrings0;
00179        gchar * teststrings1[] = {"File", "Close Window", NULL}; teststrings[1] = teststrings1;
00180        gchar * teststrings2[] = {"Edit", "Keyboard Shortcuts...", NULL}; teststrings[2] = teststrings2;
00181        gchar * teststrings3[] = {"Network", "VPN Configuration", "Configure VPN...", NULL}; teststrings[3] = teststrings3;
00182 
00183        test_set(teststrings, 4, "House", 0);
00184        test_set(teststrings, 4, "House C", 0);
00185        test_set(teststrings, 4, "House Cle", 0);
00186        test_set(teststrings, 4, "House Clean", 0);
00187        test_set(teststrings, 4, "Clean House", 0);
00188 
00189        return;
00190 }
00191 
00192 /* A variety of strings that should have predictable results */
00193 static void
00194 test_distance_french_pref (void)
00195 {
00196        GStrv teststrings[3];
00197        gchar * teststrings0[] = {"Fichier", "aperçu avant impression", NULL}; teststrings[0] = teststrings0;
00198        gchar * teststrings1[] = {"Connexion au réseau...", NULL}; teststrings[1] = teststrings1;
00199        gchar * teststrings2[] = {"Edition", "préférences", NULL}; teststrings[2] = teststrings2;
00200 
00201        test_set(teststrings, 3, "préférences", 2);
00202        test_set(teststrings, 3, "pré", 2);
00203        test_set(teststrings, 3, "préf", 2);
00204        test_set(teststrings, 3, "préfé", 2);
00205        test_set(teststrings, 3, "pref", 2);
00206 
00207        return;
00208 }
00209 
00210 /* Check to make sure the returned hits are not dups and the
00211    proper number */
00212 static void
00213 test_distance_dups (void)
00214 {
00215        GStrv hits = NULL;
00216        gchar * teststrings[] = {"Inflated", "Confluated", "Sublimated", "Sadated", "Situated", "Infatuated", NULL};
00217 
00218        g_assert(calculate_distance("ted inf", teststrings, &hits) != 0);
00219        g_assert(g_strv_length(hits) == 2);
00220        g_assert(g_strcmp0(hits[0], hits[1]) != 0);
00221 
00222        g_strfreev(hits);
00223 
00224        return;
00225 }
00226 
00227 /* Check to make sure 'Save' matches better than 'Save As...' for "save" */
00228 static void
00229 test_distance_extra_terms (void)
00230 {
00231   const gchar *save_as[] = { "File", "Save", "As...", NULL };
00232   const gchar *save[] = { "File", "Save", NULL };
00233 
00234   g_assert_cmpint (calculate_distance ("save", (GStrv) save, NULL),
00235                    <,
00236                    calculate_distance ("save", (GStrv) save_as, NULL));
00237 }
00238 
00239 /* Build the test suite */
00240 static void
00241 test_distance_suite (void)
00242 {
00243        g_test_add_func ("/hud/distance/base",          test_distance_base);
00244        g_test_add_func ("/hud/distance/subfunction",   test_distance_subfunction);
00245        g_test_add_func ("/hud/distance/missspelll",    test_distance_missspelll);
00246        g_test_add_func ("/hud/distance/print_issues",  test_distance_print_issues);
00247        g_test_add_func ("/hud/distance/duplicates",    test_distance_dups);
00248        g_test_add_func ("/hud/distance/variety",       test_distance_variety);
00249        g_test_add_func ("/hud/distance/french_pref",   test_distance_french_pref);
00250        g_test_add_func ("/hud/distance/extra_terms",   test_distance_extra_terms);
00251        return;
00252 }
00253 
00254 gint
00255 main (gint argc, gchar * argv[])
00256 {
00257        //gtk_init(&argc, &argv);
00258        g_type_init();
00259 
00260        g_test_init(&argc, &argv, NULL);
00261 
00262        /* Test suites */
00263        test_distance_suite();
00264 
00265        return g_test_run ();
00266 }