msxml: Fix for get_nodeValue on attributes.
[wine/multimedia.git] / dlls / msxml3 / tests / domdoc.c
blob5d745ced17799c595fa2edb30d4f9fd335b86afb
1 /*
2 * XML test
4 * Copyright 2005 Mike McCormack for CodeWeavers
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define COBJMACROS
24 #include "windows.h"
25 #include "ole2.h"
26 #include "msxml2.h"
27 #include <stdio.h>
29 #include "wine/test.h"
31 static const WCHAR szEmpty[] = { 0 };
32 static const WCHAR szIncomplete[] = {
33 '<','?','x','m','l',' ',
34 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
36 static const WCHAR szComplete1[] = {
37 '<','?','x','m','l',' ',
38 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
39 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
41 static const WCHAR szComplete2[] = {
42 '<','?','x','m','l',' ',
43 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
44 '<','o','>','<','/','o','>','\n',0
46 static const WCHAR szComplete3[] = {
47 '<','?','x','m','l',' ',
48 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
49 '<','a','>','<','/','a','>','\n',0
51 static const WCHAR szComplete4[] = {
52 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
53 '<','l','c',' ','d','l','=','\'','s','t','r','1','\'','>','\n',
54 '<','b','s',' ','v','r','=','\'','s','t','r','2','\'',' ','s','z','=','\'','1','2','3','4','\'','>',
55 'f','n','1','.','t','x','t','\n',
56 '<','/','b','s','>','\n',
57 '<','p','r',' ','i','d','=','\'','s','t','r','3','\'',' ','v','r','=','\'','1','.','2','.','3','\'',' ',
58 'p','n','=','\'','w','i','n','e',' ','2','0','0','5','0','8','0','4','\'','>','\n',
59 'f','n','2','.','t','x','t','\n',
60 '<','/','p','r','>','\n',
61 '<','/','l','c','>','\n',0
63 static const WCHAR szNonExistentFile[] = {
64 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
66 static const WCHAR szDocument[] = {
67 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
70 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
71 static const WCHAR szdl[] = { 'd','l',0 };
72 static const WCHAR szlc[] = { 'l','c',0 };
73 static const WCHAR szbs[] = { 'b','s',0 };
74 static const WCHAR szstr1[] = { 's','t','r','1',0 };
75 static const WCHAR szstr2[] = { 's','t','r','2',0 };
77 void test_domdoc( void )
79 HRESULT r;
80 IXMLDOMDocument *doc = NULL;
81 IXMLDOMParseError *error;
82 IXMLDOMElement *element = NULL;
83 VARIANT_BOOL b;
84 VARIANT var;
85 BSTR str;
86 long code;
88 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
89 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
90 if( r != S_OK )
91 return;
93 /* try some stupid things */
94 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
95 ok( r == S_FALSE, "loadXML failed\n");
97 b = VARIANT_TRUE;
98 r = IXMLDOMDocument_loadXML( doc, NULL, &b );
99 ok( r == S_FALSE, "loadXML failed\n");
100 ok( b == VARIANT_FALSE, "failed to load XML string\n");
102 /* try to load a document from a nonexistent file */
103 b = VARIANT_TRUE;
104 str = SysAllocString( szNonExistentFile );
105 VariantInit(&var);
106 V_VT(&var) = VT_BSTR;
107 V_BSTR(&var) = str;
109 r = IXMLDOMDocument_load( doc, var, &b);
110 ok( r == S_FALSE, "load (from file) failed\n");
111 ok( b == VARIANT_FALSE, "failed to load XML file\n");
112 SysFreeString( str );
114 /* try load an empty document */
115 b = VARIANT_TRUE;
116 str = SysAllocString( szEmpty );
117 r = IXMLDOMDocument_loadXML( doc, str, &b );
118 ok( r == S_FALSE, "loadXML failed\n");
119 ok( b == VARIANT_FALSE, "failed to load XML string\n");
120 SysFreeString( str );
122 /* check that there's no document element */
123 element = NULL;
124 r = IXMLDOMDocument_get_documentElement( doc, &element );
125 ok( r == S_FALSE, "should be no document element\n");
127 b = VARIANT_TRUE;
128 str = SysAllocString( szIncomplete );
129 r = IXMLDOMDocument_loadXML( doc, str, &b );
130 ok( r == S_FALSE, "loadXML failed\n");
131 ok( b == VARIANT_FALSE, "failed to load XML string\n");
132 SysFreeString( str );
134 /* check that there's no document element */
135 element = (IXMLDOMElement*)1;
136 r = IXMLDOMDocument_get_documentElement( doc, &element );
137 ok( r == S_FALSE, "should be no document element\n");
138 ok( element == NULL, "Element should be NULL\n");
140 /* try to load something valid */
141 b = VARIANT_FALSE;
142 str = SysAllocString( szComplete1 );
143 r = IXMLDOMDocument_loadXML( doc, str, &b );
144 ok( r == S_OK, "loadXML failed\n");
145 ok( b == VARIANT_TRUE, "failed to load XML string\n");
146 SysFreeString( str );
148 /* try with a null out pointer - crashes */
149 if (0)
151 r = IXMLDOMDocument_get_documentElement( doc, NULL );
152 ok( r == S_OK, "should be no document element\n");
155 /* check if nodename is correct */
156 r = IXMLDOMDocument_get_nodeName( doc, NULL );
157 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
159 /* content doesn't matter here */
160 str = SysAllocString( szNonExistentFile );
161 r = IXMLDOMDocument_get_nodeName( doc, &str );
162 ok ( r == S_OK, "get_nodeName wrong code\n");
163 ok ( str != NULL, "str is null\n");
164 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
165 SysFreeString( str );
168 /* check that there's a document element */
169 element = NULL;
170 r = IXMLDOMDocument_get_documentElement( doc, &element );
171 ok( r == S_OK, "should be a document element\n");
172 if( element )
174 BSTR tag = NULL;
176 /* check if the tag is correct */
177 r = IXMLDOMElement_get_tagName( element, &tag );
178 ok( r == S_OK, "couldn't get tag name\n");
179 ok( tag != NULL, "tag was null\n");
180 ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
181 SysFreeString( tag );
183 /* figure out what happens if we try to reload the document */
184 str = SysAllocString( szComplete2 );
185 r = IXMLDOMDocument_loadXML( doc, str, &b );
186 ok( r == S_OK, "loadXML failed\n");
187 ok( b == VARIANT_TRUE, "failed to load XML string\n");
188 SysFreeString( str );
190 /* check if the tag is still correct */
191 tag = NULL;
192 r = IXMLDOMElement_get_tagName( element, &tag );
193 ok( r == S_OK, "couldn't get tag name\n");
194 ok( tag != NULL, "tag was null\n");
195 ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
196 SysFreeString( tag );
198 IXMLDOMElement_Release( element );
199 element = NULL;
202 /* as soon as we call loadXML again, the document element will disappear */
203 b = 2;
204 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
205 ok( r == S_FALSE, "loadXML failed\n");
206 ok( b == 2, "variant modified\n");
207 r = IXMLDOMDocument_get_documentElement( doc, &element );
208 ok( r == S_FALSE, "should be no document element\n");
210 /* try to load something else simple and valid */
211 b = VARIANT_FALSE;
212 str = SysAllocString( szComplete3 );
213 r = IXMLDOMDocument_loadXML( doc, str, &b );
214 ok( r == S_OK, "loadXML failed\n");
215 ok( b == VARIANT_TRUE, "failed to load XML string\n");
216 SysFreeString( str );
218 /* try something a little more complicated */
219 b = FALSE;
220 str = SysAllocString( szComplete4 );
221 r = IXMLDOMDocument_loadXML( doc, str, &b );
222 ok( r == S_OK, "loadXML failed\n");
223 ok( b == VARIANT_TRUE, "failed to load XML string\n");
224 SysFreeString( str );
226 r = IXMLDOMDocument_get_parseError( doc, &error );
227 ok( r == S_OK, "returns %08lx\n", r );
229 r = IXMLDOMParseError_get_errorCode( error, &code );
230 ok( r == S_FALSE, "returns %08lx\n", r );
231 ok( code == 0, "code %ld\n", code );
232 IXMLDOMParseError_Release( error );
234 r = IXMLDOMDocument_Release( doc );
235 ok( r == 0, "document ref count incorrect\n");
239 void test_domnode( void )
241 HRESULT r;
242 IXMLDOMDocument *doc = NULL, *owner = NULL;
243 IXMLDOMElement *element = NULL;
244 IXMLDOMNamedNodeMap *map = NULL;
245 IXMLDOMNode *node = NULL, *next = NULL;
246 IXMLDOMNodeList *list = NULL;
247 DOMNodeType type = NODE_INVALID;
248 VARIANT_BOOL b;
249 BSTR str;
250 VARIANT var;
251 long count;
253 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
254 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
255 if( r != S_OK )
256 return;
258 b = FALSE;
259 str = SysAllocString( szComplete4 );
260 r = IXMLDOMDocument_loadXML( doc, str, &b );
261 ok( r == S_OK, "loadXML failed\n");
262 ok( b == VARIANT_TRUE, "failed to load XML string\n");
263 SysFreeString( str );
265 if (doc)
267 b = 1;
268 r = IXMLDOMNode_hasChildNodes( doc, &b );
269 ok( r == S_OK, "hasChildNoes bad return\n");
270 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
272 r = IXMLDOMDocument_get_documentElement( doc, &element );
273 ok( r == S_OK, "should be a document element\n");
274 ok( element != NULL, "should be an element\n");
276 else
277 ok( FALSE, "no document\n");
279 VariantInit(&var);
280 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
281 r = IXMLDOMNode_get_nodeValue( doc, &var );
282 ok( r == S_FALSE, "nextNode returned wrong code\n");
283 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
284 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
286 if (element)
288 owner = NULL;
289 r = IXMLDOMNode_get_ownerDocument( element, &owner );
290 todo_wine {
291 ok( r == S_OK, "get_ownerDocument return code\n");
293 ok( owner != doc, "get_ownerDocument return\n");
295 type = NODE_INVALID;
296 r = IXMLDOMNode_get_nodeType( element, &type);
297 ok( r == S_OK, "getNamedItem returned wrong code\n");
298 ok( type == NODE_ELEMENT, "node not an element\n");
300 str = NULL;
301 r = IXMLDOMNode_get_baseName( element, &str );
302 ok( r == S_OK, "get_baseName returned wrong code\n");
303 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
305 /* check if nodename is correct */
306 r = IXMLDOMElement_get_nodeName( element, NULL );
307 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
309 /* content doesn't matter here */
310 str = SysAllocString( szNonExistentFile );
311 r = IXMLDOMElement_get_nodeName( element, &str );
312 ok ( r == S_OK, "get_nodeName wrong code\n");
313 ok ( str != NULL, "str is null\n");
314 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
315 SysFreeString( str );
317 str = SysAllocString( szNonExistentFile );
318 V_VT(&var) = VT_I4;
319 V_I4(&var) = 0x1234;
320 r = IXMLDOMElement_getAttribute( element, str, &var );
321 ok( r == E_FAIL, "getAttribute ret %08lx\n", r );
322 ok( V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
323 VariantClear(&var);
324 SysFreeString( str );
326 str = SysAllocString( szdl );
327 V_VT(&var) = VT_I4;
328 V_I4(&var) = 0x1234;
329 r = IXMLDOMElement_getAttribute( element, str, &var );
330 ok( r == S_OK, "getAttribute ret %08lx\n", r );
331 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
332 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
333 VariantClear( &var );
334 SysFreeString( str );
336 r = IXMLDOMElement_get_attributes( element, &map );
337 ok( r == S_OK, "get_attributes returned wrong code\n");
338 ok( map != NULL, "should be attributes\n");
340 b = 1;
341 r = IXMLDOMNode_hasChildNodes( element, &b );
342 ok( r == S_OK, "hasChildNoes bad return\n");
343 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
345 else
346 ok( FALSE, "no element\n");
348 if (map)
350 str = SysAllocString( szdl );
351 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
352 ok( r == S_OK, "getNamedItem returned wrong code\n");
353 ok( node != NULL, "should be attributes\n");
354 IXMLDOMNode_Release(node);
355 SysFreeString( str );
357 /* test indexed access of attributes */
358 r = IXMLDOMNamedNodeMap_get_length( map, &count );
359 ok ( r == S_OK, "get_length wrong code\n");
360 ok ( count == 1, "get_length != 1\n");
362 node = NULL;
363 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
364 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
365 ok ( node == NULL, "there is no node\n");
367 node = NULL;
368 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
369 ok ( r == S_FALSE, "get_item (1) wrong code\n");
370 ok ( node == NULL, "there is no attribute\n");
372 node = NULL;
373 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
374 ok ( r == S_OK, "get_item (0) wrong code\n");
375 ok ( node != NULL, "should be attribute\n");
377 r = IXMLDOMNode_get_nodeName( node, NULL );
378 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
380 /* content doesn't matter here */
381 str = SysAllocString( szNonExistentFile );
382 r = IXMLDOMNode_get_nodeName( node, &str );
383 ok ( r == S_OK, "get_nodeName wrong code\n");
384 ok ( str != NULL, "str is null\n");
385 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
386 SysFreeString( str );
388 else
389 ok( FALSE, "no map\n");
391 if (node)
393 type = NODE_INVALID;
394 r = IXMLDOMNode_get_nodeType( node, &type);
395 ok( r == S_OK, "getNamedItem returned wrong code\n");
396 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
398 str = NULL;
399 r = IXMLDOMNode_get_baseName( node, NULL );
400 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
402 str = NULL;
403 r = IXMLDOMNode_get_baseName( node, &str );
404 ok( r == S_OK, "get_baseName returned wrong code\n");
405 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
407 r = IXMLDOMNode_get_nodeValue( node, &var );
408 ok( r == S_OK, "returns %08lx\n", r );
409 ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
410 ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
411 VariantClear(&var);
413 r = IXMLDOMNode_get_childNodes( node, NULL );
414 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
416 r = IXMLDOMNode_get_childNodes( node, &list );
417 ok( r == S_OK, "get_childNodes returned wrong code\n");
419 if (list)
421 r = IXMLDOMNodeList_nextNode( list, &next );
422 ok( r == S_OK, "nextNode returned wrong code\n");
424 else
425 ok( FALSE, "no childlist\n");
427 if (next)
429 b = 1;
430 r = IXMLDOMNode_hasChildNodes( next, &b );
431 ok( r == S_FALSE, "hasChildNoes bad return\n");
432 ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
434 type = NODE_INVALID;
435 r = IXMLDOMNode_get_nodeType( next, &type);
436 ok( r == S_OK, "getNamedItem returned wrong code\n");
437 ok( type == NODE_TEXT, "node not text\n");
439 str = (BSTR) 1;
440 r = IXMLDOMNode_get_baseName( next, &str );
441 ok( r == S_FALSE, "get_baseName returned wrong code\n");
442 ok( str == NULL, "basename was wrong\n");
444 else
445 ok( FALSE, "no next\n");
447 if (next)
448 IXMLDOMNode_Release( next );
449 next = NULL;
450 if (list)
451 IXMLDOMNodeList_Release( list );
452 list = NULL;
453 if (node)
454 IXMLDOMNode_Release( node );
456 else
457 ok( FALSE, "no node\n");
458 node = NULL;
460 if (map)
461 IXMLDOMNamedNodeMap_Release( map );
463 /* now traverse the tree from the root node */
464 if (element)
466 r = IXMLDOMNode_get_childNodes( element, &list );
467 ok( r == S_OK, "get_childNodes returned wrong code\n");
469 else
470 ok( FALSE, "no element\n");
472 r = IXMLDOMNode_selectSingleNode( element, (BSTR)szdl, &node );
473 ok( r == S_FALSE, "ret %08lx\n", r );
474 r = IXMLDOMNode_selectSingleNode( element, (BSTR)szbs, &node );
475 ok( r == S_OK, "ret %08lx\n", r );
476 r = IXMLDOMNode_Release( node );
477 ok( r == 0, "ret %08lx\n", r );
479 if (list)
481 r = IXMLDOMNodeList_get_length( list, &count );
482 ok( r == S_OK, "get_length returns %08lx\n", r );
483 ok( count == 2, "get_length got %ld\n", count );
485 r = IXMLDOMNodeList_nextNode( list, &node );
486 ok( r == S_OK, "nextNode returned wrong code\n");
488 else
489 ok( FALSE, "no list\n");
491 if (node)
493 type = NODE_INVALID;
494 r = IXMLDOMNode_get_nodeType( node, &type);
495 ok( r == S_OK, "getNamedItem returned wrong code\n");
496 ok( type == NODE_ELEMENT, "node not text\n");
498 VariantInit(&var);
499 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
500 r = IXMLDOMNode_get_nodeValue( node, &var );
501 ok( r == S_FALSE, "nextNode returned wrong code\n");
502 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
503 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
505 r = IXMLDOMNode_hasChildNodes( node, NULL );
506 ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
508 b = 1;
509 r = IXMLDOMNode_hasChildNodes( node, &b );
510 ok( r == S_OK, "hasChildNoes bad return\n");
511 ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
513 str = NULL;
514 r = IXMLDOMNode_get_baseName( node, &str );
515 ok( r == S_OK, "get_baseName returned wrong code\n");
516 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
518 else
519 ok( FALSE, "no node\n");
521 if (node)
522 IXMLDOMNode_Release( node );
523 if (list)
524 IXMLDOMNodeList_Release( list );
525 if (element)
526 IXMLDOMElement_Release( element );
527 if (doc)
528 IXMLDOMDocument_Release( doc );
531 static void test_refs(void)
533 HRESULT r;
534 BSTR str;
535 VARIANT_BOOL b;
536 IXMLDOMDocument *doc = NULL;
537 IXMLDOMElement *element = NULL;
538 IXMLDOMNode *node = NULL, *node2;
539 IXMLDOMNodeList *node_list = NULL;
540 LONG ref;
541 IUnknown *unk, *unk2;
543 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
544 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
545 if( r != S_OK )
546 return;
547 ref = IXMLDOMDocument_Release(doc);
548 ok( ref == 0, "ref %ld\n", ref);
550 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
551 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
552 if( r != S_OK )
553 return;
555 str = SysAllocString( szComplete4 );
556 r = IXMLDOMDocument_loadXML( doc, str, &b );
557 ok( r == S_OK, "loadXML failed\n");
558 ok( b == VARIANT_TRUE, "failed to load XML string\n");
559 SysFreeString( str );
561 ref = IXMLDOMDocument_AddRef( doc );
562 ok( ref == 2, "ref %ld\n", ref );
563 ref = IXMLDOMDocument_AddRef( doc );
564 ok( ref == 3, "ref %ld\n", ref );
565 IXMLDOMDocument_Release( doc );
566 IXMLDOMDocument_Release( doc );
568 r = IXMLDOMDocument_get_documentElement( doc, &element );
569 ok( r == S_OK, "should be a document element\n");
570 ok( element != NULL, "should be an element\n");
572 ref = IXMLDOMDocument_AddRef( doc );
573 ok( ref == 2, "ref %ld\n", ref );
574 IXMLDOMDocument_Release( doc );
576 r = IXMLDOMElement_get_childNodes( element, &node_list );
577 ok( r == S_OK, "rets %08lx\n", r);
578 ref = IXMLDOMNodeList_AddRef( node_list );
579 ok( ref == 2, "ref %ld\n", ref );
580 IXMLDOMNodeList_Release( node_list );
582 IXMLDOMNodeList_get_item( node_list, 0, &node );
583 ok( r == S_OK, "rets %08lx\n", r);
585 IXMLDOMNodeList_get_item( node_list, 0, &node2 );
586 ok( r == S_OK, "rets %08lx\n", r);
588 ref = IXMLDOMNode_AddRef( node );
589 ok( ref == 2, "ref %ld\n", ref );
590 IXMLDOMNode_Release( node );
592 ref = IXMLDOMNode_Release( node );
593 ok( ref == 0, "ref %ld\n", ref );
594 ref = IXMLDOMNode_Release( node2 );
595 ok( ref == 0, "ref %ld\n", ref );
597 ref = IXMLDOMNodeList_Release( node_list );
598 ok( ref == 0, "ref %ld\n", ref );
600 ok( node != node2, "node %p node2 %p\n", node, node2 );
602 ref = IXMLDOMDocument_Release( doc );
603 ok( ref == 0, "ref %ld\n", ref );
605 ref = IXMLDOMElement_AddRef( element );
606 todo_wine {
607 ok( ref == 3, "ref %ld\n", ref );
609 IXMLDOMElement_Release( element );
611 /* IUnknown must be unique however we obtain it */
612 r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (LPVOID*)&unk );
613 ok( r == S_OK, "rets %08lx\n", r );
614 r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (LPVOID*)&node );
615 ok( r == S_OK, "rets %08lx\n", r );
616 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk2 );
617 ok( r == S_OK, "rets %08lx\n", r );
618 ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
620 IUnknown_Release( unk2 );
621 IUnknown_Release( unk );
622 IXMLDOMNode_Release( node );
624 IXMLDOMElement_Release( element );
628 static void test_create(void)
630 HRESULT r;
631 VARIANT var;
632 BSTR str, name;
633 IXMLDOMDocument *doc;
634 IXMLDOMElement *element;
635 IXMLDOMNode *root, *node, *child;
636 IXMLDOMNamedNodeMap *attr_map;
637 IUnknown *unk;
638 LONG ref, num;
640 r = CoCreateInstance( &CLSID_DOMDocument, NULL,
641 CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
642 if( r != S_OK )
643 return;
645 V_VT(&var) = VT_I4;
646 V_I4(&var) = NODE_ELEMENT;
647 str = SysAllocString( szlc );
648 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
649 ok( r == S_OK, "returns %08lx\n", r );
650 r = IXMLDOMDocument_appendChild( doc, node, &root );
651 ok( r == S_OK, "returns %08lx\n", r );
652 ok( node == root, "%p %p\n", node, root );
654 ref = IXMLDOMNode_AddRef( node );
655 ok(ref == 3, "ref %ld\n", ref);
656 IXMLDOMNode_Release( node );
658 ref = IXMLDOMNode_Release( node );
659 ok(ref == 1, "ref %ld\n", ref);
660 SysFreeString( str );
662 V_VT(&var) = VT_I4;
663 V_I4(&var) = NODE_ELEMENT;
664 str = SysAllocString( szbs );
665 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
666 ok( r == S_OK, "returns %08lx\n", r );
668 ref = IXMLDOMNode_AddRef( node );
669 ok(ref == 2, "ref = %ld\n", ref);
670 IXMLDOMNode_Release( node );
672 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk );
673 ok( r == S_OK, "returns %08lx\n", r );
675 ref = IXMLDOMNode_AddRef( unk );
676 ok(ref == 3, "ref = %ld\n", ref);
677 IXMLDOMNode_Release( unk );
679 V_VT(&var) = VT_EMPTY;
680 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
681 ok( r == S_OK, "returns %08lx\n", r );
682 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
683 IXMLDOMNode_Release( child );
684 IUnknown_Release( unk );
687 V_VT(&var) = VT_NULL;
688 V_DISPATCH(&var) = (IDispatch*)node;
689 r = IXMLDOMNode_insertBefore( root, node, var, &child );
690 ok( r == S_OK, "returns %08lx\n", r );
691 ok( node == child, "%p %p\n", node, child );
692 IXMLDOMNode_Release( child );
693 IXMLDOMNode_Release( node );
696 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (LPVOID*)&element );
697 ok( r == S_OK, "returns %08lx\n", r );
699 r = IXMLDOMElement_get_attributes( element, &attr_map );
700 ok( r == S_OK, "returns %08lx\n", r );
701 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
702 ok( r == S_OK, "returns %08lx\n", r );
703 ok( num == 0, "num %ld\n", num );
704 IXMLDOMNamedNodeMap_Release( attr_map );
706 V_VT(&var) = VT_BSTR;
707 V_BSTR(&var) = SysAllocString( szstr1 );
708 name = SysAllocString( szdl );
709 r = IXMLDOMElement_setAttribute( element, name, var );
710 ok( r == S_OK, "returns %08lx\n", r );
711 r = IXMLDOMElement_get_attributes( element, &attr_map );
712 ok( r == S_OK, "returns %08lx\n", r );
713 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
714 ok( r == S_OK, "returns %08lx\n", r );
715 ok( num == 1, "num %ld\n", num );
716 IXMLDOMNamedNodeMap_Release( attr_map );
717 VariantClear(&var);
719 V_VT(&var) = VT_BSTR;
720 V_BSTR(&var) = SysAllocString( szstr2 );
721 r = IXMLDOMElement_setAttribute( element, name, var );
722 ok( r == S_OK, "returns %08lx\n", r );
723 r = IXMLDOMElement_get_attributes( element, &attr_map );
724 ok( r == S_OK, "returns %08lx\n", r );
725 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
726 ok( r == S_OK, "returns %08lx\n", r );
727 ok( num == 1, "num %ld\n", num );
728 IXMLDOMNamedNodeMap_Release( attr_map );
729 VariantClear(&var);
730 r = IXMLDOMElement_getAttribute( element, name, &var );
731 ok( r == S_OK, "returns %08lx\n", r );
732 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
733 VariantClear(&var);
734 SysFreeString(name);
736 V_VT(&var) = VT_BSTR;
737 V_BSTR(&var) = SysAllocString( szstr1 );
738 name = SysAllocString( szlc );
739 r = IXMLDOMElement_setAttribute( element, name, var );
740 ok( r == S_OK, "returns %08lx\n", r );
741 r = IXMLDOMElement_get_attributes( element, &attr_map );
742 ok( r == S_OK, "returns %08lx\n", r );
743 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
744 ok( r == S_OK, "returns %08lx\n", r );
745 ok( num == 2, "num %ld\n", num );
746 IXMLDOMNamedNodeMap_Release( attr_map );
747 VariantClear(&var);
748 SysFreeString(name);
750 V_VT(&var) = VT_I4;
751 V_I4(&var) = 10;
752 name = SysAllocString( szbs );
753 r = IXMLDOMElement_setAttribute( element, name, var );
754 ok( r == S_OK, "returns %08lx\n", r );
755 VariantClear(&var);
756 r = IXMLDOMElement_getAttribute( element, name, &var );
757 ok( r == S_OK, "returns %08lx\n", r );
758 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
759 VariantClear(&var);
760 SysFreeString(name);
762 IXMLDOMElement_Release( element );
763 IXMLDOMNode_Release( root );
764 IXMLDOMDocument_Release( doc );
768 START_TEST(domdoc)
770 HRESULT r;
772 r = CoInitialize( NULL );
773 ok( r == S_OK, "failed to init com\n");
775 test_domdoc();
776 test_domnode();
777 test_refs();
778 test_create();
780 CoUninitialize();