Release a stray node.
[wine] / dlls / msxml3 / tests / domdoc.c
1 /*
2  * XML test
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21
22 #define COBJMACROS
23
24 #include "windows.h"
25 #include "ole2.h"
26 #include "msxml2.h"
27 #include <stdio.h>
28
29 #include "wine/test.h"
30
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
35 };
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
40 };
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
45 };
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
50 };
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
62 };
63 static const WCHAR szNonExistentFile[] = {
64     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
65 };
66 static const WCHAR szDocument[] = {
67     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
68 };
69
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
75 const GUID CLSID_DOMDocument = 
76     { 0x2933BF90, 0x7B36, 0x11d2, {0xB2,0x0E,0x00,0xC0,0x4F,0x98,0x3E,0x60}};
77 const GUID IID_IXMLDOMDocument = 
78     { 0x2933BF81, 0x7B36, 0x11d2, {0xB2,0x0E,0x00,0xC0,0x4F,0x98,0x3E,0x60}};
79
80 void test_domdoc( void )
81 {
82     HRESULT r;
83     IXMLDOMDocument *doc = NULL;
84     IXMLDOMParseError *error;
85     IXMLDOMElement *element = NULL;
86     VARIANT_BOOL b;
87     VARIANT var;
88     BSTR str;
89     long code;
90
91     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
92         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
93     if( r != S_OK )
94         return;
95
96     /* try some stupid things */
97     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
98     ok( r == S_FALSE, "loadXML failed\n");
99
100     b = VARIANT_TRUE;
101     r = IXMLDOMDocument_loadXML( doc, NULL, &b );
102     ok( r == S_FALSE, "loadXML failed\n");
103     ok( b == VARIANT_FALSE, "failed to load XML string\n");
104
105     /* try to load a document from a nonexistent file */
106     b = VARIANT_TRUE;
107     str = SysAllocString( szNonExistentFile );
108     VariantInit(&var);
109     V_VT(&var) = VT_BSTR;
110     V_BSTR(&var) = str;
111
112     r = IXMLDOMDocument_load( doc, var, &b);
113     ok( r == S_FALSE, "load (from file) failed\n");
114     ok( b == VARIANT_FALSE, "failed to load XML file\n");
115     SysFreeString( str );
116
117     /* try load an empty document */
118     b = VARIANT_TRUE;
119     str = SysAllocString( szEmpty );
120     r = IXMLDOMDocument_loadXML( doc, str, &b );
121     ok( r == S_FALSE, "loadXML failed\n");
122     ok( b == VARIANT_FALSE, "failed to load XML string\n");
123     SysFreeString( str );
124
125     /* check that there's no document element */
126     element = NULL;
127     r = IXMLDOMDocument_get_documentElement( doc, &element );
128     ok( r == S_FALSE, "should be no document element\n");
129
130     b = VARIANT_TRUE;
131     str = SysAllocString( szIncomplete );
132     r = IXMLDOMDocument_loadXML( doc, str, &b );
133     ok( r == S_FALSE, "loadXML failed\n");
134     ok( b == VARIANT_FALSE, "failed to load XML string\n");
135     SysFreeString( str );
136
137     /* check that there's no document element */
138     element = (IXMLDOMElement*)1;
139     r = IXMLDOMDocument_get_documentElement( doc, &element );
140     ok( r == S_FALSE, "should be no document element\n");
141     ok( element == NULL, "Element should be NULL\n");
142
143     /* try to load something valid */
144     b = VARIANT_FALSE;
145     str = SysAllocString( szComplete1 );
146     r = IXMLDOMDocument_loadXML( doc, str, &b );
147     ok( r == S_OK, "loadXML failed\n");
148     ok( b == VARIANT_TRUE, "failed to load XML string\n");
149     SysFreeString( str );
150
151     /* try with a null out pointer - crashes */
152     if (0)
153     {
154         r = IXMLDOMDocument_get_documentElement( doc, NULL );
155         ok( r == S_OK, "should be no document element\n");
156     }
157
158     /* check if nodename is correct */
159     r = IXMLDOMDocument_get_nodeName( doc, NULL );
160     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
161
162     /* content doesn't matter here */
163     str = SysAllocString( szNonExistentFile );
164     r = IXMLDOMDocument_get_nodeName( doc, &str );
165     ok ( r == S_OK, "get_nodeName wrong code\n");
166     ok ( str != NULL, "str is null\n");
167     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
168     SysFreeString( str );
169
170
171     /* check that there's a document element */
172     element = NULL;
173     r = IXMLDOMDocument_get_documentElement( doc, &element );
174     ok( r == S_OK, "should be a document element\n");
175     if( element )
176     {
177         BSTR tag = NULL;
178
179         /* check if the tag is correct */
180         r = IXMLDOMElement_get_tagName( element, &tag );
181         ok( r == S_OK, "couldn't get tag name\n");
182         ok( tag != NULL, "tag was null\n");
183         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
184         SysFreeString( tag );
185
186         /* figure out what happens if we try to reload the document */
187         str = SysAllocString( szComplete2 );
188         r = IXMLDOMDocument_loadXML( doc, str, &b );
189         ok( r == S_OK, "loadXML failed\n");
190         ok( b == VARIANT_TRUE, "failed to load XML string\n");
191         SysFreeString( str );
192
193         /* check if the tag is still correct */
194         tag = NULL;
195         r = IXMLDOMElement_get_tagName( element, &tag );
196         ok( r == S_OK, "couldn't get tag name\n");
197         ok( tag != NULL, "tag was null\n");
198         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
199         SysFreeString( tag );
200
201         IXMLDOMElement_Release( element );
202         element = NULL;
203     }
204
205     /* as soon as we call loadXML again, the document element will disappear */
206     b = 2;
207     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
208     ok( r == S_FALSE, "loadXML failed\n");
209     ok( b == 2, "variant modified\n");
210     r = IXMLDOMDocument_get_documentElement( doc, &element );
211     ok( r == S_FALSE, "should be no document element\n");
212
213     /* try to load something else simple and valid */
214     b = VARIANT_FALSE;
215     str = SysAllocString( szComplete3 );
216     r = IXMLDOMDocument_loadXML( doc, str, &b );
217     ok( r == S_OK, "loadXML failed\n");
218     ok( b == VARIANT_TRUE, "failed to load XML string\n");
219     SysFreeString( str );
220
221     /* try something a little more complicated */
222     b = FALSE;
223     str = SysAllocString( szComplete4 );
224     r = IXMLDOMDocument_loadXML( doc, str, &b );
225     ok( r == S_OK, "loadXML failed\n");
226     ok( b == VARIANT_TRUE, "failed to load XML string\n");
227     SysFreeString( str );
228
229     r = IXMLDOMDocument_get_parseError( doc, &error );
230     ok( r == S_OK, "returns %08lx\n", r );
231
232     r = IXMLDOMParseError_get_errorCode( error, &code );
233     ok( r == S_FALSE, "returns %08lx\n", r );
234     ok( code == 0, "code %ld\n", code );
235     IXMLDOMParseError_Release( error );
236
237     r = IXMLDOMDocument_Release( doc );
238     ok( r == 0, "document ref count incorrect\n");
239
240 }
241
242 void test_domnode( void )
243 {
244     HRESULT r;
245     IXMLDOMDocument *doc = NULL, *owner = NULL;
246     IXMLDOMElement *element = NULL;
247     IXMLDOMNamedNodeMap *map = NULL;
248     IXMLDOMNode *node = NULL, *next = NULL;
249     IXMLDOMNodeList *list = NULL;
250     DOMNodeType type = NODE_INVALID;
251     VARIANT_BOOL b;
252     BSTR str;
253     VARIANT var;
254     long count;
255
256     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
257         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
258     if( r != S_OK )
259         return;
260
261     b = FALSE;
262     str = SysAllocString( szComplete4 );
263     r = IXMLDOMDocument_loadXML( doc, str, &b );
264     ok( r == S_OK, "loadXML failed\n");
265     ok( b == VARIANT_TRUE, "failed to load XML string\n");
266     SysFreeString( str );
267
268     if (doc)
269     {
270         b = 1;
271         r = IXMLDOMNode_hasChildNodes( doc, &b );
272         ok( r == S_OK, "hasChildNoes bad return\n");
273         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
274
275         r = IXMLDOMDocument_get_documentElement( doc, &element );
276         ok( r == S_OK, "should be a document element\n");
277         ok( element != NULL, "should be an element\n");
278     }
279     else
280         ok( FALSE, "no document\n");
281
282     VariantInit(&var);
283     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
284     r = IXMLDOMNode_get_nodeValue( doc, &var );
285     ok( r == S_FALSE, "nextNode returned wrong code\n");
286     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
287     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
288
289     if (element)
290     {
291         owner = NULL;
292         r = IXMLDOMNode_get_ownerDocument( element, &owner );
293         todo_wine {
294         ok( r == S_OK, "get_ownerDocument return code\n");
295         }
296         ok( owner != doc, "get_ownerDocument return\n");
297
298         type = NODE_INVALID;
299         r = IXMLDOMNode_get_nodeType( element, &type);
300         ok( r == S_OK, "getNamedItem returned wrong code\n");
301         ok( type == NODE_ELEMENT, "node not an element\n");
302
303         str = NULL;
304         r = IXMLDOMNode_get_baseName( element, &str );
305         ok( r == S_OK, "get_baseName returned wrong code\n");
306         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
307
308         /* check if nodename is correct */
309         r = IXMLDOMElement_get_nodeName( element, NULL );
310         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
311     
312         /* content doesn't matter here */
313         str = SysAllocString( szNonExistentFile );
314         r = IXMLDOMElement_get_nodeName( element, &str );
315         ok ( r == S_OK, "get_nodeName wrong code\n");
316         ok ( str != NULL, "str is null\n");
317         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
318         SysFreeString( str );
319
320         r = IXMLDOMElement_get_attributes( element, &map );
321         ok( r == S_OK, "get_attributes returned wrong code\n");
322         ok( map != NULL, "should be attributes\n");
323
324         b = 1;
325         r = IXMLDOMNode_hasChildNodes( element, &b );
326         ok( r == S_OK, "hasChildNoes bad return\n");
327         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
328     }
329     else
330         ok( FALSE, "no element\n");
331
332     if (map)
333     {
334         str = SysAllocString( szdl );
335         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
336         ok( r == S_OK, "getNamedItem returned wrong code\n");
337         ok( node != NULL, "should be attributes\n");
338         IXMLDOMNode_Release(node);
339         SysFreeString( str );
340
341         /* test indexed access of attributes */
342         r = IXMLDOMNamedNodeMap_get_length( map, &count );
343         ok ( r == S_OK, "get_length wrong code\n");
344         ok ( count == 1, "get_length != 1\n");
345
346         node = NULL;
347         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
348         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
349         ok ( node == NULL, "there is no node\n");
350
351         node = NULL;
352         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
353         ok ( r == S_FALSE, "get_item (1) wrong code\n");
354         ok ( node == NULL, "there is no attribute\n");
355
356         node = NULL;
357         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
358         ok ( r == S_OK, "get_item (0) wrong code\n");
359         ok ( node != NULL, "should be attribute\n");
360
361         r = IXMLDOMNode_get_nodeName( node, NULL );
362         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
363
364         /* content doesn't matter here */
365         str = SysAllocString( szNonExistentFile );
366         r = IXMLDOMNode_get_nodeName( node, &str );
367         ok ( r == S_OK, "get_nodeName wrong code\n");
368         ok ( str != NULL, "str is null\n");
369         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
370         SysFreeString( str );
371     }
372     else
373         ok( FALSE, "no map\n");
374
375     if (node)
376     {
377         type = NODE_INVALID;
378         r = IXMLDOMNode_get_nodeType( node, &type);
379         ok( r == S_OK, "getNamedItem returned wrong code\n");
380         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
381
382         str = NULL;
383         r = IXMLDOMNode_get_baseName( node, NULL );
384         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
385
386         str = NULL;
387         r = IXMLDOMNode_get_baseName( node, &str );
388         ok( r == S_OK, "get_baseName returned wrong code\n");
389         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
390
391         r = IXMLDOMNode_get_childNodes( node, NULL );
392         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
393
394         r = IXMLDOMNode_get_childNodes( node, &list );
395         ok( r == S_OK, "get_childNodes returned wrong code\n");
396
397         if (list)
398         {
399             r = IXMLDOMNodeList_nextNode( list, &next );
400             ok( r == S_OK, "nextNode returned wrong code\n");
401         }
402         else
403             ok( FALSE, "no childlist\n");
404
405         if (next)
406         {
407             b = 1;
408             r = IXMLDOMNode_hasChildNodes( next, &b );
409             ok( r == S_FALSE, "hasChildNoes bad return\n");
410             ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
411
412             type = NODE_INVALID;
413             r = IXMLDOMNode_get_nodeType( next, &type);
414             ok( r == S_OK, "getNamedItem returned wrong code\n");
415             ok( type == NODE_TEXT, "node not text\n");
416
417             str = (BSTR) 1;
418             r = IXMLDOMNode_get_baseName( next, &str );
419             ok( r == S_FALSE, "get_baseName returned wrong code\n");
420             ok( str == NULL, "basename was wrong\n");
421         }
422         else
423             ok( FALSE, "no next\n");
424
425         if (next)
426             IXMLDOMNode_Release( next );
427         next = NULL;
428         if (list)
429             IXMLDOMNodeList_Release( list );
430         list = NULL;
431         if (node)
432             IXMLDOMNode_Release( node );
433     }
434     else
435         ok( FALSE, "no node\n");
436     node = NULL;
437
438     if (map)
439         IXMLDOMNamedNodeMap_Release( map );
440
441     /* now traverse the tree from the root node */
442     if (element)
443     {
444         r = IXMLDOMNode_get_childNodes( element, &list );
445         ok( r == S_OK, "get_childNodes returned wrong code\n");
446     }
447     else
448         ok( FALSE, "no element\n");
449
450     r = IXMLDOMNode_selectSingleNode( element, (BSTR)szdl, &node );
451     ok( r == S_FALSE, "ret %08lx\n", r );
452     r = IXMLDOMNode_selectSingleNode( element, (BSTR)szbs, &node );
453     ok( r == S_OK, "ret %08lx\n", r );
454     r = IXMLDOMNode_Release( node );
455     ok( r == 0, "ret %08lx\n", r );
456
457     if (list)
458     {
459         r = IXMLDOMNodeList_get_length( list, &count );
460         ok( r == S_OK, "get_length returns %08lx\n", r );
461         ok( count == 2, "get_length got %ld\n", count );
462
463         r = IXMLDOMNodeList_nextNode( list, &node );
464         ok( r == S_OK, "nextNode returned wrong code\n");
465     }
466     else
467         ok( FALSE, "no list\n");
468
469     if (node)
470     {
471         type = NODE_INVALID;
472         r = IXMLDOMNode_get_nodeType( node, &type);
473         ok( r == S_OK, "getNamedItem returned wrong code\n");
474         ok( type == NODE_ELEMENT, "node not text\n");
475
476         VariantInit(&var);
477         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
478         r = IXMLDOMNode_get_nodeValue( node, &var );
479         ok( r == S_FALSE, "nextNode returned wrong code\n");
480         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
481         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
482
483         r = IXMLDOMNode_hasChildNodes( node, NULL );
484         ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
485
486         b = 1;
487         r = IXMLDOMNode_hasChildNodes( node, &b );
488         ok( r == S_OK, "hasChildNoes bad return\n");
489         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
490
491         str = NULL;
492         r = IXMLDOMNode_get_baseName( node, &str );
493         ok( r == S_OK, "get_baseName returned wrong code\n");
494         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
495     }
496     else
497         ok( FALSE, "no node\n");
498
499     if (node)
500         IXMLDOMNode_Release( node );
501     if (list)
502         IXMLDOMNodeList_Release( list );
503     if (element)
504         IXMLDOMElement_Release( element );
505     if (doc)
506         IXMLDOMDocument_Release( doc );
507 }
508
509 static void test_refs(void)
510 {
511     HRESULT r;
512     BSTR str;
513     VARIANT_BOOL b;
514     IXMLDOMDocument *doc = NULL;
515     IXMLDOMElement *element = NULL;
516     IXMLDOMNode *node = NULL, *node2;
517     IXMLDOMNodeList *node_list = NULL;
518     LONG ref;
519
520     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
521         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
522     if( r != S_OK )
523         return;
524
525     str = SysAllocString( szComplete4 );
526     r = IXMLDOMDocument_loadXML( doc, str, &b );
527     ok( r == S_OK, "loadXML failed\n");
528     ok( b == VARIANT_TRUE, "failed to load XML string\n");
529     SysFreeString( str );
530
531     ref = IXMLDOMDocument_AddRef( doc );
532     ok( ref == 2, "ref %ld\n", ref );
533     ref = IXMLDOMDocument_AddRef( doc );
534     ok( ref == 3, "ref %ld\n", ref );
535     IXMLDOMDocument_Release( doc );
536     IXMLDOMDocument_Release( doc );
537
538     r = IXMLDOMDocument_get_documentElement( doc, &element );
539     ok( r == S_OK, "should be a document element\n");
540     ok( element != NULL, "should be an element\n");
541
542     ref = IXMLDOMDocument_AddRef( doc );
543     ok( ref == 2, "ref %ld\n", ref );
544     IXMLDOMDocument_Release( doc );
545
546     r = IXMLDOMElement_get_childNodes( element, &node_list );
547     ok( r == S_OK, "rets %08lx\n", r);
548     ref = IXMLDOMNodeList_AddRef( node_list );
549     ok( ref == 2, "ref %ld\n", ref );
550     IXMLDOMNodeList_Release( node_list );
551
552     IXMLDOMNodeList_get_item( node_list, 0, &node );
553     ok( r == S_OK, "rets %08lx\n", r);
554
555     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
556     ok( r == S_OK, "rets %08lx\n", r);
557
558     ref = IXMLDOMNode_AddRef( node );
559     ok( ref == 2, "ref %ld\n", ref );
560     IXMLDOMNode_Release( node );
561
562     ref = IXMLDOMNode_Release( node );
563     ok( ref == 0, "ref %ld\n", ref );
564     ref = IXMLDOMNode_Release( node2 );
565     ok( ref == 0, "ref %ld\n", ref );
566
567     ref = IXMLDOMNodeList_Release( node_list );
568     ok( ref == 0, "ref %ld\n", ref );
569
570     ok( node != node2, "node %p node2 %p\n", node, node2 );
571
572     ref = IXMLDOMDocument_Release( doc );
573     ok( ref == 0, "ref %ld\n", ref );
574
575     ref = IXMLDOMElement_AddRef( element );
576     todo_wine {
577     ok( ref == 3, "ref %ld\n", ref );
578     }
579
580     IXMLDOMElement_Release( element );
581     IXMLDOMElement_Release( element );
582
583 }
584
585 START_TEST(domdoc)
586 {
587     HRESULT r;
588
589     r = CoInitialize( NULL );
590     ok( r == S_OK, "failed to init com\n");
591
592     test_domdoc();
593     test_domnode();
594     test_refs();
595
596     CoUninitialize();
597 }