mshtml/tests: Add initial tests for NULL Dispatch objects in scripts.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3349dc5eea
commit
3485f162e9
|
@ -1322,6 +1322,64 @@ sync_test("builtins_diffs", function() {
|
|||
}
|
||||
});
|
||||
|
||||
sync_test("nullDisp", function() {
|
||||
var v = document.documentMode, nullDisp = external.nullDisp, r;
|
||||
|
||||
todo_wine.
|
||||
ok(external.getVT(nullDisp) === "VT_NULL", "getVT(nullDisp) is not VT_NULL");
|
||||
ok(typeof(nullDisp) === "object", "typeof(nullDisp) = " + typeof(nullDisp));
|
||||
ok(nullDisp === nullDisp, "nullDisp !== nullDisp");
|
||||
ok(nullDisp === null, "nullDisp === null");
|
||||
ok(nullDisp == null, "nullDisp == null");
|
||||
ok(!nullDisp === true, "!nullDisp = " + !nullDisp);
|
||||
ok(String(nullDisp) === "null", "String(nullDisp) = " + String(nullDisp));
|
||||
ok(+nullDisp === 0, "+nullDisp !== 0");
|
||||
ok(''+nullDisp === "null", "''+nullDisp !== null");
|
||||
ok(nullDisp != new Object(), "nullDisp == new Object()");
|
||||
ok(new Object() != nullDisp, "new Object() == nullDisp");
|
||||
ok((typeof Object(nullDisp)) === "object", "typeof Object(nullDisp) !== 'object'");
|
||||
r = Object(nullDisp).toString();
|
||||
ok(r === "[object Object]", "Object(nullDisp).toString() = " + r);
|
||||
ok(Object(nullDisp) != nullDisp, "Object(nullDisp) == nullDisp");
|
||||
ok(new Object(nullDisp) != nullDisp, "new Object(nullDisp) == nullDisp");
|
||||
|
||||
if(v >= 8) {
|
||||
r = JSON.stringify.call(null, nullDisp);
|
||||
todo_wine.
|
||||
ok(r === "null", "JSON.stringify(nullDisp) returned " + r);
|
||||
}
|
||||
|
||||
try {
|
||||
(new Object()) instanceof nullDisp;
|
||||
ok(false, "expected exception on (new Object()) instanceof nullDisp");
|
||||
}catch(e) {
|
||||
ok(e.number === 0xa138a - 0x80000000, "(new Object()) instanceof nullDisp threw " + e.number);
|
||||
}
|
||||
|
||||
try {
|
||||
Function.prototype.apply.call(nullDisp, Object, []);
|
||||
ok(false, "expected exception calling Function.apply on nullDisp");
|
||||
}catch(e) {
|
||||
todo_wine.
|
||||
ok(e.number === 0xa138a - 0x80000000, "Function.apply on nullDisp threw " + e.number);
|
||||
}
|
||||
try {
|
||||
Function.prototype.call.call(nullDisp, Object);
|
||||
ok(false, "expected exception calling Function.call on nullDisp");
|
||||
}catch(e) {
|
||||
todo_wine.
|
||||
ok(e.number === 0xa138a - 0x80000000, "Function.call on nullDisp threw " + e.number);
|
||||
}
|
||||
|
||||
try {
|
||||
new nullDisp;
|
||||
ok(false, "expected exception for new nullDisp");
|
||||
}catch(e) {
|
||||
todo_wine.
|
||||
ok(e.number === 0xa138f - 0x80000000, "new nullDisp threw " + e.number);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("__proto__", function() {
|
||||
var v = document.documentMode;
|
||||
var r, x = 42;
|
||||
|
|
|
@ -298,9 +298,25 @@ sync_test("getOwnPropertyDescriptor", function() {
|
|||
test_own_data_prop_desc(function(){}, "prototype", true, false, false);
|
||||
test_own_data_prop_desc(Function, "prototype", false, false, false);
|
||||
test_own_data_prop_desc(String.prototype, "constructor", true, false, true);
|
||||
|
||||
try {
|
||||
Object.getOwnPropertyDescriptor(null, "prototype");
|
||||
ok(false, "expected exception with null");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "with null context threw " + n);
|
||||
}
|
||||
try {
|
||||
Object.getOwnPropertyDescriptor(external.nullDisp, "prototype");
|
||||
ok(false, "expected exception calling getOwnPropertyDescriptor(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "getOwnPropertyDescriptor(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("defineProperty", function() {
|
||||
var nullDisp = external.nullDisp;
|
||||
function test_accessor_prop_desc(obj, prop, orig_desc) {
|
||||
var expected_enumerable = "enumerable" in orig_desc && !!orig_desc.enumerable;
|
||||
var expected_configurable = "configurable" in orig_desc && !!orig_desc.configurable;
|
||||
|
@ -548,6 +564,16 @@ sync_test("defineProperty", function() {
|
|||
Object.defineProperty(obj, "funcprop", desc);
|
||||
test_accessor_prop_desc(obj, "funcprop", desc);
|
||||
ok(obj.funcprop(100) === 10, "obj.funcprop() = " + obj.funcprop(100));
|
||||
|
||||
expect_exception(function() {
|
||||
Object.defineProperty(null, "funcprop", desc);
|
||||
}, JS_E_OBJECT_EXPECTED);
|
||||
expect_exception(function() {
|
||||
Object.defineProperty(nullDisp, "funcprop", desc);
|
||||
}, JS_E_OBJECT_EXPECTED);
|
||||
expect_exception(function() {
|
||||
Object.defineProperty(obj, "funcprop", nullDisp);
|
||||
}, JS_E_OBJECT_EXPECTED);
|
||||
});
|
||||
|
||||
sync_test("defineProperties", function() {
|
||||
|
@ -831,6 +857,13 @@ sync_test("getPrototypeOf", function() {
|
|||
ok(Object.getPrototypeOf(obj) === null, "Object.getPrototypeOf(obj) = " + Object.getPrototypeOf(obj));
|
||||
|
||||
ok(Object.getPrototypeOf(external) === null, "Object.getPrototypeOf(non-JS obj) = " + Object.getPrototypeOf(external));
|
||||
try {
|
||||
Object.getOwnPropertyDescriptor(external.nullDisp);
|
||||
ok(false, "expected exception calling getOwnPropertyDescriptor(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "getOwnPropertyDescriptor(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("toString", function() {
|
||||
|
@ -956,6 +989,14 @@ sync_test("keys", function() {
|
|||
ok(keys === "", "keys([]) = " + keys);
|
||||
|
||||
ok(Object.keys.length === 1, "Object.keys.length = " + Object.keys.length);
|
||||
|
||||
try {
|
||||
Object.keys(external.nullDisp);
|
||||
ok(false, "expected exception calling keys(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "keys(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("getOwnPropertyNames", function() {
|
||||
|
@ -980,6 +1021,14 @@ sync_test("getOwnPropertyNames", function() {
|
|||
ok(names === "length", "names = " + names);
|
||||
|
||||
ok(Object.getOwnPropertyNames.length === 1, "Object.getOwnPropertyNames.length = " + Object.getOwnPropertyNames.length);
|
||||
|
||||
try {
|
||||
Object.getOwnPropertyNames(external.nullDisp);
|
||||
ok(false, "expected exception calling getOwnPropertyNames(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "getOwnPropertyNames(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("reduce", function() {
|
||||
|
@ -1091,6 +1140,14 @@ sync_test("preventExtensions", function() {
|
|||
|
||||
ok(Object.preventExtensions.length === 1, "Object.preventExtensions.length = " + Object.preventExtensions.length);
|
||||
ok(Object.isExtensible.length === 1, "Object.isExtensible.length = " + Object.isExtensible.length);
|
||||
|
||||
try {
|
||||
Object.preventExtensions(external.nullDisp);
|
||||
ok(false, "expected exception calling preventExtensions(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "preventExtensions(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("freeze", function() {
|
||||
|
@ -1143,6 +1200,14 @@ sync_test("freeze", function() {
|
|||
}
|
||||
ok(o[0] === 1, "o[0] = " + o[0]);
|
||||
ok(o.length === 1, "o.length = " + o.length);
|
||||
|
||||
try {
|
||||
Object.freeze(external.nullDisp);
|
||||
ok(false, "expected exception freeze(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "freeze(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("seal", function() {
|
||||
|
@ -1195,9 +1260,18 @@ sync_test("seal", function() {
|
|||
}
|
||||
ok(o[0] === 1, "o[0] = " + o[0]);
|
||||
ok(o.length === 1, "o.length = " + o.length);
|
||||
|
||||
try {
|
||||
Object.seal(external.nullDisp);
|
||||
ok(false, "expected exception calling seal(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "seal(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("isFrozen", function() {
|
||||
var nullDisp = external.nullDisp;
|
||||
ok(Object.isFrozen.length === 1, "Object.isFrozen.length = " + Object.isFrozen.length);
|
||||
ok(Object.isSealed.length === 1, "Object.isSealed.length = " + Object.isSealed.length);
|
||||
|
||||
|
@ -1263,6 +1337,28 @@ sync_test("isFrozen", function() {
|
|||
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||
|
||||
try {
|
||||
Object.isFrozen(nullDisp);
|
||||
ok(false, "expected exception calling isFrozen(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "isFrozen(nullDisp) threw " + n);
|
||||
}
|
||||
try {
|
||||
Object.isSealed(nullDisp);
|
||||
ok(false, "expected exception calling isSealed(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "isSealed(nullDisp) threw " + n);
|
||||
}
|
||||
try {
|
||||
Object.isExtensible(nullDisp);
|
||||
ok(false, "expected exception calling isExtensible(nullDisp)");
|
||||
}catch(ex) {
|
||||
var n = ex.number >>> 0;
|
||||
ok(n === JS_E_OBJECT_EXPECTED, "isExtensible(nullDisp) threw " + n);
|
||||
}
|
||||
});
|
||||
|
||||
sync_test("builtin_context", function() {
|
||||
|
|
|
@ -151,6 +151,8 @@ DEFINE_EXPECT(GetTypeInfo);
|
|||
#define DISPID_EXTERNAL_BROKEN 0x300004
|
||||
#define DISPID_EXTERNAL_WIN_SKIP 0x300005
|
||||
#define DISPID_EXTERNAL_WRITESTREAM 0x300006
|
||||
#define DISPID_EXTERNAL_GETVT 0x300007
|
||||
#define DISPID_EXTERNAL_NULL_DISP 0x300008
|
||||
|
||||
static const GUID CLSID_TestScript =
|
||||
{0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
|
||||
|
@ -589,6 +591,14 @@ static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName,
|
|||
*pid = DISPID_EXTERNAL_WRITESTREAM;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"getVT")) {
|
||||
*pid = DISPID_EXTERNAL_GETVT;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"nullDisp")) {
|
||||
*pid = DISPID_EXTERNAL_NULL_DISP;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
@ -716,6 +726,64 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID
|
|||
stream_write(V_BSTR(pdp->rgvarg+1), V_BSTR(pdp->rgvarg));
|
||||
return S_OK;
|
||||
|
||||
case DISPID_EXTERNAL_GETVT:
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||
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 != NULL, "pvarRes == NULL\n");
|
||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
|
||||
V_VT(pvarRes) = VT_BSTR;
|
||||
switch(V_VT(pdp->rgvarg)) {
|
||||
case VT_EMPTY:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_EMPTY");
|
||||
break;
|
||||
case VT_NULL:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_NULL");
|
||||
break;
|
||||
case VT_I4:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_I4");
|
||||
break;
|
||||
case VT_R8:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_R8");
|
||||
break;
|
||||
case VT_BSTR:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_BSTR");
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_DISPATCH");
|
||||
break;
|
||||
case VT_BOOL:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_BOOL");
|
||||
break;
|
||||
case VT_DATE:
|
||||
V_BSTR(pvarRes) = SysAllocString(L"VT_DATE");
|
||||
break;
|
||||
default:
|
||||
ok(0, "unknown vt %d\n", V_VT(pdp->rgvarg));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
case DISPID_EXTERNAL_NULL_DISP:
|
||||
ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(!pdp->rgvarg, "rgvarg != NULL\n");
|
||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||
ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
|
||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = NULL;
|
||||
return S_OK;
|
||||
|
||||
default:
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
|
|
Loading…
Reference in New Issue