Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/msscript.ocx/msscript.c | 20 ++++++- dlls/msscript.ocx/tests/msscript.c | 91 +++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 5 deletions(-)
diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c index 6e4c8d166a..49040b9455 100644 --- a/dlls/msscript.ocx/msscript.c +++ b/dlls/msscript.ocx/msscript.c @@ -71,6 +71,7 @@ typedef struct ScriptHost {
IActiveScript *script; IActiveScriptParse *parse; + SCRIPTSTATE script_state; CLSID clsid;
struct list named_items; @@ -568,6 +569,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) WARN("InitNew failed, %#x\n", hr); goto failed; } + host->script_state = SCRIPTSTATE_INITIALIZED;
*ret = host; return S_OK; @@ -952,6 +954,20 @@ static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, return hr; }
+static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state, BOOL check_state) +{ + HRESULT hr; + + if (check_state && (host->script_state == SCRIPTSTATE_STARTED)) + return S_OK; + + hr = IActiveScript_SetScriptState(host->script, state); + if (SUCCEEDED(hr)) + host->script_state = state; + + return hr; +} + static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface) { ScriptControl *This = impl_from_IScriptControl(iface); @@ -962,7 +978,7 @@ static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface) return E_FAIL;
clear_named_items(This->host); - return IActiveScript_SetScriptState(This->host->script, SCRIPTSTATE_INITIALIZED); + return set_script_state(This->host, SCRIPTSTATE_INITIALIZED, FALSE); }
static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code) @@ -987,7 +1003,7 @@ static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression, if (!This->host || This->state != Initialized) return E_FAIL;
- hr = IActiveScript_SetScriptState(This->host->script, SCRIPTSTATE_STARTED); + hr = set_script_state(This->host, SCRIPTSTATE_STARTED, TRUE); if (FAILED(hr)) return hr;
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c index 2d500d8308..8ed4af2e6f 100644 --- a/dlls/msscript.ocx/tests/msscript.c +++ b/dlls/msscript.ocx/tests/msscript.c @@ -95,6 +95,8 @@ DEFINE_EXPECT(Close); DEFINE_EXPECT(SetScriptSite); DEFINE_EXPECT(QI_IActiveScriptParse); DEFINE_EXPECT(SetScriptState_INITIALIZED); +DEFINE_EXPECT(SetScriptState_STARTED); +DEFINE_EXPECT(ParseScriptText); DEFINE_EXPECT(AddNamedItem);
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) @@ -147,8 +149,8 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { - ok(0, "unexpected call\n"); - return E_NOTIMPL; + CHECK_EXPECT(ParseScriptText); + return S_OK; }
static const IActiveScriptParseVtbl ActiveScriptParseVtbl = { @@ -304,6 +306,10 @@ static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTST CHECK_EXPECT(SetScriptState_INITIALIZED); return S_OK; } + else if (ss == SCRIPTSTATE_STARTED) { + CHECK_EXPECT(SetScriptState_STARTED); + return S_OK; + } else ok(0, "unexpected call, state %u\n", ss);
@@ -1381,7 +1387,7 @@ static void _check_error(IScriptControl *sc, LONG exp_num, int line) { error_num = 0xdeadbeef; hr = IScriptError_get_Number(script_err, &error_num); - ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.", hr); + ok_(__FILE__,line)(hr == S_OK, "IScriptError_get_Number failed: 0x%08x.\n", hr); ok_(__FILE__,line)(error_num == exp_num, "got wrong error number: %d, expected %d.\n", error_num, exp_num); IScriptError_Release(script_err); @@ -1485,6 +1491,85 @@ static void test_IScriptControl_Eval(void) SysFreeString(script_str);
IScriptControl_Release(sc); + + /* custom script engine */ + if (register_script_engine()) + { + hr = CoCreateInstance(&CLSID_ScriptControl, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, + &IID_IScriptControl, (void **)&sc); + ok(hr == S_OK, "Failed to create IScriptControl interface: 0x%08x.\n", hr); + + SET_EXPECT(CreateInstance); + SET_EXPECT(SetInterfaceSafetyOptions); + SET_EXPECT(SetScriptSite); + SET_EXPECT(QI_IActiveScriptParse); + SET_EXPECT(InitNew); + + language= a2bstr("testscript"); + hr = IScriptControl_put_Language(sc, language); + ok(hr == S_OK, "IScriptControl_put_Language failed: 0x%08x.\n", hr); + SysFreeString(language); + + CHECK_CALLED(CreateInstance); + CHECK_CALLED(SetInterfaceSafetyOptions); + CHECK_CALLED(SetScriptSite); + CHECK_CALLED(QI_IActiveScriptParse); + CHECK_CALLED(InitNew); + + SET_EXPECT(SetScriptState_STARTED); + SET_EXPECT(ParseScriptText); + script_str = a2bstr("var1 = 1 + 1"); + V_VT(&var) = VT_NULL; + V_I4(&var) = 0xdeadbeef; + hr = IScriptControl_Eval(sc, script_str, &var); + ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr); + ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n", + V_VT(&var), V_I4(&var)); + SysFreeString(script_str); + CHECK_CALLED(SetScriptState_STARTED); + CHECK_CALLED(ParseScriptText); + + SET_EXPECT(ParseScriptText); + script_str = a2bstr("var2 = 10 + var1"); + V_VT(&var) = VT_NULL; + V_I4(&var) = 0xdeadbeef; + hr = IScriptControl_Eval(sc, script_str, &var); + ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr); + ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n", + V_VT(&var), V_I4(&var)); + SysFreeString(script_str); + CHECK_CALLED(ParseScriptText); + + SET_EXPECT(SetScriptState_INITIALIZED); + hr = IScriptControl_Reset(sc); + ok(hr == S_OK, "IScriptControl_Reset failed: 0x%08x.\n", hr); + CHECK_CALLED(SetScriptState_INITIALIZED); + + SET_EXPECT(SetScriptState_STARTED); + SET_EXPECT(ParseScriptText); + script_str = a2bstr("var2 = 10 + var1"); + V_VT(&var) = VT_NULL; + V_I4(&var) = 0xdeadbeef; + hr = IScriptControl_Eval(sc, script_str, &var); + ok(hr == S_OK, "IScriptControl_Eval failed: 0x%08x.\n", hr); + ok((V_VT(&var) == VT_EMPTY) && (V_I4(&var) == 0xdeadbeef), "V_VT(var) = %d, V_I4(var) = %d.\n", + V_VT(&var), V_I4(&var)); + SysFreeString(script_str); + CHECK_CALLED(SetScriptState_STARTED); + CHECK_CALLED(ParseScriptText); + + IActiveScriptSite_Release(site); + + init_registry(FALSE); + + SET_EXPECT(Close); + + IScriptControl_Release(sc); + + CHECK_CALLED(Close); + } + else + skip("Could not register TestScript engine.\n"); }
START_TEST(msscript)
Hi Jactry,
On 9/16/19 4:19 PM, Jactry Zeng wrote:
@@ -952,6 +954,20 @@ static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, return hr; }
+static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state, BOOL check_state) +{
- HRESULT hr;
- if (check_state && (host->script_state == SCRIPTSTATE_STARTED))
return S_OK;
- hr = IActiveScript_SetScriptState(host->script, state);
- if (SUCCEEDED(hr))
host->script_state = state;
- return hr;
+}
I think that the previous version was better. Nikolay's comment was a question. The answer seems to be that only some set_script_state callers call the engine repeatedly.
@@ -147,8 +149,8 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) {
- ok(0, "unexpected call\n");
- return E_NOTIMPL;
- CHECK_EXPECT(ParseScriptText);
- return S_OK; }
It would be interesting to test some arguments. Especially flags will be useful.
- /* custom script engine */
- if (register_script_engine())
- {
It seems to be done in quite a few places already. Maybe we should move the call to START_TEST and have have_custom_engine global variable?
Thanks,
Jacek