Tizen 2.1 base
[external/enchant.git] / unittests / EnchantTestFixture.h
1 /* Copyright (c) 2007 Eric Scott Albright\r
2  * \r
3  * Permission is hereby granted, free of charge, to any person obtaining a copy\r
4  * of this software and associated documentation files (the "Software"), to deal\r
5  * in the Software without restriction, including without limitation the rights\r
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
7  * copies of the Software, and to permit persons to whom the Software is\r
8  * furnished to do so, subject to the following conditions:\r
9  * \r
10  * The above copyright notice and this permission notice shall be included in\r
11  * all copies or substantial portions of the Software.\r
12  * \r
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
19  * THE SOFTWARE.\r
20  */\r
21 \r
22 #ifndef __ENCHANTTESTFIXTURE\r
23 #define __ENCHANTTESTFIXTURE\r
24 \r
25 #if defined(_MSC_VER)\r
26 #pragma once\r
27 #endif\r
28 \r
29 #ifdef _WIN32\r
30 #define WIN32_LEAN_AND_MEAN\r
31 #include <windows.h>\r
32 #include <shlwapi.h>\r
33 #endif\r
34 #include <io.h>\r
35 #include <assert.h>\r
36 #include <glib.h>\r
37 #include <string>\r
38 \r
39 struct EnchantTestFixture\r
40 {\r
41     std::string savedRegistryHomeDir;\r
42     std::string savedUserRegistryModuleDir;\r
43     std::string savedMachineRegistryModuleDir;\r
44     std::string savedUserRegistryConfigDir;\r
45     std::string savedMachineRegistryConfigDir;\r
46 \r
47     //Setup\r
48     EnchantTestFixture()\r
49     {\r
50         CleanUpFiles(); //just in case we stopped the process in the middle.\r
51         MoveEnchantUserFilesOutOfTheWay();\r
52 \r
53 #ifdef _WIN32\r
54         savedRegistryHomeDir = GetRegistryHomeDir();\r
55         ClearRegistryHomeDir();\r
56 \r
57         savedUserRegistryModuleDir = GetUserRegistryModuleDir();\r
58         ClearUserRegistryModuleDir();\r
59 \r
60         savedMachineRegistryModuleDir = GetMachineRegistryModuleDir();\r
61         ClearMachineRegistryModuleDir();\r
62 \r
63         savedUserRegistryConfigDir = GetUserRegistryConfigDir();\r
64         ClearUserRegistryConfigDir();\r
65 \r
66         savedMachineRegistryConfigDir = GetMachineRegistryConfigDir();\r
67         ClearMachineRegistryConfigDir();\r
68 #endif\r
69     }\r
70 \r
71     //Teardown\r
72     ~EnchantTestFixture(){\r
73 #ifdef _WIN32\r
74         if(savedRegistryHomeDir.empty()) {\r
75             ClearRegistryHomeDir();\r
76         }\r
77         else {\r
78             SetRegistryHomeDir(savedRegistryHomeDir);\r
79         }\r
80                 \r
81         if(savedUserRegistryModuleDir.empty()) {\r
82             ClearUserRegistryModuleDir();\r
83         }\r
84         else{\r
85             SetUserRegistryModuleDir(savedUserRegistryModuleDir);\r
86         }\r
87 \r
88         if(savedMachineRegistryModuleDir.empty())\r
89         {\r
90             ClearMachineRegistryModuleDir();\r
91         }\r
92         else{\r
93             SetMachineRegistryModuleDir(savedMachineRegistryModuleDir);\r
94         }\r
95 \r
96         if(savedUserRegistryConfigDir.empty())\r
97         {\r
98             ClearUserRegistryConfigDir();\r
99         }\r
100         else{\r
101             SetUserRegistryConfigDir(savedUserRegistryConfigDir);\r
102         }\r
103 \r
104         if(savedMachineRegistryConfigDir.empty()) {\r
105             ClearMachineRegistryConfigDir();\r
106         }\r
107         else {\r
108             SetMachineRegistryConfigDir(savedMachineRegistryConfigDir);\r
109         }\r
110 \r
111 #endif\r
112         RestoreEnchantUserFiles();\r
113         CleanUpFiles();\r
114     }\r
115     void CleanUpFiles()\r
116     {\r
117         //clean up personal dictionaries from home dir\r
118         DeleteDirAndFiles(GetTempUserEnchantDir());\r
119         DeleteDirAndFiles(AddToPath(GetDirectoryOfThisModule(), "lib"));\r
120         DeleteDirAndFiles(AddToPath(GetDirectoryOfThisModule(), "share"));\r
121     }\r
122 \r
123     std::string GetTempUserEnchantDir()\r
124     {\r
125         return GetEnchantHomeDirFromBase(GetDirectoryOfThisModule());\r
126     }\r
127 \r
128     void MoveEnchantUserFilesOutOfTheWay()\r
129     {\r
130         GetFilesOutOfTheWay(GetEnchantHomeDirFromBase(g_get_user_config_dir()));\r
131         GetFilesOutOfTheWay(GetEnchantHomeDirFromBase(g_get_home_dir()));\r
132     }\r
133 \r
134     void RestoreEnchantUserFiles()\r
135     {\r
136         RestoreFiles(GetEnchantHomeDirFromBase(g_get_user_config_dir()));\r
137         RestoreFiles(GetEnchantHomeDirFromBase(g_get_home_dir()));\r
138     }\r
139 \r
140 #define OUT_OF_THE_WAY ".real";\r
141 \r
142     void GetFilesOutOfTheWay(const std::string& dir)\r
143     {\r
144         std::string toTheSideDir = dir + OUT_OF_THE_WAY;\r
145         \r
146         if(DirExists(dir) && !DirExists(toTheSideDir))\r
147         {\r
148             MoveDir(dir, toTheSideDir);\r
149         }\r
150 \r
151         DeleteDirAndFiles(dir);\r
152     }\r
153 \r
154     void RestoreFiles(const std::string& dir)\r
155     {\r
156         std::string toTheSideDir = dir + OUT_OF_THE_WAY;\r
157         if(DirExists(toTheSideDir))\r
158         {\r
159             DeleteDirAndFiles(dir);\r
160             MoveDir(toTheSideDir, dir);\r
161         }\r
162     }\r
163 \r
164     std::string GetEnchantConfigDir()\r
165     {\r
166         return AddToPath(AddToPath(GetDirectoryOfThisModule(), "share"), "enchant");\r
167     }\r
168 \r
169     static bool DirExists(const std::string& dir)\r
170     {\r
171         return g_file_test(dir.c_str(), G_FILE_TEST_IS_DIR) != 0;\r
172     }\r
173 \r
174     static void MoveDir(const std::string& from, const std::string& to)\r
175     {\r
176         int result = g_rename(from.c_str(), to.c_str());\r
177         if(result!= 0)\r
178         {\r
179            perror("failed (will retry)");\r
180             // try once more.\r
181            result = g_rename(from.c_str(), to.c_str());\r
182         }\r
183         assert(result == 0);\r
184         if(result!= 0)\r
185         {\r
186            perror("failed (giving up)");\r
187         }\r
188     }\r
189 \r
190     static void DeleteDirAndFiles(const std::string& dir)\r
191     {\r
192         GDir* gdir = g_dir_open(dir.c_str(), 0, NULL);\r
193         if(gdir != NULL)\r
194         {\r
195             const gchar* filename;\r
196             for(;;){\r
197                 filename = g_dir_read_name(gdir);\r
198                 if(filename == NULL)\r
199                 {\r
200                     break;\r
201                 }\r
202                 std::string filepath = AddToPath(dir, filename);\r
203                                 if(g_file_test(filepath.c_str(), G_FILE_TEST_IS_DIR)){\r
204                     DeleteDirAndFiles(filepath);\r
205                 }\r
206                 else {\r
207                     DeleteFile(filepath);\r
208                 }\r
209             } \r
210             g_dir_close(gdir);\r
211         }\r
212         g_rmdir(dir.c_str());\r
213     }\r
214 \r
215     static std::string GetTemporaryFilename(const std::string & prefix){\r
216         char* tempFileName = tempnam(".", prefix.c_str());\r
217         std::string temp(tempFileName);\r
218         free(tempFileName);\r
219         return temp;\r
220     }\r
221 \r
222     static void CreateDirectory(const std::string& filepath)\r
223     {\r
224         g_mkdir_with_parents(filepath.c_str(), S_IREAD | S_IWRITE | S_IEXEC);\r
225     }\r
226     static void CreateFile(const std::string& filepath)\r
227     {\r
228         int fh = g_creat(filepath.c_str(), _S_IREAD | _S_IWRITE);\r
229         if(fh != -1) {\r
230             close(fh);\r
231     }\r
232     }\r
233     static void DeleteFile(const std::string& filepath)\r
234     {\r
235         if(FileExists(filepath)){\r
236             g_remove(filepath.c_str());\r
237         }\r
238     }\r
239     static bool FileExists(const std::string& filepath)\r
240     {\r
241         return(g_access(filepath.c_str(), 0)==0);\r
242     }\r
243 \r
244     std::string Convert(const std::wstring & ws)\r
245     {\r
246         gchar* str = g_utf16_to_utf8((gunichar2*)ws.c_str(), (glong)ws.length(), NULL, NULL, NULL);\r
247         std::string s(str);\r
248         g_free(str);\r
249         return s;\r
250     }\r
251 \r
252     std::wstring Convert(const std::string & s)\r
253     {\r
254         gunichar2* str = g_utf8_to_utf16(s.c_str(), (glong)s.length(), NULL, NULL, NULL);\r
255         std::wstring ws((wchar_t*)str);\r
256         g_free(str);\r
257         return ws;\r
258     }\r
259 \r
260     std::string GetDirectoryOfThisModule()\r
261     {\r
262         std::string result;\r
263 #if defined(_WIN32)\r
264         // should be in the same directory as our test fixture\r
265         WCHAR szFilename[MAX_PATH];\r
266         GetModuleFileName(NULL, (LPWSTR) &szFilename, sizeof(szFilename));\r
267         PathRemoveFileSpec((LPWSTR)&szFilename);\r
268 \r
269         result = Convert(szFilename);\r
270 #elif defined(ENABLE_BINRELOC) \r
271         gchar* prefix = gbr_find_prefix(NULL);\r
272         result = std::string(prefix);\r
273         g_free(prefix);\r
274 #endif\r
275         return result;\r
276       }\r
277 \r
278     std::string GetRegistryHomeDir()\r
279     {\r
280         return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir"));\r
281     }\r
282 \r
283     void SetRegistryHomeDir(const std::string & dir)\r
284     {\r
285         SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir", dir);\r
286     }\r
287 \r
288     void ClearRegistryHomeDir()\r
289     {\r
290         ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Home_Dir");\r
291     }\r
292 \r
293     std::string GetUserRegistryModuleDir()\r
294     {\r
295         return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir"));\r
296 \r
297     }\r
298 \r
299     void SetUserRegistryModuleDir(const std::string & dir)\r
300     {\r
301         SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir", dir);\r
302     }\r
303 \r
304     void ClearUserRegistryModuleDir()\r
305     {\r
306         ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Module_Dir");\r
307     }\r
308 \r
309     std::string GetMachineRegistryModuleDir()\r
310     {\r
311         return Convert(GetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir"));\r
312 \r
313     }\r
314 \r
315     void SetMachineRegistryModuleDir(const std::string & dir)\r
316     {\r
317         SetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir", dir);\r
318     }\r
319 \r
320     void ClearMachineRegistryModuleDir()\r
321     {\r
322         ClearRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Module_Dir");\r
323     }\r
324 \r
325     std::string GetUserRegistryConfigDir()\r
326     {\r
327         return Convert(GetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir"));\r
328     }\r
329 \r
330     void SetUserRegistryConfigDir(const std::string & dir)\r
331     {\r
332         SetRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir", dir);\r
333     }\r
334 \r
335     void ClearUserRegistryConfigDir()\r
336     {\r
337         ClearRegistryValue(HKEY_CURRENT_USER, L"Software\\Enchant\\Config", L"Data_Dir");\r
338     }\r
339 \r
340     std::string GetMachineRegistryConfigDir()\r
341     {\r
342         return Convert(GetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir"));\r
343     }\r
344 \r
345     void SetMachineRegistryConfigDir(const std::string & dir)\r
346     {\r
347         SetRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir", dir);\r
348     }\r
349 \r
350     void ClearMachineRegistryConfigDir()\r
351     {\r
352         ClearRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Enchant\\Config", L"Data_Dir");\r
353     }\r
354 \r
355     std::wstring GetRegistryValue(HKEY baseKey, const std::wstring& key, const std::wstring& valueName)\r
356   {\r
357       std::wstring result;\r
358 \r
359       WCHAR data[2048];\r
360       DWORD dwSize = sizeof(data) * sizeof(WCHAR);\r
361       HKEY hkey;\r
362 \r
363       if(RegOpenKeyEx(baseKey, \r
364                       key.c_str(), \r
365                       0, KEY_WRITE, &hkey) == ERROR_SUCCESS)\r
366       {\r
367          if(RegQueryValueEx(hkey, \r
368                             valueName.c_str(),\r
369                             0, \r
370                             NULL,\r
371                            (LPBYTE)&data, &dwSize) \r
372                                     == ERROR_SUCCESS){\r
373             result = std::wstring(data,dwSize);\r
374           }\r
375       }\r
376       return result;\r
377   }\r
378 \r
379   void SetRegistryValue(HKEY baseKey, \r
380                        const std::wstring& key, \r
381                        const std::wstring& valueName, \r
382                        const std::string& value)\r
383   {\r
384       SetRegistryValue(baseKey, key, valueName, Convert(value));\r
385   }\r
386   void SetRegistryValue(HKEY baseKey, \r
387                        const std::wstring& key, \r
388                        const std::wstring& valueName, \r
389                        const std::wstring& value)\r
390   {\r
391     HKEY hkey;\r
392     if(RegCreateKeyEx(baseKey, \r
393                       key.c_str(), \r
394                       0, NULL,\r
395                       REG_OPTION_NON_VOLATILE,\r
396                       KEY_WRITE,\r
397                       NULL, &hkey,\r
398                       NULL) == ERROR_SUCCESS)\r
399     {\r
400       RegSetValueEx(hkey, \r
401                     valueName.c_str(), \r
402                     0, \r
403                     REG_SZ, \r
404                     (LPBYTE)value.c_str(), \r
405                     (DWORD)((value.length()+1)*sizeof(wchar_t)) );\r
406     \r
407       RegCloseKey(hkey);\r
408     }\r
409   }\r
410 \r
411   void ClearRegistryValue(HKEY baseKey,\r
412       const std::wstring& key,\r
413       const std::wstring& valueName)\r
414   {\r
415     HKEY hkey;\r
416     if(RegOpenKeyEx(baseKey, \r
417                     key.c_str(), \r
418                     0, KEY_WRITE, &hkey) == ERROR_SUCCESS)\r
419     {\r
420         RegDeleteValue(hkey, valueName.c_str());\r
421         RegCloseKey(hkey);\r
422     }\r
423   }\r
424 \r
425 \r
426   static std::string AddToPath(const std::string & path, const std::string & fileOrDirName)\r
427     {\r
428         std::string result;\r
429         gchar* filename = g_build_filename(path.c_str(), fileOrDirName.c_str(), NULL);\r
430         result = std::string(filename);\r
431         g_free(filename);\r
432 \r
433         return result;\r
434     }\r
435 \r
436     static std::string GetEnchantHomeDirFromBase(const std::string& basePath)\r
437     {\r
438 #ifdef XP_TARGET_COCOA\r
439         return AddToPath(AddToPath(AddToPath(basePath,"Library"), \r
440                                                        "Application Support"), \r
441                                                        "Enchant");\r
442 #elif defined(_WIN32)\r
443         return AddToPath(basePath,"enchant");\r
444 #else\r
445         return AddToPath(basePath,".enchant");\r
446 #endif\r
447     }\r
448 };\r
449 \r
450 #endif\r