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