1 /* Unit tests for autocomplete
3 * Copyright 2007 Mikolaj Zalewski
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"
31 #define stop_on_error(exp) \
33 HRESULT res = (exp); \
36 ok(FALSE, #exp " failed: %x\n", res); \
43 HRESULT res = (exp); \
45 ok(FALSE, #exp " failed: %x\n", res); \
48 static LPWSTR
strdup_AtoW(LPCSTR str
)
50 int size
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
51 LPWSTR wstr
= CoTaskMemAlloc((size
+ 1)*sizeof(WCHAR
));
52 MultiByteToWideChar(CP_ACP
, 0, str
, -1, wstr
, size
+1);
58 IEnumStringVtbl
*vtbl
;
68 extern IEnumStringVtbl TestACLVtbl
;
69 extern IACListVtbl TestACL_ACListVtbl
;
71 static TestACL
*impl_from_IACList(IACList
*iface
)
73 return (TestACL
*)((char *)iface
- FIELD_OFFSET(TestACL
, aclVtbl
));
76 static TestACL
*TestACL_Constructor(int limit
, const char **strings
)
78 TestACL
*This
= CoTaskMemAlloc(sizeof(TestACL
));
79 ZeroMemory(This
, sizeof(*This
));
80 This
->vtbl
= &TestACLVtbl
;
81 This
->aclVtbl
= &TestACL_ACListVtbl
;
89 static ULONG STDMETHODCALLTYPE
TestACL_AddRef(IEnumString
*iface
)
91 TestACL
*This
= (TestACL
*)iface
;
92 trace("ACL(%p): addref (%d)\n", This
, This
->ref
+1);
93 return InterlockedIncrement(&This
->ref
);
96 static ULONG STDMETHODCALLTYPE
TestACL_Release(IEnumString
*iface
)
98 TestACL
*This
= (TestACL
*)iface
;
101 res
= InterlockedDecrement(&This
->ref
);
102 trace("ACL(%p): release (%d)\n", This
, res
);
106 static HRESULT STDMETHODCALLTYPE
TestACL_QueryInterface(IEnumString
*iface
, REFIID iid
, LPVOID
*ppvOut
)
108 TestACL
*This
= (TestACL
*)iface
;
110 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IEnumString
))
114 else if (IsEqualGUID(iid
, &IID_IACList
))
116 *ppvOut
= &This
->aclVtbl
;
121 iface
->lpVtbl
->AddRef(iface
);
125 #if 0 /* IID_IEnumACString not defined yet in wine */
126 if (!IsEqualGUID(iid
, &IID_IEnumACString
))
127 trace("unknown interface queried\n");
129 return E_NOINTERFACE
;
132 static HRESULT STDMETHODCALLTYPE
TestACL_Next(IEnumString
*iface
, ULONG celt
, LPOLESTR
*rgelt
, ULONG
*pceltFetched
)
134 TestACL
*This
= (TestACL
*)iface
;
137 trace("ACL(%p): read %d item(s)\n", This
, celt
);
138 for (i
= 0; i
< celt
; i
++)
140 if (This
->pos
>= This
->limit
)
142 rgelt
[i
] = strdup_AtoW(This
->data
[This
->pos
]);
153 static HRESULT STDMETHODCALLTYPE
TestACL_Skip(IEnumString
*iface
, ULONG celt
)
155 ok(FALSE
, "Unexpected call to TestACL_Skip\n");
159 static HRESULT STDMETHODCALLTYPE
TestACL_Clone(IEnumString
*iface
, IEnumString
**out
)
161 ok(FALSE
, "Unexpected call to TestACL_Clone\n");
162 return E_OUTOFMEMORY
;
165 static HRESULT STDMETHODCALLTYPE
TestACL_Reset(IEnumString
*iface
)
167 TestACL
*This
= (TestACL
*)iface
;
168 trace("ACL(%p): Reset\n", This
);
173 static HRESULT STDMETHODCALLTYPE
TestACL_Expand(IACList
*iface
, LPCOLESTR str
)
175 TestACL
*This
= impl_from_IACList(iface
);
176 trace("ACL(%p): Expand\n", impl_from_IACList(iface
));
181 IEnumStringVtbl TestACLVtbl
=
183 TestACL_QueryInterface
,
193 static ULONG STDMETHODCALLTYPE
TestACL_ACList_AddRef(IACList
*iface
)
195 return TestACL_AddRef((IEnumString
*)impl_from_IACList(iface
));
198 static ULONG STDMETHODCALLTYPE
TestACL_ACList_Release(IACList
*iface
)
200 return TestACL_Release((IEnumString
*)impl_from_IACList(iface
));
203 static HRESULT STDMETHODCALLTYPE
TestACL_ACList_QueryInterface(IACList
*iface
, REFIID iid
, LPVOID
*ppvout
)
205 return TestACL_QueryInterface((IEnumString
*)impl_from_IACList(iface
), iid
, ppvout
);
208 IACListVtbl TestACL_ACListVtbl
=
210 TestACL_ACList_QueryInterface
,
211 TestACL_ACList_AddRef
,
212 TestACL_ACList_Release
,
217 #define expect_str(obj, str) \
219 ole_ok(obj->lpVtbl->Next(obj, 1, &wstr, &i)); \
220 ok(i == 1, "Expected i == 1, got %d\n", i); \
221 ok(str[0] == wstr[0], "String mismatch\n"); \
222 CoTaskMemFree(wstr); \
225 #define expect_end(obj) \
226 ok(obj->lpVtbl->Next(obj, 1, &wstr, &i) == S_FALSE, "Unexpected return from Next\n");
228 static void test_ACLMulti(void)
230 const char *strings1
[] = {"a", "c", "e"};
231 const char *strings2
[] = {"a", "b", "d"};
232 WCHAR exp
[] = {'A','B','C',0};
234 TestACL
*acl1
, *acl2
;
242 stop_on_error(CoCreateInstance(&CLSID_ACLMulti
, NULL
, CLSCTX_INPROC
, &IID_IEnumString
, (LPVOID
*)&obj
));
243 stop_on_error(obj
->lpVtbl
->QueryInterface(obj
, &IID_IACList
, (LPVOID
*)&acl
));
244 ok(obj
->lpVtbl
->QueryInterface(obj
, &IID_IACList2
, &tmp
) == E_NOINTERFACE
,
245 "Unexpected interface IACList2 in ACLMulti\n");
246 stop_on_error(obj
->lpVtbl
->QueryInterface(obj
, &IID_IObjMgr
, (LPVOID
*)&mgr
));
247 #if 0 /* IID_IEnumACString not defined yet in wine */
248 ole_ok(obj
->lpVtbl
->QueryInterface(obj
, &IID_IEnumACString
, &unk
));
250 unk
->lpVtbl
->Release(unk
);
253 ok(obj
->lpVtbl
->Next(obj
, 1, (LPOLESTR
*)&tmp
, &i
) == S_FALSE
, "Unexpected return from Next\n");
254 ok(i
== 0, "Unexpected fetched value %d\n", i
);
255 ok(obj
->lpVtbl
->Next(obj
, 44, (LPOLESTR
*)&tmp
, &i
) == S_FALSE
, "Unexpected return from Next\n");
256 ok(obj
->lpVtbl
->Skip(obj
, 1) == E_NOTIMPL
, "Unexpected return from Skip\n");
257 ok(obj
->lpVtbl
->Clone(obj
, (IEnumString
**)&tmp
) == E_OUTOFMEMORY
, "Unexpected return from Clone\n");
258 ole_ok(acl
->lpVtbl
->Expand(acl
, exp
));
260 acl1
= TestACL_Constructor(3, strings1
);
261 acl2
= TestACL_Constructor(3, strings2
);
262 stop_on_error(mgr
->lpVtbl
->Append(mgr
, (IUnknown
*)acl1
));
263 stop_on_error(mgr
->lpVtbl
->Append(mgr
, (IUnknown
*)acl2
));
264 ok(mgr
->lpVtbl
->Append(mgr
, NULL
) == E_FAIL
, "Unexpected return from Append\n");
265 expect_str(obj
, "a");
266 expect_str(obj
, "c");
267 expect_str(obj
, "e");
268 expect_str(obj
, "a");
269 expect_str(obj
, "b");
270 expect_str(obj
, "d");
273 ole_ok(obj
->lpVtbl
->Reset(obj
));
274 ok(acl1
->pos
== 0, "acl1 not reset\n");
275 ok(acl2
->pos
== 0, "acl2 not reset\n");
277 ole_ok(acl
->lpVtbl
->Expand(acl
, exp
));
278 ok(acl1
->expcount
== 1, "expcount - expected 1, got %d\n", acl1
->expcount
);
279 ok(acl2
->expcount
== 0 /* XP */ || acl2
->expcount
== 1 /* Vista */,
280 "expcount - expected 0 or 1, got %d\n", acl2
->expcount
);
282 ole_ok(obj
->lpVtbl
->Next(obj
, 15, wstrtab
, &i
));
283 ok(i
== 1, "Expected i == 1, got %d\n", i
);
284 CoTaskMemFree(wstrtab
[0]);
285 ole_ok(obj
->lpVtbl
->Next(obj
, 15, wstrtab
, &i
));
286 CoTaskMemFree(wstrtab
[0]);
287 ole_ok(obj
->lpVtbl
->Next(obj
, 15, wstrtab
, &i
));
288 CoTaskMemFree(wstrtab
[0]);
289 ole_ok(obj
->lpVtbl
->Next(obj
, 15, wstrtab
, &i
));
290 CoTaskMemFree(wstrtab
[0]);
291 ole_ok(acl
->lpVtbl
->Expand(acl
, exp
));
292 ok(acl1
->expcount
== 2, "expcount - expected 1, got %d\n", acl1
->expcount
);
293 ok(acl2
->expcount
== 0 /* XP */ || acl2
->expcount
== 2 /* Vista */,
294 "expcount - expected 0 or 2, got %d\n", acl2
->expcount
);
295 acl1
->expret
= S_FALSE
;
296 ole_ok(acl
->lpVtbl
->Expand(acl
, exp
));
297 ok(acl1
->expcount
== 3, "expcount - expected 1, got %d\n", acl1
->expcount
);
298 ok(acl2
->expcount
== 1 /* XP */ || acl2
->expcount
== 3 /* Vista */,
299 "expcount - expected 0 or 3, got %d\n", acl2
->expcount
);
300 acl1
->expret
= E_NOTIMPL
;
301 ole_ok(acl
->lpVtbl
->Expand(acl
, exp
));
302 ok(acl1
->expcount
== 4, "expcount - expected 1, got %d\n", acl1
->expcount
);
303 ok(acl2
->expcount
== 2 /* XP */ || acl2
->expcount
== 4 /* Vista */,
304 "expcount - expected 0 or 4, got %d\n", acl2
->expcount
);
305 acl2
->expret
= E_OUTOFMEMORY
;
306 ok(acl
->lpVtbl
->Expand(acl
, exp
) == E_OUTOFMEMORY
, "Unexpected Expand return\n");
307 acl2
->expret
= E_FAIL
;
308 ok(acl
->lpVtbl
->Expand(acl
, exp
) == E_FAIL
, "Unexpected Expand return\n");
310 stop_on_error(mgr
->lpVtbl
->Remove(mgr
, (IUnknown
*)acl1
));
311 ok(acl1
->ref
== 1, "acl1 not released\n");
313 obj
->lpVtbl
->Reset(obj
);
314 expect_str(obj
, "a");
315 expect_str(obj
, "b");
316 expect_str(obj
, "d");
319 obj
->lpVtbl
->Release(obj
);
320 acl
->lpVtbl
->Release(acl
);
321 ok(mgr
->lpVtbl
->Release(mgr
) == 0, "Unexpected references\n");
322 ok(acl1
->ref
== 1, "acl1 not released\n");
323 ok(acl2
->ref
== 1, "acl2 not released\n");
329 START_TEST(autocomplete
)