Release 0.9.61.
[wine/gsoc-2012-control.git] / dlls / mshtml / tests / script.c
blobac604cce06da5a5e97d527aa9c412e0efb1a690f
1 /*
2 * Copyright 2008 Jacek Caban for CodeWeavers
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 #define CONST_VTABLE
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "mshtml.h"
30 #include "activscp.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
38 #define CHECK_EXPECT2(func) \
39 do { \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
42 }while(0)
44 #define CHECK_EXPECT(func) \
45 do { \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
48 }while(0)
50 #define CHECK_CALLED(func) \
51 do { \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
54 }while(0)
56 #define CHECK_NOT_CALLED(func) \
57 do { \
58 ok(!called_ ## func, "unexpected " #func "\n"); \
59 expect_ ## func = called_ ## func = FALSE; \
60 }while(0)
62 #define CLEAR_CALLED(func) \
63 expect_ ## func = called_ ## func = FALSE
66 DEFINE_EXPECT(CreateInstance);
69 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
71 static const GUID CLSID_TestScript =
72 {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
74 static IHTMLDocument2 *notif_doc;
75 static BOOL doc_complete;
77 static const char *debugstr_guid(REFIID riid)
79 static char buf[50];
81 sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
82 riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
83 riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
84 riid->Data4[5], riid->Data4[6], riid->Data4[7]);
86 return buf;
89 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
90 REFIID riid, void**ppv)
92 if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
93 *ppv = iface;
94 return S_OK;
97 return E_NOINTERFACE;
100 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
102 return 2;
105 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
107 return 1;
110 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
112 if(dispID == DISPID_READYSTATE){
113 BSTR state;
114 HRESULT hres;
116 static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
118 hres = IHTMLDocument2_get_readyState(notif_doc, &state);
119 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
121 if(!lstrcmpW(state, completeW))
122 doc_complete = TRUE;
124 SysFreeString(state);
127 return S_OK;
130 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
132 ok(0, "unexpected call\n");
133 return E_NOTIMPL;
136 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
137 PropertyNotifySink_QueryInterface,
138 PropertyNotifySink_AddRef,
139 PropertyNotifySink_Release,
140 PropertyNotifySink_OnChanged,
141 PropertyNotifySink_OnRequestEdit
144 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
146 static IHTMLDocument2 *create_document(void)
148 IHTMLDocument2 *doc;
149 HRESULT hres;
151 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
152 &IID_IHTMLDocument2, (void**)&doc);
153 ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
155 return doc;
158 static IHTMLDocument2 *create_doc_with_string(const char *str)
160 IPersistStreamInit *init;
161 IStream *stream;
162 IHTMLDocument2 *doc;
163 HGLOBAL mem;
164 SIZE_T len;
166 notif_doc = doc = create_document();
167 if(!doc)
168 return NULL;
170 doc_complete = FALSE;
171 len = strlen(str);
172 mem = GlobalAlloc(0, len);
173 memcpy(mem, str, len);
174 CreateStreamOnHGlobal(mem, TRUE, &stream);
176 IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
178 IPersistStreamInit_Load(init, stream);
179 IPersistStreamInit_Release(init);
180 IStream_Release(stream);
182 return doc;
185 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
187 IConnectionPointContainer *container;
188 IConnectionPoint *cp;
189 DWORD cookie;
190 HRESULT hres;
192 hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
193 ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
195 hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
196 IConnectionPointContainer_Release(container);
197 ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
199 hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
200 IConnectionPoint_Release(cp);
201 ok(hres == S_OK, "Advise failed: %08x\n", hres);
204 typedef void (*domtest_t)(IHTMLDocument2*);
206 static IHTMLDocument2 *create_and_load_doc(const char *str)
208 IHTMLDocument2 *doc;
209 IHTMLElement *body = NULL;
210 ULONG ref;
211 MSG msg;
212 HRESULT hres;
214 doc = create_doc_with_string(str);
215 do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
217 while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
218 TranslateMessage(&msg);
219 DispatchMessage(&msg);
222 hres = IHTMLDocument2_get_body(doc, &body);
223 ok(hres == S_OK, "get_body failed: %08x\n", hres);
225 if(!body) {
226 skip("Could not get document body. Assuming no Gecko installed.\n");
227 ref = IHTMLDocument2_Release(doc);
228 ok(!ref, "ref = %d\n", ref);
229 return NULL;
232 IHTMLElement_Release(body);
233 return doc;
236 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
238 *ppv = NULL;
240 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
241 *ppv = iface;
242 return S_OK;
245 if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
246 /* TODO */
247 return E_NOINTERFACE;
250 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
251 return E_NOINTERFACE;
254 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
256 return 2;
259 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
261 return 1;
264 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
266 ok(0, "unexpected call\n");
267 return E_NOTIMPL;
270 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
271 void **ppvObject)
273 ok(0, "unexpected call\n");
274 return E_NOTIMPL;
277 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
279 ok(0, "unexpected call\n");
280 return E_NOTIMPL;
283 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
285 ok(0, "unexpected call\n");
286 return E_NOTIMPL;
289 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
291 ok(0, "unexpected call\n");
292 return E_NOTIMPL;
295 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
296 LPCOLESTR pstrName, DWORD dwFlags)
298 ok(0, "unexpected call\n");
299 return E_NOTIMPL;
302 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
303 DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
305 ok(0, "unexpected call\n");
306 return E_NOTIMPL;
309 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
310 IDispatch **ppdisp)
312 ok(0, "unexpected call\n");
313 return E_NOTIMPL;
316 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
317 SCRIPTTHREADID *pstridThread)
319 ok(0, "unexpected call\n");
320 return E_NOTIMPL;
323 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
324 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
326 ok(0, "unexpected call\n");
327 return E_NOTIMPL;
330 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
331 SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
333 ok(0, "unexpected call\n");
334 return E_NOTIMPL;
337 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
338 SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
340 ok(0, "unexpected call\n");
341 return E_NOTIMPL;
344 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
346 ok(0, "unexpected call\n");
347 return E_NOTIMPL;
350 static const IActiveScriptVtbl ActiveScriptVtbl = {
351 ActiveScript_QueryInterface,
352 ActiveScript_AddRef,
353 ActiveScript_Release,
354 ActiveScript_SetScriptSite,
355 ActiveScript_GetScriptSite,
356 ActiveScript_SetScriptState,
357 ActiveScript_GetScriptState,
358 ActiveScript_Close,
359 ActiveScript_AddNamedItem,
360 ActiveScript_AddTypeLib,
361 ActiveScript_GetScriptDispatch,
362 ActiveScript_GetCurrentScriptThreadID,
363 ActiveScript_GetScriptThreadID,
364 ActiveScript_GetScriptThreadState,
365 ActiveScript_InterruptScriptThread,
366 ActiveScript_Clone
369 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
371 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
373 *ppv = NULL;
375 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
376 *ppv = iface;
377 return S_OK;
380 if(IsEqualGUID(&IID_IMarshal, riid))
381 return E_NOINTERFACE;
382 if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
383 return E_NOINTERFACE;
385 ok(0, "unexpected riid %s\n", debugstr_guid(riid));
386 return E_NOTIMPL;
389 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
391 return 2;
394 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
396 return 1;
399 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
401 CHECK_EXPECT(CreateInstance);
403 ok(!outer, "outer = %p\n", outer);
404 ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
405 *ppv = &ActiveScript;
406 return S_OK;
409 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
411 ok(0, "unexpected call\n");
412 return S_OK;
415 static const IClassFactoryVtbl ClassFactoryVtbl = {
416 ClassFactory_QueryInterface,
417 ClassFactory_AddRef,
418 ClassFactory_Release,
419 ClassFactory_CreateInstance,
420 ClassFactory_LockServer
423 static IClassFactory script_cf = { &ClassFactoryVtbl };
425 static const char simple_script_str[] =
426 "<html><head></head><body>"
427 "<script language=\"TestScript\">simple script</script>"
428 "</body></html>";
430 static void test_simple_script(void)
432 IHTMLDocument2 *doc;
434 SET_EXPECT(CreateInstance);
436 doc = create_and_load_doc(simple_script_str);
437 if(!doc) return;
439 CHECK_CALLED(CreateInstance);
441 IHTMLDocument2_Release(doc);
444 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
446 HKEY hkey;
447 DWORD res;
449 if(!init) {
450 RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
451 return TRUE;
454 res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
455 if(res != ERROR_SUCCESS)
456 return FALSE;
458 if(def_value)
459 res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
461 RegCloseKey(hkey);
463 return res == ERROR_SUCCESS;
466 static BOOL init_registry(BOOL init)
468 return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
469 && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
470 NULL, init)
471 && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
472 NULL, init);
475 static BOOL register_script_engine(void)
477 DWORD regid;
478 HRESULT hres;
480 if(!init_registry(TRUE)) {
481 init_registry(FALSE);
482 return FALSE;
485 hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
486 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
487 ok(hres == S_OK, "Could not register screipt engine: %08x\n", hres);
489 return TRUE;
492 static void gecko_installer_workaround(BOOL disable)
494 HKEY hkey;
495 DWORD res;
497 static BOOL has_url = FALSE;
498 static char url[2048];
500 if(!disable && !has_url)
501 return;
503 res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
504 if(res != ERROR_SUCCESS)
505 return;
507 if(disable) {
508 DWORD type, size = sizeof(url);
510 res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
511 if(res == ERROR_SUCCESS && type == REG_SZ)
512 has_url = TRUE;
514 RegDeleteValue(hkey, "GeckoUrl");
515 }else {
516 RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
519 RegCloseKey(hkey);
522 START_TEST(script)
524 gecko_installer_workaround(TRUE);
525 CoInitialize(NULL);
527 if(register_script_engine()) {
528 test_simple_script();
529 init_registry(FALSE);
530 }else {
531 skip("Could not register TestScript engine\n");
534 CoUninitialize();
535 gecko_installer_workaround(FALSE);