secur32/tests: Use importlib for functions available since Windows XP.
[wine.git] / dlls / msxml3 / tests / xmldoc.c
blob359297f592f006faed32632805e421a781492e20
1 /*
2 * IXMLDocument tests
4 * Copyright 2007 James Hawkins
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.
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.
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
21 #define COBJMACROS
23 #include <stdio.h>
24 #include "windows.h"
25 #include "ole2.h"
26 #include "msxml2.h"
27 #include "msxml2did.h"
28 #include "ocidl.h"
30 #include "wine/test.h"
32 #define EXPECT_HR(hr,hr_exp) \
33 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
35 /* Deprecated Error Code */
36 #define XML_E_INVALIDATROOTLEVEL 0xc00ce556
38 static void create_xml_file(LPCSTR filename)
40 DWORD dwNumberOfBytesWritten;
41 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL,
42 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
44 static const char data[] =
45 "<?xml version=\"1.0\" ?>\n"
46 "<!DOCTYPE BankAccount>\n"
47 "<BankAccount>\n"
48 " <Number>1234</Number>\n"
49 " <Name>Captain Ahab</Name>\n"
50 "</BankAccount>";
52 WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL);
53 CloseHandle(hf);
56 static void create_stream_on_file(IStream **stream, LPCSTR path)
58 HANDLE hfile;
59 HGLOBAL hglobal;
60 LPVOID ptr;
61 HRESULT hr;
62 DWORD file_size, read;
64 hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL,
65 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
66 ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n");
67 file_size = GetFileSize(hfile, NULL);
69 hglobal = GlobalAlloc(GHND, file_size);
70 ptr = GlobalLock(hglobal);
72 ReadFile(hfile, ptr, file_size, &read, NULL);
73 ok(file_size == read, "Expected to read the whole file, read %d\n", read);
75 hr = CreateStreamOnHGlobal(hglobal, TRUE, stream);
76 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
77 ok(*stream != NULL, "Expected non-NULL stream\n");
79 CloseHandle(hfile);
80 GlobalUnlock(hglobal);
83 static void test_xmldoc(void)
85 IXMLElement *element = NULL, *child = NULL, *value = NULL;
86 IXMLElementCollection *collection = NULL, *inner = NULL;
87 IPersistStreamInit *psi = NULL;
88 IXMLDocument *doc = NULL;
89 IStream *stream = NULL;
90 VARIANT vIndex, vName;
91 LONG type, num_child;
92 CHAR path[MAX_PATH];
93 IDispatch *disp;
94 ITypeInfo *ti;
95 HRESULT hr;
96 BSTR name;
98 static const WCHAR szBankAccount[] = {'B','A','N','K','A','C','C','O','U','N','T',0};
99 static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
100 static const WCHAR szNumVal[] = {'1','2','3','4',0};
101 static const WCHAR szName[] = {'N','A','M','E',0};
102 static const WCHAR szNameVal[] = {'C','a','p','t','a','i','n',' ','A','h','a','b',0};
103 static const WCHAR szVersion[] = {'1','.','0',0};
104 static const WCHAR rootW[] = {'r','o','o','t',0};
106 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
107 &IID_IXMLDocument, (void**)&doc);
108 EXPECT_HR(hr, S_OK);
110 /* IDispatch */
111 hr = IXMLDocument_QueryInterface(doc, &IID_IDispatch, (void**)&disp);
112 EXPECT_HR(hr, S_OK);
114 /* just to make sure we're on right type data */
115 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
116 EXPECT_HR(hr, S_OK);
117 name = NULL;
118 hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLDOCUMENT_ROOT, &name, NULL, NULL, NULL);
119 EXPECT_HR(hr, S_OK);
120 ok(!lstrcmpW(name, rootW), "got name %s\n", wine_dbgstr_w(name));
121 SysFreeString(name);
123 ITypeInfo_Release(ti);
124 IDispatch_Release(disp);
126 hr = IXMLDocument_QueryInterface(doc, &IID_IXMLDOMDocument, (void**)&disp);
127 EXPECT_HR(hr, E_NOINTERFACE);
129 create_xml_file("bank.xml");
130 GetFullPathNameA("bank.xml", MAX_PATH, path, NULL);
131 create_stream_on_file(&stream, path);
133 hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&psi);
134 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
135 ok(psi != NULL, "Expected non-NULL psi\n");
137 hr = IXMLDocument_get_root(doc, &element);
138 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
139 ok(element == NULL, "Expected NULL element\n");
141 hr = IPersistStreamInit_Load(psi, stream);
142 ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr);
143 if(hr == XML_E_INVALIDATROOTLEVEL)
144 goto cleanup;
146 ok(stream != NULL, "Expected non-NULL stream\n");
148 /* version field */
149 hr = IXMLDocument_get_version(doc, NULL);
150 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
152 name = NULL;
153 hr = IXMLDocument_get_version(doc, &name);
154 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
155 ok(!lstrcmpW(name, szVersion), "Expected 1.0, got %s\n", wine_dbgstr_w(name));
156 SysFreeString(name);
158 /* doctype */
159 hr = IXMLDocument_get_doctype(doc, NULL);
160 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
162 hr = IXMLDocument_get_doctype(doc, &name);
163 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
164 ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT, got %s\n", wine_dbgstr_w(name));
165 SysFreeString(name);
167 hr = IXMLDocument_get_root(doc, &element);
168 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
169 ok(element != NULL, "Expected non-NULL element\n");
171 /* ::root() returns new instance each time */
172 hr = IXMLDocument_get_root(doc, &child);
173 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
174 ok(child != NULL, "Expected non-NULL element\n");
175 ok(child != element, "Expected new element instance\n");
176 IXMLElement_Release(child);
178 hr = IXMLElement_get_type(element, &type);
179 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
180 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
182 hr = IXMLElement_get_tagName(element, &name);
183 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
184 ok(!lstrcmpW(name, szBankAccount), "Expected BANKACCOUNT\n");
185 SysFreeString(name);
187 hr = IXMLElement_get_children(element, &collection);
188 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
189 ok(collection != NULL, "Expected non-NULL collection\n");
191 hr = IXMLElementCollection_get_length(collection, &num_child);
192 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
193 ok(num_child == 2, "Expected 2, got %d\n", num_child);
195 V_VT(&vIndex) = VT_I4;
196 V_I4(&vIndex) = 0;
197 V_VT(&vName) = VT_ERROR;
198 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
199 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
200 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
201 ok(child != NULL, "Expected non-NULL child\n");
203 hr = IXMLElement_get_type(child, &type);
204 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
205 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
207 hr = IXMLElement_get_tagName(child, &name);
208 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
209 ok(!lstrcmpW(name, szNumber), "Expected NUMBER\n");
210 SysFreeString(name);
212 hr = IXMLElement_get_children(child, &inner);
213 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
214 ok(inner != NULL, "Expected non-NULL inner\n");
216 hr = IXMLElementCollection_get_length(inner, &num_child);
217 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
218 ok(num_child == 1, "Expected 1, got %d\n", num_child);
220 hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value);
221 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
222 ok(value != NULL, "Expected non-NULL value\n");
224 hr = IXMLElement_get_type(value, &type);
225 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
226 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
228 hr = IXMLElement_get_text(value, &name);
229 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
230 ok(!lstrcmpW(name, szNumVal), "Expected '1234'\n");
231 SysFreeString(name);
233 IXMLElementCollection_Release(inner);
235 inner = (IXMLElementCollection *)0xdeadbeef;
236 hr = IXMLElement_get_children(value, &inner);
237 ok(hr == 1, "Expected 1, got %08x\n", hr);
238 ok(inner == NULL, "Expected NULL inner, got %p\n", inner);
240 IXMLElement_Release(value);
241 IXMLElement_Release(child);
242 value = NULL;
243 child = NULL;
245 V_I4(&vIndex) = 1;
246 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
247 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
248 ok(child != NULL, "Expected non-NULL child\n");
250 hr = IXMLElement_get_type(child, &type);
251 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
252 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
254 hr = IXMLElement_get_tagName(child, &name);
255 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
256 ok(!lstrcmpW(name, szName), "Expected NAME\n");
257 SysFreeString(name);
259 hr = IXMLElement_get_children(child, &inner);
260 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
261 ok(inner != NULL, "Expected non-NULL inner\n");
263 hr = IXMLElementCollection_get_length(inner, &num_child);
264 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
265 ok(num_child == 1, "Expected 1, got %d\n", num_child);
267 V_I4(&vIndex) = 0;
268 hr = IXMLElementCollection_item(inner, vIndex, vName, (IDispatch **)&value);
269 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
270 ok(value != NULL, "Expected non-NULL value\n");
272 hr = IXMLElement_get_type(value, &type);
273 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
274 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
276 hr = IXMLElement_get_text(value, &name);
277 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
278 ok(!lstrcmpW(name, szNameVal), "Expected 'Captain Ahab'\n");
279 SysFreeString(name);
281 IXMLElementCollection_Release(inner);
283 inner = (IXMLElementCollection *)0xdeadbeef;
284 hr = IXMLElement_get_children(value, &inner);
285 ok(hr == 1, "Expected 1, got %08x\n", hr);
286 ok(inner == NULL, "Expected NULL inner, got %p\n", inner);
288 IXMLElement_Release(value);
289 IXMLElement_Release(child);
290 IXMLElementCollection_Release(collection);
291 IXMLElement_Release(element);
292 cleanup:
293 IStream_Release(stream);
294 IPersistStreamInit_Release(psi);
295 IXMLDocument_Release(doc);
297 DeleteFileA("bank.xml");
300 static void test_createElement(void)
302 HRESULT hr;
303 IXMLDocument *doc = NULL;
304 IXMLElement *element = NULL, *root = NULL;
305 VARIANT vType, vName;
306 LONG type;
308 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
309 &IID_IXMLDocument, (LPVOID*)&doc);
310 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
312 /* invalid vType type */
313 V_VT(&vType) = VT_NULL;
314 V_VT(&vName) = VT_NULL;
315 element = (IXMLElement *)0xdeadbeef;
316 hr = IXMLDocument_createElement(doc, vType, vName, &element);
317 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
318 ok(element == NULL, "Expected NULL element\n");
320 /* invalid vType value */
321 V_VT(&vType) = VT_I4;
322 V_I4(&vType) = -1;
323 V_VT(&vName) = VT_NULL;
324 hr = IXMLDocument_createElement(doc, vType, vName, &element);
325 /* Up to and including SP7, createElement returns an element. */
326 if(hr == S_OK)
328 ok(element != NULL, "Expected element\n");
329 if (element != NULL)
331 hr = IXMLElement_get_type(element, &type);
332 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
333 /* SP7 returns an XMLELEMTYPE_ELEMENT */
334 ok(type == XMLELEMTYPE_OTHER || type == XMLELEMTYPE_ELEMENT,
335 "Expected XMLELEMTYPE_OTHER || XMLELEMTYPE_ELEMENT, got %d\n", type);
337 IXMLElement_Release(element);
340 else
342 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
343 ok(element == NULL, "Expected NULL element\n");
346 /* invalid vName type */
347 V_VT(&vType) = VT_I4;
348 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
349 V_VT(&vName) = VT_I4;
350 hr = IXMLDocument_createElement(doc, vType, vName, &element);
351 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
352 ok(element != NULL, "Expected non-NULL element\n");
354 hr = IXMLElement_get_type(element, &type);
355 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
356 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
358 IXMLElement_Release(element);
360 /* NULL element */
361 V_VT(&vType) = VT_I4;
362 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
363 V_VT(&vName) = VT_I4;
364 hr = IXMLDocument_createElement(doc, vType, vName, NULL);
365 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
367 root = (IXMLElement *)0xdeadbeef;
368 hr = IXMLDocument_get_root(doc, &root);
369 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
370 ok(root == NULL, "Expected NULL root\n");
372 V_VT(&vType) = VT_I4;
373 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
374 V_VT(&vName) = VT_NULL;
375 hr = IXMLDocument_createElement(doc, vType, vName, &element);
376 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
377 ok(element != NULL, "Expected non-NULL element\n");
379 /* createElement does not set the new element as root */
380 root = (IXMLElement *)0xdeadbeef;
381 hr = IXMLDocument_get_root(doc, &root);
382 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
383 ok(root == NULL, "Expected NULL root\n");
385 IXMLElement_Release(element);
386 IXMLDocument_Release(doc);
389 static void test_persiststreaminit(void)
391 IXMLDocument *doc = NULL;
392 IXMLElement *element = NULL;
393 IPersistStreamInit *psi = NULL;
394 IStream *stream = NULL;
395 STATSTG stat;
396 HRESULT hr;
397 ULARGE_INTEGER size;
398 CHAR path[MAX_PATH];
399 CLSID id;
400 BSTR str;
401 static const WCHAR testW[] = {'t','e','s','t',0};
403 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
404 &IID_IXMLDocument, (LPVOID*)&doc);
405 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
407 hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (LPVOID *)&psi);
408 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
409 ok(psi != NULL, "Expected non-NULL psi\n");
411 /* null arguments */
412 hr = IPersistStreamInit_GetSizeMax(psi, NULL);
413 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
415 hr = IPersistStreamInit_Load(psi, NULL);
416 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
418 hr = IPersistStreamInit_Save(psi, NULL, FALSE);
419 todo_wine ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
421 hr = IPersistStreamInit_GetClassID(psi, NULL);
422 ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr);
424 hr = IPersistStreamInit_IsDirty(psi);
425 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
427 create_xml_file("bank.xml");
428 GetFullPathNameA("bank.xml", MAX_PATH, path, NULL);
429 create_stream_on_file(&stream, path);
431 /* GetSizeMax not implemented */
432 size.QuadPart = 0;
433 hr = IPersistStreamInit_GetSizeMax(psi, &size);
434 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
435 ok(size.QuadPart == 0, "Expected 0\n");
437 hr = IPersistStreamInit_Load(psi, stream);
438 IStream_Release(stream);
439 ok(hr == S_OK || hr == XML_E_INVALIDATROOTLEVEL, "Expected S_OK, got %08x\n", hr);
440 if(hr == XML_E_INVALIDATROOTLEVEL)
441 goto cleanup;
443 hr = IPersistStreamInit_IsDirty(psi);
444 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
446 /* try to save document */
447 stream = NULL;
448 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
449 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
450 hr = IPersistStreamInit_Save(psi, stream, FALSE);
451 todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
453 stat.cbSize.QuadPart = 0;
454 hr = IStream_Stat(stream, &stat, 0);
455 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
456 todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n");
457 IStream_Release(stream);
459 str = SysAllocString(testW);
460 hr = IXMLDocument_get_root(doc, &element);
461 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
462 hr = IXMLElement_put_text(element, str);
463 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
464 IXMLElement_Release(element);
465 SysFreeString(str);
467 hr = IPersistStreamInit_IsDirty(psi);
468 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
470 create_stream_on_file(&stream, path);
471 hr = IPersistStreamInit_Load(psi, stream);
472 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
473 IStream_Release(stream);
475 hr = IPersistStreamInit_IsDirty(psi);
476 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
478 /* reset internal stream */
479 hr = IPersistStreamInit_InitNew(psi);
480 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
482 hr = IPersistStreamInit_IsDirty(psi);
483 todo_wine ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
485 stream = NULL;
486 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
487 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
489 hr = IPersistStreamInit_Save(psi, stream, FALSE);
490 todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
492 stat.cbSize.QuadPart = 0;
493 hr = IStream_Stat(stream, &stat, 0);
494 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
495 todo_wine ok(stat.cbSize.QuadPart > 0, "Expected >0\n");
496 IStream_Release(stream);
498 memset(&id, 0, sizeof(id));
499 hr = IPersistStreamInit_GetClassID(psi, &id);
500 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
501 ok(IsEqualCLSID(&id, &CLSID_XMLDocument), "Expected CLSID_XMLDocument\n");
503 cleanup:
504 IPersistStreamInit_Release(psi);
505 IXMLDocument_Release(doc);
506 DeleteFileA("bank.xml");
509 static BOOL test_try_xmldoc(void)
511 IXMLDocument *doc = NULL;
512 HRESULT hr;
514 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
515 &IID_IXMLDocument, (LPVOID*)&doc);
516 if (FAILED(hr))
518 win_skip("Failed to create XMLDocument instance\n");
519 return FALSE;
522 IXMLDocument_Release(doc);
523 return TRUE;
526 static void test_xmlelem_children(void)
528 IXMLDocument *doc = NULL;
529 IXMLElement *element = NULL, *child = NULL, *child2 = NULL;
530 IXMLElementCollection *collection = NULL;
531 VARIANT vType, vName, vIndex;
532 LONG length;
533 HRESULT hr;
535 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
536 &IID_IXMLDocument, (LPVOID*)&doc);
537 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
539 V_VT(&vType) = VT_I4;
540 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
541 V_VT(&vName) = VT_NULL;
542 hr = IXMLDocument_createElement(doc, vType, vName, &element);
543 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
544 ok(element != NULL, "Expected non-NULL element\n");
546 V_VT(&vType) = VT_I4;
547 V_I4(&vType) = XMLELEMTYPE_TEXT;
548 V_VT(&vName) = VT_NULL;
549 hr = IXMLDocument_createElement(doc, vType, vName, &child);
550 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
551 ok(child != NULL, "Expected non-NULL child\n");
553 V_VT(&vType) = VT_I4;
554 V_I4(&vType) = XMLELEMTYPE_TEXT;
555 V_VT(&vName) = VT_NULL;
556 hr = IXMLDocument_createElement(doc, vType, vName, &child2);
557 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
558 ok(child2 != NULL, "Expected non-NULL child\n");
560 hr = IXMLElement_addChild(element, child, 0, -1);
561 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
563 hr = IXMLElement_get_children(element, &collection);
564 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
565 ok(collection != NULL, "Expected non-NULL collection\n");
567 length = 0;
568 hr = IXMLElementCollection_get_length(collection, &length);
569 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
570 ok(length == 1, "Expected 1, got %08x\n", length);
572 /* remove/add child and check what happens with collection */
573 hr = IXMLElement_removeChild(element, child);
574 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
576 length = -1;
577 hr = IXMLElementCollection_get_length(collection, &length);
578 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
579 ok(length == 0, "Expected 0, got %08x\n", length);
580 IXMLElementCollection_Release(collection);
582 hr = IXMLElement_AddRef(child);
583 ok(hr == 2, "Expected 2, got %08x\n", hr);
584 IXMLElement_Release(child);
585 hr = IXMLElement_addChild(element, child, 0, -1);
586 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
587 hr = IXMLElement_AddRef(child);
588 ok(hr == 2, "Expected 2, got %08x\n", hr);
589 IXMLElement_Release(child);
590 hr = IXMLElement_addChild(element, child2, 0, -1);
591 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
593 hr = IXMLElement_get_children(element, &collection);
594 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
595 ok(collection != NULL, "Expected non-NULL collection\n");
597 hr = IXMLElement_AddRef(child);
598 ok(hr == 2, "Expected 2, got %08x\n", hr);
599 IXMLElement_Release(child);
601 length = 0;
602 hr = IXMLElementCollection_get_length(collection, &length);
603 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
604 ok(length == 2, "Expected 2, got %08x\n", length);
606 IXMLElement_Release(child2);
608 length = 0;
609 hr = IXMLElementCollection_get_length(collection, &length);
610 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
611 ok(length == 2, "Expected 2, got %08x\n", length);
613 V_VT(&vIndex) = VT_I4;
614 V_I4(&vIndex) = 1;
615 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child2);
616 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
617 ok(child2 != NULL, "Expected not NULL child\n");
618 IXMLElementCollection_Release(collection);
619 IXMLElement_Release(child2);
621 /* add element->child->child2 structure, then remove child2 from node */
622 V_VT(&vType) = VT_I4;
623 V_I4(&vType) = XMLELEMTYPE_TEXT;
624 V_VT(&vName) = VT_NULL;
625 hr = IXMLDocument_createElement(doc, vType, vName, &child2);
626 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
627 ok(child2 != NULL, "Expected non-NULL child\n");
629 hr = IXMLElement_addChild(child, child2, 0, -1);
630 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
632 hr = IXMLElement_removeChild(element, child2);
633 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
635 hr = IXMLElement_removeChild(child, child2);
636 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
638 hr = IXMLElement_removeChild(child, NULL);
639 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
641 IXMLElement_Release(element);
642 IXMLElement_Release(child);
643 IXMLElement_Release(child2);
644 IXMLDocument_Release(doc);
647 static void test_xmlelem_collection(void)
649 HRESULT hr;
650 IUnknown *unk = NULL;
651 IXMLDocument *doc = NULL;
652 IXMLElement *element = NULL, *child;
653 IXMLElementCollection *collection = NULL;
654 IEnumVARIANT *enumVar = NULL;
655 CHAR pathA[MAX_PATH];
656 WCHAR path[MAX_PATH];
657 LONG length, type;
658 ULONG num_vars;
659 VARIANT var, dummy, vIndex, vName;
660 BSTR url, str;
661 static const CHAR szBankXML[] = "bank.xml";
662 static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
663 static const WCHAR szName[] = {'N','A','M','E',0};
665 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
666 &IID_IXMLDocument, (LPVOID*)&doc);
667 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
669 create_xml_file(szBankXML);
670 GetFullPathNameA(szBankXML, MAX_PATH, pathA, NULL);
671 MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
673 url = SysAllocString(path);
674 hr = IXMLDocument_put_URL(doc, url);
675 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
676 SysFreeString(url);
678 if(hr != S_OK)
679 goto cleanup;
681 hr = IXMLDocument_get_root(doc, &element);
682 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
683 ok(element != NULL, "Expected non-NULL element\n");
685 hr = IXMLElement_get_children(element, &collection);
686 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
687 ok(collection != NULL, "Expected non-NULL collection\n");
689 hr = IXMLElementCollection_get_length(collection, NULL);
690 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
692 hr = IXMLElementCollection_get_length(collection, &length);
693 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
694 ok(length == 2, "Expected 2, got %d\n", length);
696 /* IXMLElementCollection:put_length does nothing */
697 hr = IXMLElementCollection_put_length(collection, -1);
698 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
700 hr = IXMLElementCollection_put_length(collection, 0);
701 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
703 hr = IXMLElementCollection_put_length(collection, 1);
704 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
706 hr = IXMLElementCollection_put_length(collection, 2);
707 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
709 hr = IXMLElementCollection_put_length(collection, 3);
710 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
712 hr = IXMLElementCollection_put_length(collection, 50);
713 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
715 /* make sure the length hasn't changed */
716 hr = IXMLElementCollection_get_length(collection, &length);
717 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
718 ok(length == 2, "Expected 2, got %d\n", length);
720 /* IXMLElementCollection implements IEnumVARIANT */
721 hr = IXMLElementCollection_QueryInterface(collection, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
722 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
723 ok(enumVar != NULL, "Expected non-NULL enumVar\n");
724 IEnumVARIANT_Release(enumVar);
726 hr = IXMLElementCollection_get__newEnum(collection, &unk);
727 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
728 ok(unk != NULL, "Expected non-NULL unk\n");
730 enumVar = (void *)0xdeadbeef;
731 hr = IUnknown_QueryInterface(unk, &IID_IXMLElementCollection, (LPVOID *)&enumVar);
732 ok(hr == E_NOINTERFACE, "Expected E_NOINTERFACE, got %08x\n", hr);
733 ok(enumVar == NULL || broken(enumVar == (void *)0xdeadbeef) /* XP */, "Expected NULL, got %p\n", enumVar);
735 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (LPVOID *)&enumVar);
736 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
737 ok(enumVar != NULL, "Expected non-NULL enumVar\n");
738 IUnknown_Release(unk);
740 /* <Number>1234</Number> */
741 hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
742 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
743 ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
744 ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
746 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
747 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
748 ok(child != NULL, "Expected non-NULL child\n");
750 VariantClear(&var);
752 hr = IXMLElement_get_type(child, &type);
753 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
754 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
756 hr = IXMLElement_get_tagName(child, &str);
757 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
758 ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
759 SysFreeString(str);
760 IXMLElement_Release(child);
762 /* <Name>Captain Ahab</Name> */
763 hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
764 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
765 ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
766 ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
768 /* try advance further, no children left */
769 V_VT(&dummy) = VT_I4;
770 hr = IEnumVARIANT_Next(enumVar, 1, &dummy, &num_vars);
771 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
772 ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy));
773 ok(num_vars == 0, "Expected 0, got %d\n", num_vars);
775 V_VT(&dummy) = VT_I4;
776 hr = IEnumVARIANT_Next(enumVar, 1, &dummy, NULL);
777 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
778 ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy));
780 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
781 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
782 ok(child != NULL, "Expected non-NULL child\n");
784 VariantClear(&var);
786 hr = IXMLElement_get_type(child, &type);
787 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
788 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
790 hr = IXMLElement_get_tagName(child, &str);
791 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
792 ok(!lstrcmpW(str, szName), "Expected NAME\n");
793 SysFreeString(str);
794 IXMLElement_Release(child);
796 /* <Number>1234</Number> */
797 V_VT(&vIndex) = VT_I4;
798 V_I4(&vIndex) = 0;
799 V_VT(&vName) = VT_ERROR;
800 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
801 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
802 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
803 ok(child != NULL, "Expected non-NULL child\n");
805 hr = IXMLElement_get_type(child, &type);
806 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
807 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
809 hr = IXMLElement_get_tagName(child, &str);
810 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
811 ok(!lstrcmpW(str, szNumber), "Expected NUMBER\n");
812 SysFreeString(str);
813 IXMLElement_Release(child);
815 /* <Name>Captain Ahab</Name> */
816 V_VT(&vIndex) = VT_I4;
817 V_I4(&vIndex) = 1;
818 V_VT(&vName) = VT_ERROR;
819 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
820 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
821 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
822 ok(child != NULL, "Expected non-NULL child\n");
824 hr = IXMLElement_get_type(child, &type);
825 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
826 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
828 hr = IXMLElement_get_tagName(child, &str);
829 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
830 ok(!lstrcmpW(str, szName), "Expected NAME\n");
831 SysFreeString(str);
832 IXMLElement_Release(child);
834 V_I4(&vIndex) = 100;
835 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
836 ok(hr == E_FAIL, "Expected E_FAIL, got %08x\n", hr);
837 ok(child == NULL, "Expected NULL child\n");
839 V_I4(&vIndex) = -1;
840 child = (IXMLElement *)0xdeadbeef;
841 hr = IXMLElementCollection_item(collection, vIndex, vName, (IDispatch **)&child);
842 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);
843 ok(child == NULL, "Expected NULL child\n");
845 IEnumVARIANT_Release(enumVar);
846 IXMLElement_Release(element);
847 IXMLElementCollection_Release(collection);
848 cleanup:
849 IXMLDocument_Release(doc);
850 DeleteFileA("bank.xml");
853 static void test_xmlelem(void)
855 HRESULT hr;
856 IXMLDocument *doc = NULL;
857 IXMLElement *element = NULL, *parent;
858 IXMLElement *child, *child2;
859 IXMLElementCollection *children;
860 VARIANT vType, vName;
861 VARIANT vIndex, vValue;
862 BSTR str, val, name;
863 LONG type, num_child;
864 IDispatch *disp;
865 ITypeInfo *ti;
867 static const WCHAR propName[] = {'p','r','o','p',0};
868 static const WCHAR propVal[] = {'v','a','l',0};
869 static const WCHAR nextVal[] = {'n','e','x','t',0};
870 static const WCHAR noexist[] = {'n','o','e','x','i','s','t',0};
871 static const WCHAR crazyCase1[] = {'C','R','a','z','Y','c','A','S','E',0};
872 static const WCHAR crazyCase2[] = {'C','R','A','Z','Y','C','A','S','E',0};
874 hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
875 &IID_IXMLDocument, (LPVOID*)&doc);
876 EXPECT_HR(hr, S_OK);
878 V_VT(&vType) = VT_I4;
879 V_I4(&vType) = XMLELEMTYPE_ELEMENT;
880 V_VT(&vName) = VT_NULL;
881 hr = IXMLDocument_createElement(doc, vType, vName, &element);
882 EXPECT_HR(hr, S_OK);
883 ok(element != NULL, "Expected non-NULL element\n");
885 /* test for IDispatch */
886 disp = NULL;
887 hr = IXMLElement_QueryInterface(element, &IID_IDispatch, (void**)&disp);
888 EXPECT_HR(hr, S_OK);
890 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
891 EXPECT_HR(hr, S_OK);
893 name = NULL;
894 hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLELEMENT_TAGNAME, &name, NULL, NULL, NULL);
895 EXPECT_HR(hr, S_OK);
896 SysFreeString(name);
898 ITypeInfo_Release(ti);
899 IDispatch_Release(disp);
901 hr = IXMLElement_get_tagName(element, &str);
902 EXPECT_HR(hr, S_OK);
903 ok(!str, "Expected empty tag name, got %s\n", wine_dbgstr_w(str));
904 SysFreeString(str);
906 parent = (IXMLElement *)0xdeadbeef;
907 hr = IXMLElement_get_parent(element, &parent);
908 ok(hr == 1, "Expected 1, got %08x\n", hr);
909 ok(parent == NULL, "Expected NULL parent\n");
911 str = SysAllocString(noexist);
912 hr = IXMLElement_getAttribute(element, str, &vValue);
913 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
914 ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
915 ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
916 VariantClear(&vValue);
917 SysFreeString(str);
919 str = SysAllocString(crazyCase1);
920 val = SysAllocString(propVal);
921 V_VT(&vValue) = VT_BSTR;
922 V_BSTR(&vValue) = val;
923 hr = IXMLElement_setAttribute(element, str, vValue);
924 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
925 SysFreeString(str);
926 SysFreeString(val);
928 str = SysAllocString(crazyCase2);
929 hr = IXMLElement_getAttribute(element, str, &vValue);
930 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
931 ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
932 ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
933 VariantClear(&vValue);
934 SysFreeString(str);
936 str = SysAllocString(propName);
937 val = SysAllocString(propVal);
938 V_VT(&vValue) = VT_BSTR;
939 V_BSTR(&vValue) = val;
940 hr = IXMLElement_setAttribute(element, str, vValue);
941 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
942 SysFreeString(val);
944 hr = IXMLElement_getAttribute(element, str, &vValue);
945 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
946 ok(V_VT(&vValue) == VT_BSTR, "Expected VT_BSTR, got %d\n", V_VT(&vValue));
947 ok(!lstrcmpW(V_BSTR(&vValue), propVal), "Expected 'val'\n");
948 VariantClear(&vValue);
950 hr = IXMLElement_removeAttribute(element, str);
951 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
953 /* remove now nonexistent attribute */
954 hr = IXMLElement_removeAttribute(element, str);
955 ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
957 hr = IXMLElement_getAttribute(element, str, &vValue);
958 ok(hr == 1, "Expected 1, got %08x\n", hr);
959 ok(V_VT(&vValue) == VT_EMPTY, "Expected VT_EMPTY, got %d\n", V_VT(&vValue));
960 ok(V_BSTR(&vValue) == NULL, "Expected null value\n");
961 SysFreeString(str);
962 VariantClear(&vValue);
964 children = (IXMLElementCollection *)0xdeadbeef;
965 hr = IXMLElement_get_children(element, &children);
966 ok(hr == 1, "Expected 1, got %08x\n", hr);
967 ok(children == NULL, "Expected NULL collection\n");
969 hr = IXMLElement_get_type(element, &type);
970 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
971 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
973 hr = IXMLElement_get_text(element, &str);
974 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
975 ok(lstrlenW(str) == 0, "Expected empty text\n");
976 SysFreeString(str);
978 /* put_text with an ELEMENT */
979 str = SysAllocString(propVal);
980 hr = IXMLElement_put_text(element, str);
981 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
982 SysFreeString(str);
984 V_VT(&vType) = VT_I4;
985 V_I4(&vType) = XMLELEMTYPE_TEXT;
986 V_VT(&vName) = VT_NULL;
987 hr = IXMLDocument_createElement(doc, vType, vName, &child);
988 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
989 ok(child != NULL, "Expected non-NULL child\n");
991 hr = IXMLElement_addChild(element, child, 0, -1);
992 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
994 str = SysAllocString(propVal);
995 hr = IXMLElement_put_text(child, str);
996 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
997 SysFreeString(str);
999 parent = (IXMLElement *)0xdeadbeef;
1000 hr = IXMLElement_get_parent(child, &parent);
1001 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1002 ok(parent != element, "Expected parent != element\n");
1004 hr = IXMLElement_get_type(parent, &type);
1005 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1006 ok(type == XMLELEMTYPE_ELEMENT, "Expected XMLELEMTYPE_ELEMENT, got %d\n", type);
1008 children = (IXMLElementCollection *)0xdeadbeef;
1009 hr = IXMLElement_get_children(element, &children);
1010 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1011 ok(children != NULL, "Expected non-NULL collection\n");
1013 hr = IXMLElementCollection_get_length(children, &num_child);
1014 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1015 ok(num_child == 1, "Expected 1, got %d\n", num_child);
1017 V_VT(&vIndex) = VT_I4;
1018 V_I4(&vIndex) = 0;
1019 V_VT(&vName) = VT_ERROR;
1020 V_ERROR(&vName) = DISP_E_PARAMNOTFOUND;
1021 hr = IXMLElementCollection_item(children, vIndex, vName, (IDispatch **)&child2);
1022 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1023 ok(child2 != NULL, "Expected non-NULL child\n");
1025 hr = IXMLElement_get_type(child2, &type);
1026 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1027 ok(type == XMLELEMTYPE_TEXT, "Expected XMLELEMTYPE_TEXT, got %d\n", type);
1029 hr = IXMLElement_get_text(element, &str);
1030 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1031 ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
1032 SysFreeString(str);
1034 hr = IXMLElement_get_text(child2, &str);
1035 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1036 ok(!lstrcmpW(str, propVal), "Expected 'val'\n");
1037 SysFreeString(str);
1039 /* try put_text on ELEMENT again, now that it has a text child */
1040 str = SysAllocString(nextVal);
1041 hr = IXMLElement_put_text(element, str);
1042 ok(hr == E_NOTIMPL, "Expected E_NOTIMPL, got %08x\n", hr);
1043 SysFreeString(str);
1045 str = SysAllocString(nextVal);
1046 hr = IXMLElement_put_text(child2, str);
1047 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1048 SysFreeString(str);
1050 hr = IXMLElement_get_text(element, &str);
1051 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1052 ok(!lstrcmpW(str, nextVal), "Expected 'val'\n");
1053 SysFreeString(str);
1055 IXMLElement_Release(child2);
1056 IXMLElementCollection_Release(children);
1057 IXMLElement_Release(parent);
1058 IXMLElement_Release(child);
1059 IXMLElement_Release(element);
1060 IXMLDocument_Release(doc);
1063 START_TEST(xmldoc)
1065 HRESULT hr;
1067 hr = CoInitialize(NULL);
1068 ok(hr == S_OK, "failed to init com\n");
1070 if (!test_try_xmldoc())
1072 CoUninitialize();
1073 return;
1076 test_xmldoc();
1077 test_createElement();
1078 test_persiststreaminit();
1079 test_xmlelem();
1080 test_xmlelem_collection();
1081 test_xmlelem_children();
1083 CoUninitialize();