/* 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 <fstream>
#include "EnchantBrokerTestFixture.h"
static bool mock1ProviderRequestDictionaryCalled;
static bool mock2ProviderRequestDictionaryCalled;
static EnchantDict * RequestDictionary1 (EnchantProvider *me, const char *tag)
{
mock1ProviderRequestDictionaryCalled = true;
return MockEnGbAndQaaProviderRequestDictionary(me, tag);
}
static EnchantDict * RequestDictionary2 (EnchantProvider *me, const char *tag)
{
mock2ProviderRequestDictionaryCalled = true;
return MockEnGbAndQaaProviderRequestDictionary(me, tag);
}
static const char *
MockProvider1Identify (EnchantProvider *)
{
return "mock1";
}
static const char *
MockProvider2Identify (EnchantProvider *)
{
return "mock2";
}
static void Request_Dictionary_ProviderConfiguration1 (EnchantProvider * me, const char *)
{
me->request_dict = RequestDictionary1;
me->dispose_dict = MockProviderDisposeDictionary;
me->identify = MockProvider1Identify;
}
static void Request_Dictionary_ProviderConfiguration2 (EnchantProvider * me, const char *)
{
me->request_dict = RequestDictionary2;
me->dispose_dict = MockProviderDisposeDictionary;
me->identify = MockProvider2Identify;
}
enum ProviderOrder {
Mock1ThenMock2=1,
Mock2ThenMock1=2,
ErrorBothCalled=3,
ErrorNeitherCalled=4
};
struct EnchantBrokerSetOrdering_TestFixture : EnchantBrokerTestFixture
{
//Setup
EnchantBrokerSetOrdering_TestFixture():
EnchantBrokerTestFixture(Request_Dictionary_ProviderConfiguration1,Request_Dictionary_ProviderConfiguration2)
{
mock1ProviderRequestDictionaryCalled = false;
mock2ProviderRequestDictionaryCalled = false;
}
ProviderOrder GetProviderOrder(const std::string & languageTag)
{
ProviderOrder result = ErrorBothCalled;
EnchantDict* dict = enchant_broker_request_dict(_broker, languageTag.c_str());
if(mock2ProviderRequestDictionaryCalled && !mock1ProviderRequestDictionaryCalled)
{
result = Mock2ThenMock1;
}
else if(mock1ProviderRequestDictionaryCalled && !mock2ProviderRequestDictionaryCalled)
{
result = Mock1ThenMock2;
}
else if(!mock2ProviderRequestDictionaryCalled && !mock1ProviderRequestDictionaryCalled)
{
result = ErrorNeitherCalled;
}
FreeDictionary(dict);
mock1ProviderRequestDictionaryCalled = false;
mock2ProviderRequestDictionaryCalled = false;
return result;
}
};
struct EnchantBrokerFileSetOrdering_TestFixture: EnchantBrokerSetOrdering_TestFixture
{
EnchantBrokerFileSetOrdering_TestFixture()
{
if(_broker){ // this is now freed so that individual tests can set up the file state they
// need before calling _broker = enchant_broker_init ();
enchant_broker_free (_broker);
_broker = NULL;
}
}
static void WriteStringToOrderingFile(const std::string& path, const std::string& contents)
{
CreateDirectory(path);
std::ofstream file(AddToPath(path, "enchant.ordering").c_str());
file << contents;
}
};
/**
* enchant_broker_set_ordering
* @broker: A non-null #EnchantBroker
* @tag: A non-null language tag (en_US)
* @ordering: A non-null ordering (aspell,hunspell,hspell)
*
* Declares a preference of dictionaries to use for the language
* described/referred to by @tag. The ordering is a comma delimited
* list of provider names. As a special exception, the "*" tag can
* be used as a language tag to declare a default ordering for any
* language that does not explictly declare an ordering.
*/
/////////////////////////////////////////////////////////////////////////////
// Test Normal Operation
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_AsteriskForLanguage_SetsDefaultOrdering)
{
enchant_broker_set_ordering(_broker, "*", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
enchant_broker_set_ordering(_broker, "*", "mock1,mock2");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_NoSpaces)
{
enchant_broker_set_ordering(_broker, "qaa", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_WhitespaceAroundProvider)
{
enchant_broker_set_ordering(_broker, "qaa", "\n\f\t mock2\n \f\t,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_WhitespaceAroundProviderAfterComma)
{
enchant_broker_set_ordering(_broker, "qaa", "aspell,\n\f\t mock2\n\f \t,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
/* Vertical tab is not considered to be whitespace in glib!
See bug# 59388 http://bugzilla.gnome.org/show_bug.cgi?id=59388
*/
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_VerticalTabSurroundingProvider_NotRemoved)
{
enchant_broker_set_ordering(_broker, "qaa", "\vmock2,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
enchant_broker_set_ordering(_broker, "qaa", "mock2\v,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
enchant_broker_set_ordering(_broker, "qaa", "aspell,\vmock2,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
enchant_broker_set_ordering(_broker, "qaa", "aspell,mock2\v,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_SpecificLanguage_SetsOrderingForSpecific)
{
enchant_broker_set_ordering(_broker, "qaa", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
enchant_broker_set_ordering(_broker, "qaa", "mock1,mock2");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_UnknownProvider_Ignored)
{
enchant_broker_set_ordering(_broker, "qaa", "unknown,mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_WhitespaceSurroundingLanguageTag_Removed)
{
enchant_broker_set_ordering(_broker, "\n qaa \t\f", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
/* Vertical tab is not considered to be whitespace in glib!
See bug# 59388 http://bugzilla.gnome.org/show_bug.cgi?id=59388
*/
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_VerticalTabPrecedingLanguageTag_NotRemoved)
{
enchant_broker_set_ordering(_broker, "*", "mock1,mock2");
enchant_broker_set_ordering(_broker, "\vqaa", "mock2,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
/* Vertical tab is not considered to be whitespace in glib!
See bug# 59388 http://bugzilla.gnome.org/show_bug.cgi?id=59388
*/
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_VerticalTabFollowingLanguageTag_NotRemoved)
{
enchant_broker_set_ordering(_broker, "*", "mock1,mock2");
enchant_broker_set_ordering(_broker, "qaa\v", "mock2,mock1");
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_AtSignInLanguageTag_RemovesToTail)
{
enchant_broker_set_ordering(_broker, "en_GB@euro", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerDictExists_PeriodInLanguageTag_RemovesToTail)
{
enchant_broker_set_ordering(_broker, "en_GB.UTF-8", "unknown,mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_HyphensInLanguageTag_SubstitutedWithUnderscore)
{
enchant_broker_set_ordering(_broker, "en-GB", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_DifferentCaseInLanguageTag_SubstitutedWithCorrectCase)
{
enchant_broker_set_ordering(_broker, "EN-gb", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_DifferentCaseInLanguageTagNoRegion_SubstitutedWithCorrectCase)
{
enchant_broker_set_ordering(_broker, "QAA", "mock2,mock1");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_HasPreviousError_ErrorCleared)
{
SetErrorOnMockProvider("something bad happened");
enchant_broker_set_ordering(_broker, "qaa", "mock2,mock1");
CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
}
/////////////////////////////////////////////////////////////////////////////
// Test Error Conditions
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_NullBroker_DoNothing)
{
enchant_broker_set_ordering(_broker, "qaa", "mock2,mock1");
enchant_broker_set_ordering(NULL, "qaa", "mock1,mock2");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_NullLanguageTag_DoNothing)
{
enchant_broker_set_ordering(_broker, "*", "mock2,mock1");
enchant_broker_set_ordering(_broker, NULL, "mock1,mock2");
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_EmptyAfterNormalization_DoNothing)
{
enchant_broker_set_ordering(_broker, " @ ", "mock1,mock2");
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_EmptyLanguageTag_DoNothing)
{
enchant_broker_set_ordering(_broker, "", "aspell,hunspell");
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_NullOrdering_DoNothing)
{
enchant_broker_set_ordering(_broker, "en_GB", NULL);
}
TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
EnchantBrokerSetOrdering_EmptyOrdering_DoNothing)
{
enchant_broker_set_ordering(_broker, "en_GB", "");
}
// FIXME: This test passes trivially, as the providers mock1 and mock2 are
// added to the end of the providers list in any case. Change the tests so
// that we can detect whether they were explicitly called or not. This
// will allow us to add CHECKs to the foregoing tests as well.
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_CarriageReturnEndsLine_NotNeitherCalled)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:\rmock1,mock2");
InitializeBroker();
CHECK(ErrorNeitherCalled != GetProviderOrder("en_GB"));
}
/*
* Ordering can also be set in enchant.ordering file:
* Language_Tag : Provider1, Provider2, ProviderN
*
* See enchant(1) for details of how the file is located.
*/
/////////////////////////////////////////////////////////////////////////////
// Test Normal Operation
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrderingMock1ThenMock2_DefaultConfigDirectory)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock1,mock2");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrderingMock2ThenMock1_DefaultConfigDirectory)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock2,mock1");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrderingMock1ThenMock2_UserOverriddenConfigDirectory)
{
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock1,mock2");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrderingMock2ThenMock1_UserOverriddenConfigDirectory)
{
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock2,mock1");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ExtraSpacesAndTabs_Mock1Then2)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"\t en_GB\f \t:\t mock1\t , \tmock2\t ");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ExtraSpacesAndTabs_Mock2Then1)
{
WriteStringToOrderingFile(GetEnchantConfigDir()," \ten_GB\t \f: \tmock2 \t,\t mock1 \t");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ExtraNewLines_Mock1Then2)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"\nen_GB:mock1,mock2\n\nqaa:mock2,mock1\n*:mock2\n");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ExtraNewLines_Mock2Then1)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"\nen_GB:mock2,mock1\n\nqaa:mock2,mock1\n*:mock2\n");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_HomeAndGlobal_HomeMergedWithGlobal_HomeTakesPrecedence_Mock1Then2)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock2,mock1\nqaa:mock1,mock2");
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock1,mock2");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("qaa"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_HomeAndGlobal_HomeMergedWithGlobal_HomeTakesPrecedence_Mock2Then1)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock1,mock2\nqaa:mock2,mock1");
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock2,mock1");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
}
/////////////////////////////////////////////////////////////////////////////
// Test Error Conditions
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_EmptyFile)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"");
InitializeBroker();
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_NoLanguageTag)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),":mock1,mock2");
InitializeBroker();
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_NoColon)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB mock1,mock2");
InitializeBroker();
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_NoProviders_DoesNotOverridePreviousOrdering_Mock1Then2)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:");
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock1,mock2");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_NoProviders_DoesNotOverridePreviousOrdering_Mock2Then1)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:");
WriteStringToOrderingFile(GetTempUserEnchantDir(), "en_GB:mock2,mock1");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ListedTwice_LastTakesPrecedence_Mock1ThenMock2)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock2,mock1\nen_GB:mock1,mock2");
InitializeBroker();
CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
}
TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
EnchantBrokerFileOrdering_ListedTwice_LastTakesPrecedence_Mock2ThenMock1)
{
WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock1,mock2\nen_GB:mock2,mock1");
InitializeBroker();
CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
}