2 * Copyright (C) 2012 Alistair Leslie-Hughes
3 * Copyright 2015 Nikolay Sivov for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
33 static void test_interfaces(void)
35 static const WCHAR key_add
[] = {'a', 0};
36 static const WCHAR key_add_value
[] = {'a', 0};
37 static const WCHAR key_non_exist
[] = {'b', 0};
42 IObjectWithSite
*site
;
47 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
48 &IID_IDispatch
, (void**)&disp
);
49 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
54 hr
= IDispatch_QueryInterface(disp
, &IID_IDictionary
, (void**)&dict
);
55 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
57 hr
= IDispatch_QueryInterface(disp
, &IID_IObjectWithSite
, (void**)&site
);
58 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
60 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
61 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
64 V_BSTR(&key
) = SysAllocString(key_add
);
65 V_VT(&value
) = VT_BSTR
;
66 V_BSTR(&value
) = SysAllocString(key_add_value
);
67 hr
= IDictionary_Add(dict
, &key
, &value
);
68 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
71 exists
= VARIANT_FALSE
;
72 hr
= IDictionary_Exists(dict
, &key
, &exists
);
73 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
74 ok(exists
== VARIANT_TRUE
, "Expected TRUE but got FALSE.\n");
77 exists
= VARIANT_TRUE
;
79 V_BSTR(&key
) = SysAllocString(key_non_exist
);
80 hr
= IDictionary_Exists(dict
, &key
, &exists
);
81 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
82 ok(exists
== VARIANT_FALSE
, "Expected FALSE but got TRUE.\n");
85 hr
= IDictionary_get_Count(dict
, &count
);
86 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
87 ok(count
== 1, "got %d, expected 1\n", count
);
89 IDictionary_Release(dict
);
90 IDispatch_Release(disp
);
93 static void test_comparemode(void)
100 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
101 &IID_IDictionary
, (void**)&dict
);
102 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
104 if (0) /* crashes on native */
105 hr
= IDictionary_get_CompareMode(dict
, NULL
);
108 hr
= IDictionary_get_CompareMode(dict
, &method
);
109 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
110 ok(method
== BinaryCompare
, "got %d\n", method
);
112 /* invalid mode value is not checked */
113 hr
= IDictionary_put_CompareMode(dict
, 10);
114 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
116 hr
= IDictionary_get_CompareMode(dict
, &method
);
117 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
118 ok(method
== 10, "got %d\n", method
);
120 hr
= IDictionary_put_CompareMode(dict
, DatabaseCompare
);
121 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
123 hr
= IDictionary_get_CompareMode(dict
, &method
);
124 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
125 ok(method
== DatabaseCompare
, "got %d\n", method
);
127 /* try to change mode of a non-empty dict */
131 hr
= IDictionary_Add(dict
, &key
, &item
);
132 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
134 hr
= IDictionary_put_CompareMode(dict
, BinaryCompare
);
135 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
, "got 0x%08x\n", hr
);
137 IDictionary_Release(dict
);
140 static DWORD
get_str_hash(const WCHAR
*str
, CompareMethod method
)
147 if (method
== TextCompare
|| method
== DatabaseCompare
)
148 ch
= PtrToInt(CharLowerW(IntToPtr(*str
)));
152 hash
+= (hash
<< 4) + ch
;
159 static DWORD
get_num_hash(FLOAT num
)
161 return (*((DWORD
*)&num
)) % 1201;
164 static DWORD
get_ptr_hash(void *ptr
)
166 return PtrToUlong(ptr
) % 1201;
174 unsigned int exp_bias
: 8;
175 unsigned int sign
: 1;
184 unsigned int m_lo
: 32; /* 52 bits of precision */
185 unsigned int m_hi
: 20;
186 unsigned int exp_bias
: 11; /* bias == 1023 */
187 unsigned int sign
: 1;
192 static HRESULT WINAPI
test_unk_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
194 if (IsEqualIID(riid
, &IID_IUnknown
)) {
199 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid
));
201 return E_NOINTERFACE
;
204 static HRESULT WINAPI
test_unk_no_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
207 return E_NOINTERFACE
;
210 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
212 ok(0, "unxpected\n");
216 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
221 static const IUnknownVtbl test_unk_vtbl
= {
227 static const IUnknownVtbl test_unk_no_vtbl
= {
233 static HRESULT WINAPI
test_disp_QI(IDispatch
*iface
, REFIID riid
, void **obj
)
235 if (IsEqualIID(riid
, &IID_IDispatch
) || IsEqualIID(riid
, &IID_IUnknown
)) {
240 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid
));
242 return E_NOINTERFACE
;
245 static ULONG WINAPI
test_disp_AddRef(IDispatch
*iface
)
247 ok(0, "unxpected\n");
251 static ULONG WINAPI
test_disp_Release(IDispatch
*iface
)
256 static HRESULT WINAPI
test_disp_GetTypeInfoCount(IDispatch
*iface
, UINT
*count
)
258 ok(0, "unexpected call\n");
262 static HRESULT WINAPI
test_disp_GetTypeInfo(IDispatch
*iface
, UINT index
, LCID lcid
, ITypeInfo
**ti
)
264 ok(0, "unexpected call\n");
268 static HRESULT WINAPI
test_disp_GetIDsOfNames(IDispatch
*iface
, REFIID riid
, LPOLESTR
*names
,
269 UINT name_count
, LCID lcid
, DISPID
*dispid
)
271 ok(0, "unexpected call\n");
275 static HRESULT WINAPI
test_disp_Invoke(IDispatch
*iface
, DISPID dispid
, REFIID riid
,
276 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*arg_err
)
278 ok(0, "unexpected call\n");
282 static const IDispatchVtbl test_disp_vtbl
= {
286 test_disp_GetTypeInfoCount
,
287 test_disp_GetTypeInfo
,
288 test_disp_GetIDsOfNames
,
292 static IUnknown test_unk
= { &test_unk_vtbl
};
293 static IUnknown test_unk2
= { &test_unk_no_vtbl
};
294 static IDispatch test_disp
= { &test_disp_vtbl
};
296 static void test_hash_value(void)
298 /* string test data */
299 static const WCHAR str_hash_tests
[][10] = {
301 {'a','B','C','d','1',0},
308 static const int int_hash_tests
[] = {
312 static const FLOAT float_hash_tests
[] = {
313 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
326 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
327 &IID_IDictionary
, (void**)&dict
);
328 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
330 V_VT(&key
) = VT_BSTR
;
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
) == 0, "got %d\n", V_I4(&hash
));
338 for (i
= 0; i
< sizeof(str_hash_tests
)/sizeof(str_hash_tests
[0]); i
++) {
339 expected
= get_str_hash(str_hash_tests
[i
], BinaryCompare
);
341 hr
= IDictionary_put_CompareMode(dict
, BinaryCompare
);
342 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
344 V_VT(&key
) = VT_BSTR
;
345 V_BSTR(&key
) = SysAllocString(str_hash_tests
[i
]);
347 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
348 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
349 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
350 ok(V_I4(&hash
) == expected
, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
354 expected
= get_str_hash(str_hash_tests
[i
], TextCompare
);
355 hr
= IDictionary_put_CompareMode(dict
, TextCompare
);
356 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
358 V_VT(&key
) = VT_BSTR
;
359 V_BSTR(&key
) = SysAllocString(str_hash_tests
[i
]);
361 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
362 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
363 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
364 ok(V_I4(&hash
) == expected
, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
368 expected
= get_str_hash(str_hash_tests
[i
], DatabaseCompare
);
369 hr
= IDictionary_put_CompareMode(dict
, DatabaseCompare
);
370 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
372 V_VT(&key
) = VT_BSTR
;
373 V_BSTR(&key
) = SysAllocString(str_hash_tests
[i
]);
375 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
376 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
377 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
378 ok(V_I4(&hash
) == expected
, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
386 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
387 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
388 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
389 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x\n", V_I4(&hash
));
391 V_VT(&key
) = VT_UINT
;
394 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
395 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
396 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
397 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x\n", V_I4(&hash
));
402 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
403 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
404 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
405 ok(V_I4(&hash
) == ~0u || broken(V_I4(&hash
) == 0xa1), "got hash 0x%08x\n", V_I4(&hash
));
410 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
411 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
412 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
413 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x\n", V_I4(&hash
));
418 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
419 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
420 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
421 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x\n", V_I4(&hash
));
426 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
427 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
428 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
429 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x\n", V_I4(&hash
));
431 for (i
= 0; i
< sizeof(int_hash_tests
)/sizeof(int_hash_tests
[0]); i
++) {
436 expected
= get_num_hash(int_hash_tests
[i
]);
439 V_I2(&key
) = int_hash_tests
[i
];
441 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
442 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
443 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
444 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
447 i2
= int_hash_tests
[i
];
448 V_VT(&key
) = VT_I2
|VT_BYREF
;
451 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
452 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
453 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
454 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
458 V_I4(&key
) = int_hash_tests
[i
];
460 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
461 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
462 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
463 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
466 i4
= int_hash_tests
[i
];
467 V_VT(&key
) = VT_I4
|VT_BYREF
;
470 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
471 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
472 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
473 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
476 expected
= get_num_hash((FLOAT
)(BYTE
)int_hash_tests
[i
]);
478 V_UI1(&key
) = int_hash_tests
[i
];
480 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
481 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
482 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
483 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
486 ui1
= int_hash_tests
[i
];
487 V_VT(&key
) = VT_UI1
|VT_BYREF
;
488 V_UI1REF(&key
) = &ui1
;
490 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
492 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
493 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
499 fx4
.i
.exp_bias
= 0xff;
504 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
505 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
506 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
507 ok(V_I4(&hash
) == ~0u || broken(V_I4(&hash
) == 0 /* win2k */ ||
508 V_I4(&hash
) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash
));
513 fx4
.i
.exp_bias
= 0xff;
518 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
519 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
520 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
521 ok(V_I4(&hash
) == 0, "got hash 0x%08x\n", V_I4(&hash
));
525 fx8
.i
.exp_bias
= 0x7ff;
530 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
531 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
532 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
533 ok(V_I4(&hash
) == ~0u || broken(V_I4(&hash
) == 0 /* win2k */ ||
534 V_I4(&hash
) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash
));
536 V_VT(&key
) = VT_DATE
;
537 V_DATE(&key
) = fx8
.d
;
539 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
540 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k, win2k3 */, "got 0x%08x\n", hr
);
541 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
542 ok(V_I4(&hash
) == ~0u || broken(V_I4(&hash
) == 0 /* win2k */ ||
543 V_I4(&hash
) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash
));
549 fx8
.i
.exp_bias
= 0x7ff;
554 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
556 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
557 ok(V_I4(&hash
) == 0, "got hash 0x%08x\n", V_I4(&hash
));
559 V_VT(&key
) = VT_DATE
;
560 V_DATE(&key
) = fx8
.d
;
562 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
563 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
564 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
565 ok(V_I4(&hash
) == 0, "got hash 0x%08x\n", V_I4(&hash
));
567 for (i
= 0; i
< sizeof(float_hash_tests
)/sizeof(float_hash_tests
[0]); i
++) {
572 expected
= get_num_hash(float_hash_tests
[i
]);
575 V_R4(&key
) = float_hash_tests
[i
];
577 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
578 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
579 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
580 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
583 flt
= float_hash_tests
[i
];
584 V_VT(&key
) = VT_R4
|VT_BYREF
;
585 V_R4REF(&key
) = &flt
;
587 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
588 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
589 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
590 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
594 V_R8(&key
) = float_hash_tests
[i
];
596 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
597 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
598 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
599 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
602 dbl
= float_hash_tests
[i
];
603 V_VT(&key
) = VT_R8
|VT_BYREF
;
604 V_R8REF(&key
) = &dbl
;
606 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
607 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
608 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
609 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
612 V_VT(&key
) = VT_DATE
;
613 V_DATE(&key
) = float_hash_tests
[i
];
615 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
616 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
617 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
618 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
621 V_VT(&key
) = VT_DATE
|VT_BYREF
;
622 date
= float_hash_tests
[i
];
623 V_DATEREF(&key
) = &date
;
625 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
627 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
628 ok(V_I4(&hash
) == expected
, "%d: got hash 0x%08x, expected 0x%08x\n", i
, V_I4(&hash
),
632 /* interface pointers as keys */
633 V_VT(&key
) = VT_UNKNOWN
;
637 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
638 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
639 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
640 ok(V_I4(&hash
) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash
));
642 /* QI doesn't work */
643 V_VT(&key
) = VT_UNKNOWN
;
644 V_UNKNOWN(&key
) = &test_unk2
;
646 expected
= get_ptr_hash(&test_unk2
);
647 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
648 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
649 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
650 ok(V_I4(&hash
) == ~0u, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
652 V_VT(&key
) = VT_UNKNOWN
;
653 V_UNKNOWN(&key
) = &test_unk
;
655 expected
= get_ptr_hash(&test_unk
);
656 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
657 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
658 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
659 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
661 /* interface without IDispatch support */
662 V_VT(&key
) = VT_DISPATCH
;
663 V_DISPATCH(&key
) = (IDispatch
*)&test_unk
;
665 expected
= get_ptr_hash(&test_unk
);
666 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
667 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
668 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
669 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
671 V_VT(&key
) = VT_DISPATCH
;
672 V_DISPATCH(&key
) = &test_disp
;
674 expected
= get_ptr_hash(&test_disp
);
675 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
676 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
677 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
678 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
680 /* same with BYREF */
681 if (0) { /* crashes on native */
682 V_VT(&key
) = VT_UNKNOWN
|VT_BYREF
;
683 V_UNKNOWNREF(&key
) = 0;
684 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
687 V_VT(&key
) = VT_UNKNOWN
|VT_BYREF
;
688 V_UNKNOWNREF(&key
) = &unk
;
691 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
692 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
693 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
694 ok(V_I4(&hash
) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash
));
696 V_VT(&key
) = VT_UNKNOWN
|VT_BYREF
;
698 V_UNKNOWNREF(&key
) = &unk
;
700 expected
= get_ptr_hash(&test_unk
);
701 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
702 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
703 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
704 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
706 /* interface without IDispatch support */
707 V_VT(&key
) = VT_DISPATCH
|VT_BYREF
;
709 V_DISPATCHREF(&key
) = (IDispatch
**)&unk
;
711 expected
= get_ptr_hash(&test_unk
);
712 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
713 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
714 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
715 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
717 V_VT(&key
) = VT_DISPATCH
|VT_BYREF
;
719 V_DISPATCHREF(&key
) = &disp
;
721 expected
= get_ptr_hash(&test_disp
);
722 hr
= IDictionary_get_HashVal(dict
, &key
, &hash
);
723 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
724 ok(V_VT(&hash
) == VT_I4
, "got %d\n", V_VT(&hash
));
725 ok(V_I4(&hash
) == expected
, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash
), expected
);
727 IDictionary_Release(dict
);
730 static void test_Exists(void)
737 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
738 &IID_IDictionary
, (void**)&dict
);
739 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
741 if (0) /* crashes on native */
742 hr
= IDictionary_Exists(dict
, NULL
, NULL
);
746 hr
= IDictionary_Exists(dict
, &key
, NULL
);
747 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
, "got 0x%08x\n", hr
);
751 exists
= VARIANT_TRUE
;
752 hr
= IDictionary_Exists(dict
, &key
, &exists
);
753 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
754 ok(exists
== VARIANT_FALSE
, "got %x\n", exists
);
757 hr
= IDictionary_Add(dict
, &key
, &item
);
758 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
762 hr
= IDictionary_Add(dict
, &key
, &item
);
763 ok(hr
== CTL_E_KEY_ALREADY_EXISTS
, "got 0x%08x\n", hr
);
767 hr
= IDictionary_Exists(dict
, &key
, NULL
);
768 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
, "got 0x%08x\n", hr
);
772 exists
= VARIANT_FALSE
;
773 hr
= IDictionary_Exists(dict
, &key
, &exists
);
774 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
775 ok(exists
== VARIANT_TRUE
, "got %x\n", exists
);
777 /* key of different type, but resolves to same hash value */
780 exists
= VARIANT_FALSE
;
781 hr
= IDictionary_Exists(dict
, &key
, &exists
);
782 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
783 ok(exists
== VARIANT_TRUE
, "got %x\n", exists
);
785 IDictionary_Release(dict
);
788 static void test_Keys(void)
790 VARIANT key
, keys
, item
;
795 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
796 &IID_IDictionary
, (void**)&dict
);
797 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
799 hr
= IDictionary_Keys(dict
, NULL
);
800 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
803 hr
= IDictionary_Keys(dict
, &keys
);
804 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
805 ok(V_VT(&keys
) == (VT_ARRAY
|VT_VARIANT
), "got %d\n", V_VT(&keys
));
811 hr
= IDictionary_Add(dict
, &key
, &item
);
812 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
815 hr
= IDictionary_Keys(dict
, &keys
);
816 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
817 ok(V_VT(&keys
) == (VT_ARRAY
|VT_VARIANT
), "got %d\n", V_VT(&keys
));
821 hr
= SafeArrayGetElement(V_ARRAY(&keys
), &index
, &key
);
822 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
823 ok(V_VT(&key
) == VT_R4
, "got %d\n", V_VT(&key
));
825 index
= SafeArrayGetDim(V_ARRAY(&keys
));
826 ok(index
== 1, "got %d\n", index
);
828 hr
= SafeArrayGetUBound(V_ARRAY(&keys
), 1, &index
);
829 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
830 ok(index
== 0, "got %d\n", index
);
834 IDictionary_Release(dict
);
837 static void test_Remove(void)
843 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
844 &IID_IDictionary
, (void**)&dict
);
845 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
848 hr
= IDictionary_Remove(dict
, NULL
);
850 /* nothing added yet */
853 hr
= IDictionary_Remove(dict
, &key
);
854 ok(hr
== CTL_E_ELEMENT_NOT_FOUND
, "got 0x%08x\n", hr
);
857 hr
= IDictionary_Add(dict
, &key
, &item
);
858 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
860 hr
= IDictionary_Remove(dict
, &key
);
861 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
863 IDictionary_Release(dict
);
866 static void test_Item(void)
872 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
873 &IID_IDictionary
, (void**)&dict
);
874 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
880 hr
= IDictionary_get_Item(dict
, &key
, &item
);
881 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
882 ok(V_VT(&item
) == VT_EMPTY
, "got %d\n", V_VT(&item
));
887 hr
= IDictionary_get_Item(dict
, &key
, &item
);
888 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
889 ok(V_VT(&item
) == VT_EMPTY
, "got %d\n", V_VT(&item
));
891 IDictionary_Release(dict
);
894 static void test_Add(void)
896 static const WCHAR testW
[] = {'t','e','s','t','W',0};
902 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
903 &IID_IDictionary
, (void**)&dict
);
904 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
906 str
= SysAllocString(testW
);
909 V_VT(&item
) = VT_BSTR
|VT_BYREF
;
910 V_BSTRREF(&item
) = &str
;
911 hr
= IDictionary_Add(dict
, &key
, &item
);
912 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
914 hr
= IDictionary_get_Item(dict
, &key
, &item
);
915 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
916 ok(V_VT(&item
) == VT_BSTR
, "got %d\n", V_VT(&item
));
920 IDictionary_Release(dict
);
923 static void test_IEnumVARIANT(void)
925 IUnknown
*enum1
, *enum2
;
926 IEnumVARIANT
*enumvar
;
932 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
933 &IID_IDictionary
, (void**)&dict
);
934 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
936 if (0) /* crashes on native */
937 hr
= IDictionary__NewEnum(dict
, NULL
);
939 hr
= IDictionary__NewEnum(dict
, &enum1
);
940 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
942 hr
= IDictionary__NewEnum(dict
, &enum2
);
943 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
944 ok(enum1
!= enum2
, "got %p, %p\n", enum2
, enum1
);
945 IUnknown_Release(enum2
);
947 hr
= IUnknown_QueryInterface(enum1
, &IID_IEnumVARIANT
, (void**)&enumvar
);
948 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
949 IUnknown_Release(enum1
);
951 /* dictionary is empty */
952 hr
= IEnumVARIANT_Skip(enumvar
, 1);
953 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
955 hr
= IEnumVARIANT_Skip(enumvar
, 0);
956 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
962 hr
= IDictionary_Add(dict
, &key
, &item
);
963 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
965 hr
= IEnumVARIANT_Skip(enumvar
, 0);
966 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
968 hr
= IEnumVARIANT_Reset(enumvar
);
969 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
970 hr
= IEnumVARIANT_Skip(enumvar
, 1);
971 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
972 hr
= IEnumVARIANT_Skip(enumvar
, 1);
973 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
979 hr
= IDictionary_Add(dict
, &key
, &item
);
980 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
986 hr
= IDictionary_Add(dict
, &key
, &item
);
987 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
989 hr
= IEnumVARIANT_Reset(enumvar
);
990 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
993 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
994 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
995 ok(V_VT(&key
) == VT_I2
, "got %d\n", V_VT(&key
));
996 ok(V_I2(&key
) == 1, "got %d\n", V_I2(&key
));
997 ok(fetched
== 1, "got %u\n", fetched
);
999 hr
= IEnumVARIANT_Reset(enumvar
);
1000 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1002 hr
= IDictionary_Remove(dict
, &key
);
1003 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1006 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
1007 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1008 ok(V_VT(&key
) == VT_I2
, "got %d\n", V_VT(&key
));
1009 ok(V_I2(&key
) == 4000, "got %d\n", V_I2(&key
));
1010 ok(fetched
== 1, "got %u\n", fetched
);
1013 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
1014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1015 ok(V_VT(&key
) == VT_I2
, "got %d\n", V_VT(&key
));
1016 ok(V_I2(&key
) == 0, "got %d\n", V_I2(&key
));
1017 ok(fetched
== 1, "got %u\n", fetched
);
1019 /* enumeration reached the bottom, add one more pair */
1021 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
1022 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1026 V_VT(&item
) = VT_I4
;
1028 hr
= IDictionary_Add(dict
, &key
, &item
);
1029 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1031 /* still doesn't work until Reset() */
1033 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
1034 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1036 IEnumVARIANT_Release(enumvar
);
1037 IDictionary_Release(dict
);
1040 START_TEST(dictionary
)
1047 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1048 &IID_IDispatch
, (void**)&disp
);
1050 win_skip("Dictionary object is not supported: %08x\n", hr
);
1054 IDispatch_Release(disp
);
1064 test_IEnumVARIANT();