Release 1.4-rc5.
[wine] / dlls / jscript / tests / jscript.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <initguid.h>
23 #include <ole2.h>
24 #include <activscp.h>
25 #include <objsafe.h>
26 #include <dispex.h>
27
28 #include "wine/test.h"
29
30 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
31
32 static const CLSID CLSID_JScript =
33     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
34
35 #define DEFINE_EXPECT(func) \
36     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37
38 #define SET_EXPECT(func) \
39     expect_ ## func = TRUE
40
41 #define CHECK_EXPECT2(func) \
42     do { \
43         ok(expect_ ##func, "unexpected call " #func "\n"); \
44         called_ ## func = TRUE; \
45     }while(0)
46
47 #define CHECK_EXPECT(func) \
48     do { \
49         CHECK_EXPECT2(func); \
50         expect_ ## func = FALSE; \
51     }while(0)
52
53 #define CHECK_CALLED(func) \
54     do { \
55         ok(called_ ## func, "expected " #func "\n"); \
56         expect_ ## func = called_ ## func = FALSE; \
57     }while(0)
58
59 DEFINE_EXPECT(GetLCID);
60 DEFINE_EXPECT(OnStateChange_UNINITIALIZED);
61 DEFINE_EXPECT(OnStateChange_STARTED);
62 DEFINE_EXPECT(OnStateChange_CONNECTED);
63 DEFINE_EXPECT(OnStateChange_DISCONNECTED);
64 DEFINE_EXPECT(OnStateChange_CLOSED);
65 DEFINE_EXPECT(OnStateChange_INITIALIZED);
66 DEFINE_EXPECT(OnEnterScript);
67 DEFINE_EXPECT(OnLeaveScript);
68
69 static BSTR a2bstr(const char *str)
70 {
71     BSTR ret;
72     int len;
73
74     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
75     ret = SysAllocStringLen(NULL, len-1);
76     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
77
78     return ret;
79 }
80
81 #define test_state(s,ss) _test_state(__LINE__,s,ss)
82 static void _test_state(unsigned line, IActiveScript *script, SCRIPTSTATE exstate)
83 {
84     SCRIPTSTATE state = -1;
85     HRESULT hres;
86
87     hres = IActiveScript_GetScriptState(script, &state);
88     ok_(__FILE__,line) (hres == S_OK, "GetScriptState failed: %08x\n", hres);
89     ok_(__FILE__,line) (state == exstate, "state=%d, expected %d\n", state, exstate);
90 }
91
92 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
93 {
94     *ppv = NULL;
95
96     if(IsEqualGUID(&IID_IUnknown, riid))
97         *ppv = iface;
98     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
99         *ppv = iface;
100     else
101         return E_NOINTERFACE;
102
103     IUnknown_AddRef((IUnknown*)*ppv);
104     return S_OK;
105 }
106
107 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
108 {
109     return 2;
110 }
111
112 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
113 {
114     return 1;
115 }
116
117 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
118 {
119     CHECK_EXPECT(GetLCID);
120     return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
124         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
125 {
126     ok(0, "unexpected call\n");
127     return E_NOTIMPL;
128 }
129
130 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
131 {
132     ok(0, "unexpected call\n");
133     return E_NOTIMPL;
134 }
135
136 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
137         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
138 {
139     ok(0, "unexpected call\n");
140     return E_NOTIMPL;
141 }
142
143 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
144 {
145     switch(ssScriptState) {
146     case SCRIPTSTATE_UNINITIALIZED:
147         CHECK_EXPECT(OnStateChange_UNINITIALIZED);
148         return S_OK;
149     case SCRIPTSTATE_STARTED:
150         CHECK_EXPECT(OnStateChange_STARTED);
151         return S_OK;
152     case SCRIPTSTATE_CONNECTED:
153         CHECK_EXPECT(OnStateChange_CONNECTED);
154         return S_OK;
155     case SCRIPTSTATE_DISCONNECTED:
156         CHECK_EXPECT(OnStateChange_DISCONNECTED);
157         return S_OK;
158     case SCRIPTSTATE_CLOSED:
159         CHECK_EXPECT(OnStateChange_CLOSED);
160         return S_OK;
161     case SCRIPTSTATE_INITIALIZED:
162         CHECK_EXPECT(OnStateChange_INITIALIZED);
163         return S_OK;
164     default:
165         ok(0, "unexpected call %d\n", ssScriptState);
166     }
167
168     return E_NOTIMPL;
169 }
170
171 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
172 {
173     ok(0, "unexpected call\n");
174     return E_NOTIMPL;
175 }
176
177 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
178 {
179     CHECK_EXPECT(OnEnterScript);
180     return S_OK;
181 }
182
183 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
184 {
185     CHECK_EXPECT(OnLeaveScript);
186     return S_OK;
187 }
188
189 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
190     ActiveScriptSite_QueryInterface,
191     ActiveScriptSite_AddRef,
192     ActiveScriptSite_Release,
193     ActiveScriptSite_GetLCID,
194     ActiveScriptSite_GetItemInfo,
195     ActiveScriptSite_GetDocVersionString,
196     ActiveScriptSite_OnScriptTerminate,
197     ActiveScriptSite_OnStateChange,
198     ActiveScriptSite_OnScriptError,
199     ActiveScriptSite_OnEnterScript,
200     ActiveScriptSite_OnLeaveScript
201 };
202
203 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
204
205 static void test_script_dispatch(IDispatchEx *dispex)
206 {
207     DISPPARAMS dp = {NULL,NULL,0,0};
208     EXCEPINFO ei;
209     BSTR str;
210     DISPID id;
211     VARIANT v;
212     HRESULT hres;
213
214     str = a2bstr("ActiveXObject");
215     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
216     SysFreeString(str);
217     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
218
219     str = a2bstr("Math");
220     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
221     SysFreeString(str);
222     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
223
224     memset(&ei, 0, sizeof(ei));
225     hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
226     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
227     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
228     ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(v) = NULL\n");
229     VariantClear(&v);
230
231     str = a2bstr("String");
232     hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
233     SysFreeString(str);
234     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
235
236     memset(&ei, 0, sizeof(ei));
237     hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &v, &ei, NULL);
238     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
239     ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
240     ok(V_DISPATCH(&v) != NULL, "V_DISPATCH(v) = NULL\n");
241     VariantClear(&v);
242 }
243
244 static IDispatchEx *get_script_dispatch(IActiveScript *script)
245 {
246     IDispatchEx *dispex;
247     IDispatch *disp;
248     HRESULT hres;
249
250     disp = (void*)0xdeadbeef;
251     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
252     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
253
254     IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
255     IDispatch_Release(disp);
256     ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres);
257     return dispex;
258 }
259
260 static void test_no_script_dispatch(IActiveScript *script)
261 {
262     IDispatch *disp;
263     HRESULT hres;
264
265     disp = (void*)0xdeadbeef;
266     hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
267     ok(hres == E_UNEXPECTED, "hres = %08x, expected E_UNEXPECTED\n", hres);
268     ok(!disp, "disp != NULL\n");
269 }
270
271 static void test_safety(IUnknown *unk)
272 {
273     IObjectSafety *safety;
274     DWORD supported, enabled;
275     HRESULT hres;
276
277     hres = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&safety);
278     ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
279     if(FAILED(hres))
280         return;
281
282     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, NULL);
283     ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
284     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, NULL, &enabled);
285     ok(hres == E_POINTER, "GetInterfaceSafetyOptions failed: %08x, expected E_POINTER\n", hres);
286
287     supported = enabled = 0xdeadbeef;
288     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_NULL, &supported, &enabled);
289     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
290     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
291        "supported=%x\n", supported);
292     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
293
294     supported = enabled = 0xdeadbeef;
295     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScript, &supported, &enabled);
296     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
297     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
298        "supported=%x\n", supported);
299     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
300
301     supported = enabled = 0xdeadbeef;
302     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
303     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
304     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
305        "supported=%x\n", supported);
306     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
307
308     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
309             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER
310                 |INTERFACESAFE_FOR_UNTRUSTED_CALLER,
311             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
312     ok(hres == E_FAIL, "SetInterfaceSafetyOptions failed: %08x, expected E_FAIL\n", hres);
313
314     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
315             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
316             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
317     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
318
319     supported = enabled = 0xdeadbeef;
320     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
321     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
322     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
323        "supported=%x\n", supported);
324     ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
325        "enabled=%x\n", enabled);
326
327     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
328     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
329
330     supported = enabled = 0xdeadbeef;
331     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
332     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
333     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
334        "supported=%x\n", supported);
335     ok(enabled == (INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER), "enabled=%x\n", enabled);
336
337     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
338             INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER, 0);
339     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
340
341     supported = enabled = 0xdeadbeef;
342     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
343     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
344     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
345        "supported=%x\n", supported);
346     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
347
348     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
349             INTERFACE_USES_DISPEX, 0);
350     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
351
352     supported = enabled = 0xdeadbeef;
353     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
354     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
355     ok(supported == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
356        "supported=%x\n", supported);
357     ok(enabled == INTERFACE_USES_DISPEX, "enabled=%x\n", enabled);
358
359     IObjectSafety_Release(safety);
360 }
361
362 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
363 {
364     IActiveScriptProperty *script_prop;
365     HRESULT hres;
366
367     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
368             (void**)&script_prop);
369     ok(hres == S_OK, "Could not get IActiveScriptProperty: %08x\n", hres);
370     if(FAILED(hres))
371         return hres;
372
373     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
374     IActiveScriptProperty_Release(script_prop);
375     return hres;
376 }
377
378 static void test_invoke_versioning(IActiveScript *script)
379 {
380     VARIANT v;
381     HRESULT hres;
382
383     V_VT(&v) = VT_NULL;
384     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
385     if(hres == E_NOTIMPL) {
386         win_skip("SCRIPTPROP_INVOKESTRING not supported\n");
387         return;
388     }
389     ok(hres == E_INVALIDARG, "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
390
391     V_VT(&v) = VT_I2;
392     V_I2(&v) = 0;
393     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
394     ok(hres == E_INVALIDARG, "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
395
396     V_VT(&v) = VT_I4;
397     V_I4(&v) = 16;
398     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
399     ok(hres == E_INVALIDARG, "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
400
401     V_VT(&v) = VT_I4;
402     V_I4(&v) = 2;
403     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
404     ok(hres == S_OK, "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
405 }
406
407 static IActiveScript *create_jscript(void)
408 {
409     IActiveScript *ret;
410     HRESULT hres;
411
412     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
413             &IID_IActiveScript, (void**)&ret);
414     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
415
416     return ret;
417 }
418
419 static void test_jscript(void)
420 {
421     IActiveScriptParse *parse;
422     IActiveScript *script;
423     IDispatchEx *dispex;
424     ULONG ref;
425     HRESULT hres;
426
427     script = create_jscript();
428
429     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
430     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
431
432     test_state(script, SCRIPTSTATE_UNINITIALIZED);
433     test_safety((IUnknown*)script);
434     test_invoke_versioning(script);
435
436     hres = IActiveScriptParse64_InitNew(parse);
437     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
438
439     hres = IActiveScriptParse64_InitNew(parse);
440     ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
441
442     hres = IActiveScript_SetScriptSite(script, NULL);
443     ok(hres == E_POINTER, "SetScriptSite failed: %08x, expected E_POINTER\n", hres);
444
445     test_state(script, SCRIPTSTATE_UNINITIALIZED);
446     test_no_script_dispatch(script);
447
448     SET_EXPECT(GetLCID);
449     SET_EXPECT(OnStateChange_INITIALIZED);
450     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
451     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
452     CHECK_CALLED(GetLCID);
453     CHECK_CALLED(OnStateChange_INITIALIZED);
454
455     test_state(script, SCRIPTSTATE_INITIALIZED);
456
457     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
458     ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
459
460     dispex = get_script_dispatch(script);
461     test_script_dispatch(dispex);
462
463     SET_EXPECT(OnStateChange_STARTED);
464     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED);
465     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
466     CHECK_CALLED(OnStateChange_STARTED);
467
468     test_state(script, SCRIPTSTATE_STARTED);
469
470     SET_EXPECT(OnStateChange_CLOSED);
471     hres = IActiveScript_Close(script);
472     ok(hres == S_OK, "Close failed: %08x\n", hres);
473     CHECK_CALLED(OnStateChange_CLOSED);
474
475     test_state(script, SCRIPTSTATE_CLOSED);
476     test_no_script_dispatch(script);
477     test_script_dispatch(dispex);
478     IDispatchEx_Release(dispex);
479
480     IUnknown_Release(parse);
481
482     ref = IActiveScript_Release(script);
483     ok(!ref, "ref = %d\n", ref);
484 }
485
486 static void test_jscript2(void)
487 {
488     IActiveScriptParse *parse;
489     IActiveScript *script;
490     ULONG ref;
491     HRESULT hres;
492
493     script = create_jscript();
494
495     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
496     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
497
498     test_state(script, SCRIPTSTATE_UNINITIALIZED);
499
500     SET_EXPECT(GetLCID);
501     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
502     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
503     CHECK_CALLED(GetLCID);
504
505     test_state(script, SCRIPTSTATE_UNINITIALIZED);
506
507     SET_EXPECT(OnStateChange_INITIALIZED);
508     hres = IActiveScriptParse64_InitNew(parse);
509     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
510     CHECK_CALLED(OnStateChange_INITIALIZED);
511
512     hres = IActiveScriptParse64_InitNew(parse);
513     ok(hres == E_UNEXPECTED, "InitNew failed: %08x, expected E_UNEXPECTED\n", hres);
514
515     SET_EXPECT(OnStateChange_CONNECTED);
516     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
517     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
518     CHECK_CALLED(OnStateChange_CONNECTED);
519
520     test_state(script, SCRIPTSTATE_CONNECTED);
521
522     SET_EXPECT(OnStateChange_DISCONNECTED);
523     SET_EXPECT(OnStateChange_INITIALIZED);
524     SET_EXPECT(OnStateChange_CLOSED);
525     hres = IActiveScript_Close(script);
526     ok(hres == S_OK, "Close failed: %08x\n", hres);
527     CHECK_CALLED(OnStateChange_DISCONNECTED);
528     CHECK_CALLED(OnStateChange_INITIALIZED);
529     CHECK_CALLED(OnStateChange_CLOSED);
530
531     test_state(script, SCRIPTSTATE_CLOSED);
532     test_no_script_dispatch(script);
533
534     IUnknown_Release(parse);
535
536     ref = IActiveScript_Release(script);
537     ok(!ref, "ref = %d\n", ref);
538 }
539
540 static void test_jscript_uninitializing(void)
541 {
542     IActiveScriptParse *parse;
543     IActiveScript *script;
544     IDispatchEx *dispex;
545     ULONG ref;
546     HRESULT hres;
547
548     static const WCHAR script_textW[] =
549         {'f','u','n','c','t','i','o','n',' ','f','(',')',' ','{','}',0};
550
551     script = create_jscript();
552
553     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
554     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
555
556     test_state(script, SCRIPTSTATE_UNINITIALIZED);
557
558     hres = IActiveScriptParse64_InitNew(parse);
559     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
560
561     SET_EXPECT(GetLCID);
562     SET_EXPECT(OnStateChange_INITIALIZED);
563     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
564     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
565     CHECK_CALLED(GetLCID);
566     CHECK_CALLED(OnStateChange_INITIALIZED);
567
568     test_state(script, SCRIPTSTATE_INITIALIZED);
569
570     hres = IActiveScriptParse64_ParseScriptText(parse, script_textW, NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
571     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
572
573     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
574     ok(hres == E_UNEXPECTED, "SetScriptSite failed: %08x, expected E_UNEXPECTED\n", hres);
575
576     SET_EXPECT(OnStateChange_UNINITIALIZED);
577     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
578     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
579     CHECK_CALLED(OnStateChange_UNINITIALIZED);
580
581     test_state(script, SCRIPTSTATE_UNINITIALIZED);
582
583     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
584     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
585
586     SET_EXPECT(GetLCID);
587     SET_EXPECT(OnStateChange_INITIALIZED);
588     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
589     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
590     CHECK_CALLED(GetLCID);
591     CHECK_CALLED(OnStateChange_INITIALIZED);
592
593     SET_EXPECT(OnStateChange_CONNECTED);
594     SET_EXPECT(OnEnterScript);
595     SET_EXPECT(OnLeaveScript);
596     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
597     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
598     CHECK_CALLED(OnStateChange_CONNECTED);
599     CHECK_CALLED(OnEnterScript);
600     CHECK_CALLED(OnLeaveScript);
601
602     test_state(script, SCRIPTSTATE_CONNECTED);
603
604     dispex = get_script_dispatch(script);
605     ok(dispex != NULL, "dispex == NULL\n");
606     IDispatchEx_Release(dispex);
607
608     SET_EXPECT(OnStateChange_DISCONNECTED);
609     SET_EXPECT(OnStateChange_INITIALIZED);
610     SET_EXPECT(OnStateChange_UNINITIALIZED);
611     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
612     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x\n", hres);
613     CHECK_CALLED(OnStateChange_DISCONNECTED);
614     CHECK_CALLED(OnStateChange_INITIALIZED);
615     CHECK_CALLED(OnStateChange_UNINITIALIZED);
616
617     test_state(script, SCRIPTSTATE_UNINITIALIZED);
618
619     hres = IActiveScript_Close(script);
620     ok(hres == S_OK, "Close failed: %08x\n", hres);
621
622     test_state(script, SCRIPTSTATE_CLOSED);
623
624     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_UNINITIALIZED);
625     ok(hres == E_UNEXPECTED, "SetScriptState(SCRIPTSTATE_UNINITIALIZED) failed: %08x, expected E_UNEXPECTED\n", hres);
626
627     test_state(script, SCRIPTSTATE_CLOSED);
628
629     IUnknown_Release(parse);
630
631     ref = IActiveScript_Release(script);
632     ok(!ref, "ref = %d\n", ref);
633 }
634
635 static void test_aggregation(void)
636 {
637     IUnknown *unk = (IUnknown*)0xdeadbeef;
638     HRESULT hres;
639
640     hres = CoCreateInstance(&CLSID_JScript, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
641             &IID_IUnknown, (void**)&unk);
642     ok(hres == CLASS_E_NOAGGREGATION || broken(E_INVALIDARG) /* win2k */,
643        "CoCreateInstance failed: %08x, expected CLASS_E_NOAGGREGATION\n", hres);
644     ok(!unk || broken(unk != NULL), "unk = %p\n", unk);
645 }
646
647 static BOOL check_jscript(void)
648 {
649     IActiveScriptProperty *script_prop;
650     HRESULT hres;
651
652     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
653             &IID_IActiveScriptProperty, (void**)&script_prop);
654     if(SUCCEEDED(hres))
655         IActiveScriptProperty_Release(script_prop);
656
657     return hres == S_OK;
658 }
659
660 START_TEST(jscript)
661 {
662     CoInitialize(NULL);
663
664     if(check_jscript()) {
665         test_jscript();
666         test_jscript2();
667         test_jscript_uninitializing();
668         test_aggregation();
669     }else {
670         win_skip("Broken engine, probably too old\n");
671     }
672
673     CoUninitialize();
674 }