From cded9c4565fc08a78126e07bcc5278155865f7ee Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 4 Oct 2019 16:30:51 +0200 Subject: [PATCH] vbscript/tests: Add more tests. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/vbscript/tests/run.c | 250 +++++++++++++++++++++++++++++++++++++- 1 file changed, 246 insertions(+), 4 deletions(-) diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index f50d90d6aaf..2791244ac70 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -94,6 +94,7 @@ DEFINE_EXPECT(global_vbvar_d); DEFINE_EXPECT(global_vbvar_i); DEFINE_EXPECT(global_letobj_i); DEFINE_EXPECT(global_setobj_i); +DEFINE_EXPECT(global_globalcallback_i); DEFINE_EXPECT(testobj_propget_d); DEFINE_EXPECT(testobj_propget_i); DEFINE_EXPECT(testobj_propput_d); @@ -110,6 +111,8 @@ DEFINE_EXPECT(GetWindow); DEFINE_EXPECT(GetUIBehavior); DEFINE_EXPECT(EnableModeless); DEFINE_EXPECT(OnScriptError); +DEFINE_EXPECT(OnEnterScript); +DEFINE_EXPECT(OnLeaveScript); #define DISPID_GLOBAL_REPORTSUCCESS 1000 #define DISPID_GLOBAL_TRACE 1001 @@ -133,6 +136,7 @@ DEFINE_EXPECT(OnScriptError); #define DISPID_GLOBAL_SETOBJ 1019 #define DISPID_GLOBAL_TODO_WINE_OK 1020 #define DISPID_GLOBAL_WEEKSTARTDAY 1021 +#define DISPID_GLOBAL_GLOBALCALLBACK 1022 #define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 @@ -153,6 +157,7 @@ static int test_counter; static SCRIPTUICHANDLING uic_handling = SCRIPTUICHANDLING_NOUIERROR; static IDispatchEx testObj; static HRESULT onerror_hres = E_NOTIMPL; +static BOOL strict_enter_script; static BSTR a2bstr(const char *str) { @@ -1109,6 +1114,11 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD *pid = DISPID_GLOBAL_WEEKSTARTDAY; return S_OK; } + if(!strcmp_wa(bstrName, "globalCallback")) { + test_grfdex(grfdex, fdexNameCaseInsensitive); + *pid = DISPID_GLOBAL_GLOBALCALLBACK; + return S_OK; + } if(!strcmp_wa(bstrName, "testObj")) { test_grfdex(grfdex, fdexNameCaseInsensitive); *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)); 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); @@ -1736,9 +1793,11 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S return E_NOTIMPL; } +static IActiveScriptError **store_script_error; + static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) { - HRESULT hr = onerror_hres; + HRESULT hr = onerror_hres, hres; if(!expect_OnScriptError) { EXCEPINFO info; @@ -1749,7 +1808,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I if(SUCCEEDED(hres)) hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info); 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); @@ -1760,16 +1830,18 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface) { + if(strict_enter_script) + CHECK_EXPECT(OnEnterScript); return E_NOTIMPL; } static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface) { + if(strict_enter_script) + CHECK_EXPECT(OnLeaveScript); return E_NOTIMPL; } -#undef ACTSCPSITE_THIS - static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = { ActiveScriptSite_QueryInterface, ActiveScriptSite_AddRef, @@ -2018,6 +2090,7 @@ static void test_procedures(void) VARIANT v; HRESULT hres; + strict_enter_script = TRUE; script = create_and_init_script(0, TRUE); 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); + SET_EXPECT(OnEnterScript); + SET_EXPECT(OnLeaveScript); V_VT(&v) = VT_EMPTY; hres = IDispatchEx_InvokeEx(proc, DISPID_VALUE, 0, DISPATCH_METHOD, &dp, &v, &ei, &caller_sp); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + CHECK_CALLED(OnEnterScript); + CHECK_CALLED(OnLeaveScript); VariantClear(&v); IDispatchEx_Release(proc); 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); 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(!strcmp_wa(V_BSTR(&v), "foobar"), "Wrong string, got %s\n", wine_dbgstr_w(V_BSTR(&v))); VariantClear(&v); @@ -2046,6 +2128,164 @@ static void test_procedures(void) IActiveScriptParseProcedure2_Release(parse_proc); 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) @@ -2482,6 +2722,7 @@ static void run_from_res(const char *name) ok(hres == S_OK, "parse_script failed: %08x\n", hres); SysFreeString(str); + test_name = ""; } static void run_tests(void) @@ -2723,6 +2964,7 @@ static void run_tests(void) test_isexpression(); test_parse_errors(); test_parse_context(); + test_callbacks(); } static BOOL check_vbscript(void)