scrrun: Implement IEnumVARIANT support for dictionary.
[wine/multimedia.git] / dlls / scrrun / tests / dictionary.c
blob18698610aa65b73ec68d1b584aa64eee0982bb3b
1 /*
2 * Copyright (C) 2012 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #include <stdio.h>
22 #include "windows.h"
23 #include "ole2.h"
24 #include "oleauto.h"
25 #include "olectl.h"
26 #include "dispex.h"
28 #include "wine/test.h"
30 #include "scrrun.h"
32 static void test_interfaces(void)
34 static const WCHAR key_add[] = {'a', 0};
35 static const WCHAR key_add_value[] = {'a', 0};
36 static const WCHAR key_non_exist[] = {'b', 0};
37 HRESULT hr;
38 IDispatch *disp;
39 IDispatchEx *dispex;
40 IDictionary *dict;
41 IObjectWithSite *site;
42 VARIANT key, value;
43 VARIANT_BOOL exists;
44 LONG count = 0;
46 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
47 &IID_IDispatch, (void**)&disp);
48 ok(hr == S_OK, "got 0x%08x\n", hr);
50 VariantInit(&key);
51 VariantInit(&value);
53 hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
54 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
56 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
57 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
59 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
60 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
62 V_VT(&key) = VT_BSTR;
63 V_BSTR(&key) = SysAllocString(key_add);
64 V_VT(&value) = VT_BSTR;
65 V_BSTR(&value) = SysAllocString(key_add_value);
66 hr = IDictionary_Add(dict, &key, &value);
67 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
68 VariantClear(&value);
70 exists = VARIANT_FALSE;
71 hr = IDictionary_Exists(dict, &key, &exists);
72 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
73 ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n");
74 VariantClear(&key);
76 exists = VARIANT_TRUE;
77 V_VT(&key) = VT_BSTR;
78 V_BSTR(&key) = SysAllocString(key_non_exist);
79 hr = IDictionary_Exists(dict, &key, &exists);
80 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
81 ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n");
82 VariantClear(&key);
84 hr = IDictionary_get_Count(dict, &count);
85 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
86 ok(count == 1, "got %d, expected 1\n", count);
88 IDictionary_Release(dict);
89 IDispatch_Release(disp);
92 static void test_comparemode(void)
94 CompareMethod method;
95 IDictionary *dict;
96 VARIANT key, item;
97 HRESULT hr;
99 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
100 &IID_IDictionary, (void**)&dict);
101 ok(hr == S_OK, "got 0x%08x\n", hr);
103 if (0) /* crashes on native */
104 hr = IDictionary_get_CompareMode(dict, NULL);
106 method = 10;
107 hr = IDictionary_get_CompareMode(dict, &method);
108 ok(hr == S_OK, "got 0x%08x\n", hr);
109 ok(method == BinaryCompare, "got %d\n", method);
111 /* invalid mode value is not checked */
112 hr = IDictionary_put_CompareMode(dict, 10);
113 ok(hr == S_OK, "got 0x%08x\n", hr);
115 hr = IDictionary_get_CompareMode(dict, &method);
116 ok(hr == S_OK, "got 0x%08x\n", hr);
117 ok(method == 10, "got %d\n", method);
119 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
120 ok(hr == S_OK, "got 0x%08x\n", hr);
122 hr = IDictionary_get_CompareMode(dict, &method);
123 ok(hr == S_OK, "got 0x%08x\n", hr);
124 ok(method == DatabaseCompare, "got %d\n", method);
126 /* try to change mode of a non-empty dict */
127 V_VT(&key) = VT_I2;
128 V_I2(&key) = 0;
129 VariantInit(&item);
130 hr = IDictionary_Add(dict, &key, &item);
131 ok(hr == S_OK, "got 0x%08x\n", hr);
133 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
134 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
136 IDictionary_Release(dict);
139 static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
141 DWORD hash = 0;
143 while (*str) {
144 WCHAR ch;
146 if (method == TextCompare || method == DatabaseCompare)
147 ch = PtrToInt(CharLowerW(IntToPtr(*str)));
148 else
149 ch = *str;
151 hash += (hash << 4) + ch;
152 str++;
155 return hash % 1201;
158 static DWORD get_num_hash(FLOAT num)
160 return (*((DWORD*)&num)) % 1201;
163 typedef union
165 struct
167 unsigned int m : 23;
168 unsigned int exp_bias : 8;
169 unsigned int sign : 1;
170 } i;
171 float f;
172 } R4_FIELDS;
174 typedef union
176 struct
178 unsigned int m_lo : 32; /* 52 bits of precision */
179 unsigned int m_hi : 20;
180 unsigned int exp_bias : 11; /* bias == 1023 */
181 unsigned int sign : 1;
182 } i;
183 double d;
184 } R8_FIELDS;
186 static void test_hash_value(void)
188 /* string test data */
189 static const WCHAR str_hash_tests[][10] = {
190 {'a','b','c','d',0},
191 {'a','B','C','d','1',0},
192 {'1','2','3',0},
193 {'A',0},
194 {'a',0},
195 { 0 }
198 static const int int_hash_tests[] = {
199 0, -1, 100, 1, 255
202 static const FLOAT float_hash_tests[] = {
203 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
206 IDictionary *dict;
207 VARIANT key, hash;
208 R8_FIELDS fx8;
209 R4_FIELDS fx4;
210 HRESULT hr;
211 unsigned i;
213 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
214 &IID_IDictionary, (void**)&dict);
215 ok(hr == S_OK, "got 0x%08x\n", hr);
217 V_VT(&key) = VT_BSTR;
218 V_BSTR(&key) = NULL;
219 VariantInit(&hash);
220 hr = IDictionary_get_HashVal(dict, &key, &hash);
221 ok(hr == S_OK, "got 0x%08x\n", hr);
222 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
223 ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash));
225 for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) {
226 DWORD expected = get_str_hash(str_hash_tests[i], BinaryCompare);
228 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
229 ok(hr == S_OK, "got 0x%08x\n", hr);
231 V_VT(&key) = VT_BSTR;
232 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
233 VariantInit(&hash);
234 hr = IDictionary_get_HashVal(dict, &key, &hash);
235 ok(hr == S_OK, "got 0x%08x\n", hr);
236 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
237 ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
238 expected);
239 VariantClear(&key);
241 expected = get_str_hash(str_hash_tests[i], TextCompare);
242 hr = IDictionary_put_CompareMode(dict, TextCompare);
243 ok(hr == S_OK, "got 0x%08x\n", hr);
245 V_VT(&key) = VT_BSTR;
246 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
247 VariantInit(&hash);
248 hr = IDictionary_get_HashVal(dict, &key, &hash);
249 ok(hr == S_OK, "got 0x%08x\n", hr);
250 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
251 ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
252 expected);
253 VariantClear(&key);
255 expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
256 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
257 ok(hr == S_OK, "got 0x%08x\n", hr);
259 V_VT(&key) = VT_BSTR;
260 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
261 VariantInit(&hash);
262 hr = IDictionary_get_HashVal(dict, &key, &hash);
263 ok(hr == S_OK, "got 0x%08x\n", hr);
264 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
265 ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
266 expected);
267 VariantClear(&key);
270 V_VT(&key) = VT_INT;
271 V_INT(&key) = 1;
272 VariantInit(&hash);
273 hr = IDictionary_get_HashVal(dict, &key, &hash);
274 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
275 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
276 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
278 V_VT(&key) = VT_UINT;
279 V_UINT(&key) = 1;
280 VariantInit(&hash);
281 hr = IDictionary_get_HashVal(dict, &key, &hash);
282 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
283 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
284 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
286 V_VT(&key) = VT_I1;
287 V_I1(&key) = 1;
288 VariantInit(&hash);
289 hr = IDictionary_get_HashVal(dict, &key, &hash);
290 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
291 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
292 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "got hash 0x%08x\n", V_I4(&hash));
294 V_VT(&key) = VT_I8;
295 V_I8(&key) = 1;
296 VariantInit(&hash);
297 hr = IDictionary_get_HashVal(dict, &key, &hash);
298 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
299 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
300 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
302 V_VT(&key) = VT_UI2;
303 V_UI2(&key) = 1;
304 VariantInit(&hash);
305 hr = IDictionary_get_HashVal(dict, &key, &hash);
306 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
307 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
308 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
310 V_VT(&key) = VT_UI4;
311 V_UI4(&key) = 1;
312 VariantInit(&hash);
313 hr = IDictionary_get_HashVal(dict, &key, &hash);
314 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
315 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
316 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
318 for (i = 0; i < sizeof(int_hash_tests)/sizeof(int_hash_tests[0]); i++) {
319 DWORD expected = get_num_hash(int_hash_tests[i]);
321 V_VT(&key) = VT_I2;
322 V_I2(&key) = int_hash_tests[i];
323 VariantInit(&hash);
324 hr = IDictionary_get_HashVal(dict, &key, &hash);
325 ok(hr == S_OK, "got 0x%08x\n", hr);
326 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
327 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
328 expected);
330 V_VT(&key) = VT_I4;
331 V_I4(&key) = int_hash_tests[i];
332 VariantInit(&hash);
333 hr = IDictionary_get_HashVal(dict, &key, &hash);
334 ok(hr == S_OK, "got 0x%08x\n", hr);
335 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
336 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
337 expected);
339 expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]);
340 V_VT(&key) = VT_UI1;
341 V_UI1(&key) = int_hash_tests[i];
342 VariantInit(&hash);
343 hr = IDictionary_get_HashVal(dict, &key, &hash);
344 ok(hr == S_OK, "got 0x%08x\n", hr);
345 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
346 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
347 expected);
350 /* nan */
351 fx4.f = 10.0;
352 fx4.i.exp_bias = 0xff;
354 V_VT(&key) = VT_R4;
355 V_R4(&key) = fx4.f;
356 VariantInit(&hash);
357 hr = IDictionary_get_HashVal(dict, &key, &hash);
358 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
359 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
360 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
361 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
363 /* inf */
364 fx4.f = 10.0;
365 fx4.i.m = 0;
366 fx4.i.exp_bias = 0xff;
368 V_VT(&key) = VT_R4;
369 V_R4(&key) = fx4.f;
370 V_I4(&hash) = 10;
371 hr = IDictionary_get_HashVal(dict, &key, &hash);
372 ok(hr == S_OK, "got 0x%08x\n", hr);
373 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
374 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
376 /* nan */
377 fx8.d = 10.0;
378 fx8.i.exp_bias = 0x7ff;
380 V_VT(&key) = VT_R8;
381 V_R8(&key) = fx8.d;
382 VariantInit(&hash);
383 hr = IDictionary_get_HashVal(dict, &key, &hash);
384 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
385 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
386 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
387 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
389 /* inf */
390 fx8.d = 10.0;
391 fx8.i.m_lo = 0;
392 fx8.i.m_hi = 0;
393 fx8.i.exp_bias = 0x7ff;
395 V_VT(&key) = VT_R8;
396 V_R8(&key) = fx8.d;
397 V_I4(&hash) = 10;
398 hr = IDictionary_get_HashVal(dict, &key, &hash);
399 ok(hr == S_OK, "got 0x%08x\n", hr);
400 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
401 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
403 for (i = 0; i < sizeof(float_hash_tests)/sizeof(float_hash_tests[0]); i++) {
404 DWORD expected = get_num_hash(float_hash_tests[i]);
406 V_VT(&key) = VT_R4;
407 V_R4(&key) = float_hash_tests[i];
408 VariantInit(&hash);
409 hr = IDictionary_get_HashVal(dict, &key, &hash);
410 ok(hr == S_OK, "got 0x%08x\n", hr);
411 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
412 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
413 expected);
415 V_VT(&key) = VT_R8;
416 V_R8(&key) = float_hash_tests[i];
417 VariantInit(&hash);
418 hr = IDictionary_get_HashVal(dict, &key, &hash);
419 ok(hr == S_OK, "got 0x%08x\n", hr);
420 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
421 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
422 expected);
425 IDictionary_Release(dict);
428 static void test_Exists(void)
430 VARIANT_BOOL exists;
431 IDictionary *dict;
432 VARIANT key, item;
433 HRESULT hr;
435 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
436 &IID_IDictionary, (void**)&dict);
437 ok(hr == S_OK, "got 0x%08x\n", hr);
439 if (0) /* crashes on native */
440 hr = IDictionary_Exists(dict, NULL, NULL);
442 V_VT(&key) = VT_I2;
443 V_I2(&key) = 0;
444 hr = IDictionary_Exists(dict, &key, NULL);
445 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
447 V_VT(&key) = VT_I2;
448 V_I2(&key) = 0;
449 exists = VARIANT_TRUE;
450 hr = IDictionary_Exists(dict, &key, &exists);
451 ok(hr == S_OK, "got 0x%08x\n", hr);
452 ok(exists == VARIANT_FALSE, "got %x\n", exists);
454 VariantInit(&item);
455 hr = IDictionary_Add(dict, &key, &item);
456 ok(hr == S_OK, "got 0x%08x\n", hr);
458 V_VT(&key) = VT_R4;
459 V_R4(&key) = 0.0;
460 hr = IDictionary_Add(dict, &key, &item);
461 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "got 0x%08x\n", hr);
463 V_VT(&key) = VT_I2;
464 V_I2(&key) = 0;
465 hr = IDictionary_Exists(dict, &key, NULL);
466 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
468 V_VT(&key) = VT_I2;
469 V_I2(&key) = 0;
470 exists = VARIANT_FALSE;
471 hr = IDictionary_Exists(dict, &key, &exists);
472 ok(hr == S_OK, "got 0x%08x\n", hr);
473 ok(exists == VARIANT_TRUE, "got %x\n", exists);
475 /* key of different type, but resolves to same hash value */
476 V_VT(&key) = VT_R4;
477 V_R4(&key) = 0.0;
478 exists = VARIANT_FALSE;
479 hr = IDictionary_Exists(dict, &key, &exists);
480 ok(hr == S_OK, "got 0x%08x\n", hr);
481 ok(exists == VARIANT_TRUE, "got %x\n", exists);
483 IDictionary_Release(dict);
486 static void test_Keys(void)
488 VARIANT key, keys, item;
489 IDictionary *dict;
490 LONG index;
491 HRESULT hr;
493 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
494 &IID_IDictionary, (void**)&dict);
495 ok(hr == S_OK, "got 0x%08x\n", hr);
497 hr = IDictionary_Keys(dict, NULL);
498 ok(hr == S_OK, "got 0x%08x\n", hr);
500 VariantInit(&keys);
501 hr = IDictionary_Keys(dict, &keys);
502 ok(hr == S_OK, "got 0x%08x\n", hr);
503 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
504 VariantClear(&keys);
506 V_VT(&key) = VT_R4;
507 V_R4(&key) = 0.0;
508 VariantInit(&item);
509 hr = IDictionary_Add(dict, &key, &item);
510 ok(hr == S_OK, "got 0x%08x\n", hr);
512 VariantInit(&keys);
513 hr = IDictionary_Keys(dict, &keys);
514 ok(hr == S_OK, "got 0x%08x\n", hr);
515 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
517 VariantInit(&key);
518 index = 0;
519 hr = SafeArrayGetElement(V_ARRAY(&keys), &index, &key);
520 ok(hr == S_OK, "got 0x%08x\n", hr);
521 ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key));
523 index = SafeArrayGetDim(V_ARRAY(&keys));
524 ok(index == 1, "got %d\n", index);
526 hr = SafeArrayGetUBound(V_ARRAY(&keys), 1, &index);
527 ok(hr == S_OK, "got 0x%08x\n", hr);
528 ok(index == 0, "got %d\n", index);
530 VariantClear(&keys);
532 IDictionary_Release(dict);
535 static void test_Remove(void)
537 VARIANT key, item;
538 IDictionary *dict;
539 HRESULT hr;
541 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
542 &IID_IDictionary, (void**)&dict);
543 ok(hr == S_OK, "got 0x%08x\n", hr);
545 if (0)
546 hr = IDictionary_Remove(dict, NULL);
548 /* nothing added yet */
549 V_VT(&key) = VT_R4;
550 V_R4(&key) = 0.0;
551 hr = IDictionary_Remove(dict, &key);
552 ok(hr == CTL_E_ELEMENT_NOT_FOUND, "got 0x%08x\n", hr);
554 VariantInit(&item);
555 hr = IDictionary_Add(dict, &key, &item);
556 ok(hr == S_OK, "got 0x%08x\n", hr);
558 hr = IDictionary_Remove(dict, &key);
559 ok(hr == S_OK, "got 0x%08x\n", hr);
561 IDictionary_Release(dict);
564 static void test_Item(void)
566 VARIANT key, item;
567 IDictionary *dict;
568 HRESULT hr;
570 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
571 &IID_IDictionary, (void**)&dict);
572 ok(hr == S_OK, "got 0x%08x\n", hr);
574 V_VT(&key) = VT_I2;
575 V_I2(&key) = 10;
576 V_VT(&item) = VT_I2;
577 V_I2(&item) = 123;
578 hr = IDictionary_get_Item(dict, &key, &item);
579 ok(hr == S_OK, "got 0x%08x\n", hr);
580 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
582 V_VT(&key) = VT_I2;
583 V_I2(&key) = 10;
584 V_VT(&item) = VT_I2;
585 hr = IDictionary_get_Item(dict, &key, &item);
586 ok(hr == S_OK, "got 0x%08x\n", hr);
587 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
589 IDictionary_Release(dict);
592 static void test_Add(void)
594 static const WCHAR testW[] = {'t','e','s','t','W',0};
595 VARIANT key, item;
596 IDictionary *dict;
597 HRESULT hr;
598 BSTR str;
600 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
601 &IID_IDictionary, (void**)&dict);
602 ok(hr == S_OK, "got 0x%08x\n", hr);
604 str = SysAllocString(testW);
605 V_VT(&key) = VT_I2;
606 V_I2(&key) = 1;
607 V_VT(&item) = VT_BSTR|VT_BYREF;
608 V_BSTRREF(&item) = &str;
609 hr = IDictionary_Add(dict, &key, &item);
610 ok(hr == S_OK, "got 0x%08x\n", hr);
612 hr = IDictionary_get_Item(dict, &key, &item);
613 ok(hr == S_OK, "got 0x%08x\n", hr);
614 ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item));
616 SysFreeString(str);
618 IDictionary_Release(dict);
621 static void test_IEnumVARIANT(void)
623 IUnknown *enum1, *enum2;
624 IEnumVARIANT *enumvar;
625 VARIANT key, item;
626 IDictionary *dict;
627 ULONG fetched;
628 HRESULT hr;
630 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
631 &IID_IDictionary, (void**)&dict);
632 ok(hr == S_OK, "got 0x%08x\n", hr);
634 if (0) /* crashes on native */
635 hr = IDictionary__NewEnum(dict, NULL);
637 hr = IDictionary__NewEnum(dict, &enum1);
638 ok(hr == S_OK, "got 0x%08x\n", hr);
640 hr = IDictionary__NewEnum(dict, &enum2);
641 ok(hr == S_OK, "got 0x%08x\n", hr);
642 ok(enum1 != enum2, "got %p, %p\n", enum2, enum1);
643 IUnknown_Release(enum2);
645 hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar);
646 ok(hr == S_OK, "got 0x%08x\n", hr);
647 IUnknown_Release(enum1);
649 /* dictionary is empty */
650 hr = IEnumVARIANT_Skip(enumvar, 1);
651 ok(hr == S_FALSE, "got 0x%08x\n", hr);
653 hr = IEnumVARIANT_Skip(enumvar, 0);
654 ok(hr == S_OK, "got 0x%08x\n", hr);
656 V_VT(&key) = VT_I2;
657 V_I2(&key) = 1;
658 V_VT(&item) = VT_I4;
659 V_I4(&item) = 100;
660 hr = IDictionary_Add(dict, &key, &item);
661 ok(hr == S_OK, "got 0x%08x\n", hr);
663 hr = IEnumVARIANT_Skip(enumvar, 0);
664 ok(hr == S_OK, "got 0x%08x\n", hr);
666 hr = IEnumVARIANT_Reset(enumvar);
667 ok(hr == S_OK, "got 0x%08x\n", hr);
668 hr = IEnumVARIANT_Skip(enumvar, 1);
669 ok(hr == S_OK, "got 0x%08x\n", hr);
670 hr = IEnumVARIANT_Skip(enumvar, 1);
671 ok(hr == S_FALSE, "got 0x%08x\n", hr);
673 V_VT(&key) = VT_I2;
674 V_I2(&key) = 4000;
675 V_VT(&item) = VT_I4;
676 V_I4(&item) = 200;
677 hr = IDictionary_Add(dict, &key, &item);
678 ok(hr == S_OK, "got 0x%08x\n", hr);
680 V_VT(&key) = VT_I2;
681 V_I2(&key) = 0;
682 V_VT(&item) = VT_I4;
683 V_I4(&item) = 300;
684 hr = IDictionary_Add(dict, &key, &item);
685 ok(hr == S_OK, "got 0x%08x\n", hr);
687 hr = IEnumVARIANT_Reset(enumvar);
688 ok(hr == S_OK, "got 0x%08x\n", hr);
690 VariantInit(&key);
691 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
692 ok(hr == S_OK, "got 0x%08x\n", hr);
693 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
694 ok(V_I2(&key) == 1, "got %d\n", V_I2(&key));
695 ok(fetched == 1, "got %u\n", fetched);
697 hr = IEnumVARIANT_Reset(enumvar);
698 ok(hr == S_OK, "got 0x%08x\n", hr);
700 hr = IDictionary_Remove(dict, &key);
701 ok(hr == S_OK, "got 0x%08x\n", hr);
703 VariantInit(&key);
704 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
705 ok(hr == S_OK, "got 0x%08x\n", hr);
706 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
707 ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key));
708 ok(fetched == 1, "got %u\n", fetched);
710 VariantInit(&key);
711 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
712 ok(hr == S_OK, "got 0x%08x\n", hr);
713 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
714 ok(V_I2(&key) == 0, "got %d\n", V_I2(&key));
715 ok(fetched == 1, "got %u\n", fetched);
717 /* enumeration reached the bottom, add one more pair */
718 VariantInit(&key);
719 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
720 ok(hr == S_FALSE, "got 0x%08x\n", hr);
722 V_VT(&key) = VT_I2;
723 V_I2(&key) = 13;
724 V_VT(&item) = VT_I4;
725 V_I4(&item) = 350;
726 hr = IDictionary_Add(dict, &key, &item);
727 ok(hr == S_OK, "got 0x%08x\n", hr);
729 /* still doesn't work until Reset() */
730 VariantInit(&key);
731 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
732 ok(hr == S_FALSE, "got 0x%08x\n", hr);
734 IEnumVARIANT_Release(enumvar);
735 IDictionary_Release(dict);
738 START_TEST(dictionary)
740 IDispatch *disp;
741 HRESULT hr;
743 CoInitialize(NULL);
745 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
746 &IID_IDispatch, (void**)&disp);
747 if(FAILED(hr)) {
748 win_skip("Dictionary object is not supported: %08x\n", hr);
749 CoUninitialize();
750 return;
752 IDispatch_Release(disp);
754 test_interfaces();
755 test_comparemode();
756 test_hash_value();
757 test_Exists();
758 test_Keys();
759 test_Remove();
760 test_Item();
761 test_Add();
762 test_IEnumVARIANT();
764 CoUninitialize();