secur32: Update ntlm_auth version detection to detect new samba4 version numbers.
[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         '<','e','m','p','t','y','>','<','/','e','m','p','t','y','>','\n',
62     '<','/','l','c','>','\n',0
63 };
64 static const WCHAR szNonExistentFile[] = {
65     'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
66 };
67 static const WCHAR szDocument[] = {
68     '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
69 };
70
71 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
72 static const WCHAR szdl[] = { 'd','l',0 };
73 static const WCHAR szvr[] = { 'v','r',0 };
74 static const WCHAR szlc[] = { 'l','c',0 };
75 static const WCHAR szbs[] = { 'b','s',0 };
76 static const WCHAR szstr1[] = { 's','t','r','1',0 };
77 static const WCHAR szstr2[] = { 's','t','r','2',0 };
78 static const WCHAR szstar[] = { '*',0 };
79 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
80
81 void test_domdoc( void )
82 {
83     HRESULT r;
84     IXMLDOMDocument *doc = NULL;
85     IXMLDOMParseError *error;
86     IXMLDOMElement *element = NULL;
87     VARIANT_BOOL b;
88     VARIANT var;
89     BSTR str;
90     long code;
91
92     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
93         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
94     if( r != S_OK )
95         return;
96
97     /* try some stupid things */
98     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
99     ok( r == S_FALSE, "loadXML failed\n");
100
101     b = VARIANT_TRUE;
102     r = IXMLDOMDocument_loadXML( doc, NULL, &b );
103     ok( r == S_FALSE, "loadXML failed\n");
104     ok( b == VARIANT_FALSE, "failed to load XML string\n");
105
106     /* try to load a document from a nonexistent file */
107     b = VARIANT_TRUE;
108     str = SysAllocString( szNonExistentFile );
109     VariantInit(&var);
110     V_VT(&var) = VT_BSTR;
111     V_BSTR(&var) = str;
112
113     r = IXMLDOMDocument_load( doc, var, &b);
114     ok( r == S_FALSE, "load (from file) failed\n");
115     ok( b == VARIANT_FALSE, "failed to load XML file\n");
116     SysFreeString( str );
117
118     /* try load an empty document */
119     b = VARIANT_TRUE;
120     str = SysAllocString( szEmpty );
121     r = IXMLDOMDocument_loadXML( doc, str, &b );
122     ok( r == S_FALSE, "loadXML failed\n");
123     ok( b == VARIANT_FALSE, "failed to load XML string\n");
124     SysFreeString( str );
125
126     /* check that there's no document element */
127     element = NULL;
128     r = IXMLDOMDocument_get_documentElement( doc, &element );
129     ok( r == S_FALSE, "should be no document element\n");
130
131     b = VARIANT_TRUE;
132     str = SysAllocString( szIncomplete );
133     r = IXMLDOMDocument_loadXML( doc, str, &b );
134     ok( r == S_FALSE, "loadXML failed\n");
135     ok( b == VARIANT_FALSE, "failed to load XML string\n");
136     SysFreeString( str );
137
138     /* check that there's no document element */
139     element = (IXMLDOMElement*)1;
140     r = IXMLDOMDocument_get_documentElement( doc, &element );
141     ok( r == S_FALSE, "should be no document element\n");
142     ok( element == NULL, "Element should be NULL\n");
143
144     /* try to load something valid */
145     b = VARIANT_FALSE;
146     str = SysAllocString( szComplete1 );
147     r = IXMLDOMDocument_loadXML( doc, str, &b );
148     ok( r == S_OK, "loadXML failed\n");
149     ok( b == VARIANT_TRUE, "failed to load XML string\n");
150     SysFreeString( str );
151
152     /* try with a null out pointer - crashes */
153     if (0)
154     {
155         r = IXMLDOMDocument_get_documentElement( doc, NULL );
156         ok( r == S_OK, "should be no document element\n");
157     }
158
159     /* check if nodename is correct */
160     r = IXMLDOMDocument_get_nodeName( doc, NULL );
161     ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
162
163     /* content doesn't matter here */
164     str = SysAllocString( szNonExistentFile );
165     r = IXMLDOMDocument_get_nodeName( doc, &str );
166     ok ( r == S_OK, "get_nodeName wrong code\n");
167     ok ( str != NULL, "str is null\n");
168     ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
169     SysFreeString( str );
170
171
172     /* check that there's a document element */
173     element = NULL;
174     r = IXMLDOMDocument_get_documentElement( doc, &element );
175     ok( r == S_OK, "should be a document element\n");
176     if( element )
177     {
178         BSTR tag = NULL;
179
180         /* check if the tag is correct */
181         r = IXMLDOMElement_get_tagName( element, &tag );
182         ok( r == S_OK, "couldn't get tag name\n");
183         ok( tag != NULL, "tag was null\n");
184         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
185         SysFreeString( tag );
186
187         /* figure out what happens if we try to reload the document */
188         str = SysAllocString( szComplete2 );
189         r = IXMLDOMDocument_loadXML( doc, str, &b );
190         ok( r == S_OK, "loadXML failed\n");
191         ok( b == VARIANT_TRUE, "failed to load XML string\n");
192         SysFreeString( str );
193
194         /* check if the tag is still correct */
195         tag = NULL;
196         r = IXMLDOMElement_get_tagName( element, &tag );
197         ok( r == S_OK, "couldn't get tag name\n");
198         ok( tag != NULL, "tag was null\n");
199         ok( !lstrcmpW( tag, szOpen ), "incorrect tag name\n");
200         SysFreeString( tag );
201
202         IXMLDOMElement_Release( element );
203         element = NULL;
204     }
205
206     /* as soon as we call loadXML again, the document element will disappear */
207     b = 2;
208     r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
209     ok( r == S_FALSE, "loadXML failed\n");
210     ok( b == 2, "variant modified\n");
211     r = IXMLDOMDocument_get_documentElement( doc, &element );
212     ok( r == S_FALSE, "should be no document element\n");
213
214     /* try to load something else simple and valid */
215     b = VARIANT_FALSE;
216     str = SysAllocString( szComplete3 );
217     r = IXMLDOMDocument_loadXML( doc, str, &b );
218     ok( r == S_OK, "loadXML failed\n");
219     ok( b == VARIANT_TRUE, "failed to load XML string\n");
220     SysFreeString( str );
221
222     /* try something a little more complicated */
223     b = FALSE;
224     str = SysAllocString( szComplete4 );
225     r = IXMLDOMDocument_loadXML( doc, str, &b );
226     ok( r == S_OK, "loadXML failed\n");
227     ok( b == VARIANT_TRUE, "failed to load XML string\n");
228     SysFreeString( str );
229
230     r = IXMLDOMDocument_get_parseError( doc, &error );
231     ok( r == S_OK, "returns %08lx\n", r );
232
233     r = IXMLDOMParseError_get_errorCode( error, &code );
234     ok( r == S_FALSE, "returns %08lx\n", r );
235     ok( code == 0, "code %ld\n", code );
236     IXMLDOMParseError_Release( error );
237
238     r = IXMLDOMDocument_Release( doc );
239     ok( r == 0, "document ref count incorrect\n");
240
241 }
242
243 void test_domnode( void )
244 {
245     HRESULT r;
246     IXMLDOMDocument *doc = NULL, *owner = NULL;
247     IXMLDOMElement *element = NULL;
248     IXMLDOMNamedNodeMap *map = NULL;
249     IXMLDOMNode *node = NULL, *next = NULL;
250     IXMLDOMNodeList *list = NULL;
251     DOMNodeType type = NODE_INVALID;
252     VARIANT_BOOL b;
253     BSTR str;
254     VARIANT var;
255     long count;
256
257     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
258         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
259     if( r != S_OK )
260         return;
261
262     b = FALSE;
263     str = SysAllocString( szComplete4 );
264     r = IXMLDOMDocument_loadXML( doc, str, &b );
265     ok( r == S_OK, "loadXML failed\n");
266     ok( b == VARIANT_TRUE, "failed to load XML string\n");
267     SysFreeString( str );
268
269     if (doc)
270     {
271         b = 1;
272         r = IXMLDOMNode_hasChildNodes( doc, &b );
273         ok( r == S_OK, "hasChildNoes bad return\n");
274         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
275
276         r = IXMLDOMDocument_get_documentElement( doc, &element );
277         ok( r == S_OK, "should be a document element\n");
278         ok( element != NULL, "should be an element\n");
279     }
280     else
281         ok( FALSE, "no document\n");
282
283     VariantInit(&var);
284     ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
285     r = IXMLDOMNode_get_nodeValue( doc, &var );
286     ok( r == S_FALSE, "nextNode returned wrong code\n");
287     ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
288     ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
289
290     if (element)
291     {
292         owner = NULL;
293         r = IXMLDOMNode_get_ownerDocument( element, &owner );
294         todo_wine {
295         ok( r == S_OK, "get_ownerDocument return code\n");
296         }
297         ok( owner != doc, "get_ownerDocument return\n");
298
299         type = NODE_INVALID;
300         r = IXMLDOMNode_get_nodeType( element, &type);
301         ok( r == S_OK, "getNamedItem returned wrong code\n");
302         ok( type == NODE_ELEMENT, "node not an element\n");
303
304         str = NULL;
305         r = IXMLDOMNode_get_baseName( element, &str );
306         ok( r == S_OK, "get_baseName returned wrong code\n");
307         ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
308
309         /* check if nodename is correct */
310         r = IXMLDOMElement_get_nodeName( element, NULL );
311         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
312     
313         /* content doesn't matter here */
314         str = SysAllocString( szNonExistentFile );
315         r = IXMLDOMElement_get_nodeName( element, &str );
316         ok ( r == S_OK, "get_nodeName wrong code\n");
317         ok ( str != NULL, "str is null\n");
318         ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
319         SysFreeString( str );
320
321         str = SysAllocString( szNonExistentFile );      
322         V_VT(&var) = VT_I4;
323         V_I4(&var) = 0x1234;
324         r = IXMLDOMElement_getAttribute( element, str, &var );
325         ok( r == E_FAIL, "getAttribute ret %08lx\n", r );
326         ok( V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
327         VariantClear(&var);
328         SysFreeString( str );
329
330         str = SysAllocString( szdl );   
331         V_VT(&var) = VT_I4;
332         V_I4(&var) = 0x1234;
333         r = IXMLDOMElement_getAttribute( element, str, &var );
334         ok( r == S_OK, "getAttribute ret %08lx\n", r );
335         ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
336         ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
337         VariantClear( &var );
338         SysFreeString( str );
339
340         r = IXMLDOMElement_get_attributes( element, &map );
341         ok( r == S_OK, "get_attributes returned wrong code\n");
342         ok( map != NULL, "should be attributes\n");
343
344         b = 1;
345         r = IXMLDOMNode_hasChildNodes( element, &b );
346         ok( r == S_OK, "hasChildNoes bad return\n");
347         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
348     }
349     else
350         ok( FALSE, "no element\n");
351
352     if (map)
353     {
354         ISupportErrorInfo *support_error;
355         r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (LPVOID*)&support_error );
356         ok( r == S_OK, "ret %08lx\n", r );
357
358         r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
359 todo_wine
360 {
361         ok( r == S_OK, "ret %08lx\n", r );
362 }
363         ISupportErrorInfo_Release( support_error );
364
365         str = SysAllocString( szdl );
366         r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
367         ok( r == S_OK, "getNamedItem returned wrong code\n");
368         ok( node != NULL, "should be attributes\n");
369         IXMLDOMNode_Release(node);
370         SysFreeString( str );
371
372         /* test indexed access of attributes */
373         r = IXMLDOMNamedNodeMap_get_length( map, &count );
374         ok ( r == S_OK, "get_length wrong code\n");
375         ok ( count == 1, "get_length != 1\n");
376
377         node = NULL;
378         r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
379         ok ( r == S_FALSE, "get_item (-1) wrong code\n");
380         ok ( node == NULL, "there is no node\n");
381
382         node = NULL;
383         r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
384         ok ( r == S_FALSE, "get_item (1) wrong code\n");
385         ok ( node == NULL, "there is no attribute\n");
386
387         node = NULL;
388         r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
389         ok ( r == S_OK, "get_item (0) wrong code\n");
390         ok ( node != NULL, "should be attribute\n");
391
392         r = IXMLDOMNode_get_nodeName( node, NULL );
393         ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
394
395         /* content doesn't matter here */
396         str = SysAllocString( szNonExistentFile );
397         r = IXMLDOMNode_get_nodeName( node, &str );
398         ok ( r == S_OK, "get_nodeName wrong code\n");
399         ok ( str != NULL, "str is null\n");
400         ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
401         SysFreeString( str );
402     }
403     else
404         ok( FALSE, "no map\n");
405
406     if (node)
407     {
408         type = NODE_INVALID;
409         r = IXMLDOMNode_get_nodeType( node, &type);
410         ok( r == S_OK, "getNamedItem returned wrong code\n");
411         ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
412
413         str = NULL;
414         r = IXMLDOMNode_get_baseName( node, NULL );
415         ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
416
417         str = NULL;
418         r = IXMLDOMNode_get_baseName( node, &str );
419         ok( r == S_OK, "get_baseName returned wrong code\n");
420         ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
421
422         r = IXMLDOMNode_get_nodeValue( node, &var );
423         ok( r == S_OK, "returns %08lx\n", r );
424         ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
425         ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
426         VariantClear(&var);
427
428         r = IXMLDOMNode_get_childNodes( node, NULL );
429         ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
430
431         r = IXMLDOMNode_get_childNodes( node, &list );
432         ok( r == S_OK, "get_childNodes returned wrong code\n");
433
434         if (list)
435         {
436             r = IXMLDOMNodeList_nextNode( list, &next );
437             ok( r == S_OK, "nextNode returned wrong code\n");
438         }
439         else
440             ok( FALSE, "no childlist\n");
441
442         if (next)
443         {
444             b = 1;
445             r = IXMLDOMNode_hasChildNodes( next, &b );
446             ok( r == S_FALSE, "hasChildNoes bad return\n");
447             ok( b == VARIANT_FALSE, "hasChildNoes wrong result\n");
448
449             type = NODE_INVALID;
450             r = IXMLDOMNode_get_nodeType( next, &type);
451             ok( r == S_OK, "getNamedItem returned wrong code\n");
452             ok( type == NODE_TEXT, "node not text\n");
453
454             str = (BSTR) 1;
455             r = IXMLDOMNode_get_baseName( next, &str );
456             ok( r == S_FALSE, "get_baseName returned wrong code\n");
457             ok( str == NULL, "basename was wrong\n");
458         }
459         else
460             ok( FALSE, "no next\n");
461
462         if (next)
463             IXMLDOMNode_Release( next );
464         next = NULL;
465         if (list)
466             IXMLDOMNodeList_Release( list );
467         list = NULL;
468         if (node)
469             IXMLDOMNode_Release( node );
470     }
471     else
472         ok( FALSE, "no node\n");
473     node = NULL;
474
475     if (map)
476         IXMLDOMNamedNodeMap_Release( map );
477
478     /* now traverse the tree from the root node */
479     if (element)
480     {
481         r = IXMLDOMNode_get_childNodes( element, &list );
482         ok( r == S_OK, "get_childNodes returned wrong code\n");
483     }
484     else
485         ok( FALSE, "no element\n");
486
487     r = IXMLDOMNode_selectSingleNode( element, (BSTR)szdl, &node );
488     ok( r == S_FALSE, "ret %08lx\n", r );
489     r = IXMLDOMNode_selectSingleNode( element, (BSTR)szbs, &node );
490     ok( r == S_OK, "ret %08lx\n", r );
491     r = IXMLDOMNode_Release( node );
492     ok( r == 0, "ret %08lx\n", r );
493
494     if (list)
495     {
496         r = IXMLDOMNodeList_get_length( list, &count );
497         ok( r == S_OK, "get_length returns %08lx\n", r );
498         ok( count == 3, "get_length got %ld\n", count );
499
500         r = IXMLDOMNodeList_nextNode( list, &node );
501         ok( r == S_OK, "nextNode returned wrong code\n");
502     }
503     else
504         ok( FALSE, "no list\n");
505
506     if (node)
507     {
508         type = NODE_INVALID;
509         r = IXMLDOMNode_get_nodeType( node, &type);
510         ok( r == S_OK, "getNamedItem returned wrong code\n");
511         ok( type == NODE_ELEMENT, "node not text\n");
512
513         VariantInit(&var);
514         ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
515         r = IXMLDOMNode_get_nodeValue( node, &var );
516         ok( r == S_FALSE, "nextNode returned wrong code\n");
517         ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
518         ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
519
520         r = IXMLDOMNode_hasChildNodes( node, NULL );
521         ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
522
523         b = 1;
524         r = IXMLDOMNode_hasChildNodes( node, &b );
525         ok( r == S_OK, "hasChildNoes bad return\n");
526         ok( b == VARIANT_TRUE, "hasChildNoes wrong result\n");
527
528         str = NULL;
529         r = IXMLDOMNode_get_baseName( node, &str );
530         ok( r == S_OK, "get_baseName returned wrong code\n");
531         ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
532     }
533     else
534         ok( FALSE, "no node\n");
535
536     if (node)
537         IXMLDOMNode_Release( node );
538     if (list)
539         IXMLDOMNodeList_Release( list );
540     if (element)
541         IXMLDOMElement_Release( element );
542     if (doc)
543         IXMLDOMDocument_Release( doc );
544 }
545
546 static void test_refs(void)
547 {
548     HRESULT r;
549     BSTR str;
550     VARIANT_BOOL b;
551     IXMLDOMDocument *doc = NULL;
552     IXMLDOMElement *element = NULL;
553     IXMLDOMNode *node = NULL, *node2;
554     IXMLDOMNodeList *node_list = NULL;
555     LONG ref;
556     IUnknown *unk, *unk2;
557
558     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
559         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
560     if( r != S_OK )
561         return;
562     ref = IXMLDOMDocument_Release(doc);
563     ok( ref == 0, "ref %ld\n", ref);
564
565     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
566         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
567     if( r != S_OK )
568         return;
569
570     str = SysAllocString( szComplete4 );
571     r = IXMLDOMDocument_loadXML( doc, str, &b );
572     ok( r == S_OK, "loadXML failed\n");
573     ok( b == VARIANT_TRUE, "failed to load XML string\n");
574     SysFreeString( str );
575
576     ref = IXMLDOMDocument_AddRef( doc );
577     ok( ref == 2, "ref %ld\n", ref );
578     ref = IXMLDOMDocument_AddRef( doc );
579     ok( ref == 3, "ref %ld\n", ref );
580     IXMLDOMDocument_Release( doc );
581     IXMLDOMDocument_Release( doc );
582
583     r = IXMLDOMDocument_get_documentElement( doc, &element );
584     ok( r == S_OK, "should be a document element\n");
585     ok( element != NULL, "should be an element\n");
586
587     ref = IXMLDOMDocument_AddRef( doc );
588     ok( ref == 2, "ref %ld\n", ref );
589     IXMLDOMDocument_Release( doc );
590
591     r = IXMLDOMElement_get_childNodes( element, &node_list );
592     ok( r == S_OK, "rets %08lx\n", r);
593     ref = IXMLDOMNodeList_AddRef( node_list );
594     ok( ref == 2, "ref %ld\n", ref );
595     IXMLDOMNodeList_Release( node_list );
596
597     IXMLDOMNodeList_get_item( node_list, 0, &node );
598     ok( r == S_OK, "rets %08lx\n", r);
599
600     IXMLDOMNodeList_get_item( node_list, 0, &node2 );
601     ok( r == S_OK, "rets %08lx\n", r);
602
603     ref = IXMLDOMNode_AddRef( node );
604     ok( ref == 2, "ref %ld\n", ref );
605     IXMLDOMNode_Release( node );
606
607     ref = IXMLDOMNode_Release( node );
608     ok( ref == 0, "ref %ld\n", ref );
609     ref = IXMLDOMNode_Release( node2 );
610     ok( ref == 0, "ref %ld\n", ref );
611
612     ref = IXMLDOMNodeList_Release( node_list );
613     ok( ref == 0, "ref %ld\n", ref );
614
615     ok( node != node2, "node %p node2 %p\n", node, node2 );
616
617     ref = IXMLDOMDocument_Release( doc );
618     ok( ref == 0, "ref %ld\n", ref );
619
620     ref = IXMLDOMElement_AddRef( element );
621     todo_wine {
622     ok( ref == 3, "ref %ld\n", ref );
623     }
624     IXMLDOMElement_Release( element );
625
626     /* IUnknown must be unique however we obtain it */
627     r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (LPVOID*)&unk );
628     ok( r == S_OK, "rets %08lx\n", r );
629     r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (LPVOID*)&node );
630     ok( r == S_OK, "rets %08lx\n", r );
631     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk2 );
632     ok( r == S_OK, "rets %08lx\n", r );
633     ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
634
635     IUnknown_Release( unk2 );
636     IUnknown_Release( unk );
637     IXMLDOMNode_Release( node );
638
639     IXMLDOMElement_Release( element );
640
641 }
642
643 static void test_create(void)
644 {
645     HRESULT r;
646     VARIANT var;
647     BSTR str, name;
648     IXMLDOMDocument *doc;
649     IXMLDOMElement *element;
650     IXMLDOMNode *root, *node, *child;
651     IXMLDOMNamedNodeMap *attr_map;
652     IUnknown *unk;
653     LONG ref, num;
654
655     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
656         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
657     if( r != S_OK )
658         return;
659
660     V_VT(&var) = VT_I4;
661     V_I4(&var) = NODE_ELEMENT;
662     str = SysAllocString( szlc );
663     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
664     ok( r == S_OK, "returns %08lx\n", r );
665     r = IXMLDOMDocument_appendChild( doc, node, &root );
666     ok( r == S_OK, "returns %08lx\n", r );
667     ok( node == root, "%p %p\n", node, root );
668
669     ref = IXMLDOMNode_AddRef( node );
670     ok(ref == 3, "ref %ld\n", ref);
671     IXMLDOMNode_Release( node );
672
673     ref = IXMLDOMNode_Release( node );
674     ok(ref == 1, "ref %ld\n", ref);
675     SysFreeString( str );
676
677     V_VT(&var) = VT_I4;
678     V_I4(&var) = NODE_ELEMENT;
679     str = SysAllocString( szbs );
680     r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
681     ok( r == S_OK, "returns %08lx\n", r );
682
683     ref = IXMLDOMNode_AddRef( node );
684     ok(ref == 2, "ref = %ld\n", ref);
685     IXMLDOMNode_Release( node );
686
687     r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (LPVOID*)&unk );
688     ok( r == S_OK, "returns %08lx\n", r );
689
690     ref = IXMLDOMNode_AddRef( unk );
691     ok(ref == 3, "ref = %ld\n", ref);
692     IXMLDOMNode_Release( unk );
693
694     V_VT(&var) = VT_EMPTY;
695     r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
696     ok( r == S_OK, "returns %08lx\n", r );
697     ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
698     IXMLDOMNode_Release( child );
699     IUnknown_Release( unk );
700
701
702     V_VT(&var) = VT_NULL;
703     V_DISPATCH(&var) = (IDispatch*)node;
704     r = IXMLDOMNode_insertBefore( root, node, var, &child );
705     ok( r == S_OK, "returns %08lx\n", r );
706     ok( node == child, "%p %p\n", node, child );
707     IXMLDOMNode_Release( child );
708     IXMLDOMNode_Release( node );
709
710
711     r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (LPVOID*)&element );
712     ok( r == S_OK, "returns %08lx\n", r );
713
714     r = IXMLDOMElement_get_attributes( element, &attr_map );
715     ok( r == S_OK, "returns %08lx\n", r );
716     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
717     ok( r == S_OK, "returns %08lx\n", r );
718     ok( num == 0, "num %ld\n", num );
719     IXMLDOMNamedNodeMap_Release( attr_map );
720
721     V_VT(&var) = VT_BSTR;
722     V_BSTR(&var) = SysAllocString( szstr1 );
723     name = SysAllocString( szdl );
724     r = IXMLDOMElement_setAttribute( element, name, var );
725     ok( r == S_OK, "returns %08lx\n", r );
726     r = IXMLDOMElement_get_attributes( element, &attr_map );
727     ok( r == S_OK, "returns %08lx\n", r );
728     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
729     ok( r == S_OK, "returns %08lx\n", r );
730     ok( num == 1, "num %ld\n", num );
731     IXMLDOMNamedNodeMap_Release( attr_map );
732     VariantClear(&var);
733
734     V_VT(&var) = VT_BSTR;
735     V_BSTR(&var) = SysAllocString( szstr2 );
736     r = IXMLDOMElement_setAttribute( element, name, var );
737     ok( r == S_OK, "returns %08lx\n", r );
738     r = IXMLDOMElement_get_attributes( element, &attr_map );
739     ok( r == S_OK, "returns %08lx\n", r );
740     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
741     ok( r == S_OK, "returns %08lx\n", r );
742     ok( num == 1, "num %ld\n", num );
743     IXMLDOMNamedNodeMap_Release( attr_map );
744     VariantClear(&var);
745     r = IXMLDOMElement_getAttribute( element, name, &var );
746     ok( r == S_OK, "returns %08lx\n", r );
747     ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
748     VariantClear(&var);
749     SysFreeString(name);
750
751     V_VT(&var) = VT_BSTR;
752     V_BSTR(&var) = SysAllocString( szstr1 );
753     name = SysAllocString( szlc );
754     r = IXMLDOMElement_setAttribute( element, name, var );
755     ok( r == S_OK, "returns %08lx\n", r );
756     r = IXMLDOMElement_get_attributes( element, &attr_map );
757     ok( r == S_OK, "returns %08lx\n", r );
758     r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
759     ok( r == S_OK, "returns %08lx\n", r );
760     ok( num == 2, "num %ld\n", num );
761     IXMLDOMNamedNodeMap_Release( attr_map );
762     VariantClear(&var);
763     SysFreeString(name);
764
765     V_VT(&var) = VT_I4;
766     V_I4(&var) = 10;
767     name = SysAllocString( szbs );
768     r = IXMLDOMElement_setAttribute( element, name, var );
769     ok( r == S_OK, "returns %08lx\n", r );
770     VariantClear(&var);
771     r = IXMLDOMElement_getAttribute( element, name, &var );
772     ok( r == S_OK, "returns %08lx\n", r );
773     ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
774     VariantClear(&var);
775     SysFreeString(name);
776
777     IXMLDOMElement_Release( element );
778     IXMLDOMNode_Release( root );
779     IXMLDOMDocument_Release( doc );
780 }
781
782 static void test_getElementsByTagName(void)
783 {
784     HRESULT r;
785     BSTR str;
786     VARIANT_BOOL b;
787     IXMLDOMDocument *doc;
788     IXMLDOMNodeList *node_list;
789     LONG len;
790
791     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
792         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
793     if( r != S_OK )
794         return;
795
796     str = SysAllocString( szComplete4 );
797     r = IXMLDOMDocument_loadXML( doc, str, &b );
798     ok( r == S_OK, "loadXML failed\n");
799     ok( b == VARIANT_TRUE, "failed to load XML string\n");
800     SysFreeString( str );
801
802     str = SysAllocString( szstar );
803     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
804     ok( r == S_OK, "ret %08lx\n", r );
805     r = IXMLDOMNodeList_get_length( node_list, &len );
806     ok( r == S_OK, "ret %08lx\n", r );
807     ok( len == 4, "len %ld\n", len );
808     IXMLDOMNodeList_Release( node_list );
809     SysFreeString( str );
810
811     str = SysAllocString( szbs );
812     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
813     ok( r == S_OK, "ret %08lx\n", r );
814     r = IXMLDOMNodeList_get_length( node_list, &len );
815     ok( r == S_OK, "ret %08lx\n", r );
816     ok( len == 1, "len %ld\n", len );
817     IXMLDOMNodeList_Release( node_list );
818     SysFreeString( str );
819
820     str = SysAllocString( szdl );
821     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
822     ok( r == S_OK, "ret %08lx\n", r );
823     r = IXMLDOMNodeList_get_length( node_list, &len );
824     ok( r == S_OK, "ret %08lx\n", r );
825     ok( len == 0, "len %ld\n", len );
826     IXMLDOMNodeList_Release( node_list );
827     SysFreeString( str );
828
829     str = SysAllocString( szstr1 );
830     r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
831     ok( r == S_OK, "ret %08lx\n", r );
832     r = IXMLDOMNodeList_get_length( node_list, &len );
833     ok( r == S_OK, "ret %08lx\n", r );
834     ok( len == 0, "len %ld\n", len );
835     IXMLDOMNodeList_Release( node_list );
836     SysFreeString( str );
837
838     IXMLDOMDocument_Release( doc );
839 }
840
841 static void test_get_text(void)
842 {
843     HRESULT r;
844     BSTR str;
845     VARIANT_BOOL b;
846     IXMLDOMDocument *doc;
847     IXMLDOMNode *node, *node2, *node3;
848     IXMLDOMNodeList *node_list;
849     IXMLDOMNamedNodeMap *node_map;
850
851     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
852         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
853     if( r != S_OK )
854         return;
855
856     str = SysAllocString( szComplete4 );
857     r = IXMLDOMDocument_loadXML( doc, str, &b );
858     ok( r == S_OK, "loadXML failed\n");
859     ok( b == VARIANT_TRUE, "failed to load XML string\n");
860     SysFreeString( str );
861
862     str = SysAllocString( szbs );
863     r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
864     ok( r == S_OK, "ret %08lx\n", r );
865     SysFreeString(str);
866     
867     r = IXMLDOMNodeList_get_item( node_list, 0, &node );
868     ok( r == S_OK, "ret %08lx\n", r ); 
869     IXMLDOMNodeList_Release( node_list );
870
871     r = IXMLDOMNode_get_text( node, &str );
872     ok( r == S_OK, "ret %08lx\n", r );
873 todo_wine {
874     ok( !memcmp(str, szfn1_txt, sizeof(szfn1_txt)), "wrong string\n" );
875  }
876     ok( !memcmp(str, szfn1_txt, sizeof(szfn1_txt)-4), "wrong string\n" );
877     SysFreeString(str);
878
879     r = IXMLDOMNode_get_attributes( node, &node_map );
880     ok( r == S_OK, "ret %08lx\n", r );
881     
882     str = SysAllocString( szvr );
883     r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
884     ok( r == S_OK, "ret %08lx\n", r );
885     SysFreeString(str);
886
887     r = IXMLDOMNode_get_text( node2, &str );
888     ok( r == S_OK, "ret %08lx\n", r );
889     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
890     SysFreeString(str);
891
892     r = IXMLDOMNode_get_firstChild( node2, &node3 );
893     ok( r == S_OK, "ret %08lx\n", r );
894
895     r = IXMLDOMNode_get_text( node3, &str );
896     ok( r == S_OK, "ret %08lx\n", r );
897     ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
898     SysFreeString(str);
899
900
901     IXMLDOMNode_Release( node3 );
902     IXMLDOMNode_Release( node2 );
903     IXMLDOMNamedNodeMap_Release( node_map );
904     IXMLDOMNode_Release( node );
905     IXMLDOMDocument_Release( doc );
906 }
907
908 static void test_get_childNodes(void)
909 {
910     HRESULT r;
911     BSTR str;
912     VARIANT_BOOL b;
913     IXMLDOMDocument *doc;
914     IXMLDOMElement *element;
915     IXMLDOMNode *node, *node2;
916     IXMLDOMNodeList *node_list, *node_list2;
917     long len;
918
919     r = CoCreateInstance( &CLSID_DOMDocument, NULL, 
920         CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
921     if( r != S_OK )
922         return;
923
924     str = SysAllocString( szComplete4 );
925     r = IXMLDOMDocument_loadXML( doc, str, &b );
926     ok( r == S_OK, "loadXML failed\n");
927     ok( b == VARIANT_TRUE, "failed to load XML string\n");
928     SysFreeString( str );
929
930     r = IXMLDOMDocument_get_documentElement( doc, &element );
931     ok( r == S_OK, "ret %08lx\n", r);
932
933     r = IXMLDOMElement_get_childNodes( element, &node_list );
934     ok( r == S_OK, "ret %08lx\n", r);
935
936     r = IXMLDOMNodeList_get_length( node_list, &len );
937     ok( r == S_OK, "ret %08lx\n", r);
938     ok( len == 3, "len %ld\n", len);
939
940     r = IXMLDOMNodeList_get_item( node_list, 2, &node );
941     ok( r == S_OK, "ret %08lx\n", r);
942
943     r = IXMLDOMNode_get_childNodes( node, &node_list2 );
944     ok( r == S_OK, "ret %08lx\n", r);
945
946     r = IXMLDOMNodeList_get_length( node_list2, &len );
947     ok( r == S_OK, "ret %08lx\n", r);
948     ok( len == 0, "len %ld\n", len);
949
950     r = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
951     ok( r == S_FALSE, "ret %08lx\n", r);
952
953     IXMLDOMNodeList_Release( node_list2 );
954     IXMLDOMNode_Release( node );
955     IXMLDOMNodeList_Release( node_list );
956     IXMLDOMElement_Release( element );
957     IXMLDOMDocument_Release( doc );
958 }
959     
960 START_TEST(domdoc)
961 {
962     HRESULT r;
963
964     r = CoInitialize( NULL );
965     ok( r == S_OK, "failed to init com\n");
966
967     test_domdoc();
968     test_domnode();
969     test_refs();
970     test_create();
971     test_getElementsByTagName();
972     test_get_text();
973     test_get_childNodes();
974
975     CoUninitialize();
976 }