/* Copyright (c) 2008 Eric Scott Albright * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include "unittest_enchant_providers.h" int Test(char* path); int TestProvider(char* filename); int TestProvidersInDirectory(char * dir_name); typedef EnchantProvider *(*EnchantProviderInitFunc) (void); typedef void (*EnchantPreConfigureFunc) (EnchantProvider * provider, const char * module_dir); // from enchant.c: we need this so that providers can set errors. struct str_enchant_broker { GSList *provider_list; /* list of all of the spelling backend providers */ GHashTable *dict_map; /* map of language tag -> dictionary */ GHashTable *provider_ordering; /* map of language tag -> provider order */ gchar * error; }; // comes with a list of directories or providers int main(int argc, char* argv[]) { int result = 0; for(int i=1; i < argc; ++i) { int resultT = Test(argv[i]); if(resultT != 0) { result = resultT; } } if(argc == 1) { char* current_dir = g_get_current_dir(); result = TestProvidersInDirectory(current_dir); g_free(current_dir); } return result; } EnchantProvider* g_provider; EnchantProvider* GetProviderForTests() { return g_provider; } char* GetErrorMessage(EnchantProvider* provider) { return provider->owner->error; } //path is provider filename or directory containing providers int Test(char* path) { assert(path); if (g_file_test (path, (GFileTest)(G_FILE_TEST_IS_DIR))) { return TestProvidersInDirectory(path); } else { return TestProvider(path); } } int TestProvidersInDirectory(char * dir_name) { GDir *dir = g_dir_open (dir_name, 0, NULL); if (!dir) return 0; size_t g_module_suffix_len = strlen (G_MODULE_SUFFIX); int result = 0; const char *dir_entry; while ((dir_entry = g_dir_read_name (dir)) != NULL) { size_t entry_len = strlen (dir_entry); if ((entry_len > g_module_suffix_len) && !strcmp(dir_entry + (entry_len - g_module_suffix_len), G_MODULE_SUFFIX)) { char *filename = g_build_filename (dir_name, dir_entry, NULL); int resultT = Test(filename); if(resultT != 0) result = resultT; g_free (filename); } } g_dir_close (dir); return result; } int TestProvider(char* filename) { assert(g_provider == NULL); int result = 0; EnchantProviderInitFunc init_func; EnchantPreConfigureFunc conf_func; GModule* module = g_module_open (filename, (GModuleFlags) 0); if (module) { if (g_module_symbol(module, "init_enchant_provider", (gpointer *) (&init_func)) && init_func) { g_provider = init_func (); } /* optional entry point to allow modules to look for associated files */ if (g_provider && g_module_symbol(module, "configure_enchant_provider", (gpointer *) (&conf_func)) && conf_func) { char* dir_name = g_path_get_dirname(filename); conf_func (g_provider, dir_name); g_free(dir_name); } } else { g_warning ("Could not load provider: %s\n", g_module_error()); } if (g_provider) { EnchantBroker broker; // just so we have someplace to put errors broker.error=NULL; g_provider->enchant_private_data = (void *) module; g_provider->owner = &broker; printf("\nRunning tests on %s\n", filename); result = UnitTest::RunAllTests(); if(g_provider->dispose) g_provider->dispose(g_provider); g_provider = NULL; free(broker.error); } if(module){ g_module_close(module); } return result; }