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 
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
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
Definition: EnchantBrokerTestFixture.h:103
Definition: EnchantDictionaryTestFixture.h:91
Definition: enchant-provider.h:125
Definition: enchant-provider.h:150