/* Copyright (c) 2007 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 <algorithm>
#include <functional>
#include <vector>
#include "EnchantBrokerTestFixture.h"
struct ProviderDescription
{
std::string Name;
std::string Description;
std::string DllFile;
ProviderDescription(const char * const provider_name,
const char * const provider_desc,
const char * const provider_dll_file):
Name(provider_name),
Description(provider_desc),
DllFile(provider_dll_file)
{}
bool DataIsComplete() const
{
return (Name.length() &&
Description.length() &&
DllFile.length());
}
};
void EnchantBrokerDescribeCallback (const char * const provider_name,
const char * const provider_desc,
const char * const provider_dll_file,
void * user_data)
{
std::vector<ProviderDescription>* providerList = reinterpret_cast<std::vector<ProviderDescription>*>(user_data);
providerList->push_back(ProviderDescription(provider_name, provider_desc, provider_dll_file));
}
static void * global_user_data;
void EnchantBrokerDescribeAssignUserDataToStaticCallback (const char * const,
const char * const,
const char * const,
void * user_data)
{
global_user_data = user_data;
}
struct EnchantBrokerNoProvidersTestFixture : EnchantTestFixture
{
//Setup
EnchantBrokerNoProvidersTestFixture()
{
_broker = enchant_broker_init ();
}
//Teardown
~EnchantBrokerNoProvidersTestFixture()
{
enchant_broker_free (_broker);
}
EnchantBroker* _broker;
std::vector<ProviderDescription> _providerList;
};
static const char *
MockProvider2Identify (EnchantProvider *)
{
return "mock2";
}
static void Provider2Configuration (EnchantProvider * me, const char *)
{
me->identify = MockProvider2Identify;
me->describe = MockProviderDescribe;
}
struct EnchantBrokerDescribeTestFixtureBase : EnchantBrokerTestFixture
{
std::vector<ProviderDescription> _providerList;
//Setup
EnchantBrokerDescribeTestFixtureBase(ConfigureHook userConfiguration):
EnchantBrokerTestFixture(userConfiguration, Provider2Configuration, true)
{ }
};
static void List_Providers_ProviderConfiguration (EnchantProvider * me, const char *)
{
me->identify = MockProviderIdentify;
me->describe = MockProviderDescribe;
}
struct EnchantBrokerDescribeTestFixture : EnchantBrokerDescribeTestFixtureBase
{
//Setup
EnchantBrokerDescribeTestFixture():
EnchantBrokerDescribeTestFixtureBase(List_Providers_ProviderConfiguration)
{
global_user_data = NULL;
}
};
static void List_Providers_ProviderConfigurationNoIdentify (EnchantProvider * me, const char *)
{
me->identify = NULL;
}
struct EnchantBrokerDescribe_ProviderLacksIdentify_TestFixture : EnchantBrokerDescribeTestFixtureBase
{
//Setup
EnchantBrokerDescribe_ProviderLacksIdentify_TestFixture():
EnchantBrokerDescribeTestFixtureBase(List_Providers_ProviderConfigurationNoIdentify)
{
global_user_data = NULL;
}
};
static void List_Providers_ProviderConfigurationNoDescribe (EnchantProvider * me, const char *)
{
me->describe = NULL;
}
struct EnchantBrokerDescribe_ProviderLacksDescribe_TestFixture : EnchantBrokerDescribeTestFixtureBase
{
//Setup
EnchantBrokerDescribe_ProviderLacksDescribe_TestFixture():
EnchantBrokerDescribeTestFixtureBase(List_Providers_ProviderConfigurationNoDescribe)
{
global_user_data = NULL;
}
};
static const char *
MockProviderIllegalUtf8 (EnchantProvider *)
{
return "\xa5\xf1\x08";
}
static void List_Providers_ProviderConfigurationInvalidIdentify (EnchantProvider * me, const char *)
{
me->identify = MockProviderIllegalUtf8;
}
struct EnchantBrokerDescribe_ProviderHasInvalidUtf8Identify_TestFixture : EnchantBrokerDescribeTestFixtureBase
{
//Setup
EnchantBrokerDescribe_ProviderHasInvalidUtf8Identify_TestFixture():
EnchantBrokerDescribeTestFixtureBase(List_Providers_ProviderConfigurationInvalidIdentify)
{
global_user_data = NULL;
}
};
static void List_Providers_ProviderConfigurationInvalidDescribe (EnchantProvider * me, const char *)
{
me->describe = MockProviderIllegalUtf8;
}
struct EnchantBrokerDescribe_ProviderHasInvalidUtf8Describe_TestFixture : EnchantBrokerDescribeTestFixtureBase
{
//Setup
EnchantBrokerDescribe_ProviderHasInvalidUtf8Describe_TestFixture():
EnchantBrokerDescribeTestFixtureBase(List_Providers_ProviderConfigurationInvalidDescribe)
{
global_user_data = NULL;
}
};
/**
* enchant_broker_describe
* @broker: A non-null #EnchantBroker
* @fn: A non-null #EnchantBrokerDescribeFn
* @user_data: Optional user-data
*
* Enumerates the Enchant providers and tells
* you some rudimentary information about them.
*/
/*
* Providers are discovered by probing first in the .enchant directory
* in the user's home directory.
* [on windows in the enchant directory in the user's Application Data
* directory]
*
* Then from the module directory (that libenchant is in).
*/
/////////////////////////////////////////////////////////////////////////////
// Test Normal Operation
TEST_FIXTURE(EnchantBrokerNoProvidersTestFixture,
EnchantBrokerDescribe_NoProviders)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)0, _providerList.size());
}
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_ProvidersInUserDirectoryTakePrecedenceOverProvidersInSystem)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)2, _providerList.size());
CHECK_EQUAL(2, std::count_if(_providerList.begin(),
_providerList.end(),
std::mem_fun_ref(&ProviderDescription::DataIsComplete)));
}
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_NullUserData_PassedThroughToCallback)
{
global_user_data = const_cast<char *>("hello world");
enchant_broker_describe(_broker,
EnchantBrokerDescribeAssignUserDataToStaticCallback,
NULL);
CHECK_EQUAL((void*)NULL, global_user_data);
}
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_NonNullUserData_PassedThroughToCallback)
{
const char* data = "some data";
global_user_data = NULL;
enchant_broker_describe(_broker,
EnchantBrokerDescribeAssignUserDataToStaticCallback,
const_cast<char*>(data));
CHECK(global_user_data);
if(global_user_data){
CHECK_EQUAL(data, (char*)global_user_data);
}
}
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_HasPreviousError_ErrorCleared)
{
SetErrorOnMockProvider("something bad happened");
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
}
/////////////////////////////////////////////////////////////////////////////
// Test Error Conditions
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_NullBroker_DoNothing)
{
enchant_broker_describe(NULL, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((void*)NULL, global_user_data);
}
TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
EnchantBrokerDescribe_NullDescribeFunction_DoNothing)
{
enchant_broker_describe(_broker, NULL, &_providerList);
CHECK_EQUAL((void*)NULL, global_user_data);
}
TEST_FIXTURE(EnchantBrokerDescribe_ProviderLacksIdentify_TestFixture,
EnchantBrokerDescribe_ProviderLacksIdentify_NotLoaded)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)1, _providerList.size());
CHECK_EQUAL(1, std::count_if(_providerList.begin(),
_providerList.end(),
std::mem_fun_ref(&ProviderDescription::DataIsComplete)));
}
TEST_FIXTURE(EnchantBrokerDescribe_ProviderLacksDescribe_TestFixture,
EnchantBrokerDescribe_ProviderLacksDescribe_NotLoaded)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)1, _providerList.size());
CHECK_EQUAL(1, std::count_if(_providerList.begin(),
_providerList.end(),
std::mem_fun_ref(&ProviderDescription::DataIsComplete)));
}
TEST_FIXTURE(EnchantBrokerDescribe_ProviderHasInvalidUtf8Describe_TestFixture,
EnchantBrokerDescribe_ProviderHasInvalidUtf8Describe_NotLoaded)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)1, _providerList.size());
CHECK_EQUAL(1, std::count_if(_providerList.begin(),
_providerList.end(),
std::mem_fun_ref(&ProviderDescription::DataIsComplete)));
}
TEST_FIXTURE(EnchantBrokerDescribe_ProviderHasInvalidUtf8Identify_TestFixture,
EnchantBrokerDescribe_ProviderHasInvalidUtf8Identify_NotLoaded)
{
enchant_broker_describe(_broker, EnchantBrokerDescribeCallback, &_providerList);
CHECK_EQUAL((unsigned int)1, _providerList.size());
CHECK_EQUAL(1, std::count_if(_providerList.begin(),
_providerList.end(),
std::mem_fun_ref(&ProviderDescription::DataIsComplete)));
}