diff options
Diffstat (limited to 'src/libs/dutil/test/DUtilUnitTest/IniUtilTest.cpp')
-rw-r--r-- | src/libs/dutil/test/DUtilUnitTest/IniUtilTest.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/src/libs/dutil/test/DUtilUnitTest/IniUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/IniUtilTest.cpp new file mode 100644 index 00000000..946f19c5 --- /dev/null +++ b/src/libs/dutil/test/DUtilUnitTest/IniUtilTest.cpp | |||
@@ -0,0 +1,345 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | using namespace System; | ||
6 | using namespace Xunit; | ||
7 | using namespace WixBuildTools::TestSupport; | ||
8 | |||
9 | typedef HRESULT (__clrcall *IniFormatParameters)( | ||
10 | INI_HANDLE | ||
11 | ); | ||
12 | |||
13 | namespace DutilTests | ||
14 | { | ||
15 | public ref class IniUtil | ||
16 | { | ||
17 | public: | ||
18 | [Fact] | ||
19 | void IniUtilTest() | ||
20 | { | ||
21 | HRESULT hr = S_OK; | ||
22 | LPWSTR sczTempIniFilePath = NULL; | ||
23 | LPWSTR sczTempIniFileDir = NULL; | ||
24 | LPWSTR wzIniContents = L" PlainValue = \t Blah \r\n;CommentHere\r\n[Section1]\r\n ;Another Comment With = Equal Sign\r\nSection1ValueA=Foo\r\n\r\nSection1ValueB=Bar\r\n[Section2]\r\nSection2ValueA=Cha\r\nArray[0]=Arr\r\n"; | ||
25 | LPWSTR wzScriptContents = L"setf ~PlainValue Blah\r\n;CommentHere\r\n\r\nsetf ~Section1\\Section1ValueA Foo\r\n\r\nsetf ~Section1\\Section1ValueB Bar\r\nsetf ~Section2\\Section2ValueA Cha\r\nsetf ~Section2\\Array[0] Arr\r\n"; | ||
26 | |||
27 | DutilInitialize(&DutilTestTraceError); | ||
28 | |||
29 | try | ||
30 | { | ||
31 | hr = PathExpand(&sczTempIniFilePath, L"%TEMP%\\IniUtilTest\\Test.ini", PATH_EXPAND_ENVIRONMENT); | ||
32 | NativeAssert::Succeeded(hr, "Failed to get path to temp INI file"); | ||
33 | |||
34 | hr = PathGetDirectory(sczTempIniFilePath, &sczTempIniFileDir); | ||
35 | NativeAssert::Succeeded(hr, "Failed to get directory to temp INI file"); | ||
36 | |||
37 | hr = DirEnsureDelete(sczTempIniFileDir, TRUE, TRUE); | ||
38 | if (E_PATHNOTFOUND == hr) | ||
39 | { | ||
40 | hr = S_OK; | ||
41 | } | ||
42 | NativeAssert::Succeeded(hr, "Failed to delete IniUtilTest directory: {0}", sczTempIniFileDir); | ||
43 | |||
44 | hr = DirEnsureExists(sczTempIniFileDir, NULL); | ||
45 | NativeAssert::Succeeded(hr, "Failed to ensure temp directory exists: {0}", sczTempIniFileDir); | ||
46 | |||
47 | // Tests parsing, then modifying a regular INI file | ||
48 | TestReadThenWrite(sczTempIniFilePath, StandardIniFormat, wzIniContents); | ||
49 | |||
50 | // Tests programmatically creating from scratch, then parsing an INI file | ||
51 | TestWriteThenRead(sczTempIniFilePath, StandardIniFormat); | ||
52 | |||
53 | // Tests parsing, then modifying a regular INI file | ||
54 | TestReadThenWrite(sczTempIniFilePath, ScriptFormat, wzScriptContents); | ||
55 | |||
56 | // Tests programmatically creating from scratch, then parsing an INI file | ||
57 | TestWriteThenRead(sczTempIniFilePath, ScriptFormat); | ||
58 | } | ||
59 | finally | ||
60 | { | ||
61 | ReleaseStr(sczTempIniFilePath); | ||
62 | ReleaseStr(sczTempIniFileDir); | ||
63 | DutilUninitialize(); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | private: | ||
68 | void AssertValue(INI_HANDLE iniHandle, LPCWSTR wzValueName, LPCWSTR wzValue) | ||
69 | { | ||
70 | HRESULT hr = S_OK; | ||
71 | LPWSTR sczValue = NULL; | ||
72 | |||
73 | try | ||
74 | { | ||
75 | hr = IniGetValue(iniHandle, wzValueName, &sczValue); | ||
76 | NativeAssert::Succeeded(hr, "Failed to get ini value: {0}", wzValueName); | ||
77 | |||
78 | if (0 != wcscmp(sczValue, wzValue)) | ||
79 | { | ||
80 | hr = E_FAIL; | ||
81 | ExitOnFailure(hr, "Expected to find value in INI: '%ls'='%ls' - but found value '%ls' instead", wzValueName, wzValue, sczValue); | ||
82 | } | ||
83 | } | ||
84 | finally | ||
85 | { | ||
86 | ReleaseStr(sczValue); | ||
87 | } | ||
88 | |||
89 | LExit: | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | void AssertNoValue(INI_HANDLE iniHandle, LPCWSTR wzValueName) | ||
94 | { | ||
95 | HRESULT hr = S_OK; | ||
96 | LPWSTR sczValue = NULL; | ||
97 | |||
98 | try | ||
99 | { | ||
100 | hr = IniGetValue(iniHandle, wzValueName, &sczValue); | ||
101 | if (E_NOTFOUND != hr) | ||
102 | { | ||
103 | if (SUCCEEDED(hr)) | ||
104 | { | ||
105 | hr = E_FAIL; | ||
106 | } | ||
107 | ExitOnFailure(hr, "INI value shouldn't have been found: %ls", wzValueName); | ||
108 | } | ||
109 | } | ||
110 | finally | ||
111 | { | ||
112 | ReleaseStr(sczValue); | ||
113 | } | ||
114 | |||
115 | LExit: | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | static HRESULT StandardIniFormat(__inout INI_HANDLE iniHandle) | ||
120 | { | ||
121 | HRESULT hr = S_OK; | ||
122 | |||
123 | hr = IniSetOpenTag(iniHandle, L"[", L"]"); | ||
124 | NativeAssert::Succeeded(hr, "Failed to set open tag settings on ini handle"); | ||
125 | |||
126 | hr = IniSetValueStyle(iniHandle, NULL, L"="); | ||
127 | NativeAssert::Succeeded(hr, "Failed to set value separator setting on ini handle"); | ||
128 | |||
129 | hr = IniSetCommentStyle(iniHandle, L";"); | ||
130 | NativeAssert::Succeeded(hr, "Failed to set comment style setting on ini handle"); | ||
131 | |||
132 | return hr; | ||
133 | } | ||
134 | |||
135 | static HRESULT ScriptFormat(__inout INI_HANDLE iniHandle) | ||
136 | { | ||
137 | HRESULT hr = S_OK; | ||
138 | |||
139 | hr = IniSetValueStyle(iniHandle, L"setf ~", L" "); | ||
140 | NativeAssert::Succeeded(hr, "Failed to set value separator setting on ini handle"); | ||
141 | |||
142 | return hr; | ||
143 | } | ||
144 | |||
145 | void TestReadThenWrite(LPWSTR wzIniFilePath, IniFormatParameters SetFormat, LPCWSTR wzContents) | ||
146 | { | ||
147 | HRESULT hr = S_OK; | ||
148 | INI_HANDLE iniHandle = NULL; | ||
149 | INI_HANDLE iniHandle2 = NULL; | ||
150 | INI_VALUE *rgValues = NULL; | ||
151 | DWORD cValues = 0; | ||
152 | |||
153 | try | ||
154 | { | ||
155 | hr = FileWrite(wzIniFilePath, 0, reinterpret_cast<LPCBYTE>(wzContents), lstrlenW(wzContents) * sizeof(WCHAR), NULL); | ||
156 | NativeAssert::Succeeded(hr, "Failed to write out INI file"); | ||
157 | |||
158 | hr = IniInitialize(&iniHandle); | ||
159 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
160 | |||
161 | hr = SetFormat(iniHandle); | ||
162 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
163 | |||
164 | hr = IniParse(iniHandle, wzIniFilePath, NULL); | ||
165 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
166 | |||
167 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
168 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
169 | |||
170 | NativeAssert::Equal<DWORD>(5, cValues); | ||
171 | |||
172 | AssertValue(iniHandle, L"PlainValue", L"Blah"); | ||
173 | AssertNoValue(iniHandle, L"PlainValue2"); | ||
174 | AssertValue(iniHandle, L"Section1\\Section1ValueA", L"Foo"); | ||
175 | AssertValue(iniHandle, L"Section1\\Section1ValueB", L"Bar"); | ||
176 | AssertValue(iniHandle, L"Section2\\Section2ValueA", L"Cha"); | ||
177 | AssertNoValue(iniHandle, L"Section1\\ValueDoesntExist"); | ||
178 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
179 | |||
180 | hr = IniSetValue(iniHandle, L"PlainValue2", L"Blah2"); | ||
181 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
182 | |||
183 | hr = IniSetValue(iniHandle, L"Section1\\CreatedValue", L"Woo"); | ||
184 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
185 | |||
186 | hr = IniSetValue(iniHandle, L"Section2\\Array[0]", L"Arrmod"); | ||
187 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
188 | |||
189 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
190 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
191 | |||
192 | NativeAssert::Equal<DWORD>(7, cValues); | ||
193 | |||
194 | AssertValue(iniHandle, L"PlainValue", L"Blah"); | ||
195 | AssertValue(iniHandle, L"PlainValue2", L"Blah2"); | ||
196 | AssertValue(iniHandle, L"Section1\\Section1ValueA", L"Foo"); | ||
197 | AssertValue(iniHandle, L"Section1\\Section1ValueB", L"Bar"); | ||
198 | AssertValue(iniHandle, L"Section2\\Section2ValueA", L"Cha"); | ||
199 | AssertNoValue(iniHandle, L"Section1\\ValueDoesntExist"); | ||
200 | AssertValue(iniHandle, L"Section1\\CreatedValue", L"Woo"); | ||
201 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arrmod"); | ||
202 | |||
203 | // Try deleting a value as well | ||
204 | hr = IniSetValue(iniHandle, L"Section1\\Section1ValueB", NULL); | ||
205 | NativeAssert::Succeeded(hr, "Failed to kill value in INI"); | ||
206 | |||
207 | hr = IniWriteFile(iniHandle, NULL, FILE_ENCODING_UNSPECIFIED); | ||
208 | NativeAssert::Succeeded(hr, "Failed to write ini file back out to disk"); | ||
209 | |||
210 | ReleaseNullIni(iniHandle); | ||
211 | // Now re-parse the INI we just wrote and make sure it matches the values we expect | ||
212 | hr = IniInitialize(&iniHandle2); | ||
213 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
214 | |||
215 | hr = SetFormat(iniHandle2); | ||
216 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
217 | |||
218 | hr = IniParse(iniHandle2, wzIniFilePath, NULL); | ||
219 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
220 | |||
221 | hr = IniGetValueList(iniHandle2, &rgValues, &cValues); | ||
222 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
223 | |||
224 | NativeAssert::Equal<DWORD>(6, cValues); | ||
225 | |||
226 | AssertValue(iniHandle2, L"PlainValue", L"Blah"); | ||
227 | AssertValue(iniHandle2, L"PlainValue2", L"Blah2"); | ||
228 | AssertValue(iniHandle2, L"Section1\\Section1ValueA", L"Foo"); | ||
229 | AssertNoValue(iniHandle2, L"Section1\\Section1ValueB"); | ||
230 | AssertValue(iniHandle2, L"Section2\\Section2ValueA", L"Cha"); | ||
231 | AssertNoValue(iniHandle2, L"Section1\\ValueDoesntExist"); | ||
232 | AssertValue(iniHandle2, L"Section1\\CreatedValue", L"Woo"); | ||
233 | AssertValue(iniHandle2, L"Section2\\Array[0]", L"Arrmod"); | ||
234 | } | ||
235 | finally | ||
236 | { | ||
237 | ReleaseIni(iniHandle); | ||
238 | ReleaseIni(iniHandle2); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | void TestWriteThenRead(LPWSTR wzIniFilePath, IniFormatParameters SetFormat) | ||
243 | { | ||
244 | HRESULT hr = S_OK; | ||
245 | INI_HANDLE iniHandle = NULL; | ||
246 | INI_HANDLE iniHandle2 = NULL; | ||
247 | INI_VALUE *rgValues = NULL; | ||
248 | DWORD cValues = 0; | ||
249 | |||
250 | try | ||
251 | { | ||
252 | hr = FileEnsureDelete(wzIniFilePath); | ||
253 | NativeAssert::Succeeded(hr, "Failed to ensure file is deleted"); | ||
254 | |||
255 | hr = IniInitialize(&iniHandle); | ||
256 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
257 | |||
258 | hr = SetFormat(iniHandle); | ||
259 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
260 | |||
261 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
262 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
263 | |||
264 | NativeAssert::Equal<DWORD>(0, cValues); | ||
265 | |||
266 | hr = IniSetValue(iniHandle, L"Value1", L"BlahTypo"); | ||
267 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
268 | |||
269 | hr = IniSetValue(iniHandle, L"Value2", L"Blah2"); | ||
270 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
271 | |||
272 | hr = IniSetValue(iniHandle, L"Section1\\Value1", L"Section1Value1"); | ||
273 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
274 | |||
275 | hr = IniSetValue(iniHandle, L"Section1\\Value2", L"Section1Value2"); | ||
276 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
277 | |||
278 | hr = IniSetValue(iniHandle, L"Section2\\Value1", L"Section2Value1"); | ||
279 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
280 | |||
281 | hr = IniSetValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
282 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
283 | |||
284 | hr = IniSetValue(iniHandle, L"Value3", L"Blah3"); | ||
285 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
286 | |||
287 | hr = IniSetValue(iniHandle, L"Value4", L"Blah4"); | ||
288 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
289 | |||
290 | hr = IniSetValue(iniHandle, L"Value4", NULL); | ||
291 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
292 | |||
293 | hr = IniSetValue(iniHandle, L"Value1", L"Blah1"); | ||
294 | NativeAssert::Succeeded(hr, "Failed to set value in INI"); | ||
295 | |||
296 | hr = IniGetValueList(iniHandle, &rgValues, &cValues); | ||
297 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
298 | |||
299 | NativeAssert::Equal<DWORD>(8, cValues); | ||
300 | |||
301 | AssertValue(iniHandle, L"Value1", L"Blah1"); | ||
302 | AssertValue(iniHandle, L"Value2", L"Blah2"); | ||
303 | AssertValue(iniHandle, L"Value3", L"Blah3"); | ||
304 | AssertNoValue(iniHandle, L"Value4"); | ||
305 | AssertValue(iniHandle, L"Section1\\Value1", L"Section1Value1"); | ||
306 | AssertValue(iniHandle, L"Section1\\Value2", L"Section1Value2"); | ||
307 | AssertValue(iniHandle, L"Section2\\Value1", L"Section2Value1"); | ||
308 | AssertValue(iniHandle, L"Section2\\Array[0]", L"Arr"); | ||
309 | |||
310 | hr = IniWriteFile(iniHandle, wzIniFilePath, FILE_ENCODING_UNSPECIFIED); | ||
311 | NativeAssert::Succeeded(hr, "Failed to write ini file back out to disk"); | ||
312 | |||
313 | ReleaseNullIni(iniHandle); | ||
314 | // Now re-parse the INI we just wrote and make sure it matches the values we expect | ||
315 | hr = IniInitialize(&iniHandle2); | ||
316 | NativeAssert::Succeeded(hr, "Failed to initialize INI object"); | ||
317 | |||
318 | hr = SetFormat(iniHandle2); | ||
319 | NativeAssert::Succeeded(hr, "Failed to set parameters for INI file"); | ||
320 | |||
321 | hr = IniParse(iniHandle2, wzIniFilePath, NULL); | ||
322 | NativeAssert::Succeeded(hr, "Failed to parse INI file"); | ||
323 | |||
324 | hr = IniGetValueList(iniHandle2, &rgValues, &cValues); | ||
325 | NativeAssert::Succeeded(hr, "Failed to get list of values in INI"); | ||
326 | |||
327 | NativeAssert::Equal<DWORD>(7, cValues); | ||
328 | |||
329 | AssertValue(iniHandle2, L"Value1", L"Blah1"); | ||
330 | AssertValue(iniHandle2, L"Value2", L"Blah2"); | ||
331 | AssertValue(iniHandle2, L"Value3", L"Blah3"); | ||
332 | AssertNoValue(iniHandle2, L"Value4"); | ||
333 | AssertValue(iniHandle2, L"Section1\\Value1", L"Section1Value1"); | ||
334 | AssertValue(iniHandle2, L"Section1\\Value2", L"Section1Value2"); | ||
335 | AssertValue(iniHandle2, L"Section2\\Value1", L"Section2Value1"); | ||
336 | AssertValue(iniHandle2, L"Section2\\Array[0]", L"Arr"); | ||
337 | } | ||
338 | finally | ||
339 | { | ||
340 | ReleaseIni(iniHandle); | ||
341 | ReleaseIni(iniHandle2); | ||
342 | } | ||
343 | } | ||
344 | }; | ||
345 | } | ||