4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2007-2008 Alistair Leslie-Hughes
6 * Copyright 2010-2011 Adam Martinson for CodeWeavers
7 * Copyright 2010-2013 Nikolay Sivov for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define WIN32_NO_STATUS
27 #define COM_NO_WINDOWS_H
35 //#include "windows.h"
37 #include <wine/test.h>
43 #include <msxml2did.h>
46 //#include "initguid.h"
48 /* undef the #define in msxml2 so that we can access all versions */
49 #undef CLSID_DOMDocument
51 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
53 static int g_unexpectedcall
, g_expectedcall
;
55 struct msxmlsupported_data_t
63 static struct msxmlsupported_data_t domdoc_support_data
[] =
65 { &CLSID_DOMDocument
, "DOMDocument", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
} },
66 { &CLSID_DOMDocument2
, "DOMDocument2", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
} },
67 { &CLSID_DOMDocument30
, "DOMDocument30", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
} },
68 { &CLSID_DOMDocument40
, "DOMDocument40", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
} },
69 { &CLSID_DOMDocument60
, "DOMDocument60", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
, &IID_IXMLDOMDocument3
} },
70 { &CLSID_FreeThreadedDOMDocument
, "FreeThreadedDOMDocument", {&IID_IXMLDOMDocument
, &IID_IXMLDOMDocument2
} },
71 { &CLSID_XMLSchemaCache
, "XMLSchemaCache", {&IID_IXMLDOMSchemaCollection
} },
72 { &CLSID_XSLTemplate
, "XSLTemplate", {&IID_IXSLTemplate
} },
73 { &CLSID_MXNamespaceManager40
, "MXNamespaceManager40", {&IID_IMXNamespaceManager
} },
77 static const char *debugstr_msxml_guid(REFIID riid
)
82 if (IsEqualIID(&IID_IXMLDOMDocument
, riid
))
83 return "IXMLDOMDocument";
84 else if (IsEqualIID(&IID_IXMLDOMDocument2
, riid
))
85 return "IXMLDOMDocument2";
86 else if (IsEqualIID(&IID_IXMLDOMDocument3
, riid
))
87 return "IXMLDOMDocument3";
88 else if (IsEqualIID(&IID_IXMLDOMSchemaCollection
, riid
))
89 return "IXMLDOMSchemaCollection";
90 else if (IsEqualIID(&IID_IXSLTemplate
, riid
))
91 return "IXSLTemplate";
92 else if (IsEqualIID(&IID_IMXNamespaceManager
, riid
))
93 return "IMXNamespaceManager";
95 return wine_dbgstr_guid(riid
);
98 static void get_class_support_data(struct msxmlsupported_data_t
*table
)
106 for (i
= 0; i
< sizeof(table
->ifaces
)/sizeof(table
->ifaces
[0]) && table
->ifaces
[i
] != NULL
; i
++)
108 hr
= CoCreateInstance(table
->clsid
, NULL
, CLSCTX_INPROC_SERVER
, table
->ifaces
[i
], (void**)&unk
);
109 if (hr
== S_OK
) IUnknown_Release(unk
);
111 table
->supported
[i
] = hr
== S_OK
;
112 if (hr
!= S_OK
) win_skip("class %s, iface %s not supported\n", table
->name
, debugstr_msxml_guid(table
->ifaces
[i
]));
119 static BOOL
is_clsid_supported(const GUID
*clsid
, REFIID riid
)
121 const struct msxmlsupported_data_t
*table
= domdoc_support_data
;
124 if (table
->clsid
== clsid
)
128 for (i
= 0; i
< sizeof(table
->ifaces
)/sizeof(table
->ifaces
[0]) && table
->ifaces
[i
] != NULL
; i
++)
129 if (table
->ifaces
[i
] == riid
) return table
->supported
[i
];
139 IDispatch IDispatch_iface
;
143 static inline dispevent
*impl_from_IDispatch( IDispatch
*iface
)
145 return CONTAINING_RECORD(iface
, dispevent
, IDispatch_iface
);
148 static HRESULT WINAPI
dispevent_QueryInterface(IDispatch
*iface
, REFIID riid
, void **ppvObject
)
152 if ( IsEqualGUID( riid
, &IID_IDispatch
) ||
153 IsEqualGUID( riid
, &IID_IUnknown
) )
158 return E_NOINTERFACE
;
160 IDispatch_AddRef( iface
);
165 static ULONG WINAPI
dispevent_AddRef(IDispatch
*iface
)
167 dispevent
*This
= impl_from_IDispatch( iface
);
168 return InterlockedIncrement( &This
->ref
);
171 static ULONG WINAPI
dispevent_Release(IDispatch
*iface
)
173 dispevent
*This
= impl_from_IDispatch( iface
);
174 ULONG ref
= InterlockedDecrement( &This
->ref
);
177 HeapFree(GetProcessHeap(), 0, This
);
182 static HRESULT WINAPI
dispevent_GetTypeInfoCount(IDispatch
*iface
, UINT
*pctinfo
)
189 static HRESULT WINAPI
dispevent_GetTypeInfo(IDispatch
*iface
, UINT iTInfo
,
190 LCID lcid
, ITypeInfo
**ppTInfo
)
196 static HRESULT WINAPI
dispevent_GetIDsOfNames(IDispatch
*iface
, REFIID riid
,
197 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
203 static HRESULT WINAPI
dispevent_Invoke(IDispatch
*iface
, DISPID member
, REFIID riid
,
204 LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*result
,
205 EXCEPINFO
*excepInfo
, UINT
*argErr
)
207 ok(member
== 0, "expected 0 member, got %d\n", member
);
208 ok(lcid
== LOCALE_SYSTEM_DEFAULT
, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid
);
209 ok(flags
== DISPATCH_METHOD
, "expected DISPATCH_METHOD, got %d\n", flags
);
211 ok(params
->cArgs
== 0, "got %d\n", params
->cArgs
);
212 ok(params
->cNamedArgs
== 0, "got %d\n", params
->cNamedArgs
);
213 ok(params
->rgvarg
== NULL
, "got %p\n", params
->rgvarg
);
214 ok(params
->rgdispidNamedArgs
== NULL
, "got %p\n", params
->rgdispidNamedArgs
);
216 ok(result
== NULL
, "got %p\n", result
);
217 ok(excepInfo
== NULL
, "got %p\n", excepInfo
);
218 ok(argErr
== NULL
, "got %p\n", argErr
);
224 static const IDispatchVtbl dispeventVtbl
=
226 dispevent_QueryInterface
,
229 dispevent_GetTypeInfoCount
,
230 dispevent_GetTypeInfo
,
231 dispevent_GetIDsOfNames
,
235 static IDispatch
* create_dispevent(void)
237 dispevent
*event
= HeapAlloc(GetProcessHeap(), 0, sizeof(*event
));
239 event
->IDispatch_iface
.lpVtbl
= &dispeventVtbl
;
242 return (IDispatch
*)&event
->IDispatch_iface
;
246 static HRESULT WINAPI
istream_QueryInterface(IStream
*iface
, REFIID riid
, void **ppvObject
)
250 if (IsEqualGUID(riid
, &IID_IStream
) ||
251 IsEqualGUID(riid
, &IID_IUnknown
))
254 return E_NOINTERFACE
;
259 static ULONG WINAPI
istream_AddRef(IStream
*iface
)
264 static ULONG WINAPI
istream_Release(IStream
*iface
)
269 static HRESULT WINAPI
istream_Read(IStream
*iface
, void *ptr
, ULONG len
, ULONG
*pread
)
271 ok(0, "unexpected call\n");
275 static HRESULT WINAPI
istream_Write(IStream
*iface
, const void *ptr
, ULONG len
, ULONG
*written
)
281 static HRESULT WINAPI
istream_Seek(IStream
*iface
, LARGE_INTEGER move
, DWORD origin
, ULARGE_INTEGER
*new_pos
)
283 ok(0, "unexpected call\n");
287 static HRESULT WINAPI
istream_SetSize(IStream
*iface
, ULARGE_INTEGER size
)
289 ok(0, "unexpected call\n");
293 static HRESULT WINAPI
istream_CopyTo(IStream
*iface
, IStream
*stream
, ULARGE_INTEGER len
,
294 ULARGE_INTEGER
*pread
, ULARGE_INTEGER
*written
)
296 ok(0, "unexpected call\n");
300 static HRESULT WINAPI
istream_Commit(IStream
*iface
, DWORD flags
)
302 ok(0, "unexpected call\n");
306 static HRESULT WINAPI
istream_Revert(IStream
*iface
)
308 ok(0, "unexpected call\n");
312 static HRESULT WINAPI
istream_LockRegion(IStream
*iface
, ULARGE_INTEGER offset
,
313 ULARGE_INTEGER len
, DWORD locktype
)
315 ok(0, "unexpected call\n");
319 static HRESULT WINAPI
istream_UnlockRegion(IStream
*iface
, ULARGE_INTEGER offset
,
320 ULARGE_INTEGER len
, DWORD locktype
)
322 ok(0, "unexpected call\n");
326 static HRESULT WINAPI
istream_Stat(IStream
*iface
, STATSTG
*pstatstg
, DWORD flag
)
328 ok(0, "unexpected call\n");
332 static HRESULT WINAPI
istream_Clone(IStream
*iface
, IStream
**stream
)
334 ok(0, "unexpected call\n");
338 static const IStreamVtbl StreamVtbl
= {
339 istream_QueryInterface
,
350 istream_UnlockRegion
,
355 static IStream savestream
= { &StreamVtbl
};
357 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
358 static void _expect_children(IXMLDOMNode
*node
, int line
)
364 hr
= IXMLDOMNode_hasChildNodes(node
, &b
);
365 ok_(__FILE__
,line
)(hr
== S_OK
, "hasChildNodes() failed, 0x%08x\n", hr
);
366 ok_(__FILE__
,line
)(b
== VARIANT_TRUE
, "no children, %d\n", b
);
369 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
370 static void _expect_no_children(IXMLDOMNode
*node
, int line
)
376 hr
= IXMLDOMNode_hasChildNodes(node
, &b
);
377 ok_(__FILE__
,line
)(hr
== S_FALSE
, "hasChildNodes() failed, 0x%08x\n", hr
);
378 ok_(__FILE__
,line
)(b
== VARIANT_FALSE
, "no children, %d\n", b
);
381 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
382 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
385 IUnknown_AddRef(obj
);
386 rc
= IUnknown_Release(obj
);
387 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
390 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
391 static void _expect_list_len(IXMLDOMNodeList
*list
, LONG len
, int line
)
397 hr
= IXMLDOMNodeList_get_length(list
, &length
);
398 ok_(__FILE__
,line
)(hr
== S_OK
, "got 0x%08x\n", hr
);
399 ok_(__FILE__
,line
)(length
== len
, "got %d, expected %d\n", length
, len
);
402 #define EXPECT_HR(hr,hr_exp) \
403 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
405 #define EXPECT_NOT_HR(hr,hr_exp) \
406 ok(hr != hr_exp, "got 0x%08x, expected not 0x%08x\n", hr, hr_exp)
408 static const WCHAR szEmpty
[] = { 0 };
409 static const WCHAR szIncomplete
[] = {
410 '<','?','x','m','l',' ',
411 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
413 static const WCHAR szComplete1
[] = {
414 '<','?','x','m','l',' ',
415 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
416 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
418 static const WCHAR szComplete2
[] = {
419 '<','?','x','m','l',' ',
420 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
421 '<','a','>','<','/','a','>','\n',0
423 static const char complete4A
[] =
424 "<?xml version=\'1.0\'?>\n"
426 "<bs vr=\'str2\' sz=\'1234\'>"
429 "<pr id=\'str3\' vr=\'1.2.3\' pn=\'wine 20050804\'>\n"
440 static const WCHAR szComplete5
[] = {
441 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
442 'x','m','l','n','s',':','C','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y','"',
443 ' ','x','m','l','n','s',':','S','=','"','u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','o','f','f','i','c','e',':','c','l','i','p','g','a','l','l','e','r','y',':','s','e','a','r','c','h','"','>',
444 '<','S',':','s','c','o','p','e','>',
445 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
446 '<','/','S',':','s','c','o','p','e','>',
447 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
448 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
449 'c','o','m','p','u','t','e','r',
450 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
451 '<','/','S',':','s','e','a','r','c','h','>',0
454 static const WCHAR szComplete6
[] = {
455 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
456 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
457 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
460 static const char complete7
[] = {
461 "<?xml version=\"1.0\"?>\n\t"
469 #define DECL_WIN_1252 \
470 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
472 static const char win1252xml
[] =
476 static const char win1252decl
[] =
480 static const char nocontent
[] = "no xml content here";
482 static const char szExampleXML
[] =
483 "<?xml version='1.0' encoding='utf-8'?>\n"
484 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' a=\"attr a\" foo:b=\"attr b\" >\n"
490 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
491 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
492 " This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
494 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
495 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
503 " <c type=\"old\">C2 field</c>\n"
507 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
516 " <foo:c>C4 field</foo:c>\n"
521 static const char charrefsxml
[] =
522 "<?xml version='1.0'?>"
524 "<b1> Text A end </b1>"
525 "<b2>AB C </b2>"
528 static const CHAR szNodeTypesXML
[] =
529 "<?xml version='1.0'?>"
530 "<!-- comment node 0 -->"
531 "<root id='0' depth='0'>"
532 " <!-- comment node 1 -->"
534 " <x id='1' depth='1'>"
535 " <?foo value='PI for x'?>"
536 " <!-- comment node 2 -->"
538 " <a id='3' depth='2'/>"
539 " <b id='4' depth='2'/>"
540 " <c id='5' depth='2'/>"
542 " <y id='2' depth='1'>"
543 " <?bar value='PI for y'?>"
544 " <!-- comment node 3 -->"
546 " <a id='6' depth='2'/>"
547 " <b id='7' depth='2'/>"
548 " <c id='8' depth='2'/>"
552 static const CHAR szTransformXML
[] =
553 "<?xml version=\"1.0\"?>\n"
558 static const CHAR szTransformSSXML
[] =
559 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
560 " <xsl:output method=\"html\"/>\n"
561 " <xsl:template match=\"/\">\n"
562 " <xsl:apply-templates select=\"greeting\"/>\n"
564 " <xsl:template match=\"greeting\">\n"
568 " <xsl:value-of select=\".\"/>\n"
575 static const CHAR szTransformOutput
[] =
578 "</h1></body></html>";
580 static const CHAR szTypeValueXML
[] =
581 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
582 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
583 " <string>Wine</string>\n"
584 " <string2 dt:dt=\"string\">String</string2>\n"
585 " <number dt:dt=\"number\">12.44</number>\n"
586 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
587 " <int dt:dt=\"int\">-13</int>\n"
588 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
589 " <bool dt:dt=\"boolean\">1</bool>\n"
590 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
591 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
592 " <date dt:dt=\"date\">3721-11-01</date>\n"
593 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
594 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
595 " <i1 dt:dt=\"i1\">-13</i1>\n"
596 " <i2 dt:dt=\"i2\">31915</i2>\n"
597 " <i4 dt:dt=\"i4\">-312232</i4>\n"
598 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
599 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
600 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
601 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
602 " <r8 dt:dt=\"r8\">0.412</r8>\n"
603 " <float dt:dt=\"float\">41221.421</float>\n"
604 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
605 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
606 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
607 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
608 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
611 static const CHAR szBasicTransformSSXMLPart1
[] =
612 "<?xml version=\"1.0\"?>"
613 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
614 "<xsl:output method=\"html\"/>\n"
615 "<xsl:template match=\"/\">"
616 "<HTML><BODY><TABLE>"
617 " <xsl:apply-templates select='document(\"";
619 static const CHAR szBasicTransformSSXMLPart2
[] =
621 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
622 " </xsl:apply-templates>"
623 "</TABLE></BODY></HTML>"
625 "<xsl:template match=\"bottle\">"
626 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
628 "<xsl:template match=\"name\">"
629 " <TD><xsl:apply-templates /></TD>"
631 "<xsl:template match=\"cost\">"
632 " <TD><xsl:apply-templates /></TD>"
636 static const CHAR szBasicTransformXML
[] =
637 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
639 static const CHAR szBasicTransformOutput
[] =
640 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
642 #define SZ_EMAIL_DTD \
644 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
645 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
646 " <!ATTLIST email sent (yes|no) \"no\">"\
647 " <!ELEMENT recipients (to+,cc*)>"\
648 " <!ELEMENT to (#PCDATA)>"\
649 " <!ATTLIST to name CDATA #IMPLIED>"\
650 " <!ELEMENT cc (#PCDATA)>"\
651 " <!ATTLIST cc name CDATA #IMPLIED>"\
652 " <!ELEMENT from (#PCDATA)>"\
653 " <!ATTLIST from name CDATA #IMPLIED>"\
654 " <!ELEMENT reply-to (#PCDATA)>"\
655 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
656 " <!ELEMENT subject ANY>"\
657 " <!ELEMENT body ANY>"\
658 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
659 " <!ELEMENT attachment (#PCDATA)>"\
660 " <!ATTLIST attachment id ID #REQUIRED>"\
663 static const CHAR szEmailXML
[] =
664 "<?xml version=\"1.0\"?>"
666 "<email attachments=\"patch1\">"
668 " <to>wine-patches@winehq.org</to>"
670 " <from name=\"Anonymous\">user@localhost</from>"
671 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
673 " It no longer causes spontaneous combustion..."
675 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
678 static const CHAR szEmailXML_0D
[] =
679 "<?xml version=\"1.0\"?>"
681 "<email attachments=\"patch1\">"
683 " <to>wine-patches@winehq.org</to>"
685 " <from name=\"Anonymous\">user@localhost</from>"
686 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
689 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
691 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
694 static const CHAR szEmailXML_0E
[] =
695 "<?xml version=\"1.0\"?>"
697 "<email attachments=\"patch1\">"
699 " <to>wine-patches@winehq.org</to>"
701 " <from name=\"Anonymous\">user@localhost</from>"
702 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
704 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
706 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
709 static const CHAR szEmailXML_11
[] =
710 "<?xml version=\"1.0\"?>"
712 "<email attachments=\"patch1\">"
715 " <from name=\"Anonymous\">user@localhost</from>"
716 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
718 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
720 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
723 static const CHAR szEmailXML_13
[] =
724 "<?xml version=\"1.0\"?>"
726 "<msg attachments=\"patch1\">"
728 " <to>wine-patches@winehq.org</to>"
730 " <from name=\"Anonymous\">user@localhost</from>"
731 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
733 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
735 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
738 static const CHAR szEmailXML_14
[] =
739 "<?xml version=\"1.0\"?>"
741 "<email attachments=\"patch1\">"
742 " <to>wine-patches@winehq.org</to>"
743 " <from name=\"Anonymous\">user@localhost</from>"
744 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
746 " XML_INVALID_CONTENT 0xC00CE014"
748 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
751 static const CHAR szEmailXML_15
[] =
752 "<?xml version=\"1.0\"?>"
754 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
756 " <to>wine-patches@winehq.org</to>"
758 " <from name=\"Anonymous\">user@localhost</from>"
759 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
761 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
763 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
766 static const CHAR szEmailXML_16
[] =
767 "<?xml version=\"1.0\"?>"
769 "<email attachments=\"patch1\">"
771 " <to>wine-patches@winehq.org</to>"
773 " <from name=\"Anonymous\">user@localhost</from>"
774 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
775 " <body enc=\"ASCII\">"
776 " XML_ATTRIBUTE_FIXED 0xC00CE016"
778 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
781 static const CHAR szEmailXML_17
[] =
782 "<?xml version=\"1.0\"?>"
784 "<email attachments=\"patch1\" sent=\"true\">"
786 " <to>wine-patches@winehq.org</to>"
788 " <from name=\"Anonymous\">user@localhost</from>"
789 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
791 " XML_ATTRIBUTE_VALUE 0xC00CE017"
793 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
796 static const CHAR szEmailXML_18
[] =
797 "<?xml version=\"1.0\"?>"
799 "<email attachments=\"patch1\">"
802 " <to>wine-patches@winehq.org</to>"
804 " <from name=\"Anonymous\">user@localhost</from>"
805 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
807 " XML_ILLEGAL_TEXT 0xC00CE018"
809 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
812 static const CHAR szEmailXML_20
[] =
813 "<?xml version=\"1.0\"?>"
817 " <to>wine-patches@winehq.org</to>"
819 " <from name=\"Anonymous\">user@localhost</from>"
820 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
822 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
824 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
827 static const char xpath_simple_list
[] =
828 "<?xml version=\"1.0\"?>"
830 " <a attr1=\"1\" attr2=\"2\" />"
836 static const char default_ns_doc
[] = {
837 "<?xml version=\"1.0\"?>"
838 "<a xmlns:ns=\"nshref\" xml:lang=\"ru\" ns:b=\"b attr\" xml:c=\"c attr\" "
842 static const char attributes_map
[] = {
843 "<?xml version=\"1.0\"?>"
844 "<a attr1=\"value1\" attr2=\"value2\" attr3=\"value3\" attr4=\"value4\" />"
847 static const WCHAR nonexistent_fileW
[] = {
848 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
850 static const WCHAR nonexistent_attrW
[] = {
851 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
853 static const WCHAR szDocument
[] = {
854 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
857 static const WCHAR szOpen
[] = { 'o','p','e','n',0 };
858 static const WCHAR szdl
[] = { 'd','l',0 };
859 static const WCHAR szvr
[] = { 'v','r',0 };
860 static const WCHAR szlc
[] = { 'l','c',0 };
861 static const WCHAR szbs
[] = { 'b','s',0 };
862 static const WCHAR szstr1
[] = { 's','t','r','1',0 };
863 static const WCHAR szstr2
[] = { 's','t','r','2',0 };
864 static const WCHAR szstar
[] = { '*',0 };
865 static const WCHAR szfn1_txt
[] = {'f','n','1','.','t','x','t',0};
867 static const WCHAR szComment
[] = {'A',' ','C','o','m','m','e','n','t',0 };
868 static const WCHAR szCommentXML
[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
869 static const WCHAR szCommentNodeText
[] = {'#','c','o','m','m','e','n','t',0 };
871 static WCHAR szElement
[] = {'E','l','e','T','e','s','t', 0 };
872 static const WCHAR szElementXML
[] = {'<','E','l','e','T','e','s','t','/','>',0 };
873 static const WCHAR szElementXML2
[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
874 static const WCHAR szElementXML3
[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
875 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
876 static const WCHAR szElementXML4
[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
877 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
879 static const WCHAR szAttribute
[] = {'A','t','t','r',0 };
880 static const WCHAR szAttributeXML
[] = {'A','t','t','r','=','"','"',0 };
882 static const WCHAR szCData
[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
883 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
884 static const WCHAR szCDataXML
[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
885 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
887 static const WCHAR szCDataNodeText
[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
888 static const WCHAR szDocFragmentText
[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
890 static const WCHAR szEntityRef
[] = {'e','n','t','i','t','y','r','e','f',0 };
891 static const WCHAR szEntityRefXML
[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
892 static const WCHAR szStrangeChars
[] = {'&','x',' ',0x2103, 0};
894 #define expect_bstr_eq_and_free(bstr, expect) { \
895 BSTR bstrExp = alloc_str_from_narrow(expect); \
896 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
897 SysFreeString(bstr); \
898 SysFreeString(bstrExp); \
901 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
903 #define ole_check(expr) { \
905 ok(r == S_OK, #expr " returned %x\n", r); \
908 #define ole_expect(expr, expect) { \
910 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
913 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
915 static void* _create_object(const GUID
*clsid
, const char *name
, const IID
*iid
, int line
)
920 hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, iid
, &obj
);
921 ok(hr
== S_OK
, "failed to create %s instance: 0x%08x\n", name
, hr
);
926 #define _create(cls) cls, #cls
928 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument2), iid, __LINE__)
929 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
930 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
931 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
933 static BSTR
alloc_str_from_narrow(const char *str
)
935 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
936 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
937 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
941 static BSTR alloced_bstrs
[256];
942 static int alloced_bstrs_count
;
944 static BSTR
_bstr_(const char *str
)
946 assert(alloced_bstrs_count
< sizeof(alloced_bstrs
)/sizeof(alloced_bstrs
[0]));
947 alloced_bstrs
[alloced_bstrs_count
] = alloc_str_from_narrow(str
);
948 return alloced_bstrs
[alloced_bstrs_count
++];
951 static void free_bstrs(void)
954 for (i
= 0; i
< alloced_bstrs_count
; i
++)
955 SysFreeString(alloced_bstrs
[i
]);
956 alloced_bstrs_count
= 0;
959 static VARIANT
_variantbstr_(const char *str
)
963 V_BSTR(&v
) = _bstr_(str
);
967 static BOOL
compareIgnoreReturns(BSTR sLeft
, BSTR sRight
)
971 while (*sLeft
== '\r' || *sLeft
== '\n') sLeft
++;
972 while (*sRight
== '\r' || *sRight
== '\n') sRight
++;
973 if (*sLeft
!= *sRight
) return FALSE
;
974 if (!*sLeft
) return TRUE
;
980 static void get_str_for_type(DOMNodeType type
, char *buf
)
999 case NODE_PROCESSING_INSTRUCTION
:
1003 wsprintfA(buf
, "[%d]", type
);
1007 static int get_node_position(IXMLDOMNode
*node
)
1012 IXMLDOMNode_AddRef(node
);
1015 IXMLDOMNode
*new_node
;
1018 r
= IXMLDOMNode_get_previousSibling(node
, &new_node
);
1019 ok(SUCCEEDED(r
), "get_previousSibling failed\n");
1020 IXMLDOMNode_Release(node
);
1022 } while (r
== S_OK
);
1026 static void node_to_string(IXMLDOMNode
*node
, char *buf
)
1033 lstrcpyA(buf
, "(null)");
1037 IXMLDOMNode_AddRef(node
);
1040 IXMLDOMNode
*new_node
;
1042 ole_check(IXMLDOMNode_get_nodeType(node
, &type
));
1043 get_str_for_type(type
, buf
);
1046 if (type
== NODE_ATTRIBUTE
)
1049 ole_check(IXMLDOMNode_get_nodeName(node
, &bstr
));
1051 wsprintfA(buf
, "%ws", bstr
);
1054 SysFreeString(bstr
);
1056 r
= IXMLDOMNode_selectSingleNode(node
, _bstr_(".."), &new_node
);
1060 r
= IXMLDOMNode_get_parentNode(node
, &new_node
);
1061 sprintf(buf
, "%d", get_node_position(node
));
1065 ok(SUCCEEDED(r
), "get_parentNode failed (%08x)\n", r
);
1066 IXMLDOMNode_Release(node
);
1075 static char *list_to_string(IXMLDOMNodeList
*list
)
1077 static char buf
[4096];
1085 strcpy(buf
, "(null)");
1088 hr
= IXMLDOMNodeList_get_length(list
, &len
);
1089 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1090 for (i
= 0; i
< len
; i
++)
1095 ole_check(IXMLDOMNodeList_nextNode(list
, &node
));
1096 node_to_string(node
, pos
);
1098 IXMLDOMNode_Release(node
);
1104 #define expect_node(node, expstr) { char str[4096]; node_to_string(node, str); ok(strcmp(str, expstr)==0, "Invalid node: %s, expected %s\n", str, expstr); }
1105 #define expect_list_and_release(list, expstr) { char *str = list_to_string(list); ok(strcmp(str, expstr)==0, "Invalid node list: %s, expected %s\n", str, expstr); if (list) IXMLDOMNodeList_Release(list); }
1107 struct docload_ret_t
{
1112 struct leading_spaces_t
{
1115 struct docload_ret_t ret
[2]; /* 0 - ::load(), 1 - ::loadXML() */
1118 static const struct leading_spaces_t leading_spaces_classdata
[] = {
1119 { &CLSID_DOMDocument
, "CLSID_DOMDocument", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_TRUE
, S_OK
} }},
1120 { &CLSID_DOMDocument2
, "CLSID_DOMDocument2", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_FALSE
, S_FALSE
} }},
1121 { &CLSID_DOMDocument26
, "CLSID_DOMDocument26", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_TRUE
, S_OK
} }},
1122 { &CLSID_DOMDocument30
, "CLSID_DOMDocument30", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_FALSE
, S_FALSE
} }},
1123 { &CLSID_DOMDocument40
, "CLSID_DOMDocument40", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_FALSE
, S_FALSE
} }},
1124 { &CLSID_DOMDocument60
, "CLSID_DOMDocument60", {{VARIANT_FALSE
, S_FALSE
}, {VARIANT_FALSE
, S_FALSE
} }},
1128 static const char* leading_spaces_xmldata
[] = {
1129 "\n<?xml version=\"1.0\" encoding=\"UTF-16\" ?><root/>",
1130 " <?xml version=\"1.0\"?><root/>",
1131 "\n<?xml version=\"1.0\"?><root/>",
1132 "\t<?xml version=\"1.0\"?><root/>",
1133 "\r\n<?xml version=\"1.0\"?><root/>",
1134 "\r<?xml version=\"1.0\"?><root/>",
1135 "\r\r\r\r\t\t \n\n <?xml version=\"1.0\"?><root/>",
1139 static void test_domdoc( void )
1142 IXMLDOMDocument
*doc
;
1143 IXMLDOMParseError
*error
;
1144 IXMLDOMElement
*element
= NULL
;
1146 IXMLDOMText
*nodetext
= NULL
;
1147 IXMLDOMComment
*node_comment
= NULL
;
1148 IXMLDOMAttribute
*node_attr
= NULL
;
1149 IXMLDOMNode
*nodeChild
= NULL
;
1150 IXMLDOMProcessingInstruction
*nodePI
= NULL
;
1151 const struct leading_spaces_t
*class_ptr
;
1152 const char **data_ptr
;
1159 char path
[MAX_PATH
];
1162 GetTempPathA(MAX_PATH
, path
);
1163 strcat(path
, "leading_spaces.xml");
1165 /* Load document with leading spaces
1167 * Test all CLSIDs with all test data XML strings
1169 class_ptr
= leading_spaces_classdata
;
1171 while (class_ptr
->clsid
)
1176 if (is_clsid_supported(class_ptr
->clsid
, &IID_IXMLDOMDocument
))
1178 hr
= CoCreateInstance(class_ptr
->clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IXMLDOMDocument
, (void**)&doc
);
1187 data_ptr
= leading_spaces_xmldata
;
1190 BSTR data
= _bstr_(*data_ptr
);
1194 file
= CreateFileA(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1195 ok(file
!= INVALID_HANDLE_VALUE
, "can't create file %s: %u\n", path
, GetLastError());
1197 WriteFile(file
, data
, lstrlenW(data
)*sizeof(WCHAR
), &written
, NULL
);
1201 V_VT(&var
) = VT_BSTR
;
1202 V_BSTR(&var
) = _bstr_(path
);
1203 hr
= IXMLDOMDocument_load(doc
, var
, &b
);
1204 EXPECT_HR(hr
, class_ptr
->ret
[0].hr
);
1205 ok(b
== class_ptr
->ret
[0].b
, "%d:%d, got %d, expected %d\n", index
, i
, b
, class_ptr
->ret
[0].b
);
1210 hr
= IXMLDOMDocument_loadXML(doc
, data
, &b
);
1211 EXPECT_HR(hr
, class_ptr
->ret
[1].hr
);
1212 ok(b
== class_ptr
->ret
[1].b
, "%d:%d, got %d, expected %d\n", index
, i
, b
, class_ptr
->ret
[1].b
);
1223 doc
= create_document(&IID_IXMLDOMDocument
);
1228 /* crashes on native */
1229 IXMLDOMDocument_loadXML( doc
, (BSTR
)0x1, NULL
);
1232 /* try some stupid things */
1233 hr
= IXMLDOMDocument_loadXML( doc
, NULL
, NULL
);
1234 EXPECT_HR(hr
, S_FALSE
);
1237 hr
= IXMLDOMDocument_loadXML( doc
, NULL
, &b
);
1238 EXPECT_HR(hr
, S_FALSE
);
1239 ok( b
== VARIANT_FALSE
, "failed to load XML string\n");
1241 /* try to load a document from a nonexistent file */
1243 str
= SysAllocString( nonexistent_fileW
);
1245 V_VT(&var
) = VT_BSTR
;
1248 r
= IXMLDOMDocument_load( doc
, var
, &b
);
1249 ok( r
== S_FALSE
, "loadXML succeeded\n");
1250 ok( b
== VARIANT_FALSE
, "succeeded in loading XML string\n");
1251 SysFreeString( str
);
1254 hr
= IXMLDOMDocument_get_url(doc
, &str
);
1255 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1256 ok(str
== NULL
, "got %p\n", str
);
1258 /* try load an empty document */
1260 str
= SysAllocString( szEmpty
);
1261 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1262 ok( r
== S_FALSE
, "loadXML succeeded\n");
1263 ok( b
== VARIANT_FALSE
, "succeeded in loading XML string\n");
1264 SysFreeString( str
);
1266 r
= IXMLDOMDocument_get_async( doc
, &b
);
1267 ok( r
== S_OK
, "get_async failed (%08x)\n", r
);
1268 ok( b
== VARIANT_TRUE
, "Wrong default value\n");
1270 /* check that there's no document element */
1272 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
1273 ok( r
== S_FALSE
, "should be no document element\n");
1275 /* try finding a node */
1277 str
= SysAllocString( szstr1
);
1278 r
= IXMLDOMDocument_selectSingleNode( doc
, str
, &node
);
1279 ok( r
== S_FALSE
, "ret %08x\n", r
);
1280 SysFreeString( str
);
1283 str
= SysAllocString( szIncomplete
);
1284 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1285 ok( r
== S_FALSE
, "loadXML succeeded\n");
1286 ok( b
== VARIANT_FALSE
, "succeeded in loading XML string\n");
1287 SysFreeString( str
);
1289 /* check that there's no document element */
1290 element
= (IXMLDOMElement
*)1;
1291 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
1292 ok( r
== S_FALSE
, "should be no document element\n");
1293 ok( element
== NULL
, "Element should be NULL\n");
1295 /* test for BSTR handling, pass broken BSTR */
1296 memcpy(&buff
[2], szComplete1
, sizeof(szComplete1
));
1297 /* just a big length */
1298 *(DWORD
*)buff
= 0xf0f0;
1300 r
= IXMLDOMDocument_loadXML( doc
, &buff
[2], &b
);
1301 ok( r
== S_OK
, "loadXML failed\n");
1302 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1304 /* loadXML ignores the encoding attribute and always expects Unicode */
1306 str
= SysAllocString( szComplete6
);
1307 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1308 ok( r
== S_OK
, "loadXML failed\n");
1309 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1310 SysFreeString( str
);
1312 /* try a BSTR containing a Windows-1252 document */
1314 str
= SysAllocStringByteLen( win1252xml
, strlen(win1252xml
) );
1315 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1316 ok( r
== S_FALSE
, "loadXML succeeded\n");
1317 ok( b
== VARIANT_FALSE
, "succeeded in loading XML string\n");
1318 SysFreeString( str
);
1320 /* try to load something valid */
1322 str
= SysAllocString( szComplete1
);
1323 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1324 ok( r
== S_OK
, "loadXML failed\n");
1325 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1326 SysFreeString( str
);
1328 /* check if nodename is correct */
1329 r
= IXMLDOMDocument_get_nodeName( doc
, NULL
);
1330 ok ( r
== E_INVALIDARG
, "get_nodeName (NULL) wrong code\n");
1332 str
= (BSTR
)0xdeadbeef;
1333 r
= IXMLDOMDocument_get_baseName( doc
, &str
);
1334 ok ( r
== S_FALSE
, "got 0x%08x\n", r
);
1335 ok (str
== NULL
, "got %p\n", str
);
1337 /* content doesn't matter here */
1339 r
= IXMLDOMDocument_get_nodeName( doc
, &str
);
1340 ok ( r
== S_OK
, "get_nodeName wrong code\n");
1341 ok ( str
!= NULL
, "str is null\n");
1342 ok( !lstrcmpW( str
, szDocument
), "incorrect nodeName\n");
1343 SysFreeString( str
);
1346 r
= IXMLDOMDocument_put_text( doc
, _bstr_("Should fail") );
1347 ok( r
== E_FAIL
, "ret %08x\n", r
);
1349 /* check that there's a document element */
1351 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
1352 ok( r
== S_OK
, "should be a document element\n");
1355 IObjectIdentity
*ident
;
1357 r
= IXMLDOMElement_QueryInterface( element
, &IID_IObjectIdentity
, (void**)&ident
);
1358 ok( r
== E_NOINTERFACE
, "ret %08x\n", r
);
1360 IXMLDOMElement_Release( element
);
1364 /* as soon as we call loadXML again, the document element will disappear */
1366 r
= IXMLDOMDocument_loadXML( doc
, NULL
, NULL
);
1367 ok( r
== S_FALSE
, "loadXML failed\n");
1368 ok( b
== 2, "variant modified\n");
1369 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
1370 ok( r
== S_FALSE
, "should be no document element\n");
1372 /* try to load something else simple and valid */
1374 str
= SysAllocString( szComplete2
);
1375 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
1376 ok( r
== S_OK
, "loadXML failed\n");
1377 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1378 SysFreeString( str
);
1380 /* try something a little more complicated */
1382 r
= IXMLDOMDocument_loadXML( doc
, _bstr_(complete4A
), &b
);
1383 ok( r
== S_OK
, "loadXML failed\n");
1384 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1386 r
= IXMLDOMDocument_get_parseError( doc
, &error
);
1387 ok( r
== S_OK
, "returns %08x\n", r
);
1389 r
= IXMLDOMParseError_get_errorCode( error
, &code
);
1390 ok( r
== S_FALSE
, "returns %08x\n", r
);
1391 ok( code
== 0, "code %d\n", code
);
1392 IXMLDOMParseError_Release( error
);
1394 /* test createTextNode */
1395 r
= IXMLDOMDocument_createTextNode(doc
, _bstr_(""), &nodetext
);
1396 ok( r
== S_OK
, "returns %08x\n", r
);
1397 IXMLDOMText_Release(nodetext
);
1399 str
= SysAllocString( szOpen
);
1400 r
= IXMLDOMDocument_createTextNode(doc
, str
, NULL
);
1401 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
1402 r
= IXMLDOMDocument_createTextNode(doc
, str
, &nodetext
);
1403 ok( r
== S_OK
, "returns %08x\n", r
);
1404 SysFreeString( str
);
1407 r
= IXMLDOMText_QueryInterface(nodetext
, &IID_IXMLDOMElement
, (void**)&element
);
1408 ok(r
== E_NOINTERFACE
, "ret %08x\n", r
);
1410 /* Text Last Child Checks */
1411 r
= IXMLDOMText_get_lastChild(nodetext
, NULL
);
1412 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1414 nodeChild
= (IXMLDOMNode
*)0x1;
1415 r
= IXMLDOMText_get_lastChild(nodetext
, &nodeChild
);
1416 ok(r
== S_FALSE
, "ret %08x\n", r
);
1417 ok(nodeChild
== NULL
, "nodeChild not NULL\n");
1419 /* test length property */
1420 r
= IXMLDOMText_get_length(nodetext
, NULL
);
1421 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1423 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1424 ok(r
== S_OK
, "ret %08x\n", r
);
1425 ok(nLength
== 4, "expected 4 got %d\n", nLength
);
1427 /* put data Tests */
1428 r
= IXMLDOMText_put_data(nodetext
, _bstr_("This &is a ; test <>\\"));
1429 ok(r
== S_OK
, "ret %08x\n", r
);
1431 /* get data Tests */
1432 r
= IXMLDOMText_get_data(nodetext
, &str
);
1433 ok(r
== S_OK
, "ret %08x\n", r
);
1434 ok( !lstrcmpW( str
, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1437 /* Confirm XML text is good */
1438 r
= IXMLDOMText_get_xml(nodetext
, &str
);
1439 ok(r
== S_OK
, "ret %08x\n", r
);
1440 ok( !lstrcmpW( str
, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1443 /* Confirm we get the put_data Text back */
1444 r
= IXMLDOMText_get_text(nodetext
, &str
);
1445 ok(r
== S_OK
, "ret %08x\n", r
);
1446 ok( !lstrcmpW( str
, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1449 /* test substringData */
1450 r
= IXMLDOMText_substringData(nodetext
, 0, 4, NULL
);
1451 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1453 /* test substringData - Invalid offset */
1454 str
= (BSTR
)&szElement
;
1455 r
= IXMLDOMText_substringData(nodetext
, -1, 4, &str
);
1456 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1457 ok( str
== NULL
, "incorrect string\n");
1459 /* test substringData - Invalid offset */
1460 str
= (BSTR
)&szElement
;
1461 r
= IXMLDOMText_substringData(nodetext
, 30, 0, &str
);
1462 ok(r
== S_FALSE
, "ret %08x\n", r
);
1463 ok( str
== NULL
, "incorrect string\n");
1465 /* test substringData - Invalid size */
1466 str
= (BSTR
)&szElement
;
1467 r
= IXMLDOMText_substringData(nodetext
, 0, -1, &str
);
1468 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1469 ok( str
== NULL
, "incorrect string\n");
1471 /* test substringData - Invalid size */
1472 str
= (BSTR
)&szElement
;
1473 r
= IXMLDOMText_substringData(nodetext
, 2, 0, &str
);
1474 ok(r
== S_FALSE
, "ret %08x\n", r
);
1475 ok( str
== NULL
, "incorrect string\n");
1477 /* test substringData - Start of string */
1478 r
= IXMLDOMText_substringData(nodetext
, 0, 4, &str
);
1479 ok(r
== S_OK
, "ret %08x\n", r
);
1480 ok( !lstrcmpW( str
, _bstr_("This") ), "incorrect substringData string\n");
1483 /* test substringData - Middle of string */
1484 r
= IXMLDOMText_substringData(nodetext
, 13, 4, &str
);
1485 ok(r
== S_OK
, "ret %08x\n", r
);
1486 ok( !lstrcmpW( str
, _bstr_("test") ), "incorrect substringData string\n");
1489 /* test substringData - End of string */
1490 r
= IXMLDOMText_substringData(nodetext
, 20, 4, &str
);
1491 ok(r
== S_OK
, "ret %08x\n", r
);
1492 ok( !lstrcmpW( str
, _bstr_("\\") ), "incorrect substringData string\n");
1495 /* test appendData */
1496 r
= IXMLDOMText_appendData(nodetext
, NULL
);
1497 ok(r
== S_OK
, "ret %08x\n", r
);
1499 r
= IXMLDOMText_appendData(nodetext
, _bstr_(""));
1500 ok(r
== S_OK
, "ret %08x\n", r
);
1502 r
= IXMLDOMText_appendData(nodetext
, _bstr_("Append"));
1503 ok(r
== S_OK
, "ret %08x\n", r
);
1505 r
= IXMLDOMText_get_text(nodetext
, &str
);
1506 ok(r
== S_OK
, "ret %08x\n", r
);
1507 ok( !lstrcmpW( str
, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1510 /* test insertData */
1511 str
= SysAllocStringLen(NULL
, 0);
1512 r
= IXMLDOMText_insertData(nodetext
, -1, str
);
1513 ok(r
== S_OK
, "ret %08x\n", r
);
1515 r
= IXMLDOMText_insertData(nodetext
, -1, NULL
);
1516 ok(r
== S_OK
, "ret %08x\n", r
);
1518 r
= IXMLDOMText_insertData(nodetext
, 1000, str
);
1519 ok(r
== S_OK
, "ret %08x\n", r
);
1521 r
= IXMLDOMText_insertData(nodetext
, 1000, NULL
);
1522 ok(r
== S_OK
, "ret %08x\n", r
);
1524 r
= IXMLDOMText_insertData(nodetext
, 0, NULL
);
1525 ok(r
== S_OK
, "ret %08x\n", r
);
1527 r
= IXMLDOMText_insertData(nodetext
, 0, str
);
1528 ok(r
== S_OK
, "ret %08x\n", r
);
1531 r
= IXMLDOMText_insertData(nodetext
, -1, _bstr_("Inserting"));
1532 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1534 r
= IXMLDOMText_insertData(nodetext
, 1000, _bstr_("Inserting"));
1535 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1537 r
= IXMLDOMText_insertData(nodetext
, 0, _bstr_("Begin "));
1538 ok(r
== S_OK
, "ret %08x\n", r
);
1540 r
= IXMLDOMText_insertData(nodetext
, 17, _bstr_("Middle"));
1541 ok(r
== S_OK
, "ret %08x\n", r
);
1543 r
= IXMLDOMText_insertData(nodetext
, 39, _bstr_(" End"));
1544 ok(r
== S_OK
, "ret %08x\n", r
);
1546 r
= IXMLDOMText_get_text(nodetext
, &str
);
1547 ok(r
== S_OK
, "ret %08x\n", r
);
1548 ok( !lstrcmpW( str
, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1552 /* invalid arguments */
1553 r
= IXMLDOMText_deleteData(nodetext
, -1, 1);
1554 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1556 r
= IXMLDOMText_deleteData(nodetext
, 0, 0);
1557 ok(r
== S_OK
, "ret %08x\n", r
);
1559 r
= IXMLDOMText_deleteData(nodetext
, 0, -1);
1560 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1562 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1563 ok(r
== S_OK
, "ret %08x\n", r
);
1564 ok(nLength
== 43, "expected 43 got %d\n", nLength
);
1566 r
= IXMLDOMText_deleteData(nodetext
, nLength
, 1);
1567 ok(r
== S_OK
, "ret %08x\n", r
);
1569 r
= IXMLDOMText_deleteData(nodetext
, nLength
+1, 1);
1570 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1572 /* delete from start */
1573 r
= IXMLDOMText_deleteData(nodetext
, 0, 5);
1574 ok(r
== S_OK
, "ret %08x\n", r
);
1576 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1577 ok(r
== S_OK
, "ret %08x\n", r
);
1578 ok(nLength
== 38, "expected 38 got %d\n", nLength
);
1580 r
= IXMLDOMText_get_text(nodetext
, &str
);
1581 ok(r
== S_OK
, "ret %08x\n", r
);
1582 ok( !lstrcmpW( str
, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1585 /* delete from end */
1586 r
= IXMLDOMText_deleteData(nodetext
, 35, 3);
1587 ok(r
== S_OK
, "ret %08x\n", r
);
1589 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1590 ok(r
== S_OK
, "ret %08x\n", r
);
1591 ok(nLength
== 35, "expected 35 got %d\n", nLength
);
1593 r
= IXMLDOMText_get_text(nodetext
, &str
);
1594 ok(r
== S_OK
, "ret %08x\n", r
);
1595 ok( !lstrcmpW( str
, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1598 /* delete from inside */
1599 r
= IXMLDOMText_deleteData(nodetext
, 1, 33);
1600 ok(r
== S_OK
, "ret %08x\n", r
);
1602 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1603 ok(r
== S_OK
, "ret %08x\n", r
);
1604 ok(nLength
== 2, "expected 2 got %d\n", nLength
);
1606 r
= IXMLDOMText_get_text(nodetext
, &str
);
1607 ok(r
== S_OK
, "ret %08x\n", r
);
1608 ok( !lstrcmpW( str
, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1611 /* delete whole data ... */
1612 r
= IXMLDOMText_get_length(nodetext
, &nLength
);
1613 ok(r
== S_OK
, "ret %08x\n", r
);
1615 r
= IXMLDOMText_deleteData(nodetext
, 0, nLength
);
1616 ok(r
== S_OK
, "ret %08x\n", r
);
1617 /* ... and try again with empty string */
1618 r
= IXMLDOMText_deleteData(nodetext
, 0, nLength
);
1619 ok(r
== S_OK
, "ret %08x\n", r
);
1622 V_VT(&var
) = VT_BSTR
;
1623 V_BSTR(&var
) = SysAllocString(szstr1
);
1624 r
= IXMLDOMText_put_nodeValue(nodetext
, var
);
1625 ok(r
== S_OK
, "ret %08x\n", r
);
1628 r
= IXMLDOMText_get_text(nodetext
, &str
);
1629 ok(r
== S_OK
, "ret %08x\n", r
);
1630 ok( !lstrcmpW( str
, szstr1
), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1636 r
= IXMLDOMText_put_nodeValue(nodetext
, var
);
1637 ok(r
== S_OK
, "ret %08x\n", r
);
1640 r
= IXMLDOMText_get_text(nodetext
, &str
);
1641 ok(r
== S_OK
, "ret %08x\n", r
);
1642 ok( !lstrcmpW( str
, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1645 /* ::replaceData() */
1646 V_VT(&var
) = VT_BSTR
;
1647 V_BSTR(&var
) = SysAllocString(szstr1
);
1648 r
= IXMLDOMText_put_nodeValue(nodetext
, var
);
1649 ok(r
== S_OK
, "ret %08x\n", r
);
1652 r
= IXMLDOMText_replaceData(nodetext
, 6, 0, NULL
);
1653 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1654 r
= IXMLDOMText_get_text(nodetext
, &str
);
1655 ok(r
== S_OK
, "ret %08x\n", r
);
1656 ok( !lstrcmpW( str
, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1659 r
= IXMLDOMText_replaceData(nodetext
, 0, 0, NULL
);
1660 ok(r
== S_OK
, "ret %08x\n", r
);
1661 r
= IXMLDOMText_get_text(nodetext
, &str
);
1662 ok(r
== S_OK
, "ret %08x\n", r
);
1663 ok( !lstrcmpW( str
, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1666 /* NULL pointer means delete */
1667 r
= IXMLDOMText_replaceData(nodetext
, 0, 1, NULL
);
1668 ok(r
== S_OK
, "ret %08x\n", r
);
1669 r
= IXMLDOMText_get_text(nodetext
, &str
);
1670 ok(r
== S_OK
, "ret %08x\n", r
);
1671 ok( !lstrcmpW( str
, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1674 /* empty string means delete */
1675 r
= IXMLDOMText_replaceData(nodetext
, 0, 1, _bstr_(""));
1676 ok(r
== S_OK
, "ret %08x\n", r
);
1677 r
= IXMLDOMText_get_text(nodetext
, &str
);
1678 ok(r
== S_OK
, "ret %08x\n", r
);
1679 ok( !lstrcmpW( str
, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1682 /* zero count means insert */
1683 r
= IXMLDOMText_replaceData(nodetext
, 0, 0, _bstr_("a"));
1684 ok(r
== S_OK
, "ret %08x\n", r
);
1685 r
= IXMLDOMText_get_text(nodetext
, &str
);
1686 ok(r
== S_OK
, "ret %08x\n", r
);
1687 ok( !lstrcmpW( str
, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1690 r
= IXMLDOMText_replaceData(nodetext
, 0, 2, NULL
);
1691 ok(r
== S_OK
, "ret %08x\n", r
);
1693 r
= IXMLDOMText_insertData(nodetext
, 0, _bstr_("m"));
1694 ok(r
== S_OK
, "ret %08x\n", r
);
1695 r
= IXMLDOMText_get_text(nodetext
, &str
);
1696 ok(r
== S_OK
, "ret %08x\n", r
);
1697 ok( !lstrcmpW( str
, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1700 /* nonempty string, count greater than its length */
1701 r
= IXMLDOMText_replaceData(nodetext
, 0, 2, _bstr_("a1.2"));
1702 ok(r
== S_OK
, "ret %08x\n", r
);
1703 r
= IXMLDOMText_get_text(nodetext
, &str
);
1704 ok(r
== S_OK
, "ret %08x\n", r
);
1705 ok( !lstrcmpW( str
, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1708 /* nonempty string, count less than its length */
1709 r
= IXMLDOMText_replaceData(nodetext
, 0, 1, _bstr_("wine"));
1710 ok(r
== S_OK
, "ret %08x\n", r
);
1711 r
= IXMLDOMText_get_text(nodetext
, &str
);
1712 ok(r
== S_OK
, "ret %08x\n", r
);
1713 ok( !lstrcmpW( str
, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str
) );
1716 IXMLDOMText_Release( nodetext
);
1719 /* test Create Comment */
1720 r
= IXMLDOMDocument_createComment(doc
, NULL
, NULL
);
1721 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
1722 node_comment
= (IXMLDOMComment
*)0x1;
1725 r
= IXMLDOMDocument_createComment(doc
, _bstr_(""), &node_comment
);
1726 ok( r
== S_OK
, "returns %08x\n", r
);
1728 r
= IXMLDOMComment_get_data(node_comment
, &str
);
1729 ok( r
== S_OK
, "returns %08x\n", r
);
1730 ok( str
&& SysStringLen(str
) == 0, "expected empty string data\n");
1731 IXMLDOMComment_Release(node_comment
);
1734 r
= IXMLDOMDocument_createComment(doc
, NULL
, &node_comment
);
1735 ok( r
== S_OK
, "returns %08x\n", r
);
1737 r
= IXMLDOMComment_get_data(node_comment
, &str
);
1738 ok( r
== S_OK
, "returns %08x\n", r
);
1739 ok( str
&& (SysStringLen(str
) == 0), "expected empty string data\n");
1740 IXMLDOMComment_Release(node_comment
);
1743 str
= SysAllocString(szComment
);
1744 r
= IXMLDOMDocument_createComment(doc
, str
, &node_comment
);
1746 ok( r
== S_OK
, "returns %08x\n", r
);
1749 /* Last Child Checks */
1750 r
= IXMLDOMComment_get_lastChild(node_comment
, NULL
);
1751 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1753 nodeChild
= (IXMLDOMNode
*)0x1;
1754 r
= IXMLDOMComment_get_lastChild(node_comment
, &nodeChild
);
1755 ok(r
== S_FALSE
, "ret %08x\n", r
);
1756 ok(nodeChild
== NULL
, "pLastChild not NULL\n");
1759 str
= (BSTR
)0xdeadbeef;
1760 r
= IXMLDOMComment_get_baseName(node_comment
, &str
);
1761 ok(r
== S_FALSE
, "ret %08x\n", r
);
1762 ok(str
== NULL
, "Expected NULL\n");
1764 IXMLDOMComment_Release( node_comment
);
1767 /* test Create Attribute */
1768 str
= SysAllocString(szAttribute
);
1769 r
= IXMLDOMDocument_createAttribute(doc
, NULL
, NULL
);
1770 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
1771 r
= IXMLDOMDocument_createAttribute(doc
, str
, &node_attr
);
1772 ok( r
== S_OK
, "returns %08x\n", r
);
1773 IXMLDOMAttribute_Release( node_attr
);
1776 /* test Processing Instruction */
1777 str
= SysAllocStringLen(NULL
, 0);
1778 r
= IXMLDOMDocument_createProcessingInstruction(doc
, str
, str
, NULL
);
1779 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
1780 r
= IXMLDOMDocument_createProcessingInstruction(doc
, NULL
, str
, &nodePI
);
1781 ok( r
== E_FAIL
, "returns %08x\n", r
);
1782 r
= IXMLDOMDocument_createProcessingInstruction(doc
, str
, str
, &nodePI
);
1783 ok( r
== E_FAIL
, "returns %08x\n", r
);
1786 r
= IXMLDOMDocument_createProcessingInstruction(doc
, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI
);
1787 ok( r
== S_OK
, "returns %08x\n", r
);
1790 /* Last Child Checks */
1791 r
= IXMLDOMProcessingInstruction_get_lastChild(nodePI
, NULL
);
1792 ok(r
== E_INVALIDARG
, "ret %08x\n", r
);
1794 nodeChild
= (IXMLDOMNode
*)0x1;
1795 r
= IXMLDOMProcessingInstruction_get_lastChild(nodePI
, &nodeChild
);
1796 ok(r
== S_FALSE
, "ret %08x\n", r
);
1797 ok(nodeChild
== NULL
, "nodeChild not NULL\n");
1800 r
= IXMLDOMProcessingInstruction_get_nodeName(nodePI
, &str
);
1801 ok(r
== S_OK
, "ret %08x\n", r
);
1802 ok( !lstrcmpW( str
, _bstr_("xml") ), "incorrect nodeName string\n");
1807 r
= IXMLDOMProcessingInstruction_get_baseName(nodePI
, &str
);
1808 ok(r
== S_OK
, "ret %08x\n", r
);
1809 ok( !lstrcmpW( str
, _bstr_("xml") ), "incorrect nodeName string\n");
1813 r
= IXMLDOMProcessingInstruction_get_target(nodePI
, &str
);
1814 ok(r
== S_OK
, "ret %08x\n", r
);
1815 ok( !lstrcmpW( str
, _bstr_("xml") ), "incorrect target string\n");
1819 r
= IXMLDOMProcessingInstruction_get_data(nodePI
, &str
);
1820 ok(r
== S_OK
, "ret %08x\n", r
);
1821 ok( !lstrcmpW( str
, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1825 r
= IXMLDOMProcessingInstruction_put_data(nodePI
, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
1826 ok(r
== E_FAIL
, "ret %08x\n", r
);
1829 V_VT(&var
) = VT_BSTR
;
1830 V_BSTR(&var
) = SysAllocString(szOpen
); /* Doesn't matter what the string is, cannot set an xml node. */
1831 r
= IXMLDOMProcessingInstruction_put_nodeValue(nodePI
, var
);
1832 ok(r
== E_FAIL
, "ret %08x\n", r
);
1835 /* test get nodeName */
1836 r
= IXMLDOMProcessingInstruction_get_nodeName(nodePI
, &str
);
1837 ok( !lstrcmpW( str
, _bstr_("xml") ), "incorrect nodeName string\n");
1838 ok(r
== S_OK
, "ret %08x\n", r
);
1841 IXMLDOMProcessingInstruction_Release(nodePI
);
1844 ref
= IXMLDOMDocument_Release( doc
);
1845 ok( ref
== 0, "got %d\n", ref
);
1850 static void test_persiststreaminit(void)
1852 IXMLDOMDocument
*doc
;
1853 IPersistStreamInit
*streaminit
;
1854 ULARGE_INTEGER size
;
1857 doc
= create_document(&IID_IXMLDOMDocument
);
1859 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IPersistStreamInit
, (void**)&streaminit
);
1860 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1862 hr
= IPersistStreamInit_InitNew(streaminit
);
1863 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1865 hr
= IPersistStreamInit_GetSizeMax(streaminit
, &size
);
1866 ok(hr
== E_NOTIMPL
, "got 0x%08x\n", hr
);
1868 IXMLDOMDocument_Release(doc
);
1871 static void test_domnode( void )
1874 IXMLDOMDocument
*doc
, *owner
= NULL
;
1875 IXMLDOMElement
*element
= NULL
;
1876 IXMLDOMNamedNodeMap
*map
= NULL
;
1877 IXMLDOMNode
*node
= NULL
, *next
= NULL
;
1878 IXMLDOMNodeList
*list
= NULL
;
1879 IXMLDOMAttribute
*attr
= NULL
;
1880 DOMNodeType type
= NODE_INVALID
;
1886 doc
= create_document(&IID_IXMLDOMDocument
);
1889 r
= IXMLDOMDocument_loadXML( doc
, _bstr_(complete4A
), &b
);
1890 ok( r
== S_OK
, "loadXML failed\n");
1891 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
1893 EXPECT_CHILDREN(doc
);
1895 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
1896 ok( r
== S_OK
, "should be a document element\n");
1897 ok( element
!= NULL
, "should be an element\n");
1900 ok( V_VT(&var
) == VT_EMPTY
, "variant init failed\n");
1902 r
= IXMLDOMDocument_get_nodeValue( doc
, NULL
);
1903 ok(r
== E_INVALIDARG
, "get_nodeValue ret %08x\n", r
);
1905 r
= IXMLDOMDocument_get_nodeValue( doc
, &var
);
1906 ok( r
== S_FALSE
, "nextNode returned wrong code\n");
1907 ok( V_VT(&var
) == VT_NULL
, "variant wasn't empty\n");
1908 ok( V_BSTR(&var
) == NULL
, "variant value wasn't null\n");
1913 r
= IXMLDOMElement_get_ownerDocument( element
, &owner
);
1914 ok( r
== S_OK
, "get_ownerDocument return code\n");
1915 ok( owner
!= doc
, "get_ownerDocument return\n");
1916 IXMLDOMDocument_Release(owner
);
1918 type
= NODE_INVALID
;
1919 r
= IXMLDOMElement_get_nodeType( element
, &type
);
1920 ok( r
== S_OK
, "got %08x\n", r
);
1921 ok( type
== NODE_ELEMENT
, "node not an element\n");
1924 r
= IXMLDOMElement_get_baseName( element
, &str
);
1925 ok( r
== S_OK
, "get_baseName returned wrong code\n");
1926 ok( lstrcmpW(str
,szlc
) == 0, "basename was wrong\n");
1929 /* check if nodename is correct */
1930 r
= IXMLDOMElement_get_nodeName( element
, NULL
);
1931 ok ( r
== E_INVALIDARG
, "get_nodeName (NULL) wrong code\n");
1933 /* content doesn't matter here */
1935 r
= IXMLDOMElement_get_nodeName( element
, &str
);
1936 ok ( r
== S_OK
, "get_nodeName wrong code\n");
1937 ok ( str
!= NULL
, "str is null\n");
1938 ok( !lstrcmpW( str
, szlc
), "incorrect nodeName\n");
1939 SysFreeString( str
);
1941 str
= SysAllocString( nonexistent_fileW
);
1943 V_I4(&var
) = 0x1234;
1944 r
= IXMLDOMElement_getAttribute( element
, str
, &var
);
1945 ok( r
== E_FAIL
, "getAttribute ret %08x\n", r
);
1946 ok( V_VT(&var
) == VT_NULL
|| V_VT(&var
) == VT_EMPTY
, "vt = %x\n", V_VT(&var
));
1950 str
= SysAllocString( szdl
);
1952 V_I4(&var
) = 0x1234;
1953 r
= IXMLDOMElement_getAttribute( element
, str
, &var
);
1954 ok( r
== S_OK
, "getAttribute ret %08x\n", r
);
1955 ok( V_VT(&var
) == VT_BSTR
, "vt = %x\n", V_VT(&var
));
1956 ok( !lstrcmpW(V_BSTR(&var
), szstr1
), "wrong attr value\n");
1957 VariantClear( &var
);
1959 r
= IXMLDOMElement_getAttribute( element
, NULL
, &var
);
1960 ok( r
== E_INVALIDARG
, "getAttribute ret %08x\n", r
);
1962 r
= IXMLDOMElement_getAttribute( element
, str
, NULL
);
1963 ok( r
== E_INVALIDARG
, "getAttribute ret %08x\n", r
);
1966 r
= IXMLDOMElement_getAttributeNode( element
, str
, &attr
);
1967 ok( r
== S_OK
, "GetAttributeNode ret %08x\n", r
);
1968 ok( attr
!= NULL
, "getAttributeNode returned NULL\n" );
1971 r
= IXMLDOMAttribute_get_parentNode( attr
, NULL
);
1972 ok( r
== E_INVALIDARG
, "Expected E_INVALIDARG, ret %08x\n", r
);
1974 /* attribute doesn't have a parent in msxml interpretation */
1975 node
= (IXMLDOMNode
*)0xdeadbeef;
1976 r
= IXMLDOMAttribute_get_parentNode( attr
, &node
);
1977 ok( r
== S_FALSE
, "Expected S_FALSE, ret %08x\n", r
);
1978 ok( node
== NULL
, "Expected NULL, got %p\n", node
);
1980 IXMLDOMAttribute_Release(attr
);
1983 SysFreeString( str
);
1985 r
= IXMLDOMElement_get_attributes( element
, &map
);
1986 ok( r
== S_OK
, "get_attributes returned wrong code\n");
1987 ok( map
!= NULL
, "should be attributes\n");
1989 EXPECT_CHILDREN(element
);
1992 ok( FALSE
, "no element\n");
1996 str
= SysAllocString( szdl
);
1997 r
= IXMLDOMNamedNodeMap_getNamedItem( map
, str
, &node
);
1998 ok( r
== S_OK
, "getNamedItem returned wrong code\n");
1999 ok( node
!= NULL
, "should be attributes\n");
2000 IXMLDOMNode_Release(node
);
2001 SysFreeString( str
);
2003 str
= SysAllocString( szdl
);
2004 r
= IXMLDOMNamedNodeMap_getNamedItem( map
, str
, NULL
);
2005 ok( r
== E_INVALIDARG
, "getNamedItem should return E_INVALIDARG\n");
2006 SysFreeString( str
);
2008 /* something that isn't in complete4A */
2009 str
= SysAllocString( szOpen
);
2010 node
= (IXMLDOMNode
*) 1;
2011 r
= IXMLDOMNamedNodeMap_getNamedItem( map
, str
, &node
);
2012 ok( r
== S_FALSE
, "getNamedItem found a node that wasn't there\n");
2013 ok( node
== NULL
, "getNamedItem should have returned NULL\n");
2014 SysFreeString( str
);
2016 /* test indexed access of attributes */
2017 r
= IXMLDOMNamedNodeMap_get_length( map
, NULL
);
2018 ok ( r
== E_INVALIDARG
, "get_length should return E_INVALIDARG\n");
2020 r
= IXMLDOMNamedNodeMap_get_length( map
, &count
);
2021 ok ( r
== S_OK
, "get_length wrong code\n");
2022 ok ( count
== 1, "get_length != 1\n");
2025 r
= IXMLDOMNamedNodeMap_get_item( map
, -1, &node
);
2026 ok ( r
== S_FALSE
, "get_item (-1) wrong code\n");
2027 ok ( node
== NULL
, "there is no node\n");
2030 r
= IXMLDOMNamedNodeMap_get_item( map
, 1, &node
);
2031 ok ( r
== S_FALSE
, "get_item (1) wrong code\n");
2032 ok ( node
== NULL
, "there is no attribute\n");
2035 r
= IXMLDOMNamedNodeMap_get_item( map
, 0, &node
);
2036 ok ( r
== S_OK
, "get_item (0) wrong code\n");
2037 ok ( node
!= NULL
, "should be attribute\n");
2039 r
= IXMLDOMNode_get_nodeName( node
, NULL
);
2040 ok ( r
== E_INVALIDARG
, "get_nodeName (NULL) wrong code\n");
2042 /* content doesn't matter here */
2044 r
= IXMLDOMNode_get_nodeName( node
, &str
);
2045 ok ( r
== S_OK
, "get_nodeName wrong code\n");
2046 ok ( str
!= NULL
, "str is null\n");
2047 ok( !lstrcmpW( str
, szdl
), "incorrect node name\n");
2048 SysFreeString( str
);
2049 IXMLDOMNode_Release( node
);
2051 /* test sequential access of attributes */
2053 r
= IXMLDOMNamedNodeMap_nextNode( map
, &node
);
2054 ok ( r
== S_OK
, "nextNode (first time) wrong code\n");
2055 ok ( node
!= NULL
, "nextNode, should be attribute\n");
2056 IXMLDOMNode_Release( node
);
2058 r
= IXMLDOMNamedNodeMap_nextNode( map
, &node
);
2059 ok ( r
!= S_OK
, "nextNode (second time) wrong code\n");
2060 ok ( node
== NULL
, "nextNode, there is no attribute\n");
2062 r
= IXMLDOMNamedNodeMap_reset( map
);
2063 ok ( r
== S_OK
, "reset should return S_OK\n");
2065 r
= IXMLDOMNamedNodeMap_nextNode( map
, &node
);
2066 ok ( r
== S_OK
, "nextNode (third time) wrong code\n");
2067 ok ( node
!= NULL
, "nextNode, should be attribute\n");
2070 ok( FALSE
, "no map\n");
2074 type
= NODE_INVALID
;
2075 r
= IXMLDOMNode_get_nodeType( node
, &type
);
2076 ok( r
== S_OK
, "getNamedItem returned wrong code\n");
2077 ok( type
== NODE_ATTRIBUTE
, "node not an attribute\n");
2080 r
= IXMLDOMNode_get_baseName( node
, NULL
);
2081 ok( r
== E_INVALIDARG
, "get_baseName returned wrong code\n");
2084 r
= IXMLDOMNode_get_baseName( node
, &str
);
2085 ok( r
== S_OK
, "get_baseName returned wrong code\n");
2086 ok( lstrcmpW(str
,szdl
) == 0, "basename was wrong\n");
2087 SysFreeString( str
);
2089 r
= IXMLDOMNode_get_childNodes( node
, NULL
);
2090 ok( r
== E_INVALIDARG
, "get_childNodes returned wrong code\n");
2092 r
= IXMLDOMNode_get_childNodes( node
, &list
);
2093 ok( r
== S_OK
, "get_childNodes returned wrong code\n");
2097 r
= IXMLDOMNodeList_nextNode( list
, &next
);
2098 ok( r
== S_OK
, "nextNode returned wrong code\n");
2101 ok( FALSE
, "no childlist\n");
2105 EXPECT_NO_CHILDREN(next
);
2107 type
= NODE_INVALID
;
2108 r
= IXMLDOMNode_get_nodeType( next
, &type
);
2109 ok( r
== S_OK
, "getNamedItem returned wrong code\n");
2110 ok( type
== NODE_TEXT
, "node not text\n");
2113 r
= IXMLDOMNode_get_baseName( next
, &str
);
2114 ok( r
== S_FALSE
, "get_baseName returned wrong code\n");
2115 ok( str
== NULL
, "basename was wrong\n");
2119 ok( FALSE
, "no next\n");
2122 IXMLDOMNode_Release( next
);
2125 IXMLDOMNodeList_Release( list
);
2128 IXMLDOMNode_Release( node
);
2131 ok( FALSE
, "no node\n");
2135 IXMLDOMNamedNodeMap_Release( map
);
2137 /* now traverse the tree from the root element */
2140 r
= IXMLDOMElement_get_childNodes( element
, &list
);
2141 ok( r
== S_OK
, "get_childNodes returned wrong code\n");
2143 /* using get_item for child list doesn't advance the position */
2144 ole_check(IXMLDOMNodeList_get_item(list
, 1, &node
));
2145 expect_node(node
, "E2.E2.D1");
2146 IXMLDOMNode_Release(node
);
2147 ole_check(IXMLDOMNodeList_nextNode(list
, &node
));
2148 expect_node(node
, "E1.E2.D1");
2149 IXMLDOMNode_Release(node
);
2150 ole_check(IXMLDOMNodeList_reset(list
));
2152 IXMLDOMNodeList_AddRef(list
);
2153 expect_list_and_release(list
, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
2154 ole_check(IXMLDOMNodeList_reset(list
));
2156 node
= (void*)0xdeadbeef;
2157 str
= SysAllocString(szdl
);
2158 r
= IXMLDOMElement_selectSingleNode( element
, str
, &node
);
2160 ok( r
== S_FALSE
, "ret %08x\n", r
);
2161 ok( node
== NULL
, "node %p\n", node
);
2163 str
= SysAllocString(szbs
);
2164 r
= IXMLDOMElement_selectSingleNode( element
, str
, &node
);
2166 ok( r
== S_OK
, "ret %08x\n", r
);
2167 r
= IXMLDOMNode_Release( node
);
2168 ok( r
== 0, "ret %08x\n", r
);
2171 ok( FALSE
, "no element\n");
2175 r
= IXMLDOMNodeList_get_item(list
, 0, NULL
);
2176 ok(r
== E_INVALIDARG
, "Expected E_INVALIDARG got %08x\n", r
);
2178 r
= IXMLDOMNodeList_get_length(list
, NULL
);
2179 ok(r
== E_INVALIDARG
, "Expected E_INVALIDARG got %08x\n", r
);
2181 r
= IXMLDOMNodeList_get_length( list
, &count
);
2182 ok( r
== S_OK
, "get_length returns %08x\n", r
);
2183 ok( count
== 4, "get_length got %d\n", count
);
2185 r
= IXMLDOMNodeList_nextNode(list
, NULL
);
2186 ok(r
== E_INVALIDARG
, "Expected E_INVALIDARG got %08x\n", r
);
2188 r
= IXMLDOMNodeList_nextNode( list
, &node
);
2189 ok( r
== S_OK
, "nextNode returned wrong code\n");
2192 ok( FALSE
, "no list\n");
2196 type
= NODE_INVALID
;
2197 r
= IXMLDOMNode_get_nodeType( node
, &type
);
2198 ok( r
== S_OK
, "getNamedItem returned wrong code\n");
2199 ok( type
== NODE_ELEMENT
, "node not text\n");
2201 r
= IXMLDOMNode_hasChildNodes( node
, NULL
);
2202 ok( r
== E_INVALIDARG
, "hasChildNodes bad return\n");
2204 EXPECT_CHILDREN(node
);
2207 r
= IXMLDOMNode_get_baseName( node
, &str
);
2208 ok( r
== S_OK
, "get_baseName returned wrong code\n");
2209 ok( lstrcmpW(str
,szbs
) == 0, "basename was wrong\n");
2213 ok( FALSE
, "no node\n");
2216 IXMLDOMNode_Release( node
);
2218 IXMLDOMNodeList_Release( list
);
2220 IXMLDOMElement_Release( element
);
2223 str
= SysAllocString( szComplete5
);
2224 r
= IXMLDOMDocument_loadXML( doc
, str
, &b
);
2225 ok( r
== S_OK
, "loadXML failed\n");
2226 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
2227 SysFreeString( str
);
2229 EXPECT_CHILDREN(doc
);
2231 r
= IXMLDOMDocument_get_documentElement( doc
, &element
);
2232 ok( r
== S_OK
, "should be a document element\n");
2233 ok( element
!= NULL
, "should be an element\n");
2237 static const WCHAR szSSearch
[] = {'S',':','s','e','a','r','c','h',0};
2240 /* check if the tag is correct */
2241 r
= IXMLDOMElement_get_tagName( element
, &tag
);
2242 ok( r
== S_OK
, "couldn't get tag name\n");
2243 ok( tag
!= NULL
, "tag was null\n");
2244 ok( !lstrcmpW( tag
, szSSearch
), "incorrect tag name\n");
2245 SysFreeString( tag
);
2247 IXMLDOMElement_Release( element
);
2249 ok(IXMLDOMDocument_Release( doc
) == 0, "document is not destroyed\n");
2259 static const refcount_test_t refcount_test
[] = {
2260 { NODE_ELEMENT
, &IID_IXMLDOMElement
},
2261 { NODE_ATTRIBUTE
, &IID_IXMLDOMAttribute
},
2262 { NODE_TEXT
, &IID_IXMLDOMText
},
2263 { NODE_CDATA_SECTION
, &IID_IXMLDOMCDATASection
},
2264 { NODE_ENTITY_REFERENCE
, &IID_IXMLDOMEntityReference
},
2265 { NODE_PROCESSING_INSTRUCTION
, &IID_IXMLDOMProcessingInstruction
},
2266 { NODE_COMMENT
, &IID_IXMLDOMComment
},
2267 { NODE_DOCUMENT_FRAGMENT
, &IID_IXMLDOMDocumentFragment
},
2268 { NODE_INVALID
, &IID_NULL
}
2271 static void test_refs(void)
2273 IXMLDOMImplementation
*impl
, *impl2
;
2274 IXMLDOMElement
*element
, *elem2
;
2275 IXMLDOMNodeList
*node_list
= NULL
;
2276 IXMLDOMNode
*node
, *node2
, *node3
;
2277 const refcount_test_t
*ptr
;
2278 IXMLDOMDocument
*doc
;
2279 IUnknown
*unk
, *unk2
;
2284 doc
= create_document(&IID_IXMLDOMDocument
);
2286 ptr
= refcount_test
;
2287 while (ptr
->type
!= NODE_INVALID
)
2289 IUnknown
*node_typed
, *node_typed2
;
2290 IDispatchEx
*dispex
, *dispex2
;
2291 IDispatch
*disp
, *disp2
;
2294 V_VT(&type
) = VT_I1
;
2295 V_I1(&type
) = ptr
->type
;
2298 hr
= IXMLDOMDocument_createNode(doc
, type
, _bstr_("name"), NULL
, &node
);
2299 EXPECT_HR(hr
, S_OK
);
2301 EXPECT_REF(node
, 1);
2303 /* try IDispatch and IUnknown from IXMLDOMNode */
2304 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IUnknown
, (void**)&unk
);
2305 EXPECT_HR(hr
, S_OK
);
2308 EXPECT_REF(node
, 1);
2309 ok(unk
!= (IUnknown
*)node
, "%d: got %p and %p\n", ptr
->type
, unk
, node
);
2312 hr
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&disp
);
2313 EXPECT_HR(hr
, S_OK
);
2314 todo_wine
ok(unk
!= (IUnknown
*)disp
, "%d: got %p and %p\n", ptr
->type
, unk
, disp
);
2316 todo_wine
EXPECT_REF(disp
, 1);
2319 hr
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&disp2
);
2320 EXPECT_HR(hr
, S_OK
);
2321 todo_wine
ok(disp
!= disp2
, "%d: got %p and %p\n", ptr
->type
, disp
, disp2
);
2323 todo_wine
EXPECT_REF(disp2
, 1);
2325 IDispatch_Release(disp
);
2326 IDispatch_Release(disp2
);
2328 /* get IXMLDOMNode from this IUnknown */
2330 hr
= IUnknown_QueryInterface(unk
, &IID_IXMLDOMNode
, (void**)&node2
);
2331 EXPECT_HR(hr
, S_OK
);
2332 todo_wine
ok(unk
!= (IUnknown
*)node2
, "%d: got %p and %p\n", ptr
->type
, unk
, node2
);
2334 todo_wine
EXPECT_REF(node2
, 1);
2337 hr
= IUnknown_QueryInterface(unk
, &IID_IXMLDOMNode
, (void**)&node3
);
2338 EXPECT_HR(hr
, S_OK
);
2339 todo_wine
ok(node2
!= node3
, "%d: got %p and %p\n", ptr
->type
, node2
, node3
);
2341 todo_wine
EXPECT_REF(node3
, 1);
2343 IXMLDOMNode_Release(node2
);
2344 IXMLDOMNode_Release(node3
);
2346 /* try IDispatchEx from IUnknown */
2348 hr
= IUnknown_QueryInterface(unk
, &IID_IDispatchEx
, (void**)&dispex
);
2349 EXPECT_HR(hr
, S_OK
);
2350 ok(unk
!= (IUnknown
*)dispex
, "%d: got %p and %p\n", ptr
->type
, unk
, dispex
);
2352 todo_wine
EXPECT_REF(dispex
, 1);
2355 hr
= IUnknown_QueryInterface(unk
, &IID_IDispatchEx
, (void**)&dispex2
);
2356 EXPECT_HR(hr
, S_OK
);
2357 todo_wine
ok(dispex
!= dispex2
, "%d: got %p and %p\n", ptr
->type
, dispex
, dispex2
);
2359 todo_wine
EXPECT_REF(dispex2
, 1);
2361 IDispatchEx_Release(dispex
);
2362 IDispatchEx_Release(dispex2
);
2364 /* try corresponding IXMLDOM* */
2366 hr
= IUnknown_QueryInterface(unk
, ptr
->iid
, (void**)&node_typed
);
2367 EXPECT_HR(hr
, S_OK
);
2369 hr
= IUnknown_QueryInterface(unk
, ptr
->iid
, (void**)&node_typed2
);
2370 EXPECT_HR(hr
, S_OK
);
2372 todo_wine
ok(node_typed
!= node_typed2
, "%d: got %p and %p\n", ptr
->type
, node_typed
, node_typed2
);
2373 IUnknown_Release(node_typed
);
2374 IUnknown_Release(node_typed2
);
2376 /* try invalid IXMLDOM* */
2377 hr
= IUnknown_QueryInterface(unk
, (ptr
+1)->iid
, (void**)&node_typed
);
2378 EXPECT_HR(hr
, E_NOINTERFACE
);
2380 IUnknown_Release(unk
);
2382 EXPECT_REF(node
, 1);
2383 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMNode
, (void**)&node2
);
2384 EXPECT_HR(hr
, S_OK
);
2385 EXPECT_REF(node
, 2);
2386 ok(node
== node2
, "%d: got %p and %p\n", ptr
->type
, node
, node2
);
2388 EXPECT_REF(node
, 2);
2389 hr
= IXMLDOMNode_QueryInterface(node
, ptr
->iid
, (void**)&node_typed
);
2390 EXPECT_HR(hr
, S_OK
);
2391 EXPECT_REF(node
, 3);
2393 EXPECT_REF(node_typed
, 2);
2394 ok((IUnknown
*)node
!= node_typed
, "%d: got %p and %p\n", ptr
->type
, node
, node_typed
);
2396 IUnknown_Release(node_typed
);
2398 IXMLDOMNode_Release(node2
);
2399 IXMLDOMNode_Release(node
);
2405 ref
= IXMLDOMDocument_Release(doc
);
2406 ok( ref
== 0, "ref %d\n", ref
);
2408 /* check IUnknown after releasing DOM iface */
2409 doc
= create_document(&IID_IXMLDOMDocument
);
2411 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IUnknown
, (void**)&unk
);
2412 EXPECT_HR(hr
, S_OK
);
2417 IXMLDOMDocument_Release(doc
);
2419 IUnknown_Release(unk
);
2421 doc
= create_document(&IID_IXMLDOMDocument
);
2424 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IUnknown
, (void**)&unk
);
2425 EXPECT_HR(hr
, S_OK
);
2430 IUnknown_Release(unk
);
2432 /* IXMLDOMImplementation */
2434 hr
= IXMLDOMDocument_get_implementation(doc
, &impl
);
2435 EXPECT_HR(hr
, S_OK
);
2437 EXPECT_REF(impl
, 1);
2438 hr
= IXMLDOMDocument_get_implementation(doc
, &impl2
);
2439 EXPECT_HR(hr
, S_OK
);
2441 EXPECT_REF(impl2
, 1);
2442 ok(impl
!= impl2
, "got %p, %p\n", impl
, impl2
);
2443 IXMLDOMImplementation_Release(impl
);
2444 IXMLDOMImplementation_Release(impl2
);
2446 hr
= IXMLDOMDocument_loadXML( doc
, _bstr_(complete4A
), &b
);
2447 EXPECT_HR(hr
, S_OK
);
2448 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
2451 IXMLDOMDocument_AddRef( doc
);
2453 IXMLDOMDocument_AddRef( doc
);
2456 IXMLDOMDocument_Release( doc
);
2457 IXMLDOMDocument_Release( doc
);
2460 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IUnknown
, (void**)&unk
);
2461 EXPECT_HR(hr
, S_OK
);
2466 hr
= IXMLDOMDocument_get_documentElement(doc
, &element
);
2467 EXPECT_HR(hr
, S_OK
);
2470 EXPECT_REF(element
, 2);
2472 hr
= IXMLDOMDocument_get_documentElement(doc
, &elem2
);
2473 EXPECT_HR(hr
, S_OK
);
2477 EXPECT_REF(element
, 2);
2478 EXPECT_REF(elem2
, 2);
2480 IXMLDOMElement_AddRef(element
);
2481 todo_wine
EXPECT_REF(element
, 3);
2482 IXMLDOMElement_Release(element
);
2484 /* get IUnknown from a node doesn't touch node instance refcount */
2485 hr
= IXMLDOMElement_QueryInterface(element
, &IID_IUnknown
, (void**)&unk
);
2486 EXPECT_HR(hr
, S_OK
);
2487 EXPECT_REF(element
, 2);
2490 EXPECT_REF(elem2
, 2);
2492 hr
= IXMLDOMElement_QueryInterface(elem2
, &IID_IUnknown
, (void**)&unk2
);
2493 EXPECT_HR(hr
, S_OK
);
2496 EXPECT_REF(unk2
, 5);
2498 EXPECT_REF(element
, 2);
2499 EXPECT_REF(elem2
, 2);
2501 todo_wine
ok(unk
== unk2
, "got %p and %p\n", unk
, unk2
);
2502 IUnknown_Release(unk
);
2504 /* IUnknown refcount is not affected by node refcount */
2505 todo_wine
EXPECT_REF(unk2
, 4);
2506 IXMLDOMElement_AddRef(elem2
);
2507 todo_wine
EXPECT_REF(unk2
, 4);
2508 IXMLDOMElement_Release(elem2
);
2510 IXMLDOMElement_Release(elem2
);
2511 todo_wine
EXPECT_REF(unk2
, 3);
2513 IUnknown_Release(unk2
);
2515 hr
= IXMLDOMElement_get_childNodes( element
, &node_list
);
2516 EXPECT_HR(hr
, S_OK
);
2518 todo_wine
EXPECT_REF(element
, 2);
2519 EXPECT_REF(node_list
, 1);
2521 hr
= IXMLDOMNodeList_get_item( node_list
, 0, &node
);
2522 EXPECT_HR(hr
, S_OK
);
2523 EXPECT_REF(node_list
, 1);
2524 EXPECT_REF(node
, 1);
2526 hr
= IXMLDOMNodeList_get_item( node_list
, 0, &node2
);
2527 EXPECT_HR(hr
, S_OK
);
2528 EXPECT_REF(node_list
, 1);
2529 EXPECT_REF(node2
, 1);
2531 ref
= IXMLDOMNode_Release( node
);
2532 ok( ref
== 0, "ref %d\n", ref
);
2533 ref
= IXMLDOMNode_Release( node2
);
2534 ok( ref
== 0, "ref %d\n", ref
);
2536 ref
= IXMLDOMNodeList_Release( node_list
);
2537 ok( ref
== 0, "ref %d\n", ref
);
2539 ok( node
!= node2
, "node %p node2 %p\n", node
, node2
);
2541 ref
= IXMLDOMDocument_Release( doc
);
2542 todo_wine
ok( ref
== 0, "ref %d\n", ref
);
2544 todo_wine
EXPECT_REF(element
, 2);
2546 /* IUnknown must be unique however we obtain it */
2547 hr
= IXMLDOMElement_QueryInterface(element
, &IID_IUnknown
, (void**)&unk
);
2548 EXPECT_HR(hr
, S_OK
);
2549 EXPECT_REF(element
, 2);
2550 hr
= IXMLDOMElement_QueryInterface(element
, &IID_IXMLDOMNode
, (void**)&node
);
2551 EXPECT_HR(hr
, S_OK
);
2552 todo_wine
EXPECT_REF(element
, 2);
2553 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IUnknown
, (void**)&unk2
);
2554 EXPECT_HR(hr
, S_OK
);
2555 todo_wine
EXPECT_REF(element
, 2);
2556 ok(unk
== unk2
, "unk %p unk2 %p\n", unk
, unk2
);
2557 todo_wine
ok(element
!= (void*)node
, "node %p element %p\n", node
, element
);
2559 IUnknown_Release( unk2
);
2560 IUnknown_Release( unk
);
2561 IXMLDOMNode_Release( node
);
2562 todo_wine
EXPECT_REF(element
, 2);
2564 IXMLDOMElement_Release( element
);
2569 static void test_create(void)
2571 static const WCHAR szOne
[] = {'1',0};
2572 static const WCHAR szOneGarbage
[] = {'1','G','a','r','b','a','g','e',0};
2576 IXMLDOMDocument
*doc
;
2577 IXMLDOMElement
*element
;
2578 IXMLDOMComment
*comment
;
2580 IXMLDOMCDATASection
*cdata
;
2581 IXMLDOMNode
*root
, *node
, *child
;
2582 IXMLDOMNamedNodeMap
*attr_map
;
2587 doc
= create_document(&IID_IXMLDOMDocument
);
2591 /* types not supported for creation */
2593 V_I1(&var
) = NODE_DOCUMENT
;
2594 node
= (IXMLDOMNode
*)0x1;
2595 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2596 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2597 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2600 V_I1(&var
) = NODE_DOCUMENT_TYPE
;
2601 node
= (IXMLDOMNode
*)0x1;
2602 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2603 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2604 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2607 V_I1(&var
) = NODE_ENTITY
;
2608 node
= (IXMLDOMNode
*)0x1;
2609 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2610 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2611 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2614 V_I1(&var
) = NODE_NOTATION
;
2615 node
= (IXMLDOMNode
*)0x1;
2616 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2617 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2618 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2622 V_I1(&var
) = NODE_COMMENT
;
2624 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2625 ok( r
== S_OK
, "returns %08x\n", r
);
2626 ok( node
!= NULL
, "\n");
2628 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)&comment
);
2629 ok( r
== S_OK
, "returns %08x\n", r
);
2630 IXMLDOMNode_Release(node
);
2633 r
= IXMLDOMComment_get_data(comment
, &str
);
2634 ok( r
== S_OK
, "returns %08x\n", r
);
2635 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2636 IXMLDOMComment_Release(comment
);
2639 node
= (IXMLDOMNode
*)0x1;
2640 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2641 ok( r
== S_OK
, "returns %08x\n", r
);
2643 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)&comment
);
2644 ok( r
== S_OK
, "returns %08x\n", r
);
2645 IXMLDOMNode_Release(node
);
2648 r
= IXMLDOMComment_get_data(comment
, &str
);
2649 ok( r
== S_OK
, "returns %08x\n", r
);
2650 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2651 IXMLDOMComment_Release(comment
);
2654 node
= (IXMLDOMNode
*)0x1;
2655 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_("blah"), NULL
, &node
);
2656 ok( r
== S_OK
, "returns %08x\n", r
);
2658 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)&comment
);
2659 ok( r
== S_OK
, "returns %08x\n", r
);
2660 IXMLDOMNode_Release(node
);
2663 r
= IXMLDOMComment_get_data(comment
, &str
);
2664 ok( r
== S_OK
, "returns %08x\n", r
);
2665 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2666 IXMLDOMComment_Release(comment
);
2671 V_I1(&var
) = NODE_TEXT
;
2673 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2674 ok( r
== S_OK
, "returns %08x\n", r
);
2675 ok( node
!= NULL
, "\n");
2677 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)&text
);
2678 ok( r
== S_OK
, "returns %08x\n", r
);
2679 IXMLDOMNode_Release(node
);
2682 r
= IXMLDOMText_get_data(text
, &str
);
2683 ok( r
== S_OK
, "returns %08x\n", r
);
2684 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2685 IXMLDOMText_Release(text
);
2688 node
= (IXMLDOMNode
*)0x1;
2689 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2690 ok( r
== S_OK
, "returns %08x\n", r
);
2692 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)&text
);
2693 ok( r
== S_OK
, "returns %08x\n", r
);
2694 IXMLDOMNode_Release(node
);
2697 r
= IXMLDOMText_get_data(text
, &str
);
2698 ok( r
== S_OK
, "returns %08x\n", r
);
2699 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2700 IXMLDOMText_Release(text
);
2703 node
= (IXMLDOMNode
*)0x1;
2704 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_("blah"), NULL
, &node
);
2705 ok( r
== S_OK
, "returns %08x\n", r
);
2707 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)&text
);
2708 ok( r
== S_OK
, "returns %08x\n", r
);
2709 IXMLDOMNode_Release(node
);
2712 r
= IXMLDOMText_get_data(text
, &str
);
2713 ok( r
== S_OK
, "returns %08x\n", r
);
2714 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2715 IXMLDOMText_Release(text
);
2718 /* NODE_CDATA_SECTION */
2720 V_I1(&var
) = NODE_CDATA_SECTION
;
2722 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2723 ok( r
== S_OK
, "returns %08x\n", r
);
2724 ok( node
!= NULL
, "\n");
2726 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)&cdata
);
2727 ok( r
== S_OK
, "returns %08x\n", r
);
2728 IXMLDOMNode_Release(node
);
2731 r
= IXMLDOMCDATASection_get_data(cdata
, &str
);
2732 ok( r
== S_OK
, "returns %08x\n", r
);
2733 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2734 IXMLDOMCDATASection_Release(cdata
);
2737 node
= (IXMLDOMNode
*)0x1;
2738 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2739 ok( r
== S_OK
, "returns %08x\n", r
);
2741 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)&cdata
);
2742 ok( r
== S_OK
, "returns %08x\n", r
);
2743 IXMLDOMNode_Release(node
);
2746 r
= IXMLDOMCDATASection_get_data(cdata
, &str
);
2747 ok( r
== S_OK
, "returns %08x\n", r
);
2748 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2749 IXMLDOMCDATASection_Release(cdata
);
2752 node
= (IXMLDOMNode
*)0x1;
2753 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_("blah"), NULL
, &node
);
2754 ok( r
== S_OK
, "returns %08x\n", r
);
2756 r
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)&cdata
);
2757 ok( r
== S_OK
, "returns %08x\n", r
);
2758 IXMLDOMNode_Release(node
);
2761 r
= IXMLDOMCDATASection_get_data(cdata
, &str
);
2762 ok( r
== S_OK
, "returns %08x\n", r
);
2763 ok( str
&& SysStringLen(str
) == 0, "expected empty comment, %p\n", str
);
2764 IXMLDOMCDATASection_Release(cdata
);
2767 /* NODE_ATTRIBUTE */
2769 V_I1(&var
) = NODE_ATTRIBUTE
;
2770 node
= (IXMLDOMNode
*)0x1;
2771 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2772 ok( r
== E_FAIL
, "returns %08x\n", r
);
2773 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2776 V_I1(&var
) = NODE_ATTRIBUTE
;
2777 node
= (IXMLDOMNode
*)0x1;
2778 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2779 ok( r
== E_FAIL
, "returns %08x\n", r
);
2780 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2783 V_I1(&var
) = NODE_ATTRIBUTE
;
2784 str
= SysAllocString( szlc
);
2785 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2786 ok( r
== S_OK
, "returns %08x\n", r
);
2787 if( SUCCEEDED(r
) ) IXMLDOMNode_Release( node
);
2790 /* a name is required for attribute, try a BSTR with first null wchar */
2792 V_I1(&var
) = NODE_ATTRIBUTE
;
2793 str
= SysAllocString( szstr1
);
2795 node
= (IXMLDOMNode
*)0x1;
2796 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2797 ok( r
== E_FAIL
, "returns %08x\n", r
);
2798 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2801 /* NODE_PROCESSING_INSTRUCTION */
2803 V_I1(&var
) = NODE_PROCESSING_INSTRUCTION
;
2804 node
= (IXMLDOMNode
*)0x1;
2805 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2806 ok( r
== E_FAIL
, "returns %08x\n", r
);
2807 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2810 V_I1(&var
) = NODE_PROCESSING_INSTRUCTION
;
2811 node
= (IXMLDOMNode
*)0x1;
2812 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2813 ok( r
== E_FAIL
, "returns %08x\n", r
);
2814 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2817 V_I1(&var
) = NODE_PROCESSING_INSTRUCTION
;
2818 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_("pi"), NULL
, NULL
);
2819 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2821 /* NODE_ENTITY_REFERENCE */
2823 V_I1(&var
) = NODE_ENTITY_REFERENCE
;
2824 node
= (IXMLDOMNode
*)0x1;
2825 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2826 ok( r
== E_FAIL
, "returns %08x\n", r
);
2827 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2830 V_I1(&var
) = NODE_ENTITY_REFERENCE
;
2831 node
= (IXMLDOMNode
*)0x1;
2832 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2833 ok( r
== E_FAIL
, "returns %08x\n", r
);
2834 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2838 V_I1(&var
) = NODE_ELEMENT
;
2839 node
= (IXMLDOMNode
*)0x1;
2840 r
= IXMLDOMDocument_createNode( doc
, var
, NULL
, NULL
, &node
);
2841 ok( r
== E_FAIL
, "returns %08x\n", r
);
2842 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2845 V_I1(&var
) = NODE_ELEMENT
;
2846 node
= (IXMLDOMNode
*)0x1;
2847 r
= IXMLDOMDocument_createNode( doc
, var
, _bstr_(""), NULL
, &node
);
2848 ok( r
== E_FAIL
, "returns %08x\n", r
);
2849 ok( node
== (void*)0x1, "expected same ptr, got %p\n", node
);
2852 V_I1(&var
) = NODE_ELEMENT
;
2853 str
= SysAllocString( szlc
);
2854 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2855 ok( r
== S_OK
, "returns %08x\n", r
);
2856 if( SUCCEEDED(r
) ) IXMLDOMNode_Release( node
);
2859 V_I1(&var
) = NODE_ELEMENT
;
2860 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, NULL
);
2861 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2864 V_R4(&var
) = NODE_ELEMENT
;
2865 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2866 ok( r
== S_OK
, "returns %08x\n", r
);
2867 if( SUCCEEDED(r
) ) IXMLDOMNode_Release( node
);
2869 V_VT(&var
) = VT_BSTR
;
2870 V_BSTR(&var
) = SysAllocString( szOne
);
2871 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2872 ok( r
== S_OK
, "returns %08x\n", r
);
2873 if( SUCCEEDED(r
) ) IXMLDOMNode_Release( node
);
2876 V_VT(&var
) = VT_BSTR
;
2877 V_BSTR(&var
) = SysAllocString( szOneGarbage
);
2878 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2879 ok( r
== E_INVALIDARG
, "returns %08x\n", r
);
2880 if( SUCCEEDED(r
) ) IXMLDOMNode_Release( node
);
2884 V_I4(&var
) = NODE_ELEMENT
;
2885 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2886 ok( r
== S_OK
, "returns %08x\n", r
);
2889 r
= IXMLDOMDocument_appendChild( doc
, node
, &root
);
2890 ok( r
== S_OK
, "returns %08x\n", r
);
2891 ok( node
== root
, "%p %p\n", node
, root
);
2894 EXPECT_REF(node
, 2);
2896 ref
= IXMLDOMNode_Release( node
);
2897 ok(ref
== 1, "ref %d\n", ref
);
2898 SysFreeString( str
);
2901 V_I4(&var
) = NODE_ELEMENT
;
2902 str
= SysAllocString( szbs
);
2903 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
2904 ok( r
== S_OK
, "returns %08x\n", r
);
2905 SysFreeString( str
);
2907 EXPECT_REF(node
, 1);
2909 r
= IXMLDOMNode_QueryInterface( node
, &IID_IUnknown
, (void**)&unk
);
2910 ok( r
== S_OK
, "returns %08x\n", r
);
2914 V_VT(&var
) = VT_EMPTY
;
2916 r
= IXMLDOMNode_insertBefore( root
, (IXMLDOMNode
*)unk
, var
, &child
);
2917 ok( r
== S_OK
, "returns %08x\n", r
);
2918 ok( unk
== (IUnknown
*)child
, "%p %p\n", unk
, child
);
2920 todo_wine
EXPECT_REF(unk
, 4);
2922 IXMLDOMNode_Release( child
);
2923 IUnknown_Release( unk
);
2925 V_VT(&var
) = VT_NULL
;
2926 V_DISPATCH(&var
) = (IDispatch
*)node
;
2927 r
= IXMLDOMNode_insertBefore( root
, node
, var
, &child
);
2928 ok( r
== S_OK
, "returns %08x\n", r
);
2929 ok( node
== child
, "%p %p\n", node
, child
);
2930 IXMLDOMNode_Release( child
);
2932 V_VT(&var
) = VT_NULL
;
2933 V_DISPATCH(&var
) = (IDispatch
*)node
;
2934 r
= IXMLDOMNode_insertBefore( root
, node
, var
, NULL
);
2935 ok( r
== S_OK
, "returns %08x\n", r
);
2936 IXMLDOMNode_Release( node
);
2938 r
= IXMLDOMNode_QueryInterface( root
, &IID_IXMLDOMElement
, (void**)&element
);
2939 ok( r
== S_OK
, "returns %08x\n", r
);
2941 r
= IXMLDOMElement_get_attributes( element
, &attr_map
);
2942 ok( r
== S_OK
, "returns %08x\n", r
);
2943 r
= IXMLDOMNamedNodeMap_get_length( attr_map
, &num
);
2944 ok( r
== S_OK
, "returns %08x\n", r
);
2945 ok( num
== 0, "num %d\n", num
);
2946 IXMLDOMNamedNodeMap_Release( attr_map
);
2948 V_VT(&var
) = VT_BSTR
;
2949 V_BSTR(&var
) = SysAllocString( szstr1
);
2950 name
= SysAllocString( szdl
);
2951 r
= IXMLDOMElement_setAttribute( element
, name
, var
);
2952 ok( r
== S_OK
, "returns %08x\n", r
);
2953 r
= IXMLDOMElement_get_attributes( element
, &attr_map
);
2954 ok( r
== S_OK
, "returns %08x\n", r
);
2955 r
= IXMLDOMNamedNodeMap_get_length( attr_map
, &num
);
2956 ok( r
== S_OK
, "returns %08x\n", r
);
2957 ok( num
== 1, "num %d\n", num
);
2958 IXMLDOMNamedNodeMap_Release( attr_map
);
2961 V_VT(&var
) = VT_BSTR
;
2962 V_BSTR(&var
) = SysAllocString( szstr2
);
2963 r
= IXMLDOMElement_setAttribute( element
, name
, var
);
2964 ok( r
== S_OK
, "returns %08x\n", r
);
2965 r
= IXMLDOMElement_get_attributes( element
, &attr_map
);
2966 ok( r
== S_OK
, "returns %08x\n", r
);
2967 r
= IXMLDOMNamedNodeMap_get_length( attr_map
, &num
);
2968 ok( r
== S_OK
, "returns %08x\n", r
);
2969 ok( num
== 1, "num %d\n", num
);
2970 IXMLDOMNamedNodeMap_Release( attr_map
);
2972 r
= IXMLDOMElement_getAttribute( element
, name
, &var
);
2973 ok( r
== S_OK
, "returns %08x\n", r
);
2974 ok( !lstrcmpW(V_BSTR(&var
), szstr2
), "wrong attr value\n");
2976 SysFreeString(name
);
2978 V_VT(&var
) = VT_BSTR
;
2979 V_BSTR(&var
) = SysAllocString( szstr1
);
2980 name
= SysAllocString( szlc
);
2981 r
= IXMLDOMElement_setAttribute( element
, name
, var
);
2982 ok( r
== S_OK
, "returns %08x\n", r
);
2983 r
= IXMLDOMElement_get_attributes( element
, &attr_map
);
2984 ok( r
== S_OK
, "returns %08x\n", r
);
2985 r
= IXMLDOMNamedNodeMap_get_length( attr_map
, &num
);
2986 ok( r
== S_OK
, "returns %08x\n", r
);
2987 ok( num
== 2, "num %d\n", num
);
2988 IXMLDOMNamedNodeMap_Release( attr_map
);
2990 SysFreeString(name
);
2994 name
= SysAllocString( szbs
);
2995 r
= IXMLDOMElement_setAttribute( element
, name
, var
);
2996 ok( r
== S_OK
, "returns %08x\n", r
);
2998 r
= IXMLDOMElement_getAttribute( element
, name
, &var
);
2999 ok( r
== S_OK
, "returns %08x\n", r
);
3000 ok( V_VT(&var
) == VT_BSTR
, "variant type %x\n", V_VT(&var
));
3002 SysFreeString(name
);
3004 /* Create an Attribute */
3006 V_I4(&var
) = NODE_ATTRIBUTE
;
3007 str
= SysAllocString( szAttribute
);
3008 r
= IXMLDOMDocument_createNode( doc
, var
, str
, NULL
, &node
);
3009 ok( r
== S_OK
, "returns %08x\n", r
);
3010 ok( node
!= NULL
, "node was null\n");
3013 IXMLDOMElement_Release( element
);
3014 IXMLDOMNode_Release( root
);
3015 IXMLDOMDocument_Release( doc
);
3018 struct queryresult_t
{
3024 static const struct queryresult_t elementsbytagname
[] = {
3025 { "", "P1.D1 E2.D1 E1.E2.D1 T1.E1.E2.D1 E2.E2.D1 T1.E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1 T1.E1.E4.E2.D1", 10 },
3026 { "*", "E2.D1 E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1", 6 },
3027 { "bs", "E1.E2.D1", 1 },
3033 static void test_getElementsByTagName(void)
3035 const struct queryresult_t
*ptr
= elementsbytagname
;
3036 IXMLDOMNodeList
*node_list
;
3037 IXMLDOMDocument
*doc
;
3038 IXMLDOMElement
*elem
;
3045 doc
= create_document(&IID_IXMLDOMDocument
);
3047 r
= IXMLDOMDocument_loadXML( doc
, _bstr_(complete4A
), &b
);
3048 ok( r
== S_OK
, "loadXML failed\n");
3049 ok( b
== VARIANT_TRUE
, "failed to load XML string\n");
3051 /* null arguments cases */
3052 r
= IXMLDOMDocument_getElementsByTagName(doc
, NULL
, &node_list
);
3053 ok( r
== E_INVALIDARG
, "ret %08x\n", r
);
3054 r
= IXMLDOMDocument_getElementsByTagName(doc
, _bstr_("*"), NULL
);
3055 ok( r
== E_INVALIDARG
, "ret %08x\n", r
);
3059 r
= IXMLDOMDocument_getElementsByTagName(doc
, _bstr_(ptr
->query
), &node_list
);
3060 ok(r
== S_OK
, "ret %08x\n", r
);
3061 r
= IXMLDOMNodeList_get_length(node