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
22 #include <wine/test.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) \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
44 #define CHECK_EXPECT(func) \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
50 #define CHECK_CALLED(func) \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
56 #define CHECK_NOT_CALLED(func) \
58 ok(!called_ ## func, "unexpected " #func "\n"); \
59 expect_ ## func = called_ ## func = FALSE; \
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
)
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]);
89 static HRESULT WINAPI
PropertyNotifySink_QueryInterface(IPropertyNotifySink
*iface
,
90 REFIID riid
, void**ppv
)
92 if(IsEqualGUID(&IID_IPropertyNotifySink
, riid
)) {
100 static ULONG WINAPI
PropertyNotifySink_AddRef(IPropertyNotifySink
*iface
)
105 static ULONG WINAPI
PropertyNotifySink_Release(IPropertyNotifySink
*iface
)
110 static HRESULT WINAPI
PropertyNotifySink_OnChanged(IPropertyNotifySink
*iface
, DISPID dispID
)
112 if(dispID
== DISPID_READYSTATE
){
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
))
124 SysFreeString(state
);
130 static HRESULT WINAPI
PropertyNotifySink_OnRequestEdit(IPropertyNotifySink
*iface
, DISPID dispID
)
132 ok(0, "unexpected call\n");
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)
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
);
158 static IHTMLDocument2
*create_doc_with_string(const char *str
)
160 IPersistStreamInit
*init
;
166 notif_doc
= doc
= create_document();
170 doc_complete
= FALSE
;
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
);
185 static void do_advise(IUnknown
*unk
, REFIID riid
, IUnknown
*unk_advise
)
187 IConnectionPointContainer
*container
;
188 IConnectionPoint
*cp
;
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
)
209 IHTMLElement
*body
= NULL
;
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
);
226 skip("Could not get document body. Assuming no Gecko installed.\n");
227 ref
= IHTMLDocument2_Release(doc
);
228 ok(!ref
, "ref = %d\n", ref
);
232 IHTMLElement_Release(body
);
236 static HRESULT WINAPI
ActiveScript_QueryInterface(IActiveScript
*iface
, REFIID riid
, void **ppv
)
240 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IActiveScript
, riid
)) {
245 if(IsEqualGUID(&IID_IActiveScriptParse
, riid
)) {
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
)
259 static ULONG WINAPI
ActiveScript_Release(IActiveScript
*iface
)
264 static HRESULT WINAPI
ActiveScript_SetScriptSite(IActiveScript
*iface
, IActiveScriptSite
*pass
)
266 ok(0, "unexpected call\n");
270 static HRESULT WINAPI
ActiveScript_GetScriptSite(IActiveScript
*iface
, REFIID riid
,
273 ok(0, "unexpected call\n");
277 static HRESULT WINAPI
ActiveScript_SetScriptState(IActiveScript
*iface
, SCRIPTSTATE ss
)
279 ok(0, "unexpected call\n");
283 static HRESULT WINAPI
ActiveScript_GetScriptState(IActiveScript
*iface
, SCRIPTSTATE
*pssState
)
285 ok(0, "unexpected call\n");
289 static HRESULT WINAPI
ActiveScript_Close(IActiveScript
*iface
)
291 ok(0, "unexpected call\n");
295 static HRESULT WINAPI
ActiveScript_AddNamedItem(IActiveScript
*iface
,
296 LPCOLESTR pstrName
, DWORD dwFlags
)
298 ok(0, "unexpected call\n");
302 static HRESULT WINAPI
ActiveScript_AddTypeLib(IActiveScript
*iface
, REFGUID rguidTypeLib
,
303 DWORD dwMajor
, DWORD dwMinor
, DWORD dwFlags
)
305 ok(0, "unexpected call\n");
309 static HRESULT WINAPI
ActiveScript_GetScriptDispatch(IActiveScript
*iface
, LPCOLESTR pstrItemName
,
312 ok(0, "unexpected call\n");
316 static HRESULT WINAPI
ActiveScript_GetCurrentScriptThreadID(IActiveScript
*iface
,
317 SCRIPTTHREADID
*pstridThread
)
319 ok(0, "unexpected call\n");
323 static HRESULT WINAPI
ActiveScript_GetScriptThreadID(IActiveScript
*iface
,
324 DWORD dwWin32ThreadId
, SCRIPTTHREADID
*pstidThread
)
326 ok(0, "unexpected call\n");
330 static HRESULT WINAPI
ActiveScript_GetScriptThreadState(IActiveScript
*iface
,
331 SCRIPTTHREADID stidThread
, SCRIPTTHREADSTATE
*pstsState
)
333 ok(0, "unexpected call\n");
337 static HRESULT WINAPI
ActiveScript_InterruptScriptThread(IActiveScript
*iface
,
338 SCRIPTTHREADID stidThread
, const EXCEPINFO
*pexcepinfo
, DWORD dwFlags
)
340 ok(0, "unexpected call\n");
344 static HRESULT WINAPI
ActiveScript_Clone(IActiveScript
*iface
, IActiveScript
**ppscript
)
346 ok(0, "unexpected call\n");
350 static const IActiveScriptVtbl ActiveScriptVtbl
= {
351 ActiveScript_QueryInterface
,
353 ActiveScript_Release
,
354 ActiveScript_SetScriptSite
,
355 ActiveScript_GetScriptSite
,
356 ActiveScript_SetScriptState
,
357 ActiveScript_GetScriptState
,
359 ActiveScript_AddNamedItem
,
360 ActiveScript_AddTypeLib
,
361 ActiveScript_GetScriptDispatch
,
362 ActiveScript_GetCurrentScriptThreadID
,
363 ActiveScript_GetScriptThreadID
,
364 ActiveScript_GetScriptThreadState
,
365 ActiveScript_InterruptScriptThread
,
369 static IActiveScript ActiveScript
= { &ActiveScriptVtbl
};
371 static HRESULT WINAPI
ClassFactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
375 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IClassFactory
, riid
)) {
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
));
389 static ULONG WINAPI
ClassFactory_AddRef(IClassFactory
*iface
)
394 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
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
;
409 static HRESULT WINAPI
ClassFactory_LockServer(IClassFactory
*iface
, BOOL dolock
)
411 ok(0, "unexpected call\n");
415 static const IClassFactoryVtbl ClassFactoryVtbl
= {
416 ClassFactory_QueryInterface
,
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>"
430 static void test_simple_script(void)
434 SET_EXPECT(CreateInstance
);
436 doc
= create_and_load_doc(simple_script_str
);
439 CHECK_CALLED(CreateInstance
);
441 IHTMLDocument2_Release(doc
);
444 static BOOL
init_key(const char *key_name
, const char *def_value
, BOOL init
)
450 RegDeleteKey(HKEY_CLASSES_ROOT
, key_name
);
454 res
= RegCreateKeyA(HKEY_CLASSES_ROOT
, key_name
, &hkey
);
455 if(res
!= ERROR_SUCCESS
)
459 res
= RegSetValueA(hkey
, NULL
, REG_SZ
, def_value
, strlen(def_value
));
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}",
471 && init_key("CLSID\\"TESTSCRIPT_CLSID
"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
475 static BOOL
register_script_engine(void)
480 if(!init_registry(TRUE
)) {
481 init_registry(FALSE
);
485 hres
= CoRegisterClassObject(&CLSID_TestScript
, (IUnknown
*)&script_cf
,
486 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, ®id
);
487 ok(hres
== S_OK
, "Could not register screipt engine: %08x\n", hres
);
492 static void gecko_installer_workaround(BOOL disable
)
497 static BOOL has_url
= FALSE
;
498 static char url
[2048];
500 if(!disable
&& !has_url
)
503 res
= RegOpenKey(HKEY_CURRENT_USER
, "Software\\Wine\\MSHTML", &hkey
);
504 if(res
!= ERROR_SUCCESS
)
508 DWORD type
, size
= sizeof(url
);
510 res
= RegQueryValueEx(hkey
, "GeckoUrl", NULL
, &type
, (PVOID
)url
, &size
);
511 if(res
== ERROR_SUCCESS
&& type
== REG_SZ
)
514 RegDeleteValue(hkey
, "GeckoUrl");
516 RegSetValueEx(hkey
, "GeckoUrl", 0, REG_SZ
, (PVOID
)url
, lstrlenA(url
)+1);
524 gecko_installer_workaround(TRUE
);
527 if(register_script_engine()) {
528 test_simple_script();
529 init_registry(FALSE
);
531 skip("Could not register TestScript engine\n");
535 gecko_installer_workaround(FALSE
);