/* 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 <UnitTest++.h>
#include <enchant.h>
#include <enchant-provider.h>
#include <glib.h>
#include <gmodule.h>
#include <assert.h>
#include <string.h>
#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_CONST_RETURN char *dir_entry;
size_t entry_len, g_module_suffix_len;
char * filename;
int result = 0;
dir = g_dir_open (dir_name, 0, NULL);
if (!dir)
return 0;
g_module_suffix_len = strlen (G_MODULE_SUFFIX);
while ((dir_entry = g_dir_read_name (dir)) != NULL)
{
entry_len = strlen (dir_entry);
if ((entry_len > g_module_suffix_len) &&
!strcmp(dir_entry+(entry_len-g_module_suffix_len), G_MODULE_SUFFIX))
{
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;
}
if(module){
g_module_close(module);
}
return result;
}