summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Albright <eric_albright@sil.org>2007-11-10 11:53:31 +0000
committerEric Albright <eric_albright@sil.org>2007-11-10 11:53:31 +0000
commitd2aaca3f5f0d943fcdc2f63f2f96316d5a906d6b (patch)
tree08a5254d6acdc3df15c27ec90a49e51f945e8d53
parente4a881d43f0f9001ab803ee9a9277816f5fea3e4 (diff)
downloadenchant-d2aaca3f5f0d943fcdc2f63f2f96316d5a906d6b.tar.gz
unit tests over enchant.c
git-svn-id: svn+ssh://svn.abisource.com/svnroot/enchant/trunk@22303 bcba8976-2d24-0410-9c9c-aab3bd5fdfd6
-rw-r--r--msvc/enchant.sln24
-rw-r--r--msvc/libenchant.vcproj4
-rw-r--r--msvc/libenchant_mock_provider.vcproj205
-rw-r--r--msvc/unittest-enchant.vcproj335
-rw-r--r--unittests/EnchantBrokerTestFixture.h388
-rw-r--r--unittests/EnchantDictionaryTestFixture.h206
-rw-r--r--unittests/EnchantTestFixture.h292
-rw-r--r--unittests/Readme.txt3
-rw-r--r--unittests/broker/enchant_broker_describe_tests.cpp274
-rw-r--r--unittests/broker/enchant_broker_dict_exists_tests.cpp148
-rw-r--r--unittests/broker/enchant_broker_dict_exists_tests.i143
-rw-r--r--unittests/broker/enchant_broker_free_dict_tests.cpp134
-rw-r--r--unittests/broker/enchant_broker_free_tests.cpp128
-rw-r--r--unittests/broker/enchant_broker_get_error_tests.cpp65
-rw-r--r--unittests/broker/enchant_broker_init_tests.cpp40
-rw-r--r--unittests/broker/enchant_broker_list_dicts_tests.cpp234
-rw-r--r--unittests/broker/enchant_broker_request_dict_tests.cpp216
-rw-r--r--unittests/broker/enchant_broker_request_pwl_dict_tests.cpp129
-rw-r--r--unittests/broker/enchant_broker_set_ordering_tests.cpp597
-rw-r--r--unittests/dictionary/enchant_dict_add_to_pwl_tests.cpp202
-rw-r--r--unittests/dictionary/enchant_dict_add_to_session_tests.cpp203
-rw-r--r--unittests/dictionary/enchant_dict_check_tests.cpp207
-rw-r--r--unittests/dictionary/enchant_dict_describe_tests.cpp140
-rw-r--r--unittests/dictionary/enchant_dict_free_string_list_tests.cpp95
-rw-r--r--unittests/dictionary/enchant_dict_get_error_tests.cpp70
-rw-r--r--unittests/dictionary/enchant_dict_is_in_session_tests.cpp115
-rw-r--r--unittests/dictionary/enchant_dict_store_replacement_tests.cpp214
-rw-r--r--unittests/dictionary/enchant_dict_suggest_tests.cpp391
-rw-r--r--unittests/main.cpp31
-rw-r--r--unittests/mock_provider/mock_provider.cpp108
-rw-r--r--unittests/mock_provider/mock_provider.h22
-rw-r--r--unittests/provider/enchant_provider_broker_set_error_tests.cpp93
-rw-r--r--unittests/provider/enchant_provider_dict_set_error_tests.cpp86
-rw-r--r--unittests/provider/enchant_provider_get_prefix_dir_tests.cpp68
-rw-r--r--unittests/provider/enchant_provider_get_registry_value_tests.cpp180
-rw-r--r--unittests/provider/enchant_provider_get_user_home_dir_tests.cpp81
-rw-r--r--unittests/provider/enchant_provider_get_user_language_tests.cpp88
37 files changed, 5959 insertions, 0 deletions
diff --git a/msvc/enchant.sln b/msvc/enchant.sln
index 88cab47..6cbeef2 100644
--- a/msvc/enchant.sln
+++ b/msvc/enchant.sln
@@ -105,6 +105,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "enchant-lsmod", "enchant-ls
{E0DB6274-F44C-48E6-AE30-C00D59864569} = {E0DB6274-F44C-48E6-AE30-C00D59864569}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-enchant", "unittest-enchant.vcproj", "{44BF74D0-5462-4A3B-8768-61E0DEF81B7B}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
+ ProjectSection(ProjectDependencies) = postProject
+ {E0DB6274-F44C-48E6-AE30-C00D59864569} = {E0DB6274-F44C-48E6-AE30-C00D59864569}
+ {A8F1C09A-A244-441B-804C-635106305056} = {A8F1C09A-A244-441B-804C-635106305056}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libenchant_mock_provider", "libenchant_mock_provider.vcproj", "{A8F1C09A-A244-441B-804C-635106305056}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -151,6 +167,14 @@ Global
{8B0F0A17-CEB4-42DF-B97E-375C60DB31E7}.Debug|Win32.Build.0 = Debug|Win32
{8B0F0A17-CEB4-42DF-B97E-375C60DB31E7}.Release|Win32.ActiveCfg = Release|Win32
{8B0F0A17-CEB4-42DF-B97E-375C60DB31E7}.Release|Win32.Build.0 = Release|Win32
+ {44BF74D0-5462-4A3B-8768-61E0DEF81B7B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {44BF74D0-5462-4A3B-8768-61E0DEF81B7B}.Debug|Win32.Build.0 = Debug|Win32
+ {44BF74D0-5462-4A3B-8768-61E0DEF81B7B}.Release|Win32.ActiveCfg = Release|Win32
+ {44BF74D0-5462-4A3B-8768-61E0DEF81B7B}.Release|Win32.Build.0 = Release|Win32
+ {A8F1C09A-A244-441B-804C-635106305056}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A8F1C09A-A244-441B-804C-635106305056}.Debug|Win32.Build.0 = Debug|Win32
+ {A8F1C09A-A244-441B-804C-635106305056}.Release|Win32.ActiveCfg = Release|Win32
+ {A8F1C09A-A244-441B-804C-635106305056}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/msvc/libenchant.vcproj b/msvc/libenchant.vcproj
index fd1acd1..e12f1b1 100644
--- a/msvc/libenchant.vcproj
+++ b/msvc/libenchant.vcproj
@@ -92,6 +92,8 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ Description="Copy dependencies"
+ CommandLine="copy &quot;$(SolutionDir)..\lib\glib\*.dll&quot; &quot;$(OutDir)\&quot;"
/>
</Configuration>
<Configuration
@@ -171,6 +173,8 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ Description="Copy dependencies"
+ CommandLine="copy &quot;$(SolutionDir)..\lib\glib\*.dll&quot; &quot;$(OutDir)\&quot;"
/>
</Configuration>
</Configurations>
diff --git a/msvc/libenchant_mock_provider.vcproj b/msvc/libenchant_mock_provider.vcproj
new file mode 100644
index 0000000..07cfbf6
--- /dev/null
+++ b/msvc/libenchant_mock_provider.vcproj
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libenchant_mock_provider"
+ ProjectGUID="{A8F1C09A-A244-441B-804C-635106305056}"
+ RootNamespace="libenchant_mock_provider"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(TargetName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(SolutionDir)..\lib\glib\include\glib-2.0&quot;;&quot;$(SolutionDir)..\src&quot;;"
+ PreprocessorDefinitions="HAVE_CONFIG_H;_ENCHANT_BUILD=1;WIN32;_DEBUG;_USRDLL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="&quot;$(SolutionDir)..\lib\glib\lib&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(TargetName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(SolutionDir)..\lib\glib\include\glib-2.0&quot;;&quot;$(SolutionDir)..\src&quot;;"
+ PreprocessorDefinitions="HAVE_CONFIG_H;_ENCHANT_BUILD=1;WIN32;NDEBUG;_USRDLL"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="&quot;$(SolutionDir)..\lib\glib\lib&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\unittests\mock_provider\mock_provider.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\unittests\mock_provider\mock_provider.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/msvc/unittest-enchant.vcproj b/msvc/unittest-enchant.vcproj
new file mode 100644
index 0000000..b7e9420
--- /dev/null
+++ b/msvc/unittest-enchant.vcproj
@@ -0,0 +1,335 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="unittest-enchant"
+ ProjectGUID="{44BF74D0-5462-4A3B-8768-61E0DEF81B7B}"
+ RootNamespace="unittest-enchant"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(TargetName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ CommandLine=""
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(SolutionDir)..\lib\UnitTest++\src&quot;;&quot;$(SolutionDir)..\lib\glib\include\glib-2.0&quot;;&quot;$(SolutionDir)..\src&quot;;"
+ PreprocessorDefinitions="HAVE_CONFIG_H;VERSION=\&quot;1.3.1\&quot;;WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib UnitTest++.vsnet2005.lib shlwapi.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="&quot;$(SolutionDir)..\lib\glib\lib&quot;; &quot;$(SolutionDir)..\lib\UnitTest++\$(ConfigurationName)&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Run All Tests"
+ CommandLine="&quot;$(TargetPath)&quot;"
+ ExcludedFromBuild="false"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(TargetName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="&quot;$(SolutionDir)..\lib\UnitTest++\src&quot;;&quot;$(SolutionDir)..\lib\glib\include\glib-2.0&quot;;&quot;$(SolutionDir)..\src&quot;;"
+ PreprocessorDefinitions="HAVE_CONFIG_H;VERSION=\&quot;1.3.1\&quot;;WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib UnitTest++.vsnet2005.lib shlwapi.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="&quot;$(SolutionDir)..\lib\glib\lib&quot;; &quot;$(SolutionDir)..\lib\UnitTest++\$(ConfigurationName)&quot;"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Run All Tests"
+ CommandLine="&quot;$(TargetPath)&quot;&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\unittests\main.cpp"
+ >
+ </File>
+ <Filter
+ Name="broker"
+ >
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_describe_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_dict_exists_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_dict_exists_tests.i"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_free_dict_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_free_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_get_error_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_init_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_list_dicts_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_request_dict_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_request_pwl_dict_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\broker\enchant_broker_set_ordering_tests.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="dictionary"
+ >
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_add_to_pwl_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_add_to_session_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_check_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_describe_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_free_string_list_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_get_error_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_is_in_session_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_store_replacement_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\dictionary\enchant_dict_suggest_tests.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="provider"
+ >
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_broker_set_error_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_dict_set_error_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_get_prefix_dir_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_get_registry_value_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_get_user_home_dir_tests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\provider\enchant_provider_get_user_language_tests.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\unittests\EnchantBrokerTestFixture.h"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\EnchantDictionaryTestFixture.h"
+ >
+ </File>
+ <File
+ RelativePath="..\unittests\EnchantTestFixture.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/unittests/EnchantBrokerTestFixture.h b/unittests/EnchantBrokerTestFixture.h
new file mode 100644
index 0000000..f91d681
--- /dev/null
+++ b/unittests/EnchantBrokerTestFixture.h
@@ -0,0 +1,388 @@
+/* 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.
+ */
+
+#ifndef __ENCHANTBROKERTESTFIXTURE
+#define __ENCHANTBROKERTESTFIXTURE
+
+#if defined(_MSC_VER)
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4505) //unreferenced local function has been removed
+#pragma warning(disable: 4996) //The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name.
+#endif
+
+#include "EnchantTestFixture.h"
+#include "mock_provider/mock_provider.h"
+#include <stack>
+#include <stdio.h>
+#include <io.h>
+#include <direct.h>
+
+#if !defined(_WIN32)
+#if !defined(O_BINARY)
+#define O_BINARY 0 // Posix systems don'd distinguish between text and binary so define O_BINARY for compatibility
+#endif
+#endif
+
+//////////////////////////////////////
+// Mock provider functions
+static void
+MockProviderDispose(EnchantProvider *me)
+{
+ g_free(me);
+}
+
+static int
+MockEnGbAndQaaProviderDictionaryExists (EnchantProvider *,
+ const char *const tag)
+{
+ return (strcmp(tag, "en_GB")==0 || strcmp(tag, "qaa") ==0);
+}
+
+
+static EnchantDict*
+MockEnGbAndQaaProviderRequestDictionary(EnchantProvider * me, const char *tag)
+{
+ EnchantDict *dict = NULL;
+
+ if(MockEnGbAndQaaProviderDictionaryExists(me, tag)){
+ dict = g_new0 (EnchantDict, 1);
+ }
+ return dict;
+}
+
+static void
+MockProviderDisposeDictionary (EnchantProvider *, EnchantDict * dict)
+{
+ g_free(dict);
+}
+
+static char *
+MockProviderIdentify (EnchantProvider *)
+{
+ return "mock";
+}
+
+static char *
+MockProviderDescribe (EnchantProvider *)
+{
+ return "Mock Provider";
+}
+
+static char **
+MockEnGbAndQaaProviderListDictionaries (EnchantProvider *,
+ size_t * out_n_dicts)
+{
+ *out_n_dicts = 2;
+ char** out_list = g_new0 (char *, *out_n_dicts + 1);
+ out_list[0] = g_strdup ("en_GB");
+ out_list[1] = g_strdup ("qaa");
+
+ return out_list;
+}
+
+static char **
+MockEnGbProviderListDictionaries (EnchantProvider *,
+ size_t * out_n_dicts)
+{
+ *out_n_dicts = 1;
+ char** out_list = g_new0 (char *, *out_n_dicts + 1);
+ out_list[0] = g_strdup ("en_GB");
+
+ return out_list;
+}
+
+static void
+MockProviderFreeStringList (EnchantProvider *, char **str_list)
+{
+ g_strfreev (str_list);
+}
+
+typedef void (*SET_CONFIGURE)(ConfigureHook);
+
+struct EnchantBrokerTestFixture : EnchantTestFixture
+{
+ EnchantBroker* _broker;
+ HMODULE hModule, hModule2;
+
+ //Setup
+ EnchantBrokerTestFixture(ConfigureHook userConfiguration=NULL,
+ ConfigureHook user2Configuration=NULL,
+ bool includeNullProviders = false)
+ {
+ CleanUpFiles(); //just in case we stopped the process in the middle.
+
+ userMockProviderConfiguration = userConfiguration;
+ userMockProvider2Configuration = user2Configuration;
+
+#if _WIN32
+ CopyProvider("libenchant_mock_provider", "libenchant_mock_provider");
+ hModule = LoadLibrary(L"lib\\enchant\\libenchant_mock_provider.dll");
+ if(hModule!=NULL){
+ SET_CONFIGURE sc = (SET_CONFIGURE) GetProcAddress(hModule, "set_configure");
+ (sc)(ConfigureMockProvider);
+ }
+
+ hModule2 = NULL;
+ if(user2Configuration != NULL){
+ CopyProvider("libenchant_mock_provider", "libenchant_mock_provider2");
+ hModule2 = LoadLibrary(L"lib\\enchant\\libenchant_mock_provider2.dll");
+ if(hModule2!=NULL){
+ SET_CONFIGURE sc = (SET_CONFIGURE) GetProcAddress(hModule2, "set_configure");
+ (sc)(ConfigureMockProvider2);
+ }
+ }
+#else
+ // What to do?
+#endif
+
+ if(includeNullProviders){
+ CopyProvider("libenchant_mock_provider", "null_provider");
+ CopyProvider("libenchant_mock_provider", "null_identify");
+ CopyProvider("libenchant_mock_provider", "null_describe");
+ CopyProvider("libenchant", "libenchant"); //not a provider
+ }
+
+ SetRegistryHomeDir(GetDirectoryOfThisModule());
+ InitializeBroker();
+ }
+
+ //Teardown
+ ~EnchantBrokerTestFixture(){
+#if _WIN32
+ if(hModule!=NULL){
+ FreeLibrary(hModule);
+ }
+ if(hModule2!=NULL){
+ FreeLibrary(hModule2);
+ }
+#endif
+
+ if(_broker){
+ enchant_broker_free (_broker);
+ }
+ while(!pwlFilenames.empty())
+ {
+ DeleteFile(pwlFilenames.top());
+ pwlFilenames.pop();
+ }
+ CleanUpFiles();
+ }
+
+ void InitializeBroker()
+ {
+ _broker = enchant_broker_init ();
+ }
+
+ void CleanUpFiles()
+ {
+ //clean up personal dictionaries from home dir
+ DeleteDirAndFiles(GetEnchantPersonalDir());
+ DeleteDirAndFiles(AddToPath(GetDirectoryOfThisModule(), "lib"));
+ DeleteDirAndFiles(AddToPath(GetDirectoryOfThisModule(), "share"));
+ }
+
+ void CopyProvider(const std::string& sourceProviderName, const std::string& destinationProviderName)
+ {
+ std::string sourceName = sourceProviderName +"."+ G_MODULE_SUFFIX;
+ std::string destinationName = destinationProviderName + "." +G_MODULE_SUFFIX;
+
+ std::string destinationDir = AddToPath(AddToPath(GetDirectoryOfThisModule(), "lib"),"enchant");
+
+ CreateDirectory(destinationDir);
+
+ std::string destinationPath = AddToPath(destinationDir, destinationName);
+
+ gchar * contents;
+ gsize length;
+ if(g_file_get_contents(AddToPath(GetDirectoryOfThisModule(), sourceName).c_str(),
+ &contents,
+ &length,
+ NULL)){
+ g_file_set_contents(destinationPath.c_str(),
+ contents,
+ length,
+ NULL);
+ }
+ }
+
+ std::string GetEnchantPersonalDir()
+ {
+ return AddToPath(GetDirectoryOfThisModule(), ".enchant");
+ }
+
+ std::string GetEnchantConfigDir()
+ {
+ return AddToPath(AddToPath(GetDirectoryOfThisModule(), "share"), "enchant");
+ }
+
+ static std::string AddToPath(const std::string & path, const std::string & fileOrDirName)
+ {
+ std::string result;
+ gchar* filename = g_build_filename(path.c_str(), fileOrDirName.c_str(), NULL);
+ result = std::string(filename);
+ g_free(filename);
+
+ return result;
+ }
+
+ EnchantProvider* GetMockProvider(){
+ return mock_provider;
+ }
+
+ void SetErrorOnMockProvider(const std::string& error)
+ {
+ EnchantProvider* provider = GetMockProvider();
+ if(provider != NULL)
+ {
+ enchant_provider_set_error(provider, error.c_str());
+ }
+ }
+
+ EnchantDict* RequestDictionary(const std::string& tag){
+ return enchant_broker_request_dict(_broker, tag.c_str());
+ }
+
+ static std::string GetTemporaryFilename(const std::string & extension){
+ char* tempFileName = tempnam(".", extension.c_str());
+ std::string temp(tempFileName);
+ free(tempFileName);
+ return temp;
+ }
+
+ static void CreateDirectory(const std::string& filepath)
+ {
+ g_mkdir_with_parents(filepath.c_str(), S_IREAD | S_IWRITE | S_IEXEC);
+ }
+ static void CreateFile(const std::string& filepath)
+ {
+ g_creat(filepath.c_str(), _S_IREAD | _S_IWRITE);
+ }
+ static void DeleteFile(const std::string& filepath)
+ {
+ if(FileExists(filepath)){
+ g_remove(filepath.c_str());
+ }
+ }
+ static bool FileExists(const std::string& filepath)
+ {
+ return(g_access(filepath.c_str(), 0)==0);
+ }
+ static void DeleteDirAndFiles(const std::string& dir)
+ {
+ GDir* gdir = g_dir_open(dir.c_str(), 0, NULL);
+ if(gdir != NULL)
+ {
+ const gchar* filename;
+ for(;;){
+ filename = g_dir_read_name(gdir);
+ if(filename == NULL)
+ {
+ break;
+ }
+ std::string filepath = AddToPath(dir, filename);
+ if(g_file_test(filename, G_FILE_TEST_IS_DIR)){
+ DeleteDirAndFiles(filepath);
+ }
+ else {
+ DeleteFile(filepath);
+ }
+ }
+ g_dir_close(gdir);
+ }
+ g_rmdir(dir.c_str());
+ }
+
+ EnchantDict* RequestPersonalDictionary(){
+ std::string pwlFileName = GetTemporaryFilename("epwl");
+ CreateFile(pwlFileName);
+ pwlFilenames.push(pwlFileName);
+ return enchant_broker_request_pwl_dict(_broker, pwlFileName.c_str());
+ }
+
+ void FreeDictionary(EnchantDict* dictionary){
+ if(dictionary != NULL){
+ enchant_broker_free_dict(_broker, dictionary);
+ }
+ }
+
+ private:
+ std::stack<std::string> pwlFilenames;
+ static EnchantProvider * mock_provider;
+ static ConfigureHook userMockProviderConfiguration;
+ static ConfigureHook userMockProvider2Configuration;
+ static void ConfigureMockProvider (EnchantProvider * me, const char * dir_name)
+ {
+ mock_provider = me;
+ if(userMockProviderConfiguration){
+ userMockProviderConfiguration(me, dir_name);
+ }
+ }
+
+ static void ConfigureMockProvider2 (EnchantProvider * me, const char * dir_name)
+ {
+ mock_provider = me;
+ if(userMockProvider2Configuration){
+ userMockProvider2Configuration(me, dir_name);
+ }
+ }
+
+};
+
+struct DictionaryDescription
+{
+ std::string LanguageTag;
+ std::string Name;
+ std::string Description;
+ std::string DllFile;
+ DictionaryDescription()
+ {}
+ DictionaryDescription(const char* const language_tag,
+ const char * const provider_name,
+ const char * const provider_desc,
+ const char * const provider_file):
+ LanguageTag(language_tag),
+ Name(provider_name),
+ Description(provider_desc),
+ DllFile(provider_file)
+ {}
+
+ DictionaryDescription(const DictionaryDescription& d):
+ LanguageTag(d.LanguageTag),
+ Name(d.Name),
+ Description(d.Description),
+ DllFile(d.DllFile)
+ {}
+
+ bool DataIsComplete()
+ {
+ return (LanguageTag.length() &&
+ Name.length() &&
+ Description.length() &&
+ DllFile.length());
+ }
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif \ No newline at end of file
diff --git a/unittests/EnchantDictionaryTestFixture.h b/unittests/EnchantDictionaryTestFixture.h
new file mode 100644
index 0000000..e380cbc
--- /dev/null
+++ b/unittests/EnchantDictionaryTestFixture.h
@@ -0,0 +1,206 @@
+/* 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.
+ */
+
+#ifndef __ENCHANTDICTIONARYTESTFIXTURE
+#define __ENCHANTDICTIONARYTESTFIXTURE
+
+#if defined(_MSC_VER)
+#pragma once
+#pragma warning(push)
+#pragma warning(disable: 4996) //The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name.
+#endif
+
+#include "../EnchantBrokerTestFixture.h"
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static EnchantDict*
+MockProviderRequestEmptyMockDictionary(EnchantProvider *, const char *)
+{
+ EnchantDict* dict = g_new0(EnchantDict, 1);
+ dict->user_data = NULL;
+ dict->check = NULL;
+ dict->suggest = NULL;
+ dict->add_to_personal = NULL;
+ dict->add_to_session = NULL;
+ dict->store_replacement = NULL;
+
+ return dict;
+}
+
+static void EmptyDictionary_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestEmptyMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+
+static char**
+MockDictionarySuggest (EnchantDict * ,
+ const char *const word,
+ size_t len,
+ size_t * out_n_suggs)
+{
+ char **sugg_arr = NULL;
+
+ *out_n_suggs = 4;
+
+ sugg_arr = g_new0 (char *, *out_n_suggs + 1);
+ for(size_t i=0; i<*out_n_suggs;++i){
+ if(len == -1) {
+ sugg_arr[i] = g_strdup (word);
+ }
+ else {
+ sugg_arr[i] = g_strndup (word, (gsize)len);
+ }
+ sugg_arr[i][0] = 'a' + (char)i;
+ }
+ return sugg_arr;
+}
+
+static EnchantDict*
+MockProviderRequestBasicMockDictionary(EnchantProvider *me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->suggest = MockDictionarySuggest;
+ return dict;
+}
+
+
+static void BasicDictionary_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestBasicMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ me->free_string_list = MockProviderFreeStringList;
+}
+
+struct EnchantDictionaryTestFixture : EnchantBrokerTestFixture
+{
+ EnchantDict* _dict;
+ EnchantDict* _pwl;
+ std::string origLangEnv;
+ bool hasLangEnv;
+ std::string languageTag;
+
+ //Setup
+ EnchantDictionaryTestFixture(ConfigureHook userConfiguration=BasicDictionary_ProviderConfiguration, const std::string& languageTag="qaa"):
+ EnchantBrokerTestFixture(userConfiguration),
+ languageTag(languageTag)
+ {
+ InitializeTestDictionary();
+ _pwl = RequestPersonalDictionary();
+
+ bool hasLangEnv = (g_getenv("LANG") != NULL);
+ if(hasLangEnv)
+ {
+ origLangEnv = std::string(g_getenv("LANG"));
+ }
+ }
+
+ //Teardown
+ ~EnchantDictionaryTestFixture(){
+ FreeTestDictionary();
+ FreeDictionary(_pwl);
+ ResetLocale();
+ }
+
+ void SetLocale(const std::string& locale)
+ {
+ g_setenv("LANG", locale.c_str(), TRUE);
+ }
+
+ void ResetLocale()
+ {
+ if(hasLangEnv)
+ {
+ g_setenv("LANG", origLangEnv.c_str(), TRUE);
+ }
+ else{
+ g_unsetenv("LANG");
+ }
+ }
+
+ void ReloadTestDictionary()
+ {
+ FreeTestDictionary();
+ InitializeTestDictionary();
+ }
+
+ void InitializeTestDictionary()
+ {
+ _dict = enchant_broker_request_dict(_broker, languageTag.c_str());
+ }
+
+ void FreeTestDictionary()
+ {
+ FreeDictionary(_dict);
+ }
+
+ bool PersonalWordListFileHasContents()
+ {
+ bool hasContents = false;
+ int fd = open(GetPersonalDictFileName().c_str(), O_RDONLY);
+ if(fd == -1){
+ return false;
+ }
+
+ char c;
+ if(read(fd, &c, 1) == 1){
+ hasContents = true;
+ }
+ close(fd);
+
+ return hasContents;
+ }
+
+ std::string GetPersonalDictFileName(){
+ return AddToPath(GetEnchantPersonalDir(), "qaa.dic");
+ }
+
+ void SetErrorOnMockDictionary(const std::string& error)
+ {
+ enchant_dict_set_error(_dict, error.c_str());
+ }
+
+ void FreeStringList(char** list)
+ {
+ if(list)
+ {
+ enchant_dict_free_string_list(_dict, list);
+ }
+ }
+
+ bool IsWordInSession(const std::string& word){
+ return enchant_dict_is_in_session(_dict, word.c_str(), word.size())!=0;
+ }
+
+ bool IsWordInDictionary(const std::string& word){
+ return enchant_dict_check(_dict, word.c_str(), word.size())==0;
+ }
+};
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif \ No newline at end of file
diff --git a/unittests/EnchantTestFixture.h b/unittests/EnchantTestFixture.h
new file mode 100644
index 0000000..e01a634
--- /dev/null
+++ b/unittests/EnchantTestFixture.h
@@ -0,0 +1,292 @@
+/* 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.
+ */
+
+#ifndef __ENCHANTTESTFIXTURE
+#define __ENCHANTTESTFIXTURE
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <shlwapi.h>
+#endif
+
+#include <glib.h>
+#include <string>
+
+struct EnchantTestFixture
+{
+ std::string savedRegistryHomeDir;
+ std::string savedUserRegistryModuleDir;
+ std::string savedMachineRegistryModuleDir;
+ std::string savedUserRegistryConfigDir;
+ std::string savedMachineRegistryConfigDir;
+
+ //Setup
+ EnchantTestFixture()
+ {
+#ifdef _WIN32
+ savedRegistryHomeDir = GetRegistryHomeDir();
+ ClearRegistryHomeDir();
+
+ savedUserRegistryModuleDir = GetUserRegistryModuleDir();
+ ClearUserRegistryModuleDir();
+
+ savedMachineRegistryModuleDir = GetMachineRegistryModuleDir();
+ ClearMachineRegistryModuleDir();
+
+ savedUserRegistryConfigDir = GetUserRegistryConfigDir();
+ ClearUserRegistryConfigDir();
+
+ savedMachineRegistryConfigDir = GetMachineRegistryConfigDir();
+ ClearMachineRegistryConfigDir();
+#endif
+ }
+
+ //Teardown
+ ~EnchantTestFixture(){
+#ifdef _WIN32
+ if(savedRegistryHomeDir.empty()) {
+ ClearRegistryHomeDir();
+ }
+ else {
+ SetRegistryHomeDir(savedRegistryHomeDir);
+ }
+
+ if(savedUserRegistryModuleDir.empty()) {
+ ClearUserRegistryModuleDir();
+ }
+ else{
+ SetUserRegistryModuleDir(savedUserRegistryModuleDir);
+ }
+
+ if(savedMachineRegistryModuleDir.empty())
+ {
+ ClearMachineRegistryModuleDir();
+ }
+ else{
+ SetMachineRegistryModuleDir(savedMachineRegistryModuleDir);
+ }
+
+ if(savedUserRegistryConfigDir.empty())
+ {
+ ClearUserRegistryConfigDir();
+ }
+ else{
+ SetUserRegistryConfigDir(savedUserRegistryConfigDir);
+ }
+
+ if(savedMachineRegistryConfigDir.empty()) {
+ ClearMachineRegistryConfigDir();
+ }
+ else {
+ SetMachineRegistryConfigDir(savedMachineRegistryConfigDir);
+ }
+#endif
+ }
+
+ std::string Convert(const std::wstring & ws)
+ {
+ gchar* str = g_utf16_to_utf8((gunichar2*)ws.c_str(), (glong)ws.length(), NULL, NULL, NULL);
+ std::string s(str);
+ g_free(str);
+ return s;
+ }
+
+ std::wstring Convert(const std::string & s)
+ {
+ gunichar2* str = g_utf8_to_utf16(s.c_str(), (glong)s.length(), NULL, NULL, NULL);
+ std::wstring ws((wchar_t*)str);
+ g_free(str);
+ return ws;
+ }
+
+ std::string GetDirectoryOfThisModule()
+ {
+ std::string result;
+#if defined(_WIN32)
+ // should be in the same directory as our test fixture
+ WCHAR szFilename[MAX_PATH];
+ GetModuleFileName(NULL, (LPWSTR) &szFilename, sizeof(szFilename));
+ PathRemoveFileSpec((LPWSTR)&szFilename);
+
+ result = Convert(szFilename);
+#elif defined(ENABLE_BINRELOC)
+ gchar* prefix = gbr_find_prefix(NULL);
+ result = std::string(prefix);
+ g_free(prefix);
+#endif
+ return result;
+ }
+
+ std::string GetRegistryHomeDir()
+ {
+ return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir"));
+ }
+
+ void SetRegistryHomeDir(const std::string & dir)
+ {
+ SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir", dir);
+ }
+
+ void ClearRegistryHomeDir()
+ {
+ ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir");
+ }
+
+ std::string GetUserRegistryModuleDir()
+ {
+ return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir"));
+
+ }
+
+ void SetUserRegistryModuleDir(const std::string & dir)
+ {
+ SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir", dir);
+ }
+
+ void ClearUserRegistryModuleDir()
+ {
+ ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir");
+ }
+
+ std::string GetMachineRegistryModuleDir()
+ {
+ return Convert(GetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir"));
+
+ }
+
+ void SetMachineRegistryModuleDir(const std::string & dir)
+ {
+ SetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir", dir);
+ }
+
+ void ClearMachineRegistryModuleDir()
+ {
+ ClearRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir");
+ }
+
+ std::string GetUserRegistryConfigDir()
+ {
+ return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir"));
+ }
+
+ void SetUserRegistryConfigDir(const std::string & dir)
+ {
+ SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir", dir);
+ }
+
+ void ClearUserRegistryConfigDir()
+ {
+ ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir");
+ }
+
+ std::string GetMachineRegistryConfigDir()
+ {
+ return Convert(GetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir"));
+ }
+
+ void SetMachineRegistryConfigDir(const std::string & dir)
+ {
+ SetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir", dir);
+ }
+
+ void ClearMachineRegistryConfigDir()
+ {
+ ClearRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir");
+ }
+
+ std::wstring GetRegistryValue(HKEY baseKey, const std::wstring& key, const std::wstring& valueName)
+ {
+ std::wstring result;
+
+ WCHAR data[2048];
+ DWORD dwSize = sizeof(data) * sizeof(WCHAR);
+ HKEY hkey;
+
+ if(RegOpenKeyEx(baseKey,
+ key.c_str(),
+ 0, KEY_WRITE, &hkey) == ERROR_SUCCESS)
+ {
+ if(RegQueryValueEx(hkey,
+ valueName.c_str(),
+ 0,
+ NULL,
+ (LPBYTE)&data, &dwSize)
+ == ERROR_SUCCESS){
+ result = std::wstring(data,dwSize);
+ }
+ }
+ return result;
+ }
+
+ void SetRegistryValue(HKEY baseKey,
+ const std::wstring& key,
+ const std::wstring& valueName,
+ const std::string& value)
+ {
+ SetRegistryValue(baseKey, key, valueName, Convert(value));
+ }
+ void SetRegistryValue(HKEY baseKey,
+ const std::wstring& key,
+ const std::wstring& valueName,
+ const std::wstring& value)
+ {
+ HKEY hkey;
+ if(RegCreateKeyEx(baseKey,
+ key.c_str(),
+ 0, NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_WRITE,
+ NULL, &hkey,
+ NULL) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hkey,
+ valueName.c_str(),
+ 0,
+ REG_SZ,
+ (LPBYTE)value.c_str(),
+ (DWORD)((value.length()+1)*sizeof(wchar_t)) );
+
+ RegCloseKey(hkey);
+ }
+ }
+
+ void ClearRegistryValue(HKEY baseKey,
+ const std::wstring& key,
+ const std::wstring& valueName)
+ {
+ HKEY hkey;
+ if(RegOpenKeyEx(baseKey,
+ key.c_str(),
+ 0, KEY_WRITE, &hkey) == ERROR_SUCCESS)
+ {
+ RegDeleteValue(hkey, valueName.c_str());
+ RegCloseKey(hkey);
+ }
+ }
+
+};
+
+#endif \ No newline at end of file
diff --git a/unittests/Readme.txt b/unittests/Readme.txt
new file mode 100644
index 0000000..e3a6319
--- /dev/null
+++ b/unittests/Readme.txt
@@ -0,0 +1,3 @@
+Enchant Unit Tests are written using the UnitTest++ framework.
+
+See http://unittest-cpp.sourceforge.net/ for more details.
diff --git a/unittests/broker/enchant_broker_describe_tests.cpp b/unittests/broker/enchant_broker_describe_tests.cpp
new file mode 100644
index 0000000..677e6ec
--- /dev/null
+++ b/unittests/broker/enchant_broker_describe_tests.cpp
@@ -0,0 +1,274 @@
+/* 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()
+ {
+#ifdef _WIN32
+ SetRegistryHomeDir("someplace_that_does_not_exist");
+ SetUserRegistryModuleDir("someplace_that_does_not_exist");
+#endif
+ _broker = enchant_broker_init ();
+ }
+
+ //Teardown
+ ~EnchantBrokerNoProvidersTestFixture()
+ {
+ enchant_broker_free (_broker);
+ }
+
+ EnchantBroker* _broker;
+ std::vector<ProviderDescription> _providerList;
+};
+
+static 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;
+ }
+};
+
+/**
+ * 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.
+ *
+ * The user's home directory on windows can be overridden using the registry
+ * setting HKEY_CURRENT_USER\Software\Enchant\Config\Home_Dir
+ *
+ * Then from the module directory (that libenchant is in).
+ *
+ * The module directory can be overridden using the registry setting
+ * HKEY_CURRENT_USER\Software\Enchant\Config\Module_Dir
+ * or HKEY_LOCAL_MACHINE\Software\Enchant\Config\Module_Dir
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// 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 = "hello world";
+
+ enchant_broker_describe(_broker,
+ EnchantBrokerDescribeAssignUserDataToStaticCallback,
+ NULL);
+ CHECK_EQUAL((void*)NULL, global_user_data);
+}
+
+TEST_FIXTURE(EnchantBrokerDescribeTestFixture,
+ EnchantBrokerDescribe_NonNullUserData_PassedThroughToCallback)
+{
+ char* data = "some data";
+ global_user_data = NULL;
+ enchant_broker_describe(_broker,
+ EnchantBrokerDescribeAssignUserDataToStaticCallback,
+ 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)));
+} \ No newline at end of file
diff --git a/unittests/broker/enchant_broker_dict_exists_tests.cpp b/unittests/broker/enchant_broker_dict_exists_tests.cpp
new file mode 100644
index 0000000..819bb12
--- /dev/null
+++ b/unittests/broker/enchant_broker_dict_exists_tests.cpp
@@ -0,0 +1,148 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+
+static int dictionaryExistsCalled;
+static int DoesDictionaryExist (EnchantProvider * me, const char *const tag)
+{
+ dictionaryExistsCalled++;
+ return MockEnGbAndQaaProviderDictionaryExists(me, tag);
+}
+
+static void Dictionary_Exists_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->dictionary_exists=DoesDictionaryExist;
+}
+
+struct EnchantBrokerDictExists_ProviderImplementsDictionaryExist_TestFixture : EnchantBrokerTestFixture{
+ //Setup
+ EnchantBrokerDictExists_ProviderImplementsDictionaryExist_TestFixture():
+ EnchantBrokerTestFixture(Dictionary_Exists_ProviderConfiguration)
+ { dictionaryExistsCalled=0; }
+};
+
+#define EnchantBrokerDictExistsTestFixture EnchantBrokerDictExists_ProviderImplementsDictionaryExist_TestFixture
+#define DictionaryExistsMethodCalled dictionaryExistsCalled
+#include "enchant_broker_dict_exists_tests.i"
+
+static int listDictionariesCalled;
+static char** ListDictionaries (EnchantProvider * me, size_t * out_n_dicts)
+{
+ listDictionariesCalled++;
+
+ return MockEnGbAndQaaProviderListDictionaries(me, out_n_dicts);
+}
+
+static void List_Dictionaries_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->list_dicts=ListDictionaries;
+ me->free_string_list = MockProviderFreeStringList;
+}
+
+struct EnchantBrokerDictExists_ProviderImplementsListDictionaries_TestFixture : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerDictExists_ProviderImplementsListDictionaries_TestFixture():
+ EnchantBrokerTestFixture(List_Dictionaries_ProviderConfiguration)
+ {
+ listDictionariesCalled = 0;
+ }
+
+};
+
+#undef EnchantBrokerDictExistsTestFixture
+#define EnchantBrokerDictExistsTestFixture EnchantBrokerDictExists_ProviderImplementsListDictionaries_TestFixture
+#undef DictionaryExistsMethodCalled
+#define DictionaryExistsMethodCalled listDictionariesCalled
+#include "enchant_broker_dict_exists_tests.i"
+
+static int requestDictionaryCalled;
+static EnchantDict * RequestDictionary (EnchantProvider *me, const char *tag)
+{
+ requestDictionaryCalled++;
+ return MockEnGbAndQaaProviderRequestDictionary(me, tag);
+}
+
+static void Request_Dictionary_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = RequestDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+struct EnchantBrokerDictExists_ProviderImplementsRequestDictionary_TestFixture : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerDictExists_ProviderImplementsRequestDictionary_TestFixture():
+ EnchantBrokerTestFixture(Request_Dictionary_ProviderConfiguration)
+ {
+ requestDictionaryCalled = 0;
+ }
+};
+
+#undef EnchantBrokerDictExistsTestFixture
+#define EnchantBrokerDictExistsTestFixture EnchantBrokerDictExists_ProviderImplementsRequestDictionary_TestFixture
+#undef DictionaryExistsMethodCalled
+#define DictionaryExistsMethodCalled requestDictionaryCalled
+#include "enchant_broker_dict_exists_tests.i"
+
+static void ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = RequestDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ me->list_dicts = ListDictionaries;
+ me->free_string_list = MockProviderFreeStringList;
+ me->dictionary_exists = DoesDictionaryExist;
+}
+
+struct EnchantBrokerDictExists_ProviderImplementsAll_TestFixture : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerDictExists_ProviderImplementsAll_TestFixture():
+ EnchantBrokerTestFixture(ProviderConfiguration)
+ {
+ listDictionariesCalled = 0;
+ requestDictionaryCalled = 0;
+ dictionaryExistsCalled = 0;
+ }
+};
+
+TEST_FIXTURE(EnchantBrokerDictExists_ProviderImplementsAll_TestFixture,
+ EnchantBrokerDictExists_CalledWhenDictionaryIsInUse_DoesNotCallAnyMethods_GetsCachedResult)
+{
+ EnchantDict* dict = enchant_broker_request_dict(_broker, "en-GB");
+ requestDictionaryCalled = 0;
+
+ enchant_broker_dict_exists(_broker, "en-GB");
+ CHECK_EQUAL(0,listDictionariesCalled);
+ CHECK_EQUAL(0,requestDictionaryCalled);
+ CHECK_EQUAL(0,dictionaryExistsCalled);
+
+ enchant_broker_free_dict(_broker, dict);
+}
+
+TEST_FIXTURE(EnchantBrokerTestFixture,
+ EnchantBrokerDictExists_ProviderImplementsNoMethods_0)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "en_GB"));
+}
diff --git a/unittests/broker/enchant_broker_dict_exists_tests.i b/unittests/broker/enchant_broker_dict_exists_tests.i
new file mode 100644
index 0000000..7f9cc2b
--- /dev/null
+++ b/unittests/broker/enchant_broker_dict_exists_tests.i
@@ -0,0 +1,143 @@
+#ifndef EnchantBrokerDictExistsTestFixture
+#error EnchantBrokerDictExistsTestFixture must be defined as the testfixture class to run these tests against
+#endif
+
+#ifndef DictionaryExistsMethodCalled
+#error DictionaryExistsMethodCalled must be defined as the variable that is set when the method is called
+#endif
+
+/**
+ * enchant_broker_dict_exists
+ * @broker: A non-null #EnchantBroker
+ * @tag: The non-null language tag you wish to request a dictionary for ("en_US", "de_DE", ...)
+ *
+ * language tags are normalized by stripping leading and trailing whitespace,
+ * removing '@' and any trailing characters, removing '.' and any trailing characters,
+ * and replacing '-' with '_'
+ *
+ * If no providers have the given language tag, enchant will fallback to the language code
+ * prefix (everything before the first "_")
+ *
+ * Return existance of the requested dictionary (1 == true, 0 == false)
+ */
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_DictDoesNotExist_FalseOnlyAsksOnce)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "en"));
+ CHECK_EQUAL(1,DictionaryExistsMethodCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_DictExists_TrueAsksOnce)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "en_GB"));
+ CHECK_EQUAL(1,DictionaryExistsMethodCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_BaseDictExists_TrueAsksTwice)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "qaa_CA"));
+ CHECK_EQUAL(2,DictionaryExistsMethodCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_ExtraStuffAfterSecondUnderscore_NotStrippedForComparison)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "en_GB_special"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_WhitespaceSurroundingLanguageTag_Removed)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "\n\r en_GB \t\f"));
+}
+
+/* Vertical tab is not considered to be whitespace in glib!
+ See bug# 59388 http://bugzilla.gnome.org/show_bug.cgi?id=59388
+*/
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_VerticalTabSurroundingLanguageTag_NotRemoved)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "\ven_GB"));
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "en_GB\v"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_AtSignInLanguageTag_RemovesToTail)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "en_GB@euro"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_NothingLeftAfterNormalizingLanguageTag_DoesNotCallProvider)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists(_broker, "@euro"));
+ CHECK_EQUAL(0,DictionaryExistsMethodCalled);
+}
+
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_PeriodInLanguageTag_RemovesToTail)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "en_GB.UTF-8"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_HyphensInLanguageTag_SubstitutedWithUnderscore)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "en-GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_CalledWhenDictionaryIsNotInUse_MakesCall)
+{
+ DictionaryExistsMethodCalled = false;
+ enchant_broker_dict_exists(_broker, "en-GB");
+ CHECK_EQUAL(1,DictionaryExistsMethodCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_DifferentCase_Finds)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "EN_gb"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_DifferentCase_NoRegion_Finds)
+{
+ CHECK_EQUAL(1, enchant_broker_dict_exists(_broker, "QAA"));
+}
+
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockProvider("something bad happened");
+
+ enchant_broker_dict_exists(_broker, "en_US");
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_NullBroker_0)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists (NULL, "en_US"));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_NullTag_0)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists (_broker, NULL));
+}
+
+TEST_FIXTURE(EnchantBrokerDictExistsTestFixture,
+ EnchantBrokerDictExists_EmptyTag_0)
+{
+ CHECK_EQUAL(0, enchant_broker_dict_exists (_broker, ""));
+}
diff --git a/unittests/broker/enchant_broker_free_dict_tests.cpp b/unittests/broker/enchant_broker_free_dict_tests.cpp
new file mode 100644
index 0000000..5027caa
--- /dev/null
+++ b/unittests/broker/enchant_broker_free_dict_tests.cpp
@@ -0,0 +1,134 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+/**
+ * enchant_broker_free_dict
+ * @broker: A non-null #EnchantBroker
+ * @dict: A non-null #EnchantDict
+ *
+ * Releases the dictionary when you are done using it
+ *
+ * Must only be called once per dictionary request
+ */
+
+EnchantDict* dictionaryToBeFreed=NULL;
+static void
+DisposeDictionary (EnchantProvider *me, EnchantDict * dict)
+{
+ dictionaryToBeFreed = dict;
+ MockProviderDisposeDictionary(me, dict);
+}
+
+static void ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockEnGbAndQaaProviderRequestDictionary;
+ me->dispose_dict = DisposeDictionary;
+}
+
+struct EnchantBrokerFreeDictTestFixture: EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerFreeDictTestFixture():EnchantBrokerTestFixture(ProviderConfiguration)
+ {
+ _dictionary = RequestDictionary("en-GB");
+ dictionaryToBeFreed=NULL;
+ }
+
+ //Teardown
+ ~EnchantBrokerFreeDictTestFixture()
+ {
+ FreeDictionary(_dictionary);
+ }
+
+ EnchantDict* _dictionary;
+};
+
+static void NoDisposeProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockEnGbAndQaaProviderRequestDictionary;
+}
+
+struct EnchantBrokerFreeDictNoDisposeTestFixture: EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerFreeDictNoDisposeTestFixture():EnchantBrokerTestFixture(NoDisposeProviderConfiguration)
+ {
+ _dictionary = enchant_broker_request_dict(_broker, "en-GB");
+ dictionaryToBeFreed=NULL;
+ }
+
+ //Teardown
+ ~EnchantBrokerFreeDictNoDisposeTestFixture(){
+ FreeDictionary(_dictionary);
+ }
+
+ EnchantDict* _dictionary;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerFreeDictTestFixture,
+ EnchantBrokerFreeDict)
+{
+ enchant_broker_free_dict(_broker, _dictionary);
+ CHECK_EQUAL(_dictionary, dictionaryToBeFreed);
+ _dictionary = NULL;
+}
+
+TEST_FIXTURE(EnchantBrokerFreeDictTestFixture,
+ EnchantBrokerFreeDict_HasPreviousError_ErrorCleared)
+{
+
+ SetErrorOnMockProvider("something bad happened");
+
+ enchant_broker_free_dict(_broker, _dictionary);
+ _dictionary = NULL;
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerFreeDictTestFixture,
+ EnchantBrokerFreeDict_NullBroker_DoNothing)
+{
+ enchant_broker_free_dict(NULL, _dictionary);
+ CHECK_EQUAL((EnchantDict*)NULL, dictionaryToBeFreed);
+}
+
+TEST_FIXTURE(EnchantBrokerFreeDictTestFixture,
+ EnchantBrokerFreeDict_NullDict_DoNothing)
+{
+ enchant_broker_free_dict(_broker, NULL);
+ CHECK_EQUAL((EnchantDict*)NULL, dictionaryToBeFreed);
+}
+
+TEST_FIXTURE(EnchantBrokerFreeDictNoDisposeTestFixture,
+ EnchantBrokerFreeDict_NotOnProvider_DoNothing)
+{
+ testResults_;
+ enchant_broker_free_dict(_broker, _dictionary);
+ _dictionary = NULL;
+}
diff --git a/unittests/broker/enchant_broker_free_tests.cpp b/unittests/broker/enchant_broker_free_tests.cpp
new file mode 100644
index 0000000..eec9257
--- /dev/null
+++ b/unittests/broker/enchant_broker_free_tests.cpp
@@ -0,0 +1,128 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+
+/**
+ * enchant_broker_free
+ * @broker: A non-null #EnchantBroker
+ *
+ * Destroys the broker object
+ *
+ * Free must only be called once!
+ */
+
+bool disposeWasCalled;
+static void
+Dispose (EnchantProvider *me)
+{
+ disposeWasCalled = true;
+ MockProviderDispose(me);
+}
+
+bool disposeDictionaryCalled;
+static void
+DisposeDictionary (EnchantProvider *me, EnchantDict * dict)
+{
+ disposeDictionaryCalled = true;
+ MockProviderDisposeDictionary(me, dict);
+}
+
+static void ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->dispose = Dispose;
+ me->request_dict = MockEnGbAndQaaProviderRequestDictionary;
+ me->dispose_dict = DisposeDictionary;
+}
+
+struct EnchantBrokerFreeTestFixture: EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerFreeTestFixture():EnchantBrokerTestFixture(ProviderConfiguration)
+ {
+ disposeWasCalled = false;
+ disposeDictionaryCalled = false;
+ }
+};
+
+
+static void NoDisposeProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->dispose = NULL;
+}
+
+struct EnchantBrokerFreeNoDisposeTestFixture: EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerFreeNoDisposeTestFixture():EnchantBrokerTestFixture(NoDisposeProviderConfiguration)
+ { }
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST(EnchantBrokerFree)
+{
+ testResults_;
+ EnchantBroker* broker = enchant_broker_init ();
+ enchant_broker_free(broker);
+ broker = NULL;
+}
+
+TEST_FIXTURE(EnchantBrokerFreeTestFixture,
+ EnchantBrokerFree_DisposesProviders)
+{
+ enchant_broker_free(_broker);
+ CHECK(disposeWasCalled);
+ _broker = NULL;
+}
+
+TEST_FIXTURE(EnchantBrokerFreeNoDisposeTestFixture,
+ EnchantBrokerFree_ProviderLacksDispose)
+{
+ testResults_;
+ enchant_broker_free(_broker);
+ _broker = NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerFreeTestFixture,
+ EnchantBrokerFree_NullBroker_DoNothing)
+{
+ enchant_broker_free(NULL);
+ CHECK(!disposeWasCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerFreeTestFixture,
+ EnchantBrokerFree_DictionaryNotFreed_FreesDictionary)
+{
+ EnchantDict* dict = enchant_broker_request_dict(_broker, "en_GB");
+ CHECK(dict);
+ CHECK(!disposeDictionaryCalled);
+
+ enchant_broker_free(_broker);
+ _broker = NULL;
+ CHECK(disposeDictionaryCalled);
+}
diff --git a/unittests/broker/enchant_broker_get_error_tests.cpp b/unittests/broker/enchant_broker_get_error_tests.cpp
new file mode 100644
index 0000000..7c55cca
--- /dev/null
+++ b/unittests/broker/enchant_broker_get_error_tests.cpp
@@ -0,0 +1,65 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+
+/**
+ * enchant_broker_get_error
+ * @broker: A non-null broker
+ *
+ * Returns a const char string or NULL describing the last exception.
+ * WARNING: error is transient and is likely cleared as soon as the
+ * next broker operation happens
+ */
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerTestFixture,
+ EnchantBrokerGetError_HasPreviousError_Error)
+{
+ std::string errorMessage("something bad happened");
+ SetErrorOnMockProvider(errorMessage);
+
+ char * result = enchant_broker_get_error(_broker);
+ CHECK(result);
+ if(result)
+ {
+ CHECK_EQUAL(errorMessage.c_str(), result);
+ }
+}
+
+TEST_FIXTURE(EnchantBrokerTestFixture,
+ EnchantBrokerGetError_NoPreviousError_Null)
+{
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+
+TEST(EnchantBrokerGetError_NullBroker_Null)
+{
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(NULL));
+} \ No newline at end of file
diff --git a/unittests/broker/enchant_broker_init_tests.cpp b/unittests/broker/enchant_broker_init_tests.cpp
new file mode 100644
index 0000000..0da684e
--- /dev/null
+++ b/unittests/broker/enchant_broker_init_tests.cpp
@@ -0,0 +1,40 @@
+/* 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>
+
+/**
+ * enchant_broker_init
+ *
+ * Returns: A new broker object capable of requesting
+ * dictionaries from
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST(EnchantBrokerInit_CreatesObject)
+{
+ EnchantBroker *broker = enchant_broker_init();
+ CHECK(broker);
+ enchant_broker_free(broker);
+}
diff --git a/unittests/broker/enchant_broker_list_dicts_tests.cpp b/unittests/broker/enchant_broker_list_dicts_tests.cpp
new file mode 100644
index 0000000..de71dee
--- /dev/null
+++ b/unittests/broker/enchant_broker_list_dicts_tests.cpp
@@ -0,0 +1,234 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+#include <vector>
+
+
+void EnchantDictionaryDescribeCallback (const char * const lang_tag,
+ const char * const provider_name,
+ const char * const provider_desc,
+ const char * const provider_file,
+ void * user_data)
+{
+ std::vector<DictionaryDescription>* dictionaryList = reinterpret_cast<std::vector<DictionaryDescription>*>(user_data);
+ dictionaryList->push_back(DictionaryDescription(lang_tag, provider_name, provider_desc, provider_file));
+}
+
+static void * global_user_data;
+void EnchantDictionaryDescribeAssignUserDataToStaticCallback (const char * const,
+ const char * const,
+ const char * const,
+ const char * const,
+ void * user_data)
+{
+ global_user_data = user_data;
+}
+
+static bool freeStringListCalled;
+static void FreeStringList (EnchantProvider * me, char **str_list)
+{
+ freeStringListCalled = true;
+
+ return MockProviderFreeStringList(me, str_list);
+}
+
+static bool listDictionariesCalled;
+static char** ListDictionaries (EnchantProvider * me, size_t * out_n_dicts)
+{
+ listDictionariesCalled = true;
+
+ return MockEnGbProviderListDictionaries(me, out_n_dicts);
+}
+
+struct EnchantBrokerListDictionaries_TestFixtureBase : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerListDictionaries_TestFixtureBase(ConfigureHook userConfiguration):
+ EnchantBrokerTestFixture(userConfiguration)
+ {
+ listDictionariesCalled=false;
+ freeStringListCalled=false;
+ global_user_data = NULL;
+ }
+ std::vector<DictionaryDescription> _dictionaryList;
+};
+
+static void List_Dictionaries_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->list_dicts=ListDictionaries;
+ me->free_string_list = FreeStringList;
+}
+
+
+struct EnchantBrokerListDictionaries_TestFixture : EnchantBrokerListDictionaries_TestFixtureBase
+{
+ //Setup
+ EnchantBrokerListDictionaries_TestFixture():
+ EnchantBrokerListDictionaries_TestFixtureBase(List_Dictionaries_ProviderConfiguration)
+ { }
+};
+
+static void List_Dictionaries_ProviderConfigurationLacksFreeStringList (EnchantProvider * me, const char *)
+{
+ me->list_dicts=ListDictionaries;
+ me->free_string_list = NULL;
+}
+
+struct EnchantBrokerListDictionaries_ProviderLacksFreeStringList_TestFixture : EnchantBrokerListDictionaries_TestFixtureBase
+{
+ //Setup
+ EnchantBrokerListDictionaries_ProviderLacksFreeStringList_TestFixture():
+ EnchantBrokerListDictionaries_TestFixtureBase(List_Dictionaries_ProviderConfigurationLacksFreeStringList)
+ { }
+};
+
+
+static char **
+DuplicateEnGbListDictionaries (EnchantProvider *,
+ size_t * out_n_dicts)
+{
+ *out_n_dicts = 2;
+ char** out_list = g_new0 (char *, *out_n_dicts + 1);
+ out_list[0] = g_strdup ("en_GB");
+ out_list[1] = g_strdup ("en_GB");
+
+ return out_list;
+}
+
+static void List_Dictionaries_ProviderConfigurationDuplicateTags (EnchantProvider * me, const char *)
+{
+ me->list_dicts=DuplicateEnGbListDictionaries;
+ me->free_string_list = MockProviderFreeStringList;
+}
+
+struct EnchantBrokerListDictionaries_ProviderDuplicateTags_TestFixture : EnchantBrokerListDictionaries_TestFixtureBase
+{
+ //Setup
+ EnchantBrokerListDictionaries_ProviderDuplicateTags_TestFixture():
+ EnchantBrokerListDictionaries_TestFixtureBase(List_Dictionaries_ProviderConfigurationDuplicateTags)
+ { }
+};
+
+/**
+ * enchant_broker_list_dicts
+ * @broker: A non-null #EnchantBroker
+ * @fn: A non-null #EnchantDictDescribeFn
+ * @user_data: Optional user-data
+ *
+ * Enumerates the dictionaries available from
+ * all Enchant providers.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_UserDataNotNull_PassedThrough)
+{
+ char* userData = "some user data";
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeAssignUserDataToStaticCallback, userData);
+ CHECK_EQUAL(userData, global_user_data);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_UserDataNull_PassedThrough)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeAssignUserDataToStaticCallback, NULL);
+ CHECK_EQUAL((void*)NULL, global_user_data);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_listDictionariesCalledOnProvider)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+ CHECK(listDictionariesCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_freeStringListCalledOnProvider)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+ CHECK(freeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_dictionaryListHasDictionariesFromProvider)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+ CHECK_EQUAL((unsigned int)1, _dictionaryList.size());
+ if(_dictionaryList.size()>0){
+ CHECK(_dictionaryList[0].DataIsComplete());
+ CHECK_EQUAL(std::string("en_GB"), _dictionaryList[0].LanguageTag);
+ CHECK_EQUAL(std::string("mock"), _dictionaryList[0].Name);
+ CHECK_EQUAL(std::string("Mock Provider"), _dictionaryList[0].Description);
+ }
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockProvider("something bad happened");
+
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_NullBroker_DoNotCallDescribeFunction)
+{
+ enchant_broker_list_dicts(NULL, EnchantDictionaryDescribeAssignUserDataToStaticCallback, NULL);
+ CHECK(!listDictionariesCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_TestFixture,
+ EnchantBrokerListDictionaries_NullCallback_DoNotCallDescribeFunction)
+{
+ enchant_broker_list_dicts(_broker, NULL, NULL);
+ CHECK(!listDictionariesCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerTestFixture,
+ EnchantBrokerListDictionaries_ProviderLacksListDictionaries_CallbackNeverCalled)
+{
+ void* userData = "some user data";
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeAssignUserDataToStaticCallback, userData);
+ CHECK_EQUAL((void*)NULL, global_user_data);
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_ProviderDuplicateTags_TestFixture,
+ EnchantBrokerListDictionaries_ProviderDuplicateTags_CallbackCalledOnlyOncePerUniqueTag)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+ CHECK_EQUAL((unsigned int)1, _dictionaryList.size());
+}
+
+TEST_FIXTURE(EnchantBrokerListDictionaries_ProviderLacksFreeStringList_TestFixture,
+ EnchantBrokerListDictionaries_freeStringListCalledOnProvider)
+{
+ enchant_broker_list_dicts(_broker, EnchantDictionaryDescribeCallback, &_dictionaryList);
+ CHECK(!freeStringListCalled);
+}
diff --git a/unittests/broker/enchant_broker_request_dict_tests.cpp b/unittests/broker/enchant_broker_request_dict_tests.cpp
new file mode 100644
index 0000000..9ccd0bd
--- /dev/null
+++ b/unittests/broker/enchant_broker_request_dict_tests.cpp
@@ -0,0 +1,216 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+
+static bool requestDictionaryCalled;
+static EnchantDict * RequestDictionary (EnchantProvider *me, const char *tag)
+{
+ requestDictionaryCalled = true;
+ return MockEnGbAndQaaProviderRequestDictionary(me, tag);
+}
+
+static void Request_Dictionary_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = RequestDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+struct EnchantBrokerRequestDictionary_TestFixture : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerRequestDictionary_TestFixture():
+ EnchantBrokerTestFixture(Request_Dictionary_ProviderConfiguration)
+ {
+ _dict = NULL;
+ requestDictionaryCalled = false;
+ }
+
+ //Teardown
+ ~EnchantBrokerRequestDictionary_TestFixture()
+ {
+ FreeDictionary(_dict);
+ }
+
+ EnchantDict* _dict;
+};
+
+/**
+ * enchant_broker_request_dict
+ * @broker: A non-null #EnchantBroker
+ * @tag: The non-null language tag you wish to request a dictionary for ("en_US", "de_DE", ...)
+ *
+ * Returns: An #EnchantDict, or %null if no suitable dictionary could be found.
+ */
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_ProviderHas_CallsProvider)
+{
+ _dict = enchant_broker_request_dict(_broker, "en_GB");
+ CHECK(_dict);
+ CHECK(requestDictionaryCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_CalledTwice_CallsProviderOnceReturnsSame)
+{
+ _dict = enchant_broker_request_dict(_broker, "en_GB");
+ requestDictionaryCalled = false;
+ EnchantDict* dict = enchant_broker_request_dict(_broker, "en_GB");
+ CHECK(!requestDictionaryCalled);
+
+ CHECK_EQUAL(_dict, dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_ProviderDoesNotHave_CallsProvider)
+{
+ _dict = enchant_broker_request_dict(_broker, "en");
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+ CHECK(requestDictionaryCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_ProviderHasBase_CallsProvider)
+{
+ _dict = enchant_broker_request_dict(_broker, "qaa_CA");
+ CHECK(_dict);
+ CHECK(requestDictionaryCalled);
+}
+
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_WhitespaceSurroundingLanguageTag_Removed)
+{
+ _dict = enchant_broker_request_dict(_broker, "\n\r en_GB \t\f");
+ CHECK(_dict);
+}
+
+/* Vertical tab is not considered to be whitespace in glib!
+ See bug# 59388 http://bugzilla.gnome.org/show_bug.cgi?id=59388
+*/
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_VerticalTabBeforeLanguageTag_NotRemoved)
+{
+ _dict = enchant_broker_request_dict(_broker, "\ven_GB");
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_VerticalTabAfterLanguageTag_NotRemoved)
+{
+ _dict = enchant_broker_request_dict(_broker, "en_GB\v");
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+}
+
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_AtSignInLanguageTag_RemovesToTail)
+{
+ _dict = enchant_broker_request_dict(_broker, "en_GB@euro");
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_PeriodInLanguageTag_RemovesToTail)
+{
+ _dict = enchant_broker_request_dict(_broker, "en_GB.UTF-8");
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_HyphensInLanguageTag_SubstitutedWithUnderscore)
+{
+ _dict = enchant_broker_request_dict(_broker, "en-GB");
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_DifferentCase_Finds)
+{
+ _dict = enchant_broker_request_dict(_broker, "En_gb");
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_DifferentCase_NoRegion_Finds)
+{
+ _dict = enchant_broker_request_dict(_broker, "QAA");
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockProvider("something bad happened");
+
+ _dict = enchant_broker_request_dict(_broker, "en-GB");
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+// ordering of providers for request is tested by enchant_broker_set_ordering tests
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_NullBroker_NULL)
+{
+ _dict = enchant_broker_request_dict(NULL, "en_GB");
+
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+ CHECK(!requestDictionaryCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_NullLanguageTag_NULL)
+{
+ _dict = enchant_broker_request_dict(_broker, NULL);
+
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+ CHECK(!requestDictionaryCalled);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestDictionary_TestFixture,
+ EnchantBrokerRequestDictionary_EmptyLanguageTag_NULL)
+{
+ _dict = enchant_broker_request_dict(_broker, "");
+
+ CHECK_EQUAL((void*)NULL, _dict);
+ CHECK(!requestDictionaryCalled);
+
+}
+
+TEST_FIXTURE(EnchantBrokerTestFixture,
+ EnchantBrokerRequestDictionary_ProviderLacksListDictionaries_CallbackNeverCalled)
+{
+ EnchantDict* dict = enchant_broker_request_dict(_broker, "en_GB");
+
+ CHECK_EQUAL((void*)NULL, dict);
+ CHECK(!requestDictionaryCalled);
+} \ No newline at end of file
diff --git a/unittests/broker/enchant_broker_request_pwl_dict_tests.cpp b/unittests/broker/enchant_broker_request_pwl_dict_tests.cpp
new file mode 100644
index 0000000..23cebfb
--- /dev/null
+++ b/unittests/broker/enchant_broker_request_pwl_dict_tests.cpp
@@ -0,0 +1,129 @@
+/* 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 "../EnchantBrokerTestFixture.h"
+
+struct EnchantBrokerRequestPwlDictionary_TestFixture : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerRequestPwlDictionary_TestFixture()
+ {
+ _dict = NULL;
+ _pwlFile = GetTemporaryFilename("epwl");
+ }
+
+ //Teardown
+ ~EnchantBrokerRequestPwlDictionary_TestFixture()
+ {
+ FreeDictionary(_dict);
+ DeleteFile(_pwlFile);
+ }
+
+ EnchantDict* _dict;
+ std::string _pwlFile;
+};
+
+/**
+ * enchant_broker_request_pwl_dict
+ *
+ * PWL is a personal wordlist file, 1 entry per line
+ *
+ * Returns:
+ */
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_FileExists)
+{
+ CreateFile(_pwlFile);
+ _dict = enchant_broker_request_pwl_dict(_broker, _pwlFile.c_str());
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_FileDoesNotExist_SucceedsCreatesFile)
+{
+ _dict = enchant_broker_request_pwl_dict(_broker, _pwlFile.c_str());
+ CHECK(FileExists(_pwlFile));
+ CHECK(_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_CalledTwice_ReturnsSame)
+{
+ _dict = enchant_broker_request_pwl_dict(_broker, _pwlFile.c_str());
+ EnchantDict* dict = enchant_broker_request_pwl_dict(_broker, _pwlFile.c_str());
+ CHECK_EQUAL(_dict, dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockProvider("something bad happened");
+
+ _dict = enchant_broker_request_pwl_dict(_broker, _pwlFile.c_str());
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_broker_get_error(_broker));
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_NullBroker_NULL)
+{
+ _dict = enchant_broker_request_pwl_dict(NULL, _pwlFile.c_str());
+
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_NullFilename_NULL)
+{
+ _dict = enchant_broker_request_pwl_dict(_broker, NULL);
+
+ CHECK_EQUAL((void*)NULL, (void*)_dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_EmptyFilename_NULL)
+{
+ _dict = enchant_broker_request_pwl_dict(_broker, "");
+
+ CHECK_EQUAL((void*)NULL, _dict);
+}
+
+TEST_FIXTURE(EnchantBrokerRequestPwlDictionary_TestFixture,
+ EnchantBrokerRequestPwlDictionary_IllegalFilename_NULL)
+{
+ // Colon is illegal for Windows and Mac but okay for Linux;
+#if defined(XP_TARGET_COCOA) || defined(_WIN32)
+ _dict = enchant_broker_request_pwl_dict(_broker, ":");
+ CHECK(!_dict);
+ CHECK((void*)enchant_broker_get_error(_broker));
+#endif
+} \ No newline at end of file
diff --git a/unittests/broker/enchant_broker_set_ordering_tests.cpp b/unittests/broker/enchant_broker_set_ordering_tests.cpp
new file mode 100644
index 0000000..d961928
--- /dev/null
+++ b/unittests/broker/enchant_broker_set_ordering_tests.cpp
@@ -0,0 +1,597 @@
+/* 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 char *
+MockProvider1Identify (EnchantProvider *)
+{
+ return "mock1";
+}
+
+static 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
+{
+ std::string _tempPath;
+
+ 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;
+ }
+ _tempPath = GetTemporaryFilename("");
+ }
+
+ ~EnchantBrokerFileSetOrdering_TestFixture()
+ {
+ DeleteDirAndFiles(_tempPath);
+ }
+
+ 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,myspell,ispell,uspell,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\r mock2\n \f\t\r,mock1");
+ CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("qaa"));
+}
+
+TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
+ EnchantBrokerSetOrdering_WhitespaceAroundProviderAfterComma)
+{
+ enchant_broker_set_ordering(_broker, "qaa", "aspell,\n\f\t \rmock2\n\f \r\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\r 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_VerticalTabPreceedingLanguageTag_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)
+{
+ testResults_;
+ enchant_broker_set_ordering(_broker, " @ ", "mock1,mock2");
+}
+
+TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
+ EnchantBrokerSetOrdering_EmptyLanguageTag_DoNothing)
+{
+ testResults_;
+ enchant_broker_set_ordering(_broker, "", "aspell,myspell,ispell");
+}
+
+TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
+ EnchantBrokerSetOrdering_NullOrdering_DoNothing)
+{
+ testResults_;
+ enchant_broker_set_ordering(_broker, "en_GB", NULL);
+}
+
+TEST_FIXTURE(EnchantBrokerSetOrdering_TestFixture,
+ EnchantBrokerSetOrdering_EmptyOrdering_DoNothing)
+{
+ testResults_;
+ enchant_broker_set_ordering(_broker, "en_GB", "");
+}
+
+
+/*
+ * Ordering can also be set in enchant.ordering file:
+ * Language_Tag : Provider1, Provider2, ProviderN
+ *
+ * The enchant.ordering file is discovered by first looking in the user's
+ * config directory, then in the .enchant directory in the user's home directory.
+ *
+ * The user's config directory is located at share/enchant
+ * in the module directory (that libenchant is in)
+ * but it can be overridden using the registry setting
+ * HKEY_CURRENT_USER\Software\Enchant\Config\Data_Dir
+ * or HKEY_LOCAL_MACHINE\Software\Enchant\Config\Data_Dir
+ *
+ * The user's home directory on windows can be overridden using the registry
+ * setting HKEY_CURRENT_USER\Software\Enchant\Config\Home_Dir
+ *
+ * The module directory can be overridden using the registry setting
+ * HKEY_CURRENT_USER\Software\Enchant\Config\Module_Dir
+ * or HKEY_LOCAL_MACHINE\Software\Enchant\Config\Module_Dir
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// 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(_tempPath, "en_GB:mock1,mock2");
+ SetUserRegistryConfigDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrderingMock2ThenMock1_UserOverriddenConfigDirectory)
+{
+ WriteStringToOrderingFile(_tempPath, "en_GB:mock2,mock1");
+ SetUserRegistryConfigDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrderingMock1ThenMock2_MachineOverriddenConfigDirectory)
+{
+ WriteStringToOrderingFile(_tempPath, "en_GB:mock1,mock2");
+ SetMachineRegistryConfigDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrderingMock2ThenMock1_MachineOverriddenConfigDirectory)
+{
+ WriteStringToOrderingFile(_tempPath, "en_GB:mock2,mock1");
+ SetMachineRegistryConfigDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrderingMock1ThenMock2_HomeDirectory)
+{
+ WriteStringToOrderingFile(AddToPath(_tempPath,".enchant"), "en_GB:mock1,mock2");
+ SetRegistryHomeDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrderingMock2ThenMock1_HomeDirectory)
+{
+ WriteStringToOrderingFile(AddToPath(_tempPath,".enchant"), "en_GB:mock2,mock1");
+ SetRegistryHomeDir(_tempPath);
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
+}
+
+// if config registry "" global from share/enchant
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrdering_OverriddenConfigDirectoryIsBlank_UsesSettingsFromDefaultConfigDirectory_Mock1Then2)
+{
+ WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock1,mock2");
+ SetUserRegistryConfigDir("");
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrdering_OverriddenConfigDirectoryIsBlank_UsesSettingsFromDefaultConfigDirectory_Mock2Then1)
+{
+ WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:mock2,mock1");
+ SetUserRegistryConfigDir("");
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock2ThenMock1, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrdering_ExtraSpacesAndTabs_Mock1Then2)
+{
+ WriteStringToOrderingFile(GetEnchantConfigDir(),"\t en_GB\f \t:\r\t mock1\t , \tmock2\t ");
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrdering_ExtraSpaces_Mock2Then1)
+{
+ WriteStringToOrderingFile(GetEnchantConfigDir()," \ten_GB\t \f:\r \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(AddToPath(_tempPath,".enchant"), "en_GB:mock1,mock2");
+ SetRegistryHomeDir(_tempPath);
+
+ 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(AddToPath(_tempPath,".enchant"), "en_GB:mock2,mock1");
+ SetRegistryHomeDir(_tempPath);
+
+ 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(AddToPath(_tempPath,".enchant"), "en_GB:mock1,mock2");
+ SetRegistryHomeDir(_tempPath);
+
+ InitializeBroker();
+
+ CHECK_EQUAL(Mock1ThenMock2, GetProviderOrder("en_GB"));
+}
+
+TEST_FIXTURE(EnchantBrokerFileSetOrdering_TestFixture,
+ EnchantBrokerFileOrdering_NoProviders_DoesNotOverridePreviousOrdering_Mock2Then1)
+{
+ WriteStringToOrderingFile(GetEnchantConfigDir(),"en_GB:");
+ WriteStringToOrderingFile(AddToPath(_tempPath,".enchant"), "en_GB:mock2,mock1");
+ SetRegistryHomeDir(_tempPath);
+
+ 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"));
+}
diff --git a/unittests/dictionary/enchant_dict_add_to_pwl_tests.cpp b/unittests/dictionary/enchant_dict_add_to_pwl_tests.cpp
new file mode 100644
index 0000000..c4397aa
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_add_to_pwl_tests.cpp
@@ -0,0 +1,202 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+static bool addToPersonalCalled;
+static std::string wordToAdd;
+
+static void
+MockDictionaryAddToPersonal (EnchantDict * dict, const char *const word, size_t len)
+{
+ dict;
+ addToPersonalCalled = true;
+ wordToAdd = std::string(word, len);
+}
+
+static EnchantDict* MockProviderRequestAddToPersonalMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->add_to_personal = MockDictionaryAddToPersonal;
+ return dict;
+}
+
+static void DictionaryAddToPersonal_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestAddToPersonalMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+struct EnchantDictionaryAddToPersonal_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryAddToPersonal_TestFixture():
+ EnchantDictionaryTestFixture(DictionaryAddToPersonal_ProviderConfiguration)
+ {
+ addToPersonalCalled = false;
+ }
+};
+
+struct EnchantDictionaryAddToPersonalNotImplemented_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryAddToPersonalNotImplemented_TestFixture():
+ EnchantDictionaryTestFixture(EmptyDictionary_ProviderConfiguration)
+ {
+ addToPersonalCalled = false;
+ }
+};
+/**
+ * enchant_dict_add_to_pwl
+ * @dict: A non-null #EnchantDict
+ * @word: The non-null word you wish to add to your personal dictionary, in UTF-8 encoding
+ * @len: The byte length of @word, or -1 for strlen (@word)
+ *
+ */
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_WordAddedToEnchantPwlFile)
+{
+ CHECK(!PersonalWordListFileHasContents());
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK(PersonalWordListFileHasContents());
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_PassedOnToProvider_LenComputed)
+{
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK(addToPersonalCalled);
+ CHECK_EQUAL(std::string("hello"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_PassedOnToProvider_LenSpecified)
+{
+ enchant_dict_add_to_pwl(_dict, "hellodisregard me", 5);
+ CHECK(addToPersonalCalled);
+ CHECK_EQUAL(std::string("hello"), wordToAdd);
+}
+
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_WordExistsInSession_StillCallsProvider)
+{
+ enchant_dict_add_to_session(_dict, "session", -1);
+ CHECK(!addToPersonalCalled);
+
+ enchant_dict_add_to_pwl(_dict, "session", -1);
+ CHECK(addToPersonalCalled);
+ CHECK_EQUAL(std::string("session"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_WordExistsInPersonal_StillCallsProvider)
+{
+ enchant_dict_add_to_pwl(_dict, "personal", -1);
+ addToPersonalCalled=false;
+ wordToAdd = std::string();
+
+ enchant_dict_add_to_pwl(_dict, "personal", -1);
+ CHECK(addToPersonalCalled);
+ CHECK_EQUAL(std::string("personal"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_InBrokerPwl)
+{
+ enchant_dict_add_to_pwl(_pwl, "personal", -1);
+ CHECK(!addToPersonalCalled);
+ CHECK(!PersonalWordListFileHasContents());
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_IsPermanent)
+{
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK(IsWordInSession("hello"));
+
+ ReloadTestDictionary();
+
+ CHECK(IsWordInSession("hello"));
+}
+
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_NullDictionary_NotAdded)
+{
+ enchant_dict_add_to_pwl(NULL, "hello", -1);
+ CHECK(!addToPersonalCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_NullWord_NotAdded)
+{
+ enchant_dict_add_to_pwl(_dict, NULL, -1);
+ CHECK(!addToPersonalCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_EmptyWord_NotAdded)
+{
+ enchant_dict_add_to_pwl(_dict, "", -1);
+ CHECK(!addToPersonalCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonal_TestFixture,
+ EnchantDictionaryAddToPersonal_WordSize0_NotAdded)
+{
+ enchant_dict_add_to_pwl(_dict, "hello", 0);
+ CHECK(!addToPersonalCalled);
+}
+
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonalNotImplemented_TestFixture,
+ EnchantDictionaryAddToPersonalNotImplemented_WordAddedToEnchantPwlFile)
+{
+ CHECK(!PersonalWordListFileHasContents());
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK(PersonalWordListFileHasContents());
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToPersonalNotImplemented_TestFixture,
+ EnchantDictionaryAddToPersonalNotImplemented_NotPassedOnToProvider)
+{
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ CHECK(!addToPersonalCalled);
+}
diff --git a/unittests/dictionary/enchant_dict_add_to_session_tests.cpp b/unittests/dictionary/enchant_dict_add_to_session_tests.cpp
new file mode 100644
index 0000000..bc86535
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_add_to_session_tests.cpp
@@ -0,0 +1,203 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+static bool addToSessionCalled;
+static std::string wordToAdd;
+
+static void
+MockDictionaryAddToSession (EnchantDict * dict, const char *const word, size_t len)
+{
+ dict;
+ addToSessionCalled = true;
+ wordToAdd = std::string(word, len);
+}
+
+static EnchantDict* MockProviderRequestAddToSessionMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->add_to_session = MockDictionaryAddToSession;
+ return dict;
+}
+
+static void DictionaryAddToSession_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestAddToSessionMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+struct EnchantDictionaryAddToSession_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryAddToSession_TestFixture():
+ EnchantDictionaryTestFixture(DictionaryAddToSession_ProviderConfiguration)
+ {
+ addToSessionCalled = false;
+ }
+};
+
+struct EnchantDictionaryAddToSessionNotImplemented_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryAddToSessionNotImplemented_TestFixture():
+ EnchantDictionaryTestFixture(EmptyDictionary_ProviderConfiguration)
+ {
+ addToSessionCalled = false;
+ }
+};
+/**
+ * enchant_dict_add_to_session
+ * @dict: A non-null #EnchantDict
+ * @word: The non-null word you wish to add to this spell-checking session, in UTF-8 encoding
+ * @len: The byte length of @word, or -1 for strlen (@word)
+ *
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_WordNotAddedToEnchantPwlFile)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(!PersonalWordListFileHasContents());
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_PassedOnToProvider_LenComputed)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(addToSessionCalled);
+ CHECK_EQUAL(std::string("hello"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_PassedOnToProvider_LenSpecified)
+{
+ enchant_dict_add_to_session(_dict, "hellodisregard me", 5);
+ CHECK(addToSessionCalled);
+ CHECK_EQUAL(std::string("hello"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_WordExistsInSession_StillCallsProvider)
+{
+ enchant_dict_add_to_session(_dict, "session", -1);
+ addToSessionCalled=false;
+ wordToAdd = std::string();
+
+ enchant_dict_add_to_session(_dict, "session", -1);
+ CHECK(addToSessionCalled);
+ CHECK_EQUAL(std::string("session"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_WordExistsInPersonal_StillCallsProvider)
+{
+ enchant_dict_add_to_pwl(_dict, "personal", -1);
+ CHECK(!addToSessionCalled);
+
+ enchant_dict_add_to_session(_dict, "personal", -1);
+ CHECK(addToSessionCalled);
+ CHECK_EQUAL(std::string("personal"), wordToAdd);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_WordAddedToSession)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(IsWordInSession("hello"));
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_InBrokerSession)
+{
+ enchant_dict_add_to_session(_pwl, "personal", -1);
+ CHECK(!addToSessionCalled);
+ CHECK(!PersonalWordListFileHasContents());
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_IsNotPermanent)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(IsWordInSession("hello"));
+
+ ReloadTestDictionary();
+
+ CHECK(!IsWordInSession("hello"));
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_NullDictionary_NotAdded)
+{
+ enchant_dict_add_to_session(NULL, "hello", -1);
+ CHECK(!addToSessionCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_NullWord_NotAdded)
+{
+ enchant_dict_add_to_session(_dict, NULL, -1);
+ CHECK(!addToSessionCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_EmptyWord_NotAdded)
+{
+ enchant_dict_add_to_session(_dict, "", -1);
+ CHECK(!addToSessionCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSession_TestFixture,
+ EnchantDictionaryAddToSession_WordSize0_NotAdded)
+{
+ enchant_dict_add_to_session(_dict, "hello", 0);
+ CHECK(!addToSessionCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSessionNotImplemented_TestFixture,
+ EnchantDictionaryAddToSessionNotImplemented_WordAddedToSession)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(IsWordInSession("hello"));
+}
+
+TEST_FIXTURE(EnchantDictionaryAddToSessionNotImplemented_TestFixture,
+ EnchantDictionaryAddToSessionNotImplemented_NotPassedOnToProvider)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+ CHECK(!addToSessionCalled);
+}
diff --git a/unittests/dictionary/enchant_dict_check_tests.cpp b/unittests/dictionary/enchant_dict_check_tests.cpp
new file mode 100644
index 0000000..6155639
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_check_tests.cpp
@@ -0,0 +1,207 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+static bool dictCheckCalled;
+
+static int
+MockDictionaryCheck (EnchantDict * dict, const char *const word, size_t len)
+{
+ dict;
+ dictCheckCalled = true;
+ if(strncmp("hello", word, len)==0)
+ {
+ return 0; //good word
+ }
+ return 1; // bad word
+}
+
+static EnchantDict* MockProviderRequestCheckMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->check = MockDictionaryCheck;
+ return dict;
+}
+
+
+static void DictionaryCheck_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestCheckMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+}
+
+
+struct EnchantDictionaryCheck_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryCheck_TestFixture():
+ EnchantDictionaryTestFixture(DictionaryCheck_ProviderConfiguration)
+ {
+ dictCheckCalled = false;
+ }
+};
+
+struct EnchantDictionaryCheckNotImplemented_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryCheckNotImplemented_TestFixture():
+ EnchantDictionaryTestFixture(EmptyDictionary_ProviderConfiguration)
+ {
+ dictCheckCalled = false;
+ }
+};
+
+
+/**
+ * enchant_dict_check
+ * @dict: A non-null #EnchantDict
+ * @word: The non-null word you wish to correct, in UTF-8 encoding
+ * @len: The byte length of @word, or -1 for strlen (@word)
+ *
+ * Will return an "incorrect" value if any of those pre-conditions
+ * are not met.
+ *
+ * Returns: 0 if the word is correctly spelled, positive if not, negative if error
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordExists_LenComputed_0)
+{
+ CHECK_EQUAL(0, enchant_dict_check(_dict, "hello", -1));
+ CHECK(dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordExists_LenSpecified_0)
+{
+ CHECK_EQUAL(0, enchant_dict_check(_dict, "hellodisregard me", 5));
+ CHECK(dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordDoesNotExist_LenComputed_1)
+{
+ CHECK_EQUAL(1, enchant_dict_check(_dict, "helo", -1));
+ CHECK(dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordDoesNotExist_LenSpecified_1)
+{
+ CHECK_EQUAL(1, enchant_dict_check(_dict, "helodisregard me", 4));
+ CHECK(dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordExistsInSession_0_DoesNotCallProvider)
+{
+ enchant_dict_add_to_session(_dict, "session", -1);
+ CHECK_EQUAL(0, enchant_dict_check(_dict, "session", -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordExistsInPersonal_0_DoesNotCallProvider)
+{
+ enchant_dict_add_to_pwl(_dict, "personal", -1);
+
+ CHECK_EQUAL(0, enchant_dict_check(_dict, "personal", -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordDoesExists_InBrokerPwlSession_0)
+{
+ enchant_dict_add_to_session(_pwl, "session", -1);
+ CHECK_EQUAL(0, enchant_dict_check(_pwl, "session", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordDoesExists_InBrokerPwl_0)
+{
+ enchant_dict_add_to_pwl(_pwl, "personal", -1);
+ CHECK_EQUAL(0, enchant_dict_check(_pwl, "personal", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordDoesNotExist_InBrokerPwl_1)
+{
+ CHECK_EQUAL(1, enchant_dict_check(_pwl, "session", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_check(_dict, "hello", -1);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_NullDictionary_Negative1)
+{
+ CHECK_EQUAL(-1, enchant_dict_check(NULL, "helo", -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_NullWord_Negative1)
+{
+ CHECK_EQUAL(-1, enchant_dict_check(_dict, NULL, -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_EmptyWord_Negative1)
+{
+ CHECK_EQUAL(-1, enchant_dict_check(_dict, "", -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheck_TestFixture,
+ EnchantDictionaryCheck_WordSize0_Negative1)
+{
+ CHECK_EQUAL(-1, enchant_dict_check(_dict, "helo", 0));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheckNotImplemented_TestFixture,
+ EnchantDictionaryCheckNotImplemented_Negative1)
+{
+ CHECK_EQUAL(-1, enchant_dict_check(_dict, "hello", -1));
+ CHECK(!dictCheckCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryCheckNotImplemented_TestFixture,
+ EnchantDictionaryCheckNotImplemented_InBrokerPwl_1)
+{
+ CHECK_EQUAL(1, enchant_dict_check(_pwl, "hello", -1));
+ CHECK(!dictCheckCalled);
+} \ No newline at end of file
diff --git a/unittests/dictionary/enchant_dict_describe_tests.cpp b/unittests/dictionary/enchant_dict_describe_tests.cpp
new file mode 100644
index 0000000..d083f5e
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_describe_tests.cpp
@@ -0,0 +1,140 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+static bool callbackCalled;
+
+void EnchantSingleDictionaryDescribeCallback (const char * const lang_tag,
+ const char * const provider_name,
+ const char * const provider_desc,
+ const char * const provider_file,
+ void * user_data)
+{
+ DictionaryDescription* description = reinterpret_cast<DictionaryDescription*>(user_data);
+ *description = DictionaryDescription(lang_tag, provider_name, provider_desc, provider_file);
+ callbackCalled = true;
+}
+
+static void * global_user_data;
+void EnchantSingleDictionaryDescribeAssignUserDataToStaticCallback (const char * const,
+ const char * const,
+ const char * const,
+ const char * const,
+ void * user_data)
+{
+ global_user_data = user_data;
+ callbackCalled = true;
+}
+
+struct EnchantDictionaryDescribe_TestFixtureBase : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryDescribe_TestFixtureBase(ConfigureHook userConfig):
+ EnchantDictionaryTestFixture(userConfig)
+ {
+ callbackCalled = false;
+ }
+ DictionaryDescription _description;
+};
+
+struct EnchantDictionaryDescribe_TestFixture : EnchantDictionaryDescribe_TestFixtureBase
+{
+ //Setup
+ EnchantDictionaryDescribe_TestFixture():
+ EnchantDictionaryDescribe_TestFixtureBase(EmptyDictionary_ProviderConfiguration)
+ { }
+};
+
+
+/**
+ * enchant_dict_describe
+ * @broker: A non-null #EnchantDict
+ * @dict: A non-null #EnchantDictDescribeFn
+ * @user_data: Optional user-data
+ *
+ * Describes an individual dictionary
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe)
+{
+ enchant_dict_describe(_dict, EnchantSingleDictionaryDescribeCallback, &_description);
+ CHECK(callbackCalled);
+ CHECK(_description.DataIsComplete());
+ CHECK_EQUAL(std::string("qaa"), _description.LanguageTag);
+}
+
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_Pwl)
+{
+ enchant_dict_describe(_pwl, EnchantSingleDictionaryDescribeCallback, &_description);
+ CHECK(callbackCalled);
+ CHECK(_description.DataIsComplete());
+ CHECK_EQUAL(std::string("Personal Wordlist"), _description.LanguageTag);
+ CHECK_EQUAL(std::string("Personal Wordlist"), _description.Name);
+ CHECK_EQUAL(std::string("Personal Wordlist"), _description.Description);
+}
+
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_NullUserdata_PassedToCallback)
+{
+ enchant_dict_describe(_dict, EnchantSingleDictionaryDescribeAssignUserDataToStaticCallback, NULL);
+ CHECK(callbackCalled);
+ CHECK_EQUAL((void*)NULL, global_user_data);
+}
+
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_NonNullUserdata_PassedToCallback)
+{
+ void* userData = "some user data";
+ enchant_dict_describe(_dict, EnchantSingleDictionaryDescribeAssignUserDataToStaticCallback, userData);
+ CHECK(callbackCalled);
+ CHECK_EQUAL(userData, global_user_data);
+}
+
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_describe(_dict, EnchantSingleDictionaryDescribeAssignUserDataToStaticCallback, NULL);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_NullDict_DoNothing)
+{
+ enchant_dict_describe(NULL, EnchantSingleDictionaryDescribeCallback, &_description);
+ CHECK(!callbackCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryDescribe_TestFixture,
+ EnchantDictionaryDescribe_NullCallback_DoNothing)
+{
+ enchant_dict_describe(_dict, NULL, &_description);
+ CHECK(!callbackCalled);
+} \ No newline at end of file
diff --git a/unittests/dictionary/enchant_dict_free_string_list_tests.cpp b/unittests/dictionary/enchant_dict_free_string_list_tests.cpp
new file mode 100644
index 0000000..a98455d
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_free_string_list_tests.cpp
@@ -0,0 +1,95 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+struct EnchantDictFreeStringList_TestFixture : EnchantDictionaryTestFixture
+{
+ //setup
+ EnchantDictFreeStringList_TestFixture()
+ {
+ _string_list = enchant_dict_suggest (_dict, "foo", -1, NULL);
+ _pwl_string_list = enchant_dict_suggest (_pwl, "foo", -1, NULL);
+ }
+ //Teardown
+ ~EnchantDictFreeStringList_TestFixture()
+ {
+ FreeStringList(_string_list);
+ FreeStringList(_pwl_string_list);
+ }
+ char ** _string_list;
+ char ** _pwl_string_list;
+};
+
+/**
+ * enchant_dict_free_string_list
+ * @dict: A non-null #EnchantDict
+ * @string_list: A non-null string list returned from enchant_dict_suggest
+ *
+ * Releases the string list
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictFreeStringList_TestFixture,
+ EnchantDictFreeStringList)
+{
+ testResults_;
+ enchant_dict_free_string_list(_dict, _string_list);
+ _string_list = NULL;
+}
+
+TEST_FIXTURE(EnchantDictFreeStringList_TestFixture,
+ EnchantDictFreeStringListOnPwl)
+{
+ testResults_;
+ enchant_dict_free_string_list(_pwl, _string_list);
+ _string_list = NULL;
+}
+
+TEST_FIXTURE(EnchantDictFreeStringList_TestFixture,
+ EnchantDictFreeStringList_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_free_string_list(_dict, _string_list);
+ _string_list = NULL;
+
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictFreeStringList_TestFixture,
+ EnchantDictFreeStringList_NullDict_DoNothing)
+{
+ testResults_;
+ enchant_dict_free_string_list(NULL, _string_list);
+}
+
+TEST_FIXTURE(EnchantDictFreeStringList_TestFixture,
+ EnchantDictFreeStringList_NullStringList_DoNothing)
+{
+ testResults_;
+ enchant_dict_free_string_list(_dict, NULL);
+}
diff --git a/unittests/dictionary/enchant_dict_get_error_tests.cpp b/unittests/dictionary/enchant_dict_get_error_tests.cpp
new file mode 100644
index 0000000..a401bb1
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_get_error_tests.cpp
@@ -0,0 +1,70 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+/**
+ * enchant_dict_get_error
+ * @dict: A non-null dictionary
+ *
+ * Returns a const char string or NULL describing the last exception.
+ * WARNING: error is transient. It will likely be cleared as soon as
+ * the next dictionary operation is called
+ *
+ * Returns: an error message
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantDictionaryTestFixture,
+ EnchantDictionaryGetError_HasPreviousError_Error)
+{
+ std::string errorMessage("something bad happened");
+ SetErrorOnMockDictionary(errorMessage);
+
+ CHECK_EQUAL(errorMessage.c_str(), enchant_dict_get_error(_dict));
+}
+
+TEST_FIXTURE(EnchantDictionaryTestFixture,
+ EnchantDictionaryGetErrorOnPwl_HasPreviousError_Error)
+{
+ std::string errorMessage("something bad happened");
+ enchant_dict_set_error(_pwl, errorMessage.c_str());
+
+
+ CHECK_EQUAL(errorMessage.c_str(), enchant_dict_get_error(_pwl));
+}
+
+TEST_FIXTURE(EnchantDictionaryTestFixture,
+ EnchantDictionaryGetError_NoPreviousError_Null)
+{
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST(EnchantDictionaryGetError_NullBroker_Null)
+{
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(NULL));
+} \ No newline at end of file
diff --git a/unittests/dictionary/enchant_dict_is_in_session_tests.cpp b/unittests/dictionary/enchant_dict_is_in_session_tests.cpp
new file mode 100644
index 0000000..5b12beb
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_is_in_session_tests.cpp
@@ -0,0 +1,115 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+struct EnchantDictionaryIsInSession_TestFixture : EnchantDictionaryTestFixture
+{};
+
+/**
+ * enchant_dict_is_in_session
+ * @dict: A non-null #EnchantDict
+ * @word: The word you wish to see if it's in your session
+ * @len: the byte length of @word, or -1 for strlen (@word)
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_InSession_1)
+{
+ enchant_dict_add_to_session(_dict, "hello", -1);
+
+ CHECK_EQUAL(1, enchant_dict_is_in_session(_dict, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_InPersonal_1)
+{
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+
+ CHECK_EQUAL(1, enchant_dict_is_in_session(_dict, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_NotInSession_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(_dict, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_OnBrokerPwl_InSession_1)
+{
+ enchant_dict_add_to_session(_pwl, "hello", -1);
+
+ CHECK_EQUAL(1, enchant_dict_is_in_session(_pwl, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_OnBrokerPwl_InPersonal_1)
+{
+ enchant_dict_add_to_pwl(_pwl, "hello", -1);
+
+ CHECK_EQUAL(1, enchant_dict_is_in_session(_pwl, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_OnBrokerPwl_NotInSession_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(_pwl, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ enchant_dict_is_in_session(_dict, "hello", -1);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_NullDictionary_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(NULL, "hello", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_NullWord_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(_dict, NULL, -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_EmptyWord_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(_dict, "", -1));
+}
+
+TEST_FIXTURE(EnchantDictionaryIsInSession_TestFixture,
+ EnchantDictionaryIsInSession_WordSize0_0)
+{
+ CHECK_EQUAL(0, enchant_dict_is_in_session(_dict, "hello", 0));
+} \ No newline at end of file
diff --git a/unittests/dictionary/enchant_dict_store_replacement_tests.cpp b/unittests/dictionary/enchant_dict_store_replacement_tests.cpp
new file mode 100644
index 0000000..a1a7ded
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_store_replacement_tests.cpp
@@ -0,0 +1,214 @@
+/* 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 "../EnchantDictionaryTestFixture.h"
+
+struct EnchantDictionaryStoreReplacement_TestFixture : EnchantDictionaryTestFixture
+{
+ static std::string misspelling;
+ static std::string correction;
+
+ static bool storeReplacementCalled;
+
+ //Setup
+ EnchantDictionaryStoreReplacement_TestFixture():
+ EnchantDictionaryTestFixture(DictionaryStoreReplacement_ProviderConfiguration)
+ {
+ storeReplacementCalled = false;
+ misspelling.clear();
+ correction.clear();
+ }
+
+ static void
+ MockDictionaryStoreReplacement (EnchantDict *,
+ const char *const mis, size_t mis_len,
+ const char *const cor, size_t cor_len)
+ {
+ misspelling = std::string(mis, mis_len);
+ correction = std::string(cor, cor_len);
+ storeReplacementCalled = true;
+ }
+
+ static EnchantDict*
+ MockProviderRequestStoreReplacementMockDictionary(EnchantProvider * me, const char *tag)
+ {
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->store_replacement = MockDictionaryStoreReplacement;
+ return dict;
+ }
+
+ static void DictionaryStoreReplacement_ProviderConfiguration (EnchantProvider * me, const char *)
+ {
+ me->request_dict = MockProviderRequestStoreReplacementMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ }
+};
+bool EnchantDictionaryStoreReplacement_TestFixture::storeReplacementCalled;
+std::string EnchantDictionaryStoreReplacement_TestFixture::misspelling;
+std::string EnchantDictionaryStoreReplacement_TestFixture::correction;
+
+struct EnchantDictionaryLacksStoreReplacement_TestFixture : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionaryLacksStoreReplacement_TestFixture():
+ EnchantDictionaryTestFixture(EmptyDictionary_ProviderConfiguration)
+ { }
+};
+
+
+
+
+/**
+ * enchant_dict_store_replacement
+ * @dict: A non-null #EnchantDict
+ * @mis: The non-null word you wish to add a correction for, in UTF-8 encoding
+ * @mis_len: The byte length of @mis, or -1 for strlen (@mis)
+ * @cor: The non-null correction word, in UTF-8 encoding
+ * @cor_len: The byte length of @cor, or -1 for strlen (@cor)
+ *
+ * Notes that you replaced @mis with @cor, so it's possibly more likely
+ * that future occurrences of @mis will be replaced with @cor. So it might
+ * bump @cor up in the suggestion list.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ExplicitWordLength)
+{
+ std::string misspelling("helo");
+ std::string correction("hello");
+ enchant_dict_store_replacement(_dict,
+ misspelling.c_str(),
+ misspelling.size(),
+ correction.c_str(),
+ correction.size());
+ CHECK(storeReplacementCalled);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::misspelling, misspelling);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::correction, correction);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ComputedWordLength)
+{
+ std::string misspelling("helo");
+ std::string correction("hello");
+ enchant_dict_store_replacement(_dict,
+ misspelling.c_str(),
+ -1,
+ correction.c_str(),
+ -1);
+ CHECK(storeReplacementCalled);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::misspelling, misspelling);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::correction, correction);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_OnBrokerPwl)
+{
+ std::string misspelling("helo");
+ std::string correction("hello");
+ enchant_dict_store_replacement(_pwl,
+ misspelling.c_str(),
+ -1,
+ correction.c_str(),
+ -1);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_NullDict_DoNothing)
+{
+ enchant_dict_store_replacement(NULL, "helo", -1, "hello", -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_NullMisspelling_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, NULL, -1, "hello", -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_NullCorrection_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, "helo", -1, NULL, -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_EmptyMisspelling_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, "", -1, "hello", -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_EmptyCorrection_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, "helo", -1, "", -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ZeroMisspellingLength_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, "helo", 0, "hello", -1);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ZeroCorrectionLength_DoNothing)
+{
+ enchant_dict_store_replacement(_dict, "helo", -1, "hello", 0);
+ CHECK(!storeReplacementCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryLacksStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ProviderLacksStoreReplacement_DoNothing)
+{
+ testResults_;
+ enchant_dict_store_replacement(_dict, "helo", -1, "hello", -1);
+}
+
+TEST_FIXTURE(EnchantDictionaryStoreReplacement_TestFixture,
+ EnchantDictStoreReplacment_ExplicitWordLengthDoesNotCoincideWithNulTerminator)
+{
+ std::string misspelling("helo1");
+ std::string correction("hello1");
+ enchant_dict_store_replacement(_dict,
+ misspelling.c_str(),
+ misspelling.size()-1,
+ correction.c_str(),
+ correction.size()-1);
+
+ misspelling.resize(misspelling.size()-1);
+ correction.resize(correction.size()-1);
+
+ CHECK(storeReplacementCalled);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::misspelling, misspelling);
+ CHECK_EQUAL(EnchantDictionaryStoreReplacement_TestFixture::correction, correction);
+}
diff --git a/unittests/dictionary/enchant_dict_suggest_tests.cpp b/unittests/dictionary/enchant_dict_suggest_tests.cpp
new file mode 100644
index 0000000..c6bc4af
--- /dev/null
+++ b/unittests/dictionary/enchant_dict_suggest_tests.cpp
@@ -0,0 +1,391 @@
+/* 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.
+ */
+
+#define NOMINMAX //don't want windows to collide with std::min
+#include <UnitTest++.h>
+#include <enchant.h>
+#include "../EnchantDictionaryTestFixture.h"
+#include <vector>
+#include <algorithm>
+
+static bool dictSuggestCalled;
+static bool providerFreeStringListCalled;
+std::string suggestWord;
+
+static enum SuggestBehavior{
+ returnNull,
+ returnZero,
+ returnFour,
+} suggestBehavior;
+
+struct EnchantDictionarySuggestTestFixtureBase : EnchantDictionaryTestFixture
+{
+ //Setup
+ EnchantDictionarySuggestTestFixtureBase(ConfigureHook userConfiguration):
+ EnchantDictionaryTestFixture(userConfiguration)
+ {
+ dictSuggestCalled = false;
+ providerFreeStringListCalled = false;
+ _suggestions = NULL;
+ suggestWord = std::string();
+ suggestBehavior = returnFour;
+ }
+ //Teardown
+ ~EnchantDictionarySuggestTestFixtureBase()
+ {
+ FreeStringList(_suggestions);
+ }
+
+ std::vector<std::string> GetExpectedSuggestions(const std::string& s)
+ {
+ size_t cSuggestions;
+ char** expectedSuggestions = MockDictionarySuggest (_dict,
+ s.c_str(),
+ s.size(),
+ &cSuggestions);
+
+ std::vector<std::string> result;
+ if(expectedSuggestions != NULL){
+ result.insert(result.begin(), expectedSuggestions, expectedSuggestions+cSuggestions);
+ FreeStringList(expectedSuggestions);
+ }
+
+ return result;
+ }
+
+ char** _suggestions;
+
+};
+
+static char **
+MyMockDictionarySuggest (EnchantDict * dict, const char *const word, size_t len, size_t * out_n_suggs)
+{
+ dictSuggestCalled = true;
+ suggestWord = std::string(word,len);
+ *out_n_suggs = 0;
+
+ switch(suggestBehavior)
+ {
+ case returnNull:
+ return NULL;
+ case returnZero:
+ return g_new0 (char *, *out_n_suggs + 1);
+ case returnFour:
+ return MockDictionarySuggest(dict, word, len, out_n_suggs);
+ }
+
+ return NULL;
+}
+
+static void
+MyMockProviderFreeStringList (EnchantProvider * provider, char **str_list)
+{
+ providerFreeStringListCalled = true;
+ return MockProviderFreeStringList(provider, str_list);
+}
+
+static EnchantDict* MockProviderRequestSuggestMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->suggest = MyMockDictionarySuggest;
+ return dict;
+}
+
+static void DictionarySuggest_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestSuggestMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ me->free_string_list = MyMockProviderFreeStringList;
+}
+
+
+
+
+struct EnchantDictionarySuggest_TestFixture : EnchantDictionarySuggestTestFixtureBase
+{
+ //Setup
+ EnchantDictionarySuggest_TestFixture():
+ EnchantDictionarySuggestTestFixtureBase(DictionarySuggest_ProviderConfiguration)
+ { }
+};
+
+
+
+
+static EnchantDict* MockProviderRequestNoSuggestMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->suggest = NULL;
+ return dict;
+}
+
+static void DictionaryNoSuggest_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestNoSuggestMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ me->free_string_list = MyMockProviderFreeStringList;
+}
+
+struct EnchantDictionarySuggestNotImplemented_TestFixture : EnchantDictionarySuggestTestFixtureBase
+{
+ //Setup
+ EnchantDictionarySuggestNotImplemented_TestFixture():
+ EnchantDictionarySuggestTestFixtureBase(DictionaryNoSuggest_ProviderConfiguration)
+ { }
+};
+
+
+static EnchantDict* MockProviderRequestNoFreeMockDictionary(EnchantProvider * me, const char *tag)
+{
+
+ EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
+ dict->suggest = MyMockDictionarySuggest;
+ return dict;
+}
+
+static void DictionaryNoFree_ProviderConfiguration (EnchantProvider * me, const char *)
+{
+ me->request_dict = MockProviderRequestNoFreeMockDictionary;
+ me->dispose_dict = MockProviderDisposeDictionary;
+ me->free_string_list = NULL;
+}
+
+struct EnchantDictionaryFreeNotImplemented_TestFixture : EnchantDictionarySuggestTestFixtureBase
+{
+ //Setup
+ EnchantDictionaryFreeNotImplemented_TestFixture():
+ EnchantDictionarySuggestTestFixtureBase(DictionaryNoFree_ProviderConfiguration)
+ { }
+};
+
+
+
+
+/**
+ * enchant_dict_suggest
+ * @dict: A non-null #EnchantDict
+ * @word: The non-null word you wish to find suggestions for, in UTF-8 encoding
+ * @len: The byte length of @word, or -1 for strlen (@word)
+ * @out_n_suggs: The location to store the # of suggestions returned, or %null
+ *
+ * Will return an %null value if any of those pre-conditions
+ * are not met.
+ *
+ * Returns: A %null terminated list of UTF-8 encoded suggestions, or %null
+ */
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_LenComputed)
+{
+ size_t cSuggestions;
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggestions);
+ CHECK(_suggestions);
+ CHECK_EQUAL(std::string("helo"), suggestWord);
+ CHECK_EQUAL(4, cSuggestions);
+
+ std::vector<std::string> suggestions;
+ if(_suggestions != NULL){
+ suggestions.insert(suggestions.begin(), _suggestions, _suggestions+cSuggestions);
+ }
+
+ CHECK_ARRAY_EQUAL(GetExpectedSuggestions("helo"), suggestions, std::min((size_t)4,cSuggestions));
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_LenSpecified)
+{
+ size_t cSuggestions;
+ _suggestions = enchant_dict_suggest(_dict, "helodisregard me", 4, &cSuggestions);
+ CHECK(_suggestions);
+ CHECK_EQUAL(std::string("helo"), suggestWord);
+ CHECK_EQUAL(4, cSuggestions);
+
+ std::vector<std::string> suggestions;
+ if(_suggestions != NULL){
+ suggestions.insert(suggestions.begin(), _suggestions, _suggestions+cSuggestions);
+ }
+
+ CHECK_ARRAY_EQUAL(GetExpectedSuggestions("helo"), suggestions, std::min((size_t)4,cSuggestions));
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_StringListFreed)
+{
+ size_t cSuggs;
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggs);
+ CHECK(dictSuggestCalled);
+ CHECK(providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_NullOutputSuggestionCount)
+{
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, NULL);
+ CHECK(_suggestions);
+ CHECK(dictSuggestCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_InBrokerPwlSession)
+{
+ enchant_dict_add_to_pwl(_pwl, "hello", -1);
+ _suggestions = enchant_dict_suggest(_pwl, "helo", -1, NULL);
+ CHECK(_suggestions);
+ CHECK(!dictSuggestCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_SuggestionsFromPersonal_addedToEnd)
+{
+ size_t cSuggestions;
+ enchant_dict_add_to_pwl(_dict, "hello", -1);
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggestions);
+ CHECK(_suggestions);
+ CHECK_EQUAL(5, cSuggestions);
+
+ std::vector<std::string> suggestions;
+ if(_suggestions != NULL){
+ suggestions.insert(suggestions.begin(), _suggestions, _suggestions+cSuggestions);
+ }
+
+ std::vector<std::string> expected = GetExpectedSuggestions("helo");
+ expected.push_back("hello");
+
+ CHECK_ARRAY_EQUAL(expected, suggestions, std::min((size_t)5,cSuggestions));
+}
+
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_DuplicateSuggestionsFromPersonal_notIncluded)
+{
+ size_t cSuggestions;
+
+ enchant_dict_add_to_pwl(_dict, "aelo", -1);
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggestions);
+ CHECK(_suggestions);
+ CHECK_EQUAL(4, cSuggestions);
+
+ std::vector<std::string> suggestions;
+ if(_suggestions != NULL){
+ suggestions.insert(suggestions.begin(), _suggestions, _suggestions+cSuggestions);
+ }
+
+ CHECK_ARRAY_EQUAL(GetExpectedSuggestions("helo"), suggestions, std::min((size_t)4,cSuggestions));
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_HasPreviousError_ErrorCleared)
+{
+ SetErrorOnMockDictionary("something bad happened");
+
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, NULL);
+ CHECK_EQUAL((void*)NULL, (void*)enchant_dict_get_error(_dict));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_NullDictionary_NullSuggestions)
+{
+ _suggestions = enchant_dict_suggest(NULL, "helo", -1, NULL);
+
+ CHECK(!_suggestions);
+ CHECK(!dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_NullWord_NullSuggestions)
+{
+ _suggestions = enchant_dict_suggest(_dict, NULL, -1, NULL);
+
+ CHECK(!_suggestions);
+ CHECK(!dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_EmptyWord_NullSuggestions)
+{
+ _suggestions = enchant_dict_suggest(_dict, "", -1, NULL);
+
+ CHECK(!_suggestions);
+ CHECK(!dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_WordSize0_NullSuggestions)
+{
+ _suggestions = enchant_dict_suggest(_dict, "helo", 0, NULL);
+
+ CHECK(!_suggestions);
+ CHECK(!dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggestNotImplemented_TestFixture,
+ EnchantDictionarySuggestNotImplemented_NullSuggestions)
+{
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, NULL);
+
+ CHECK(!_suggestions);
+ CHECK(!dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionaryFreeNotImplemented_TestFixture,
+ EnchantDictionaryFreeNotImplemented_Suggestions_FreeNotCalled)
+{
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, NULL);
+
+ CHECK(_suggestions);
+ CHECK(dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_EmptySuggetionList_FreeCalled)
+{
+ suggestBehavior = returnZero;
+ size_t cSuggs;
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggs);
+ CHECK(!_suggestions);
+ CHECK_EQUAL(0, cSuggs);
+ CHECK(dictSuggestCalled);
+ CHECK(providerFreeStringListCalled);
+}
+
+TEST_FIXTURE(EnchantDictionarySuggest_TestFixture,
+ EnchantDictionarySuggest_NullSuggetionList_FreeNotCalled)
+{
+ suggestBehavior = returnNull;
+ size_t cSuggs;
+ _suggestions = enchant_dict_suggest(_dict, "helo", -1, &cSuggs);
+ CHECK(!_suggestions);
+ CHECK_EQUAL(0, cSuggs);
+ CHECK(dictSuggestCalled);
+ CHECK(!providerFreeStringListCalled);
+}
+
diff --git a/unittests/main.cpp b/unittests/main.cpp
new file mode 100644
index 0000000..44b5ac3
--- /dev/null
+++ b/unittests/main.cpp
@@ -0,0 +1,31 @@
+/* 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 "EnchantBrokerTestFixture.h"
+EnchantProvider * EnchantBrokerTestFixture::mock_provider=NULL;
+ConfigureHook EnchantBrokerTestFixture::userMockProviderConfiguration=NULL;
+ConfigureHook EnchantBrokerTestFixture::userMockProvider2Configuration=NULL;
+
+
+int main(){
+ return UnitTest::RunAllTests();
+} \ No newline at end of file
diff --git a/unittests/mock_provider/mock_provider.cpp b/unittests/mock_provider/mock_provider.cpp
new file mode 100644
index 0000000..e8b90dd
--- /dev/null
+++ b/unittests/mock_provider/mock_provider.cpp
@@ -0,0 +1,108 @@
+/* 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 <glib.h>
+#include <string>
+#include "mock_provider.h"
+
+ENCHANT_PLUGIN_DECLARE("mock")
+
+static void
+mock_provider_dispose(EnchantProvider *me)
+{
+ g_free(me);
+}
+
+static char *
+mock_provider_identify (EnchantProvider *)
+{
+ return "mock";
+}
+
+static char *
+mock_provider_describe (EnchantProvider *)
+{
+ return "Mock Provider";
+}
+
+static ConfigureHook _hook;
+
+
+extern "C" {
+
+ENCHANT_MODULE_EXPORT(void)
+set_configure(ConfigureHook hook){
+ _hook = hook;
+}
+
+
+ENCHANT_MODULE_EXPORT(EnchantProvider *)
+init_enchant_provider(void)
+{
+ bool hasIdentify = true;
+ bool hasDescribe = true;
+#if defined(_WIN32)
+ std::wstring null_provider(L"null_provider.dll");
+ std::wstring null_identify(L"null_identify.dll");
+ std::wstring null_describe(L"null_describe.dll");
+ WCHAR szFilename[MAX_PATH];
+ DWORD cFilename = GetModuleFileName((HMODULE)s_hModule, (LPWSTR) &szFilename, sizeof(szFilename));
+ if(cFilename > null_provider.size()){
+ if(std::wstring(&szFilename[cFilename-null_provider.size()]) == null_provider){
+ return NULL;
+ }
+ }
+ if(cFilename > null_identify.size()){
+ if(std::wstring(&szFilename[cFilename-null_identify.size()]) == null_identify){
+ hasIdentify = false;
+ }
+ }
+ if(cFilename > null_describe.size()){
+ if(std::wstring(&szFilename[cFilename-null_describe.size()]) == null_describe){
+ hasDescribe = false;
+ }
+ }
+
+#endif
+
+ EnchantProvider *provider;
+
+ provider = g_new0(EnchantProvider, 1);
+ provider->dispose = mock_provider_dispose; //although this is technically optional, it will result in a memory leak
+ provider->request_dict = NULL;
+ provider->dispose_dict = NULL;
+ provider->identify = hasIdentify ? mock_provider_identify : NULL; // this is required or module won't load
+ provider->describe = hasDescribe ? mock_provider_describe : NULL; // this is required or module won't load
+ provider->list_dicts = NULL;
+ provider->dictionary_exists = NULL;
+ provider->free_string_list = NULL;
+
+ return provider;
+}
+
+ENCHANT_MODULE_EXPORT(void)
+configure_enchant_provider(EnchantProvider * me, const char *dir_name)
+{
+ if(_hook){
+ _hook(me, dir_name);
+ }
+}
+
+} \ No newline at end of file
diff --git a/unittests/mock_provider/mock_provider.h b/unittests/mock_provider/mock_provider.h
new file mode 100644
index 0000000..3e1a997
--- /dev/null
+++ b/unittests/mock_provider/mock_provider.h
@@ -0,0 +1,22 @@
+#ifndef ___MOCK_PROVIDER_H
+#define ___MOCK_PROVIDER_H
+
+#include "enchant-provider.h"
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+typedef void (*ConfigureHook) (EnchantProvider * me, const char * dir_name);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ENCHANT_MODULE_EXPORT(void) set_configure(ConfigureHook hook);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif \ No newline at end of file
diff --git a/unittests/provider/enchant_provider_broker_set_error_tests.cpp b/unittests/provider/enchant_provider_broker_set_error_tests.cpp
new file mode 100644
index 0000000..f7f490b
--- /dev/null
+++ b/unittests/provider/enchant_provider_broker_set_error_tests.cpp
@@ -0,0 +1,93 @@
+/* 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-provider.h>
+
+#include "../EnchantBrokerTestFixture.h"
+
+struct EnchantBrokerSetErrorTests : EnchantBrokerTestFixture
+{
+ //Setup
+ EnchantBrokerSetErrorTests()
+ {
+ provider = GetMockProvider();
+ }
+
+ std::string GetErrorMessage(){
+ char* error = enchant_broker_get_error(_broker);
+ if(error == NULL){
+ error = "";
+ }
+ return std::string(error);
+ }
+
+ EnchantProvider* provider;
+};
+
+/**
+ * enchant_provider_set_error
+ * @provider: A non-null provider
+ * @err: A non-null error message
+ *
+ * Sets the current runtime error to @err. This API is private to
+ * the providers.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantBrokerSetErrorTests,
+ SetErrorMessageOnProvider)
+{
+ std::string expectedErrorMessage("Error message to display");
+ enchant_provider_set_error(provider, expectedErrorMessage.c_str());
+
+ CHECK_EQUAL(expectedErrorMessage, GetErrorMessage());
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantBrokerSetErrorTests,
+ SetErrorMessageOnProvider_NullProvider_NoErrorSet)
+{
+ enchant_provider_set_error(NULL, "Error message to display");
+
+ CHECK_EQUAL(std::string(), GetErrorMessage());
+}
+
+TEST_FIXTURE(EnchantBrokerSetErrorTests,
+ SetErrorMessageOnProvider_NullError_NoErrorSet)
+{
+ enchant_provider_set_error(provider, NULL);
+
+ CHECK_EQUAL(std::string(), GetErrorMessage());
+}
+
+TEST_FIXTURE(EnchantBrokerSetErrorTests,
+ SetErrorMessageOnProvider_MessageCopied)
+{
+ std::string expectedErrorMessage("Error message to display");
+ enchant_provider_set_error(provider, expectedErrorMessage.c_str());
+
+ expectedErrorMessage[0] = 'e';
+ CHECK(expectedErrorMessage != GetErrorMessage());
+}
diff --git a/unittests/provider/enchant_provider_dict_set_error_tests.cpp b/unittests/provider/enchant_provider_dict_set_error_tests.cpp
new file mode 100644
index 0000000..a8222cc
--- /dev/null
+++ b/unittests/provider/enchant_provider_dict_set_error_tests.cpp
@@ -0,0 +1,86 @@
+/* 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-provider.h>
+#include "../EnchantDictionaryTestFixture.h"
+
+struct EnchantDictionarySetErrorTests : EnchantDictionaryTestFixture
+{
+ //Setup
+ std::string GetErrorMessage(){
+ char* error = enchant_dict_get_error(_dict);
+ if(error == NULL){
+ error = "";
+ }
+ return std::string(error);
+ }
+};
+
+/**
+ * enchant_dict_set_error
+ * @dict: A non-null dictionary
+ * @err: A non-null error message
+ *
+ * Sets the current runtime error to @err. This API is private to the
+ * providers.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+
+TEST_FIXTURE(EnchantDictionarySetErrorTests,
+ SetErrorMessageOnDictionary)
+{
+ std::string expectedErrorMessage("Error message to display");
+ enchant_dict_set_error(_dict, expectedErrorMessage.c_str());
+
+ CHECK_EQUAL(expectedErrorMessage, GetErrorMessage());
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST_FIXTURE(EnchantDictionarySetErrorTests,
+ SetErrorMessageOnDictionary_NullDictionary_NoErrorSet)
+{
+ enchant_dict_set_error(NULL, "Error message to display");
+
+ CHECK_EQUAL(std::string(), GetErrorMessage());
+}
+
+TEST_FIXTURE(EnchantDictionarySetErrorTests,
+ SetErrorMessageOnDictionary_NullError_NoErrorSet)
+{
+ enchant_dict_set_error(_dict, NULL);
+
+ CHECK_EQUAL(std::string(), GetErrorMessage());
+}
+
+
+TEST_FIXTURE(EnchantDictionarySetErrorTests,
+ SetErrorMessageOnDictionary_MessageCopied)
+{
+ std::string expectedErrorMessage("Error message to display");
+ enchant_dict_set_error(_dict, expectedErrorMessage.c_str());
+
+ expectedErrorMessage[0] = 'e';
+ CHECK(expectedErrorMessage != GetErrorMessage());
+} \ No newline at end of file
diff --git a/unittests/provider/enchant_provider_get_prefix_dir_tests.cpp b/unittests/provider/enchant_provider_get_prefix_dir_tests.cpp
new file mode 100644
index 0000000..429d7cc
--- /dev/null
+++ b/unittests/provider/enchant_provider_get_prefix_dir_tests.cpp
@@ -0,0 +1,68 @@
+/* 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-provider.h>
+#include <glib.h>
+#include "../EnchantTestFixture.h"
+
+struct EnchantGetPrefixDirTestFixture : EnchantTestFixture{
+ //Setup
+ EnchantGetPrefixDirTestFixture()
+ {
+ expectedPrefixDir = GetDirectoryOfThisModule();
+ }
+
+ const char* ExpectedPrefixDir()
+ {
+ if(expectedPrefixDir.empty()){
+ return NULL;
+ }
+
+ return expectedPrefixDir.c_str();
+ }
+
+ std::string expectedPrefixDir;
+
+};
+
+/**
+ * enchant_get_prefix_dir
+ *
+ * Returns a string giving the location of the base directory
+ * of the enchant installation. This corresponds roughly to
+ * the --prefix option given to ./configure when enchant is
+ * compiled, except it is determined at runtime based on the location
+ * of the enchant library.
+ *
+ * This API is private to the providers.
+ *
+ * returns NULL if it cannot dynamically determine the location of
+ * the enchant library
+ */
+
+TEST_FIXTURE(EnchantGetPrefixDirTestFixture,
+ EnchantGetPrefixDir)
+{
+ char* prefixDir = enchant_get_prefix_dir();
+ CHECK_EQUAL(ExpectedPrefixDir(), prefixDir);
+ g_free(prefixDir);
+} \ No newline at end of file
diff --git a/unittests/provider/enchant_provider_get_registry_value_tests.cpp b/unittests/provider/enchant_provider_get_registry_value_tests.cpp
new file mode 100644
index 0000000..e978c42
--- /dev/null
+++ b/unittests/provider/enchant_provider_get_registry_value_tests.cpp
@@ -0,0 +1,180 @@
+/* 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-provider.h>
+#include "../EnchantTestFixture.h"
+
+struct EnchantGetRegistryValue_TestFixture : EnchantTestFixture{
+ //Teardown
+ ~EnchantGetRegistryValue_TestFixture(){
+ ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Test", L"Value");
+ ClearRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Test", L"Value");
+ }
+
+ void SetUserRegistryValue(const std::string& value)
+ {
+ SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Test", L"Value", value);
+ }
+
+ void SetMachineRegistryValue(const std::string& value)
+ {
+ SetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Test", L"Value", value);
+ }
+};
+
+
+/**
+ * enchant_get_registry_value
+ * @prefix: Your category, such as "Ispell" or "Myspell"
+ * @key: The tag within your category that you're interested in
+ *
+ * Returns: the value if it exists and is not an empty string ("") or %null otherwise. Must be free'd.
+ *
+ * Choices: User Machine Result
+ * "hello" "world" "hello"
+ * "hello" NULL "hello"
+ * "hello" "" "hello"
+ * "" "world" "world"
+ * "" NULL ""
+ * "" "" ""
+ * NULL "world" "world"
+ * NULL NULL NULL
+ * NULL "" ""
+ *
+ * This API is private to the providers.
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+#ifdef _WIN32
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_UserAndMachine_ValueFromUser)
+{
+ SetUserRegistryValue("hello");
+ SetMachineRegistryValue("world");
+
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(value);
+ CHECK_EQUAL("hello", value);
+
+ g_free(value);
+}
+
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_UserOnly_ValueFromUser)
+{
+ SetUserRegistryValue("hello");
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(value);
+ CHECK_EQUAL("hello", value);
+
+ g_free(value);
+}
+
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_MachineOnly_ValueFromMachine)
+{
+ SetMachineRegistryValue("world");
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(value);
+ CHECK_EQUAL("world", value);
+
+ g_free(value);
+}
+
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_UserEmptyAndMachineSet_ValueFromMachine)
+{
+ SetUserRegistryValue("");
+ SetMachineRegistryValue("world");
+
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(value);
+ CHECK_EQUAL("world", value);
+
+ g_free(value);
+}
+
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_UserEmptyAndMachineNotSet_Null)
+{
+ SetUserRegistryValue("");
+
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(!value);
+
+ g_free(value);
+}
+#endif
+
+
+TEST(GetRegistryValue_None_NULL)
+{
+ char * value = enchant_get_registry_value("Test", "Value");
+
+ CHECK(value == NULL);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Error Conditions
+TEST(GetRegistryValue_NullPrefix_NULL)
+{
+ char * value = enchant_get_registry_value(NULL, "Value");
+
+ CHECK(value == NULL);
+}
+
+TEST(GetRegistryValue_NullKey_NULL)
+{
+ char * value = enchant_get_registry_value("Test", NULL);
+
+ CHECK(value == NULL);
+}
+
+#ifdef _WIN32
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_NullPrefix_Null)
+{
+ SetUserRegistryValue("hello");
+
+ char * value = enchant_get_registry_value(NULL, "Value");
+
+ CHECK(value == NULL);
+}
+
+TEST_FIXTURE(EnchantGetRegistryValue_TestFixture,
+ GetRegistryValue_NullKey_Null)
+{
+ SetUserRegistryValue("hello");
+
+ char * value = enchant_get_registry_value("Test", NULL);
+
+ CHECK(value == NULL);
+}
+
+#endif \ No newline at end of file
diff --git a/unittests/provider/enchant_provider_get_user_home_dir_tests.cpp b/unittests/provider/enchant_provider_get_user_home_dir_tests.cpp
new file mode 100644
index 0000000..9cc0b56
--- /dev/null
+++ b/unittests/provider/enchant_provider_get_user_home_dir_tests.cpp
@@ -0,0 +1,81 @@
+/* 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 "../EnchantTestFixture.h"
+#include <UnitTest++.h>
+#include <enchant-provider.h>
+
+/**
+ * enchant_get_user_home_dir
+ *
+ * Returns: the user's home directory, or %null. Returned value
+ * must be free'd.
+ *
+ * This API is private to the providers.
+ */
+
+/*
+ * The user's home directory on windows can be overridden using the registry
+ * setting HKEY_CURRENT_USER\Software\Enchant\Config\Home_Dir
+ */
+#ifdef _WIN32
+TEST_FIXTURE(EnchantTestFixture,
+ GetUserHomeDir_FromRegistry)
+{
+ std::string homeDir("here I am");
+ SetRegistryHomeDir(homeDir);
+
+ char * enchantUserHomeDir = enchant_get_user_home_dir();
+
+ CHECK(enchantUserHomeDir);
+ CHECK_EQUAL(homeDir, enchantUserHomeDir);
+
+ g_free(enchantUserHomeDir);
+}
+
+#ifdef _WIN32
+TEST_FIXTURE(EnchantTestFixture,
+ GetUserHomeDir_BlankFromRegistry_RegistryEntryIgnored)
+{
+ std::string homeDir("");
+ SetRegistryHomeDir(homeDir);
+
+ char * enchantUserHomeDir = enchant_get_user_home_dir();
+
+ CHECK(enchantUserHomeDir);
+ CHECK_EQUAL(g_get_home_dir(), enchantUserHomeDir);
+
+ g_free(enchantUserHomeDir);
+}
+#endif
+
+#endif
+
+TEST_FIXTURE(EnchantTestFixture,
+ GetUserHomeDir)
+{
+ char * enchantUserHomeDir = enchant_get_user_home_dir();
+
+ CHECK(enchantUserHomeDir);
+ CHECK_EQUAL(g_get_home_dir(), enchantUserHomeDir);
+
+ g_free(enchantUserHomeDir);
+} \ No newline at end of file
diff --git a/unittests/provider/enchant_provider_get_user_language_tests.cpp b/unittests/provider/enchant_provider_get_user_language_tests.cpp
new file mode 100644
index 0000000..792cf30
--- /dev/null
+++ b/unittests/provider/enchant_provider_get_user_language_tests.cpp
@@ -0,0 +1,88 @@
+/* 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-provider.h>
+#include <glib.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// Test Normal Operation
+TEST(EnchantGetUserLanguage)
+{
+ char* userLanguage = enchant_get_user_language();
+ CHECK(userLanguage);
+ g_free(userLanguage);
+}
+
+TEST(EnchantGetUserLanguage_FromLangEnvironmentVariable)
+{
+ std::string origLangEnv;
+ bool hasLangEnv = (g_getenv("LANG") != NULL);
+ if(hasLangEnv)
+ {
+ origLangEnv = std::string(g_getenv("LANG"));
+ }
+
+ g_setenv("LANG", "qaa", TRUE);
+ char* userLanguage = enchant_get_user_language();
+ CHECK(userLanguage);
+ CHECK_EQUAL("qaa", userLanguage);
+
+ g_free(userLanguage);
+
+ if(hasLangEnv)
+ {
+ g_setenv("LANG", origLangEnv.c_str(), TRUE);
+ }
+ else{
+ g_unsetenv("LANG");
+ }
+}
+
+#ifndef _WIN32
+TEST(EnchantGetUserLanguage_FromLocale)
+{
+ std::string origLocale(setlocale (LC_ALL, NULL));
+
+ setlocale (LC_ALL, "qaa");
+ char* userLanguage = enchant_get_user_language();
+ CHECK(userLanguage);
+ CHECK_EQUAL("qaa", userLanguage);
+
+ g_free(userLanguage);
+
+ setlocale (LC_ALL, origLocale.c_str());
+}
+
+TEST(EnchantGetUserLanguage_LocaleIsC_LocalIsEn)
+{
+ std::string origLocale(setlocale (LC_ALL, NULL));
+
+ setlocale (LC_ALL, "C");
+ char* userLanguage = enchant_get_user_language();
+ CHECK(userLanguage);
+ CHECK_EQUAL("en", userLanguage);
+
+ g_free(userLanguage);
+
+ setlocale (LC_ALL, origLocale.c_str());
+}
+#endif \ No newline at end of file