return (IDispatch*)&event->lpVtbl;
}
+#define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
+static void _expect_children(IXMLDOMNode *node, int line)
+{
+ VARIANT_BOOL b;
+ HRESULT hr;
+
+ b = VARIANT_FALSE;
+ hr = IXMLDOMNode_hasChildNodes(node, &b);
+ ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
+ ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
+}
+
+#define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
+static void _expect_no_children(IXMLDOMNode *node, int line)
+{
+ VARIANT_BOOL b;
+ HRESULT hr;
+
+ b = VARIANT_TRUE;
+ hr = IXMLDOMNode_hasChildNodes(node, &b);
+ ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
+ ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
+}
+
+#define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
+static void _expect_ref(IUnknown* obj, ULONG ref, int line)
+{
+ ULONG rc = IUnknown_AddRef(obj);
+ IUnknown_Release(obj);
+ ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
+}
static const WCHAR szEmpty[] = { 0 };
static const WCHAR szIncomplete[] = {
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
- b = 1;
- r = IXMLDOMNode_hasChildNodes( doc, &b );
- ok( r == S_OK, "hasChildNoes bad return\n");
- ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
+ EXPECT_CHILDREN(doc);
r = IXMLDOMDocument_get_documentElement( doc, &element );
ok( r == S_OK, "should be a document element\n");
ok( r == S_OK, "get_attributes returned wrong code\n");
ok( map != NULL, "should be attributes\n");
- b = 1;
- r = IXMLDOMNode_hasChildNodes( element, &b );
- ok( r == S_OK, "hasChildNoes bad return\n");
- ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
+ EXPECT_CHILDREN(element);
}
else
ok( FALSE, "no element\n");
if (next)
{
- b = 1;
- r = IXMLDOMNode_hasChildNodes( next, &b );
- ok( r == S_FALSE, "hasChildNoes bad return\n");
- ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
+ EXPECT_NO_CHILDREN(next);
type = NODE_INVALID;
r = IXMLDOMNode_get_nodeType( next, &type);
r = IXMLDOMNode_hasChildNodes( node, NULL );
ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
- b = 1;
- r = IXMLDOMNode_hasChildNodes( node, &b );
- ok( r == S_OK, "hasChildNoes bad return\n");
- ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
+ EXPECT_CHILDREN(node);
str = NULL;
r = IXMLDOMNode_get_baseName( node, &str );
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
- b = 1;
- r = IXMLDOMNode_hasChildNodes( doc, &b );
- ok( r == S_OK, "hasChildNoes bad return\n");
- ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
+ EXPECT_CHILDREN(doc);
r = IXMLDOMDocument_get_documentElement( doc, &element );
ok( r == S_OK, "should be a document element\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
- ref = IXMLDOMDocument_AddRef( doc );
- ok( ref == 2, "ref %d\n", ref );
- ref = IXMLDOMDocument_AddRef( doc );
- ok( ref == 3, "ref %d\n", ref );
+ IXMLDOMDocument_AddRef( doc );
+ EXPECT_REF(doc, 2);
+ IXMLDOMDocument_AddRef( doc );
+ EXPECT_REF(doc, 3);
+
IXMLDOMDocument_Release( doc );
IXMLDOMDocument_Release( doc );
ok( r == S_OK, "should be a document element\n");
ok( element != NULL, "should be an element\n");
- ref = IXMLDOMDocument_AddRef( doc );
- ok( ref == 2, "ref %d\n", ref );
- IXMLDOMDocument_Release( doc );
+ EXPECT_REF(doc, 1);
r = IXMLDOMElement_get_childNodes( element, &node_list );
ok( r == S_OK, "rets %08x\n", r);
- ref = IXMLDOMNodeList_AddRef( node_list );
- ok( ref == 2, "ref %d\n", ref );
- IXMLDOMNodeList_Release( node_list );
+ EXPECT_REF(node_list, 1);
IXMLDOMNodeList_get_item( node_list, 0, &node );
ok( r == S_OK, "rets %08x\n", r);
IXMLDOMNodeList_get_item( node_list, 0, &node2 );
ok( r == S_OK, "rets %08x\n", r);
- ref = IXMLDOMNode_AddRef( node );
- ok( ref == 2, "ref %d\n", ref );
- IXMLDOMNode_Release( node );
+ EXPECT_REF(node, 1);
ref = IXMLDOMNode_Release( node );
ok( ref == 0, "ref %d\n", ref );
ref = IXMLDOMDocument_Release( doc );
ok( ref == 0, "ref %d\n", ref );
- ref = IXMLDOMElement_AddRef( element );
- todo_wine {
- ok( ref == 3, "ref %d\n", ref );
- }
- IXMLDOMElement_Release( element );
+ todo_wine EXPECT_REF(element, 2);
/* IUnknown must be unique however we obtain it */
r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (void**)&unk );
ok( r == S_OK, "returns %08x\n", r );
ok( node == root, "%p %p\n", node, root );
- ref = IXMLDOMNode_AddRef( node );
- ok(ref == 3, "ref %d\n", ref);
- IXMLDOMNode_Release( node );
+ EXPECT_REF(node, 2);
ref = IXMLDOMNode_Release( node );
ok(ref == 1, "ref %d\n", ref);
ok( r == S_OK, "returns %08x\n", r );
SysFreeString( str );
- ref = IXMLDOMNode_AddRef( node );
- ok(ref == 2, "ref = %d\n", ref);
- IXMLDOMNode_Release( node );
+ EXPECT_REF(node, 1);
r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
ok( r == S_OK, "returns %08x\n", r );
- ref = IXMLDOMNode_AddRef( unk );
- ok(ref == 3, "ref = %d\n", ref);
- IXMLDOMNode_Release( unk );
+ EXPECT_REF(unk, 2);
V_VT(&var) = VT_EMPTY;
child = NULL;
ok( r == S_OK, "returns %08x\n", r );
ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
- ref = IXMLDOMNode_AddRef( unk );
- todo_wine ok(ref == 5, "ref = %d\n", ref);
- IXMLDOMNode_Release( unk );
+ todo_wine EXPECT_REF(unk, 4);
IXMLDOMNode_Release( child );
IUnknown_Release( unk );
VARIANT dummy;
VARIANT async;
VARIANT varbody;
- LONG state, status, ref, bound;
+ LONG state, status, bound;
void *ptr;
IDispatch *event;
HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
event = create_dispevent();
- ref = IDispatch_AddRef(event);
- ok(ref == 2, "got %d\n", ref);
- IDispatch_Release(event);
+ EXPECT_REF(event, 1);
hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, event);
ok(hr == S_OK, "got 0x%08x\n", hr);
-
- ref = IDispatch_AddRef(event);
- ok(ref == 3, "got %d\n", ref);
- IDispatch_Release(event);
+ EXPECT_REF(event, 2);
g_unexpectedcall = g_expectedcall = 0;
VARIANT_BOOL b;
VARIANT var;
HRESULT r;
- LONG ref, res;
+ LONG res;
BSTR str;
doc = create_document(&IID_IXMLDOMDocument);
}
/* we will check if the variant got cleared */
- ref = IXMLDOMDocument2_AddRef(doc2);
- expect_eq(ref, 3, int, "%d"); /* doc, doc2, AddRef*/
+ IXMLDOMDocument2_AddRef(doc2);
+ EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
+
V_VT(&var) = VT_UNKNOWN;
V_UNKNOWN(&var) = (IUnknown *)doc2;
IXMLDOMElement_Release(elem);
ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
- b = VARIANT_FALSE;
- hr = IXMLDOMElement_hasChildNodes(elem, &b);
- ok( hr == S_OK, "got 0x%08x\n", hr);
- ok(b == VARIANT_TRUE, "got %d\n", b);
+ EXPECT_CHILDREN(elem);
+ EXPECT_CHILDREN(elem2);
- b = VARIANT_FALSE;
- hr = IXMLDOMElement_hasChildNodes(elem2, &b);
- ok( hr == S_OK, "got 0x%08x\n", hr);
- ok(b == VARIANT_TRUE, "got %d\n", b);
IXMLDOMElement_Release(elem2);
attr2 = NULL;
VARIANT v, var;
BSTR prefix, str;
HRESULT hr;
+ ULONG ref;
doc = create_document(&IID_IXMLDOMDocument);
if (!doc) return;
+ /* reference count tests */
+ hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
+ ok( hr == S_OK, "got 0x%08x\n", hr);
+
+ /* initial reference is 2 */
+todo_wine {
+ EXPECT_REF(elem, 2);
+ ref = IXMLDOMElement_Release(elem);
+ ok(ref == 1, "got %d\n", ref);
+ /* it's released already, attempt to release now will crash it */
+}
+
/* NODE_ELEMENT nodes */
/* 1. specified namespace */
V_VT(&v) = VT_I4;
HRESULT hr;
VARIANT v;
IDispatch *event;
- ULONG ref;
doc = create_document(&IID_IXMLDOMDocument);
if (!doc) return;
hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
ok(hr == S_OK, "got 0x%08x\n", hr);
- ref = IDispatch_AddRef(event);
- IDispatch_Release(event);
- ok(ref == 3, "got %d\n", ref);
+ EXPECT_REF(event, 2);
V_VT(&v) = VT_DISPATCH;
V_DISPATCH(&v) = event;
hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
ok(hr == S_OK, "got 0x%08x\n", hr);
- ref = IDispatch_AddRef(event);
- IDispatch_Release(event);
- ok(ref == 3, "got %d\n", ref);
+ EXPECT_REF(event, 2);
/* VT_NULL doesn't reset event handler */
V_VT(&v) = VT_NULL;
hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
- ref = IDispatch_AddRef(event);
- IDispatch_Release(event);
- ok(ref == 3, "got %d\n", ref);
+ EXPECT_REF(event, 2);
V_VT(&v) = VT_DISPATCH;
V_DISPATCH(&v) = NULL;
hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
ok(hr == S_OK, "got 0x%08x\n", hr);
- ref = IDispatch_AddRef(event);
- IDispatch_Release(event);
- ok(ref == 2, "got %d\n", ref);
+ EXPECT_REF(event, 1);
V_VT(&v) = VT_UNKNOWN;
V_DISPATCH(&v) = NULL;
IStream *stream;
VARIANT_BOOL b;
HRESULT hr;
- ULONG ref1, ref2, ref;
+ ULONG ref1, ref2;
VARIANT v;
template = create_xsltemplate(&IID_IXSLTemplate);
hr = IXSLTemplate_createProcessor(template, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
- ref = IXSLTemplate_AddRef(template);
- IXSLTemplate_Release(template);
- ok(ref == 2, "got %d\n", ref);
-
+ EXPECT_REF(template, 1);
hr = IXSLTemplate_createProcessor(template, &processor);
ok(hr == S_OK, "got 0x%08x\n", hr);
-
- ref = IXSLTemplate_AddRef(template);
- IXSLTemplate_Release(template);
- ok(ref == 3, "got %d\n", ref);
+ EXPECT_REF(template, 2);
/* input no set yet */
V_VT(&v) = VT_BSTR;
ok(hr == S_OK, "got 0x%08x\n", hr);
CreateStreamOnHGlobal(NULL, TRUE, &stream);
- ref = IStream_AddRef(stream);
- IStream_Release(stream);
- ok(ref == 2, "got %d\n", ref);
+ EXPECT_REF(stream, 1);
V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = (IUnknown*)stream;
ok(hr == S_OK, "got 0x%08x\n", hr);
/* it seems processor grabs 2 references */
- ref = IStream_AddRef(stream);
- IStream_Release(stream);
- todo_wine ok(ref == 4, "got %d\n", ref);
+ todo_wine EXPECT_REF(stream, 3);
V_VT(&v) = VT_EMPTY;
hr = IXSLProcessor_get_output(processor, &v);
ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
- ref = IStream_AddRef(stream);
- IStream_Release(stream);
- todo_wine ok(ref == 5, "got %d\n", ref);
+ todo_wine EXPECT_REF(stream, 4);
VariantClear(&v);
hr = IXSLProcessor_transform(processor, NULL);
hr = IXSLProcessor_put_output(processor, v);
ok(hr == S_OK, "got 0x%08x\n", hr);
- ref = IStream_AddRef(stream);
- IStream_Release(stream);
- ok(ref == 2, "got %d\n", ref);
+ EXPECT_REF(stream, 1);
IStream_Release(stream);
{
IXMLDOMDocument *doc;
IXMLDOMAttribute *attr;
+ IXMLDOMElement *elem1, *elem2, *elem3;
IXMLDOMNode *node, *newnode;
HRESULT hr;
VARIANT v;
ok(node == NULL, "got %p\n", node);
IXMLDOMNode_Release(newnode);
+ /* insertBefore for elements */
+ hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ EXPECT_NO_CHILDREN(elem1);
+ EXPECT_NO_CHILDREN(elem2);
+ EXPECT_NO_CHILDREN(elem3);
+
+ todo_wine EXPECT_REF(elem2, 2);
+
+ V_VT(&v) = VT_NULL;
+ node = NULL;
+ hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(node == (void*)elem2, "got %p\n", node);
+
+ EXPECT_CHILDREN(elem1);
+ todo_wine EXPECT_REF(elem2, 3);
+
+ /* again for already linked node */
+ V_VT(&v) = VT_NULL;
+ node = NULL;
+ hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(node == (void*)elem2, "got %p\n", node);
+
+ EXPECT_CHILDREN(elem1);
+
+ /* increments each time */
+ todo_wine EXPECT_REF(elem2, 4);
+
+ /* try to add to another element */
+ V_VT(&v) = VT_NULL;
+ node = (void*)0xdeadbeef;
+ hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(node == (void*)elem2, "got %p\n", node);
+
+ EXPECT_CHILDREN(elem3);
+ todo_wine EXPECT_NO_CHILDREN(elem1);
+
+ IXMLDOMElement_Release(elem1);
+ IXMLDOMElement_Release(elem2);
+ IXMLDOMElement_Release(elem3);
IXMLDOMDocument_Release(doc);
free_bstrs();
}