Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/browseui/tests/autocomplete.c
5968 views
1
/* Unit tests for autocomplete
2
*
3
* Copyright 2007 Mikolaj Zalewski
4
*
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.
9
*
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.
14
*
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
18
*/
19
20
#define COBJMACROS
21
22
#include <stdarg.h>
23
24
#include <initguid.h>
25
#include <windows.h>
26
#include <shlobj.h>
27
#include <shldisp.h>
28
#include <shlwapi.h>
29
#include <shlguid.h>
30
31
#include "wine/test.h"
32
33
#define ole_ok(exp) \
34
{ \
35
HRESULT res = (exp); \
36
if (res != S_OK) \
37
ok(FALSE, #exp " failed: %#lx\n", res); \
38
}
39
40
typedef struct
41
{
42
IEnumString IEnumString_iface;
43
IACList IACList_iface;
44
LONG ref;
45
HRESULT expret;
46
INT expcount;
47
INT pos;
48
INT limit;
49
const WCHAR **data;
50
} TestACL;
51
52
extern IEnumStringVtbl TestACLVtbl;
53
extern IACListVtbl TestACL_ACListVtbl;
54
55
static inline TestACL *impl_from_IEnumString(IEnumString *iface)
56
{
57
return CONTAINING_RECORD(iface, TestACL, IEnumString_iface);
58
}
59
60
static TestACL *impl_from_IACList(IACList *iface)
61
{
62
return CONTAINING_RECORD(iface, TestACL, IACList_iface);
63
}
64
65
static TestACL *TestACL_Constructor(int limit, const WCHAR **strings)
66
{
67
TestACL *This = CoTaskMemAlloc(sizeof(TestACL));
68
ZeroMemory(This, sizeof(*This));
69
This->IEnumString_iface.lpVtbl = &TestACLVtbl;
70
This->IACList_iface.lpVtbl = &TestACL_ACListVtbl;
71
This->ref = 1;
72
This->expret = S_OK;
73
This->limit = limit;
74
This->data = strings;
75
return This;
76
}
77
78
static ULONG STDMETHODCALLTYPE TestACL_AddRef(IEnumString *iface)
79
{
80
TestACL *This = impl_from_IEnumString(iface);
81
trace("ACL(%p): addref (%ld)\n", This, This->ref+1);
82
return InterlockedIncrement(&This->ref);
83
}
84
85
static ULONG STDMETHODCALLTYPE TestACL_Release(IEnumString *iface)
86
{
87
TestACL *This = impl_from_IEnumString(iface);
88
ULONG res;
89
90
res = InterlockedDecrement(&This->ref);
91
trace("ACL(%p): release (%ld)\n", This, res);
92
return res;
93
}
94
95
static HRESULT STDMETHODCALLTYPE TestACL_QueryInterface(IEnumString *iface, REFIID iid, LPVOID *ppvOut)
96
{
97
TestACL *This = impl_from_IEnumString(iface);
98
*ppvOut = NULL;
99
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumString))
100
{
101
*ppvOut = iface;
102
}
103
else if (IsEqualGUID(iid, &IID_IACList))
104
{
105
*ppvOut = &This->IACList_iface;
106
}
107
108
if (*ppvOut)
109
{
110
IEnumString_AddRef(iface);
111
return S_OK;
112
}
113
114
if (!IsEqualGUID(iid, &IID_IEnumACString))
115
trace("unknown interface queried\n");
116
return E_NOINTERFACE;
117
}
118
119
static HRESULT STDMETHODCALLTYPE TestACL_Next(IEnumString *iface, ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
120
{
121
TestACL *This = impl_from_IEnumString(iface);
122
int size;
123
ULONG i;
124
125
trace("ACL(%p): read %ld item(s)\n", This, celt);
126
for (i = 0; i < celt; i++)
127
{
128
if (This->pos >= This->limit)
129
break;
130
131
size = wcslen(This->data[This->pos]);
132
rgelt[i] = CoTaskMemAlloc((size + 1) * sizeof(WCHAR));
133
wcscpy(rgelt[i], This->data[This->pos]);
134
This->pos++;
135
}
136
137
if (pceltFetched)
138
*pceltFetched = i;
139
if (i == celt)
140
return S_OK;
141
return S_FALSE;
142
}
143
144
static HRESULT STDMETHODCALLTYPE TestACL_Skip(IEnumString *iface, ULONG celt)
145
{
146
ok(FALSE, "Unexpected call to TestACL_Skip\n");
147
return E_NOTIMPL;
148
}
149
150
static HRESULT STDMETHODCALLTYPE TestACL_Clone(IEnumString *iface, IEnumString **out)
151
{
152
ok(FALSE, "Unexpected call to TestACL_Clone\n");
153
return E_OUTOFMEMORY;
154
}
155
156
static HRESULT STDMETHODCALLTYPE TestACL_Reset(IEnumString *iface)
157
{
158
TestACL *This = impl_from_IEnumString(iface);
159
trace("ACL(%p): Reset\n", This);
160
This->pos = 0;
161
return S_OK;
162
}
163
164
static HRESULT STDMETHODCALLTYPE TestACL_Expand(IACList *iface, LPCOLESTR str)
165
{
166
TestACL *This = impl_from_IACList(iface);
167
trace("ACL(%p): Expand\n", This);
168
This->expcount++;
169
return This->expret;
170
}
171
172
IEnumStringVtbl TestACLVtbl =
173
{
174
TestACL_QueryInterface,
175
TestACL_AddRef,
176
TestACL_Release,
177
178
TestACL_Next,
179
TestACL_Skip,
180
TestACL_Reset,
181
TestACL_Clone
182
};
183
184
static ULONG STDMETHODCALLTYPE TestACL_ACList_AddRef(IACList *iface)
185
{
186
TestACL *This = impl_from_IACList(iface);
187
return TestACL_AddRef(&This->IEnumString_iface);
188
}
189
190
static ULONG STDMETHODCALLTYPE TestACL_ACList_Release(IACList *iface)
191
{
192
TestACL *This = impl_from_IACList(iface);
193
return TestACL_Release(&This->IEnumString_iface);
194
}
195
196
static HRESULT STDMETHODCALLTYPE TestACL_ACList_QueryInterface(IACList *iface, REFIID iid, LPVOID *ppvout)
197
{
198
TestACL *This = impl_from_IACList(iface);
199
return TestACL_QueryInterface(&This->IEnumString_iface, iid, ppvout);
200
}
201
202
IACListVtbl TestACL_ACListVtbl =
203
{
204
TestACL_ACList_QueryInterface,
205
TestACL_ACList_AddRef,
206
TestACL_ACList_Release,
207
208
TestACL_Expand
209
};
210
211
#define expect_str(obj, str) \
212
{ \
213
ole_ok(IEnumString_Next(obj, 1, &wstr, &i)); \
214
ok(i == 1, "Expected i == 1, got %ld\n", i); \
215
ok(str[0] == wstr[0], "String mismatch\n"); \
216
CoTaskMemFree(wstr); \
217
}
218
219
static void test_ACLMulti(void)
220
{
221
const WCHAR *strings1[] = { L"a", L"c", L"e" };
222
const WCHAR *strings2[] = { L"a", L"b", L"d" };
223
const WCHAR exp[] = L"ABC";
224
IEnumString *obj;
225
IEnumACString *unk;
226
HRESULT hr;
227
TestACL *acl1, *acl2;
228
IACList *acl;
229
IObjMgr *mgr;
230
LPWSTR wstr;
231
LPWSTR wstrtab[15];
232
ULONG ref, i;
233
LPVOID tmp;
234
235
hr = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC, &IID_IEnumString, (void**)&obj);
236
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
237
if (hr != S_OK) return;
238
239
hr = IEnumString_QueryInterface(obj, &IID_IACList, (void**)&acl);
240
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
241
hr = IEnumString_QueryInterface(obj, &IID_IACList2, &tmp);
242
ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
243
hr = IEnumString_QueryInterface(obj, &IID_IObjMgr, (void**)&mgr);
244
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
245
246
hr = IEnumString_QueryInterface(obj, &IID_IEnumACString, (LPVOID*)&unk);
247
if (hr == E_NOINTERFACE)
248
todo_wine win_skip("IEnumACString is not supported, skipping tests\n");
249
else
250
{
251
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
252
if (unk != NULL)
253
IEnumACString_Release(unk);
254
}
255
256
i = -1;
257
hr = IEnumString_Next(obj, 1, (LPOLESTR *)&tmp, &i);
258
ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
259
ok(i == 0, "Unexpected fetched value %ld\n", i);
260
hr = IEnumString_Next(obj, 44, (LPOLESTR *)&tmp, &i);
261
ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
262
hr = IEnumString_Skip(obj, 1);
263
ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
264
hr = IEnumString_Clone(obj, (IEnumString **)&tmp);
265
ok(hr == E_OUTOFMEMORY, "Unexpected hr %#lx.\n", hr);
266
hr = IACList_Expand(acl, exp);
267
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
268
269
acl1 = TestACL_Constructor(3, strings1);
270
acl2 = TestACL_Constructor(3, strings2);
271
hr = IObjMgr_Append(mgr, (IUnknown *)&acl1->IACList_iface);
272
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
273
hr = IObjMgr_Append(mgr, (IUnknown *)&acl2->IACList_iface);
274
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
275
hr = IObjMgr_Append(mgr, NULL);
276
ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
277
expect_str(obj, "a");
278
expect_str(obj, "c");
279
expect_str(obj, "e");
280
expect_str(obj, "a");
281
expect_str(obj, "b");
282
expect_str(obj, "d");
283
hr = IEnumString_Next(obj, 1, &wstr, &i);
284
ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
285
286
hr = IEnumString_Reset(obj);
287
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
288
ok(acl1->pos == 0, "acl1 not reset\n");
289
ok(acl2->pos == 0, "acl2 not reset\n");
290
291
hr = IACList_Expand(acl, exp);
292
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
293
ok(acl1->expcount == 1, "expcount - expected 1, got %d\n", acl1->expcount);
294
ok(acl2->expcount == 0 /* XP */ || acl2->expcount == 1 /* Vista */,
295
"expcount - expected 0 or 1, got %d\n", acl2->expcount);
296
297
hr = IEnumString_Next(obj, 15, wstrtab, &i);
298
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
299
ok(i == 1, "Expected i == 1, got %ld\n", i);
300
CoTaskMemFree(wstrtab[0]);
301
302
hr = IEnumString_Next(obj, 15, wstrtab, &i);
303
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
304
CoTaskMemFree(wstrtab[0]);
305
306
hr = IEnumString_Next(obj, 15, wstrtab, &i);
307
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
308
CoTaskMemFree(wstrtab[0]);
309
310
hr = IEnumString_Next(obj, 15, wstrtab, &i);
311
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
312
CoTaskMemFree(wstrtab[0]);
313
314
hr = IACList_Expand(acl, exp);
315
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
316
ok(acl1->expcount == 2, "expcount - expected 1, got %d\n", acl1->expcount);
317
ok(acl2->expcount == 0 /* XP */ || acl2->expcount == 2 /* Vista */,
318
"expcount - expected 0 or 2, got %d\n", acl2->expcount);
319
acl1->expret = S_FALSE;
320
hr = IACList_Expand(acl, exp);
321
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
322
ok(acl1->expcount == 3, "expcount - expected 1, got %d\n", acl1->expcount);
323
ok(acl2->expcount == 1 /* XP */ || acl2->expcount == 3 /* Vista */,
324
"expcount - expected 0 or 3, got %d\n", acl2->expcount);
325
acl1->expret = E_NOTIMPL;
326
hr = IACList_Expand(acl, exp);
327
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
328
ok(acl1->expcount == 4, "expcount - expected 1, got %d\n", acl1->expcount);
329
ok(acl2->expcount == 2 /* XP */ || acl2->expcount == 4 /* Vista */,
330
"expcount - expected 0 or 4, got %d\n", acl2->expcount);
331
acl2->expret = E_OUTOFMEMORY;
332
hr = IACList_Expand(acl, exp);
333
ok(hr == E_OUTOFMEMORY, "Unexpected hr %#lx.\n", hr);
334
acl2->expret = E_FAIL;
335
hr = IACList_Expand(acl, exp);
336
ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
337
338
hr = IObjMgr_Remove(mgr, (IUnknown *)&acl1->IACList_iface);
339
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
340
341
ok(acl1->ref == 1, "acl1 not released\n");
342
hr = IEnumString_Next(obj, 1, &wstr, &i);
343
ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
344
IEnumString_Reset(obj);
345
expect_str(obj, "a");
346
expect_str(obj, "b");
347
expect_str(obj, "d");
348
hr = IEnumString_Next(obj, 1, &wstr, &i);
349
ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
350
351
IEnumString_Release(obj);
352
IACList_Release(acl);
353
ref = IObjMgr_Release(mgr);
354
ok(ref == 0, "Unexpected references\n");
355
ok(acl1->ref == 1, "acl1 not released\n");
356
ok(acl2->ref == 1, "acl2 not released\n");
357
358
CoTaskMemFree(acl1);
359
CoTaskMemFree(acl2);
360
}
361
362
static void test_ACListISF(void)
363
{
364
IEnumString *enumstring;
365
IACList *list, *list2;
366
HRESULT hr;
367
368
hr = CoCreateInstance(&CLSID_ACListISF, NULL, CLSCTX_INPROC, &IID_IACList, (void**)&list);
369
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
370
371
hr = IACList_QueryInterface(list, &IID_IEnumString, (void**)&enumstring);
372
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
373
374
hr = IEnumString_QueryInterface(enumstring, &IID_IACList, (void**)&list2);
375
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
376
ok(list == list2, "got %p, %p\n", list, list2);
377
IACList_Release(list2);
378
379
IEnumString_Release(enumstring);
380
IACList_Release(list);
381
}
382
383
START_TEST(autocomplete)
384
{
385
CoInitialize(NULL);
386
387
test_ACLMulti();
388
test_ACListISF();
389
390
CoUninitialize();
391
}
392
393