mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
mshtml/tests: Add tests for WeakMap.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
1b14d7b46d
commit
62cee99658
2 changed files with 340 additions and 0 deletions
|
@ -470,6 +470,8 @@ sync_test("window_props", function() {
|
|||
test_exposed("requestAnimationFrame", v >= 10);
|
||||
test_exposed("Map", v >= 11);
|
||||
test_exposed("Set", v >= 11);
|
||||
test_exposed("WeakMap", v >= 11);
|
||||
test_exposed("WeakSet", false);
|
||||
test_exposed("performance", true);
|
||||
test_exposed("console", v >= 10);
|
||||
test_exposed("matchMedia", v >= 10);
|
||||
|
@ -1608,6 +1610,134 @@ sync_test("map_obj", function() {
|
|||
ok(r === 1, "r = " + r);
|
||||
});
|
||||
|
||||
async_test("weakmap_obj", function() {
|
||||
if(!("WeakMap" in window)) { next_test(); return; }
|
||||
|
||||
try {
|
||||
var s = WeakMap();
|
||||
ok(false, "expected exception calling constructor as method");
|
||||
}catch(e) {
|
||||
ok(e.number === 0xa13fc - 0x80000000, "calling constructor as method threw " + e.number);
|
||||
}
|
||||
|
||||
var s = new WeakMap, r, o, o2;
|
||||
ok(Object.getPrototypeOf(s) === WeakMap.prototype, "unexpected WeakMap prototype");
|
||||
|
||||
function test_length(name, len) {
|
||||
ok(WeakMap.prototype[name].length === len, "WeakMap.prototype." + name + " = " + WeakMap.prototype[name].length);
|
||||
}
|
||||
test_length("clear", 0);
|
||||
test_length("delete", 1);
|
||||
test_length("get", 1);
|
||||
test_length("has", 1);
|
||||
test_length("set", 2);
|
||||
ok(!("entries" in s), "entries is in WeakMap");
|
||||
ok(!("forEach" in s), "forEach is in WeakMap");
|
||||
ok(!("keys" in s), "keys is in WeakMap");
|
||||
ok(!("size" in s), "size is in WeakMap");
|
||||
ok(!("values" in s), "values is in WeakMap");
|
||||
|
||||
r = Object.prototype.toString.call(s);
|
||||
ok(r === "[object Object]", "toString returned " + r);
|
||||
|
||||
r = s.get("test");
|
||||
ok(r === undefined, "get('test') returned " + r);
|
||||
r = s.has("test");
|
||||
ok(r === false, "has('test') returned " + r);
|
||||
|
||||
try {
|
||||
r = s.set("test", 1);
|
||||
ok(false, "set('test') did not throw");
|
||||
}catch(e) {
|
||||
ok(e.number === 0xa13fd - 0x80000000, "set('test') threw " + e.number);
|
||||
}
|
||||
try {
|
||||
r = s.set(external.testHostContext(true), 1);
|
||||
ok(false, "set(host_obj) did not throw");
|
||||
}catch(e) {
|
||||
ok(e.number === 0xa13fd - 0x80000000, "set(host_obj) threw " + e.number);
|
||||
}
|
||||
|
||||
r = s.set({}, 1);
|
||||
ok(r === undefined, "set({}, 1) returned " + r);
|
||||
|
||||
o = {}, o2 = {};
|
||||
r = s.get({});
|
||||
ok(r === undefined, "get({}) returned " + r);
|
||||
r = s.has({});
|
||||
ok(r === false, "has({}) returned " + r);
|
||||
|
||||
r = s.set(o, 2);
|
||||
ok(r === undefined, "set(o, 2) returned " + r);
|
||||
r = s.get(o);
|
||||
ok(r === 2, "get(o) returned " + r);
|
||||
r = s.has(o);
|
||||
ok(r === true, "has(o) returned " + r);
|
||||
r = s.get(o2);
|
||||
ok(r === undefined, "get(o2) before set returned " + r);
|
||||
r = s.has(o2);
|
||||
ok(r === false, "has(o2) before set returned " + r);
|
||||
r = s.set(o2, "test");
|
||||
ok(r === undefined, "set(o2, 'test') returned " + r);
|
||||
r = s.get(o2);
|
||||
ok(r === "test", "get(o2) returned " + r);
|
||||
r = s.has(o2);
|
||||
ok(r === true, "has(o2) returned " + r);
|
||||
|
||||
r = s["delete"]("test"); /* using s.delete() would break parsing in quirks mode */
|
||||
ok(r === false, "delete('test') returned " + r);
|
||||
r = s["delete"]({});
|
||||
ok(r === false, "delete({}) returned " + r);
|
||||
r = s["delete"](o);
|
||||
ok(r === true, "delete(o) returned " + r);
|
||||
|
||||
r = s.get(o);
|
||||
ok(r === undefined, "get(o) after delete returned " + r);
|
||||
r = s.has(o);
|
||||
ok(r === false, "has(o) after delete returned " + r);
|
||||
r = s.get(o2);
|
||||
ok(r === "test", "get(o2) after delete returned " + r);
|
||||
r = s.has(o2);
|
||||
ok(r === true, "has(o2) after delete returned " + r);
|
||||
|
||||
r = s.set(o, undefined);
|
||||
ok(r === undefined, "set(o, undefined) returned " + r);
|
||||
r = s.get(o);
|
||||
ok(r === undefined, "get(o) after re-set returned " + r);
|
||||
r = s.has(o);
|
||||
ok(r === true, "has(o) after re-set returned " + r);
|
||||
|
||||
r = s.clear();
|
||||
ok(r === undefined, "clear() returned " + r);
|
||||
r = s.get(o);
|
||||
ok(r === undefined, "get(o) after clear returned " + r);
|
||||
r = s.has(o);
|
||||
ok(r === false, "has(o) after clear returned " + r);
|
||||
r = s.get(o2);
|
||||
ok(r === undefined, "get(o2) after clear returned " + r);
|
||||
r = s.has(o2);
|
||||
ok(r === false, "has(o2) after clear returned " + r);
|
||||
|
||||
r = external.newRefTest();
|
||||
ok(r.ref === 1, "wrong ref after newRefTest: " + r.ref);
|
||||
o = { val: r.get(), map: s };
|
||||
s.set(o, o);
|
||||
ok(r.ref > 1, "map entry released");
|
||||
|
||||
o = Date.now();
|
||||
CollectGarbage();
|
||||
function retry() {
|
||||
if(r.ref > 1 && Date.now() - o < 5000) {
|
||||
CollectGarbage();
|
||||
window.setTimeout(retry);
|
||||
return;
|
||||
}
|
||||
ok(r.ref === 1, "map entry not released");
|
||||
next_test();
|
||||
}
|
||||
window.setTimeout(retry);
|
||||
});
|
||||
|
||||
sync_test("storage", function() {
|
||||
var v = document.documentMode, i, r, list;
|
||||
|
||||
|
|
|
@ -155,6 +155,8 @@ DEFINE_EXPECT(GetTypeInfo);
|
|||
|
||||
#define DISPID_SCRIPT_TESTPROP 0x100000
|
||||
#define DISPID_SCRIPT_TESTPROP2 0x100001
|
||||
#define DISPID_REFTEST_GET 0x100000
|
||||
#define DISPID_REFTEST_REF 0x100001
|
||||
|
||||
#define DISPID_EXTERNAL_OK 0x300000
|
||||
#define DISPID_EXTERNAL_TRACE 0x300001
|
||||
|
@ -171,6 +173,7 @@ DEFINE_EXPECT(GetTypeInfo);
|
|||
#define DISPID_EXTERNAL_TESTHOSTCTX 0x30000C
|
||||
#define DISPID_EXTERNAL_GETMIMETYPE 0x30000D
|
||||
#define DISPID_EXTERNAL_SETVIEWSIZE 0x30000E
|
||||
#define DISPID_EXTERNAL_NEWREFTEST 0x30000F
|
||||
|
||||
static const GUID CLSID_TestScript[] = {
|
||||
{0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}},
|
||||
|
@ -641,6 +644,13 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
|
@ -840,6 +850,181 @@ static IDispatchExVtbl testHostContextDisp_no_this_vtbl = {
|
|||
|
||||
static IDispatchEx testHostContextDisp_no_this = { &testHostContextDisp_no_this_vtbl };
|
||||
|
||||
struct refTestObj
|
||||
{
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
LONG ref;
|
||||
};
|
||||
|
||||
struct refTest
|
||||
{
|
||||
IDispatchEx IDispatchEx_iface;
|
||||
LONG ref;
|
||||
struct refTestObj *obj;
|
||||
};
|
||||
|
||||
static inline struct refTestObj *refTestObj_from_IDispatchEx(IDispatchEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct refTestObj, IDispatchEx_iface);
|
||||
}
|
||||
|
||||
static inline struct refTest *refTest_from_IDispatchEx(IDispatchEx *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct refTest, IDispatchEx_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI refTestObj_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
struct refTestObj *This = refTestObj_from_IDispatchEx(iface);
|
||||
|
||||
if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx))
|
||||
*ppv = &This->IDispatchEx_iface;
|
||||
else {
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IDispatchEx_AddRef(&This->IDispatchEx_iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI refTestObj_AddRef(IDispatchEx *iface)
|
||||
{
|
||||
struct refTestObj *This = refTestObj_from_IDispatchEx(iface);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI refTestObj_Release(IDispatchEx *iface)
|
||||
{
|
||||
struct refTestObj *This = refTestObj_from_IDispatchEx(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if(!ref)
|
||||
free(This);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl refTestObj_vtbl = {
|
||||
refTestObj_QueryInterface,
|
||||
refTestObj_AddRef,
|
||||
refTestObj_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
DispatchEx_GetDispID,
|
||||
DispatchEx_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static HRESULT WINAPI refTest_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
struct refTest *This = refTest_from_IDispatchEx(iface);
|
||||
|
||||
if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx))
|
||||
*ppv = &This->IDispatchEx_iface;
|
||||
else {
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IDispatchEx_AddRef(&This->IDispatchEx_iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI refTest_AddRef(IDispatchEx *iface)
|
||||
{
|
||||
struct refTest *This = refTest_from_IDispatchEx(iface);
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI refTest_Release(IDispatchEx *iface)
|
||||
{
|
||||
struct refTest *This = refTest_from_IDispatchEx(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if(!ref) {
|
||||
IDispatchEx_Release(&This->obj->IDispatchEx_iface);
|
||||
free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI refTest_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
if(!wcscmp(bstrName, L"get")) {
|
||||
*pid = DISPID_REFTEST_GET;
|
||||
return S_OK;
|
||||
}
|
||||
if(!wcscmp(bstrName, L"ref")) {
|
||||
*pid = DISPID_REFTEST_REF;
|
||||
return S_OK;
|
||||
}
|
||||
ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI refTest_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
struct refTest *This = refTest_from_IDispatchEx(iface);
|
||||
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(!pdp->cArgs, "pdp->cArgs = %d\n", pdp->cArgs);
|
||||
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||
ok(pei != NULL, "pei == NULL\n");
|
||||
ok(pspCaller != NULL, "pspCaller == NULL\n");
|
||||
|
||||
switch(id) {
|
||||
case DISPID_REFTEST_GET: {
|
||||
ok(wFlags == DISPATCH_METHOD, "DISPID_REFTEST_GET wFlags = %x\n", wFlags);
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = (IDispatch*)&This->obj->IDispatchEx_iface;
|
||||
IDispatchEx_AddRef(&This->obj->IDispatchEx_iface);
|
||||
break;
|
||||
}
|
||||
case DISPID_REFTEST_REF:
|
||||
ok(wFlags == DISPATCH_PROPERTYGET, "DISPID_REFTEST_REF wFlags = %x\n", wFlags);
|
||||
V_VT(pvarRes) = VT_I4;
|
||||
V_I4(pvarRes) = This->obj->ref;
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(0, "id = %ld", id);
|
||||
V_VT(pvarRes) = VT_EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IDispatchExVtbl refTest_vtbl = {
|
||||
refTest_QueryInterface,
|
||||
refTest_AddRef,
|
||||
refTest_Release,
|
||||
DispatchEx_GetTypeInfoCount,
|
||||
DispatchEx_GetTypeInfo,
|
||||
DispatchEx_GetIDsOfNames,
|
||||
DispatchEx_Invoke,
|
||||
refTest_GetDispID,
|
||||
refTest_InvokeEx,
|
||||
DispatchEx_DeleteMemberByName,
|
||||
DispatchEx_DeleteMemberByDispID,
|
||||
DispatchEx_GetMemberProperties,
|
||||
DispatchEx_GetMemberName,
|
||||
DispatchEx_GetNextDispID,
|
||||
DispatchEx_GetNameSpaceParent
|
||||
};
|
||||
|
||||
static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
if(!lstrcmpW(bstrName, L"ok")) {
|
||||
|
@ -902,6 +1087,10 @@ static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName,
|
|||
*pid = DISPID_EXTERNAL_SETVIEWSIZE;
|
||||
return S_OK;
|
||||
}
|
||||
if(!lstrcmpW(bstrName, L"newRefTest")) {
|
||||
*pid = DISPID_EXTERNAL_NEWREFTEST;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
@ -1180,6 +1369,27 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID
|
|||
return IOleDocumentView_SetRect(view, &rect);
|
||||
}
|
||||
|
||||
case DISPID_EXTERNAL_NEWREFTEST: {
|
||||
struct refTest *obj = malloc(sizeof(*obj));
|
||||
|
||||
ok(pdp != NULL, "pdp == NULL\n");
|
||||
ok(pdp->rgvarg != NULL, "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(pei != NULL, "pei == NULL\n");
|
||||
|
||||
obj->IDispatchEx_iface.lpVtbl = &refTest_vtbl;
|
||||
obj->ref = 1;
|
||||
obj->obj = malloc(sizeof(*obj->obj));
|
||||
obj->obj->IDispatchEx_iface.lpVtbl = &refTestObj_vtbl;
|
||||
obj->obj->ref = 1;
|
||||
|
||||
V_VT(pvarRes) = VT_DISPATCH;
|
||||
V_DISPATCH(pvarRes) = (IDispatch*)&obj->IDispatchEx_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
default:
|
||||
ok(0, "unexpected call\n");
|
||||
return E_NOTIMPL;
|
||||
|
|
Loading…
Reference in a new issue