wined3d: Test and fix ddraw and d3d9 GetDC differences.
[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(GetItemInfo_testVal);
70
71 #define DISPID_GLOBAL_TESTPROPGET   0x1000
72 #define DISPID_GLOBAL_TESTPROPPUT   0x1001
73 #define DISPID_GLOBAL_REPORTSUCCESS 0x1002
74 #define DISPID_GLOBAL_TRACE         0x1003
75 #define DISPID_GLOBAL_OK            0x1004
76 #define DISPID_GLOBAL_GETVT         0x1005
77 #define DISPID_GLOBAL_TESTOBJ       0x1006
78 #define DISPID_GLOBAL_NULL_BSTR     0x1007
79
80 static const WCHAR testW[] = {'t','e','s','t',0};
81 static const CHAR testA[] = "test";
82 static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0};
83 static const CHAR test_valA[] = "testVal";
84
85 static BOOL strict_dispid_check;
86 static const char *test_name = "(null)";
87
88 static BSTR a2bstr(const char *str)
89 {
90     BSTR ret;
91     int len;
92
93     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
94     ret = SysAllocStringLen(NULL, len-1);
95     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
96
97     return ret;
98 }
99
100 static int strcmp_wa(LPCWSTR strw, const char *stra)
101 {
102     CHAR buf[512];
103     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
104     return lstrcmpA(buf, stra);
105 }
106
107 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
108 {
109     *ppv = NULL;
110
111     if(IsEqualGUID(riid, &IID_IUnknown)
112        || IsEqualGUID(riid, &IID_IDispatch)
113        || IsEqualGUID(riid, &IID_IDispatchEx))
114         *ppv = iface;
115     else
116         return E_NOINTERFACE;
117
118     return S_OK;
119 }
120
121 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
122 {
123     return 2;
124 }
125
126 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
127 {
128     return 1;
129 }
130
131 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
132 {
133     ok(0, "unexpected call\n");
134     return E_NOTIMPL;
135 }
136
137 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
138                                               LCID lcid, ITypeInfo **ppTInfo)
139 {
140     ok(0, "unexpected call\n");
141     return E_NOTIMPL;
142 }
143
144 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
145                                                 LPOLESTR *rgszNames, UINT cNames,
146                                                 LCID lcid, DISPID *rgDispId)
147 {
148     ok(0, "unexpected call\n");
149     return E_NOTIMPL;
150 }
151
152 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
153                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
154                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
155 {
156     ok(0, "unexpected call\n");
157     return E_NOTIMPL;
158 }
159
160 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
161 {
162     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
163     return E_NOTIMPL;
164 }
165
166 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
167 {
168     ok(0, "unexpected call\n");
169     return E_NOTIMPL;
170 }
171
172 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
173 {
174     ok(0, "unexpected call\n");
175     return E_NOTIMPL;
176 }
177
178 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
179 {
180     ok(0, "unexpected call\n");
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
185 {
186     ok(0, "unexpected call\n");
187     return E_NOTIMPL;
188 }
189
190 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
191 {
192     ok(0, "unexpected call\n");
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
197 {
198     ok(0, "unexpected call\n");
199     return E_NOTIMPL;
200 }
201
202 static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
203         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
204 {
205     switch(id) {
206     case DISPID_VALUE:
207         CHECK_EXPECT(testobj_value);
208
209         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
210         ok(pdp != NULL, "pdp == NULL\n");
211         ok(!pdp->rgvarg, "rgvarg != NULL\n");
212         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
213         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
214         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
215         ok(pvarRes != NULL, "pvarRes == NULL\n");
216         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
217         ok(pei != NULL, "pei == NULL\n");
218
219         V_VT(pvarRes) = VT_I4;
220         V_I4(pvarRes) = 1;
221         return S_OK;
222     }
223
224     ok(0, "unexpected call %x\n", id);
225     return DISP_E_MEMBERNOTFOUND;
226 }
227
228 static HRESULT WINAPI testObj_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
229 {
230     CHECK_EXPECT(testobj_delete);
231
232     ok(!strcmp_wa(bstrName, "deleteTest"), "unexpected name %s\n", wine_dbgstr_w(bstrName));
233     ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
234     return S_OK;
235 }
236
237 static IDispatchExVtbl testObjVtbl = {
238     DispatchEx_QueryInterface,
239     DispatchEx_AddRef,
240     DispatchEx_Release,
241     DispatchEx_GetTypeInfoCount,
242     DispatchEx_GetTypeInfo,
243     DispatchEx_GetIDsOfNames,
244     DispatchEx_Invoke,
245     DispatchEx_GetDispID,
246     testObj_InvokeEx,
247     testObj_DeleteMemberByName,
248     DispatchEx_DeleteMemberByDispID,
249     DispatchEx_GetMemberProperties,
250     DispatchEx_GetMemberName,
251     DispatchEx_GetNextDispID,
252     DispatchEx_GetNameSpaceParent
253 };
254
255 static IDispatchEx testObj = { &testObjVtbl };
256
257 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
258 {
259     if(!strcmp_wa(bstrName, "ok")) {
260         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
261         *pid = DISPID_GLOBAL_OK;
262         return S_OK;
263     }
264     if(!strcmp_wa(bstrName, "trace")) {
265         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
266         *pid = DISPID_GLOBAL_TRACE;
267         return S_OK;
268     }
269     if(!strcmp_wa(bstrName, "reportSuccess")) {
270         CHECK_EXPECT(global_success_d);
271         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
272         *pid = DISPID_GLOBAL_REPORTSUCCESS;
273         return S_OK;
274     }
275     if(!strcmp_wa(bstrName, "testPropGet")) {
276         CHECK_EXPECT(global_propget_d);
277         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
278         *pid = DISPID_GLOBAL_TESTPROPGET;
279         return S_OK;
280     }
281     if(!strcmp_wa(bstrName, "testPropPut")) {
282         CHECK_EXPECT(global_propput_d);
283         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
284         *pid = DISPID_GLOBAL_TESTPROPPUT;
285         return S_OK;
286     }
287     if(!strcmp_wa(bstrName, "getVT")) {
288         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
289         *pid = DISPID_GLOBAL_GETVT;
290         return S_OK;
291     }
292     if(!strcmp_wa(bstrName, "testObj")) {
293         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
294         *pid = DISPID_GLOBAL_TESTOBJ;
295         return S_OK;
296     }
297     if(!strcmp_wa(bstrName, "createNullBSTR")) {
298         *pid = DISPID_GLOBAL_NULL_BSTR;
299         return S_OK;
300     }
301     if(!strcmp_wa(bstrName, "notExists")) {
302         CHECK_EXPECT(global_notexists_d);
303         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
304         return DISP_E_UNKNOWNNAME;
305     }
306
307     if(strict_dispid_check)
308         ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
309     return DISP_E_UNKNOWNNAME;
310 }
311
312 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
313         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
314 {
315     switch(id) {
316     case DISPID_GLOBAL_OK:
317         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
318         ok(pdp != NULL, "pdp == NULL\n");
319         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
320         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
321         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
322         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
323         if(wFlags & INVOKE_PROPERTYGET)
324             ok(pvarRes != NULL, "pvarRes == NULL\n");
325         else
326             ok(!pvarRes, "pvarRes != NULL\n");
327         ok(pei != NULL, "pei == NULL\n");
328
329         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
330         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
331         ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
332
333         return S_OK;
334
335      case DISPID_GLOBAL_TRACE:
336         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
337         ok(pdp != NULL, "pdp == NULL\n");
338         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
339         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
340         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
341         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
342         ok(!pvarRes, "pvarRes != NULL\n");
343         ok(pei != NULL, "pei == NULL\n");
344
345         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
346         if(V_VT(pdp->rgvarg) == VT_BSTR)
347             trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
348
349         return S_OK;
350
351     case DISPID_GLOBAL_REPORTSUCCESS:
352         CHECK_EXPECT(global_success_i);
353
354         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
355         ok(pdp != NULL, "pdp == NULL\n");
356         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
357         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
358         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
359         ok(!pvarRes, "pvarRes != NULL\n");
360         ok(pei != NULL, "pei == NULL\n");
361
362         return S_OK;
363
364      case DISPID_GLOBAL_TESTPROPGET:
365         CHECK_EXPECT(global_propget_i);
366
367         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
368         ok(pdp != NULL, "pdp == NULL\n");
369         ok(!pdp->rgvarg, "rgvarg != NULL\n");
370         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
371         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
372         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
373         ok(pvarRes != NULL, "pvarRes == NULL\n");
374         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
375         ok(pei != NULL, "pei == NULL\n");
376
377         V_VT(pvarRes) = VT_I4;
378         V_I4(pvarRes) = 1;
379
380         return S_OK;
381
382     case DISPID_GLOBAL_TESTPROPPUT:
383         CHECK_EXPECT(global_propput_i);
384
385         ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags);
386         ok(pdp != NULL, "pdp == NULL\n");
387         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
388         ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n");
389         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
390         ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs);
391         ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
392         ok(!pvarRes, "pvarRes != NULL\n");
393
394         ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg));
395         ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg));
396         return S_OK;
397
398      case DISPID_GLOBAL_GETVT:
399         ok(pdp != NULL, "pdp == NULL\n");
400         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
401         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
402         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
403         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
404         ok(pvarRes != NULL, "pvarRes == NULL\n");
405         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
406         ok(pei != NULL, "pei == NULL\n");
407
408         V_VT(pvarRes) = VT_BSTR;
409         switch(V_VT(pdp->rgvarg)) {
410         case VT_EMPTY:
411             V_BSTR(pvarRes) = a2bstr("VT_EMPTY");
412             break;
413         case VT_NULL:
414             V_BSTR(pvarRes) = a2bstr("VT_NULL");
415             break;
416         case VT_I4:
417             V_BSTR(pvarRes) = a2bstr("VT_I4");
418             break;
419         case VT_R8:
420             V_BSTR(pvarRes) = a2bstr("VT_R8");
421             break;
422         case VT_BSTR:
423             V_BSTR(pvarRes) = a2bstr("VT_BSTR");
424             break;
425         case VT_DISPATCH:
426             V_BSTR(pvarRes) = a2bstr("VT_DISPATCH");
427             break;
428         case VT_BOOL:
429             V_BSTR(pvarRes) = a2bstr("VT_BOOL");
430             break;
431         default:
432             ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
433             return E_FAIL;
434         }
435
436         return S_OK;
437
438     case DISPID_GLOBAL_TESTOBJ:
439         ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
440         ok(pdp != NULL, "pdp == NULL\n");
441         ok(!pdp->rgvarg, "rgvarg != NULL\n");
442         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
443         ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
444         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
445         ok(pvarRes != NULL, "pvarRes == NULL\n");
446         ok(V_VT(pvarRes) ==  VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
447         ok(pei != NULL, "pei == NULL\n");
448
449         V_VT(pvarRes) = VT_DISPATCH;
450         V_DISPATCH(pvarRes) = (IDispatch*)&testObj;
451         return S_OK;
452
453     case DISPID_GLOBAL_NULL_BSTR:
454         if(pvarRes) {
455             V_VT(pvarRes) = VT_BSTR;
456             V_BSTR(pvarRes) = NULL;
457         }
458         return S_OK;
459     }
460
461     ok(0, "unexpected call %x\n", id);
462     return DISP_E_MEMBERNOTFOUND;
463 }
464
465 static IDispatchExVtbl GlobalVtbl = {
466     DispatchEx_QueryInterface,
467     DispatchEx_AddRef,
468     DispatchEx_Release,
469     DispatchEx_GetTypeInfoCount,
470     DispatchEx_GetTypeInfo,
471     DispatchEx_GetIDsOfNames,
472     DispatchEx_Invoke,
473     Global_GetDispID,
474     Global_InvokeEx,
475     DispatchEx_DeleteMemberByName,
476     DispatchEx_DeleteMemberByDispID,
477     DispatchEx_GetMemberProperties,
478     DispatchEx_GetMemberName,
479     DispatchEx_GetNextDispID,
480     DispatchEx_GetNameSpaceParent
481 };
482
483 static IDispatchEx Global = { &GlobalVtbl };
484
485 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
486 {
487     *ppv = NULL;
488
489     if(IsEqualGUID(&IID_IUnknown, riid))
490         *ppv = iface;
491     else if(IsEqualGUID(&IID_IActiveScriptSite, riid))
492         *ppv = iface;
493     else
494         return E_NOINTERFACE;
495
496     IUnknown_AddRef((IUnknown*)*ppv);
497     return S_OK;
498 }
499
500 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
501 {
502     return 2;
503 }
504
505 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
506 {
507     return 1;
508 }
509
510 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
511 {
512     *plcid = GetUserDefaultLCID();
513     return S_OK;
514 }
515
516 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
517         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
518 {
519     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
520     ok(!ppti, "ppti != NULL\n");
521
522     if(!strcmp_wa(pstrName, test_valA))
523         CHECK_EXPECT(GetItemInfo_testVal);
524     else if(strcmp_wa(pstrName, testA))
525         ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName));
526
527     *ppiunkItem = (IUnknown*)&Global;
528     return S_OK;
529 }
530
531 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
532 {
533     return E_NOTIMPL;
534 }
535
536 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
537         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
538 {
539     return E_NOTIMPL;
540 }
541
542 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
543 {
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
548 {
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
553 {
554     return E_NOTIMPL;
555 }
556
557 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
558 {
559     return E_NOTIMPL;
560 }
561
562 #undef ACTSCPSITE_THIS
563
564 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
565     ActiveScriptSite_QueryInterface,
566     ActiveScriptSite_AddRef,
567     ActiveScriptSite_Release,
568     ActiveScriptSite_GetLCID,
569     ActiveScriptSite_GetItemInfo,
570     ActiveScriptSite_GetDocVersionString,
571     ActiveScriptSite_OnScriptTerminate,
572     ActiveScriptSite_OnStateChange,
573     ActiveScriptSite_OnScriptError,
574     ActiveScriptSite_OnEnterScript,
575     ActiveScriptSite_OnLeaveScript
576 };
577
578 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
579
580 static IActiveScript *create_script(void)
581 {
582     IActiveScript *script;
583     HRESULT hres;
584
585     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
586             &IID_IActiveScript, (void**)&script);
587     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
588
589     return script;
590 }
591
592 static void parse_script(BSTR script_str)
593 {
594     IActiveScriptParse *parser;
595     IActiveScript *engine;
596     HRESULT hres;
597
598     engine = create_script();
599     if(!engine)
600         return;
601
602     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
603     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
604     if (FAILED(hres))
605     {
606         IActiveScript_Release(engine);
607         return;
608     }
609
610     hres = IActiveScriptParse64_InitNew(parser);
611     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
612
613     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
614     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
615
616     hres = IActiveScript_AddNamedItem(engine, testW,
617             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
618     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
619
620     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
621     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
622
623     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
624     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
625
626     IActiveScript_Release(engine);
627     IUnknown_Release(parser);
628 }
629
630 static HRESULT parse_htmlscript(BSTR script_str)
631 {
632     IActiveScriptParse *parser;
633     IActiveScript *engine;
634     HRESULT hres;
635     BSTR tmp = a2bstr("</SCRIPT>");
636
637     engine = create_script();
638     if(!engine)
639         return E_FAIL;
640
641     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
642     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
643     if (FAILED(hres))
644     {
645         IActiveScript_Release(engine);
646         return E_FAIL;
647     }
648
649     hres = IActiveScriptParse64_InitNew(parser);
650     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
651
652     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
653     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
654
655     hres = IActiveScript_AddNamedItem(engine, testW,
656             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
657     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
658
659     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
660     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
661
662     hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, tmp, 0, 0, 0, NULL, NULL);
663
664     IActiveScript_Release(engine);
665     IUnknown_Release(parser);
666     SysFreeString(tmp);
667
668     return hres;
669 }
670
671 static void parse_script_a(const char *src)
672 {
673     BSTR tmp = a2bstr(src);
674     parse_script(tmp);
675     SysFreeString(tmp);
676 }
677
678 static HRESULT parse_htmlscript_a(const char *src)
679 {
680     HRESULT hres;
681     BSTR tmp = a2bstr(src);
682     hres = parse_htmlscript(tmp);
683     SysFreeString(tmp);
684
685     return hres;
686 }
687
688 static BSTR get_script_from_file(const char *filename)
689 {
690     DWORD size, len;
691     HANDLE file, map;
692     const char *file_map;
693     BSTR ret;
694
695     file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
696     if(file == INVALID_HANDLE_VALUE) {
697         trace("Could not open file: %u\n", GetLastError());
698         return NULL;
699     }
700
701     size = GetFileSize(file, NULL);
702
703     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
704     CloseHandle(file);
705     if(map == INVALID_HANDLE_VALUE) {
706         trace("Could not create file mapping: %u\n", GetLastError());
707         return NULL;
708     }
709
710     file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
711     CloseHandle(map);
712     if(!file_map) {
713         trace("MapViewOfFile failed: %u\n", GetLastError());
714         return NULL;
715     }
716
717     len = MultiByteToWideChar(CP_ACP, 0, file_map, size, NULL, 0);
718     ret = SysAllocStringLen(NULL, len);
719     MultiByteToWideChar(CP_ACP, 0, file_map, size, ret, len);
720
721     UnmapViewOfFile(file_map);
722
723     return ret;
724 }
725
726 static void run_from_file(const char *filename)
727 {
728     BSTR script_str = get_script_from_file(filename);
729
730     strict_dispid_check = FALSE;
731
732     if(script_str)
733         parse_script(script_str);
734
735     SysFreeString(script_str);
736 }
737
738 static void run_from_res(const char *name)
739 {
740     const char *data;
741     DWORD size, len;
742     BSTR str;
743     HRSRC src;
744
745     strict_dispid_check = FALSE;
746     test_name = name;
747
748     src = FindResourceA(NULL, name, (LPCSTR)40);
749     ok(src != NULL, "Could not find resource %s\n", name);
750
751     size = SizeofResource(NULL, src);
752     data = LoadResource(NULL, src);
753
754     len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0);
755     str = SysAllocStringLen(NULL, len);
756     len = MultiByteToWideChar(CP_ACP, 0, data, size, str, len);
757
758     SET_EXPECT(global_success_d);
759     SET_EXPECT(global_success_i);
760     parse_script(str);
761     CHECK_CALLED(global_success_d);
762     CHECK_CALLED(global_success_i);
763
764     SysFreeString(str);
765 }
766
767 static void test_isvisible(BOOL global_members)
768 {
769     IActiveScriptParse *parser;
770     IActiveScript *engine;
771     HRESULT hres;
772
773     static const WCHAR script_textW[] =
774         {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
775
776     engine = create_script();
777     if(!engine)
778         return;
779
780     hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
781     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
782     if (FAILED(hres))
783     {
784         IActiveScript_Release(engine);
785         return;
786     }
787
788     hres = IActiveScriptParse64_InitNew(parser);
789     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
790
791     hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
792     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
793
794     if(global_members)
795         SET_EXPECT(GetItemInfo_testVal);
796     hres = IActiveScript_AddNamedItem(engine, test_valW,
797             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|
798             (global_members ? SCRIPTITEM_GLOBALMEMBERS : 0));
799     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
800     if(global_members)
801         CHECK_CALLED(GetItemInfo_testVal);
802
803     hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
804     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
805
806     if(!global_members)
807         SET_EXPECT(GetItemInfo_testVal);
808     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
809     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
810     if(!global_members)
811         CHECK_CALLED(GetItemInfo_testVal);
812
813     hres = IActiveScriptParse64_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
814     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
815
816     IActiveScript_Release(engine);
817     IUnknown_Release(parser);
818 }
819
820 static void run_tests(void)
821 {
822     HRESULT hres;
823
824     strict_dispid_check = TRUE;
825
826     parse_script_a("");
827     parse_script_a("/* empty */ ;");
828
829     SET_EXPECT(global_propget_d);
830     SET_EXPECT(global_propget_i);
831     parse_script_a("testPropGet;");
832     CHECK_CALLED(global_propget_d);
833     CHECK_CALLED(global_propget_i);
834
835     SET_EXPECT(global_propput_d);
836     SET_EXPECT(global_propput_i);
837     parse_script_a("testPropPut = 1;");
838     CHECK_CALLED(global_propput_d);
839     CHECK_CALLED(global_propput_i);
840
841     SET_EXPECT(global_success_d);
842     SET_EXPECT(global_success_i);
843     parse_script_a("reportSuccess();");
844     CHECK_CALLED(global_success_d);
845     CHECK_CALLED(global_success_i);
846
847     SET_EXPECT(testobj_delete);
848     parse_script_a("delete testObj.deleteTest;");
849     CHECK_CALLED(testobj_delete);
850
851     parse_script_a("ok(typeof(test) === 'object', \"typeof(test) != 'object'\");");
852
853     parse_script_a("function reportSuccess() {}; reportSuccess();");
854
855     SET_EXPECT(global_propget_d);
856     parse_script_a("var testPropGet");
857     CHECK_CALLED(global_propget_d);
858
859     SET_EXPECT(global_notexists_d);
860     parse_script_a("var notExists; notExists = 1;");
861     CHECK_CALLED(global_notexists_d);
862
863     parse_script_a("function f() { var testPropGet; }");
864
865     parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
866
867     SET_EXPECT(testobj_value);
868     parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');");
869     CHECK_CALLED(testobj_value);
870
871     run_from_res("lang.js");
872     run_from_res("api.js");
873     run_from_res("regexp.js");
874
875     test_isvisible(FALSE);
876     test_isvisible(TRUE);
877
878     hres = parse_htmlscript_a("<!--");
879     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
880     hres = parse_htmlscript_a("-->");
881     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
882     hres = parse_htmlscript_a("<!--\nvar a=1;\n-->\n");
883     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
884     hres = parse_htmlscript_a("<!--\n<!-- ignore this\n-->\n");
885     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
886     hres = parse_htmlscript_a("var a=1;\nif(a-->0) a=5;\n");
887     ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
888     hres = parse_htmlscript_a("var a=1;\nif(a\n-->0) a=5;\n");
889     ok(hres != S_OK, "ParseScriptText have not failed\n");
890 }
891
892 START_TEST(run)
893 {
894     int argc;
895     char **argv;
896
897     argc = winetest_get_mainargs(&argv);
898
899     CoInitialize(NULL);
900
901     if(argc > 2)
902         run_from_file(argv[2]);
903     else
904         run_tests();
905
906     CoUninitialize();
907 }