Enchant Generic spell checking library

EnchantDictionaryTestFixture.h
1 /* Copyright (c) 2007 Eric Scott Albright
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22 #ifndef __ENCHANTDICTIONARYTESTFIXTURE
23 #define __ENCHANTDICTIONARYTESTFIXTURE
24
25 #include "EnchantBrokerTestFixture.h"
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <string>
32 #include <vector>
33
34 static EnchantDict*
35 MockProviderRequestEmptyMockDictionary(EnchantProvider *, const char *)
36 {
37 EnchantDict* dict = g_new0(EnchantDict, 1);
38 dict->user_data = NULL;
39 dict->check = NULL;
40 dict->suggest = NULL;
41 dict->add_to_session = NULL;
42
43 return dict;
44 }
45
46 static void EmptyDictionary_ProviderConfiguration (EnchantProvider * me, const char *)
47 {
48 me->request_dict = MockProviderRequestEmptyMockDictionary;
49 me->dispose_dict = MockProviderDisposeDictionary;
50 }
51
52
53 static char**
54 MockDictionarySuggest (EnchantDict * ,
55 const char *const word,
56 size_t len,
57 size_t * out_n_suggs)
58 {
59 *out_n_suggs = 4;
60
61 char **sugg_arr = g_new0 (char *, *out_n_suggs + 1);
62 for(size_t i=0; i<*out_n_suggs;++i){
63 if(len == -1) {
64 sugg_arr[i] = g_strdup (word);
65 }
66 else {
67 sugg_arr[i] = g_strndup (word, (gsize)len);
68 }
69 sugg_arr[i][0] = 'a' + (char)i;
70 }
71 return sugg_arr;
72 }
73
74 static EnchantDict*
75 MockProviderRequestBasicMockDictionary(EnchantProvider *me, const char *tag)
76 {
77
78 EnchantDict* dict = MockProviderRequestEmptyMockDictionary(me, tag);
79 dict->suggest = MockDictionarySuggest;
80 return dict;
81 }
82
83
84 static void BasicDictionary_ProviderConfiguration (EnchantProvider * me, const char *)
85 {
86 me->request_dict = MockProviderRequestBasicMockDictionary;
87 me->dispose_dict = MockProviderDisposeDictionary;
88 }
89
90 struct EnchantDictionaryTestFixture : EnchantBrokerTestFixture
91 {
92 EnchantDict* _dict;
93 EnchantDict* _pwl;
94 std::string _pwlFileName;
95 std::string origLangEnv;
96 bool hasLangEnv;
97 std::string languageTag;
98
99 //Setup
100 EnchantDictionaryTestFixture(ConfigureHook userConfiguration=BasicDictionary_ProviderConfiguration, const std::string& languageTag="qaa"):
101 EnchantBrokerTestFixture(userConfiguration),
102 languageTag(languageTag)
103 {
104 InitializeTestDictionary();
105 _pwl = RequestPersonalDictionary();
106 _pwlFileName = GetLastPersonalDictionaryFileName();
107
108 hasLangEnv = (g_getenv("LANG") != NULL);
109 if(hasLangEnv)
110 {
111 origLangEnv = std::string(g_getenv("LANG"));
112 }
113 }
114
115 //Teardown
116 ~EnchantDictionaryTestFixture(){
117 FreeTestDictionary();
118 FreeDictionary(_pwl);
119 ResetLocale();
120 }
121
122 void SetLocale(const std::string& locale)
123 {
124 g_setenv("LANG", locale.c_str(), TRUE);
125 }
126
127 void ResetLocale()
128 {
129 if(hasLangEnv)
130 {
131 g_setenv("LANG", origLangEnv.c_str(), TRUE);
132 }
133 else{
134 g_unsetenv("LANG");
135 }
136 }
137
138 void ReloadTestDictionary()
139 {
140 FreeTestDictionary();
141 InitializeTestDictionary();
142 }
143
144 void InitializeTestDictionary()
145 {
146 _dict = enchant_broker_request_dict(_broker, languageTag.c_str());
147 }
148
149 void FreeTestDictionary()
150 {
151 FreeDictionary(_dict);
152 }
153
154 bool PersonalWordListFileHasContents()
155 {
156 return FileHasContents(GetPersonalDictFileName());
157 }
158
159 bool ExcludeFileHasContents()
160 {
161 return FileHasContents(GetExcludeDictFileName());
162 }
163
164 bool BrokerPWLFileHasContents()
165 {
166 return FileHasContents(_pwlFileName);
167 }
168
169 bool FileHasContents(const std::string & filename)
170 {
171 bool hasContents = false;
172 int fd = g_open(filename.c_str(), O_RDONLY, S_IREAD );
173 if(fd == -1){
174 return false;
175 }
176
177 char c;
178 while(read(fd, &c, 1) == 1 && !hasContents){
179 switch(c)
180 {
181 case '\n':
182 case '\r':
183 case ' ':
184 break;
185 default:
186 hasContents = true;
187 }
188 }
189 close(fd);
190
191 return hasContents;
192 }
193
194 std::string GetPersonalDictFileName(){
195 return AddToPath(GetTempUserEnchantDir(), "qaa.dic");
196 }
197
198 std::string GetExcludeDictFileName(){
199 return AddToPath(GetTempUserEnchantDir(), "qaa.exc");
200 }
201
202 void SetErrorOnMockDictionary(const std::string& error)
203 {
204 enchant_dict_set_error(_dict, error.c_str());
205 }
206
207 void FreeStringList(char** list)
208 {
209 if(list)
210 {
211 enchant_dict_free_string_list(_dict, list);
212 }
213 }
214
215 void FreePwlStringList(char** list)
216 {
217 if(list)
218 {
219 enchant_dict_free_string_list(_pwl, list);
220 }
221 }
222
223 bool IsWordInSession(const std::string& word){
224 return enchant_dict_is_added(_dict, word.c_str(), word.size())!=0;
225 }
226
227 bool IsWordInDictionary(const std::string& word){
228 return enchant_dict_check(_dict, word.c_str(), word.size())==0;
229 }
230
231 void RemoveWordFromDictionary(const std::string& word)
232 {
233 enchant_dict_remove(_dict, word.c_str(), word.size());
234 }
235
236 void AddWordToDictionary(const std::string& word)
237 {
238 enchant_dict_add(_dict, word.c_str(), word.size());
239 }
240
241 void AddWordsToDictionary(const std::vector<std::string>& sWords)
242 {
243 for(std::vector<std::string>::const_iterator itWord = sWords.begin();
244 itWord != sWords.end();
245 ++itWord){
246 AddWordToDictionary(*itWord);
247 }
248 }
249
250 void ExternalAddWordToDictionary(const std::string& word)
251 {
252 ExternalAddWordToFile(word, GetPersonalDictFileName());
253 }
254
255 void ExternalAddWordToExclude(const std::string& word)
256 {
257 ExternalAddWordToFile(word, GetExcludeDictFileName());
258 }
259
260 static void ExternalAddWordToFile(const std::string& word, const std::string& filename)
261 {
262 sleep(1); // FAT systems have a 2 second resolution
263 // NTFS is appreciably faster but no specs on what it is exactly
264 // c runtime library's time_t has a 1 second resolution
265 FILE * f = g_fopen(filename.c_str(), "a");
266 if(f)
267 {
268 fputc('\n', f);
269 fputs(word.c_str(), f);
270 fclose(f);
271 }
272 }
273
274 void ExternalAddNewLineToDictionary()
275 {
276 sleep(1); // FAT systems have a 2 second resolution
277 // NTFS is appreciably faster but no specs on what it is exactly
278 // c runtime library's time_t has a 1 second resolution
279 FILE * f = g_fopen(GetPersonalDictFileName().c_str(), "a");
280 if(f)
281 {
282 fputc('\n', f);
283 fclose(f);
284 }
285 }
286
287 void ExternalAddWordsToDictionary(const std::vector<std::string>& sWords)
288 {
289 sleep(1); // FAT systems have a 2 second resolution
290 // NTFS is appreciably faster but no specs on what it is exactly
291 // c runtime library's time_t has a 1 second resolution
292 FILE * f = g_fopen(GetPersonalDictFileName().c_str(), "a");
293 if(f)
294 {
295 for (std::vector<std::string>::const_iterator itWord = sWords.begin();
296 itWord != sWords.end(); ++itWord)
297 {
298 if (itWord != sWords.begin()) {
299 fputc('\n', f);
300 }
301 fputs(itWord->c_str(), f);
302 }
303 fclose(f);
304 }
305 }
306
307 std::vector<std::string> GetExpectedSuggestions(const std::string& s, size_t begin = 0)
308 {
309 size_t cSuggestions;
310 char** expectedSuggestions = MockDictionarySuggest (_dict,
311 s.c_str(),
312 s.size(),
313 &cSuggestions);
314
315 std::vector<std::string> result;
316 if(expectedSuggestions != NULL && begin < cSuggestions){
317 result.insert(result.begin(), expectedSuggestions+begin, expectedSuggestions+cSuggestions);
318 g_strfreev(expectedSuggestions);
319 }
320
321 return result;
322 }
323
324
325 std::vector<std::string> GetSuggestionsFromWord(const std::string& word)
326 {
327 std::vector<std::string> result;
328
329 size_t cSuggestions;
330 char** suggestions = enchant_dict_suggest(_dict, word.c_str(), word.size(), &cSuggestions);
331
332 if(suggestions != NULL){
333 result.insert(result.begin(), suggestions, suggestions+cSuggestions);
334 }
335
336 FreeStringList(suggestions);
337
338 return result;
339 }
340
341 std::vector<std::string> GetSuggestions(const std::string& s)
342 {
343 return GetSuggestionsFromWord("helo");
344 }
345 };
346
347 #endif
EnchantBrokerTestFixture
Definition: EnchantBrokerTestFixture.h:103
EnchantDictionaryTestFixture
Definition: EnchantDictionaryTestFixture.h:91
str_enchant_dict
Definition: enchant-provider.h:125
str_enchant_provider
Definition: enchant-provider.h:150