jscript: Correctly handle empty matches in String.replace.
[wine] / dlls / jscript / tests / run.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 #include <stdio.h>
20
21 #define COBJMACROS
22 #define CONST_VTABLE
23
24 #include <ole2.h>
25 #include <dispex.h>
26 #include <activscp.h>
27
28 #include "wine/test.h"
29
30 static const CLSID CLSID_JScript =
31     {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
32 static const CLSID CLSID_JScriptEncode =
33     {0xf414c262,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(global_propget_d);
60 DEFINE_EXPECT(global_propget_i);
61 DEFINE_EXPECT(global_propput_d);
62 DEFINE_EXPECT(global_propput_i);
63 DEFINE_EXPECT(global_propdelete_d);
64 DEFINE_EXPECT(global_success_d);
65 DEFINE_EXPECT(global_success_i);
66 DEFINE_EXPECT(global_notexists_d);
67 DEFINE_EXPECT(global_propargput_d);
68 DEFINE_EXPECT(global_propargput_i);
69 DEFINE_EXPECT(puredisp_prop_d);
70 DEFINE_EXPECT(puredisp_noprop_d);
71 DEFINE_EXPECT(testobj_delete);
72 DEFINE_EXPECT(testobj_value);
73 DEFINE_EXPECT(testobj_prop_d);
74 DEFINE_EXPECT(testobj_noprop_d);
75 DEFINE_EXPECT(testobj_onlydispid_d);
76 DEFINE_EXPECT(testobj_onlydispid_i);
77 DEFINE_EXPECT(GetItemInfo_testVal);
78 DEFINE_EXPECT(ActiveScriptSite_OnScriptError);
79 DEFINE_EXPECT(invoke_func);
80 DEFINE_EXPECT(DeleteMemberByDispID);
81
82 #define DISPID_GLOBAL_TESTPROPGET   0x1000
83 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
84 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
85 #define DISPID_GLOBAL_TRACE         0x1003
86 #define DISPID_GLOBAL_OK            0x1004
87 #define DISPID_GLOBAL_GETVT         0x1005
88 #define DISPID_GLOBAL_TESTOBJ       0x1006
89 #define DISPID_GLOBAL_GETNULLBSTR   0x1007
90 #define DISPID_GLOBAL_NULL_DISP     0x1008
91 #define DISPID_GLOBAL_TESTTHIS      0x1009
92 #define DISPID_GLOBAL_TESTTHIS2     0x100a
93 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
94 #define DISPID_GLOBAL_CREATEARRAY   0x100c
95 #define DISPID_GLOBAL_PROPGETFUNC   0x100d
96 #define DISPID_GLOBAL_OBJECT_FLAG   0x100e
97 #define DISPID_GLOBAL_ISWIN64       0x100f
98 #define DISPID_GLOBAL_PUREDISP      0x1010
99 #define DISPID_GLOBAL_TESTPROPDELETE  0x1010
100 #define DISPID_GLOBAL_ISNULLBSTR    0x1011
101 #define DISPID_GLOBAL_PROPARGPUT    0x1012
102
103 #define DISPID_TESTOBJ_PROP         0x2000
104 #define DISPID_TESTOBJ_ONLYDISPID   0x2001
105
106 #define JS_E_INVALID_CHAR 0x800a03f6
107
108 static const WCHAR testW[] = {'t','e','s','t',0};
109 static const CHAR testA[] = "test";
110 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
111 static const CHAR test_valA[] = "testVal";
112
113 static BOOL strict_dispid_check;
114 static const char *test_name = "(null)";
115 static IDispatch *script_disp;
116 static int invoke_version;
117 static IActiveScriptError *script_error;
118 static const CLSID *engine_clsid = &CLSID_JScript;
119
120 /* Returns true if the user interface is in English. Note that this does not
121  * presume of the formatting of dates, numbers, etc.
122  */
123 static BOOL is_lang_english(void)
124 {
125     static HMODULE hkernel32 = NULL;
126     static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
127     static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
128
129     if (!hkernel32)
130     {
131         hkernel32 = GetModuleHandleA("kernel32.dll");
132         pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
133         pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
134     }
135     if (pGetThreadUILanguage)
136         return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
137     if (pGetUserDefaultUILanguage)
138         return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
139
140     return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
141 }
142
143 static BSTR a2bstr(const char *str)
144 {
145     BSTR ret;
146     int len;
147
148     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
149     ret = SysAllocStringLen(NULL, len-1);
150     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
151
152     return ret;
153 }
154
155 static int strcmp_wa(LPCWSTR strw, const char *stra)
156 {
157     CHAR buf[512];
158     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
159     return lstrcmpA(buf, stra);
160 }
161
162 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
163 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
164 {
165     expect |= invoke_version << 28;
166     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
167 }
168
169 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
170 {
171     *ppv = NULL;
172
173     if(IsEqualGUID(riid, &IID_IUnknown)
174        || IsEqualGUID(riid, &IID_IDispatch)
175        || IsEqualGUID(riid, &IID_IDispatchEx))
176         *ppv = iface;
177     else
178         return E_NOINTERFACE;
179
180     return S_OK;
181 }
182
183 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
184 {
185     return 2;
186 }
187
188 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
189 {
190     return 1;
191 }
192
193 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
194 {
195     ok(0, "unexpected call\n");
196     return E_NOTIMPL;
197 }
198
199 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
200                                               LCID lcid, ITypeInfo **ppTInfo)
201 {
202     ok(0, "unexpected call\n");
203     return E_NOTIMPL;
204 }
205
206 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
207                                                 LPOLESTR *rgszNames, UINT cNames,
208                                                 LCID lcid, DISPID *rgDispId)
209 {
210     ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n");
211     ok(cNames==1, "cNames = %d\n", cNames);
212
213     if(!strcmp_wa(*rgszNames, "prop")) {
214         CHECK_EXPECT(puredisp_prop_d);
215         *rgDispId = DISPID_TESTOBJ_PROP;
216         return S_OK;
217     } else if(!strcmp_wa(*rgszNames, "noprop")) {
218         CHECK_EXPECT(puredisp_noprop_d);
219         return DISP_E_UNKNOWNNAME;
220     }
221
222     ok(0, "unexpected call\n");
223     return E_NOTIMPL;
224 }
225
226 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
227                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
228                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
229 {
230     ok(0, "unexpected call\n");
231     return E_NOTIMPL;
232 }
233
234 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
235 {
236     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
237     return E_NOTIMPL;
238 }
239
240 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
241 {
242     ok(0, "unexpected call\n");
243     return E_NOTIMPL;
244 }
245
246 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
247 {
248     ok(0, "unexpected call\n");
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
253 {
254     ok(0, "unexpected call\n");
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
259 {
260     ok(0, "unexpected call\n");
261     return E_NOTIMPL;
262 }
263
264 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
265 {
266     ok(0, "unexpected call\n");
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
271 {
272     if(!strcmp_wa(bstrName, "prop")) {
273         CHECK_EXPECT(testobj_prop_d);
274         test_grfdex(grfdex, fdexNameCaseSensitive);
275         *pid = DISPID_TESTOBJ_PROP;
276         return S_OK;
277     }
278     if(!strcmp_wa(bstrName, "noprop")) {
279         CHECK_EXPECT(testobj_noprop_d);
280         test_grfdex(grfdex, fdexNameCaseSensitive);
281         return DISP_E_UNKNOWNNAME;
282     }
283     if(!strcmp_wa(bstrName, "onlyDispID")) {
284         if(strict_dispid_check)
285             CHECK_EXPECT(testobj_onlydispid_d);
286         test_grfdex(grfdex, fdexNameCaseSensitive);
287         *pid = DISPID_TESTOBJ_ONLYDISPID;
288         return S_OK;
289     }
290
291     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
292     return E_NOTIMPL;
293 }
294
295 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
296         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
297 {
298     ok(pspCaller != NULL, "pspCaller = NULL\n");
299
300     switch(id) {
301     case DISPID_VALUE:
302         ok(pdp != NULL, "pdp == NULL\n");
303         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
304         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
305         ok(pvarRes != NULL, "pvarRes == NULL\n");
306         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
307         ok(pei != NULL, "pei == NULL\n");
308
309         switch(wFlags) {
310         case INVOKE_PROPERTYGET:
311             CHECK_EXPECT(testobj_value);
312             ok(!pdp->rgvarg, "rgvarg != NULL\n");
313             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
314             break;
315         case INVOKE_FUNC:
316             ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
317             break;
318         case INVOKE_FUNC|INVOKE_PROPERTYGET:
319             ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
320             break;
321         default:
322             ok(0, "invalid flag (%x)\n", wFlags);
323         }
324
325         V_VT(pvarRes) = VT_I4;
326         V_I4(pvarRes) = 1;
327         return S_OK;
328     case DISPID_TESTOBJ_ONLYDISPID:
329         if(strict_dispid_check)
330             CHECK_EXPECT(testobj_onlydispid_i);
331         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
332         ok(pdp != NULL, "pdp == NULL\n");
333         ok(!pdp->rgvarg, "rgvarg != NULL\n");
334         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
335         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
336         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
337         ok(pvarRes != NULL, "pvarRes == NULL\n");
338         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
339         ok(pei != NULL, "pei == NULL\n");
340         return DISP_E_MEMBERNOTFOUND;
341     }
342
343     ok(0, "unexpected call %x\n", id);
344     return DISP_E_MEMBERNOTFOUND;
345 }
346
347 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
348 {
349     CHECK_EXPECT(testobj_delete);
350
351     ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", wine_dbgstr_w(bstrName));
352     test_grfdex(grfdex, fdexNameCaseSensitive);
353     return S_OK;
354 }
355
356 static IDispatchExVtbl testObjVtbl = {
357     DispatchEx_QueryInterface,
358     DispatchEx_AddRef,
359     DispatchEx_Release,
360     DispatchEx_GetTypeInfoCount,
361     DispatchEx_GetTypeInfo,
362     DispatchEx_GetIDsOfNames,
363     DispatchEx_Invoke,
364     testObj_GetDispID,
365     testObj_InvokeEx,
366     testObj_DeleteMemberByName,
367     DispatchEx_DeleteMemberByDispID,
368     DispatchEx_GetMemberProperties,
369     DispatchEx_GetMemberName,
370     DispatchEx_GetNextDispID,
371     DispatchEx_GetNameSpaceParent
372 };
373
374 static IDispatchEx testObj = { &testObjVtbl };
375
376 static HRESULT WINAPI pureDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
377 {
378     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
379         *ppv = iface;
380         return S_OK;
381     }
382
383     *ppv = NULL;
384     return E_NOINTERFACE;
385 }
386
387 static IDispatchExVtbl pureDispVtbl = {
388     pureDisp_QueryInterface,
389     DispatchEx_AddRef,
390     DispatchEx_Release,
391     DispatchEx_GetTypeInfoCount,
392     DispatchEx_GetTypeInfo,
393     DispatchEx_GetIDsOfNames,
394     DispatchEx_Invoke
395 };
396
397 static IDispatchEx pureDisp = { &pureDispVtbl };
398
399 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
400 {
401     if(!strcmp_wa(bstrName, "ok")) {
402         test_grfdex(grfdex, fdexNameCaseSensitive);
403         *pid = DISPID_GLOBAL_OK;
404         return S_OK;
405     }
406     if(!strcmp_wa(bstrName, "trace")) {
407         test_grfdex(grfdex, fdexNameCaseSensitive);
408         *pid = DISPID_GLOBAL_TRACE;
409         return S_OK;
410     }
411     if(!strcmp_wa(bstrName, "reportSuccess")) {
412         CHECK_EXPECT(global_success_d);
413         test_grfdex(grfdex, fdexNameCaseSensitive);
414         *pid = DISPID_GLOBAL_REPORTSUCCESS;
415         return S_OK;
416     }
417     if(!strcmp_wa(bstrName, "testPropGet")) {
418         CHECK_EXPECT(global_propget_d);
419         test_grfdex(grfdex, fdexNameCaseSensitive);
420         *pid = DISPID_GLOBAL_TESTPROPGET;
421         return S_OK;
422     }
423     if(!strcmp_wa(bstrName, "testPropPut")) {
424         CHECK_EXPECT(global_propput_d);
425         test_grfdex(grfdex, fdexNameCaseSensitive);
426         *pid = DISPID_GLOBAL_TESTPROPPUT;
427         return S_OK;
428     }
429     if(!strcmp_wa(bstrName, "testPropDelete")) {
430         CHECK_EXPECT(global_propdelete_d);
431         test_grfdex(grfdex, fdexNameCaseSensitive);
432         *pid = DISPID_GLOBAL_TESTPROPDELETE;
433         return S_OK;
434     }
435     if(!strcmp_wa(bstrName, "getVT")) {
436         test_grfdex(grfdex, fdexNameCaseSensitive);
437         *pid = DISPID_GLOBAL_GETVT;
438         return S_OK;
439     }
440     if(!strcmp_wa(bstrName, "testObj")) {
441         test_grfdex(grfdex, fdexNameCaseSensitive);
442         *pid = DISPID_GLOBAL_TESTOBJ;
443         return S_OK;
444     }
445     if(!strcmp_wa(bstrName, "getNullBSTR")) {
446         *pid = DISPID_GLOBAL_GETNULLBSTR;
447         return S_OK;
448     }
449     if(!strcmp_wa(bstrName, "isNullBSTR")) {
450         *pid = DISPID_GLOBAL_ISNULLBSTR;
451         return S_OK;
452     }
453     if(!strcmp_wa(bstrName, "nullDisp")) {
454         *pid = DISPID_GLOBAL_NULL_DISP;
455         return S_OK;
456     }
457     if(!strcmp_wa(bstrName, "notExists")) {
458         CHECK_EXPECT(global_notexists_d);
459         test_grfdex(grfdex, fdexNameCaseSensitive);
460         return DISP_E_UNKNOWNNAME;
461     }
462
463     if(!strcmp_wa(bstrName, "testThis")) {
464         test_grfdex(grfdex, fdexNameCaseSensitive);
465         *pid = DISPID_GLOBAL_TESTTHIS;
466         return S_OK;
467     }
468
469     if(!strcmp_wa(bstrName, "testThis2")) {
470         test_grfdex(grfdex, fdexNameCaseSensitive);
471         *pid = DISPID_GLOBAL_TESTTHIS2;
472         return S_OK;
473     }
474
475     if(!strcmp_wa(bstrName, "invokeVersion")) {
476         test_grfdex(grfdex, fdexNameCaseSensitive);
477         *pid = DISPID_GLOBAL_INVOKEVERSION;
478         return S_OK;
479     }
480     if(!strcmp_wa(bstrName, "createArray")) {
481         test_grfdex(grfdex, fdexNameCaseSensitive);
482         *pid = DISPID_GLOBAL_CREATEARRAY;
483         return S_OK;
484     }
485     if(!strcmp_wa(bstrName, "propGetFunc")) {
486         test_grfdex(grfdex, fdexNameCaseSensitive);
487         *pid = DISPID_GLOBAL_PROPGETFUNC;
488         return S_OK;
489     }
490     if(!strcmp_wa(bstrName, "objectFlag")) {
491         test_grfdex(grfdex, fdexNameCaseSensitive);
492         *pid = DISPID_GLOBAL_OBJECT_FLAG;
493         return S_OK;
494     }
495
496     if(!strcmp_wa(bstrName, "isWin64")) {
497         test_grfdex(grfdex, fdexNameCaseSensitive);
498         *pid = DISPID_GLOBAL_ISWIN64;
499         return S_OK;
500     }
501
502     if(!strcmp_wa(bstrName, "pureDisp")) {
503         test_grfdex(grfdex, fdexNameCaseSensitive);
504         *pid = DISPID_GLOBAL_PUREDISP;
505         return S_OK;
506     }
507
508     if(!strcmp_wa(bstrName, "propArgPutG")) {
509         CHECK_EXPECT(global_propargput_d);
510         test_grfdex(grfdex, fdexNameCaseSensitive);
511         *pid = DISPID_GLOBAL_PROPARGPUT;
512         return S_OK;
513     }
514
515     if(!strcmp_wa(bstrName, "propArgPutO")) {
516         CHECK_EXPECT(global_propargput_d);
517         test_grfdex(grfdex, fdexNameEnsure|fdexNameCaseSensitive);
518         *pid = DISPID_GLOBAL_PROPARGPUT;
519         return S_OK;
520     }
521
522     if(strict_dispid_check && strcmp_wa(bstrName, "t"))
523         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
524     return DISP_E_UNKNOWNNAME;
525 }
526
527 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
528         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
529 {
530     ok(pspCaller != NULL, "pspCaller = NULL\n");
531
532     switch(id) {
533     case DISPID_GLOBAL_OK:
534         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
535         ok(pdp != NULL, "pdp == NULL\n");
536         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
537         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
538         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
539         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
540         if(wFlags & INVOKE_PROPERTYGET)
541             ok(pvarRes != NULL, "pvarRes == NULL\n");
542         else
543             ok(!pvarRes, "pvarRes != NULL\n");
544         ok(pei != NULL, "pei == NULL\n");
545
546         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
547         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
548         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
549
550         return S_OK;
551
552      case DISPID_GLOBAL_TRACE:
553         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
554         ok(pdp != NULL, "pdp == NULL\n");
555         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
556         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
557         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
558         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
559         ok(!pvarRes, "pvarRes != NULL\n");
560         ok(pei != NULL, "pei == NULL\n");
561
562         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
563         if(V_VT(pdp->rgvarg) == VT_BSTR)
564             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
565
566         return S_OK;
567
568     case DISPID_GLOBAL_REPORTSUCCESS:
569         CHECK_EXPECT(global_success_i);
570
571         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
572         ok(pdp != NULL, "pdp == NULL\n");
573         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
574         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
575         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
576         ok(!pvarRes, "pvarRes != NULL\n");
577         ok(pei != NULL, "pei == NULL\n");
578
579         return S_OK;
580
581      case DISPID_GLOBAL_TESTPROPGET:
582         CHECK_EXPECT(global_propget_i);
583
584         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
585         ok(pdp != NULL, "pdp == NULL\n");
586         ok(!pdp->rgvarg, "rgvarg != NULL\n");
587         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
588         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
589         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
590         ok(pvarRes != NULL, "pvarRes == NULL\n");
591         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
592         ok(pei != NULL, "pei == NULL\n");
593
594         V_VT(pvarRes) = VT_I4;
595         V_I4(pvarRes) = 1;
596
597         return S_OK;
598
599     case DISPID_GLOBAL_TESTPROPPUT:
600         CHECK_EXPECT(global_propput_i);
601
602         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
603         ok(pdp != NULL, "pdp == NULL\n");
604         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
605         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
606         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
607         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
608         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
609         ok(!pvarRes, "pvarRes != NULL\n");
610
611         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
612         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
613         return S_OK;
614
615      case DISPID_GLOBAL_GETVT:
616         ok(pdp != NULL, "pdp == NULL\n");
617         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
618         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
619         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
620         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
621         ok(pvarRes != NULL, "pvarRes == NULL\n");
622         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
623         ok(pei != NULL, "pei == NULL\n");
624
625         V_VT(pvarRes) = VT_BSTR;
626         switch(V_VT(pdp->rgvarg)) {
627         case VT_EMPTY:
628             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
629             break;
630         case VT_NULL:
631             V_BSTR(pvarRes) = a2bstr("VT_NULL");
632             break;
633         case VT_I4:
634             V_BSTR(pvarRes) = a2bstr("VT_I4");
635             break;
636         case VT_R8:
637             V_BSTR(pvarRes) = a2bstr("VT_R8");
638             break;
639         case VT_BSTR:
640             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
641             break;
642         case VT_DISPATCH:
643             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
644             break;
645         case VT_BOOL:
646             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
647             break;
648         case VT_ARRAY|VT_VARIANT:
649             V_BSTR(pvarRes) = a2bstr("VT_ARRAY|VT_VARIANT");
650             break;
651         default:
652             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
653             return E_FAIL;
654         }
655
656         return S_OK;
657
658     case DISPID_GLOBAL_TESTOBJ:
659         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
660         ok(pdp != NULL, "pdp == NULL\n");
661         ok(!pdp->rgvarg, "rgvarg != NULL\n");
662         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
663         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
664         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
665         ok(pvarRes != NULL, "pvarRes == NULL\n");
666         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
667         ok(pei != NULL, "pei == NULL\n");
668
669         V_VT(pvarRes) = VT_DISPATCH;
670         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
671         return S_OK;
672
673     case DISPID_GLOBAL_PUREDISP:
674         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
675         ok(pdp != NULL, "pdp == NULL\n");
676         ok(!pdp->rgvarg, "rgvarg != NULL\n");
677         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
678         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
679         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
680         ok(pvarRes != NULL, "pvarRes == NULL\n");
681         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
682         ok(pei != NULL, "pei == NULL\n");
683
684         V_VT(pvarRes) = VT_DISPATCH;
685         V_DISPATCH(pvarRes) = (IDispatch*)&pureDisp;
686         return S_OK;
687
688     case DISPID_GLOBAL_GETNULLBSTR:
689         if(pvarRes) {
690             V_VT(pvarRes) = VT_BSTR;
691             V_BSTR(pvarRes) = NULL;
692         }
693         return S_OK;
694
695     case DISPID_GLOBAL_ISNULLBSTR:
696         ok(pdp != NULL, "pdp == NULL\n");
697         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
698         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
699         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
700         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
701         ok(pvarRes != NULL, "pvarRes == NULL\n");
702         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
703         ok(pei != NULL, "pei == NULL\n");
704         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
705
706         V_VT(pvarRes) = VT_BOOL;
707         V_BOOL(pvarRes) = V_BSTR(pdp->rgvarg) ? VARIANT_FALSE : VARIANT_TRUE;
708         return S_OK;
709
710     case DISPID_GLOBAL_ISWIN64:
711         if(pvarRes) {
712             V_VT(pvarRes) = VT_BOOL;
713             V_BOOL(pvarRes) = sizeof(void*) == 8 ? VARIANT_TRUE : VARIANT_FALSE;
714         }
715         return S_OK;
716
717     case DISPID_GLOBAL_NULL_DISP:
718         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
719         ok(pdp != NULL, "pdp == NULL\n");
720         ok(!pdp->rgvarg, "rgvarg != NULL\n");
721         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
722         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
723         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
724         ok(pvarRes != NULL, "pvarRes == NULL\n");
725         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
726         ok(pei != NULL, "pei == NULL\n");
727
728         V_VT(pvarRes) = VT_DISPATCH;
729         V_DISPATCH(pvarRes) = NULL;
730         return S_OK;
731
732     case DISPID_GLOBAL_TESTTHIS:
733         ok(pdp != NULL, "pdp == NULL\n");
734         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
735         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
736         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
737         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
738         ok(pvarRes == NULL, "pvarRes != NULL\n");
739         ok(pei != NULL, "pei == NULL\n");
740
741         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
742         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
743
744         return S_OK;
745
746     case DISPID_GLOBAL_TESTTHIS2:
747         ok(pdp != NULL, "pdp == NULL\n");
748         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
749         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
750         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
751         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
752         ok(pvarRes == NULL, "pvarRes != NULL\n");
753         ok(pei != NULL, "pei == NULL\n");
754
755         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
756         ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
757         ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
758
759         return S_OK;
760
761      case DISPID_GLOBAL_INVOKEVERSION:
762         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
763         ok(pdp != NULL, "pdp == NULL\n");
764         ok(!pdp->rgvarg, "rgvarg != NULL\n");
765         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
766         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
767         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
768         ok(pvarRes != NULL, "pvarRes == NULL\n");
769         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
770         ok(pei != NULL, "pei == NULL\n");
771
772         V_VT(pvarRes) = VT_I4;
773         V_I4(pvarRes) = invoke_version;
774
775         return S_OK;
776
777     case DISPID_GLOBAL_CREATEARRAY: {
778         SAFEARRAYBOUND bound[2];
779         VARIANT *data;
780         int i,j;
781
782         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
783         ok(pdp != NULL, "pdp == NULL\n");
784         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
785         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
786         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
787         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
788         ok(pvarRes != NULL, "pvarRes == NULL\n");
789         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
790         ok(pei != NULL, "pei == NULL\n");
791
792         bound[0].lLbound = 0;
793         bound[0].cElements = 5;
794         bound[1].lLbound = 2;
795         bound[1].cElements = 2;
796
797         V_VT(pvarRes) = VT_ARRAY|VT_VARIANT;
798         V_ARRAY(pvarRes) = SafeArrayCreate(VT_VARIANT, 2, bound);
799
800         SafeArrayAccessData(V_ARRAY(pvarRes), (void**)&data);
801         for(i=0; i<5; i++) {
802             for(j=2; j<4; j++) {
803                 V_VT(data) = VT_I4;
804                 V_I4(data) = i*10+j;
805                 data++;
806             }
807         }
808         SafeArrayUnaccessData(V_ARRAY(pvarRes));
809
810         return S_OK;
811     }
812
813     case DISPID_GLOBAL_PROPGETFUNC:
814         switch(wFlags) {
815         case INVOKE_FUNC:
816             CHECK_EXPECT(invoke_func);
817             break;
818         case INVOKE_FUNC|INVOKE_PROPERTYGET:
819             ok(pdp->cArgs != 0, "pdp->cArgs = %d\n", pdp->cArgs);
820             ok(pvarRes != NULL, "pdp->pvarRes == NULL\n");
821             break;
822         default:
823             ok(0, "invalid flag (%x)\n", wFlags);
824         }
825
826         ok(pdp != NULL, "pdp == NULL\n");
827         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
828         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
829         ok(pei != NULL, "pei == NULL\n");
830
831         if(pvarRes) {
832             ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
833             V_VT(pvarRes) = VT_I4;
834             V_I4(pvarRes) = pdp->cArgs;
835         }
836
837         return S_OK;
838
839     case DISPID_GLOBAL_PROPARGPUT:
840         CHECK_EXPECT(global_propargput_i);
841         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
842         ok(pdp != NULL, "pdp == NULL\n");
843         ok(pdp->rgvarg != NULL, "rgvarg != NULL\n");
844         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
845         ok(pdp->cArgs == 3, "cArgs = %d\n", pdp->cArgs);
846         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
847         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
848         ok(!pvarRes, "pvarRes != NULL\n");
849         ok(pei != NULL, "pei == NULL\n");
850
851         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
852         ok(V_I4(pdp->rgvarg) == 2, "V_I4(psp->rgvargs) = %d\n", V_I4(pdp->rgvarg));
853
854         ok(V_VT(pdp->rgvarg+1) == VT_I4, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg+1));
855         ok(V_I4(pdp->rgvarg+1) == 1, "V_I4(psp->rgvargs+1) = %d\n", V_I4(pdp->rgvarg+1));
856
857         ok(V_VT(pdp->rgvarg+2) == VT_I4, "V_VT(psp->rgvargs+2) = %d\n", V_VT(pdp->rgvarg+2));
858         ok(V_I4(pdp->rgvarg+2) == 0, "V_I4(psp->rgvargs+2) = %d\n", V_I4(pdp->rgvarg+2));
859         return S_OK;
860
861     case DISPID_GLOBAL_OBJECT_FLAG: {
862         IDispatchEx *dispex;
863         BSTR str;
864         HRESULT hres;
865
866         hres = IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&dispex);
867         ok(hres == S_OK, "hres = %x\n", hres);
868
869         str = a2bstr("Object");
870         hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseSensitive, &id);
871         SysFreeString(str);
872         ok(hres == S_OK, "hres = %x\n", hres);
873
874         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, NULL, pei, pspCaller);
875         ok(hres == S_OK, "hres = %x\n", hres);
876
877         V_VT(pvarRes) = VT_EMPTY;
878         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD, pdp, pvarRes, pei, pspCaller);
879         ok(hres == S_OK, "hres = %x\n", hres);
880         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
881         VariantClear(pvarRes);
882
883         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, pdp, NULL, pei, pspCaller);
884         ok(hres == S_OK, "hres = %x\n", hres);
885
886         V_VT(pvarRes) = VT_EMPTY;
887         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, pvarRes, pei, pspCaller);
888         ok(hres == S_OK, "hres = %x\n", hres);
889         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
890         VariantClear(pvarRes);
891
892         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT, pdp, NULL, pei, pspCaller);
893         ok(hres == S_OK, "hres = %x\n", hres);
894
895         V_VT(pvarRes) = VT_EMPTY;
896         hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_CONSTRUCT|DISPATCH_PROPERTYGET, pdp, pvarRes, pei, pspCaller);
897         ok(hres == E_INVALIDARG, "hres = %x\n", hres);
898
899         V_VT(pvarRes) = VT_EMPTY;
900         hres = IDispatchEx_InvokeEx(dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
901         ok(hres == S_OK, "hres = %x\n", hres);
902         ok(V_VT(pvarRes) == VT_DISPATCH, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
903         IDispatchEx_Release(dispex);
904         return S_OK;
905     }
906     }
907
908     ok(0, "unexpected call %x\n", id);
909     return DISP_E_MEMBERNOTFOUND;
910 }
911
912 static HRESULT WINAPI Global_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
913 {
914     CHECK_EXPECT(DeleteMemberByDispID);
915     ok(id == DISPID_GLOBAL_TESTPROPDELETE, "id = %d\n", id);
916     return S_OK;
917 }
918
919 static IDispatchExVtbl GlobalVtbl = {
920     DispatchEx_QueryInterface,
921     DispatchEx_AddRef,
922     DispatchEx_Release,
923     DispatchEx_GetTypeInfoCount,
924     DispatchEx_GetTypeInfo,
925     DispatchEx_GetIDsOfNames,
926     DispatchEx_Invoke,
927     Global_GetDispID,
928     Global_InvokeEx,
929     DispatchEx_DeleteMemberByName,
930     Global_DeleteMemberByDispID,
931     DispatchEx_GetMemberProperties,
932     DispatchEx_GetMemberName,
933     DispatchEx_GetNextDispID,
934     DispatchEx_GetNameSpaceParent
935 };
936
937 static IDispatchEx Global = { &GlobalVtbl };
938
939 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
940 {
941     *ppv = NULL;
942
943     if(IsEqualGUID(&IID_IUnknown, riid))
944         *ppv = iface;
945     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
946         *ppv = iface;
947     else
948         return E_NOINTERFACE;
949
950     IUnknown_AddRef((IUnknown*)*ppv);
951     return S_OK;
952 }
953
954 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
955 {
956     return 2;
957 }
958
959 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
960 {
961     return 1;
962 }
963
964 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
965 {
966     *plcid = GetUserDefaultLCID();
967     return S_OK;
968 }
969
970 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
971         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
972 {
973     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
974     ok(!ppti, "ppti != NULL\n");
975
976     if(!strcmp_wa(pstrName, test_valA))
977         CHECK_EXPECT(GetItemInfo_testVal);
978     else if(strcmp_wa(pstrName, testA))
979         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
980
981     *ppiunkItem = (IUnknown*)&Global;
982     return S_OK;
983 }
984
985 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
986 {
987     return E_NOTIMPL;
988 }
989
990 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
991         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
992 {
993     return E_NOTIMPL;
994 }
995
996 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
997 {
998     return E_NOTIMPL;
999 }
1000
1001 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1002 {
1003     return E_NOTIMPL;
1004 }
1005
1006 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
1007 {
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
1012 {
1013     return E_NOTIMPL;
1014 }
1015
1016 #undef ACTSCPSITE_THIS
1017
1018 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
1019     ActiveScriptSite_QueryInterface,
1020     ActiveScriptSite_AddRef,
1021     ActiveScriptSite_Release,
1022     ActiveScriptSite_GetLCID,
1023     ActiveScriptSite_GetItemInfo,
1024     ActiveScriptSite_GetDocVersionString,
1025     ActiveScriptSite_OnScriptTerminate,
1026     ActiveScriptSite_OnStateChange,
1027     ActiveScriptSite_OnScriptError,
1028     ActiveScriptSite_OnEnterScript,
1029     ActiveScriptSite_OnLeaveScript
1030 };
1031
1032 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
1033
1034 static HRESULT WINAPI ActiveScriptSite_OnScriptError_CheckError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
1035 {
1036     ok(pscripterror != NULL, "ActiveScriptSite_OnScriptError -- expected pscripterror to be set, got NULL\n");
1037
1038     script_error = pscripterror;
1039     IUnknown_AddRef(script_error);
1040
1041     CHECK_EXPECT(ActiveScriptSite_OnScriptError);
1042
1043     return S_OK;
1044 }
1045
1046 static const IActiveScriptSiteVtbl ActiveScriptSite_CheckErrorVtbl = {
1047     ActiveScriptSite_QueryInterface,
1048     ActiveScriptSite_AddRef,
1049     ActiveScriptSite_Release,
1050     ActiveScriptSite_GetLCID,
1051     ActiveScriptSite_GetItemInfo,
1052     ActiveScriptSite_GetDocVersionString,
1053     ActiveScriptSite_OnScriptTerminate,
1054     ActiveScriptSite_OnStateChange,
1055     ActiveScriptSite_OnScriptError_CheckError,
1056     ActiveScriptSite_OnEnterScript,
1057     ActiveScriptSite_OnLeaveScript
1058 };
1059
1060 static IActiveScriptSite ActiveScriptSite_CheckError = { &ActiveScriptSite_CheckErrorVtbl };
1061
1062 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
1063 {
1064     IActiveScriptProperty *script_prop;
1065     HRESULT hres;
1066
1067     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
1068             (void**)&script_prop);
1069     ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
1070
1071     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
1072     IActiveScriptProperty_Release(script_prop);
1073
1074     return hres;
1075 }
1076
1077 static IActiveScript *create_script(void)
1078 {
1079     IActiveScript *script;
1080     VARIANT v;
1081     HRESULT hres;
1082
1083     hres = CoCreateInstance(engine_clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1084             &IID_IActiveScript, (void**)&script);
1085     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1086
1087     V_VT(&v) = VT_I4;
1088     V_I4(&v) = invoke_version;
1089     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
1090     ok(hres == S_OK || broken(hres == E_NOTIMPL), "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
1091     if(invoke_version && FAILED(hres)) {
1092         IActiveScript_Release(script);
1093         return NULL;
1094     }
1095
1096     return script;
1097 }
1098
1099 static HRESULT parse_script(DWORD flags, BSTR script_str)
1100 {
1101     IActiveScriptParse *parser;
1102     IActiveScript *engine;
1103     HRESULT hres;
1104
1105     engine = create_script();
1106     if(!engine)
1107         return S_OK;
1108
1109     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1110     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1111     if (FAILED(hres))
1112     {
1113         IActiveScript_Release(engine);
1114         return hres;
1115     }
1116
1117     hres = IActiveScriptParse64_InitNew(parser);
1118     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1119
1120     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1121     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1122
1123     hres = IActiveScript_AddNamedItem(engine, testW,
1124             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1125     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1126
1127     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1128     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1129
1130     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1131     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1132     ok(script_disp != NULL, "script_disp == NULL\n");
1133     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1134
1135     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1136
1137     IDispatch_Release(script_disp);
1138     IActiveScript_Release(engine);
1139     IUnknown_Release(parser);
1140
1141     return hres;
1142 }
1143
1144 static HRESULT parse_htmlscript(BSTR script_str)
1145 {
1146     IActiveScriptParse *parser;
1147     IActiveScript *engine;
1148     HRESULT hres;
1149     BSTR tmp = a2bstr("</SCRIPT>");
1150
1151     engine = create_script();
1152     if(!engine)
1153         return E_FAIL;
1154
1155     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1156     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1157     if (FAILED(hres))
1158     {
1159         IActiveScript_Release(engine);
1160         return E_FAIL;
1161     }
1162
1163     hres = IActiveScriptParse64_InitNew(parser);
1164     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1165
1166     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1167     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1168
1169     hres = IActiveScript_AddNamedItem(engine, testW,
1170             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
1171     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1172
1173     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1174     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1175
1176     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
1177
1178     IActiveScript_Release(engine);
1179     IUnknown_Release(parser);
1180     SysFreeString(tmp);
1181
1182     return hres;
1183 }
1184
1185 static void test_IActiveScriptError(IActiveScriptError *error, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1186 {
1187     HRESULT hres;
1188     DWORD source_context;
1189     ULONG line_number;
1190     LONG char_position;
1191     BSTR linetext;
1192     EXCEPINFO excep;
1193
1194     /* IActiveScriptError_GetSourcePosition */
1195
1196     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, NULL);
1197     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1198
1199     source_context = 0xdeadbeef;
1200     hres = IActiveScriptError_GetSourcePosition(error, &source_context, NULL, NULL);
1201     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1202     ok(source_context == 0, "IActiveScriptError_GetSourcePosition -- source_context: expected 0, got 0x%08x\n", source_context);
1203
1204     line_number = 0xdeadbeef;
1205     hres = IActiveScriptError_GetSourcePosition(error, NULL, &line_number, NULL);
1206     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1207     ok(line_number == line, "IActiveScriptError_GetSourcePosition -- line_number: expected %d, got %d\n", line, line_number);
1208
1209     char_position = 0xdeadbeef;
1210     hres = IActiveScriptError_GetSourcePosition(error, NULL, NULL, &char_position);
1211     ok(hres == S_OK, "IActiveScriptError_GetSourcePosition -- hres: expected S_OK, got 0x%08x\n", hres);
1212     ok(char_position == pos, "IActiveScriptError_GetSourcePosition -- char_position: expected %d, got %d\n", pos, char_position);
1213
1214     /* IActiveScriptError_GetSourceLineText */
1215
1216     hres = IActiveScriptError_GetSourceLineText(error, NULL);
1217     ok(hres == E_POINTER, "IActiveScriptError_GetSourceLineText -- hres: expected E_POINTER, got 0x%08x\n", hres);
1218
1219     linetext = NULL;
1220     hres = IActiveScriptError_GetSourceLineText(error, &linetext);
1221     if (line_text) {
1222         ok(hres == S_OK, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1223         ok(linetext != NULL && !lstrcmpW(linetext, line_text),
1224            "IActiveScriptError_GetSourceLineText -- expected %s, got %s\n", wine_dbgstr_w(line_text), wine_dbgstr_w(linetext));
1225     } else {
1226         ok(hres == E_FAIL, "IActiveScriptError_GetSourceLineText -- hres: expected S_OK, got 0x%08x\n", hres);
1227         ok(linetext == NULL,
1228            "IActiveScriptError_GetSourceLineText -- expected NULL, got %s\n", wine_dbgstr_w(linetext));
1229     }
1230     SysFreeString(linetext);
1231
1232     /* IActiveScriptError_GetExceptionInfo */
1233
1234     hres = IActiveScriptError_GetExceptionInfo(error, NULL);
1235     ok(hres == E_POINTER, "IActiveScriptError_GetExceptionInfo -- hres: expected E_POINTER, got 0x%08x\n", hres);
1236
1237     excep.wCode = 0xdead;
1238     excep.wReserved = 0xdead;
1239     excep.bstrSource = (BSTR)0xdeadbeef;
1240     excep.bstrDescription = (BSTR)0xdeadbeef;
1241     excep.bstrHelpFile = (BSTR)0xdeadbeef;
1242     excep.dwHelpContext = 0xdeadbeef;
1243     excep.pvReserved = (void *)0xdeadbeef;
1244     excep.pfnDeferredFillIn = (void *)0xdeadbeef;
1245     excep.scode = 0xdeadbeef;
1246
1247     hres = IActiveScriptError_GetExceptionInfo(error, &excep);
1248     ok(hres == S_OK, "IActiveScriptError_GetExceptionInfo -- hres: expected S_OK, got 0x%08x\n", hres);
1249
1250     ok(excep.wCode == 0, "IActiveScriptError_GetExceptionInfo -- excep.wCode: expected 0, got 0x%08x\n", excep.wCode);
1251     ok(excep.wReserved == 0, "IActiveScriptError_GetExceptionInfo -- excep.wReserved: expected 0, got %d\n", excep.wReserved);
1252     if (!is_lang_english())
1253         skip("Non-english UI (test with hardcoded strings)\n");
1254     else {
1255         ok(excep.bstrSource != NULL && !lstrcmpW(excep.bstrSource, script_source),
1256            "IActiveScriptError_GetExceptionInfo -- excep.bstrSource is not valid: expected %s, got %s\n",
1257            wine_dbgstr_w(script_source), wine_dbgstr_w(excep.bstrSource));
1258         ok(excep.bstrDescription != NULL && !lstrcmpW(excep.bstrDescription, description),
1259            "IActiveScriptError_GetExceptionInfo -- excep.bstrDescription is not valid: got %s\n", wine_dbgstr_w(excep.bstrDescription));
1260     }
1261     ok(excep.bstrHelpFile == NULL,
1262        "IActiveScriptError_GetExceptionInfo -- excep.bstrHelpFile: expected NULL, got %s\n", wine_dbgstr_w(excep.bstrHelpFile));
1263     ok(excep.dwHelpContext == 0, "IActiveScriptError_GetExceptionInfo -- excep.dwHelpContext: expected 0, got %d\n", excep.dwHelpContext);
1264     ok(excep.pvReserved == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pvReserved: expected NULL, got %p\n", excep.pvReserved);
1265     ok(excep.pfnDeferredFillIn == NULL, "IActiveScriptError_GetExceptionInfo -- excep.pfnDeferredFillIn: expected NULL, got %p\n", excep.pfnDeferredFillIn);
1266     ok(excep.scode == errorcode, "IActiveScriptError_GetExceptionInfo -- excep.scode: expected 0x%08x, got 0x%08x\n", errorcode, excep.scode);
1267
1268     SysFreeString(excep.bstrSource);
1269     SysFreeString(excep.bstrDescription);
1270     SysFreeString(excep.bstrHelpFile);
1271 }
1272
1273 static void parse_script_with_error(DWORD flags, BSTR script_str, SCODE errorcode, ULONG line, LONG pos, BSTR script_source, BSTR description, BSTR line_text)
1274 {
1275     IActiveScriptParse *parser;
1276     IActiveScript *engine;
1277     HRESULT hres;
1278
1279     engine = create_script();
1280     if(!engine)
1281         return;
1282
1283     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1284     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1285     if (FAILED(hres))
1286     {
1287         IActiveScript_Release(engine);
1288         return;
1289     }
1290
1291     hres = IActiveScriptParse64_InitNew(parser);
1292     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1293
1294     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite_CheckError);
1295     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1296
1297     hres = IActiveScript_AddNamedItem(engine, testW,
1298             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
1299     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1300
1301     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1302     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1303
1304     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
1305     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
1306     ok(script_disp != NULL, "script_disp == NULL\n");
1307     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
1308
1309     script_error = NULL;
1310     SET_EXPECT(ActiveScriptSite_OnScriptError);
1311     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1312     todo_wine ok(hres == 0x80020101, "parse_script_with_error should have returned 0x80020101, got: 0x%08x\n", hres);
1313     todo_wine CHECK_CALLED(ActiveScriptSite_OnScriptError);
1314
1315     if (script_error)
1316     {
1317         test_IActiveScriptError(script_error, errorcode, line, pos, script_source, description, line_text);
1318
1319         IUnknown_Release(script_error);
1320     }
1321
1322     IDispatch_Release(script_disp);
1323     IActiveScript_Release(engine);
1324     IUnknown_Release(parser);
1325 }
1326
1327 static void parse_script_af(DWORD flags, const char *src)
1328 {
1329     BSTR tmp;
1330     HRESULT hres;
1331
1332     tmp = a2bstr(src);
1333     hres = parse_script(flags, tmp);
1334     SysFreeString(tmp);
1335     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1336 }
1337
1338 static void parse_script_a(const char *src)
1339 {
1340     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
1341 }
1342
1343 static void parse_script_with_error_a(const char *src, SCODE errorcode, ULONG line, LONG pos, LPCSTR source, LPCSTR desc, LPCSTR linetext)
1344 {
1345     BSTR tmp, script_source, description, line_text;
1346
1347     tmp = a2bstr(src);
1348     script_source = a2bstr(source);
1349     description = a2bstr(desc);
1350     line_text = a2bstr(linetext);
1351
1352     parse_script_with_error(SCRIPTITEM_GLOBALMEMBERS, tmp, errorcode, line, pos, script_source, description, line_text);
1353
1354     SysFreeString(line_text);
1355     SysFreeString(description);
1356     SysFreeString(script_source);
1357     SysFreeString(tmp);
1358 }
1359
1360 static HRESULT parse_htmlscript_a(const char *src)
1361 {
1362     HRESULT hres;
1363     BSTR tmp = a2bstr(src);
1364     hres = parse_htmlscript(tmp);
1365     SysFreeString(tmp);
1366
1367     return hres;
1368 }
1369
1370 static BSTR get_script_from_file(const char *filename)
1371 {
1372     DWORD size, len;
1373     HANDLE file, map;
1374     const char *file_map;
1375     BSTR ret;
1376
1377     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
1378     if(file == INVALID_HANDLE_VALUE) {
1379         trace("Could not open file: %u\n", GetLastError());
1380         return NULL;
1381     }
1382
1383     size = GetFileSize(file, NULL);
1384
1385     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
1386     CloseHandle(file);
1387     if(map == INVALID_HANDLE_VALUE) {
1388         trace("Could not create file mapping: %u\n", GetLastError());
1389         return NULL;
1390     }
1391
1392     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
1393     CloseHandle(map);
1394     if(!file_map) {
1395         trace("MapViewOfFile failed: %u\n", GetLastError());
1396         return NULL;
1397     }
1398
1399     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
1400     ret = SysAllocStringLen(NULL, len);
1401     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
1402
1403     UnmapViewOfFile(file_map);
1404
1405     return ret;
1406 }
1407
1408 static void run_from_file(const char *filename)
1409 {
1410     BSTR script_str;
1411     HRESULT hres;
1412
1413     script_str = get_script_from_file(filename);
1414     if(!script_str)
1415         return;
1416
1417     strict_dispid_check = FALSE;
1418     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
1419     SysFreeString(script_str);
1420     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1421 }
1422
1423 static void run_from_res(const char *name)
1424 {
1425     const char *data;
1426     DWORD size, len;
1427     BSTR str;
1428     HRSRC src;
1429     HRESULT hres;
1430
1431     strict_dispid_check = FALSE;
1432     test_name = name;
1433
1434     src = FindResourceA(NULL, name, (LPCSTR)40);
1435     ok(src != NULL, "Could not find resource %s\n", name);
1436
1437     size = SizeofResource(NULL, src);
1438     data = LoadResource(NULL, src);
1439
1440     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
1441     str = SysAllocStringLen(NULL, len);
1442     MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
1443
1444     SET_EXPECT(global_success_d);
1445     SET_EXPECT(global_success_i);
1446     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
1447     CHECK_CALLED(global_success_d);
1448     CHECK_CALLED(global_success_i);
1449
1450     ok(hres == S_OK, "parse_script failed: %08x\n", hres);
1451     SysFreeString(str);
1452 }
1453
1454 static void test_isvisible(BOOL global_members)
1455 {
1456     IActiveScriptParse *parser;
1457     IActiveScript *engine;
1458     HRESULT hres;
1459
1460     static const WCHAR script_textW[] =
1461         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
1462
1463     engine = create_script();
1464     if(!engine)
1465         return;
1466
1467     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
1468     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
1469     if (FAILED(hres))
1470     {
1471         IActiveScript_Release(engine);
1472         return;
1473     }
1474
1475     hres = IActiveScriptParse64_InitNew(parser);
1476     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
1477
1478     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
1479     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
1480
1481     if(global_members)
1482         SET_EXPECT(GetItemInfo_testVal);
1483     hres = IActiveScript_AddNamedItem(engine, test_valW,
1484             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
1485             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
1486     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
1487     if(global_members)
1488         CHECK_CALLED(GetItemInfo_testVal);
1489
1490     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
1491     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
1492
1493     if(!global_members)
1494         SET_EXPECT(GetItemInfo_testVal);
1495     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1496     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1497     if(!global_members)
1498         CHECK_CALLED(GetItemInfo_testVal);
1499
1500     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
1501     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1502
1503     IActiveScript_Release(engine);
1504     IUnknown_Release(parser);
1505 }
1506
1507 static BOOL run_tests(void)
1508 {
1509     HRESULT hres;
1510
1511     if(invoke_version) {
1512         IActiveScript *script;
1513
1514         script = create_script();
1515         if(!script) {
1516             win_skip("Could not create script\n");
1517             return FALSE;
1518         }
1519         IActiveScript_Release(script);
1520     }
1521
1522     strict_dispid_check = TRUE;
1523
1524     parse_script_a("");
1525     parse_script_a("/* empty */ ;");
1526
1527     SET_EXPECT(global_propget_d);
1528     SET_EXPECT(global_propget_i);
1529     parse_script_a("testPropGet;");
1530     CHECK_CALLED(global_propget_d);
1531     CHECK_CALLED(global_propget_i);
1532
1533     SET_EXPECT(global_propput_d);
1534     SET_EXPECT(global_propput_i);
1535     parse_script_a("testPropPut = 1;");
1536     CHECK_CALLED(global_propput_d);
1537     CHECK_CALLED(global_propput_i);
1538
1539     SET_EXPECT(global_success_d);
1540     SET_EXPECT(global_success_i);
1541     parse_script_a("reportSuccess();");
1542     CHECK_CALLED(global_success_d);
1543     CHECK_CALLED(global_success_i);
1544
1545     SET_EXPECT(testobj_delete);
1546     parse_script_a("delete testObj.deleteTest;");
1547     CHECK_CALLED(testobj_delete);
1548
1549     SET_EXPECT(global_propdelete_d);
1550     SET_EXPECT(DeleteMemberByDispID);
1551     parse_script_a("delete testPropDelete;");
1552     CHECK_CALLED(global_propdelete_d);
1553     CHECK_CALLED(DeleteMemberByDispID);
1554
1555     parse_script_a("(function reportSuccess() {})()");
1556
1557     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
1558
1559     parse_script_a("function reportSuccess() {}; reportSuccess();");
1560
1561     SET_EXPECT(global_propget_d);
1562     parse_script_a("var testPropGet");
1563     CHECK_CALLED(global_propget_d);
1564
1565     SET_EXPECT(global_propget_d);
1566     parse_script_a("eval('var testPropGet;');");
1567     CHECK_CALLED(global_propget_d);
1568
1569     SET_EXPECT(global_notexists_d);
1570     parse_script_a("var notExists; notExists = 1;");
1571     CHECK_CALLED(global_notexists_d);
1572
1573     parse_script_a("function f() { var testPropGet; }");
1574     parse_script_a("(function () { var testPropGet; })();");
1575     parse_script_a("(function () { eval('var testPropGet;'); })();");
1576
1577     SET_EXPECT(invoke_func);
1578     parse_script_a("ok(propGetFunc() == 0, \"Incorrect propGetFunc value\");");
1579     CHECK_CALLED(invoke_func);
1580     parse_script_a("ok(propGetFunc(1) == 1, \"Incorrect propGetFunc value\");");
1581     parse_script_a("ok(propGetFunc(1, 2) == 2, \"Incorrect propGetFunc value\");");
1582     SET_EXPECT(invoke_func);
1583     parse_script_a("ok(propGetFunc().toString() == 0, \"Incorrect propGetFunc value\");");
1584     CHECK_CALLED(invoke_func);
1585     parse_script_a("ok(propGetFunc(1).toString() == 1, \"Incorrect propGetFunc value\");");
1586     SET_EXPECT(invoke_func);
1587     parse_script_a("propGetFunc(1);");
1588     CHECK_CALLED(invoke_func);
1589
1590     parse_script_a("objectFlag(1).toString();");
1591
1592     parse_script_a("(function() { var tmp = (function () { return testObj; })()(1);})();");
1593     parse_script_a("(function() { var tmp = (function () { return testObj; })()();})();");
1594
1595     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
1596
1597     SET_EXPECT(testobj_prop_d);
1598     parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');");
1599     CHECK_CALLED(testobj_prop_d);
1600
1601     SET_EXPECT(testobj_noprop_d);
1602     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
1603     CHECK_CALLED(testobj_noprop_d);
1604
1605     SET_EXPECT(testobj_prop_d);
1606     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\\\"prop\\\") returned false');");
1607     CHECK_CALLED(testobj_prop_d);
1608
1609     SET_EXPECT(testobj_noprop_d);
1610     parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
1611     CHECK_CALLED(testobj_noprop_d);
1612
1613     SET_EXPECT(puredisp_prop_d);
1614     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\\\"noprop\\\") returned false');");
1615     CHECK_CALLED(puredisp_prop_d);
1616
1617     SET_EXPECT(puredisp_noprop_d);
1618     parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\\\"noprop\\\") returned true');");
1619     CHECK_CALLED(puredisp_noprop_d);
1620
1621     SET_EXPECT(testobj_value);
1622     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
1623     CHECK_CALLED(testobj_value);
1624
1625     SET_EXPECT(testobj_value);
1626     parse_script_a("ok(String.prototype.concat.call(testObj, ' OK') === '1 OK', 'wrong concat result');");
1627     CHECK_CALLED(testobj_value);
1628
1629     SET_EXPECT(global_propget_d);
1630     SET_EXPECT(global_propget_i);
1631     parse_script_a("this.testPropGet;");
1632     CHECK_CALLED(global_propget_d);
1633     CHECK_CALLED(global_propget_i);
1634
1635     SET_EXPECT(global_propget_d);
1636     SET_EXPECT(global_propget_i);
1637     parse_script_a("(function () { this.testPropGet; })();");
1638     CHECK_CALLED(global_propget_d);
1639     CHECK_CALLED(global_propget_i);
1640
1641     parse_script_a("testThis(this);");
1642     parse_script_a("(function () { testThis(this); })();");
1643
1644     SET_EXPECT(testobj_onlydispid_d);
1645     SET_EXPECT(testobj_onlydispid_i);
1646     parse_script_a("ok(typeof(testObj.onlyDispID) === 'unknown', 'unexpected typeof(testObj.onlyDispID)');");
1647     CHECK_CALLED(testobj_onlydispid_d);
1648     CHECK_CALLED(testobj_onlydispid_i);
1649
1650     SET_EXPECT(global_propargput_d);
1651     SET_EXPECT(global_propargput_i);
1652     parse_script_a("var t=0; propArgPutG(t++, t++) = t++;");
1653     CHECK_CALLED(global_propargput_d);
1654     CHECK_CALLED(global_propargput_i);
1655
1656     SET_EXPECT(global_propargput_d);
1657     SET_EXPECT(global_propargput_i);
1658     parse_script_a("var t=0; test.propArgPutO(t++, t++) = t++;");
1659     CHECK_CALLED(global_propargput_d);
1660     CHECK_CALLED(global_propargput_i);
1661
1662     run_from_res("lang.js");
1663     run_from_res("api.js");
1664     run_from_res("regexp.js");
1665     run_from_res("cc.js");
1666
1667     test_isvisible(FALSE);
1668     test_isvisible(TRUE);
1669
1670     parse_script_af(0, "test.testThis2(this);");
1671     parse_script_af(0, "(function () { test.testThis2(this); })();");
1672
1673     hres = parse_htmlscript_a("<!--");
1674     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1675     hres = parse_htmlscript_a("-->");
1676     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1677     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
1678     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1679     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
1680     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1681     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
1682     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1683     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
1684     ok(hres != S_OK, "ParseScriptText have not failed\n");
1685
1686     parse_script_with_error_a(
1687         "?",
1688         0x800a03ea, 0, 0,
1689         "Microsoft JScript compilation error",
1690         "Syntax error",
1691         "?");
1692
1693     parse_script_with_error_a(
1694         "var a=1;\nif(a\n-->0) a=5;\n",
1695         0x800a03ee, 2, 0,
1696         "Microsoft JScript compilation error",
1697         "Expected ')'",
1698         "-->0) a=5;");
1699
1700     parse_script_with_error_a(
1701         "new 3;",
1702         0x800a01bd, 0, 0,
1703         "Microsoft JScript runtime error",
1704         "Object doesn't support this action",
1705         NULL);
1706
1707     parse_script_with_error_a(
1708         "new null;",
1709         0x800a138f, 0, 0,
1710         "Microsoft JScript runtime error",
1711         "Object expected",
1712         NULL);
1713
1714     parse_script_with_error_a(
1715         "var a;\nnew null;",
1716         0x800a138f, 1, 0,
1717         "Microsoft JScript runtime error",
1718         "Object expected",
1719         NULL);
1720
1721     parse_script_with_error_a(
1722         "var a; new null;",
1723         0x800a138f, 0, 7,
1724         "Microsoft JScript runtime error",
1725         "Object expected",
1726         NULL);
1727
1728     return TRUE;
1729 }
1730
1731 static void run_encoded_tests(void)
1732 {
1733     BSTR src;
1734     HRESULT hres;
1735
1736     engine_clsid = &CLSID_JScriptEncode;
1737
1738     SET_EXPECT(global_success_d);
1739     SET_EXPECT(global_success_i);
1740     /*             |reportSuccess();                           | */
1741     parse_script_a("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1742     CHECK_CALLED(global_success_d);
1743     CHECK_CALLED(global_success_i);
1744
1745     SET_EXPECT(global_success_d);
1746     SET_EXPECT(global_success_i);
1747     parse_script_a("reportSuccess();");
1748     CHECK_CALLED(global_success_d);
1749     CHECK_CALLED(global_success_i);
1750
1751     SET_EXPECT(global_success_d);
1752     SET_EXPECT(global_success_i);
1753     /*                   |Success                         | */
1754     parse_script_a("report#@~^BwAAAA==j!m^\x7f/k2QIAAA==^#~@();");
1755     CHECK_CALLED(global_success_d);
1756     CHECK_CALLED(global_success_i);
1757
1758     SET_EXPECT(global_success_d);
1759     SET_EXPECT(global_success_i);
1760     /*             |\r\n\treportSuccess();\r\n                        | */
1761     parse_script_a("#@~^GQAAAA==@#@&d.\x7fwKDYUE1^+k/c#p@#@&OAYAAA==^#~@");
1762     CHECK_CALLED(global_success_d);
1763     CHECK_CALLED(global_success_i);
1764
1765     /*                   v                                   */
1766     src = a2bstr("#@~^EAA*AA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1767     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1768     SysFreeString(src);
1769     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1770
1771     /*                      vv                                 */
1772     src = a2bstr("#@~^EAAAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1773     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1774     SysFreeString(src);
1775     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1776
1777     /*                      v                                */
1778     src = a2bstr("#@~^EAAAAA^=.\x7fwGMYUEm1+kd`*iAQYAAA==^#~@");
1779     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1780     SysFreeString(src);
1781     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1782
1783     /*                                     v                 */
1784     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1ekd`*iAQYAAA==^#~@");
1785     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1786     SysFreeString(src);
1787     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1788
1789     /*                                                    vv  */
1790     src = a2bstr("#@~^EAAAAA==.\x7fwGMYUEm1+kd`*iAQYAAA==^~#@");
1791     hres = parse_script(SCRIPTITEM_GLOBALMEMBERS, src);
1792     SysFreeString(src);
1793     ok(hres == JS_E_INVALID_CHAR, "parse_script failed %08x\n", hres);
1794 }
1795
1796 static BOOL check_jscript(void)
1797 {
1798     IActiveScriptProperty *script_prop;
1799     BSTR str;
1800     HRESULT hres;
1801
1802     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1803             &IID_IActiveScriptProperty, (void**)&script_prop);
1804     if(FAILED(hres))
1805         return FALSE;
1806     IActiveScriptProperty_Release(script_prop);
1807
1808     str = a2bstr("if(!('localeCompare' in String.prototype)) throw 1;");
1809     hres = parse_script(0, str);
1810     SysFreeString(str);
1811
1812     return hres == S_OK;
1813 }
1814
1815 START_TEST(run)
1816 {
1817     int argc;
1818     char **argv;
1819
1820     argc = winetest_get_mainargs(&argv);
1821
1822     CoInitialize(NULL);
1823
1824     if(!check_jscript()) {
1825         win_skip("Broken engine, probably too old\n");
1826     }else if(argc > 2) {
1827         invoke_version = 2;
1828         run_from_file(argv[2]);
1829     }else {
1830         trace("invoke version 0\n");
1831         invoke_version = 0;
1832         run_tests();
1833
1834         trace("invoke version 2\n");
1835         invoke_version = 2;
1836         if(run_tests()) {
1837             trace("JSctipt.Encode tests...\n");
1838             run_encoded_tests();
1839         }
1840     }
1841
1842     CoUninitialize();
1843 }