vbscript/tests: Add more tests.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-10-04 16:30:51 +02:00 committed by Alexandre Julliard
parent 34674eff5b
commit cded9c4565
1 changed files with 246 additions and 4 deletions

View File

@ -94,6 +94,7 @@ DEFINE_EXPECT(global_vbvar_d);
DEFINE_EXPECT(global_vbvar_i); DEFINE_EXPECT(global_vbvar_i);
DEFINE_EXPECT(global_letobj_i); DEFINE_EXPECT(global_letobj_i);
DEFINE_EXPECT(global_setobj_i); DEFINE_EXPECT(global_setobj_i);
DEFINE_EXPECT(global_globalcallback_i);
DEFINE_EXPECT(testobj_propget_d); DEFINE_EXPECT(testobj_propget_d);
DEFINE_EXPECT(testobj_propget_i); DEFINE_EXPECT(testobj_propget_i);
DEFINE_EXPECT(testobj_propput_d); DEFINE_EXPECT(testobj_propput_d);
@ -110,6 +111,8 @@ DEFINE_EXPECT(GetWindow);
DEFINE_EXPECT(GetUIBehavior); DEFINE_EXPECT(GetUIBehavior);
DEFINE_EXPECT(EnableModeless); DEFINE_EXPECT(EnableModeless);
DEFINE_EXPECT(OnScriptError); DEFINE_EXPECT(OnScriptError);
DEFINE_EXPECT(OnEnterScript);
DEFINE_EXPECT(OnLeaveScript);
#define DISPID_GLOBAL_REPORTSUCCESS 1000 #define DISPID_GLOBAL_REPORTSUCCESS 1000
#define DISPID_GLOBAL_TRACE 1001 #define DISPID_GLOBAL_TRACE 1001
@ -133,6 +136,7 @@ DEFINE_EXPECT(OnScriptError);
#define DISPID_GLOBAL_SETOBJ 1019 #define DISPID_GLOBAL_SETOBJ 1019
#define DISPID_GLOBAL_TODO_WINE_OK 1020 #define DISPID_GLOBAL_TODO_WINE_OK 1020
#define DISPID_GLOBAL_WEEKSTARTDAY 1021 #define DISPID_GLOBAL_WEEKSTARTDAY 1021
#define DISPID_GLOBAL_GLOBALCALLBACK 1022
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPGET 2000
#define DISPID_TESTOBJ_PROPPUT 2001 #define DISPID_TESTOBJ_PROPPUT 2001
@ -153,6 +157,7 @@ static int test_counter;
static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR; static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR;
static IDispatchEx testObj; static IDispatchEx testObj;
static HRESULT onerror_hres = E_NOTIMPL; static HRESULT onerror_hres = E_NOTIMPL;
static BOOL strict_enter_script;
static BSTR a2bstr(const char *str) static BSTR a2bstr(const char *str)
{ {
@ -1109,6 +1114,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
*pid = DISPID_GLOBAL_WEEKSTARTDAY; *pid = DISPID_GLOBAL_WEEKSTARTDAY;
return S_OK; return S_OK;
} }
if(!strcmp_wa(bstrName, "globalCallback")) {
test_grfdex(grfdex, fdexNameCaseInsensitive);
*pid = DISPID_GLOBAL_GLOBALCALLBACK;
return S_OK;
}
if(!strcmp_wa(bstrName, "testObj")) { if(!strcmp_wa(bstrName, "testObj")) {
test_grfdex(grfdex, fdexNameCaseInsensitive); test_grfdex(grfdex, fdexNameCaseInsensitive);
*pid = DISPID_GLOBAL_TESTOBJ; *pid = DISPID_GLOBAL_TESTOBJ;
@ -1565,6 +1575,53 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v)); ok(V_ERROR(v) == DISP_E_PARAMNOTFOUND, "V_ERROR(v) = %08x\n", V_ERROR(v));
return S_OK; return S_OK;
} }
case DISPID_GLOBAL_GLOBALCALLBACK: {
DISPPARAMS dp = {0};
IDispatchEx *dispex;
EXCEPINFO ei;
VARIANT v;
DISPID id;
BSTR str;
HRESULT hres;
CHECK_EXPECT(global_globalcallback_i);
CHECK_CALLED(OnEnterScript);
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
ok(pdp != NULL, "pdp == NULL\n");
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg));
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
ok(!pvarRes, "pvarRes != NULL\n");
ok(pei != NULL, "pei == NULL\n");
hres = IDispatch_QueryInterface(V_DISPATCH(pdp->rgvarg), &IID_IDispatchEx, (void**)&dispex);
ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
str = SysAllocString(L"callback");
hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
SysFreeString(str);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
memset(&ei, 0, sizeof(ei));
hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, pspCaller);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
todo_wine
CHECK_CALLED(OnEnterScript);
todo_wine
CHECK_CALLED(OnLeaveScript);
ok(V_VT(&v) == VT_BOOL, "V_VT(v) = %d\n", V_VT(&v));
ok(V_BOOL(&v) == VARIANT_TRUE, "V_BOOL(v) = %x\n", V_BOOL(&v));
IDispatchEx_Release(dispex);
SET_EXPECT(OnLeaveScript);
return S_OK;
}
} }
ok(0, "unexpected call %d\n", id); ok(0, "unexpected call %d\n", id);
@ -1736,9 +1793,11 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S
return E_NOTIMPL; return E_NOTIMPL;
} }
static IActiveScriptError **store_script_error;
static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
{ {
HRESULT hr = onerror_hres; HRESULT hr = onerror_hres, hres;
if(!expect_OnScriptError) { if(!expect_OnScriptError) {
EXCEPINFO info; EXCEPINFO info;
@ -1749,7 +1808,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info); hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info);
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
trace("Error in line %u: %s\n", line+1, wine_dbgstr_w(info.bstrDescription)); trace("Error in line %u: %x %s\n", line+1, info.wCode, wine_dbgstr_w(info.bstrDescription));
}else {
IDispatchEx *dispex;
hres = IActiveScriptError_QueryInterface(pscripterror, &IID_IDispatchEx, (void**)&dispex);
ok(hres == E_NOINTERFACE, "QI(IDispatchEx) returned: %08x\n", hres);
}
if(store_script_error) {
IActiveScriptError_AddRef(pscripterror);
*store_script_error = pscripterror;
store_script_error = NULL;
} }
CHECK_EXPECT(OnScriptError); CHECK_EXPECT(OnScriptError);
@ -1760,16 +1830,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I
static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface) static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
{ {
if(strict_enter_script)
CHECK_EXPECT(OnEnterScript);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface) static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
{ {
if(strict_enter_script)
CHECK_EXPECT(OnLeaveScript);
return E_NOTIMPL; return E_NOTIMPL;
} }
#undef ACTSCPSITE_THIS
static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = { static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
ActiveScriptSite_QueryInterface, ActiveScriptSite_QueryInterface,
ActiveScriptSite_AddRef, ActiveScriptSite_AddRef,
@ -2018,6 +2090,7 @@ static void test_procedures(void)
VARIANT v; VARIANT v;
HRESULT hres; HRESULT hres;
strict_enter_script = TRUE;
script = create_and_init_script(0, TRUE); script = create_and_init_script(0, TRUE);
hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc); hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
@ -2029,15 +2102,24 @@ static void test_procedures(void)
proc = parse_procedure(parse_proc, "dim x\nif true then x=false", 0); proc = parse_procedure(parse_proc, "dim x\nif true then x=false", 0);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
V_VT(&v) = VT_EMPTY; V_VT(&v) = VT_EMPTY;
hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
VariantClear(&v); VariantClear(&v);
IDispatchEx_Release(proc); IDispatchEx_Release(proc);
proc = parse_procedure(parse_proc, "\"foobar\"", SCRIPTPROC_ISEXPRESSION); proc = parse_procedure(parse_proc, "\"foobar\"", SCRIPTPROC_ISEXPRESSION);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&v)); ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR, got %s\n", vt2a(&v));
ok(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v))); ok(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v)));
VariantClear(&v); VariantClear(&v);
@ -2046,6 +2128,164 @@ static void test_procedures(void)
IActiveScriptParseProcedure2_Release(parse_proc); IActiveScriptParseProcedure2_Release(parse_proc);
close_script(script); close_script(script);
strict_enter_script = FALSE;
}
static void free_ei(EXCEPINFO *ei)
{
SysFreeString(ei->bstrSource);
SysFreeString(ei->bstrDescription);
SysFreeString(ei->bstrHelpFile);
}
static void test_callbacks(void)
{
IActiveScriptError *error1, *error2;
IActiveScriptParse *parser;
DISPPARAMS dp = {NULL};
IActiveScript *script;
IDispatchEx *dispex;
IDispatch *disp;
DISPID id;
EXCEPINFO ei = {0};
BSTR str;
VARIANT v;
HRESULT hres;
strict_enter_script = TRUE;
script = create_and_init_script(SCRIPTITEM_GLOBALMEMBERS, TRUE);
hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
ok(hres == S_OK, "Could not get IActiveScriptParseProcedure2 iface: %08x\n", hres);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
hres = IActiveScriptParse_ParseScriptText(parser,
L"class CallbackClass\n"
L" public function callback()\n"
L" call ok(err.number = 2, \"err.number = \" & err.number)\n"
L" callback = true\n"
L" end function\n"
L"end class\n"
L"function callGlobalCallback()\n"
L" on error resume next\n"
L" err.raise 2\n"
L" call test.globalCallback(new CallbackClass)\n"
L" call ok(err.number = 2, \"err.number = \" & err.numner)\n"
L"end function\n",
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
hres = IActiveScript_GetScriptDispatch(script, NULL, &disp);
ok(hres == S_OK, "GetScriptDispatch failed: %08x\n", hres);
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
IDispatch_Release(disp);
str = SysAllocString(L"callGlobalCallback");
hres = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &id);
ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
SysFreeString(str);
SET_EXPECT(OnEnterScript);
/* OnLeaveScript will be set in global callback */
SET_EXPECT(global_globalcallback_i);
hres = IDispatchEx_InvokeEx(dispex, id, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
/* OnEnterScript was checked in global callback */
CHECK_CALLED(OnLeaveScript);
CHECK_CALLED(global_globalcallback_i);
store_script_error = &error1;
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
SET_EXPECT(OnScriptError);
hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise 2\n",
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == MAKE_VBSERROR(2), "ParseScriptText failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
CHECK_CALLED(OnScriptError);
store_script_error = &error2;
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
SET_EXPECT(OnScriptError);
hres = IActiveScriptParse_ParseScriptText(parser,
L"call ok(err.number = 0, \"err.number = \" & err.number)\n"
L"err.raise &h86664004&, \"src\", \"desc\", \"help\", 1\n",
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == SCRIPT_E_RECORDED, "ParseScriptText failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
CHECK_CALLED(OnScriptError);
memset(&ei, 0xcc, sizeof(ei));
hres = IActiveScriptError_GetExceptionInfo(error1, &ei);
ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres);
ok(!ei.wCode, "wCode = %x\n", ei.wCode);
ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved);
if(is_english) {
ok(!wcscmp(ei.bstrSource, L"Microsoft VBScript runtime error"),
"bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource));
ok(!wcscmp(ei.bstrDescription, L"Object doesn't support this property or method"),
"bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription));
}
ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile));
ok(!ei.dwHelpContext, "dwHelpContext = %x\n", ei.dwHelpContext);
ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved);
ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn);
ok(ei.scode == MAKE_VBSERROR(2), "scode = %x\n", ei.scode);
free_ei(&ei);
IActiveScriptError_Release(error1);
memset(&ei, 0xcc, sizeof(ei));
hres = IActiveScriptError_GetExceptionInfo(error2, &ei);
ok(hres == S_OK, "GetExceptionInfo returned %08x\n", hres);
ok(!ei.wCode, "wCode = %x\n", ei.wCode);
ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved);
ok(!wcscmp(ei.bstrSource, L"src"), "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource));
ok(!wcscmp(ei.bstrDescription, L"desc"), "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription));
ok(!wcscmp(ei.bstrHelpFile, L"help"), "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile));
ok(ei.dwHelpContext == 1, "dwHelpContext = %x\n", ei.dwHelpContext);
ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved);
ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn);
ok(ei.scode == SCRIPT_E_RECORDED, "scode = %x\n", ei.scode);
free_ei(&ei);
IActiveScriptError_Release(error2);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
SET_EXPECT(OnScriptError);
hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &hffff&\n",
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == MAKE_VBSERROR(0xffff), "ParseScriptText failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
CHECK_CALLED(OnScriptError);
SET_EXPECT(OnEnterScript);
SET_EXPECT(OnLeaveScript);
SET_EXPECT(OnScriptError);
hres = IActiveScriptParse_ParseScriptText(parser, L"err.raise &h80102030&\n",
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == 0x80102030, "ParseScriptText failed: %08x\n", hres);
CHECK_CALLED(OnEnterScript);
CHECK_CALLED(OnLeaveScript);
CHECK_CALLED(OnScriptError);
IDispatchEx_Release(dispex);
IActiveScriptParse_Release(parser);
close_script(script);
strict_enter_script = FALSE;
} }
static void test_gc(void) static void test_gc(void)
@ -2482,6 +2722,7 @@ static void run_from_res(const char *name)
ok(hres == S_OK, "parse_script failed: %08x\n", hres); ok(hres == S_OK, "parse_script failed: %08x\n", hres);
SysFreeString(str); SysFreeString(str);
test_name = "";
} }
static void run_tests(void) static void run_tests(void)
@ -2723,6 +2964,7 @@ static void run_tests(void)
test_isexpression(); test_isexpression();
test_parse_errors(); test_parse_errors();
test_parse_context(); test_parse_context();
test_callbacks();
} }
static BOOL check_vbscript(void) static BOOL check_vbscript(void)