gdiplus: Add test for GdipGetImageThumbnail.
[wine] / dlls / msxml3 / tests / xmlelem.c
1 /*
2  * IXMLElement tests
3  *
4  * Copyright 2007 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22
23 #include <stdio.h>
24
25 #include "windows.h"
26 #include "ole2.h"
27 #include "xmldom.h"
28 #include "msxml2.h"
29 #include "ocidl.h"
30
31 #include "wine/test.h"
32
33 #define ERROR_URL_NOT_FOUND 0x800c0006
34
35 static void test_xmlelem(void)
36 {
37     HRESULT hr;
38     IXMLDocument *doc = NULL;
39     IXMLElement *element = NULL, *parent;
40     IXMLElement *child, *child2;
41     IXMLElementCollection *children;
42     VARIANT vType, vName;
43     VARIANT vIndex, vValue;
44     BSTR str, val;
45     LONG type, num_child;
46
47     static const WCHAR propName[] = {'p','r','o','p',0};
48     static const WCHAR propVal[] = {'v','a','l',0};
49     static const WCHAR nextVal[] = {'n','e','x','t',0};
50     static const WCHAR noexist[] = {'n','o','e','x','i','s','t',0};
51     static const WCHAR crazyCase1[] = {'C','R','a','z','Y','c','A','S','E',0};
52     static const WCHAR crazyCase2[] = {'C','R','A','Z','Y','C','A','S','E',0};
53
54     hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
55                           &IID_IXMLDocument, (LPVOID*)&doc);
56     ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
57
58     V_VT(&vType) = VT_I4;
59     V_I4(&vType) = XMLELEMTYPE_ELEMENT;
60     V_VT(&vName) = VT_NULL;
61     hr = IXMLDocument_createElement(doc, vType, vName, &element);
62     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
63     ok(element != NULL, "Expected non-NULL element\n");
64
65     hr = IXMLElement_get_tagName(element, &str);
66     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
67     ok(lstrlenW(str) == 0, "Expected empty tag name\n");
68     SysFreeString(str);
69
70     parent = (IXMLElement *)0xdeadbeef;
71     hr = IXMLElement_get_parent(element, &parent);
72     ok(hr == 1, "Expected 1, got %08x\n", hr);
73     ok(parent == NULL, "Expected NULL parent\n");
74
75     str = SysAllocString(noexist);
76     hr = IXMLElement_getAttribute(element, str, &vValue);
77     ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
78     ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
79     ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
80     VariantClear(&vValue);
81     SysFreeString(str);
82
83     str = SysAllocString(crazyCase1);
84     val = SysAllocString(propVal);
85     V_VT(&vValue) = VT_BSTR;
86     V_BSTR(&vValue) = val;
87     hr = IXMLElement_setAttribute(element, str, vValue);
88     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
89     SysFreeString(str);
90     SysFreeString(val);
91
92     str = SysAllocString(crazyCase2);
93     hr = IXMLElement_getAttribute(element, str, &vValue);
94     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
95     ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
96     ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
97     VariantClear(&vValue);
98     SysFreeString(str);
99
100     str = SysAllocString(propName);
101     val = SysAllocString(propVal);
102     V_VT(&vValue) = VT_BSTR;
103     V_BSTR(&vValue) = val;
104     hr = IXMLElement_setAttribute(element, str, vValue);
105     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
106     SysFreeString(val);
107
108     hr = IXMLElement_getAttribute(element, str, &vValue);
109     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
110     ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
111     ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
112     VariantClear(&vValue);
113
114     hr = IXMLElement_removeAttribute(element, str);
115     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
116
117     /* remove now nonexistent attribute */
118     hr = IXMLElement_removeAttribute(element, str);
119     ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
120
121     hr = IXMLElement_getAttribute(element, str, &vValue);
122     ok(hr == 1, "Expected 1, got %08x\n", hr);
123     ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
124     ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
125     SysFreeString(str);
126     VariantClear(&vValue);
127
128     children = (IXMLElementCollection *)0xdeadbeef;
129     hr = IXMLElement_get_children(element, &children);
130     ok(hr == 1, "Expected 1, got %08x\n", hr);
131     ok(children == NULL, "Expected NULL collection\n");
132
133     hr = IXMLElement_get_type(element, &type);
134     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
135     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
136
137     hr = IXMLElement_get_text(element, &str);
138     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
139     ok(lstrlenW(str) == 0, "Expected empty text\n");
140     SysFreeString(str);
141
142     /* put_text with an ELEMENT */
143     str = SysAllocString(propVal);
144     hr = IXMLElement_put_text(element, str);
145     ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
146     SysFreeString(str);
147
148     V_VT(&vType) = VT_I4;
149     V_I4(&vType) = XMLELEMTYPE_TEXT;
150     V_VT(&vName) = VT_NULL;
151     hr = IXMLDocument_createElement(doc, vType, vName, &child);
152     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
153     ok(child != NULL, "Expected non-NULL child\n");
154
155     hr = IXMLElement_addChild(element, child, 0, -1);
156     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
157
158     str = SysAllocString(propVal);
159     hr = IXMLElement_put_text(child, str);
160     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
161     SysFreeString(str);
162
163     parent = (IXMLElement *)0xdeadbeef;
164     hr = IXMLElement_get_parent(child, &parent);
165     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
166     ok(parent != element, "Expected parent != element\n");
167
168     hr = IXMLElement_get_type(parent, &type);
169     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
170     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
171
172     children = (IXMLElementCollection *)0xdeadbeef;
173     hr = IXMLElement_get_children(element, &children);
174     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
175     ok(children != NULL, "Expected non-NULL collection\n");
176
177     hr = IXMLElementCollection_get_length(children, &num_child);
178     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
179     ok(num_child == 1, "Expected 1, got %d\n", num_child);
180
181     V_VT(&vIndex) = VT_I4;
182     V_I4(&vIndex) = 0;
183     V_VT(&vName) = VT_ERROR;
184     V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
185     hr = IXMLElementCollection_item(children, vIndex, vName, (IDispatch **)&child2);
186     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
187     ok(child2 != NULL, "Expected non-NULL child\n");
188
189     hr = IXMLElement_get_type(child2, &type);
190     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
191     ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
192
193     hr = IXMLElement_get_text(element, &str);
194     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
195     ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
196     SysFreeString(str);
197
198     hr = IXMLElement_get_text(child2, &str);
199     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
200     ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
201     SysFreeString(str);
202
203     /* try put_text on ELEMENT again, now that it has a text child */
204     str = SysAllocString(nextVal);
205     hr = IXMLElement_put_text(element, str);
206     ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
207     SysFreeString(str);
208
209     str = SysAllocString(nextVal);
210     hr = IXMLElement_put_text(child2, str);
211     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
212     SysFreeString(str);
213
214     hr = IXMLElement_get_text(element, &str);
215     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
216     ok(!lstrcmpW(str, nextVal), "Expected 'val'\n");
217     SysFreeString(str);
218
219     IXMLElement_Release(child2);
220     IXMLElementCollection_Release(children);
221     IXMLElement_Release(parent);
222     IXMLElement_Release(child);
223     IXMLElement_Release(element);
224     IXMLDocument_Release(doc);
225 }
226
227 static void create_xml_file(LPCSTR filename)
228 {
229     DWORD dwNumberOfBytesWritten;
230     HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL,
231                            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
232
233     static const char data[] =
234         "<?xml version=\"1.0\" ?>\n"
235         "<BankAccount>\n"
236         "  <Number>1234</Number>\n"
237         "  <Name>Captain Ahab</Name>\n"
238         "</BankAccount>\n";
239
240     WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
241     CloseHandle(hf);
242 }
243
244 static void test_xmlelem_collection(void)
245 {
246     HRESULT hr;
247     IUnknown *unk = NULL;
248     IXMLDocument *doc = NULL;
249     IXMLElement *element = NULL, *child;
250     IXMLElementCollection *collection = NULL;
251     IEnumVARIANT *enumVar = NULL;
252     CHAR pathA[MAX_PATH];
253     WCHAR path[MAX_PATH];
254     LONG length, type;
255     ULONG num_vars;
256     VARIANT var, vIndex, vName;
257     BSTR url, str;
258     static const CHAR szBankXML[] = "bank.xml";
259     static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
260     static const WCHAR szName[] = {'N','A','M','E',0};
261
262     hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
263                           &IID_IXMLDocument, (LPVOID*)&doc);
264     ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
265
266     create_xml_file(szBankXML);
267     GetFullPathNameA(szBankXML, MAX_PATH, pathA, NULL);
268     MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
269
270     url = SysAllocString(path);
271     hr = IXMLDocument_put_URL(doc, url);
272     ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
273     SysFreeString(url);
274
275     if(hr != S_OK)
276         goto cleanup;
277
278     hr = IXMLDocument_get_root(doc, &element);
279     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
280     ok(element != NULL, "Expected non-NULL element\n");
281
282     hr = IXMLElement_get_children(element, &collection);
283     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
284     ok(collection != NULL, "Expected non-NULL collection\n");
285
286     hr = IXMLElementCollection_get_length(collection, NULL);
287     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
288
289     hr = IXMLElementCollection_get_length(collection, &length);
290     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
291     ok(length == 2, "Expected 2, got %d\n", length);
292
293     /* IXMLElementCollection:put_length does nothing */
294     hr = IXMLElementCollection_put_length(collection, -1);
295     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
296
297     hr = IXMLElementCollection_put_length(collection, 0);
298     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
299
300     hr = IXMLElementCollection_put_length(collection, 1);
301     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
302
303     hr = IXMLElementCollection_put_length(collection, 2);
304     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
305
306     hr = IXMLElementCollection_put_length(collection, 3);
307     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
308
309     hr = IXMLElementCollection_put_length(collection, 50);
310     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
311
312     /* make sure the length hasn't changed */
313     hr = IXMLElementCollection_get_length(collection, &length);
314     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
315     ok(length == 2, "Expected 2, got %d\n", length);
316
317     /* IXMLElementCollection implements IEnumVARIANT */
318     hr = IXMLElementCollection_QueryInterface(collection, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
319     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
320     ok(enumVar != NULL, "Expected non-NULL enumVar\n");
321     IEnumVARIANT_Release(enumVar);
322
323     hr = IXMLElementCollection_get__newEnum(collection, &unk);
324     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
325     ok(unk != NULL, "Expected non-NULL unk\n");
326
327     hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
328     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
329     ok(enumVar != NULL, "Expected non-NULL enumVar\n");
330     IUnknown_Release(unk);
331
332     /* <Number>1234</Number> */
333     hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
334     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
335     ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
336     ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
337
338     hr = IUnknown_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
339     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
340     ok(child != NULL, "Expected non-NULL child\n");
341
342     VariantClear(&var);
343
344     hr = IXMLElement_get_type(child, &type);
345     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
346     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
347
348     hr = IXMLElement_get_tagName(child, &str);
349     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
350     ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
351     SysFreeString(str);
352     IXMLElement_Release(child);
353
354     /* <Name>Captain Ahab</Name> */
355     hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
356     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
357     ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
358     ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
359
360     hr = IUnknown_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
361     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
362     ok(child != NULL, "Expected non-NULL child\n");
363
364     VariantClear(&var);
365
366     hr = IXMLElement_get_type(child, &type);
367     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
368     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
369
370     hr = IXMLElement_get_tagName(child, &str);
371     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
372     ok(!lstrcmpW(str, szName), "Expected NAME\n");
373     SysFreeString(str);
374     IXMLElement_Release(child);
375
376     /* <Number>1234</Number> */
377     V_VT(&vIndex) = VT_I4;
378     V_I4(&vIndex) = 0;
379     V_VT(&vName) = VT_ERROR;
380     V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
381     hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
382     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
383     ok(child != NULL, "Expected non-NULL child\n");
384
385     hr = IXMLElement_get_type(child, &type);
386     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
387     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
388
389     hr = IXMLElement_get_tagName(child, &str);
390     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
391     ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
392     SysFreeString(str);
393     IXMLElement_Release(child);
394
395     /* <Name>Captain Ahab</Name> */
396     V_VT(&vIndex) = VT_I4;
397     V_I4(&vIndex) = 1;
398     V_VT(&vName) = VT_ERROR;
399     V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
400     hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
401     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
402     ok(child != NULL, "Expected non-NULL child\n");
403
404     hr = IXMLElement_get_type(child, &type);
405     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
406     ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
407
408     hr = IXMLElement_get_tagName(child, &str);
409     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
410     ok(!lstrcmpW(str, szName), "Expected NAME\n");
411     SysFreeString(str);
412     IXMLElement_Release(child);
413
414     V_I4(&vIndex) = 100;
415     hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
416     ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
417     ok(child == NULL, "Expected NULL child\n");
418
419     V_I4(&vIndex) = -1;
420     child = (IXMLElement *)0xdeadbeef;
421     hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
422     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
423     ok(child == NULL, "Expected NULL child\n");
424
425     IEnumVARIANT_Release(enumVar);
426     IXMLElement_Release(element);
427     IXMLElementCollection_Release(collection);
428 cleanup:
429     IXMLDocument_Release(doc);
430     DeleteFileA("bank.xml");
431 }
432
433 static void test_xmlelem_children(void)
434 {
435     IXMLDocument *doc = NULL;
436     IXMLElement *element = NULL, *child = NULL, *child2 = NULL;
437     IXMLElementCollection *collection = NULL;
438     VARIANT vType, vName, vIndex;
439     LONG length;
440     HRESULT hr;
441
442     hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
443                           &IID_IXMLDocument, (LPVOID*)&doc);
444     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
445
446     V_VT(&vType) = VT_I4;
447     V_I4(&vType) = XMLELEMTYPE_ELEMENT;
448     V_VT(&vName) = VT_NULL;
449     hr = IXMLDocument_createElement(doc, vType, vName, &element);
450     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
451     ok(element != NULL, "Expected non-NULL element\n");
452
453     V_VT(&vType) = VT_I4;
454     V_I4(&vType) = XMLELEMTYPE_TEXT;
455     V_VT(&vName) = VT_NULL;
456     hr = IXMLDocument_createElement(doc, vType, vName, &child);
457     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
458     ok(child != NULL, "Expected non-NULL child\n");
459
460     V_VT(&vType) = VT_I4;
461     V_I4(&vType) = XMLELEMTYPE_TEXT;
462     V_VT(&vName) = VT_NULL;
463     hr = IXMLDocument_createElement(doc, vType, vName, &child2);
464     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
465     ok(child2 != NULL, "Expected non-NULL child\n");
466
467     hr = IXMLElement_addChild(element, child, 0, -1);
468     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
469
470     hr = IXMLElement_get_children(element, &collection);
471     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
472     ok(collection != NULL, "Expected non-NULL collection\n");
473
474     length = 0;
475     hr = IXMLElementCollection_get_length(collection, &length);
476     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
477     ok(length == 1, "Expected 1, got %08x\n", length);
478
479     /* remove/add child and check what happens with collection */
480     hr = IXMLElement_removeChild(element, child);
481     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
482
483     length = -1;
484     hr = IXMLElementCollection_get_length(collection, &length);
485     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
486     ok(length == 0, "Expected 0, got %08x\n", length);
487     IXMLElementCollection_Release(collection);
488
489     hr = IXMLElement_AddRef(child);
490     ok(hr == 2, "Expected 2, got %08x\n", hr);
491     IXMLElement_Release(child);
492     hr = IXMLElement_addChild(element, child, 0, -1);
493     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
494     hr = IXMLElement_AddRef(child);
495     ok(hr == 2, "Expected 2, got %08x\n", hr);
496     IXMLElement_Release(child);
497     hr = IXMLElement_addChild(element, child2, 0, -1);
498     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
499
500     hr = IXMLElement_get_children(element, &collection);
501     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
502     ok(collection != NULL, "Expected non-NULL collection\n");
503
504     hr = IXMLElement_AddRef(child);
505     ok(hr == 2, "Expected 2, got %08x\n", hr);
506     IXMLElement_Release(child);
507
508     length = 0;
509     hr = IXMLElementCollection_get_length(collection, &length);
510     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
511     ok(length == 2, "Expected 2, got %08x\n", length);
512
513     IXMLElement_Release(child2);
514
515     length = 0;
516     hr = IXMLElementCollection_get_length(collection, &length);
517     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
518     ok(length == 2, "Expected 2, got %08x\n", length);
519
520     V_VT(&vIndex) = VT_I4;
521     V_I4(&vIndex) = 1;
522     hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child2);
523     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
524     ok(child2 != NULL, "Expected not NULL child\n");
525     IXMLElementCollection_Release(collection);
526     IXMLElement_Release(child2);
527
528     /* add element->child->child2 structure, then remove child2 from node */
529     V_VT(&vType) = VT_I4;
530     V_I4(&vType) = XMLELEMTYPE_TEXT;
531     V_VT(&vName) = VT_NULL;
532     hr = IXMLDocument_createElement(doc, vType, vName, &child2);
533     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
534     ok(child2 != NULL, "Expected non-NULL child\n");
535
536     hr = IXMLElement_addChild(child, child2, 0, -1);
537     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
538
539     hr = IXMLElement_removeChild(element, child2);
540     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
541
542     hr = IXMLElement_removeChild(child, child2);
543     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
544
545     hr = IXMLElement_removeChild(child, NULL);
546     ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
547
548     IXMLElement_Release(element);
549     IXMLElement_Release(child);
550     IXMLElement_Release(child2);
551     IXMLDocument_Release(doc);
552 }
553
554 static BOOL test_try_xmldoc(void)
555 {
556     IXMLDocument *doc = NULL;
557     HRESULT hr;
558
559     hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
560                           &IID_IXMLDocument, (LPVOID*)&doc);
561     if (FAILED(hr))
562     {
563         skip("Failed to create XMLDocument instance\n");
564         return FALSE;
565     }
566
567     IXMLDocument_Release(doc);
568     return TRUE;
569 }
570
571 START_TEST(xmlelem)
572 {
573     HRESULT hr;
574
575     hr = CoInitialize(NULL);
576     ok(hr == S_OK, "failed to init com\n");
577
578     if (!test_try_xmldoc())
579     {
580         CoUninitialize();
581         return;
582     }
583
584     test_xmlelem();
585     test_xmlelem_collection();
586     test_xmlelem_children();
587
588     CoUninitialize();
589 }