Module: wine Branch: master Commit: 71b58e56c24c06db589605cd53fc37aca5e2d747 URL: http://source.winehq.org/git/wine.git/?a=commit;h=71b58e56c24c06db589605cd53...
Author: Piotr Caban piotr@codeweavers.com Date: Fri Sep 2 12:24:12 2011 +0200
jscript: Added Object.hasOwnProperty implementation.
---
dlls/jscript/dispex.c | 14 ++++++++++++++ dlls/jscript/jscript.h | 1 + dlls/jscript/object.c | 43 +++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/tests/api.js | 11 +++++++++++ dlls/jscript/tests/run.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 653857c..3a0eabf 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1132,3 +1132,17 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
return delete_prop(prop); } + +VARIANT_BOOL jsdisp_is_own_prop(jsdisp_t *obj, BSTR name) +{ + dispex_prop_t *prop; + HRESULT hres; + + hres = find_prop_name(obj, name, &prop); + if(FAILED(hres)) + return VARIANT_FALSE; + else if(!prop) + return VARIANT_FALSE; + + return prop->type==PROP_VARIANT ? VARIANT_TRUE : VARIANT_FALSE; +} diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index c0b60ae..ee03e90 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -217,6 +217,7 @@ HRESULT jsdisp_propget_name(jsdisp_t*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvi HRESULT jsdisp_get_idx(jsdisp_t*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*) DECLSPEC_HIDDEN; HRESULT jsdisp_get_id(jsdisp_t*,const WCHAR*,DWORD,DISPID*) DECLSPEC_HIDDEN; HRESULT jsdisp_delete_idx(jsdisp_t*,DWORD) DECLSPEC_HIDDEN; +VARIANT_BOOL jsdisp_is_own_prop(jsdisp_t *obj, BSTR name) DECLSPEC_HIDDEN;
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD, jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 9f2e4d5..c1137c1 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -111,8 +111,47 @@ static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + BSTR name; + BOOL result; + DISPID id; + HRESULT hres; + + TRACE("\n"); + + if(!arg_cnt(dp)) { + if(retv) { + V_VT(retv) = VT_BOOL; + V_BOOL(retv) = VARIANT_FALSE; + } + + return S_OK; + } + + hres = to_string(ctx, get_arg(dp, 0), ei, &name); + if(FAILED(hres)) + return hres; + + if(is_jsdisp(jsthis)) { + result = jsdisp_is_own_prop(jsthis->u.jsdisp, name); + if(retv) { + V_VT(retv) = VT_BOOL; + V_BOOL(retv) = result; + } + + return S_OK; + } else if(is_dispex(jsthis)) { + hres = IDispatchEx_GetDispID(jsthis->u.dispex, name, + make_grfdex(ctx, fdexNameCaseSensitive), &id); + } else { + hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL, + &name, 1, ctx->lcid, &id); + } + + if(retv) { + V_VT(retv) = VT_BOOL; + V_BOOL(retv) = SUCCEEDED(hres) ? VARIANT_TRUE : VARIANT_FALSE; + } + return S_OK; }
static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index c5f0c4f..09c3360 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1864,11 +1864,22 @@ ok(err.message === 4, "err.message = " + err.message); ok(!("number" in Error), "number is in Error");
tmp = new Object(); +ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited"); tmp.toString = function() { return "test"; }; +ok(tmp.hasOwnProperty("toString") === true, "toString own property should exist"); +ok(tmp.hasOwnProperty("nonExisting") === false, "nonExisting property should not exist");
tmp = Error.prototype.toString.call(tmp); ok(tmp === "[object Error]", "Error.prototype.toString.call(tmp) = " + tmp);
+tmp = function() { return 0; }; +tmp[0] = true; +ok(tmp.hasOwnProperty("toString") === false, "toString property should be inherited"); +ok(tmp.hasOwnProperty("0") === true, "hasOwnProperty(0) returned false"); +ok(tmp.hasOwnProperty() === false, "hasOwnProperty() returned true"); + +ok(Object.prototype.hasOwnProperty.call(testObj) === false, "hasOwnProperty without name returned true"); + if(invokeVersion >= 2) { obj = new Object(); obj.name = "test"; diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 88c69ef..fbbff96 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -64,6 +64,8 @@ DEFINE_EXPECT(global_propput_i); DEFINE_EXPECT(global_success_d); DEFINE_EXPECT(global_success_i); DEFINE_EXPECT(global_notexists_d); +DEFINE_EXPECT(puredisp_prop_d); +DEFINE_EXPECT(puredisp_noprop_d); DEFINE_EXPECT(testobj_delete); DEFINE_EXPECT(testobj_value); DEFINE_EXPECT(testobj_prop_d); @@ -173,6 +175,18 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { + ok(IsEqualGUID(riid, &IID_NULL), "Expected IID_NULL\n"); + ok(cNames==1, "cNames = %d\n", cNames); + + if(!strcmp_wa(*rgszNames, "prop")) { + CHECK_EXPECT(puredisp_prop_d); + *rgDispId = DISPID_TESTOBJ_PROP; + return S_OK; + } else if(!strcmp_wa(*rgszNames, "noprop")) { + CHECK_EXPECT(puredisp_noprop_d); + return DISP_E_UNKNOWNNAME; + } + ok(0, "unexpected call\n"); return E_NOTIMPL; } @@ -1476,6 +1490,22 @@ static void run_tests(void) parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');"); CHECK_CALLED(testobj_noprop_d);
+ SET_EXPECT(testobj_prop_d); + parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'prop') === true, 'hasOwnProperty(\"prop\") returned false');"); + CHECK_CALLED(testobj_prop_d); + + SET_EXPECT(testobj_noprop_d); + parse_script_a("ok(Object.prototype.hasOwnProperty.call(testObj, 'noprop') === false, 'hasOwnProperty(\"noprop\") returned true');"); + CHECK_CALLED(testobj_noprop_d); + + SET_EXPECT(puredisp_prop_d); + parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'prop') === true, 'hasOwnProperty(\"noprop\") returned false');"); + CHECK_CALLED(puredisp_prop_d); + + SET_EXPECT(puredisp_noprop_d); + parse_script_a("ok(Object.prototype.hasOwnProperty.call(pureDisp, 'noprop') === false, 'hasOwnProperty(\"noprop\") returned true');"); + CHECK_CALLED(puredisp_noprop_d); + SET_EXPECT(testobj_value); parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');"); CHECK_CALLED(testobj_value);