jscript: Moved resetting lastIndex to do_regexp_match_next.
[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
33 #define DEFINE_EXPECT(func) \
34     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35
36 #define SET_EXPECT(func) \
37     expect_ ## func = TRUE
38
39 #define SET_CALLED(func) \
40     called_ ## func = TRUE
41
42 #define CHECK_EXPECT2(func) \
43     do { \
44         ok(expect_ ##func, "unexpected call " #func "\n"); \
45         called_ ## func = TRUE; \
46     }while(0)
47
48 #define CHECK_EXPECT(func) \
49     do { \
50         CHECK_EXPECT2(func); \
51         expect_ ## func = FALSE; \
52     }while(0)
53
54 #define CHECK_CALLED(func) \
55     do { \
56         ok(called_ ## func, "expected " #func "\n"); \
57         expect_ ## func = called_ ## func = FALSE; \
58     }while(0)
59
60 DEFINE_EXPECT(global_propget_d);
61 DEFINE_EXPECT(global_propget_i);
62 DEFINE_EXPECT(global_propput_d);
63 DEFINE_EXPECT(global_propput_i);
64 DEFINE_EXPECT(global_success_d);
65 DEFINE_EXPECT(global_success_i);
66 DEFINE_EXPECT(global_notexists_d);
67 DEFINE_EXPECT(testobj_delete);
68 DEFINE_EXPECT(testobj_value);
69 DEFINE_EXPECT(testobj_prop_d);
70 DEFINE_EXPECT(testobj_noprop_d);
71 DEFINE_EXPECT(GetItemInfo_testVal);
72
73 #define DISPID_GLOBAL_TESTPROPGET   0x1000
74 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
75 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
76 #define DISPID_GLOBAL_TRACE         0x1003
77 #define DISPID_GLOBAL_OK            0x1004
78 #define DISPID_GLOBAL_GETVT         0x1005
79 #define DISPID_GLOBAL_TESTOBJ       0x1006
80 #define DISPID_GLOBAL_NULL_BSTR     0x1007
81 #define DISPID_GLOBAL_NULL_DISP     0x1008
82 #define DISPID_GLOBAL_TESTTHIS      0x1009
83 #define DISPID_GLOBAL_TESTTHIS2     0x100a
84 #define DISPID_GLOBAL_INVOKEVERSION 0x100b
85
86 #define DISPID_TESTOBJ_PROP         0x2000
87
88 static const WCHAR testW[] = {'t','e','s','t',0};
89 static const CHAR testA[] = "test";
90 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
91 static const CHAR test_valA[] = "testVal";
92
93 static BOOL strict_dispid_check;
94 static const char *test_name = "(null)";
95 static IDispatch *script_disp;
96 static int invoke_version;
97
98 static BSTR a2bstr(const char *str)
99 {
100     BSTR ret;
101     int len;
102
103     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
104     ret = SysAllocStringLen(NULL, len-1);
105     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
106
107     return ret;
108 }
109
110 static int strcmp_wa(LPCWSTR strw, const char *stra)
111 {
112     CHAR buf[512];
113     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
114     return lstrcmpA(buf, stra);
115 }
116
117 #define test_grfdex(a,b) _test_grfdex(__LINE__,a,b)
118 static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
119 {
120     expect |= invoke_version << 28;
121     ok_(__FILE__,line)(grfdex == expect, "grfdex = %x, expected %x\n", grfdex, expect);
122 }
123
124 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
125 {
126     *ppv = NULL;
127
128     if(IsEqualGUID(riid, &IID_IUnknown)
129        || IsEqualGUID(riid, &IID_IDispatch)
130        || IsEqualGUID(riid, &IID_IDispatchEx))
131         *ppv = iface;
132     else
133         return E_NOINTERFACE;
134
135     return S_OK;
136 }
137
138 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
139 {
140     return 2;
141 }
142
143 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
144 {
145     return 1;
146 }
147
148 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
149 {
150     ok(0, "unexpected call\n");
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
155                                               LCID lcid, ITypeInfo **ppTInfo)
156 {
157     ok(0, "unexpected call\n");
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
162                                                 LPOLESTR *rgszNames, UINT cNames,
163                                                 LCID lcid, DISPID *rgDispId)
164 {
165     ok(0, "unexpected call\n");
166     return E_NOTIMPL;
167 }
168
169 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
170                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
171                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
172 {
173     ok(0, "unexpected call\n");
174     return E_NOTIMPL;
175 }
176
177 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
178 {
179     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
180     return E_NOTIMPL;
181 }
182
183 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
184 {
185     ok(0, "unexpected call\n");
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
190 {
191     ok(0, "unexpected call\n");
192     return E_NOTIMPL;
193 }
194
195 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
196 {
197     ok(0, "unexpected call\n");
198     return E_NOTIMPL;
199 }
200
201 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
202 {
203     ok(0, "unexpected call\n");
204     return E_NOTIMPL;
205 }
206
207 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
208 {
209     ok(0, "unexpected call\n");
210     return E_NOTIMPL;
211 }
212
213 static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
214 {
215     if(!strcmp_wa(bstrName, "prop")) {
216         CHECK_EXPECT(testobj_prop_d);
217         test_grfdex(grfdex, fdexNameCaseSensitive);
218         *pid = DISPID_TESTOBJ_PROP;
219         return S_OK;
220     }
221     if(!strcmp_wa(bstrName, "noprop")) {
222         CHECK_EXPECT(testobj_noprop_d);
223         test_grfdex(grfdex, fdexNameCaseSensitive);
224         return DISP_E_UNKNOWNNAME;
225     }
226
227     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
232         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
233 {
234     switch(id) {
235     case DISPID_VALUE:
236         CHECK_EXPECT(testobj_value);
237
238         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
239         ok(pdp != NULL, "pdp == NULL\n");
240         ok(!pdp->rgvarg, "rgvarg != NULL\n");
241         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
242         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
243         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
244         ok(pvarRes != NULL, "pvarRes == NULL\n");
245         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
246         ok(pei != NULL, "pei == NULL\n");
247
248         V_VT(pvarRes) = VT_I4;
249         V_I4(pvarRes) = 1;
250         return S_OK;
251     }
252
253     ok(0, "unexpected call %x\n", id);
254     return DISP_E_MEMBERNOTFOUND;
255 }
256
257 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
258 {
259     CHECK_EXPECT(testobj_delete);
260
261     ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", wine_dbgstr_w(bstrName));
262     test_grfdex(grfdex, fdexNameCaseSensitive);
263     return S_OK;
264 }
265
266 static IDispatchExVtbl testObjVtbl = {
267     DispatchEx_QueryInterface,
268     DispatchEx_AddRef,
269     DispatchEx_Release,
270     DispatchEx_GetTypeInfoCount,
271     DispatchEx_GetTypeInfo,
272     DispatchEx_GetIDsOfNames,
273     DispatchEx_Invoke,
274     testObj_GetDispID,
275     testObj_InvokeEx,
276     testObj_DeleteMemberByName,
277     DispatchEx_DeleteMemberByDispID,
278     DispatchEx_GetMemberProperties,
279     DispatchEx_GetMemberName,
280     DispatchEx_GetNextDispID,
281     DispatchEx_GetNameSpaceParent
282 };
283
284 static IDispatchEx testObj = { &testObjVtbl };
285
286 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
287 {
288     if(!strcmp_wa(bstrName, "ok")) {
289         test_grfdex(grfdex, fdexNameCaseSensitive);
290         *pid = DISPID_GLOBAL_OK;
291         return S_OK;
292     }
293     if(!strcmp_wa(bstrName, "trace")) {
294         test_grfdex(grfdex, fdexNameCaseSensitive);
295         *pid = DISPID_GLOBAL_TRACE;
296         return S_OK;
297     }
298     if(!strcmp_wa(bstrName, "reportSuccess")) {
299         CHECK_EXPECT(global_success_d);
300         test_grfdex(grfdex, fdexNameCaseSensitive);
301         *pid = DISPID_GLOBAL_REPORTSUCCESS;
302         return S_OK;
303     }
304     if(!strcmp_wa(bstrName, "testPropGet")) {
305         CHECK_EXPECT(global_propget_d);
306         test_grfdex(grfdex, fdexNameCaseSensitive);
307         *pid = DISPID_GLOBAL_TESTPROPGET;
308         return S_OK;
309     }
310     if(!strcmp_wa(bstrName, "testPropPut")) {
311         CHECK_EXPECT(global_propput_d);
312         test_grfdex(grfdex, fdexNameCaseSensitive);
313         *pid = DISPID_GLOBAL_TESTPROPPUT;
314         return S_OK;
315     }
316     if(!strcmp_wa(bstrName, "getVT")) {
317         test_grfdex(grfdex, fdexNameCaseSensitive);
318         *pid = DISPID_GLOBAL_GETVT;
319         return S_OK;
320     }
321     if(!strcmp_wa(bstrName, "testObj")) {
322         test_grfdex(grfdex, fdexNameCaseSensitive);
323         *pid = DISPID_GLOBAL_TESTOBJ;
324         return S_OK;
325     }
326     if(!strcmp_wa(bstrName, "createNullBSTR")) {
327         *pid = DISPID_GLOBAL_NULL_BSTR;
328         return S_OK;
329     }
330     if(!strcmp_wa(bstrName, "nullDisp")) {
331         *pid = DISPID_GLOBAL_NULL_DISP;
332         return S_OK;
333     }
334     if(!strcmp_wa(bstrName, "notExists")) {
335         CHECK_EXPECT(global_notexists_d);
336         test_grfdex(grfdex, fdexNameCaseSensitive);
337         return DISP_E_UNKNOWNNAME;
338     }
339
340     if(!strcmp_wa(bstrName, "testThis")) {
341         test_grfdex(grfdex, fdexNameCaseSensitive);
342         *pid = DISPID_GLOBAL_TESTTHIS;
343         return S_OK;
344     }
345
346     if(!strcmp_wa(bstrName, "testThis2")) {
347         test_grfdex(grfdex, fdexNameCaseSensitive);
348         *pid = DISPID_GLOBAL_TESTTHIS2;
349         return S_OK;
350     }
351
352     if(!strcmp_wa(bstrName, "invokeVersion")) {
353         test_grfdex(grfdex, fdexNameCaseSensitive);
354         *pid = DISPID_GLOBAL_INVOKEVERSION;
355         return S_OK;
356     }
357
358     if(strict_dispid_check)
359         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
360     return DISP_E_UNKNOWNNAME;
361 }
362
363 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
364         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
365 {
366     switch(id) {
367     case DISPID_GLOBAL_OK:
368         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
369         ok(pdp != NULL, "pdp == NULL\n");
370         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
371         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
372         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
373         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
374         if(wFlags & INVOKE_PROPERTYGET)
375             ok(pvarRes != NULL, "pvarRes == NULL\n");
376         else
377             ok(!pvarRes, "pvarRes != NULL\n");
378         ok(pei != NULL, "pei == NULL\n");
379
380         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
381         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
382         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
383
384         return S_OK;
385
386      case DISPID_GLOBAL_TRACE:
387         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
388         ok(pdp != NULL, "pdp == NULL\n");
389         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
390         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
391         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
392         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
393         ok(!pvarRes, "pvarRes != NULL\n");
394         ok(pei != NULL, "pei == NULL\n");
395
396         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
397         if(V_VT(pdp->rgvarg) == VT_BSTR)
398             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
399
400         return S_OK;
401
402     case DISPID_GLOBAL_REPORTSUCCESS:
403         CHECK_EXPECT(global_success_i);
404
405         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
406         ok(pdp != NULL, "pdp == NULL\n");
407         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
408         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
409         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
410         ok(!pvarRes, "pvarRes != NULL\n");
411         ok(pei != NULL, "pei == NULL\n");
412
413         return S_OK;
414
415      case DISPID_GLOBAL_TESTPROPGET:
416         CHECK_EXPECT(global_propget_i);
417
418         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
419         ok(pdp != NULL, "pdp == NULL\n");
420         ok(!pdp->rgvarg, "rgvarg != NULL\n");
421         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
422         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
423         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
424         ok(pvarRes != NULL, "pvarRes == NULL\n");
425         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
426         ok(pei != NULL, "pei == NULL\n");
427
428         V_VT(pvarRes) = VT_I4;
429         V_I4(pvarRes) = 1;
430
431         return S_OK;
432
433     case DISPID_GLOBAL_TESTPROPPUT:
434         CHECK_EXPECT(global_propput_i);
435
436         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
437         ok(pdp != NULL, "pdp == NULL\n");
438         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
439         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
440         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
441         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
442         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
443         ok(!pvarRes, "pvarRes != NULL\n");
444
445         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
446         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
447         return S_OK;
448
449      case DISPID_GLOBAL_GETVT:
450         ok(pdp != NULL, "pdp == NULL\n");
451         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
452         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
453         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
454         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
455         ok(pvarRes != NULL, "pvarRes == NULL\n");
456         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
457         ok(pei != NULL, "pei == NULL\n");
458
459         V_VT(pvarRes) = VT_BSTR;
460         switch(V_VT(pdp->rgvarg)) {
461         case VT_EMPTY:
462             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
463             break;
464         case VT_NULL:
465             V_BSTR(pvarRes) = a2bstr("VT_NULL");
466             break;
467         case VT_I4:
468             V_BSTR(pvarRes) = a2bstr("VT_I4");
469             break;
470         case VT_R8:
471             V_BSTR(pvarRes) = a2bstr("VT_R8");
472             break;
473         case VT_BSTR:
474             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
475             break;
476         case VT_DISPATCH:
477             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
478             break;
479         case VT_BOOL:
480             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
481             break;
482         default:
483             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
484             return E_FAIL;
485         }
486
487         return S_OK;
488
489     case DISPID_GLOBAL_TESTOBJ:
490         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
491         ok(pdp != NULL, "pdp == NULL\n");
492         ok(!pdp->rgvarg, "rgvarg != NULL\n");
493         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
494         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
495         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
496         ok(pvarRes != NULL, "pvarRes == NULL\n");
497         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
498         ok(pei != NULL, "pei == NULL\n");
499
500         V_VT(pvarRes) = VT_DISPATCH;
501         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
502         return S_OK;
503
504     case DISPID_GLOBAL_NULL_BSTR:
505         if(pvarRes) {
506             V_VT(pvarRes) = VT_BSTR;
507             V_BSTR(pvarRes) = NULL;
508         }
509         return S_OK;
510
511     case DISPID_GLOBAL_NULL_DISP:
512         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
513         ok(pdp != NULL, "pdp == NULL\n");
514         ok(!pdp->rgvarg, "rgvarg != NULL\n");
515         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
516         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
517         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
518         ok(pvarRes != NULL, "pvarRes == NULL\n");
519         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
520         ok(pei != NULL, "pei == NULL\n");
521
522         V_VT(pvarRes) = VT_DISPATCH;
523         V_DISPATCH(pvarRes) = NULL;
524         return S_OK;
525
526     case DISPID_GLOBAL_TESTTHIS:
527         ok(pdp != NULL, "pdp == NULL\n");
528         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
529         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
530         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
531         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
532         ok(pvarRes == NULL, "pvarRes != NULL\n");
533         ok(pei != NULL, "pei == NULL\n");
534
535         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
536         ok(V_DISPATCH(pdp->rgvarg) == (IDispatch*)iface, "disp != iface\n");
537
538         return S_OK;
539
540     case DISPID_GLOBAL_TESTTHIS2:
541         ok(pdp != NULL, "pdp == NULL\n");
542         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
543         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
544         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
545         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
546         ok(pvarRes == NULL, "pvarRes != NULL\n");
547         ok(pei != NULL, "pei == NULL\n");
548
549         ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(pdp->rgvarg));
550         ok(V_DISPATCH(pdp->rgvarg) != (IDispatch*)iface, "disp == iface\n");
551         ok(V_DISPATCH(pdp->rgvarg) == script_disp, "disp != script_disp\n");
552
553         return S_OK;
554
555      case DISPID_GLOBAL_INVOKEVERSION:
556         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
557         ok(pdp != NULL, "pdp == NULL\n");
558         ok(!pdp->rgvarg, "rgvarg != NULL\n");
559         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
560         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
561         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
562         ok(pvarRes != NULL, "pvarRes == NULL\n");
563         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
564         ok(pei != NULL, "pei == NULL\n");
565
566         V_VT(pvarRes) = VT_I4;
567         V_I4(pvarRes) = invoke_version;
568
569         return S_OK;
570
571     }
572
573     ok(0, "unexpected call %x\n", id);
574     return DISP_E_MEMBERNOTFOUND;
575 }
576
577 static IDispatchExVtbl GlobalVtbl = {
578     DispatchEx_QueryInterface,
579     DispatchEx_AddRef,
580     DispatchEx_Release,
581     DispatchEx_GetTypeInfoCount,
582     DispatchEx_GetTypeInfo,
583     DispatchEx_GetIDsOfNames,
584     DispatchEx_Invoke,
585     Global_GetDispID,
586     Global_InvokeEx,
587     DispatchEx_DeleteMemberByName,
588     DispatchEx_DeleteMemberByDispID,
589     DispatchEx_GetMemberProperties,
590     DispatchEx_GetMemberName,
591     DispatchEx_GetNextDispID,
592     DispatchEx_GetNameSpaceParent
593 };
594
595 static IDispatchEx Global = { &GlobalVtbl };
596
597 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
598 {
599     *ppv = NULL;
600
601     if(IsEqualGUID(&IID_IUnknown, riid))
602         *ppv = iface;
603     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
604         *ppv = iface;
605     else
606         return E_NOINTERFACE;
607
608     IUnknown_AddRef((IUnknown*)*ppv);
609     return S_OK;
610 }
611
612 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
613 {
614     return 2;
615 }
616
617 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
618 {
619     return 1;
620 }
621
622 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
623 {
624     *plcid = GetUserDefaultLCID();
625     return S_OK;
626 }
627
628 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
629         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
630 {
631     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
632     ok(!ppti, "ppti != NULL\n");
633
634     if(!strcmp_wa(pstrName, test_valA))
635         CHECK_EXPECT(GetItemInfo_testVal);
636     else if(strcmp_wa(pstrName, testA))
637         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
638
639     *ppiunkItem = (IUnknown*)&Global;
640     return S_OK;
641 }
642
643 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
644 {
645     return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
649         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
650 {
651     return E_NOTIMPL;
652 }
653
654 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
655 {
656     return E_NOTIMPL;
657 }
658
659 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
660 {
661     return E_NOTIMPL;
662 }
663
664 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
665 {
666     return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
670 {
671     return E_NOTIMPL;
672 }
673
674 #undef ACTSCPSITE_THIS
675
676 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
677     ActiveScriptSite_QueryInterface,
678     ActiveScriptSite_AddRef,
679     ActiveScriptSite_Release,
680     ActiveScriptSite_GetLCID,
681     ActiveScriptSite_GetItemInfo,
682     ActiveScriptSite_GetDocVersionString,
683     ActiveScriptSite_OnScriptTerminate,
684     ActiveScriptSite_OnStateChange,
685     ActiveScriptSite_OnScriptError,
686     ActiveScriptSite_OnEnterScript,
687     ActiveScriptSite_OnLeaveScript
688 };
689
690 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
691
692 static HRESULT set_script_prop(IActiveScript *engine, DWORD property, VARIANT *val)
693 {
694     IActiveScriptProperty *script_prop;
695     HRESULT hres;
696
697     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptProperty,
698             (void**)&script_prop);
699     ok(hres == S_OK, "Could not get IActiveScriptProperty iface: %08x\n", hres);
700
701     hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val);
702     IActiveScriptProperty_Release(script_prop);
703
704     return hres;
705 }
706
707 static IActiveScript *create_script(void)
708 {
709     IActiveScript *script;
710     VARIANT v;
711     HRESULT hres;
712
713     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
714             &IID_IActiveScript, (void**)&script);
715     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
716
717     V_VT(&v) = VT_I4;
718     V_I4(&v) = invoke_version;
719     hres = set_script_prop(script, SCRIPTPROP_INVOKEVERSIONING, &v);
720     ok(hres == S_OK || broken(hres == E_NOTIMPL), "SetProperty(SCRIPTPROP_INVOKEVERSIONING) failed: %08x\n", hres);
721     if(invoke_version && FAILED(hres)) {
722         IActiveScript_Release(script);
723         return NULL;
724     }
725
726     return script;
727 }
728
729 static void parse_script(DWORD flags, BSTR script_str)
730 {
731     IActiveScriptParse *parser;
732     IActiveScript *engine;
733     HRESULT hres;
734
735     engine = create_script();
736     if(!engine)
737         return;
738
739     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
740     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
741     if (FAILED(hres))
742     {
743         IActiveScript_Release(engine);
744         return;
745     }
746
747     hres = IActiveScriptParse64_InitNew(parser);
748     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
749
750     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
751     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
752
753     hres = IActiveScript_AddNamedItem(engine, testW,
754             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|flags);
755     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
756
757     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
758     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
759
760     hres = IActiveScript_GetScriptDispatch(engine, NULL, &script_disp);
761     ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
762     ok(script_disp != NULL, "script_disp == NULL\n");
763     ok(script_disp != (IDispatch*)&Global, "script_disp == Global\n");
764
765     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
766     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
767
768     IDispatch_Release(script_disp);
769     IActiveScript_Release(engine);
770     IUnknown_Release(parser);
771 }
772
773 static HRESULT parse_htmlscript(BSTR script_str)
774 {
775     IActiveScriptParse *parser;
776     IActiveScript *engine;
777     HRESULT hres;
778     BSTR tmp = a2bstr("</SCRIPT>");
779
780     engine = create_script();
781     if(!engine)
782         return E_FAIL;
783
784     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
785     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
786     if (FAILED(hres))
787     {
788         IActiveScript_Release(engine);
789         return E_FAIL;
790     }
791
792     hres = IActiveScriptParse64_InitNew(parser);
793     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
794
795     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
796     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
797
798     hres = IActiveScript_AddNamedItem(engine, testW,
799             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
800     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
801
802     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
803     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
804
805     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
806
807     IActiveScript_Release(engine);
808     IUnknown_Release(parser);
809     SysFreeString(tmp);
810
811     return hres;
812 }
813
814 static void parse_script_af(DWORD flags, const char *src)
815 {
816     BSTR tmp = a2bstr(src);
817     parse_script(flags, tmp);
818     SysFreeString(tmp);
819 }
820
821 static void parse_script_a(const char *src)
822 {
823     parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
824 }
825
826 static HRESULT parse_htmlscript_a(const char *src)
827 {
828     HRESULT hres;
829     BSTR tmp = a2bstr(src);
830     hres = parse_htmlscript(tmp);
831     SysFreeString(tmp);
832
833     return hres;
834 }
835
836 static BSTR get_script_from_file(const char *filename)
837 {
838     DWORD size, len;
839     HANDLE file, map;
840     const char *file_map;
841     BSTR ret;
842
843     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
844     if(file == INVALID_HANDLE_VALUE) {
845         trace("Could not open file: %u\n", GetLastError());
846         return NULL;
847     }
848
849     size = GetFileSize(file, NULL);
850
851     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
852     CloseHandle(file);
853     if(map == INVALID_HANDLE_VALUE) {
854         trace("Could not create file mapping: %u\n", GetLastError());
855         return NULL;
856     }
857
858     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
859     CloseHandle(map);
860     if(!file_map) {
861         trace("MapViewOfFile failed: %u\n", GetLastError());
862         return NULL;
863     }
864
865     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
866     ret = SysAllocStringLen(NULL, len);
867     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
868
869     UnmapViewOfFile(file_map);
870
871     return ret;
872 }
873
874 static void run_from_file(const char *filename)
875 {
876     BSTR script_str = get_script_from_file(filename);
877
878     strict_dispid_check = FALSE;
879
880     if(script_str)
881         parse_script(SCRIPTITEM_GLOBALMEMBERS, script_str);
882
883     SysFreeString(script_str);
884 }
885
886 static void run_from_res(const char *name)
887 {
888     const char *data;
889     DWORD size, len;
890     BSTR str;
891     HRSRC src;
892
893     strict_dispid_check = FALSE;
894     test_name = name;
895
896     src = FindResourceA(NULL, name, (LPCSTR)40);
897     ok(src != NULL, "Could not find resource %s\n", name);
898
899     size = SizeofResource(NULL, src);
900     data = LoadResource(NULL, src);
901
902     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
903     str = SysAllocStringLen(NULL, len);
904     len = MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
905
906     SET_EXPECT(global_success_d);
907     SET_EXPECT(global_success_i);
908     parse_script(SCRIPTITEM_GLOBALMEMBERS, str);
909     CHECK_CALLED(global_success_d);
910     CHECK_CALLED(global_success_i);
911
912     SysFreeString(str);
913 }
914
915 static void test_isvisible(BOOL global_members)
916 {
917     IActiveScriptParse *parser;
918     IActiveScript *engine;
919     HRESULT hres;
920
921     static const WCHAR script_textW[] =
922         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
923
924     engine = create_script();
925     if(!engine)
926         return;
927
928     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
929     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
930     if (FAILED(hres))
931     {
932         IActiveScript_Release(engine);
933         return;
934     }
935
936     hres = IActiveScriptParse64_InitNew(parser);
937     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
938
939     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
940     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
941
942     if(global_members)
943         SET_EXPECT(GetItemInfo_testVal);
944     hres = IActiveScript_AddNamedItem(engine, test_valW,
945             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
946             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
947     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
948     if(global_members)
949         CHECK_CALLED(GetItemInfo_testVal);
950
951     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
952     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
953
954     if(!global_members)
955         SET_EXPECT(GetItemInfo_testVal);
956     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
957     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
958     if(!global_members)
959         CHECK_CALLED(GetItemInfo_testVal);
960
961     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
962     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
963
964     IActiveScript_Release(engine);
965     IUnknown_Release(parser);
966 }
967
968 static void run_tests(void)
969 {
970     HRESULT hres;
971
972     if(invoke_version) {
973         IActiveScript *script;
974
975         script = create_script();
976         if(!script) {
977             win_skip("Could not create script\n");
978             return;
979         }
980         IActiveScript_Release(script);
981     }
982
983     strict_dispid_check = TRUE;
984
985     parse_script_a("");
986     parse_script_a("/* empty */ ;");
987
988     SET_EXPECT(global_propget_d);
989     SET_EXPECT(global_propget_i);
990     parse_script_a("testPropGet;");
991     CHECK_CALLED(global_propget_d);
992     CHECK_CALLED(global_propget_i);
993
994     SET_EXPECT(global_propput_d);
995     SET_EXPECT(global_propput_i);
996     parse_script_a("testPropPut = 1;");
997     CHECK_CALLED(global_propput_d);
998     CHECK_CALLED(global_propput_i);
999
1000     SET_EXPECT(global_success_d);
1001     SET_EXPECT(global_success_i);
1002     parse_script_a("reportSuccess();");
1003     CHECK_CALLED(global_success_d);
1004     CHECK_CALLED(global_success_i);
1005
1006     SET_EXPECT(testobj_delete);
1007     parse_script_a("delete testObj.deleteTest;");
1008     CHECK_CALLED(testobj_delete);
1009
1010     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
1011
1012     parse_script_a("function reportSuccess() {}; reportSuccess();");
1013
1014     SET_EXPECT(global_propget_d);
1015     parse_script_a("var testPropGet");
1016     CHECK_CALLED(global_propget_d);
1017
1018     SET_EXPECT(global_notexists_d);
1019     parse_script_a("var notExists; notExists = 1;");
1020     CHECK_CALLED(global_notexists_d);
1021
1022     parse_script_a("function f() { var testPropGet; }");
1023
1024     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
1025
1026     SET_EXPECT(testobj_prop_d);
1027     parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');");
1028     CHECK_CALLED(testobj_prop_d);
1029
1030     SET_EXPECT(testobj_noprop_d);
1031     parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');");
1032     CHECK_CALLED(testobj_noprop_d);
1033
1034     SET_EXPECT(testobj_value);
1035     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
1036     CHECK_CALLED(testobj_value);
1037
1038     SET_EXPECT(testobj_value);
1039     parse_script_a("ok(String.prototype.concat.call(testObj, ' OK') === '1 OK', 'wrong concat result');");
1040     CHECK_CALLED(testobj_value);
1041
1042     SET_EXPECT(global_propget_d);
1043     SET_EXPECT(global_propget_i);
1044     parse_script_a("this.testPropGet;");
1045     CHECK_CALLED(global_propget_d);
1046     CHECK_CALLED(global_propget_i);
1047
1048     SET_EXPECT(global_propget_d);
1049     SET_EXPECT(global_propget_i);
1050     parse_script_a("(function () { this.testPropGet; })();");
1051     CHECK_CALLED(global_propget_d);
1052     CHECK_CALLED(global_propget_i);
1053
1054     parse_script_a("testThis(this);");
1055     parse_script_a("(function () { testThis(this); })();");
1056
1057     run_from_res("lang.js");
1058     run_from_res("api.js");
1059     run_from_res("regexp.js");
1060
1061     test_isvisible(FALSE);
1062     test_isvisible(TRUE);
1063
1064     parse_script_af(0, "test.testThis2(this);");
1065     parse_script_af(0, "(function () { test.testThis2(this); })();");
1066
1067     hres = parse_htmlscript_a("<!--");
1068     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1069     hres = parse_htmlscript_a("-->");
1070     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1071     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
1072     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1073     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
1074     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1075     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
1076     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
1077     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
1078     ok(hres != S_OK, "ParseScriptText have not failed\n");
1079 }
1080
1081 START_TEST(run)
1082 {
1083     int argc;
1084     char **argv;
1085
1086     argc = winetest_get_mainargs(&argv);
1087
1088     CoInitialize(NULL);
1089
1090     if(argc > 2) {
1091         run_from_file(argv[2]);
1092     }else {
1093         trace("invoke version 0\n");
1094         invoke_version = 0;
1095         run_tests();
1096
1097         trace("invoke version 2\n");
1098         invoke_version = 2;
1099         run_tests();
1100     }
1101
1102     CoUninitialize();
1103 }