4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2007-2008 Alistair Leslie-Hughes
6 * Copyright 2010 Adam Martinson for CodeWeavers
7 * Copyright 2010-2011 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
31 #include "msxml2did.h"
36 #include "wine/test.h"
40 DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f,0x20, 0x00,0x80,0x5f,0x2c,0xd0,0x64);
42 static int g_unexpectedcall, g_expectedcall;
46 const struct IDispatchVtbl *lpVtbl;
50 static inline dispevent *impl_from_IDispatch( IDispatch *iface )
52 return (dispevent *)((char*)iface - FIELD_OFFSET(dispevent, lpVtbl));
55 static HRESULT WINAPI dispevent_QueryInterface(IDispatch *iface, REFIID riid, void **ppvObject)
59 if ( IsEqualGUID( riid, &IID_IDispatch) ||
60 IsEqualGUID( riid, &IID_IUnknown) )
67 IDispatch_AddRef( iface );
72 static ULONG WINAPI dispevent_AddRef(IDispatch *iface)
74 dispevent *This = impl_from_IDispatch( iface );
75 return InterlockedIncrement( &This->ref );
78 static ULONG WINAPI dispevent_Release(IDispatch *iface)
80 dispevent *This = impl_from_IDispatch( iface );
81 ULONG ref = InterlockedDecrement( &This->ref );
84 HeapFree(GetProcessHeap(), 0, This);
89 static HRESULT WINAPI dispevent_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
96 static HRESULT WINAPI dispevent_GetTypeInfo(IDispatch *iface, UINT iTInfo,
97 LCID lcid, ITypeInfo **ppTInfo)
103 static HRESULT WINAPI dispevent_GetIDsOfNames(IDispatch *iface, REFIID riid,
104 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
110 static HRESULT WINAPI dispevent_Invoke(IDispatch *iface, DISPID member, REFIID riid,
111 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result,
112 EXCEPINFO *excepInfo, UINT *argErr)
114 ok(member == 0, "expected 0 member, got %d\n", member);
115 ok(lcid == LOCALE_SYSTEM_DEFAULT, "expected LOCALE_SYSTEM_DEFAULT, got lcid %x\n", lcid);
116 ok(flags == DISPATCH_METHOD, "expected DISPATCH_METHOD, got %d\n", flags);
118 ok(params->cArgs == 0, "got %d\n", params->cArgs);
119 ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
120 ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
121 ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
123 ok(result == NULL, "got %p\n", result);
124 ok(excepInfo == NULL, "got %p\n", excepInfo);
125 ok(argErr == NULL, "got %p\n", argErr);
131 static const IDispatchVtbl dispeventVtbl =
133 dispevent_QueryInterface,
136 dispevent_GetTypeInfoCount,
137 dispevent_GetTypeInfo,
138 dispevent_GetIDsOfNames,
142 static IDispatch* create_dispevent(void)
144 dispevent *event = HeapAlloc(GetProcessHeap(), 0, sizeof(*event));
146 event->lpVtbl = &dispeventVtbl;
149 return (IDispatch*)&event->lpVtbl;
152 #define EXPECT_CHILDREN(node) _expect_children((IXMLDOMNode*)node, __LINE__)
153 static void _expect_children(IXMLDOMNode *node, int line)
159 hr = IXMLDOMNode_hasChildNodes(node, &b);
160 ok_(__FILE__,line)(hr == S_OK, "hasChildNodes() failed, 0x%08x\n", hr);
161 ok_(__FILE__,line)(b == VARIANT_TRUE, "no children, %d\n", b);
164 #define EXPECT_NO_CHILDREN(node) _expect_no_children((IXMLDOMNode*)node, __LINE__)
165 static void _expect_no_children(IXMLDOMNode *node, int line)
171 hr = IXMLDOMNode_hasChildNodes(node, &b);
172 ok_(__FILE__,line)(hr == S_FALSE, "hasChildNodes() failed, 0x%08x\n", hr);
173 ok_(__FILE__,line)(b == VARIANT_FALSE, "no children, %d\n", b);
176 #define EXPECT_REF(node,ref) _expect_ref((IUnknown*)node, ref, __LINE__)
177 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
179 ULONG rc = IUnknown_AddRef(obj);
180 IUnknown_Release(obj);
181 ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
184 #define EXPECT_LIST_LEN(list,len) _expect_list_len(list, len, __LINE__)
185 static void _expect_list_len(IXMLDOMNodeList *list, LONG len, int line)
191 hr = IXMLDOMNodeList_get_length(list, &length);
192 ok_(__FILE__,line)(hr == S_OK, "got 0x%08x\n", hr);
193 ok_(__FILE__,line)(length == len, "got %d, expected %d\n", length, len);
196 #define EXPECT_HR(hr,hr_exp) \
197 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
199 static const WCHAR szEmpty[] = { 0 };
200 static const WCHAR szIncomplete[] = {
201 '<','?','x','m','l',' ',
202 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',0
204 static const WCHAR szComplete1[] = {
205 '<','?','x','m','l',' ',
206 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
207 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
209 static const WCHAR szComplete2[] = {
210 '<','?','x','m','l',' ',
211 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
212 '<','o','>','<','/','o','>','\n',0
214 static const WCHAR szComplete3[] = {
215 '<','?','x','m','l',' ',
216 'v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
217 '<','a','>','<','/','a','>','\n',0
219 static const WCHAR szComplete4[] = {
220 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'','?','>','\n',
221 '<','l','c',' ','d','l','=','\'','s','t','r','1','\'','>','\n',
222 '<','b','s',' ','v','r','=','\'','s','t','r','2','\'',' ','s','z','=','\'','1','2','3','4','\'','>',
223 'f','n','1','.','t','x','t','\n',
224 '<','/','b','s','>','\n',
225 '<','p','r',' ','i','d','=','\'','s','t','r','3','\'',' ','v','r','=','\'','1','.','2','.','3','\'',' ',
226 'p','n','=','\'','w','i','n','e',' ','2','0','0','5','0','8','0','4','\'','>','\n',
227 'f','n','2','.','t','x','t','\n',
228 '<','/','p','r','>','\n',
229 '<','e','m','p','t','y','>','<','/','e','m','p','t','y','>','\n',
230 '<','f','o','>','\n',
231 '<','b','a','>','\n',
233 '<','/','b','a','>','\n',
234 '<','/','f','o','>','\n',
235 '<','/','l','c','>','\n',0
237 static const WCHAR szComplete5[] = {
238 '<','S',':','s','e','a','r','c','h',' ','x','m','l','n','s',':','D','=','"','D','A','V',':','"',' ',
239 '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','"',
240 ' ','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','"','>',
241 '<','S',':','s','c','o','p','e','>',
242 '<','S',':','d','e','e','p','>','/','<','/','S',':','d','e','e','p','>',
243 '<','/','S',':','s','c','o','p','e','>',
244 '<','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
245 '<','C',':','t','e','x','t','o','r','p','r','o','p','e','r','t','y','/','>',
246 'c','o','m','p','u','t','e','r',
247 '<','/','S',':','c','o','n','t','e','n','t','f','r','e','e','t','e','x','t','>',
248 '<','/','S',':','s','e','a','r','c','h','>',0
251 static const WCHAR szComplete6[] = {
252 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
253 'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
254 '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
257 static const CHAR szNonUnicodeXML[] =
258 "<?xml version='1.0' encoding='Windows-1252'?>\n"
261 static const CHAR szExampleXML[] =
262 "<?xml version='1.0' encoding='utf-8'?>\n"
263 "<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
268 " <description xmlns:foo='http://www.winehq.org' xmlns:bar='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
269 " <html xmlns='http://www.w3.org/1999/xhtml'>\n"
270 " This is <strong>a</strong> <i>description</i>. <bar:x/>\n"
272 " <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n"
273 " This is <strong>a</strong> <i>description</i> with preserved whitespace. <bar:x/>\n"
281 " <c type=\"old\">C2 field</c>\n"
284 " <elem xmlns='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
293 " <foo:c>C4 field</foo:c>\n"
297 static const CHAR szNodeTypesXML[] =
298 "<?xml version='1.0'?>"
299 "<!-- comment node 0 -->"
300 "<root id='0' depth='0'>"
301 " <!-- comment node 1 -->"
303 " <x id='1' depth='1'>"
304 " <?foo value='PI for x'?>"
305 " <!-- comment node 2 -->"
307 " <a id='3' depth='2'/>"
308 " <b id='4' depth='2'/>"
309 " <c id='5' depth='2'/>"
311 " <y id='2' depth='1'>"
312 " <?bar value='PI for y'?>"
313 " <!-- comment node 3 -->"
315 " <a id='6' depth='2'/>"
316 " <b id='7' depth='2'/>"
317 " <c id='8' depth='2'/>"
321 static const CHAR szTransformXML[] =
322 "<?xml version=\"1.0\"?>\n"
327 static const CHAR szTransformSSXML[] =
328 "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
329 " <xsl:output method=\"html\"/>\n"
330 " <xsl:template match=\"/\">\n"
331 " <xsl:apply-templates select=\"greeting\"/>\n"
333 " <xsl:template match=\"greeting\">\n"
337 " <xsl:value-of select=\".\"/>\n"
344 static const CHAR szTransformOutput[] =
347 "</h1></body></html>";
349 static const CHAR szTypeValueXML[] =
350 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
351 "<root xmlns:dt=\"urn:schemas-microsoft-com:datatypes\">\n"
352 " <string>Wine</string>\n"
353 " <string2 dt:dt=\"string\">String</string2>\n"
354 " <number dt:dt=\"number\">12.44</number>\n"
355 " <number2 dt:dt=\"NUMbEr\">-3.71e3</number2>\n"
356 " <int dt:dt=\"int\">-13</int>\n"
357 " <fixed dt:dt=\"fixed.14.4\">7322.9371</fixed>\n"
358 " <bool dt:dt=\"boolean\">1</bool>\n"
359 " <datetime dt:dt=\"datetime\">2009-11-18T03:21:33.12</datetime>\n"
360 " <datetimetz dt:dt=\"datetime.tz\">2003-07-11T11:13:57+03:00</datetimetz>\n"
361 " <date dt:dt=\"date\">3721-11-01</date>\n"
362 " <time dt:dt=\"time\">13:57:12.31321</time>\n"
363 " <timetz dt:dt=\"time.tz\">23:21:01.13+03:21</timetz>\n"
364 " <i1 dt:dt=\"i1\">-13</i1>\n"
365 " <i2 dt:dt=\"i2\">31915</i2>\n"
366 " <i4 dt:dt=\"i4\">-312232</i4>\n"
367 " <ui1 dt:dt=\"ui1\">123</ui1>\n"
368 " <ui2 dt:dt=\"ui2\">48282</ui2>\n"
369 " <ui4 dt:dt=\"ui4\">949281</ui4>\n"
370 " <r4 dt:dt=\"r4\">213124.0</r4>\n"
371 " <r8 dt:dt=\"r8\">0.412</r8>\n"
372 " <float dt:dt=\"float\">41221.421</float>\n"
373 " <uuid dt:dt=\"uuid\">333C7BC4-460F-11D0-BC04-0080C7055a83</uuid>\n"
374 " <binhex dt:dt=\"bin.hex\">fffca012003c</binhex>\n"
375 " <binbase64 dt:dt=\"bin.base64\">YmFzZTY0IHRlc3Q=</binbase64>\n"
376 " <binbase64_1 dt:dt=\"bin.base64\">\nYmFzZTY0\nIHRlc3Q=\n</binbase64_1>\n"
377 " <binbase64_2 dt:dt=\"bin.base64\">\nYmF\r\t z ZTY0\nIHRlc3Q=\n</binbase64_2>\n"
380 static const CHAR szBasicTransformSSXMLPart1[] =
381 "<?xml version=\"1.0\"?>"
382 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" >"
383 "<xsl:output method=\"html\"/>\n"
384 "<xsl:template match=\"/\">"
385 "<HTML><BODY><TABLE>"
386 " <xsl:apply-templates select='document(\"";
388 static const CHAR szBasicTransformSSXMLPart2[] =
390 " <xsl:sort select=\"cost\"/><xsl:sort select=\"name\"/>"
391 " </xsl:apply-templates>"
392 "</TABLE></BODY></HTML>"
394 "<xsl:template match=\"bottle\">"
395 " <TR><xsl:apply-templates select=\"name\" /><xsl:apply-templates select=\"cost\" /></TR>"
397 "<xsl:template match=\"name\">"
398 " <TD><xsl:apply-templates /></TD>"
400 "<xsl:template match=\"cost\">"
401 " <TD><xsl:apply-templates /></TD>"
405 static const CHAR szBasicTransformXML[] =
406 "<?xml version=\"1.0\"?><bottle><wine><name>Wine</name><cost>$25.00</cost></wine></bottle>";
408 static const CHAR szBasicTransformOutput[] =
409 "<HTML><BODY><TABLE><TD>Wine</TD><TD>$25.00</TD></TABLE></BODY></HTML>";
411 #define SZ_EMAIL_DTD \
413 " <!ELEMENT email (recipients,from,reply-to?,subject,body,attachment*)>"\
414 " <!ATTLIST email attachments IDREFS #REQUIRED>"\
415 " <!ATTLIST email sent (yes|no) \"no\">"\
416 " <!ELEMENT recipients (to+,cc*)>"\
417 " <!ELEMENT to (#PCDATA)>"\
418 " <!ATTLIST to name CDATA #IMPLIED>"\
419 " <!ELEMENT cc (#PCDATA)>"\
420 " <!ATTLIST cc name CDATA #IMPLIED>"\
421 " <!ELEMENT from (#PCDATA)>"\
422 " <!ATTLIST from name CDATA #IMPLIED>"\
423 " <!ELEMENT reply-to (#PCDATA)>"\
424 " <!ATTLIST reply-to name CDATA #IMPLIED>"\
425 " <!ELEMENT subject ANY>"\
426 " <!ELEMENT body ANY>"\
427 " <!ATTLIST body enc CDATA #FIXED \"UTF-8\">"\
428 " <!ELEMENT attachment (#PCDATA)>"\
429 " <!ATTLIST attachment id ID #REQUIRED>"\
432 static const CHAR szEmailXML[] =
433 "<?xml version=\"1.0\"?>"
435 "<email attachments=\"patch1\">"
437 " <to>wine-patches@winehq.org</to>"
439 " <from name=\"Anonymous\">user@localhost</from>"
440 " <subject>msxml3/tests: DTD validation (try 87)</subject>"
442 " It no longer causes spontaneous combustion..."
444 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
447 static const CHAR szEmailXML_0D[] =
448 "<?xml version=\"1.0\"?>"
450 "<email attachments=\"patch1\">"
452 " <to>wine-patches@winehq.org</to>"
454 " <from name=\"Anonymous\">user@localhost</from>"
455 " <subject>msxml3/tests: DTD validation (try 88)</subject>"
458 " XML_ELEMENT_UNDECLARED 0xC00CE00D"
460 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
463 static const CHAR szEmailXML_0E[] =
464 "<?xml version=\"1.0\"?>"
466 "<email attachments=\"patch1\">"
468 " <to>wine-patches@winehq.org</to>"
470 " <from name=\"Anonymous\">user@localhost</from>"
471 " <subject>msxml3/tests: DTD validation (try 89)</subject>"
473 " XML_ELEMENT_ID_NOT_FOUND 0xC00CE00E"
475 " <attachment id=\"patch\">0001-msxml3-tests-DTD-validation.patch</attachment>"
478 static const CHAR szEmailXML_11[] =
479 "<?xml version=\"1.0\"?>"
481 "<email attachments=\"patch1\">"
484 " <from name=\"Anonymous\">user@localhost</from>"
485 " <subject>msxml3/tests: DTD validation (try 90)</subject>"
487 " XML_EMPTY_NOT_ALLOWED 0xC00CE011"
489 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
492 static const CHAR szEmailXML_13[] =
493 "<?xml version=\"1.0\"?>"
495 "<msg attachments=\"patch1\">"
497 " <to>wine-patches@winehq.org</to>"
499 " <from name=\"Anonymous\">user@localhost</from>"
500 " <subject>msxml3/tests: DTD validation (try 91)</subject>"
502 " XML_ROOT_NAME_MISMATCH 0xC00CE013"
504 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
507 static const CHAR szEmailXML_14[] =
508 "<?xml version=\"1.0\"?>"
510 "<email attachments=\"patch1\">"
511 " <to>wine-patches@winehq.org</to>"
512 " <from name=\"Anonymous\">user@localhost</from>"
513 " <subject>msxml3/tests: DTD validation (try 92)</subject>"
515 " XML_INVALID_CONTENT 0xC00CE014"
517 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
520 static const CHAR szEmailXML_15[] =
521 "<?xml version=\"1.0\"?>"
523 "<email attachments=\"patch1\" ip=\"127.0.0.1\">"
525 " <to>wine-patches@winehq.org</to>"
527 " <from name=\"Anonymous\">user@localhost</from>"
528 " <subject>msxml3/tests: DTD validation (try 93)</subject>"
530 " XML_ATTRIBUTE_NOT_DEFINED 0xC00CE015"
532 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
535 static const CHAR szEmailXML_16[] =
536 "<?xml version=\"1.0\"?>"
538 "<email attachments=\"patch1\">"
540 " <to>wine-patches@winehq.org</to>"
542 " <from name=\"Anonymous\">user@localhost</from>"
543 " <subject>msxml3/tests: DTD validation (try 94)</subject>"
544 " <body enc=\"ASCII\">"
545 " XML_ATTRIBUTE_FIXED 0xC00CE016"
547 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
550 static const CHAR szEmailXML_17[] =
551 "<?xml version=\"1.0\"?>"
553 "<email attachments=\"patch1\" sent=\"true\">"
555 " <to>wine-patches@winehq.org</to>"
557 " <from name=\"Anonymous\">user@localhost</from>"
558 " <subject>msxml3/tests: DTD validation (try 95)</subject>"
560 " XML_ATTRIBUTE_VALUE 0xC00CE017"
562 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
565 static const CHAR szEmailXML_18[] =
566 "<?xml version=\"1.0\"?>"
568 "<email attachments=\"patch1\">"
571 " <to>wine-patches@winehq.org</to>"
573 " <from name=\"Anonymous\">user@localhost</from>"
574 " <subject>msxml3/tests: DTD validation (try 96)</subject>"
576 " XML_ILLEGAL_TEXT 0xC00CE018"
578 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
581 static const CHAR szEmailXML_20[] =
582 "<?xml version=\"1.0\"?>"
586 " <to>wine-patches@winehq.org</to>"
588 " <from name=\"Anonymous\">user@localhost</from>"
589 " <subject>msxml3/tests: DTD validation (try 97)</subject>"
591 " XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020"
593 " <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
596 static const WCHAR szNonExistentFile[] = {
597 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
599 static const WCHAR szNonExistentAttribute[] = {
600 'n','o','n','E','x','i','s','i','t','i','n','g','A','t','t','r','i','b','u','t','e',0
602 static const WCHAR szDocument[] = {
603 '#', 'd', 'o', 'c', 'u', 'm', 'e', 'n', 't', 0
606 static const WCHAR szOpen[] = { 'o','p','e','n',0 };
607 static WCHAR szdl[] = { 'd','l',0 };
608 static const WCHAR szvr[] = { 'v','r',0 };
609 static const WCHAR szlc[] = { 'l','c',0 };
610 static WCHAR szbs[] = { 'b','s',0 };
611 static const WCHAR szstr1[] = { 's','t','r','1',0 };
612 static const WCHAR szstr2[] = { 's','t','r','2',0 };
613 static const WCHAR szstar[] = { '*',0 };
614 static const WCHAR szfn1_txt[] = {'f','n','1','.','t','x','t',0};
616 static WCHAR szComment[] = {'A',' ','C','o','m','m','e','n','t',0 };
617 static WCHAR szCommentXML[] = {'<','!','-','-','A',' ','C','o','m','m','e','n','t','-','-','>',0 };
618 static WCHAR szCommentNodeText[] = {'#','c','o','m','m','e','n','t',0 };
620 static WCHAR szElement[] = {'E','l','e','T','e','s','t', 0 };
621 static WCHAR szElementXML[] = {'<','E','l','e','T','e','s','t','/','>',0 };
622 static WCHAR szElementXML2[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','/','>',0 };
623 static WCHAR szElementXML3[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
624 'T','e','s','t','i','n','g','N','o','d','e','<','/','E','l','e','T','e','s','t','>',0 };
625 static WCHAR szElementXML4[] = {'<','E','l','e','T','e','s','t',' ','A','t','t','r','=','"','"','>',
626 '&','a','m','p',';','x',' ',0x2103,'<','/','E','l','e','T','e','s','t','>',0 };
628 static WCHAR szAttribute[] = {'A','t','t','r',0 };
629 static WCHAR szAttributeXML[] = {'A','t','t','r','=','"','"',0 };
631 static WCHAR szCData[] = {'[','1',']','*','2','=','3',';',' ','&','g','e','e',' ','t','h','a','t','s',
632 ' ','n','o','t',' ','r','i','g','h','t','!', 0};
633 static WCHAR szCDataXML[] = {'<','!','[','C','D','A','T','A','[','[','1',']','*','2','=','3',';',' ','&',
634 'g','e','e',' ','t','h','a','t','s',' ','n','o','t',' ','r','i','g','h','t',
636 static WCHAR szCDataNodeText[] = {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0 };
637 static WCHAR szDocFragmentText[] = {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0 };
639 static WCHAR szEntityRef[] = {'e','n','t','i','t','y','r','e','f',0 };
640 static WCHAR szEntityRefXML[] = {'&','e','n','t','i','t','y','r','e','f',';',0 };
641 static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0};
643 #define expect_bstr_eq_and_free(bstr, expect) { \
644 BSTR bstrExp = alloc_str_from_narrow(expect); \
645 ok(lstrcmpW(bstr, bstrExp) == 0, "String differs\n"); \
646 SysFreeString(bstr); \
647 SysFreeString(bstrExp); \
650 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
652 #define ole_check(expr) { \
654 ok(r == S_OK, #expr " returned %x\n", r); \
657 #define ole_expect(expr, expect) { \
659 ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \
662 #define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y)
664 static void* _create_object(const GUID *clsid, const char *name, const IID *iid, int line)
669 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &obj);
671 win_skip_(__FILE__,line)("failed to create %s instance: 0x%08x\n", name, hr);
676 #define _create(cls) cls, #cls
678 #define create_document(iid) _create_object(&_create(CLSID_DOMDocument), iid, __LINE__)
679 #define create_document_version(v, iid) _create_object(&_create(CLSID_DOMDocument ## v), iid, __LINE__)
680 #define create_cache(iid) _create_object(&_create(CLSID_XMLSchemaCache), iid, __LINE__)
681 #define create_cache_version(v, iid) _create_object(&_create(CLSID_XMLSchemaCache ## v), iid, __LINE__)
682 #define create_xsltemplate(iid) _create_object(&_create(CLSID_XSLTemplate), iid, __LINE__)
684 static BSTR alloc_str_from_narrow(const char *str)
686 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
687 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
688 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
692 static BSTR alloced_bstrs[256];
693 static int alloced_bstrs_count;
695 static BSTR _bstr_(const char *str)
697 assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
698 alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
699 return alloced_bstrs[alloced_bstrs_count++];
702 static void free_bstrs(void)
705 for (i = 0; i < alloced_bstrs_count; i++)
706 SysFreeString(alloced_bstrs[i]);
707 alloced_bstrs_count = 0;
710 static VARIANT _variantbstr_(const char *str)
714 V_BSTR(&v) = _bstr_(str);
718 static BOOL compareIgnoreReturns(BSTR sLeft, BSTR sRight)
722 while (*sLeft == '\r' || *sLeft == '\n') sLeft++;
723 while (*sRight == '\r' || *sRight == '\n') sRight++;
724 if (*sLeft != *sRight) return FALSE;
725 if (!*sLeft) return TRUE;
731 static void get_str_for_type(DOMNodeType type, char *buf)
750 case NODE_PROCESSING_INSTRUCTION:
754 wsprintfA(buf, "[%d]", type);
758 #define test_disp(u) _test_disp(__LINE__,u)
759 static void _test_disp(unsigned line, IUnknown *unk)
761 DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
769 hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
770 ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
775 hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
776 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
777 ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
779 sName = SysAllocString( szstar );
780 hres = IDispatchEx_DeleteMemberByName(dispex, sName, fdexNameCaseSensitive);
781 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
782 SysFreeString( sName );
784 hres = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
785 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
787 hres = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &dwProps);
788 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
789 ok(dwProps == 0, "expected 0 got %d\n", dwProps);
791 hres = IDispatchEx_GetMemberName(dispex, dispid, &sName);
792 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
794 SysFreeString(sName);
796 hres = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
797 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
799 hres = IDispatchEx_GetNameSpaceParent(dispex, &pUnk);
800 ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
801 if(hres == S_OK && pUnk)
802 IUnknown_Release(pUnk);
804 IDispatchEx_Release(dispex);
807 static int get_node_position(IXMLDOMNode *node)
812 IXMLDOMNode_AddRef(node);
815 IXMLDOMNode *new_node;
818 r = IXMLDOMNode_get_previousSibling(node, &new_node);
819 ok(SUCCEEDED(r), "get_previousSibling failed\n");
820 IXMLDOMNode_Release(node);
826 static void node_to_string(IXMLDOMNode *node, char *buf)
833 lstrcpyA(buf, "(null)");
837 IXMLDOMNode_AddRef(node);
840 IXMLDOMNode *new_node;
842 ole_check(IXMLDOMNode_get_nodeType(node, &type));
843 get_str_for_type(type, buf);
846 if (type == NODE_ATTRIBUTE)
849 ole_check(IXMLDOMNode_get_nodeName(node, &bstr));
851 wsprintfA(buf, "%ws", bstr);
856 r = IXMLDOMNode_selectSingleNode(node, _bstr_(".."), &new_node);
860 r = IXMLDOMNode_get_parentNode(node, &new_node);
861 wsprintf(buf, "%d", get_node_position(node));
865 ok(SUCCEEDED(r), "get_parentNode failed (%08x)\n", r);
866 IXMLDOMNode_Release(node);
875 static char *list_to_string(IXMLDOMNodeList *list)
877 static char buf[4096];
884 lstrcpyA(buf, "(null)");
887 ole_check(IXMLDOMNodeList_get_length(list, &len));
888 for (i = 0; i < len; i++)
893 ole_check(IXMLDOMNodeList_nextNode(list, &node));
894 node_to_string(node, pos);
896 IXMLDOMNode_Release(node);
902 #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); }
903 #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); }
905 static void test_domdoc( void )
908 IXMLDOMDocument *doc;
909 IXMLDOMParseError *error;
910 IXMLDOMElement *element = NULL;
912 IXMLDOMText *nodetext = NULL;
913 IXMLDOMComment *node_comment = NULL;
914 IXMLDOMAttribute *node_attr = NULL;
915 IXMLDOMNode *nodeChild = NULL;
916 IXMLDOMProcessingInstruction *nodePI = NULL;
917 ISupportErrorInfo *support_error = NULL;
925 doc = create_document(&IID_IXMLDOMDocument);
928 test_disp((IUnknown*)doc);
932 /* crashes on native */
933 IXMLDOMDocument_loadXML( doc, (BSTR)0x1, NULL );
936 /* try some stupid things */
937 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
938 ok( r == S_FALSE, "loadXML succeeded\n");
941 r = IXMLDOMDocument_loadXML( doc, NULL, &b );
942 ok( r == S_FALSE, "loadXML succeeded\n");
943 ok( b == VARIANT_FALSE, "failed to load XML string\n");
945 /* try to load a document from a nonexistent file */
947 str = SysAllocString( szNonExistentFile );
949 V_VT(&var) = VT_BSTR;
952 r = IXMLDOMDocument_load( doc, var, &b);
953 ok( r == S_FALSE, "loadXML succeeded\n");
954 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
955 SysFreeString( str );
957 /* try load an empty document */
959 str = SysAllocString( szEmpty );
960 r = IXMLDOMDocument_loadXML( doc, str, &b );
961 ok( r == S_FALSE, "loadXML succeeded\n");
962 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
963 SysFreeString( str );
965 r = IXMLDOMDocument_get_async( doc, &b );
966 ok( r == S_OK, "get_async failed (%08x)\n", r);
967 ok( b == VARIANT_TRUE, "Wrong default value\n");
969 /* check that there's no document element */
971 r = IXMLDOMDocument_get_documentElement( doc, &element );
972 ok( r == S_FALSE, "should be no document element\n");
974 /* try finding a node */
976 str = SysAllocString( szstr1 );
977 r = IXMLDOMDocument_selectSingleNode( doc, str, &node );
978 ok( r == S_FALSE, "ret %08x\n", r );
979 SysFreeString( str );
982 str = SysAllocString( szIncomplete );
983 r = IXMLDOMDocument_loadXML( doc, str, &b );
984 ok( r == S_FALSE, "loadXML succeeded\n");
985 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
986 SysFreeString( str );
988 /* check that there's no document element */
989 element = (IXMLDOMElement*)1;
990 r = IXMLDOMDocument_get_documentElement( doc, &element );
991 ok( r == S_FALSE, "should be no document element\n");
992 ok( element == NULL, "Element should be NULL\n");
994 /* test for BSTR handling, pass broken BSTR */
995 memcpy(&buff[2], szComplete1, sizeof(szComplete1));
996 /* just a big length */
997 *(DWORD*)buff = 0xf0f0;
999 r = IXMLDOMDocument_loadXML( doc, &buff[2], &b );
1000 ok( r == S_OK, "loadXML failed\n");
1001 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1003 /* loadXML ignores the encoding attribute and always expects Unicode */
1005 str = SysAllocString( szComplete6 );
1006 r = IXMLDOMDocument_loadXML( doc, str, &b );
1007 ok( r == S_OK, "loadXML failed\n");
1008 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1009 SysFreeString( str );
1011 /* try a BSTR containing a Windows-1252 document */
1013 str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
1014 r = IXMLDOMDocument_loadXML( doc, str, &b );
1015 ok( r == S_FALSE, "loadXML succeeded\n");
1016 ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
1017 SysFreeString( str );
1019 /* try to load something valid */
1021 str = SysAllocString( szComplete1 );
1022 r = IXMLDOMDocument_loadXML( doc, str, &b );
1023 ok( r == S_OK, "loadXML failed\n");
1024 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1025 SysFreeString( str );
1027 /* check if nodename is correct */
1028 r = IXMLDOMDocument_get_nodeName( doc, NULL );
1029 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1031 str = (BSTR)0xdeadbeef;
1032 r = IXMLDOMDocument_get_baseName( doc, &str );
1033 ok ( r == S_FALSE, "got 0x%08x\n", r);
1034 ok (str == NULL, "got %p\n", str);
1036 /* content doesn't matter here */
1038 r = IXMLDOMDocument_get_nodeName( doc, &str );
1039 ok ( r == S_OK, "get_nodeName wrong code\n");
1040 ok ( str != NULL, "str is null\n");
1041 ok( !lstrcmpW( str, szDocument ), "incorrect nodeName\n");
1042 SysFreeString( str );
1045 r = IXMLDOMDocument_put_text( doc, _bstr_("Should Fail") );
1046 ok( r == E_FAIL, "ret %08x\n", r );
1048 /* check that there's a document element */
1050 r = IXMLDOMDocument_get_documentElement( doc, &element );
1051 ok( r == S_OK, "should be a document element\n");
1054 IObjectIdentity *ident;
1056 test_disp((IUnknown*)element);
1058 r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
1059 ok( r == E_NOINTERFACE, "ret %08x\n", r);
1061 IXMLDOMElement_Release( element );
1065 /* as soon as we call loadXML again, the document element will disappear */
1067 r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
1068 ok( r == S_FALSE, "loadXML failed\n");
1069 ok( b == 2, "variant modified\n");
1070 r = IXMLDOMDocument_get_documentElement( doc, &element );
1071 ok( r == S_FALSE, "should be no document element\n");
1073 /* try to load something else simple and valid */
1075 str = SysAllocString( szComplete3 );
1076 r = IXMLDOMDocument_loadXML( doc, str, &b );
1077 ok( r == S_OK, "loadXML failed\n");
1078 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1079 SysFreeString( str );
1081 /* try something a little more complicated */
1083 str = SysAllocString( szComplete4 );
1084 r = IXMLDOMDocument_loadXML( doc, str, &b );
1085 ok( r == S_OK, "loadXML failed\n");
1086 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1087 SysFreeString( str );
1089 r = IXMLDOMDocument_get_parseError( doc, &error );
1090 ok( r == S_OK, "returns %08x\n", r );
1092 r = IXMLDOMParseError_get_errorCode( error, &code );
1093 ok( r == S_FALSE, "returns %08x\n", r );
1094 ok( code == 0, "code %d\n", code );
1095 IXMLDOMParseError_Release( error );
1097 /* test createTextNode */
1098 r = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &nodetext);
1099 ok( r == S_OK, "returns %08x\n", r );
1100 IXMLDOMText_Release(nodetext);
1102 str = SysAllocString( szOpen );
1103 r = IXMLDOMDocument_createTextNode(doc, str, NULL);
1104 ok( r == E_INVALIDARG, "returns %08x\n", r );
1105 r = IXMLDOMDocument_createTextNode(doc, str, &nodetext);
1106 ok( r == S_OK, "returns %08x\n", r );
1107 SysFreeString( str );
1110 r = IXMLDOMText_QueryInterface(nodetext, &IID_IXMLDOMElement, (void**)&element);
1111 ok(r == E_NOINTERFACE, "ret %08x\n", r );
1113 /* Text Last Child Checks */
1114 r = IXMLDOMText_get_lastChild(nodetext, NULL);
1115 ok(r == E_INVALIDARG, "ret %08x\n", r );
1117 nodeChild = (IXMLDOMNode*)0x1;
1118 r = IXMLDOMText_get_lastChild(nodetext, &nodeChild);
1119 ok(r == S_FALSE, "ret %08x\n", r );
1120 ok(nodeChild == NULL, "nodeChild not NULL\n");
1122 /* test length property */
1123 r = IXMLDOMText_get_length(nodetext, NULL);
1124 ok(r == E_INVALIDARG, "ret %08x\n", r );
1126 r = IXMLDOMText_get_length(nodetext, &nLength);
1127 ok(r == S_OK, "ret %08x\n", r );
1128 ok(nLength == 4, "expected 4 got %d\n", nLength);
1130 /* put data Tests */
1131 r = IXMLDOMText_put_data(nodetext, _bstr_("This &is a ; test <>\\"));
1132 ok(r == S_OK, "ret %08x\n", r );
1134 /* get data Tests */
1135 r = IXMLDOMText_get_data(nodetext, &str);
1136 ok(r == S_OK, "ret %08x\n", r );
1137 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect put_data string\n");
1140 /* Confirm XML text is good */
1141 r = IXMLDOMText_get_xml(nodetext, &str);
1142 ok(r == S_OK, "ret %08x\n", r );
1143 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1146 /* Confirm we get the put_data Text back */
1147 r = IXMLDOMText_get_text(nodetext, &str);
1148 ok(r == S_OK, "ret %08x\n", r );
1149 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
1152 /* test substringData */
1153 r = IXMLDOMText_substringData(nodetext, 0, 4, NULL);
1154 ok(r == E_INVALIDARG, "ret %08x\n", r );
1156 /* test substringData - Invalid offset */
1157 str = (BSTR)&szElement;
1158 r = IXMLDOMText_substringData(nodetext, -1, 4, &str);
1159 ok(r == E_INVALIDARG, "ret %08x\n", r );
1160 ok( str == NULL, "incorrect string\n");
1162 /* test substringData - Invalid offset */
1163 str = (BSTR)&szElement;
1164 r = IXMLDOMText_substringData(nodetext, 30, 0, &str);
1165 ok(r == S_FALSE, "ret %08x\n", r );
1166 ok( str == NULL, "incorrect string\n");
1168 /* test substringData - Invalid size */
1169 str = (BSTR)&szElement;
1170 r = IXMLDOMText_substringData(nodetext, 0, -1, &str);
1171 ok(r == E_INVALIDARG, "ret %08x\n", r );
1172 ok( str == NULL, "incorrect string\n");
1174 /* test substringData - Invalid size */
1175 str = (BSTR)&szElement;
1176 r = IXMLDOMText_substringData(nodetext, 2, 0, &str);
1177 ok(r == S_FALSE, "ret %08x\n", r );
1178 ok( str == NULL, "incorrect string\n");
1180 /* test substringData - Start of string */
1181 r = IXMLDOMText_substringData(nodetext, 0, 4, &str);
1182 ok(r == S_OK, "ret %08x\n", r );
1183 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
1186 /* test substringData - Middle of string */
1187 r = IXMLDOMText_substringData(nodetext, 13, 4, &str);
1188 ok(r == S_OK, "ret %08x\n", r );
1189 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
1192 /* test substringData - End of string */
1193 r = IXMLDOMText_substringData(nodetext, 20, 4, &str);
1194 ok(r == S_OK, "ret %08x\n", r );
1195 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
1198 /* test appendData */
1199 r = IXMLDOMText_appendData(nodetext, NULL);
1200 ok(r == S_OK, "ret %08x\n", r );
1202 r = IXMLDOMText_appendData(nodetext, _bstr_(""));
1203 ok(r == S_OK, "ret %08x\n", r );
1205 r = IXMLDOMText_appendData(nodetext, _bstr_("Append"));
1206 ok(r == S_OK, "ret %08x\n", r );
1208 r = IXMLDOMText_get_text(nodetext, &str);
1209 ok(r == S_OK, "ret %08x\n", r );
1210 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1213 /* test insertData */
1214 str = SysAllocStringLen(NULL, 0);
1215 r = IXMLDOMText_insertData(nodetext, -1, str);
1216 ok(r == S_OK, "ret %08x\n", r );
1218 r = IXMLDOMText_insertData(nodetext, -1, NULL);
1219 ok(r == S_OK, "ret %08x\n", r );
1221 r = IXMLDOMText_insertData(nodetext, 1000, str);
1222 ok(r == S_OK, "ret %08x\n", r );
1224 r = IXMLDOMText_insertData(nodetext, 1000, NULL);
1225 ok(r == S_OK, "ret %08x\n", r );
1227 r = IXMLDOMText_insertData(nodetext, 0, NULL);
1228 ok(r == S_OK, "ret %08x\n", r );
1230 r = IXMLDOMText_insertData(nodetext, 0, str);
1231 ok(r == S_OK, "ret %08x\n", r );
1234 r = IXMLDOMText_insertData(nodetext, -1, _bstr_("Inserting"));
1235 ok(r == E_INVALIDARG, "ret %08x\n", r );
1237 r = IXMLDOMText_insertData(nodetext, 1000, _bstr_("Inserting"));
1238 ok(r == E_INVALIDARG, "ret %08x\n", r );
1240 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("Begin "));
1241 ok(r == S_OK, "ret %08x\n", r );
1243 r = IXMLDOMText_insertData(nodetext, 17, _bstr_("Middle"));
1244 ok(r == S_OK, "ret %08x\n", r );
1246 r = IXMLDOMText_insertData(nodetext, 39, _bstr_(" End"));
1247 ok(r == S_OK, "ret %08x\n", r );
1249 r = IXMLDOMText_get_text(nodetext, &str);
1250 ok(r == S_OK, "ret %08x\n", r );
1251 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1255 /* invalid arguments */
1256 r = IXMLDOMText_deleteData(nodetext, -1, 1);
1257 ok(r == E_INVALIDARG, "ret %08x\n", r );
1259 r = IXMLDOMText_deleteData(nodetext, 0, 0);
1260 ok(r == S_OK, "ret %08x\n", r );
1262 r = IXMLDOMText_deleteData(nodetext, 0, -1);
1263 ok(r == E_INVALIDARG, "ret %08x\n", r );
1265 r = IXMLDOMText_get_length(nodetext, &nLength);
1266 ok(r == S_OK, "ret %08x\n", r );
1267 ok(nLength == 43, "expected 43 got %d\n", nLength);
1269 r = IXMLDOMText_deleteData(nodetext, nLength, 1);
1270 ok(r == S_OK, "ret %08x\n", r );
1272 r = IXMLDOMText_deleteData(nodetext, nLength+1, 1);
1273 ok(r == E_INVALIDARG, "ret %08x\n", r );
1275 /* delete from start */
1276 r = IXMLDOMText_deleteData(nodetext, 0, 5);
1277 ok(r == S_OK, "ret %08x\n", r );
1279 r = IXMLDOMText_get_length(nodetext, &nLength);
1280 ok(r == S_OK, "ret %08x\n", r );
1281 ok(nLength == 38, "expected 38 got %d\n", nLength);
1283 r = IXMLDOMText_get_text(nodetext, &str);
1284 ok(r == S_OK, "ret %08x\n", r );
1285 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1288 /* delete from end */
1289 r = IXMLDOMText_deleteData(nodetext, 35, 3);
1290 ok(r == S_OK, "ret %08x\n", r );
1292 r = IXMLDOMText_get_length(nodetext, &nLength);
1293 ok(r == S_OK, "ret %08x\n", r );
1294 ok(nLength == 35, "expected 35 got %d\n", nLength);
1296 r = IXMLDOMText_get_text(nodetext, &str);
1297 ok(r == S_OK, "ret %08x\n", r );
1298 ok( !lstrcmpW( str, _bstr_("This &is a Middle; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1301 /* delete from inside */
1302 r = IXMLDOMText_deleteData(nodetext, 1, 33);
1303 ok(r == S_OK, "ret %08x\n", r );
1305 r = IXMLDOMText_get_length(nodetext, &nLength);
1306 ok(r == S_OK, "ret %08x\n", r );
1307 ok(nLength == 2, "expected 2 got %d\n", nLength);
1309 r = IXMLDOMText_get_text(nodetext, &str);
1310 ok(r == S_OK, "ret %08x\n", r );
1311 ok( !lstrcmpW( str, _bstr_("") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1314 /* delete whole data ... */
1315 r = IXMLDOMText_get_length(nodetext, &nLength);
1316 ok(r == S_OK, "ret %08x\n", r );
1318 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1319 ok(r == S_OK, "ret %08x\n", r );
1320 /* ... and try again with empty string */
1321 r = IXMLDOMText_deleteData(nodetext, 0, nLength);
1322 ok(r == S_OK, "ret %08x\n", r );
1325 V_VT(&var) = VT_BSTR;
1326 V_BSTR(&var) = SysAllocString(szstr1);
1327 r = IXMLDOMText_put_nodeValue(nodetext, var);
1328 ok(r == S_OK, "ret %08x\n", r );
1331 r = IXMLDOMText_get_text(nodetext, &str);
1332 ok(r == S_OK, "ret %08x\n", r );
1333 ok( !lstrcmpW( str, szstr1 ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1339 r = IXMLDOMText_put_nodeValue(nodetext, var);
1340 ok(r == S_OK, "ret %08x\n", r );
1343 r = IXMLDOMText_get_text(nodetext, &str);
1344 ok(r == S_OK, "ret %08x\n", r );
1345 ok( !lstrcmpW( str, _bstr_("99") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1348 /* ::replaceData() */
1349 V_VT(&var) = VT_BSTR;
1350 V_BSTR(&var) = SysAllocString(szstr1);
1351 r = IXMLDOMText_put_nodeValue(nodetext, var);
1352 ok(r == S_OK, "ret %08x\n", r );
1355 r = IXMLDOMText_replaceData(nodetext, 6, 0, NULL);
1356 ok(r == E_INVALIDARG, "ret %08x\n", r );
1357 r = IXMLDOMText_get_text(nodetext, &str);
1358 ok(r == S_OK, "ret %08x\n", r );
1359 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1362 r = IXMLDOMText_replaceData(nodetext, 0, 0, NULL);
1363 ok(r == S_OK, "ret %08x\n", r );
1364 r = IXMLDOMText_get_text(nodetext, &str);
1365 ok(r == S_OK, "ret %08x\n", r );
1366 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1369 /* NULL pointer means delete */
1370 r = IXMLDOMText_replaceData(nodetext, 0, 1, NULL);
1371 ok(r == S_OK, "ret %08x\n", r );
1372 r = IXMLDOMText_get_text(nodetext, &str);
1373 ok(r == S_OK, "ret %08x\n", r );
1374 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1377 /* empty string means delete */
1378 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_(""));
1379 ok(r == S_OK, "ret %08x\n", r );
1380 r = IXMLDOMText_get_text(nodetext, &str);
1381 ok(r == S_OK, "ret %08x\n", r );
1382 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1385 /* zero count means insert */
1386 r = IXMLDOMText_replaceData(nodetext, 0, 0, _bstr_("a"));
1387 ok(r == S_OK, "ret %08x\n", r );
1388 r = IXMLDOMText_get_text(nodetext, &str);
1389 ok(r == S_OK, "ret %08x\n", r );
1390 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1393 r = IXMLDOMText_replaceData(nodetext, 0, 2, NULL);
1394 ok(r == S_OK, "ret %08x\n", r );
1396 r = IXMLDOMText_insertData(nodetext, 0, _bstr_("m"));
1397 ok(r == S_OK, "ret %08x\n", r );
1398 r = IXMLDOMText_get_text(nodetext, &str);
1399 ok(r == S_OK, "ret %08x\n", r );
1400 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1403 /* nonempty string, count greater than its length */
1404 r = IXMLDOMText_replaceData(nodetext, 0, 2, _bstr_("a1.2"));
1405 ok(r == S_OK, "ret %08x\n", r );
1406 r = IXMLDOMText_get_text(nodetext, &str);
1407 ok(r == S_OK, "ret %08x\n", r );
1408 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1411 /* nonempty string, count less than its length */
1412 r = IXMLDOMText_replaceData(nodetext, 0, 1, _bstr_("wine"));
1413 ok(r == S_OK, "ret %08x\n", r );
1414 r = IXMLDOMText_get_text(nodetext, &str);
1415 ok(r == S_OK, "ret %08x\n", r );
1416 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
1419 IXMLDOMText_Release( nodetext );
1422 /* test Create Comment */
1423 r = IXMLDOMDocument_createComment(doc, NULL, NULL);
1424 ok( r == E_INVALIDARG, "returns %08x\n", r );
1425 node_comment = (IXMLDOMComment*)0x1;
1428 r = IXMLDOMDocument_createComment(doc, _bstr_(""), &node_comment);
1429 ok( r == S_OK, "returns %08x\n", r );
1431 r = IXMLDOMComment_get_data(node_comment, &str);
1432 ok( r == S_OK, "returns %08x\n", r );
1433 ok( str && SysStringLen(str) == 0, "expected empty string data\n");
1434 IXMLDOMComment_Release(node_comment);
1437 r = IXMLDOMDocument_createComment(doc, NULL, &node_comment);
1438 ok( r == S_OK, "returns %08x\n", r );
1440 r = IXMLDOMComment_get_data(node_comment, &str);
1441 ok( r == S_OK, "returns %08x\n", r );
1442 ok( str && (SysStringLen(str) == 0), "expected empty string data\n");
1443 IXMLDOMComment_Release(node_comment);
1446 str = SysAllocString(szComment);
1447 r = IXMLDOMDocument_createComment(doc, str, &node_comment);
1449 ok( r == S_OK, "returns %08x\n", r );
1452 /* Last Child Checks */
1453 r = IXMLDOMComment_get_lastChild(node_comment, NULL);
1454 ok(r == E_INVALIDARG, "ret %08x\n", r );
1456 nodeChild = (IXMLDOMNode*)0x1;
1457 r = IXMLDOMComment_get_lastChild(node_comment, &nodeChild);
1458 ok(r == S_FALSE, "ret %08x\n", r );
1459 ok(nodeChild == NULL, "pLastChild not NULL\n");
1462 str = (BSTR)0xdeadbeef;
1463 IXMLDOMComment_get_baseName(node_comment, &str);
1464 ok(r == S_FALSE, "ret %08x\n", r );
1465 ok(str == NULL, "Expected NULL\n");
1467 IXMLDOMComment_Release( node_comment );
1470 /* test Create Attribute */
1471 str = SysAllocString(szAttribute);
1472 r = IXMLDOMDocument_createAttribute(doc, NULL, NULL);
1473 ok( r == E_INVALIDARG, "returns %08x\n", r );
1474 r = IXMLDOMDocument_createAttribute(doc, str, &node_attr);
1475 ok( r == S_OK, "returns %08x\n", r );
1476 IXMLDOMText_Release( node_attr);
1479 /* test Processing Instruction */
1480 str = SysAllocStringLen(NULL, 0);
1481 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, NULL);
1482 ok( r == E_INVALIDARG, "returns %08x\n", r );
1483 r = IXMLDOMDocument_createProcessingInstruction(doc, NULL, str, &nodePI);
1484 ok( r == E_FAIL, "returns %08x\n", r );
1485 r = IXMLDOMDocument_createProcessingInstruction(doc, str, str, &nodePI);
1486 ok( r == E_FAIL, "returns %08x\n", r );
1489 r = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"), _bstr_("version=\"1.0\""), &nodePI);
1490 ok( r == S_OK, "returns %08x\n", r );
1493 /* Last Child Checks */
1494 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, NULL);
1495 ok(r == E_INVALIDARG, "ret %08x\n", r );
1497 nodeChild = (IXMLDOMNode*)0x1;
1498 r = IXMLDOMProcessingInstruction_get_lastChild(nodePI, &nodeChild);
1499 ok(r == S_FALSE, "ret %08x\n", r );
1500 ok(nodeChild == NULL, "nodeChild not NULL\n");
1503 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1504 ok(r == S_OK, "ret %08x\n", r );
1505 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1510 r = IXMLDOMProcessingInstruction_get_baseName(nodePI, &str);
1511 ok(r == S_OK, "ret %08x\n", r );
1512 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1516 r = IXMLDOMProcessingInstruction_get_target(nodePI, &str);
1517 ok(r == S_OK, "ret %08x\n", r );
1518 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect target string\n");
1521 /* test get_nodeValue */
1522 r = IXMLDOMProcessingInstruction_get_nodeValue(nodePI, &var);
1523 ok(r == S_OK, "ret %08x\n", r );
1524 ok( !lstrcmpW( V_BSTR(&var), _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1528 r = IXMLDOMProcessingInstruction_get_data(nodePI, &str);
1529 ok(r == S_OK, "ret %08x\n", r );
1530 ok( !lstrcmpW( str, _bstr_("version=\"1.0\"") ), "incorrect data string\n");
1534 r = IXMLDOMProcessingInstruction_put_data(nodePI, _bstr_("version=\"1.0\" encoding=\"UTF-8\""));
1535 ok(r == E_FAIL, "ret %08x\n", r );
1538 V_VT(&var) = VT_BSTR;
1539 V_BSTR(&var) = SysAllocString(szOpen); /* Doesn't matter what the string is, cannot set an xml node. */
1540 r = IXMLDOMProcessingInstruction_put_nodeValue(nodePI, var);
1541 ok(r == E_FAIL, "ret %08x\n", r );
1544 /* test get nodeName */
1545 r = IXMLDOMProcessingInstruction_get_nodeName(nodePI, &str);
1546 ok( !lstrcmpW( str, _bstr_("xml") ), "incorrect nodeName string\n");
1547 ok(r == S_OK, "ret %08x\n", r );
1550 IXMLDOMProcessingInstruction_Release(nodePI);
1553 r = IXMLDOMDocument_QueryInterface( doc, &IID_ISupportErrorInfo, (void**)&support_error );
1554 ok( r == S_OK, "ret %08x\n", r );
1557 r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMDocument );
1558 todo_wine ok( r == S_OK, "ret %08x\n", r );
1559 ISupportErrorInfo_Release( support_error );
1562 r = IXMLDOMDocument_Release( doc );
1563 ok( r == 0, "document ref count incorrect\n");
1568 static void test_persiststreaminit(void)
1570 IXMLDOMDocument *doc;
1571 IPersistStreamInit *streaminit;
1574 doc = create_document(&IID_IXMLDOMDocument);
1577 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
1578 ok( hr == S_OK, "failed with 0x%08x\n", hr );
1580 hr = IPersistStreamInit_InitNew(streaminit);
1581 ok( hr == S_OK, "failed with 0x%08x\n", hr );
1583 IXMLDOMDocument_Release(doc);
1586 static void test_domnode( void )
1589 IXMLDOMDocument *doc, *owner = NULL;
1590 IXMLDOMElement *element = NULL;
1591 IXMLDOMNamedNodeMap *map = NULL;
1592 IXMLDOMNode *node = NULL, *next = NULL;
1593 IXMLDOMNodeList *list = NULL;
1594 IXMLDOMAttribute *attr = NULL;
1595 DOMNodeType type = NODE_INVALID;
1601 doc = create_document(&IID_IXMLDOMDocument);
1605 str = SysAllocString( szComplete4 );
1606 r = IXMLDOMDocument_loadXML( doc, str, &b );
1607 ok( r == S_OK, "loadXML failed\n");
1608 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1609 SysFreeString( str );
1611 EXPECT_CHILDREN(doc);
1613 r = IXMLDOMDocument_get_documentElement( doc, &element );
1614 ok( r == S_OK, "should be a document element\n");
1615 ok( element != NULL, "should be an element\n");
1618 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1620 r = IXMLDOMNode_get_nodeValue( doc, NULL );
1621 ok(r == E_INVALIDARG, "get_nodeValue ret %08x\n", r );
1623 r = IXMLDOMNode_get_nodeValue( doc, &var );
1624 ok( r == S_FALSE, "nextNode returned wrong code\n");
1625 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1626 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1631 r = IXMLDOMNode_get_ownerDocument( element, &owner );
1632 ok( r == S_OK, "get_ownerDocument return code\n");
1633 ok( owner != doc, "get_ownerDocument return\n");
1634 IXMLDOMDocument_Release(owner);
1636 type = NODE_INVALID;
1637 r = IXMLDOMNode_get_nodeType( element, &type);
1638 ok( r == S_OK, "got %08x\n", r);
1639 ok( type == NODE_ELEMENT, "node not an element\n");
1642 r = IXMLDOMNode_get_baseName( element, &str );
1643 ok( r == S_OK, "get_baseName returned wrong code\n");
1644 ok( lstrcmpW(str,szlc) == 0, "basename was wrong\n");
1647 /* check if nodename is correct */
1648 r = IXMLDOMElement_get_nodeName( element, NULL );
1649 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1651 /* content doesn't matter here */
1653 r = IXMLDOMElement_get_nodeName( element, &str );
1654 ok ( r == S_OK, "get_nodeName wrong code\n");
1655 ok ( str != NULL, "str is null\n");
1656 ok( !lstrcmpW( str, szlc ), "incorrect nodeName\n");
1657 SysFreeString( str );
1659 str = SysAllocString( szNonExistentFile );
1661 V_I4(&var) = 0x1234;
1662 r = IXMLDOMElement_getAttribute( element, str, &var );
1663 ok( r == E_FAIL, "getAttribute ret %08x\n", r );
1664 ok( V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY, "vt = %x\n", V_VT(&var));
1667 r = IXMLDOMElement_getAttributeNode( element, str, NULL);
1668 ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1670 attr = (IXMLDOMAttribute*)0xdeadbeef;
1671 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1672 ok( r == E_FAIL, "getAttributeNode ret %08x\n", r );
1673 ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1674 SysFreeString( str );
1676 attr = (IXMLDOMAttribute*)0xdeadbeef;
1677 str = SysAllocString( szNonExistentAttribute );
1678 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1679 ok( r == S_FALSE, "getAttributeNode ret %08x\n", r );
1680 ok( attr == NULL, "getAttributeNode ret %p, expected NULL\n", attr );
1681 SysFreeString( str );
1683 str = SysAllocString( szdl );
1685 V_I4(&var) = 0x1234;
1686 r = IXMLDOMElement_getAttribute( element, str, &var );
1687 ok( r == S_OK, "getAttribute ret %08x\n", r );
1688 ok( V_VT(&var) == VT_BSTR, "vt = %x\n", V_VT(&var));
1689 ok( !lstrcmpW(V_BSTR(&var), szstr1), "wrong attr value\n");
1690 VariantClear( &var );
1692 r = IXMLDOMElement_getAttribute( element, NULL, &var );
1693 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1695 r = IXMLDOMElement_getAttribute( element, str, NULL );
1696 ok( r == E_INVALIDARG, "getAttribute ret %08x\n", r );
1699 r = IXMLDOMElement_getAttributeNode( element, str, &attr);
1700 ok( r == S_OK, "GetAttributeNode ret %08x\n", r );
1701 ok( attr != NULL, "getAttributeNode returned NULL\n" );
1704 r = IXMLDOMAttribute_get_parentNode( attr, NULL );
1705 ok( r == E_INVALIDARG, "Expected E_INVALIDARG, ret %08x\n", r );
1707 /* attribute doesn't have a parent in msxml interpretation */
1708 node = (IXMLDOMNode*)0xdeadbeef;
1709 r = IXMLDOMAttribute_get_parentNode( attr, &node );
1710 ok( r == S_FALSE, "Expected S_FALSE, ret %08x\n", r );
1711 ok( node == NULL, "Expected NULL, got %p\n", node );
1713 IXMLDOMAttribute_Release(attr);
1716 SysFreeString( str );
1718 r = IXMLDOMElement_get_attributes( element, &map );
1719 ok( r == S_OK, "get_attributes returned wrong code\n");
1720 ok( map != NULL, "should be attributes\n");
1722 EXPECT_CHILDREN(element);
1725 ok( FALSE, "no element\n");
1729 ISupportErrorInfo *support_error;
1730 r = IXMLDOMNamedNodeMap_QueryInterface( map, &IID_ISupportErrorInfo, (void**)&support_error );
1731 ok( r == S_OK, "ret %08x\n", r );
1733 r = ISupportErrorInfo_InterfaceSupportsErrorInfo( support_error, &IID_IXMLDOMNamedNodeMap );
1736 ok( r == S_OK, "ret %08x\n", r );
1738 ISupportErrorInfo_Release( support_error );
1740 str = SysAllocString( szdl );
1741 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1742 ok( r == S_OK, "getNamedItem returned wrong code\n");
1743 ok( node != NULL, "should be attributes\n");
1744 IXMLDOMNode_Release(node);
1745 SysFreeString( str );
1747 str = SysAllocString( szdl );
1748 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, NULL );
1749 ok( r == E_INVALIDARG, "getNamedItem should return E_INVALIDARG\n");
1750 SysFreeString( str );
1752 /* something that isn't in szComplete4 */
1753 str = SysAllocString( szOpen );
1754 node = (IXMLDOMNode *) 1;
1755 r = IXMLDOMNamedNodeMap_getNamedItem( map, str, &node );
1756 ok( r == S_FALSE, "getNamedItem found a node that wasn't there\n");
1757 ok( node == NULL, "getNamedItem should have returned NULL\n");
1758 SysFreeString( str );
1760 /* test indexed access of attributes */
1761 r = IXMLDOMNamedNodeMap_get_length( map, NULL );
1762 ok ( r == E_INVALIDARG, "get_length should return E_INVALIDARG\n");
1764 r = IXMLDOMNamedNodeMap_get_length( map, &count );
1765 ok ( r == S_OK, "get_length wrong code\n");
1766 ok ( count == 1, "get_length != 1\n");
1769 r = IXMLDOMNamedNodeMap_get_item( map, -1, &node);
1770 ok ( r == S_FALSE, "get_item (-1) wrong code\n");
1771 ok ( node == NULL, "there is no node\n");
1774 r = IXMLDOMNamedNodeMap_get_item( map, 1, &node);
1775 ok ( r == S_FALSE, "get_item (1) wrong code\n");
1776 ok ( node == NULL, "there is no attribute\n");
1779 r = IXMLDOMNamedNodeMap_get_item( map, 0, &node);
1780 ok ( r == S_OK, "get_item (0) wrong code\n");
1781 ok ( node != NULL, "should be attribute\n");
1783 r = IXMLDOMNode_get_nodeName( node, NULL );
1784 ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
1786 /* content doesn't matter here */
1788 r = IXMLDOMNode_get_nodeName( node, &str );
1789 ok ( r == S_OK, "get_nodeName wrong code\n");
1790 ok ( str != NULL, "str is null\n");
1791 ok( !lstrcmpW( str, szdl ), "incorrect node name\n");
1792 SysFreeString( str );
1793 IXMLDOMNode_Release( node );
1795 /* test sequential access of attributes */
1797 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1798 ok ( r == S_OK, "nextNode (first time) wrong code\n");
1799 ok ( node != NULL, "nextNode, should be attribute\n");
1800 IXMLDOMNode_Release( node );
1802 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1803 ok ( r != S_OK, "nextNode (second time) wrong code\n");
1804 ok ( node == NULL, "nextNode, there is no attribute\n");
1806 r = IXMLDOMNamedNodeMap_reset( map );
1807 ok ( r == S_OK, "reset should return S_OK\n");
1809 r = IXMLDOMNamedNodeMap_nextNode( map, &node );
1810 ok ( r == S_OK, "nextNode (third time) wrong code\n");
1811 ok ( node != NULL, "nextNode, should be attribute\n");
1814 ok( FALSE, "no map\n");
1818 type = NODE_INVALID;
1819 r = IXMLDOMNode_get_nodeType( node, &type);
1820 ok( r == S_OK, "getNamedItem returned wrong code\n");
1821 ok( type == NODE_ATTRIBUTE, "node not an attribute\n");
1824 r = IXMLDOMNode_get_baseName( node, NULL );
1825 ok( r == E_INVALIDARG, "get_baseName returned wrong code\n");
1828 r = IXMLDOMNode_get_baseName( node, &str );
1829 ok( r == S_OK, "get_baseName returned wrong code\n");
1830 ok( lstrcmpW(str,szdl) == 0, "basename was wrong\n");
1831 SysFreeString( str );
1833 r = IXMLDOMNode_get_nodeValue( node, &var );
1834 ok( r == S_OK, "returns %08x\n", r );
1835 ok( V_VT(&var) == VT_BSTR, "vt %x\n", V_VT(&var));
1836 ok( !lstrcmpW(V_BSTR(&var), szstr1), "nodeValue incorrect\n");
1839 r = IXMLDOMNode_get_childNodes( node, NULL );
1840 ok( r == E_INVALIDARG, "get_childNodes returned wrong code\n");
1842 r = IXMLDOMNode_get_childNodes( node, &list );
1843 ok( r == S_OK, "get_childNodes returned wrong code\n");
1847 r = IXMLDOMNodeList_nextNode( list, &next );
1848 ok( r == S_OK, "nextNode returned wrong code\n");
1851 ok( FALSE, "no childlist\n");
1855 EXPECT_NO_CHILDREN(next);
1857 type = NODE_INVALID;
1858 r = IXMLDOMNode_get_nodeType( next, &type);
1859 ok( r == S_OK, "getNamedItem returned wrong code\n");
1860 ok( type == NODE_TEXT, "node not text\n");
1863 r = IXMLDOMNode_get_baseName( next, &str );
1864 ok( r == S_FALSE, "get_baseName returned wrong code\n");
1865 ok( str == NULL, "basename was wrong\n");
1869 ok( FALSE, "no next\n");
1872 IXMLDOMNode_Release( next );
1875 IXMLDOMNodeList_Release( list );
1878 IXMLDOMNode_Release( node );
1881 ok( FALSE, "no node\n");
1885 IXMLDOMNamedNodeMap_Release( map );
1887 /* now traverse the tree from the root element */
1890 r = IXMLDOMNode_get_childNodes( element, &list );
1891 ok( r == S_OK, "get_childNodes returned wrong code\n");
1893 /* using get_item for child list doesn't advance the position */
1894 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
1895 expect_node(node, "E2.E2.D1");
1896 IXMLDOMNode_Release(node);
1897 ole_check(IXMLDOMNodeList_nextNode(list, &node));
1898 expect_node(node, "E1.E2.D1");
1899 IXMLDOMNode_Release(node);
1900 ole_check(IXMLDOMNodeList_reset(list));
1902 IXMLDOMNodeList_AddRef(list);
1903 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1");
1904 ole_check(IXMLDOMNodeList_reset(list));
1906 node = (void*)0xdeadbeef;
1907 str = SysAllocString(szdl);
1908 r = IXMLDOMNode_selectSingleNode( element, str, &node );
1910 ok( r == S_FALSE, "ret %08x\n", r );
1911 ok( node == NULL, "node %p\n", node );
1913 str = SysAllocString(szbs);
1914 r = IXMLDOMNode_selectSingleNode( element, str, &node );
1916 ok( r == S_OK, "ret %08x\n", r );
1917 r = IXMLDOMNode_Release( node );
1918 ok( r == 0, "ret %08x\n", r );
1921 ok( FALSE, "no element\n");
1925 r = IXMLDOMNodeList_get_item(list, 0, NULL);
1926 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1928 r = IXMLDOMNodeList_get_length(list, NULL);
1929 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1931 r = IXMLDOMNodeList_get_length( list, &count );
1932 ok( r == S_OK, "get_length returns %08x\n", r );
1933 ok( count == 4, "get_length got %d\n", count );
1935 r = IXMLDOMNodeList_nextNode(list, NULL);
1936 ok(r == E_INVALIDARG, "Exected E_INVALIDARG got %08x\n", r);
1938 r = IXMLDOMNodeList_nextNode( list, &node );
1939 ok( r == S_OK, "nextNode returned wrong code\n");
1942 ok( FALSE, "no list\n");
1946 type = NODE_INVALID;
1947 r = IXMLDOMNode_get_nodeType( node, &type);
1948 ok( r == S_OK, "getNamedItem returned wrong code\n");
1949 ok( type == NODE_ELEMENT, "node not text\n");
1952 ok( V_VT(&var) == VT_EMPTY, "variant init failed\n");
1953 r = IXMLDOMNode_get_nodeValue( node, &var );
1954 ok( r == S_FALSE, "nextNode returned wrong code\n");
1955 ok( V_VT(&var) == VT_NULL, "variant wasn't empty\n");
1956 ok( V_BSTR(&var) == NULL, "variant value wasn't null\n");
1958 r = IXMLDOMNode_hasChildNodes( node, NULL );
1959 ok( r == E_INVALIDARG, "hasChildNoes bad return\n");
1961 EXPECT_CHILDREN(node);
1964 r = IXMLDOMNode_get_baseName( node, &str );
1965 ok( r == S_OK, "get_baseName returned wrong code\n");
1966 ok( lstrcmpW(str,szbs) == 0, "basename was wrong\n");
1970 ok( FALSE, "no node\n");
1973 IXMLDOMNode_Release( node );
1975 IXMLDOMNodeList_Release( list );
1977 IXMLDOMElement_Release( element );
1980 str = SysAllocString( szComplete5 );
1981 r = IXMLDOMDocument_loadXML( doc, str, &b );
1982 ok( r == S_OK, "loadXML failed\n");
1983 ok( b == VARIANT_TRUE, "failed to load XML string\n");
1984 SysFreeString( str );
1986 EXPECT_CHILDREN(doc);
1988 r = IXMLDOMDocument_get_documentElement( doc, &element );
1989 ok( r == S_OK, "should be a document element\n");
1990 ok( element != NULL, "should be an element\n");
1994 static const WCHAR szSSearch[] = {'S',':','s','e','a','r','c','h',0};
1997 /* check if the tag is correct */
1998 r = IXMLDOMElement_get_tagName( element, &tag );
1999 ok( r == S_OK, "couldn't get tag name\n");
2000 ok( tag != NULL, "tag was null\n");
2001 ok( !lstrcmpW( tag, szSSearch ), "incorrect tag name\n");
2002 SysFreeString( tag );
2006 IXMLDOMElement_Release( element );
2007 ok(IXMLDOMDocument_Release( doc ) == 0, "document is not destroyed\n");
2010 static void test_refs(void)
2015 IXMLDOMDocument *doc;
2016 IXMLDOMElement *element = NULL;
2017 IXMLDOMNode *node = NULL, *node2;
2018 IXMLDOMNodeList *node_list = NULL;
2020 IUnknown *unk, *unk2;
2022 doc = create_document(&IID_IXMLDOMDocument);
2026 ref = IXMLDOMDocument_Release(doc);
2027 ok( ref == 0, "ref %d\n", ref);
2029 doc = create_document(&IID_IXMLDOMDocument);
2032 str = SysAllocString( szComplete4 );
2033 r = IXMLDOMDocument_loadXML( doc, str, &b );
2034 ok( r == S_OK, "loadXML failed\n");
2035 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2036 SysFreeString( str );
2039 IXMLDOMDocument_AddRef( doc );
2041 IXMLDOMDocument_AddRef( doc );
2044 IXMLDOMDocument_Release( doc );
2045 IXMLDOMDocument_Release( doc );
2047 r = IXMLDOMDocument_get_documentElement( doc, &element );
2048 ok( r == S_OK, "should be a document element\n");
2049 ok( element != NULL, "should be an element\n");
2052 todo_wine EXPECT_REF(element, 2);
2054 IXMLDOMElement_AddRef(element);
2055 todo_wine EXPECT_REF(element, 3);
2056 IXMLDOMElement_Release(element);
2058 r = IXMLDOMElement_get_childNodes( element, &node_list );
2059 ok( r == S_OK, "rets %08x\n", r);
2061 todo_wine EXPECT_REF(element, 2);
2062 EXPECT_REF(node_list, 1);
2064 IXMLDOMNodeList_get_item( node_list, 0, &node );
2065 ok( r == S_OK, "rets %08x\n", r);
2066 EXPECT_REF(node_list, 1);
2067 EXPECT_REF(node, 1);
2069 IXMLDOMNodeList_get_item( node_list, 0, &node2 );
2070 ok( r == S_OK, "rets %08x\n", r);
2071 EXPECT_REF(node_list, 1);
2072 EXPECT_REF(node2, 1);
2074 ref = IXMLDOMNode_Release( node );
2075 ok( ref == 0, "ref %d\n", ref );
2076 ref = IXMLDOMNode_Release( node2 );
2077 ok( ref == 0, "ref %d\n", ref );
2079 ref = IXMLDOMNodeList_Release( node_list );
2080 ok( ref == 0, "ref %d\n", ref );
2082 ok( node != node2, "node %p node2 %p\n", node, node2 );
2084 ref = IXMLDOMDocument_Release( doc );
2085 ok( ref == 0, "ref %d\n", ref );
2087 todo_wine EXPECT_REF(element, 2);
2089 /* IUnknown must be unique however we obtain it */
2090 r = IXMLDOMElement_QueryInterface( element, &IID_IUnknown, (void**)&unk );
2091 ok( r == S_OK, "rets %08x\n", r );
2092 EXPECT_REF(element, 2);
2093 r = IXMLDOMElement_QueryInterface( element, &IID_IXMLDOMNode, (void**)&node );
2094 ok( r == S_OK, "rets %08x\n", r );
2095 todo_wine EXPECT_REF(element, 2);
2096 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk2 );
2097 ok( r == S_OK, "rets %08x\n", r );
2098 todo_wine EXPECT_REF(element, 2);
2099 ok( unk == unk2, "unk %p unk2 %p\n", unk, unk2 );
2100 todo_wine ok( element != (void*)node, "node %p element %p\n", node, element );
2102 IUnknown_Release( unk2 );
2103 IUnknown_Release( unk );
2104 IXMLDOMNode_Release( node );
2105 todo_wine EXPECT_REF(element, 2);
2107 IXMLDOMElement_Release( element );
2110 static void test_create(void)
2112 static const WCHAR szOne[] = {'1',0};
2113 static const WCHAR szOneGarbage[] = {'1','G','a','r','b','a','g','e',0};
2117 IXMLDOMDocument *doc;
2118 IXMLDOMElement *element;
2119 IXMLDOMComment *comment;
2121 IXMLDOMCDATASection *cdata;
2122 IXMLDOMNode *root, *node, *child;
2123 IXMLDOMNamedNodeMap *attr_map;
2128 doc = create_document(&IID_IXMLDOMDocument);
2133 /* types not supported for creation */
2135 V_I1(&var) = NODE_DOCUMENT;
2136 node = (IXMLDOMNode*)0x1;
2137 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2138 ok( r == E_INVALIDARG, "returns %08x\n", r );
2139 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2142 V_I1(&var) = NODE_DOCUMENT_TYPE;
2143 node = (IXMLDOMNode*)0x1;
2144 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2145 ok( r == E_INVALIDARG, "returns %08x\n", r );
2146 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2149 V_I1(&var) = NODE_ENTITY;
2150 node = (IXMLDOMNode*)0x1;
2151 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2152 ok( r == E_INVALIDARG, "returns %08x\n", r );
2153 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2156 V_I1(&var) = NODE_NOTATION;
2157 node = (IXMLDOMNode*)0x1;
2158 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2159 ok( r == E_INVALIDARG, "returns %08x\n", r );
2160 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2164 V_I1(&var) = NODE_COMMENT;
2166 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2167 ok( r == S_OK, "returns %08x\n", r );
2168 ok( node != NULL, "\n");
2170 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2171 ok( r == S_OK, "returns %08x\n", r );
2172 IXMLDOMNode_Release(node);
2175 r = IXMLDOMComment_get_data(comment, &str);
2176 ok( r == S_OK, "returns %08x\n", r );
2177 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2178 IXMLDOMComment_Release(comment);
2181 node = (IXMLDOMNode*)0x1;
2182 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2183 ok( r == S_OK, "returns %08x\n", r );
2185 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2186 ok( r == S_OK, "returns %08x\n", r );
2187 IXMLDOMNode_Release(node);
2190 r = IXMLDOMComment_get_data(comment, &str);
2191 ok( r == S_OK, "returns %08x\n", r );
2192 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2193 IXMLDOMComment_Release(comment);
2196 node = (IXMLDOMNode*)0x1;
2197 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2198 ok( r == S_OK, "returns %08x\n", r );
2200 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)&comment);
2201 ok( r == S_OK, "returns %08x\n", r );
2202 IXMLDOMNode_Release(node);
2205 r = IXMLDOMComment_get_data(comment, &str);
2206 ok( r == S_OK, "returns %08x\n", r );
2207 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2208 IXMLDOMComment_Release(comment);
2213 V_I1(&var) = NODE_TEXT;
2215 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2216 ok( r == S_OK, "returns %08x\n", r );
2217 ok( node != NULL, "\n");
2219 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2220 ok( r == S_OK, "returns %08x\n", r );
2221 IXMLDOMNode_Release(node);
2224 r = IXMLDOMText_get_data(text, &str);
2225 ok( r == S_OK, "returns %08x\n", r );
2226 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2227 IXMLDOMText_Release(text);
2230 node = (IXMLDOMNode*)0x1;
2231 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2232 ok( r == S_OK, "returns %08x\n", r );
2234 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2235 ok( r == S_OK, "returns %08x\n", r );
2236 IXMLDOMNode_Release(node);
2239 r = IXMLDOMText_get_data(text, &str);
2240 ok( r == S_OK, "returns %08x\n", r );
2241 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2242 IXMLDOMText_Release(text);
2245 node = (IXMLDOMNode*)0x1;
2246 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2247 ok( r == S_OK, "returns %08x\n", r );
2249 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)&text);
2250 ok( r == S_OK, "returns %08x\n", r );
2251 IXMLDOMNode_Release(node);
2254 r = IXMLDOMText_get_data(text, &str);
2255 ok( r == S_OK, "returns %08x\n", r );
2256 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2257 IXMLDOMText_Release(text);
2260 /* NODE_CDATA_SECTION */
2262 V_I1(&var) = NODE_CDATA_SECTION;
2264 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2265 ok( r == S_OK, "returns %08x\n", r );
2266 ok( node != NULL, "\n");
2268 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2269 ok( r == S_OK, "returns %08x\n", r );
2270 IXMLDOMNode_Release(node);
2273 r = IXMLDOMCDATASection_get_data(cdata, &str);
2274 ok( r == S_OK, "returns %08x\n", r );
2275 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2276 IXMLDOMCDATASection_Release(cdata);
2279 node = (IXMLDOMNode*)0x1;
2280 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2281 ok( r == S_OK, "returns %08x\n", r );
2283 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2284 ok( r == S_OK, "returns %08x\n", r );
2285 IXMLDOMNode_Release(node);
2288 r = IXMLDOMCDATASection_get_data(cdata, &str);
2289 ok( r == S_OK, "returns %08x\n", r );
2290 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2291 IXMLDOMCDATASection_Release(cdata);
2294 node = (IXMLDOMNode*)0x1;
2295 r = IXMLDOMDocument_createNode( doc, var, _bstr_("blah"), NULL, &node );
2296 ok( r == S_OK, "returns %08x\n", r );
2298 r = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)&cdata);
2299 ok( r == S_OK, "returns %08x\n", r );
2300 IXMLDOMNode_Release(node);
2303 r = IXMLDOMCDATASection_get_data(cdata, &str);
2304 ok( r == S_OK, "returns %08x\n", r );
2305 ok( str && SysStringLen(str) == 0, "expected empty comment, %p\n", str);
2306 IXMLDOMCDATASection_Release(cdata);
2309 /* NODE_ATTRIBUTE */
2311 V_I1(&var) = NODE_ATTRIBUTE;
2312 node = (IXMLDOMNode*)0x1;
2313 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2314 ok( r == E_FAIL, "returns %08x\n", r );
2315 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2318 V_I1(&var) = NODE_ATTRIBUTE;
2319 node = (IXMLDOMNode*)0x1;
2320 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2321 ok( r == E_FAIL, "returns %08x\n", r );
2322 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2325 V_I1(&var) = NODE_ATTRIBUTE;
2326 str = SysAllocString( szlc );
2327 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2328 ok( r == S_OK, "returns %08x\n", r );
2329 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2332 /* a name is required for attribute, try a BSTR with first null wchar */
2334 V_I1(&var) = NODE_ATTRIBUTE;
2335 str = SysAllocString( szstr1 );
2337 node = (IXMLDOMNode*)0x1;
2338 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2339 ok( r == E_FAIL, "returns %08x\n", r );
2340 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2343 /* NODE_PROCESSING_INSTRUCTION */
2345 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2346 node = (IXMLDOMNode*)0x1;
2347 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2348 ok( r == E_FAIL, "returns %08x\n", r );
2349 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2352 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2353 node = (IXMLDOMNode*)0x1;
2354 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2355 ok( r == E_FAIL, "returns %08x\n", r );
2356 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2359 V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
2360 r = IXMLDOMDocument_createNode( doc, var, _bstr_("pi"), NULL, NULL );
2361 ok( r == E_INVALIDARG, "returns %08x\n", r );
2363 /* NODE_ENTITY_REFERENCE */
2365 V_I1(&var) = NODE_ENTITY_REFERENCE;
2366 node = (IXMLDOMNode*)0x1;
2367 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2368 ok( r == E_FAIL, "returns %08x\n", r );
2369 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2372 V_I1(&var) = NODE_ENTITY_REFERENCE;
2373 node = (IXMLDOMNode*)0x1;
2374 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2375 ok( r == E_FAIL, "returns %08x\n", r );
2376 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2380 V_I1(&var) = NODE_ELEMENT;
2381 node = (IXMLDOMNode*)0x1;
2382 r = IXMLDOMDocument_createNode( doc, var, NULL, NULL, &node );
2383 ok( r == E_FAIL, "returns %08x\n", r );
2384 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2387 V_I1(&var) = NODE_ELEMENT;
2388 node = (IXMLDOMNode*)0x1;
2389 r = IXMLDOMDocument_createNode( doc, var, _bstr_(""), NULL, &node );
2390 ok( r == E_FAIL, "returns %08x\n", r );
2391 ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
2394 V_I1(&var) = NODE_ELEMENT;
2395 str = SysAllocString( szlc );
2396 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2397 ok( r == S_OK, "returns %08x\n", r );
2398 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2401 V_I1(&var) = NODE_ELEMENT;
2402 r = IXMLDOMDocument_createNode( doc, var, str, NULL, NULL );
2403 ok( r == E_INVALIDARG, "returns %08x\n", r );
2406 V_R4(&var) = NODE_ELEMENT;
2407 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2408 ok( r == S_OK, "returns %08x\n", r );
2409 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2411 V_VT(&var) = VT_BSTR;
2412 V_BSTR(&var) = SysAllocString( szOne );
2413 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2414 ok( r == S_OK, "returns %08x\n", r );
2415 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2418 V_VT(&var) = VT_BSTR;
2419 V_BSTR(&var) = SysAllocString( szOneGarbage );
2420 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2421 ok( r == E_INVALIDARG, "returns %08x\n", r );
2422 if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
2426 V_I4(&var) = NODE_ELEMENT;
2427 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2428 ok( r == S_OK, "returns %08x\n", r );
2431 r = IXMLDOMDocument_appendChild( doc, node, &root );
2432 ok( r == S_OK, "returns %08x\n", r );
2433 ok( node == root, "%p %p\n", node, root );
2436 EXPECT_REF(node, 2);
2438 ref = IXMLDOMNode_Release( node );
2439 ok(ref == 1, "ref %d\n", ref);
2440 SysFreeString( str );
2443 V_I4(&var) = NODE_ELEMENT;
2444 str = SysAllocString( szbs );
2445 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2446 ok( r == S_OK, "returns %08x\n", r );
2447 SysFreeString( str );
2449 EXPECT_REF(node, 1);
2451 r = IXMLDOMNode_QueryInterface( node, &IID_IUnknown, (void**)&unk );
2452 ok( r == S_OK, "returns %08x\n", r );
2456 V_VT(&var) = VT_EMPTY;
2458 r = IXMLDOMNode_insertBefore( root, (IXMLDOMNode*)unk, var, &child );
2459 ok( r == S_OK, "returns %08x\n", r );
2460 ok( unk == (IUnknown*)child, "%p %p\n", unk, child );
2462 todo_wine EXPECT_REF(unk, 4);
2464 IXMLDOMNode_Release( child );
2465 IUnknown_Release( unk );
2467 V_VT(&var) = VT_NULL;
2468 V_DISPATCH(&var) = (IDispatch*)node;
2469 r = IXMLDOMNode_insertBefore( root, node, var, &child );
2470 ok( r == S_OK, "returns %08x\n", r );
2471 ok( node == child, "%p %p\n", node, child );
2472 IXMLDOMNode_Release( child );
2474 V_VT(&var) = VT_NULL;
2475 V_DISPATCH(&var) = (IDispatch*)node;
2476 r = IXMLDOMNode_insertBefore( root, node, var, NULL );
2477 ok( r == S_OK, "returns %08x\n", r );
2478 IXMLDOMNode_Release( node );
2480 r = IXMLDOMNode_QueryInterface( root, &IID_IXMLDOMElement, (void**)&element );
2481 ok( r == S_OK, "returns %08x\n", r );
2483 r = IXMLDOMElement_get_attributes( element, &attr_map );
2484 ok( r == S_OK, "returns %08x\n", r );
2485 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2486 ok( r == S_OK, "returns %08x\n", r );
2487 ok( num == 0, "num %d\n", num );
2488 IXMLDOMNamedNodeMap_Release( attr_map );
2490 V_VT(&var) = VT_BSTR;
2491 V_BSTR(&var) = SysAllocString( szstr1 );
2492 name = SysAllocString( szdl );
2493 r = IXMLDOMElement_setAttribute( element, name, var );
2494 ok( r == S_OK, "returns %08x\n", r );
2495 r = IXMLDOMElement_get_attributes( element, &attr_map );
2496 ok( r == S_OK, "returns %08x\n", r );
2497 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2498 ok( r == S_OK, "returns %08x\n", r );
2499 ok( num == 1, "num %d\n", num );
2500 IXMLDOMNamedNodeMap_Release( attr_map );
2503 V_VT(&var) = VT_BSTR;
2504 V_BSTR(&var) = SysAllocString( szstr2 );
2505 r = IXMLDOMElement_setAttribute( element, name, var );
2506 ok( r == S_OK, "returns %08x\n", r );
2507 r = IXMLDOMElement_get_attributes( element, &attr_map );
2508 ok( r == S_OK, "returns %08x\n", r );
2509 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2510 ok( r == S_OK, "returns %08x\n", r );
2511 ok( num == 1, "num %d\n", num );
2512 IXMLDOMNamedNodeMap_Release( attr_map );
2514 r = IXMLDOMElement_getAttribute( element, name, &var );
2515 ok( r == S_OK, "returns %08x\n", r );
2516 ok( !lstrcmpW(V_BSTR(&var), szstr2), "wrong attr value\n");
2518 SysFreeString(name);
2520 V_VT(&var) = VT_BSTR;
2521 V_BSTR(&var) = SysAllocString( szstr1 );
2522 name = SysAllocString( szlc );
2523 r = IXMLDOMElement_setAttribute( element, name, var );
2524 ok( r == S_OK, "returns %08x\n", r );
2525 r = IXMLDOMElement_get_attributes( element, &attr_map );
2526 ok( r == S_OK, "returns %08x\n", r );
2527 r = IXMLDOMNamedNodeMap_get_length( attr_map, &num );
2528 ok( r == S_OK, "returns %08x\n", r );
2529 ok( num == 2, "num %d\n", num );
2530 IXMLDOMNamedNodeMap_Release( attr_map );
2532 SysFreeString(name);
2536 name = SysAllocString( szbs );
2537 r = IXMLDOMElement_setAttribute( element, name, var );
2538 ok( r == S_OK, "returns %08x\n", r );
2540 r = IXMLDOMElement_getAttribute( element, name, &var );
2541 ok( r == S_OK, "returns %08x\n", r );
2542 ok( V_VT(&var) == VT_BSTR, "variant type %x\n", V_VT(&var));
2544 SysFreeString(name);
2546 /* Create an Attribute */
2548 V_I4(&var) = NODE_ATTRIBUTE;
2549 str = SysAllocString( szAttribute );
2550 r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
2551 ok( r == S_OK, "returns %08x\n", r );
2552 ok( node != NULL, "node was null\n");
2555 IXMLDOMElement_Release( element );
2556 IXMLDOMNode_Release( root );
2557 IXMLDOMDocument_Release( doc );
2560 static void test_getElementsByTagName(void)
2562 IXMLDOMNodeList *node_list;
2563 IXMLDOMDocument *doc;
2564 IXMLDOMElement *elem;
2571 doc = create_document(&IID_IXMLDOMDocument);
2574 str = SysAllocString( szComplete4 );
2575 r = IXMLDOMDocument_loadXML( doc, str, &b );
2576 ok( r == S_OK, "loadXML failed\n");
2577 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2578 SysFreeString( str );
2580 str = SysAllocString( szstar );
2582 /* null arguments cases */
2583 r = IXMLDOMDocument_getElementsByTagName(doc, NULL, &node_list);
2584 ok( r == E_INVALIDARG, "ret %08x\n", r );
2585 r = IXMLDOMDocument_getElementsByTagName(doc, str, NULL);
2586 ok( r == E_INVALIDARG, "ret %08x\n", r );
2588 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2589 ok( r == S_OK, "ret %08x\n", r );
2590 r = IXMLDOMNodeList_get_length( node_list, &len );
2591 ok( r == S_OK, "ret %08x\n", r );
2592 ok( len == 6, "len %d\n", len );
2594 test_disp((IUnknown*)node_list);
2596 IXMLDOMNodeList_Release( node_list );
2597 SysFreeString( str );
2599 /* broken query BSTR */
2600 memcpy(&buff[2], szstar, sizeof(szstar));
2601 /* just a big length */
2602 *(DWORD*)buff = 0xf0f0;
2603 r = IXMLDOMDocument_getElementsByTagName(doc, &buff[2], &node_list);
2604 ok( r == S_OK, "ret %08x\n", r );
2605 r = IXMLDOMNodeList_get_length( node_list, &len );
2606 ok( r == S_OK, "ret %08x\n", r );
2607 ok( len == 6, "len %d\n", len );
2608 IXMLDOMNodeList_Release( node_list );
2610 str = SysAllocString( szbs );
2611 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2612 ok( r == S_OK, "ret %08x\n", r );
2613 r = IXMLDOMNodeList_get_length( node_list, &len );
2614 ok( r == S_OK, "ret %08x\n", r );
2615 ok( len == 1, "len %d\n", len );
2616 IXMLDOMNodeList_Release( node_list );
2617 SysFreeString( str );
2619 str = SysAllocString( szdl );
2620 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2621 ok( r == S_OK, "ret %08x\n", r );
2622 r = IXMLDOMNodeList_get_length( node_list, &len );
2623 ok( r == S_OK, "ret %08x\n", r );
2624 ok( len == 0, "len %d\n", len );
2625 IXMLDOMNodeList_Release( node_list );
2626 SysFreeString( str );
2628 str = SysAllocString( szstr1 );
2629 r = IXMLDOMDocument_getElementsByTagName(doc, str, &node_list);
2630 ok( r == S_OK, "ret %08x\n", r );
2631 r = IXMLDOMNodeList_get_length( node_list, &len );
2632 ok( r == S_OK, "ret %08x\n", r );
2633 ok( len == 0, "len %d\n", len );
2634 IXMLDOMNodeList_Release( node_list );
2635 SysFreeString( str );
2637 /* test for element */
2638 r = IXMLDOMDocument_get_documentElement(doc, &elem);
2639 ok( r == S_OK, "ret %08x\n", r );
2641 str = SysAllocString( szstar );
2643 /* null arguments cases */
2644 r = IXMLDOMElement_getElementsByTagName(elem, NULL, &node_list);
2645 ok( r == E_INVALIDARG, "ret %08x\n", r );
2646 r = IXMLDOMElement_getElementsByTagName(elem, str, NULL);
2647 ok( r == E_INVALIDARG, "ret %08x\n", r );
2649 r = IXMLDOMElement_getElementsByTagName(elem, str, &node_list);
2650 ok( r == S_OK, "ret %08x\n", r );
2651 r = IXMLDOMNodeList_get_length( node_list, &len );
2652 ok( r == S_OK, "ret %08x\n", r );
2653 ok( len == 5, "len %d\n", len );
2654 expect_list_and_release(node_list, "E1.E2.D1 E2.E2.D1 E3.E2.D1 E4.E2.D1 E1.E4.E2.D1");
2655 SysFreeString( str );
2657 /* broken query BSTR */
2658 memcpy(&buff[2], szstar, sizeof(szstar));
2659 /* just a big length */
2660 *(DWORD*)buff = 0xf0f0;
2661 r = IXMLDOMElement_getElementsByTagName(elem, &buff[2], &node_list);
2662 ok( r == S_OK, "ret %08x\n", r );
2663 r = IXMLDOMNodeList_get_length( node_list, &len );
2664 ok( r == S_OK, "ret %08x\n", r );
2665 ok( len == 5, "len %d\n", len );
2666 IXMLDOMNodeList_Release( node_list );
2668 IXMLDOMElement_Release(elem);
2670 IXMLDOMDocument_Release( doc );
2673 static void test_get_text(void)
2678 IXMLDOMDocument *doc;
2679 IXMLDOMNode *node, *node2, *node3;
2680 IXMLDOMNode *nodeRoot;
2681 IXMLDOMNodeList *node_list;
2682 IXMLDOMNamedNodeMap *node_map;
2685 doc = create_document(&IID_IXMLDOMDocument);
2688 str = SysAllocString( szComplete4 );
2689 r = IXMLDOMDocument_loadXML( doc, str, &b );
2690 ok( r == S_OK, "loadXML failed\n");
2691 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2692 SysFreeString( str );
2694 str = SysAllocString( szbs );
2695 r = IXMLDOMDocument_getElementsByTagName( doc, str, &node_list );
2696 ok( r == S_OK, "ret %08x\n", r );
2699 /* Test to get all child node text. */
2700 r = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&nodeRoot);
2701 ok( r == S_OK, "ret %08x\n", r );
2704 r = IXMLDOMNode_get_text( nodeRoot, &str );
2705 ok( r == S_OK, "ret %08x\n", r );
2706 ok( compareIgnoreReturns(str, _bstr_("fn1.txt\n\n fn2.txt \n\nf1\n")), "wrong get_text: %s\n", wine_dbgstr_w(str));
2709 IXMLDOMNode_Release(nodeRoot);
2712 r = IXMLDOMNodeList_get_length( node_list, NULL );
2713 ok( r == E_INVALIDARG, "ret %08x\n", r );
2715 r = IXMLDOMNodeList_get_length( node_list, &len );
2716 ok( r == S_OK, "ret %08x\n", r );
2717 ok( len == 1, "expect 1 got %d\n", len );
2719 r = IXMLDOMNodeList_get_item( node_list, 0, NULL );
2720 ok( r == E_INVALIDARG, "ret %08x\n", r );
2722 r = IXMLDOMNodeList_nextNode( node_list, NULL );
2723 ok( r == E_INVALIDARG, "ret %08x\n", r );
2725 r = IXMLDOMNodeList_get_item( node_list, 0, &node );
2726 ok( r == S_OK, "ret %08x\n", r );
2727 IXMLDOMNodeList_Release( node_list );
2729 /* Invalid output parameter*/
2730 r = IXMLDOMNode_get_text( node, NULL );
2731 ok( r == E_INVALIDARG, "ret %08x\n", r );
2733 r = IXMLDOMNode_get_text( node, &str );
2734 ok( r == S_OK, "ret %08x\n", r );
2735 ok( !memcmp(str, szfn1_txt, lstrlenW(szfn1_txt) ), "wrong string\n" );
2738 r = IXMLDOMNode_get_attributes( node, &node_map );
2739 ok( r == S_OK, "ret %08x\n", r );
2741 str = SysAllocString( szvr );
2742 r = IXMLDOMNamedNodeMap_getNamedItem( node_map, str, &node2 );
2743 ok( r == S_OK, "ret %08x\n", r );
2746 r = IXMLDOMNode_get_text( node2, &str );
2747 ok( r == S_OK, "ret %08x\n", r );
2748 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2751 r = IXMLDOMNode_get_firstChild( node2, &node3 );
2752 ok( r == S_OK, "ret %08x\n", r );
2754 r = IXMLDOMNode_get_text( node3, &str );
2755 ok( r == S_OK, "ret %08x\n", r );
2756 ok( !memcmp(str, szstr2, sizeof(szstr2)), "wrong string\n" );
2760 IXMLDOMNode_Release( node3 );
2761 IXMLDOMNode_Release( node2 );
2762 IXMLDOMNamedNodeMap_Release( node_map );
2763 IXMLDOMNode_Release( node );
2764 IXMLDOMDocument_Release( doc );
2767 static void test_get_childNodes(void)
2772 IXMLDOMDocument *doc;
2773 IXMLDOMElement *element;
2774 IXMLDOMNode *node, *node2;
2775 IXMLDOMNodeList *node_list, *node_list2;
2778 doc = create_document(&IID_IXMLDOMDocument);
2781 str = SysAllocString( szComplete4 );
2782 r = IXMLDOMDocument_loadXML( doc, str, &b );
2783 ok( r == S_OK, "loadXML failed\n");
2784 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2785 SysFreeString( str );
2787 r = IXMLDOMDocument_get_documentElement( doc, &element );
2788 ok( r == S_OK, "ret %08x\n", r);
2790 r = IXMLDOMElement_get_childNodes( element, &node_list );
2791 ok( r == S_OK, "ret %08x\n", r);
2793 r = IXMLDOMNodeList_get_length( node_list, &len );
2794 ok( r == S_OK, "ret %08x\n", r);
2795 ok( len == 4, "len %d\n", len);
2797 r = IXMLDOMNodeList_get_item( node_list, 2, &node );
2798 ok( r == S_OK, "ret %08x\n", r);
2800 r = IXMLDOMNode_get_childNodes( node, &node_list2 );
2801 ok( r == S_OK, "ret %08x\n", r);
2803 r = IXMLDOMNodeList_get_length( node_list2, &len );
2804 ok( r == S_OK, "ret %08x\n", r);
2805 ok( len == 0, "len %d\n", len);
2807 r = IXMLDOMNodeList_get_item( node_list2, 0, &node2);
2808 ok( r == S_FALSE, "ret %08x\n", r);
2810 IXMLDOMNodeList_Release( node_list2 );
2811 IXMLDOMNode_Release( node );
2812 IXMLDOMNodeList_Release( node_list );
2813 IXMLDOMElement_Release( element );
2814 IXMLDOMDocument_Release( doc );
2817 static void test_get_firstChild(void)
2819 static WCHAR xmlW[] = {'x','m','l',0};
2820 IXMLDOMDocument *doc;
2826 doc = create_document(&IID_IXMLDOMDocument);
2829 str = SysAllocString( szComplete4 );
2830 r = IXMLDOMDocument_loadXML( doc, str, &b );
2831 ok( r == S_OK, "loadXML failed\n");
2832 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2833 SysFreeString( str );
2835 r = IXMLDOMDocument_get_firstChild( doc, &node );
2836 ok( r == S_OK, "ret %08x\n", r);
2838 r = IXMLDOMNode_get_nodeName( node, &str );
2839 ok( r == S_OK, "ret %08x\n", r);
2841 ok(memcmp(str, xmlW, sizeof(xmlW)) == 0, "expected \"xml\" node name\n");
2844 IXMLDOMNode_Release( node );
2845 IXMLDOMDocument_Release( doc );
2848 static void test_get_lastChild(void)
2850 static WCHAR lcW[] = {'l','c',0};
2851 static WCHAR foW[] = {'f','o',0};
2852 IXMLDOMDocument *doc;
2853 IXMLDOMNode *node, *child;
2858 doc = create_document(&IID_IXMLDOMDocument);
2861 str = SysAllocString( szComplete4 );
2862 r = IXMLDOMDocument_loadXML( doc, str, &b );
2863 ok( r == S_OK, "loadXML failed\n");
2864 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2865 SysFreeString( str );
2867 r = IXMLDOMDocument_get_lastChild( doc, &node );
2868 ok( r == S_OK, "ret %08x\n", r);
2870 r = IXMLDOMNode_get_nodeName( node, &str );
2871 ok( r == S_OK, "ret %08x\n", r);
2873 ok(memcmp(str, lcW, sizeof(lcW)) == 0, "expected \"lc\" node name\n");
2876 r = IXMLDOMNode_get_lastChild( node, &child );
2877 ok( r == S_OK, "ret %08x\n", r);
2879 r = IXMLDOMNode_get_nodeName( child, &str );
2880 ok( r == S_OK, "ret %08x\n", r);
2882 ok(memcmp(str, foW, sizeof(foW)) == 0, "expected \"fo\" node name\n");
2885 IXMLDOMNode_Release( child );
2886 IXMLDOMNode_Release( node );
2887 IXMLDOMDocument_Release( doc );
2890 static void test_removeChild(void)
2895 IXMLDOMDocument *doc;
2896 IXMLDOMElement *element, *lc_element;
2897 IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
2898 IXMLDOMNodeList *root_list, *fo_list;
2900 doc = create_document(&IID_IXMLDOMDocument);
2903 str = SysAllocString( szComplete4 );
2904 r = IXMLDOMDocument_loadXML( doc, str, &b );
2905 ok( r == S_OK, "loadXML failed\n");
2906 ok( b == VARIANT_TRUE, "failed to load XML string\n");
2907 SysFreeString( str );
2909 r = IXMLDOMDocument_get_documentElement( doc, &element );
2910 ok( r == S_OK, "ret %08x\n", r);
2911 todo_wine EXPECT_REF(element, 2);
2913 r = IXMLDOMElement_get_childNodes( element, &root_list );
2914 ok( r == S_OK, "ret %08x\n", r);
2915 EXPECT_REF(root_list, 1);
2917 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
2918 ok( r == S_OK, "ret %08x\n", r);
2919 EXPECT_REF(fo_node, 1);
2921 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
2922 ok( r == S_OK, "ret %08x\n", r);
2923 EXPECT_REF(fo_list, 1);
2925 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
2926 ok( r == S_OK, "ret %08x\n", r);
2927 EXPECT_REF(ba_node, 1);
2929 /* invalid parameter: NULL ptr */
2930 removed_node = (void*)0xdeadbeef;
2931 r = IXMLDOMElement_removeChild( element, NULL, &removed_node );
2932 ok( r == E_INVALIDARG, "ret %08x\n", r );
2933 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
2935 /* ba_node is a descendant of element, but not a direct child. */
2936 removed_node = (void*)0xdeadbeef;
2937 EXPECT_REF(ba_node, 1);
2938 EXPECT_CHILDREN(fo_node);
2939 r = IXMLDOMElement_removeChild( element, ba_node, &removed_node );
2940 ok( r == E_INVALIDARG, "ret %08x\n", r );
2941 ok( removed_node == NULL, "%p\n", removed_node );
2942 EXPECT_REF(ba_node, 1);
2943 EXPECT_CHILDREN(fo_node);
2945 EXPECT_REF(ba_node, 1);
2946 EXPECT_REF(fo_node, 1);
2947 r = IXMLDOMElement_removeChild( element, fo_node, &removed_node );
2948 ok( r == S_OK, "ret %08x\n", r);
2949 ok( fo_node == removed_node, "node %p node2 %p\n", fo_node, removed_node );
2950 EXPECT_REF(fo_node, 2);
2951 EXPECT_REF(ba_node, 1);
2953 /* try removing already removed child */
2954 temp_node = (void*)0xdeadbeef;
2955 r = IXMLDOMElement_removeChild( element, fo_node, &temp_node );
2956 ok( r == E_INVALIDARG, "ret %08x\n", r);
2957 ok( temp_node == NULL, "%p\n", temp_node );
2958 IXMLDOMNode_Release( fo_node );
2960 /* the removed node has no parent anymore */
2961 r = IXMLDOMNode_get_parentNode( removed_node, &temp_node );
2962 ok( r == S_FALSE, "ret %08x\n", r);
2963 ok( temp_node == NULL, "%p\n", temp_node );
2965 IXMLDOMNode_Release( removed_node );
2966 IXMLDOMNode_Release( ba_node );
2967 IXMLDOMNodeList_Release( fo_list );
2969 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
2970 ok( r == S_OK, "ret %08x\n", r);
2972 r = IXMLDOMElement_QueryInterface( lc_node, &IID_IXMLDOMElement, (void**)&lc_element );
2973 ok( r == S_OK, "ret %08x\n", r);
2975 /* MS quirk: passing wrong interface pointer works, too */
2976 r = IXMLDOMElement_removeChild( element, (IXMLDOMNode*)lc_element, NULL );
2977 ok( r == S_OK, "ret %08x\n", r);
2978 IXMLDOMElement_Release( lc_element );
2980 temp_node = (void*)0xdeadbeef;
2981 r = IXMLDOMNode_get_parentNode( lc_node, &temp_node );
2982 ok( r == S_FALSE, "ret %08x\n", r);
2983 ok( temp_node == NULL, "%p\n", temp_node );
2985 IXMLDOMNode_Release( lc_node );
2986 IXMLDOMNodeList_Release( root_list );
2987 IXMLDOMElement_Release( element );
2988 IXMLDOMDocument_Release( doc );
2991 static void test_replaceChild(void)
2996 IXMLDOMDocument *doc;
2997 IXMLDOMElement *element, *ba_element;
2998 IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node;
2999 IXMLDOMNodeList *root_list, *fo_list;
3000 IUnknown * unk1, *unk2;
3003 doc = create_document(&IID_IXMLDOMDocument);
3006 str = SysAllocString( szComplete4 );
3007 r = IXMLDOMDocument_loadXML( doc, str, &b );
3008 ok( r == S_OK, "loadXML failed\n");
3009 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3010 SysFreeString( str );
3012 r = IXMLDOMDocument_get_documentElement( doc, &element );
3013 ok( r == S_OK, "ret %08x\n", r);
3015 r = IXMLDOMElement_get_childNodes( element, &root_list );
3016 ok( r == S_OK, "ret %08x\n", r);
3018 r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node );
3019 ok( r == S_OK, "ret %08x\n", r);
3021 r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node );
3022 ok( r == S_OK, "ret %08x\n", r);
3024 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3025 ok( r == S_OK, "ret %08x\n", r);
3027 r = IXMLDOMNodeList_get_item( fo_list, 0, &ba_node );
3028 ok( r == S_OK, "ret %08x\n", r);
3030 IXMLDOMNodeList_Release( fo_list );
3032 /* invalid parameter: NULL ptr for element to remove */
3033 removed_node = (void*)0xdeadbeef;
3034 r = IXMLDOMElement_replaceChild( element, ba_node, NULL, &removed_node );
3035 ok( r == E_INVALIDARG, "ret %08x\n", r );
3036 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3038 /* invalid parameter: NULL for replacement element. (Sic!) */
3039 removed_node = (void*)0xdeadbeef;
3040 r = IXMLDOMElement_replaceChild( element, NULL, fo_node, &removed_node );
3041 ok( r == E_INVALIDARG, "ret %08x\n", r );
3042 ok( removed_node == (void*)0xdeadbeef, "%p\n", removed_node );
3044 /* invalid parameter: OldNode is not a child */
3045 removed_node = (void*)0xdeadbeef;
3046 r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node );
3047 ok( r == E_INVALIDARG, "ret %08x\n", r );
3048 ok( removed_node == NULL, "%p\n", removed_node );
3049 IXMLDOMNode_Release( lc_node );
3051 /* invalid parameter: would create loop */
3052 removed_node = (void*)0xdeadbeef;
3053 r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node );
3054 ok( r == E_FAIL, "ret %08x\n", r );
3055 ok( removed_node == NULL, "%p\n", removed_node );
3057 r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL );
3058 ok( r == S_OK, "ret %08x\n", r );
3060 r = IXMLDOMNodeList_get_item( root_list, 3, &temp_node );
3061 ok( r == S_OK, "ret %08x\n", r );
3063 /* ba_node and temp_node refer to the same node, yet they
3064 are different interface pointers */
3065 ok( ba_node != temp_node, "ba_node %p temp_node %p\n", ba_node, temp_node);
3066 r = IXMLDOMNode_QueryInterface( temp_node, &IID_IUnknown, (void**)&unk1);
3067 ok( r == S_OK, "ret %08x\n", r );
3068 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2);
3069 ok( r == S_OK, "ret %08x\n", r );
3070 todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
3072 IUnknown_Release( unk1 );
3073 IUnknown_Release( unk2 );
3075 /* ba_node should have been removed from below fo_node */
3076 r = IXMLDOMNode_get_childNodes( fo_node, &fo_list );
3077 ok( r == S_OK, "ret %08x\n", r );
3079 /* MS quirk: replaceChild also accepts elements instead of nodes */
3080 r = IXMLDOMNode_QueryInterface( ba_node, &IID_IXMLDOMElement, (void**)&ba_element);
3081 ok( r == S_OK, "ret %08x\n", r );
3082 EXPECT_REF(ba_element, 2);
3084 removed_node = NULL;
3085 r = IXMLDOMElement_replaceChild( element, ba_node, (IXMLDOMNode*)ba_element, &removed_node );
3086 ok( r == S_OK, "ret %08x\n", r );
3087 ok( removed_node != NULL, "got %p\n", removed_node);
3088 EXPECT_REF(ba_element, 3);
3089 IXMLDOMElement_Release( ba_element );
3091 r = IXMLDOMNodeList_get_length( fo_list, &len);
3092 ok( r == S_OK, "ret %08x\n", r );
3093 ok( len == 0, "len %d\n", len);
3095 IXMLDOMNodeList_Release( fo_list );
3097 IXMLDOMNode_Release(ba_node);
3098 IXMLDOMNode_Release(fo_node);
3099 IXMLDOMNode_Release(temp_node);
3100 IXMLDOMNodeList_Release( root_list );
3101 IXMLDOMElement_Release( element );
3102 IXMLDOMDocument_Release( doc );
3105 static void test_removeNamedItem(void)
3107 IXMLDOMDocument *doc;
3108 IXMLDOMElement *element;
3109 IXMLDOMNode *pr_node, *removed_node, *removed_node2;
3110 IXMLDOMNodeList *root_list;
3111 IXMLDOMNamedNodeMap * pr_attrs;
3117 doc = create_document(&IID_IXMLDOMDocument);
3120 str = SysAllocString( szComplete4 );
3121 r = IXMLDOMDocument_loadXML( doc, str, &b );
3122 ok( r == S_OK, "loadXML failed\n");
3123 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3124 SysFreeString( str );
3126 r = IXMLDOMDocument_get_documentElement( doc, &element );
3127 ok( r == S_OK, "ret %08x\n", r);
3129 r = IXMLDOMElement_get_childNodes( element, &root_list );
3130 ok( r == S_OK, "ret %08x\n", r);
3132 r = IXMLDOMNodeList_get_item( root_list, 1, &pr_node );
3133 ok( r == S_OK, "ret %08x\n", r);
3135 r = IXMLDOMNode_get_attributes( pr_node, &pr_attrs );
3136 ok( r == S_OK, "ret %08x\n", r);
3138 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3139 ok( r == S_OK, "ret %08x\n", r);
3140 ok( len == 3, "length %d\n", len);
3142 removed_node = (void*)0xdeadbeef;
3143 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node);
3144 ok ( r == E_INVALIDARG, "ret %08x\n", r);
3145 ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node);
3147 removed_node = (void*)0xdeadbeef;
3148 str = SysAllocString(szvr);
3149 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node);
3150 ok ( r == S_OK, "ret %08x\n", r);
3152 removed_node2 = (void*)0xdeadbeef;
3153 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2);
3154 ok ( r == S_FALSE, "ret %08x\n", r);
3155 ok ( removed_node2 == NULL, "got %p\n", removed_node2 );
3157 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3158 ok( r == S_OK, "ret %08x\n", r);
3159 ok( len == 2, "length %d\n", len);
3161 r = IXMLDOMNamedNodeMap_setNamedItem( pr_attrs, removed_node, NULL);
3162 ok ( r == S_OK, "ret %08x\n", r);
3163 IXMLDOMNode_Release(removed_node);
3165 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3166 ok( r == S_OK, "ret %08x\n", r);
3167 ok( len == 3, "length %d\n", len);
3169 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
3170 ok ( r == S_OK, "ret %08x\n", r);
3172 r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len );
3173 ok( r == S_OK, "ret %08x\n", r);
3174 ok( len == 2, "length %d\n", len);
3176 r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, NULL);
3177 ok ( r == S_FALSE, "ret %08x\n", r);
3181 IXMLDOMNamedNodeMap_Release( pr_attrs );
3182 IXMLDOMNode_Release( pr_node );
3183 IXMLDOMNodeList_Release( root_list );
3184 IXMLDOMElement_Release( element );
3185 IXMLDOMDocument_Release( doc );
3188 #define test_IObjectSafety_set(p, r, r2, s, m, e, e2) _test_IObjectSafety_set(__LINE__,p, r, r2, s, m, e, e2)
3189 static void _test_IObjectSafety_set(unsigned line, IObjectSafety *safety, HRESULT result,
3190 HRESULT result2, DWORD set, DWORD mask, DWORD expected,
3193 DWORD enabled, supported;
3196 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, set, mask);
3197 if (result == result2)
3198 ok_(__FILE__,line)(hr == result, "SetInterfaceSafetyOptions: expected %08x, returned %08x\n", result, hr );
3200 ok_(__FILE__,line)(broken(hr == result) || hr == result2,
3201 "SetInterfaceSafetyOptions: expected %08x, got %08x\n", result2, hr );
3203 supported = enabled = 0xCAFECAFE;
3204 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3205 ok(hr == S_OK, "ret %08x\n", hr );
3206 if (expected == expected2)
3207 ok_(__FILE__,line)(enabled == expected, "Expected %08x, got %08x\n", expected, enabled);
3209 ok_(__FILE__,line)(broken(enabled == expected) || enabled == expected2,
3210 "Expected %08x, got %08x\n", expected2, enabled);
3212 /* reset the safety options */
3214 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3215 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER,
3217 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3219 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3220 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3221 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
3224 #define test_IObjectSafety_common(s) _test_IObjectSafety_common(__LINE__,s)
3225 static void _test_IObjectSafety_common(unsigned line, IObjectSafety *safety)
3227 DWORD enabled = 0, supported = 0;
3231 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, NULL, &enabled);
3232 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
3233 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, NULL);
3234 ok_(__FILE__,line)(hr == E_POINTER, "ret %08x\n", hr );
3236 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3237 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3238 ok_(__FILE__,line)(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) ||
3239 supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
3240 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), "
3241 "got %08x\n", supported);
3242 ok_(__FILE__,line)(enabled == 0, "Expected 0, got %08x\n", enabled);
3244 /* set -- individual flags */
3246 test_IObjectSafety_set(safety, S_OK, S_OK,
3247 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3248 INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3250 test_IObjectSafety_set(safety, S_OK, S_OK,
3251 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA,
3252 INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
3254 test_IObjectSafety_set(safety, S_OK, S_OK,
3255 INTERFACE_USES_SECURITY_MANAGER, INTERFACE_USES_SECURITY_MANAGER,
3256 0, INTERFACE_USES_SECURITY_MANAGER /* msxml3 SP8+ */);
3258 /* set INTERFACE_USES_DISPEX */
3260 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
3261 INTERFACE_USES_DISPEX, INTERFACE_USES_DISPEX,
3264 test_IObjectSafety_set(safety, S_OK, E_FAIL /* msxml3 SP8+ */,
3265 INTERFACE_USES_DISPEX, 0,
3268 test_IObjectSafety_set(safety, S_OK, S_OK /* msxml3 SP8+ */,
3269 0, INTERFACE_USES_DISPEX,
3272 /* set option masking */
3274 test_IObjectSafety_set(safety, S_OK, S_OK,
3275 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3276 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3277 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3278 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3280 test_IObjectSafety_set(safety, S_OK, S_OK,
3281 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3282 INTERFACESAFE_FOR_UNTRUSTED_DATA,
3283 INTERFACESAFE_FOR_UNTRUSTED_DATA,
3284 INTERFACESAFE_FOR_UNTRUSTED_DATA);
3286 test_IObjectSafety_set(safety, S_OK, S_OK,
3287 INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA,
3288 INTERFACE_USES_SECURITY_MANAGER,
3292 /* set -- inheriting previous settings */
3294 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3295 INTERFACESAFE_FOR_UNTRUSTED_CALLER,
3296 INTERFACESAFE_FOR_UNTRUSTED_CALLER);
3297 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3298 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3299 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3301 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_CALLER) ||
3302 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */,
3303 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACE_USES_SECURITY_MANAGER), "
3304 "got %08x\n", enabled);
3306 hr = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
3307 INTERFACESAFE_FOR_UNTRUSTED_DATA,
3308 INTERFACESAFE_FOR_UNTRUSTED_DATA);
3309 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3310 hr = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled);
3311 ok_(__FILE__,line)(hr == S_OK, "ret %08x\n", hr );
3313 ok_(__FILE__,line)(broken(enabled == INTERFACESAFE_FOR_UNTRUSTED_DATA) ||
3314 enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA) /* msxml3 SP8+ */,
3315 "Expected (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA), "
3316 "got %08x\n", enabled);
3319 static void test_XMLHTTP(void)
3321 static const WCHAR wszBody[] = {'m','o','d','e','=','T','e','s','t',0};
3322 static const WCHAR wszUrl[] = {'h','t','t','p',':','/','/',
3323 'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
3324 'p','o','s','t','t','e','s','t','.','p','h','p',0};
3325 static const WCHAR xmltestW[] = {'h','t','t','p',':','/','/',
3326 'c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
3327 'x','m','l','t','e','s','t','.','x','m','l',0};
3328 static const WCHAR wszExpectedResponse[] = {'F','A','I','L','E','D',0};
3329 static const CHAR xmltestbodyA[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
3331 IXMLHttpRequest *pXMLHttpRequest;
3332 IObjectSafety *safety;
3333 IObjectWithSite *pSite;
3334 BSTR bstrResponse, url;
3338 LONG state, status, bound;
3341 HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
3342 CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest,
3343 (void **)&pXMLHttpRequest);
3346 win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
3350 hr = IXMLHttpRequest_QueryInterface(pXMLHttpRequest, &IID_IObjectWithSite, (void**)&pSite);
3351 ok(hr == S_OK, "got 0x%08x\n", hr);
3352 if(hr == S_OK) IObjectWithSite_Release(pSite);
3354 VariantInit(&dummy);
3355 V_VT(&dummy) = VT_ERROR;
3356 V_ERROR(&dummy) = DISP_E_MEMBERNOTFOUND;
3357 VariantInit(&async);
3358 V_VT(&async) = VT_BOOL;
3359 V_BOOL(&async) = VARIANT_FALSE;
3360 V_VT(&varbody) = VT_BSTR;
3361 V_BSTR(&varbody) = SysAllocString(wszBody);
3363 url = SysAllocString(wszUrl);
3365 hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, NULL);
3366 ok(hr == S_OK, "got 0x%08x\n", hr);
3368 hr = IXMLHttpRequest_abort(pXMLHttpRequest);
3369 ok(hr == S_OK, "got 0x%08x\n", hr);
3371 /* send before open */
3372 hr = IXMLHttpRequest_send(pXMLHttpRequest, dummy);
3373 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3375 /* initial status code */
3376 hr = IXMLHttpRequest_get_status(pXMLHttpRequest, NULL);
3377 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3379 status = 0xdeadbeef;
3380 hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3381 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3382 ok(status == 0xdeadbeef, "got %d\n", status);
3384 /* invalid parameters */
3385 hr = IXMLHttpRequest_open(pXMLHttpRequest, NULL, NULL, async, dummy, dummy);
3386 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3388 hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), NULL, async, dummy, dummy);
3389 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3391 hr = IXMLHttpRequest_open(pXMLHttpRequest, NULL, url, async, dummy, dummy);
3392 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3394 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, NULL);
3395 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3397 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), NULL);
3398 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3400 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
3401 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3403 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
3404 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3406 hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, NULL);
3407 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3410 hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3411 ok(hr == S_OK, "got 0x%08x\n", hr);
3412 ok(state == READYSTATE_UNINITIALIZED, "got %d, expected READYSTATE_UNINITIALIZED\n", state);
3414 event = create_dispevent();
3416 EXPECT_REF(event, 1);
3417 hr = IXMLHttpRequest_put_onreadystatechange(pXMLHttpRequest, event);
3418 ok(hr == S_OK, "got 0x%08x\n", hr);
3419 EXPECT_REF(event, 2);
3421 g_unexpectedcall = g_expectedcall = 0;
3423 hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), url, async, dummy, dummy);
3424 ok(hr == S_OK, "got 0x%08x\n", hr);
3426 ok(g_unexpectedcall == 0, "unexpected disp event call\n");
3427 ok(g_expectedcall == 1 || broken(g_expectedcall == 0) /* win2k */, "no expected disp event call\n");
3429 /* status code after ::open() */
3430 status = 0xdeadbeef;
3431 hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3432 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3433 ok(status == 0xdeadbeef, "got %d\n", status);
3436 hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3437 ok(hr == S_OK, "got 0x%08x\n", hr);
3438 ok(state == READYSTATE_LOADING, "got %d, expected READYSTATE_LOADING\n", state);
3440 hr = IXMLHttpRequest_abort(pXMLHttpRequest);
3441 ok(hr == S_OK, "got 0x%08x\n", hr);
3444 hr = IXMLHttpRequest_get_readyState(pXMLHttpRequest, &state);
3445 ok(hr == S_OK, "got 0x%08x\n", hr);
3446 ok(state == READYSTATE_UNINITIALIZED || broken(state == READYSTATE_LOADING) /* win2k */,
3447 "got %d, expected READYSTATE_UNINITIALIZED\n", state);
3449 hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("POST"), url, async, dummy, dummy);
3450 ok(hr == S_OK, "got 0x%08x\n", hr);
3452 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_("header1"), _bstr_("value1"));
3453 ok(hr == S_OK, "got 0x%08x\n", hr);
3455 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, NULL, _bstr_("value1"));
3456 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3458 hr = IXMLHttpRequest_setRequestHeader(pXMLHttpRequest, _bstr_(""), _bstr_("value1"));
3459 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3463 hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3464 if (hr == INET_E_RESOURCE_NOT_FOUND)
3466 skip("No connection could be made with crossover.codeweavers.com\n");
3467 IXMLHttpRequest_Release(pXMLHttpRequest);
3470 ok(hr == S_OK, "got 0x%08x\n", hr);
3472 /* status code after ::send() */
3473 status = 0xdeadbeef;
3474 hr = IXMLHttpRequest_get_status(pXMLHttpRequest, &status);
3475 ok(hr == S_OK, "got 0x%08x\n", hr);
3476 ok(status == 200, "got %d\n", status);
3478 /* another ::send() after completed request */
3479 hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3480 ok(hr == E_FAIL || broken(hr == E_UNEXPECTED) /* win2k */, "got 0x%08x\n", hr);
3482 VariantClear(&varbody);
3484 hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
3485 ok(hr == S_OK, "got 0x%08x\n", hr);
3486 /* the server currently returns "FAILED" because the Content-Type header is
3487 * not what the server expects */
3490 ok(!memcmp(bstrResponse, wszExpectedResponse, sizeof(wszExpectedResponse)),
3491 "expected %s, got %s\n", wine_dbgstr_w(wszExpectedResponse), wine_dbgstr_w(bstrResponse));
3492 SysFreeString(bstrResponse);
3496 url = SysAllocString(xmltestW);
3498 hr = IXMLHttpRequest_open(pXMLHttpRequest, _bstr_("GET"), url, async, dummy, dummy);
3499 ok(hr == S_OK, "got 0x%08x\n", hr);
3501 V_VT(&varbody) = VT_EMPTY;
3503 hr = IXMLHttpRequest_send(pXMLHttpRequest, varbody);
3504 if (hr == INET_E_RESOURCE_NOT_FOUND)
3506 skip("No connection could be made with crossover.codeweavers.com\n");
3507 IXMLHttpRequest_Release(pXMLHttpRequest);
3510 ok(hr == S_OK, "got 0x%08x\n", hr);
3512 hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, NULL);
3513 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3515 hr = IXMLHttpRequest_get_responseText(pXMLHttpRequest, &bstrResponse);
3516 ok(hr == S_OK, "got 0x%08x\n", hr);
3519 ok(!memcmp(bstrResponse, _bstr_(xmltestbodyA), sizeof(xmltestbodyA)*sizeof(WCHAR)),
3520 "expected %s, got %s\n", xmltestbodyA, wine_dbgstr_w(bstrResponse));
3521 SysFreeString(bstrResponse);
3524 hr = IXMLHttpRequest_get_responseBody(pXMLHttpRequest, NULL);
3525 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3527 V_VT(&varbody) = VT_EMPTY;
3528 hr = IXMLHttpRequest_get_responseBody(pXMLHttpRequest, &varbody);
3529 ok(hr == S_OK, "got 0x%08x\n", hr);
3530 ok(V_VT(&varbody) == (VT_ARRAY|VT_UI1), "got type %d, expected %d\n", V_VT(&varbody), VT_ARRAY|VT_UI1);
3531 ok(SafeArrayGetDim(V_ARRAY(&varbody)) == 1, "got %d, expected one dimension\n", SafeArrayGetDim(V_ARRAY(&varbody)));
3534 hr = SafeArrayGetLBound(V_ARRAY(&varbody), 1, &bound);
3535 ok(hr == S_OK, "got 0x%08x\n", hr);
3536 ok(bound == 0, "got %d, expected zero bound\n", bound);
3538 hr = SafeArrayAccessData(V_ARRAY(&varbody), &ptr);
3539 ok(hr == S_OK, "got 0x%08x\n", hr);
3540 ok(memcmp(ptr, xmltestbodyA, sizeof(xmltestbodyA)-1) == 0, "got wrond body data\n");
3541 SafeArrayUnaccessData(V_ARRAY(&varbody));
3543 VariantClear(&varbody);
3547 hr = IXMLHttpRequest_QueryInterface(pXMLHttpRequest, &IID_IObjectSafety, (void**)&safety);
3548 ok(hr == S_OK, "ret %08x\n", hr );
3551 test_IObjectSafety_common(safety);
3553 IObjectSafety_Release(safety);
3557 IDispatch_Release(event);
3558 IXMLHttpRequest_Release(pXMLHttpRequest);
3562 static void test_IXMLDOMDocument2(void)
3564 static const WCHAR emptyW[] = {0};
3565 IXMLDOMDocument2 *doc2, *dtddoc2;
3566 IXMLDOMDocument *doc;
3567 IXMLDOMParseError* err;
3568 IDispatchEx *dispex;
3575 doc = create_document(&IID_IXMLDOMDocument);
3578 dtddoc2 = create_document(&IID_IXMLDOMDocument2);
3581 IXMLDOMDocument_Release(doc);
3585 r = IXMLDOMDocument_QueryInterface( doc, &IID_IXMLDOMDocument2, (void**)&doc2 );
3586 ok( r == S_OK, "ret %08x\n", r );
3587 ok( doc == (IXMLDOMDocument*)doc2, "interfaces differ\n");
3589 ole_expect(IXMLDOMDocument2_get_readyState(doc2, NULL), E_INVALIDARG);
3590 ole_check(IXMLDOMDocument2_get_readyState(doc2, &res));
3591 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
3594 ole_expect(IXMLDOMDocument2_validate(doc2, NULL), S_FALSE);
3595 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
3596 ok(err != NULL, "expected a pointer\n");
3600 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3602 ok(res == E_XML_NOTWF, "got %08x\n", res);
3603 IXMLDOMParseError_Release(err);
3606 str = SysAllocString( szComplete4 );
3607 r = IXMLDOMDocument_loadXML( doc2, str, &b );
3608 ok( r == S_OK, "loadXML failed\n");
3609 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3610 SysFreeString( str );
3612 ole_check(IXMLDOMDocument2_get_readyState(doc, &res));
3613 ok(res == READYSTATE_COMPLETE, "expected READYSTATE_COMPLETE (4), got %i\n", res);
3616 ole_expect(IXMLDOMDocument2_validate(doc2, &err), S_FALSE);
3617 ok(err != NULL, "expected a pointer\n");
3621 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3623 ok(res == E_XML_NODTD, "got %08x\n", res);
3624 IXMLDOMParseError_Release(err);
3627 r = IXMLDOMDocument_QueryInterface( doc, &IID_IDispatchEx, (void**)&dispex );
3628 ok( r == S_OK, "ret %08x\n", r );
3631 IDispatchEx_Release(dispex);
3634 /* we will check if the variant got cleared */
3635 IXMLDOMDocument2_AddRef(doc2);
3636 EXPECT_REF(doc2, 3); /* doc, doc2, AddRef*/
3638 V_VT(&var) = VT_UNKNOWN;
3639 V_UNKNOWN(&var) = (IUnknown *)doc2;
3642 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("askldhfaklsdf"), &var), E_FAIL);
3643 expect_eq(V_VT(&var), VT_UNKNOWN, int, "%x");
3644 ole_expect(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), NULL), E_INVALIDARG);
3647 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
3648 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
3649 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
3652 /* the variant didn't get cleared*/
3653 expect_eq(IXMLDOMDocument2_Release(doc2), 2, int, "%d");
3655 /* setProperty tests */
3656 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("askldhfaklsdf"), var), E_FAIL);
3657 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), var), E_FAIL);
3658 ole_expect(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("alskjdh faklsjd hfk")), E_FAIL);
3659 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
3660 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3661 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
3663 V_VT(&var) = VT_BSTR;
3664 V_BSTR(&var) = SysAllocString(emptyW);
3665 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
3666 ok(r == S_OK, "got 0x%08x\n", r);
3671 r = IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionNamespaces"), var);
3672 ok(r == E_FAIL, "got 0x%08x\n", r);
3674 /* contrary to what MSDN claims you can switch back from XPath to XSLPattern */
3675 ole_check(IXMLDOMDocument2_getProperty(doc2, _bstr_("SelectionLanguage"), &var));
3676 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
3677 expect_bstr_eq_and_free(V_BSTR(&var), "XSLPattern");
3679 IXMLDOMDocument2_Release( doc2 );
3680 IXMLDOMDocument_Release( doc );
3682 /* DTD validation */
3683 ole_check(IXMLDOMDocument2_put_validateOnParse(dtddoc2, VARIANT_FALSE));
3684 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML), &b));
3685 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3687 ole_check(IXMLDOMDocument2_validate(dtddoc2, &err));
3688 ok(err != NULL, "expected pointer\n");
3692 ole_expect(IXMLDOMParseError_get_errorCode(err, &res), S_FALSE);
3693 ok(res == 0, "got %08x\n", res);
3694 IXMLDOMParseError_Release(err);
3697 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0D), &b));
3698 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3700 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3701 ok(err != NULL, "expected pointer\n");
3705 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3706 /* XML_ELEMENT_UNDECLARED */
3707 todo_wine ok(res == 0xC00CE00D, "got %08x\n", res);
3708 IXMLDOMParseError_Release(err);
3711 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_0E), &b));
3712 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3714 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3715 ok(err != NULL, "expected pointer\n");
3719 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3720 /* XML_ELEMENT_ID_NOT_FOUND */
3721 todo_wine ok(res == 0xC00CE00E, "got %08x\n", res);
3722 IXMLDOMParseError_Release(err);
3725 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_11), &b));
3726 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3728 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3729 ok(err != NULL, "expected pointer\n");
3733 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3734 /* XML_EMPTY_NOT_ALLOWED */
3735 todo_wine ok(res == 0xC00CE011, "got %08x\n", res);
3736 IXMLDOMParseError_Release(err);
3739 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_13), &b));
3740 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3742 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3743 ok(err != NULL, "expected pointer\n");
3747 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3748 /* XML_ROOT_NAME_MISMATCH */
3749 todo_wine ok(res == 0xC00CE013, "got %08x\n", res);
3750 IXMLDOMParseError_Release(err);
3753 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_14), &b));
3754 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3756 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3757 ok(err != NULL, "expected pointer\n");
3761 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3762 /* XML_INVALID_CONTENT */
3763 todo_wine ok(res == 0xC00CE014, "got %08x\n", res);
3764 IXMLDOMParseError_Release(err);
3767 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_15), &b));
3768 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3770 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3771 ok(err != NULL, "expected pointer\n");
3775 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3776 /* XML_ATTRIBUTE_NOT_DEFINED */
3777 todo_wine ok(res == 0xC00CE015, "got %08x\n", res);
3778 IXMLDOMParseError_Release(err);
3781 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_16), &b));
3782 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3784 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3785 ok(err != NULL, "expected pointer\n");
3789 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3790 /* XML_ATTRIBUTE_FIXED */
3791 todo_wine ok(res == 0xC00CE016, "got %08x\n", res);
3792 IXMLDOMParseError_Release(err);
3795 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_17), &b));
3796 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3798 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3799 ok(err != NULL, "expected pointer\n");
3803 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3804 /* XML_ATTRIBUTE_VALUE */
3805 todo_wine ok(res == 0xC00CE017, "got %08x\n", res);
3806 IXMLDOMParseError_Release(err);
3809 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_18), &b));
3810 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3812 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3813 ok(err != NULL, "expected pointer\n");
3817 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3818 /* XML_ILLEGAL_TEXT */
3819 todo_wine ok(res == 0xC00CE018, "got %08x\n", res);
3820 IXMLDOMParseError_Release(err);
3823 ole_check(IXMLDOMDocument2_loadXML(dtddoc2, _bstr_(szEmailXML_20), &b));
3824 ok( b == VARIANT_TRUE, "failed to load XML string\n");
3826 ole_expect(IXMLDOMDocument2_validate(dtddoc2, &err), S_FALSE);
3827 ok(err != NULL, "expected pointer\n");
3831 ole_check(IXMLDOMParseError_get_errorCode(err, &res));
3832 /* XML_REQUIRED_ATTRIBUTE_MISSING */
3833 todo_wine ok(res == 0xC00CE020, "got %08x\n", res);
3834 IXMLDOMParseError_Release(err);
3837 IXMLDOMDocument2_Release( dtddoc2 );
3841 #define helper_ole_check(expr) { \
3843 ok_(__FILE__, line)(r == S_OK, "=> %i: " #expr " returned %08x\n", __LINE__, r); \
3846 #define helper_expect_list_and_release(list, expstr) { \
3847 char *str = list_to_string(list); \
3848 ok_(__FILE__, line)(strcmp(str, expstr)==0, "=> %i: Invalid node list: %s, expected %s\n", __LINE__, str, expstr); \
3849 if (list) IXMLDOMNodeList_Release(list); \
3852 #define helper_expect_bstr_and_release(bstr, str) { \
3853 ok_(__FILE__, line)(lstrcmpW(bstr, _bstr_(str)) == 0, \
3854 "=> %i: got %s\n", __LINE__, wine_dbgstr_w(bstr)); \
3855 SysFreeString(bstr); \
3858 #define check_ws_ignored(doc, str) _check_ws_ignored(__LINE__, doc, str)
3859 static inline void _check_ws_ignored(int line, IXMLDOMDocument2* doc, char const* str)
3861 IXMLDOMNode *node1, *node2;
3862 IXMLDOMNodeList *list;
3865 helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
3866 helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
3867 helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
3868 helper_ole_check(IXMLDOMNodeList_reset(list));
3869 helper_expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1");
3871 helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
3872 helper_expect_list_and_release(list, "T1.E1.E4.E1.E2.D1 E2.E1.E4.E1.E2.D1 E3.E1.E4.E1.E2.D1 T4.E1.E4.E1.E2.D1 E5.E1.E4.E1.E2.D1");
3873 helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
3876 helper_expect_bstr_and_release(bstr, str);
3880 helper_expect_bstr_and_release(bstr, "This is a description.");
3882 IXMLDOMNode_Release(node1);
3884 helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
3885 helper_expect_list_and_release(list, "T1.E2.E4.E1.E2.D1 E2.E2.E4.E1.E2.D1 T3.E2.E4.E1.E2.D1 E4.E2.E4.E1.E2.D1 T5.E2.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1 T7.E2.E4.E1.E2.D1");
3886 helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
3887 helper_expect_bstr_and_release(bstr, "\n This is a description with preserved whitespace. \n ");
3888 IXMLDOMNode_Release(node2);
3891 #define check_ws_preserved(doc, str) _check_ws_preserved(__LINE__, doc, str)
3892 static inline void _check_ws_preserved(int line, IXMLDOMDocument2* doc, char const* str)
3894 IXMLDOMNode *node1, *node2;
3895 IXMLDOMNodeList *list;
3898 helper_ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list));
3899 helper_ole_check(IXMLDOMNodeList_get_item(list, 0, &node1));
3900 helper_ole_check(IXMLDOMNodeList_get_item(list, 1, &node2));
3901 helper_ole_check(IXMLDOMNodeList_reset(list));
3902 helper_expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1");
3904 helper_ole_check(IXMLDOMNode_get_childNodes(node1, &list));
3905 helper_expect_list_and_release(list, "T1.E2.E8.E2.E2.D1 E2.E2.E8.E2.E2.D1 T3.E2.E8.E2.E2.D1 E4.E2.E8.E2.E2.D1 T5.E2.E8.E2.E2.D1 E6.E2.E8.E2.E2.D1 T7.E2.E8.E2.E2.D1");
3906 helper_ole_check(IXMLDOMNode_get_text(node1, &bstr));
3909 helper_expect_bstr_and_release(bstr, str);
3913 helper_expect_bstr_and_release(bstr, "\n This is a description. \n ");
3915 IXMLDOMNode_Release(node1);
3917 helper_ole_check(IXMLDOMNode_get_childNodes(node2, &list));
3918 helper_expect_list_and_release(list, "T1.E4.E8.E2.E2.D1 E2.E4.E8.E2.E2.D1 T3.E4.E8.E2.E2.D1 E4.E4.E8.E2.E2.D1 T5.E4.E8.E2.E2.D1 E6.E4.E8.E2.E2.D1 T7.E4.E8.E2.E2.D1");
3919 helper_ole_check(IXMLDOMNode_get_text(node2, &bstr));
3920 helper_expect_bstr_and_release(bstr, "\n This is a description with preserved whitespace. \n ");
3921 IXMLDOMNode_Release(node2);
3924 static void test_whitespace(void)
3927 IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
3929 doc1 = create_document(&IID_IXMLDOMDocument2);
3930 doc2 = create_document(&IID_IXMLDOMDocument2);
3931 if (!doc1 || !doc2) return;
3933 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE));
3934 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
3935 ok(b == VARIANT_FALSE, "expected false\n");
3936 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
3937 ok(b == VARIANT_TRUE, "expected true\n");
3939 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
3940 ok(b == VARIANT_TRUE, "failed to load XML string\n");
3941 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
3942 ok(b == VARIANT_TRUE, "failed to load XML string\n");
3944 /* switch to XPath */
3945 ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3946 ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
3948 check_ws_ignored(doc1, NULL);
3949 check_ws_preserved(doc2, NULL);
3951 /* new instances copy the property */
3952 ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3));
3953 ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4));
3955 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
3956 ok(b == VARIANT_FALSE, "expected false\n");
3957 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
3958 ok(b == VARIANT_TRUE, "expected true\n");
3960 check_ws_ignored(doc3, NULL);
3961 check_ws_preserved(doc4, NULL);
3963 /* setting after loading xml affects trimming of leading/trailing ws only */
3964 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE));
3965 ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE));
3967 /* the trailing "\n " isn't there, because it was ws-only node */
3968 check_ws_ignored(doc1, "\n This is a description. ");
3969 check_ws_preserved(doc2, "This is a description.");
3971 /* it takes effect on reload */
3972 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b));
3973 ok(b == VARIANT_TRUE, "expected true\n");
3974 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b));
3975 ok(b == VARIANT_FALSE, "expected false\n");
3977 ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b));
3978 ok(b == VARIANT_TRUE, "failed to load XML string\n");
3979 ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b));
3980 ok(b == VARIANT_TRUE, "failed to load XML string\n");
3982 check_ws_preserved(doc1, NULL);
3983 check_ws_ignored(doc2, NULL);
3985 /* other instances follow suit */
3986 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b));
3987 ok(b == VARIANT_TRUE, "expected true\n");
3988 ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b));
3989 ok(b == VARIANT_FALSE, "expected false\n");
3991 check_ws_preserved(doc3, NULL);
3992 check_ws_ignored(doc4, NULL);
3994 IXMLDOMDocument_Release(doc1);
3995 IXMLDOMDocument_Release(doc2);
3996 IXMLDOMDocument_Release(doc3);
3997 IXMLDOMDocument_Release(doc4);
4001 static void test_XPath(void)
4005 IXMLDOMDocument2 *doc;
4006 IXMLDOMDocument *doc2;
4007 IXMLDOMNode *rootNode;
4008 IXMLDOMNode *elem1Node;
4010 IXMLDOMNodeList *list;
4011 IXMLDOMElement *elem;
4012 IXMLDOMAttribute *attr;
4016 doc = create_document(&IID_IXMLDOMDocument2);
4019 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
4020 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4022 /* switch to XPath */
4023 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
4025 /* some simple queries*/
4027 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4028 EXPECT_HR(hr, S_OK);
4030 EXPECT_LIST_LEN(list, 1);
4032 EXPECT_REF(list, 1);
4033 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4034 EXPECT_HR(hr, S_OK);
4035 EXPECT_REF(list, 1);
4036 EXPECT_REF(rootNode, 1);
4038 hr = IXMLDOMNodeList_reset(list);
4039 EXPECT_HR(hr, S_OK);
4040 expect_list_and_release(list, "E2.D1");
4042 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//c"), &list));
4043 expect_list_and_release(list, "E3.E1.E2.D1 E3.E2.E2.D1");
4045 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//c[@type]"), &list));
4046 expect_list_and_release(list, "E3.E2.E2.D1");
4048 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem"), &list));
4049 /* using get_item for query results advances the position */
4050 ole_check(IXMLDOMNodeList_get_item(list, 1, &node));
4051 expect_node(node, "E2.E2.D1");
4052 IXMLDOMNode_Release(node);
4053 ole_check(IXMLDOMNodeList_nextNode(list, &node));
4054 expect_node(node, "E4.E2.D1");
4055 IXMLDOMNode_Release(node);
4056 ole_check(IXMLDOMNodeList_reset(list));
4057 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E4.E2.D1");
4059 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("."), &list));
4060 expect_list_and_release(list, "E2.D1");
4062 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("elem[3]/preceding-sibling::*"), &list));
4063 ole_check(IXMLDOMNodeList_get_item(list, 0, &elem1Node));
4064 ole_check(IXMLDOMNodeList_reset(list));
4065 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
4067 /* select an attribute */
4068 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//@type"), &list));
4069 expect_list_and_release(list, "A'type'.E3.E2.E2.D1");
4071 /* would evaluate to a number */
4072 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("count(*)"), &list), E_FAIL);
4073 /* would evaluate to a boolean */
4074 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("position()>0"), &list), E_FAIL);
4075 /* would evaluate to a string */
4076 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_("name()"), &list), E_FAIL);
4079 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_("c"), &list));
4080 expect_list_and_release(list, "");
4081 ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("elem//c"), &list));
4082 expect_list_and_release(list, "");
4083 ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
4084 expect_list_and_release(list, "");
4085 ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
4086 expect_list_and_release(list, "");
4088 /* foo undeclared in document node */
4089 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4090 /* undeclared in <root> node */
4091 ole_expect(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//foo:c"), &list), E_FAIL);
4092 /* undeclared in <elem> node */
4093 ole_expect(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//foo:c"), &list), E_FAIL);
4094 /* but this trick can be used */
4095 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//*[name()='foo:c']"), &list));
4096 expect_list_and_release(list, "E3.E4.E2.D1");
4098 /* it has to be declared in SelectionNamespaces */
4099 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4100 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
4102 /* now the namespace can be used */
4103 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//test:c"), &list));
4104 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4105 ole_check(IXMLDOMNode_selectNodes(rootNode, _bstr_(".//test:c"), &list));
4106 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4107 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list));
4108 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
4109 ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list));
4110 expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
4112 /* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */
4113 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4114 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###")), E_FAIL);
4116 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4119 ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
4120 expect_eq(V_VT(&var), VT_BSTR, int, "%x");
4121 if (V_VT(&var) == VT_BSTR)
4122 expect_bstr_eq_and_free(V_BSTR(&var), "xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' xmlns:foo=###");
4124 /* extra attributes - same thing*/
4125 ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"),
4126 _variantbstr_("xmlns:test='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29' param='test'")), E_FAIL);
4127 ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
4129 IXMLDOMNode_Release(rootNode);
4130 IXMLDOMNode_Release(elem1Node);
4132 /* alter document with already built list */
4133 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4134 EXPECT_HR(hr, S_OK);
4135 EXPECT_LIST_LEN(list, 1);
4137 hr = IXMLDOMDocument2_get_lastChild(doc, &rootNode);
4138 EXPECT_HR(hr, S_OK);
4139 EXPECT_REF(rootNode, 1);
4142 hr = IXMLDOMDocument2_removeChild(doc, rootNode, NULL);
4143 EXPECT_HR(hr, S_OK);
4144 IXMLDOMNode_Release(rootNode);
4146 EXPECT_LIST_LEN(list, 1);
4148 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4149 EXPECT_HR(hr, S_OK);
4150 EXPECT_REF(rootNode, 1);
4152 IXMLDOMNodeList_Release(list);
4154 hr = IXMLDOMNode_get_nodeName(rootNode, &str);
4155 EXPECT_HR(hr, S_OK);
4156 ok(!lstrcmpW(str, _bstr_("root")), "got %s\n", wine_dbgstr_w(str));
4158 IXMLDOMNode_Release(rootNode);
4160 /* alter node from list and get it another time */
4161 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
4162 EXPECT_HR(hr, S_OK);
4163 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4165 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4166 EXPECT_HR(hr, S_OK);
4167 EXPECT_LIST_LEN(list, 1);
4169 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4170 EXPECT_HR(hr, S_OK);
4172 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
4173 EXPECT_HR(hr, S_OK);
4177 hr = IXMLDOMElement_setAttribute(elem, _bstr_("attrtest"), var);
4178 EXPECT_HR(hr, S_OK);
4179 IXMLDOMElement_Release(elem);
4180 IXMLDOMNode_Release(rootNode);
4182 /* now check attribute to be present */
4183 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4184 EXPECT_HR(hr, S_OK);
4186 hr = IXMLDOMNode_QueryInterface(rootNode, &IID_IXMLDOMElement, (void**)&elem);
4187 EXPECT_HR(hr, S_OK);
4189 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
4190 EXPECT_HR(hr, S_OK);
4191 IXMLDOMAttribute_Release(attr);
4193 IXMLDOMElement_Release(elem);
4194 IXMLDOMNode_Release(rootNode);
4196 /* and now check for attribute in original document */
4197 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
4198 EXPECT_HR(hr, S_OK);
4200 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attrtest"), &attr);
4201 EXPECT_HR(hr, S_OK);
4202 IXMLDOMAttribute_Release(attr);
4204 IXMLDOMElement_Release(elem);
4206 /* attach node from list to another document */
4207 doc2 = create_document(&IID_IXMLDOMDocument);
4209 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
4210 EXPECT_HR(hr, S_OK);
4211 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4213 hr = IXMLDOMDocument2_selectNodes(doc, _bstr_("root"), &list);
4214 EXPECT_HR(hr, S_OK);
4215 EXPECT_LIST_LEN(list, 1);
4217 hr = IXMLDOMNodeList_get_item(list, 0, &rootNode);
4218 EXPECT_HR(hr, S_OK);
4219 EXPECT_REF(rootNode, 1);
4221 hr = IXMLDOMDocument_appendChild(doc2, rootNode, NULL);
4222 EXPECT_HR(hr, S_OK);
4223 EXPECT_REF(rootNode, 1);
4224 EXPECT_REF(doc2, 1);
4225 EXPECT_REF(list, 1);
4227 EXPECT_LIST_LEN(list, 1);
4229 IXMLDOMNode_Release(rootNode);
4230 IXMLDOMNodeList_Release(list);
4231 IXMLDOMDocument_Release(doc2);
4233 IXMLDOMDocument2_Release(doc);
4237 static void test_cloneNode(void )
4239 IXMLDOMDocument *doc, *doc2;
4241 IXMLDOMNodeList *pList;
4242 IXMLDOMNamedNodeMap *mapAttr;
4243 LONG length, length1;
4244 LONG attr_cnt, attr_cnt1;
4246 IXMLDOMNode *node_clone;
4247 IXMLDOMNode *node_first;
4251 doc = create_document(&IID_IXMLDOMDocument);
4254 str = SysAllocString( szComplete4 );
4255 ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
4256 ok(b == VARIANT_TRUE, "failed to load XML string\n");
4259 hr = IXMLDOMNode_selectSingleNode(doc, _bstr_("lc/pr"), &node);
4260 ok( hr == S_OK, "ret %08x\n", hr );
4261 ok( node != NULL, "node %p\n", node );
4263 /* Check invalid parameter */
4264 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, NULL);
4265 ok( hr == E_INVALIDARG, "ret %08x\n", hr );
4268 hr = IXMLDOMNode_cloneNode(node, VARIANT_TRUE, &node_clone);
4269 ok( hr == S_OK, "ret %08x\n", hr );
4270 ok( node_clone != NULL, "node %p\n", node );
4272 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
4273 ok( hr == S_OK, "ret %08x\n", hr );
4274 hr = IXMLDOMNode_get_ownerDocument(node_clone, &doc2);
4275 ok( hr == S_OK, "ret %08x\n", hr );
4276 IXMLDOMDocument_Release(doc2);
4277 IXMLDOMNode_Release(node_first);
4279 hr = IXMLDOMNode_get_childNodes(node, &pList);
4280 ok( hr == S_OK, "ret %08x\n", hr );
4282 hr = IXMLDOMNodeList_get_length(pList, &length);
4283 ok( hr == S_OK, "ret %08x\n", hr );
4284 ok(length == 1, "got %d\n", length);
4285 IXMLDOMNodeList_Release(pList);
4287 hr = IXMLDOMNode_get_attributes(node, &mapAttr);
4288 ok( hr == S_OK, "ret %08x\n", hr );
4290 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt);
4291 ok( hr == S_OK, "ret %08x\n", hr );
4292 ok(attr_cnt == 3, "got %d\n", attr_cnt);
4293 IXMLDOMNamedNodeMap_Release(mapAttr);
4295 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
4296 ok( hr == S_OK, "ret %08x\n", hr );
4298 hr = IXMLDOMNodeList_get_length(pList, &length1);
4299 ok(length1 == 1, "got %d\n", length1);
4300 ok( hr == S_OK, "ret %08x\n", hr );
4301 IXMLDOMNodeList_Release(pList);
4303 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
4304 ok( hr == S_OK, "ret %08x\n", hr );
4306 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
4307 ok( hr == S_OK, "ret %08x\n", hr );
4308 ok(attr_cnt1 == 3, "got %d\n", attr_cnt1);
4309 IXMLDOMNamedNodeMap_Release(mapAttr);
4311 ok(length == length1, "wrong Child count (%d, %d)\n", length, length1);
4312 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
4313 IXMLDOMNode_Release(node_clone);
4316 hr = IXMLDOMNode_cloneNode(node, VARIANT_FALSE, &node_clone);
4317 ok( hr == S_OK, "ret %08x\n", hr );
4318 ok( node_clone != NULL, "node %p\n", node );
4320 hr = IXMLDOMNode_get_firstChild(node_clone, &node_first);
4321 ok(hr == S_FALSE, "ret %08x\n", hr );
4323 hr = IXMLDOMNode_get_childNodes(node_clone, &pList);
4324 ok(hr == S_OK, "ret %08x\n", hr );
4325 hr = IXMLDOMNodeList_get_length(pList, &length1);
4326 ok(hr == S_OK, "ret %08x\n", hr );
4327 ok( length1 == 0, "Length should be 0 (%d)\n", length1);
4328 IXMLDOMNodeList_Release(pList);
4330 hr = IXMLDOMNode_get_attributes(node_clone, &mapAttr);
4331 ok(hr == S_OK, "ret %08x\n", hr );
4332 hr = IXMLDOMNamedNodeMap_get_length(mapAttr, &attr_cnt1);
4333 ok(attr_cnt1 == 3, "Attribute count should be 3 (%d)\n", attr_cnt1);
4334 IXMLDOMNamedNodeMap_Release(mapAttr);
4336 ok(length != length1, "wrong Child count (%d, %d)\n", length, length1);
4337 ok(attr_cnt == attr_cnt1, "wrong Attribute count (%d, %d)\n", attr_cnt, attr_cnt1);
4338 IXMLDOMNode_Release(node_clone);
4340 IXMLDOMNode_Release(node);
4341 IXMLDOMDocument_Release(doc);
4345 static void test_xmlTypes(void)
4347 IXMLDOMDocument *doc;
4348 IXMLDOMElement *pRoot;
4350 IXMLDOMComment *pComment;
4351 IXMLDOMElement *pElement;
4352 IXMLDOMAttribute *pAttribute;
4353 IXMLDOMNamedNodeMap *pAttribs;
4354 IXMLDOMCDATASection *pCDataSec;
4355 IXMLDOMImplementation *pIXMLDOMImplementation = NULL;
4356 IXMLDOMDocumentFragment *pDocFrag = NULL;
4357 IXMLDOMEntityReference *pEntityRef = NULL;
4359 IXMLDOMNode *pNextChild;
4363 doc = create_document(&IID_IXMLDOMDocument);
4366 pNextChild = (void*)0xdeadbeef;
4367 hr = IXMLDOMDocument_get_nextSibling(doc, NULL);
4368 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4370 pNextChild = (void*)0xdeadbeef;
4371 hr = IXMLDOMDocument_get_nextSibling(doc, &pNextChild);
4372 ok(hr == S_FALSE, "ret %08x\n", hr );
4373 ok(pNextChild == NULL, "pDocChild not NULL\n");
4375 /* test previous Sibling */
4376 hr = IXMLDOMDocument_get_previousSibling(doc, NULL);
4377 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4379 pNextChild = (void*)0xdeadbeef;
4380 hr = IXMLDOMDocument_get_previousSibling(doc, &pNextChild);
4381 ok(hr == S_FALSE, "ret %08x\n", hr );
4382 ok(pNextChild == NULL, "pNextChild not NULL\n");
4384 /* test get_dataType */
4385 V_VT(&v) = VT_EMPTY;
4386 hr = IXMLDOMDocument_get_dataType(doc, &v);
4387 ok(hr == S_FALSE, "ret %08x\n", hr );
4388 ok( V_VT(&v) == VT_NULL, "incorrect dataType type\n");
4391 /* test implementation */
4392 hr = IXMLDOMDocument_get_implementation(doc, NULL);
4393 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4395 hr = IXMLDOMDocument_get_implementation(doc, &pIXMLDOMImplementation);
4396 ok(hr == S_OK, "ret %08x\n", hr );
4399 VARIANT_BOOL hasFeature = VARIANT_TRUE;
4400 BSTR sEmpty = SysAllocStringLen(NULL, 0);
4402 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, NULL, sEmpty, &hasFeature);
4403 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4405 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, NULL);
4406 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4408 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
4409 ok(hr == S_OK, "ret %08x\n", hr );
4410 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4412 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, sEmpty, sEmpty, &hasFeature);
4413 ok(hr == S_OK, "ret %08x\n", hr );
4414 ok(hasFeature == VARIANT_FALSE, "hasFeature returned true\n");
4416 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), NULL, &hasFeature);
4417 ok(hr == S_OK, "ret %08x\n", hr );
4418 ok(hasFeature == VARIANT_TRUE, "hasFeature returned false\n");
4420 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), sEmpty, &hasFeature);
4421 ok(hr == S_OK, "ret %08x\n", hr );
4422 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4424 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("DOM"), _bstr_("1.0"), &hasFeature);
4425 ok(hr == S_OK, "ret %08x\n", hr );
4426 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4428 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("XML"), _bstr_("1.0"), &hasFeature);
4429 ok(hr == S_OK, "ret %08x\n", hr );
4430 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4432 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("MS-DOM"), _bstr_("1.0"), &hasFeature);
4433 ok(hr == S_OK, "ret %08x\n", hr );
4434 ok(hasFeature == VARIANT_TRUE, "hasFeature returned true\n");
4436 hr = IXMLDOMImplementation_hasFeature(pIXMLDOMImplementation, _bstr_("SSS"), NULL, &hasFeature);
4437 ok(hr == S_OK, "ret %08x\n", hr );
4438 ok(hasFeature == VARIANT_FALSE, "hasFeature returned false\n");
4440 SysFreeString(sEmpty);
4441 IXMLDOMImplementation_Release(pIXMLDOMImplementation);
4444 pRoot = (IXMLDOMElement*)0x1;
4445 hr = IXMLDOMDocument_createElement(doc, NULL, &pRoot);
4446 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4447 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
4449 pRoot = (IXMLDOMElement*)0x1;
4450 hr = IXMLDOMDocument_createElement(doc, _bstr_(""), &pRoot);
4451 ok(hr == E_FAIL, "ret %08x\n", hr );
4452 ok(pRoot == (void*)0x1, "Expect same ptr, got %p\n", pRoot);
4454 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
4455 ok(hr == S_OK, "ret %08x\n", hr );
4458 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
4459 ok(hr == S_OK, "ret %08x\n", hr );
4463 str = SysAllocString(szComment);
4464 hr = IXMLDOMDocument_createComment(doc, str, &pComment);
4466 ok(hr == S_OK, "ret %08x\n", hr );
4469 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pComment, NULL);
4470 ok(hr == S_OK, "ret %08x\n", hr );
4472 hr = IXMLDOMComment_get_nodeName(pComment, &str);
4473 ok(hr == S_OK, "ret %08x\n", hr );
4474 ok( !lstrcmpW( str, szCommentNodeText ), "incorrect comment node Name\n");
4477 hr = IXMLDOMComment_get_xml(pComment, &str);
4478 ok(hr == S_OK, "ret %08x\n", hr );
4479 ok( !lstrcmpW( str, szCommentXML ), "incorrect comment xml\n");
4482 /* put data Tests */
4483 hr = IXMLDOMComment_put_data(pComment, _bstr_("This &is a ; test <>\\"));
4484 ok(hr == S_OK, "ret %08x\n", hr );
4486 /* get data Tests */
4487 hr = IXMLDOMComment_get_data(pComment, &str);
4488 ok(hr == S_OK, "ret %08x\n", hr );
4489 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect get_data string\n");
4492 /* get data Tests */
4493 hr = IXMLDOMComment_get_nodeValue(pComment, &v);
4494 ok(hr == S_OK, "ret %08x\n", hr );
4495 ok( V_VT(&v) == VT_BSTR, "incorrect dataType type\n");
4496 ok( !lstrcmpW( V_BSTR(&v), _bstr_("This &is a ; test <>\\") ), "incorrect get_nodeValue string\n");
4499 /* Confirm XML text is good */
4500 hr = IXMLDOMComment_get_xml(pComment, &str);
4501 ok(hr == S_OK, "ret %08x\n", hr );
4502 ok( !lstrcmpW( str, _bstr_("<!--This &is a ; test <>\\-->") ), "incorrect xml string\n");
4505 /* Confirm we get the put_data Text back */
4506 hr = IXMLDOMComment_get_text(pComment, &str);
4507 ok(hr == S_OK, "ret %08x\n", hr );
4508 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect xml string\n");
4511 /* test length property */
4512 hr = IXMLDOMComment_get_length(pComment, &len);
4513 ok(hr == S_OK, "ret %08x\n", hr );
4514 ok(len == 21, "expected 21 got %d\n", len);
4516 /* test substringData */
4517 hr = IXMLDOMComment_substringData(pComment, 0, 4, NULL);
4518 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4520 /* test substringData - Invalid offset */
4521 str = (BSTR)&szElement;
4522 hr = IXMLDOMComment_substringData(pComment, -1, 4, &str);
4523 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4524 ok( str == NULL, "incorrect string\n");
4526 /* test substringData - Invalid offset */
4527 str = (BSTR)&szElement;
4528 hr = IXMLDOMComment_substringData(pComment, 30, 0, &str);
4529 ok(hr == S_FALSE, "ret %08x\n", hr );
4530 ok( str == NULL, "incorrect string\n");
4532 /* test substringData - Invalid size */
4533 str = (BSTR)&szElement;
4534 hr = IXMLDOMComment_substringData(pComment, 0, -1, &str);
4535 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4536 ok( str == NULL, "incorrect string\n");
4538 /* test substringData - Invalid size */
4539 str = (BSTR)&szElement;
4540 hr = IXMLDOMComment_substringData(pComment, 2, 0, &str);
4541 ok(hr == S_FALSE, "ret %08x\n", hr );
4542 ok( str == NULL, "incorrect string\n");
4544 /* test substringData - Start of string */
4545 hr = IXMLDOMComment_substringData(pComment, 0, 4, &str);
4546 ok(hr == S_OK, "ret %08x\n", hr );
4547 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
4550 /* test substringData - Middle of string */
4551 hr = IXMLDOMComment_substringData(pComment, 13, 4, &str);
4552 ok(hr == S_OK, "ret %08x\n", hr );
4553 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
4556 /* test substringData - End of string */
4557 hr = IXMLDOMComment_substringData(pComment, 20, 4, &str);
4558 ok(hr == S_OK, "ret %08x\n", hr );
4559 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
4562 /* test appendData */
4563 hr = IXMLDOMComment_appendData(pComment, NULL);
4564 ok(hr == S_OK, "ret %08x\n", hr );
4566 hr = IXMLDOMComment_appendData(pComment, _bstr_(""));
4567 ok(hr == S_OK, "ret %08x\n", hr );
4569 hr = IXMLDOMComment_appendData(pComment, _bstr_("Append"));
4570 ok(hr == S_OK, "ret %08x\n", hr );
4572 hr = IXMLDOMComment_get_text(pComment, &str);
4573 ok(hr == S_OK, "ret %08x\n", hr );
4574 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4577 /* test insertData */
4578 str = SysAllocStringLen(NULL, 0);
4579 hr = IXMLDOMComment_insertData(pComment, -1, str);
4580 ok(hr == S_OK, "ret %08x\n", hr );
4582 hr = IXMLDOMComment_insertData(pComment, -1, NULL);
4583 ok(hr == S_OK, "ret %08x\n", hr );
4585 hr = IXMLDOMComment_insertData(pComment, 1000, str);
4586 ok(hr == S_OK, "ret %08x\n", hr );
4588 hr = IXMLDOMComment_insertData(pComment, 1000, NULL);
4589 ok(hr == S_OK, "ret %08x\n", hr );
4591 hr = IXMLDOMComment_insertData(pComment, 0, NULL);
4592 ok(hr == S_OK, "ret %08x\n", hr );
4594 hr = IXMLDOMComment_insertData(pComment, 0, str);
4595 ok(hr == S_OK, "ret %08x\n", hr );
4598 hr = IXMLDOMComment_insertData(pComment, -1, _bstr_("Inserting"));
4599 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4601 hr = IXMLDOMComment_insertData(pComment, 1000, _bstr_("Inserting"));
4602 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4604 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("Begin "));
4605 ok(hr == S_OK, "ret %08x\n", hr );
4607 hr = IXMLDOMComment_insertData(pComment, 17, _bstr_("Middle"));
4608 ok(hr == S_OK, "ret %08x\n", hr );
4610 hr = IXMLDOMComment_insertData(pComment, 39, _bstr_(" End"));
4611 ok(hr == S_OK, "ret %08x\n", hr );
4613 hr = IXMLDOMComment_get_text(pComment, &str);
4614 ok(hr == S_OK, "ret %08x\n", hr );
4615 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4619 /* invalid arguments */
4620 hr = IXMLDOMComment_deleteData(pComment, -1, 1);
4621 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4623 hr = IXMLDOMComment_deleteData(pComment, 0, 0);
4624 ok(hr == S_OK, "ret %08x\n", hr );
4626 hr = IXMLDOMComment_deleteData(pComment, 0, -1);
4627 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4629 hr = IXMLDOMComment_get_length(pComment, &len);
4630 ok(hr == S_OK, "ret %08x\n", hr );
4631 ok(len == 43, "expected 43 got %d\n", len);
4633 hr = IXMLDOMComment_deleteData(pComment, len, 1);
4634 ok(hr == S_OK, "ret %08x\n", hr );
4636 hr = IXMLDOMComment_deleteData(pComment, len+1, 1);
4637 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4639 /* delete from start */
4640 hr = IXMLDOMComment_deleteData(pComment, 0, 5);
4641 ok(hr == S_OK, "ret %08x\n", hr );
4643 hr = IXMLDOMComment_get_length(pComment, &len);
4644 ok(hr == S_OK, "ret %08x\n", hr );
4645 ok(len == 38, "expected 38 got %d\n", len);
4647 hr = IXMLDOMComment_get_text(pComment, &str);
4648 ok(hr == S_OK, "ret %08x\n", hr );
4649 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4652 /* delete from end */
4653 hr = IXMLDOMComment_deleteData(pComment, 35, 3);
4654 ok(hr == S_OK, "ret %08x\n", hr );
4656 hr = IXMLDOMComment_get_length(pComment, &len);
4657 ok(hr == S_OK, "ret %08x\n", hr );
4658 ok(len == 35, "expected 35 got %d\n", len);
4660 hr = IXMLDOMComment_get_text(pComment, &str);
4661 ok(hr == S_OK, "ret %08x\n", hr );
4662 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4665 /* delete from inside */
4666 hr = IXMLDOMComment_deleteData(pComment, 1, 33);
4667 ok(hr == S_OK, "ret %08x\n", hr );
4669 hr = IXMLDOMComment_get_length(pComment, &len);
4670 ok(hr == S_OK, "ret %08x\n", hr );
4671 ok(len == 2, "expected 2 got %d\n", len);
4673 hr = IXMLDOMComment_get_text(pComment, &str);
4674 ok(hr == S_OK, "ret %08x\n", hr );
4675 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4678 /* delete whole data ... */
4679 hr = IXMLDOMComment_get_length(pComment, &len);
4680 ok(hr == S_OK, "ret %08x\n", hr );
4682 hr = IXMLDOMComment_deleteData(pComment, 0, len);
4683 ok(hr == S_OK, "ret %08x\n", hr );
4684 /* ... and try again with empty string */
4685 hr = IXMLDOMComment_deleteData(pComment, 0, len);
4686 ok(hr == S_OK, "ret %08x\n", hr );
4688 /* ::replaceData() */
4690 V_BSTR(&v) = SysAllocString(szstr1);
4691 hr = IXMLDOMComment_put_nodeValue(pComment, v);
4692 ok(hr == S_OK, "ret %08x\n", hr );
4695 hr = IXMLDOMComment_replaceData(pComment, 6, 0, NULL);
4696 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4697 hr = IXMLDOMComment_get_text(pComment, &str);
4698 ok(hr == S_OK, "ret %08x\n", hr );
4699 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4702 hr = IXMLDOMComment_replaceData(pComment, 0, 0, NULL);
4703 ok(hr == S_OK, "ret %08x\n", hr );
4704 hr = IXMLDOMComment_get_text(pComment, &str);
4705 ok(hr == S_OK, "ret %08x\n", hr );
4706 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4709 /* NULL pointer means delete */
4710 hr = IXMLDOMComment_replaceData(pComment, 0, 1, NULL);
4711 ok(hr == S_OK, "ret %08x\n", hr );
4712 hr = IXMLDOMComment_get_text(pComment, &str);
4713 ok(hr == S_OK, "ret %08x\n", hr );
4714 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4717 /* empty string means delete */
4718 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_(""));
4719 ok(hr == S_OK, "ret %08x\n", hr );
4720 hr = IXMLDOMComment_get_text(pComment, &str);
4721 ok(hr == S_OK, "ret %08x\n", hr );
4722 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4725 /* zero count means insert */
4726 hr = IXMLDOMComment_replaceData(pComment, 0, 0, _bstr_("a"));
4727 ok(hr == S_OK, "ret %08x\n", hr );
4728 hr = IXMLDOMComment_get_text(pComment, &str);
4729 ok(hr == S_OK, "ret %08x\n", hr );
4730 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4733 hr = IXMLDOMComment_replaceData(pComment, 0, 2, NULL);
4734 ok(hr == S_OK, "ret %08x\n", hr );
4736 hr = IXMLDOMComment_insertData(pComment, 0, _bstr_("m"));
4737 ok(hr == S_OK, "ret %08x\n", hr );
4738 hr = IXMLDOMComment_get_text(pComment, &str);
4739 ok(hr == S_OK, "ret %08x\n", hr );
4740 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4743 /* nonempty string, count greater than its length */
4744 hr = IXMLDOMComment_replaceData(pComment, 0, 2, _bstr_("a1.2"));
4745 ok(hr == S_OK, "ret %08x\n", hr );
4746 hr = IXMLDOMComment_get_text(pComment, &str);
4747 ok(hr == S_OK, "ret %08x\n", hr );
4748 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4751 /* nonempty string, count less than its length */
4752 hr = IXMLDOMComment_replaceData(pComment, 0, 1, _bstr_("wine"));
4753 ok(hr == S_OK, "ret %08x\n", hr );
4754 hr = IXMLDOMComment_get_text(pComment, &str);
4755 ok(hr == S_OK, "ret %08x\n", hr );
4756 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
4759 IXMLDOMComment_Release(pComment);
4763 str = SysAllocString(szElement);
4764 hr = IXMLDOMDocument_createElement(doc, str, &pElement);
4766 ok(hr == S_OK, "ret %08x\n", hr );
4769 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
4770 ok(hr == S_OK, "ret %08x\n", hr );
4772 hr = IXMLDOMElement_get_nodeName(pElement, &str);
4773 ok(hr == S_OK, "ret %08x\n", hr );
4774 ok( !lstrcmpW( str, szElement ), "incorrect element node Name\n");
4777 hr = IXMLDOMElement_get_xml(pElement, &str);
4778 ok(hr == S_OK, "ret %08x\n", hr );
4779 ok( !lstrcmpW( str, szElementXML ), "incorrect element xml\n");
4783 pAttribute = (IXMLDOMAttribute*)0x1;
4784 hr = IXMLDOMDocument_createAttribute(doc, NULL, &pAttribute);
4785 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4786 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
4788 pAttribute = (IXMLDOMAttribute*)0x1;
4789 hr = IXMLDOMDocument_createAttribute(doc, _bstr_(""), &pAttribute);
4790 ok(hr == E_FAIL, "ret %08x\n", hr );
4791 ok(pAttribute == (void*)0x1, "Expect same ptr, got %p\n", pAttribute);
4793 str = SysAllocString(szAttribute);
4794 hr = IXMLDOMDocument_createAttribute(doc, str, &pAttribute);
4796 ok(hr == S_OK, "ret %08x\n", hr );
4799 IXMLDOMNode *pNewChild = (IXMLDOMNode *)0x1;
4801 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, NULL);
4802 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4804 pNextChild = (IXMLDOMNode *)0x1;
4805 hr = IXMLDOMAttribute_get_nextSibling(pAttribute, &pNextChild);
4806 ok(hr == S_FALSE, "ret %08x\n", hr );
4807 ok(pNextChild == NULL, "pNextChild not NULL\n");
4809 /* test Previous Sibling*/
4810 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, NULL);
4811 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4813 pNextChild = (IXMLDOMNode *)0x1;
4814 hr = IXMLDOMAttribute_get_previousSibling(pAttribute, &pNextChild);
4815 ok(hr == S_FALSE, "ret %08x\n", hr );
4816 ok(pNextChild == NULL, "pNextChild not NULL\n");
4818 hr = IXMLDOMElement_appendChild(pElement, (IXMLDOMNode*)pAttribute, &pNewChild);
4819 ok(hr == E_FAIL, "ret %08x\n", hr );
4820 ok(pNewChild == NULL, "pNewChild not NULL\n");
4822 hr = IXMLDOMElement_get_attributes(pElement, &pAttribs);
4823 ok(hr == S_OK, "ret %08x\n", hr );
4826 hr = IXMLDOMNamedNodeMap_setNamedItem(pAttribs, (IXMLDOMNode*)pAttribute, NULL );
4827 ok(hr == S_OK, "ret %08x\n", hr );
4829 IXMLDOMNamedNodeMap_Release(pAttribs);
4832 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
4833 ok(hr == S_OK, "ret %08x\n", hr );
4834 ok( !lstrcmpW( str, szAttribute ), "incorrect attribute node Name\n");
4838 hr = IXMLDOMAttribute_get_nodeName(pAttribute, &str);
4839 ok(hr == S_OK, "ret %08x\n", hr );
4840 ok( !lstrcmpW( str, szAttribute ), "incorrect nodeName string\n");
4843 /* test name property */
4844 hr = IXMLDOMAttribute_get_name(pAttribute, &str);
4845 ok(hr == S_OK, "ret %08x\n", hr );
4846 ok( !lstrcmpW( str, szAttribute ), "incorrect name string\n");
4849 hr = IXMLDOMAttribute_get_xml(pAttribute, &str);
4850 ok(hr == S_OK, "ret %08x\n", hr );
4851 ok( !lstrcmpW( str, szAttributeXML ), "incorrect attribute xml\n");
4854 IXMLDOMAttribute_Release(pAttribute);
4856 /* Check Element again with the Add Attribute*/
4857 hr = IXMLDOMElement_get_xml(pElement, &str);
4858 ok(hr == S_OK, "ret %08x\n", hr );
4859 ok( !lstrcmpW( str, szElementXML2 ), "incorrect element xml\n");
4863 hr = IXMLDOMElement_put_text(pElement, _bstr_("TestingNode"));
4864 ok(hr == S_OK, "ret %08x\n", hr );
4866 hr = IXMLDOMElement_get_xml(pElement, &str);
4867 ok(hr == S_OK, "ret %08x\n", hr );
4868 ok( !lstrcmpW( str, szElementXML3 ), "incorrect element xml\n");
4871 /* Test for reversible escaping */
4872 str = SysAllocString( szStrangeChars );
4873 hr = IXMLDOMElement_put_text(pElement, str);
4874 ok(hr == S_OK, "ret %08x\n", hr );
4875 SysFreeString( str );
4877 hr = IXMLDOMElement_get_xml(pElement, &str);
4878 ok(hr == S_OK, "ret %08x\n", hr );
4879 ok( !lstrcmpW( str, szElementXML4 ), "incorrect element xml\n");
4882 hr = IXMLDOMElement_get_text(pElement, &str);
4883 ok(hr == S_OK, "ret %08x\n", hr );
4884 ok( !lstrcmpW( str, szStrangeChars ), "incorrect element text\n");
4887 IXMLDOMElement_Release(pElement);
4891 str = SysAllocString(szCData);
4892 hr = IXMLDOMDocument_createCDATASection(doc, str, NULL);
4893 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4895 hr = IXMLDOMDocument_createCDATASection(doc, str, &pCDataSec);
4897 ok(hr == S_OK, "ret %08x\n", hr );
4900 IXMLDOMNode *pNextChild = (IXMLDOMNode *)0x1;
4905 hr = IXMLDOMCDATASection_QueryInterface(pCDataSec, &IID_IXMLDOMElement, (void**)&pElement);
4906 ok(hr == E_NOINTERFACE, "ret %08x\n", hr);
4908 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pCDataSec, NULL);
4909 ok(hr == S_OK, "ret %08x\n", hr );
4911 hr = IXMLDOMCDATASection_get_nodeName(pCDataSec, &str);
4912 ok(hr == S_OK, "ret %08x\n", hr );
4913 ok( !lstrcmpW( str, szCDataNodeText ), "incorrect cdata node Name\n");
4916 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
4917 ok(hr == S_OK, "ret %08x\n", hr );
4918 ok( !lstrcmpW( str, szCDataXML ), "incorrect cdata xml\n");
4921 /* test lastChild */
4922 pNextChild = (IXMLDOMNode*)0x1;
4923 hr = IXMLDOMCDATASection_get_lastChild(pCDataSec, &pNextChild);
4924 ok(hr == S_FALSE, "ret %08x\n", hr );
4925 ok(pNextChild == NULL, "pNextChild not NULL\n");
4927 /* put data Tests */
4928 hr = IXMLDOMCDATASection_put_data(pCDataSec, _bstr_("This &is a ; test <>\\"));
4929 ok(hr == S_OK, "ret %08x\n", hr );
4931 /* Confirm XML text is good */
4932 hr = IXMLDOMCDATASection_get_xml(pCDataSec, &str);
4933 ok(hr == S_OK, "ret %08x\n", hr );
4934 ok( !lstrcmpW( str, _bstr_("<![CDATA[This &is a ; test <>\\]]>") ), "incorrect xml string\n");
4937 /* Confirm we get the put_data Text back */
4938 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
4939 ok(hr == S_OK, "ret %08x\n", hr );
4940 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4943 /* test length property */
4944 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
4945 ok(hr == S_OK, "ret %08x\n", hr );
4946 ok(len == 21, "expected 21 got %d\n", len);
4948 /* test get nodeValue */
4949 hr = IXMLDOMCDATASection_get_nodeValue(pCDataSec, &var);
4950 ok(hr == S_OK, "ret %08x\n", hr );
4951 ok(V_VT(&var) == VT_BSTR, "got vt %04x\n", V_VT(&var));
4952 ok( !lstrcmpW( V_BSTR(&var), _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4956 hr = IXMLDOMCDATASection_get_data(pCDataSec, &str);
4957 ok(hr == S_OK, "ret %08x\n", hr );
4958 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\") ), "incorrect text string\n");
4961 /* test substringData */
4962 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, NULL);
4963 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4965 /* test substringData - Invalid offset */
4966 str = (BSTR)&szElement;
4967 hr = IXMLDOMCDATASection_substringData(pCDataSec, -1, 4, &str);
4968 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4969 ok( str == NULL, "incorrect string\n");
4971 /* test substringData - Invalid offset */
4972 str = (BSTR)&szElement;
4973 hr = IXMLDOMCDATASection_substringData(pCDataSec, 30, 0, &str);
4974 ok(hr == S_FALSE, "ret %08x\n", hr );
4975 ok( str == NULL, "incorrect string\n");
4977 /* test substringData - Invalid size */
4978 str = (BSTR)&szElement;
4979 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, -1, &str);
4980 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
4981 ok( str == NULL, "incorrect string\n");
4983 /* test substringData - Invalid size */
4984 str = (BSTR)&szElement;
4985 hr = IXMLDOMCDATASection_substringData(pCDataSec, 2, 0, &str);
4986 ok(hr == S_FALSE, "ret %08x\n", hr );
4987 ok( str == NULL, "incorrect string\n");
4989 /* test substringData - Start of string */
4990 hr = IXMLDOMCDATASection_substringData(pCDataSec, 0, 4, &str);
4991 ok(hr == S_OK, "ret %08x\n", hr );
4992 ok( !lstrcmpW( str, _bstr_("This") ), "incorrect substringData string\n");
4995 /* test substringData - Middle of string */
4996 hr = IXMLDOMCDATASection_substringData(pCDataSec, 13, 4, &str);
4997 ok(hr == S_OK, "ret %08x\n", hr );
4998 ok( !lstrcmpW( str, _bstr_("test") ), "incorrect substringData string\n");
5001 /* test substringData - End of string */
5002 hr = IXMLDOMCDATASection_substringData(pCDataSec, 20, 4, &str);
5003 ok(hr == S_OK, "ret %08x\n", hr );
5004 ok( !lstrcmpW( str, _bstr_("\\") ), "incorrect substringData string\n");
5007 /* test appendData */
5008 hr = IXMLDOMCDATASection_appendData(pCDataSec, NULL);
5009 ok(hr == S_OK, "ret %08x\n", hr );
5011 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_(""));
5012 ok(hr == S_OK, "ret %08x\n", hr );
5014 hr = IXMLDOMCDATASection_appendData(pCDataSec, _bstr_("Append"));
5015 ok(hr == S_OK, "ret %08x\n", hr );
5017 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5018 ok(hr == S_OK, "ret %08x\n", hr );
5019 ok( !lstrcmpW( str, _bstr_("This &is a ; test <>\\Append") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5022 /* test insertData */
5023 str = SysAllocStringLen(NULL, 0);
5024 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, str);
5025 ok(hr == S_OK, "ret %08x\n", hr );
5027 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, NULL);
5028 ok(hr == S_OK, "ret %08x\n", hr );
5030 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, str);
5031 ok(hr == S_OK, "ret %08x\n", hr );
5033 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, NULL);
5034 ok(hr == S_OK, "ret %08x\n", hr );
5036 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, NULL);
5037 ok(hr == S_OK, "ret %08x\n", hr );
5039 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, str);
5040 ok(hr == S_OK, "ret %08x\n", hr );
5043 hr = IXMLDOMCDATASection_insertData(pCDataSec, -1, _bstr_("Inserting"));
5044 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5046 hr = IXMLDOMCDATASection_insertData(pCDataSec, 1000, _bstr_("Inserting"));
5047 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5049 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("Begin "));
5050 ok(hr == S_OK, "ret %08x\n", hr );
5052 hr = IXMLDOMCDATASection_insertData(pCDataSec, 17, _bstr_("Middle"));
5053 ok(hr == S_OK, "ret %08x\n", hr );
5055 hr = IXMLDOMCDATASection_insertData(pCDataSec, 39, _bstr_(" End"));
5056 ok(hr == S_OK, "ret %08x\n", hr );
5058 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5059 ok(hr == S_OK, "ret %08x\n", hr );
5060 ok( !lstrcmpW( str, _bstr_("Begin This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5064 /* invalid arguments */
5065 hr = IXMLDOMCDATASection_deleteData(pCDataSec, -1, 1);
5066 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5068 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 0);
5069 ok(hr == S_OK, "ret %08x\n", hr );
5071 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, -1);
5072 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5074 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5075 ok(hr == S_OK, "ret %08x\n", hr );
5076 ok(len == 43, "expected 43 got %d\n", len);
5078 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len, 1);
5079 ok(hr == S_OK, "ret %08x\n", hr );
5081 hr = IXMLDOMCDATASection_deleteData(pCDataSec, len+1, 1);
5082 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5084 /* delete from start */
5085 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, 5);
5086 ok(hr == S_OK, "ret %08x\n", hr );
5088 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5089 ok(hr == S_OK, "ret %08x\n", hr );
5090 ok(len == 38, "expected 38 got %d\n", len);
5092 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5093 ok(hr == S_OK, "ret %08x\n", hr );
5094 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append End") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5097 /* delete from end */
5098 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 35, 3);
5099 ok(hr == S_OK, "ret %08x\n", hr );
5101 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5102 ok(hr == S_OK, "ret %08x\n", hr );
5103 ok(len == 35, "expected 35 got %d\n", len);
5105 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5106 ok(hr == S_OK, "ret %08x\n", hr );
5107 ok( !lstrcmpW( str, _bstr_(" This &is a Middle; test <>\\Append ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5110 /* delete from inside */
5111 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 1, 33);
5112 ok(hr == S_OK, "ret %08x\n", hr );
5114 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5115 ok(hr == S_OK, "ret %08x\n", hr );
5116 ok(len == 2, "expected 2 got %d\n", len);
5118 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5119 ok(hr == S_OK, "ret %08x\n", hr );
5120 ok( !lstrcmpW( str, _bstr_(" ") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5123 /* delete whole data ... */
5124 hr = IXMLDOMCDATASection_get_length(pCDataSec, &len);
5125 ok(hr == S_OK, "ret %08x\n", hr );
5127 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
5128 ok(hr == S_OK, "ret %08x\n", hr );
5130 /* ... and try again with empty string */
5131 hr = IXMLDOMCDATASection_deleteData(pCDataSec, 0, len);
5132 ok(hr == S_OK, "ret %08x\n", hr );
5134 /* ::replaceData() */
5136 V_BSTR(&v) = SysAllocString(szstr1);
5137 hr = IXMLDOMCDATASection_put_nodeValue(pCDataSec, v);
5138 ok(hr == S_OK, "ret %08x\n", hr );
5141 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 6, 0, NULL);
5142 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5143 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5144 ok(hr == S_OK, "ret %08x\n", hr );
5145 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5148 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, NULL);
5149 ok(hr == S_OK, "ret %08x\n", hr );
5150 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5151 ok(hr == S_OK, "ret %08x\n", hr );
5152 ok( !lstrcmpW( str, _bstr_("str1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5155 /* NULL pointer means delete */
5156 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, NULL);
5157 ok(hr == S_OK, "ret %08x\n", hr );
5158 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5159 ok(hr == S_OK, "ret %08x\n", hr );
5160 ok( !lstrcmpW( str, _bstr_("tr1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5163 /* empty string means delete */
5164 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_(""));
5165 ok(hr == S_OK, "ret %08x\n", hr );
5166 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5167 ok(hr == S_OK, "ret %08x\n", hr );
5168 ok( !lstrcmpW( str, _bstr_("r1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5171 /* zero count means insert */
5172 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 0, _bstr_("a"));
5173 ok(hr == S_OK, "ret %08x\n", hr );
5174 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5175 ok(hr == S_OK, "ret %08x\n", hr );
5176 ok( !lstrcmpW( str, _bstr_("ar1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5179 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, NULL);
5180 ok(hr == S_OK, "ret %08x\n", hr );
5182 hr = IXMLDOMCDATASection_insertData(pCDataSec, 0, _bstr_("m"));
5183 ok(hr == S_OK, "ret %08x\n", hr );
5184 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5185 ok(hr == S_OK, "ret %08x\n", hr );
5186 ok( !lstrcmpW( str, _bstr_("m1") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5189 /* nonempty string, count greater than its length */
5190 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 2, _bstr_("a1.2"));
5191 ok(hr == S_OK, "ret %08x\n", hr );
5192 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5193 ok(hr == S_OK, "ret %08x\n", hr );
5194 ok( !lstrcmpW( str, _bstr_("a1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5197 /* nonempty string, count less than its length */
5198 hr = IXMLDOMCDATASection_replaceData(pCDataSec, 0, 1, _bstr_("wine"));
5199 ok(hr == S_OK, "ret %08x\n", hr );
5200 hr = IXMLDOMCDATASection_get_text(pCDataSec, &str);
5201 ok(hr == S_OK, "ret %08x\n", hr );
5202 ok( !lstrcmpW( str, _bstr_("wine1.2") ), "incorrect get_text string, got '%s'\n", wine_dbgstr_w(str) );
5205 IXMLDOMCDATASection_Release(pCDataSec);
5208 /* Document Fragments */
5209 hr = IXMLDOMDocument_createDocumentFragment(doc, NULL);
5210 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5212 hr = IXMLDOMDocument_createDocumentFragment(doc, &pDocFrag);
5213 ok(hr == S_OK, "ret %08x\n", hr );
5218 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, NULL);
5219 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5221 node = (IXMLDOMNode *)0x1;
5222 hr = IXMLDOMDocumentFragment_get_parentNode(pDocFrag, &node);
5223 ok(hr == S_FALSE, "ret %08x\n", hr );
5224 ok(node == NULL, "expected NULL, got %p\n", node);
5226 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pDocFrag, NULL);
5227 ok(hr == S_OK, "ret %08x\n", hr );
5229 hr = IXMLDOMDocumentFragment_get_nodeName(pDocFrag, &str);
5230 ok(hr == S_OK, "ret %08x\n", hr );
5231 ok( !lstrcmpW( str, szDocFragmentText ), "incorrect docfragment node Name\n");
5234 /* test next Sibling*/
5235 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, NULL);
5236 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5238 node = (IXMLDOMNode *)0x1;
5239 hr = IXMLDOMDocumentFragment_get_nextSibling(pDocFrag, &node);
5240 ok(hr == S_FALSE, "ret %08x\n", hr );
5241 ok(node == NULL, "next sibling not NULL\n");
5243 /* test Previous Sibling*/
5244 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, NULL);
5245 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5247 node = (IXMLDOMNode *)0x1;
5248 hr = IXMLDOMDocumentFragment_get_previousSibling(pDocFrag, &node);
5249 ok(hr == S_FALSE, "ret %08x\n", hr );
5250 ok(node == NULL, "previous sibling not NULL\n");
5252 IXMLDOMDocumentFragment_Release(pDocFrag);
5255 /* Entity References */
5256 hr = IXMLDOMDocument_createEntityReference(doc, NULL, &pEntityRef);
5257 ok(hr == E_FAIL, "ret %08x\n", hr );
5258 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_(""), &pEntityRef);
5259 ok(hr == E_FAIL, "ret %08x\n", hr );
5261 str = SysAllocString(szEntityRef);
5262 hr = IXMLDOMDocument_createEntityReference(doc, str, NULL);
5263 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5265 hr = IXMLDOMDocument_createEntityReference(doc, str, &pEntityRef);
5267 ok(hr == S_OK, "ret %08x\n", hr );
5270 hr = IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pEntityRef, NULL);
5271 ok(hr == S_OK, "ret %08x\n", hr );
5274 hr = IXMLDOMEntityReference_get_xml(pEntityRef, &str);
5275 ok(hr == S_OK, "ret %08x\n", hr );
5276 ok( !lstrcmpW( str, szEntityRefXML ), "incorrect xml string\n");
5279 IXMLDOMEntityReference_Release(pEntityRef);
5282 IXMLDOMElement_Release( pRoot );
5286 IXMLDOMDocument_Release(doc);
5291 static void test_nodeTypeTests( void )
5293 IXMLDOMDocument *doc = NULL;
5294 IXMLDOMElement *pRoot;
5295 IXMLDOMElement *pElement;
5298 doc = create_document(&IID_IXMLDOMDocument);
5301 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), NULL);
5302 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5304 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &pRoot);
5305 ok(hr == S_OK, "ret %08x\n", hr );
5308 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)pRoot, NULL);
5309 ok(hr == S_OK, "ret %08x\n", hr );
5312 hr = IXMLDOMElement_put_dataType(pRoot, NULL);
5313 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5316 hr = IXMLDOMElement_put_dataType(pRoot, _bstr_("abcdefg") );
5317 ok(hr == E_FAIL, "ret %08x\n", hr );
5320 * The name passed into put_dataType is case-insensitive. So many of the names
5321 * have been changed to reflect this.
5324 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Boolean"), &pElement);
5325 ok(hr == S_OK, "ret %08x\n", hr );
5328 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5330 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Boolean") );
5331 ok(hr == S_OK, "ret %08x\n", hr );
5333 IXMLDOMElement_Release(pElement);
5337 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_String"), &pElement);
5338 ok(hr == S_OK, "ret %08x\n", hr );
5341 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5343 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("String") );
5344 ok(hr == S_OK, "ret %08x\n", hr );
5346 IXMLDOMElement_Release(pElement);
5350 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Number"), &pElement);
5351 ok(hr == S_OK, "ret %08x\n", hr );
5354 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5356 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("number") );
5357 ok(hr == S_OK, "ret %08x\n", hr );
5359 IXMLDOMElement_Release(pElement);
5363 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Int"), &pElement);
5364 ok(hr == S_OK, "ret %08x\n", hr );
5367 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5369 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("InT") );
5370 ok(hr == S_OK, "ret %08x\n", hr );
5372 IXMLDOMElement_Release(pElement);
5376 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Fixed"), &pElement);
5377 ok(hr == S_OK, "ret %08x\n", hr );
5380 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5382 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("fixed.14.4") );
5383 ok(hr == S_OK, "ret %08x\n", hr );
5385 IXMLDOMElement_Release(pElement);
5389 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime"), &pElement);
5390 ok(hr == S_OK, "ret %08x\n", hr );
5393 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5395 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime") );
5396 ok(hr == S_OK, "ret %08x\n", hr );
5398 IXMLDOMElement_Release(pElement);
5402 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_DateTime_tz"), &pElement);
5403 ok(hr == S_OK, "ret %08x\n", hr );
5406 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5408 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
5409 ok(hr == S_OK, "ret %08x\n", hr );
5411 IXMLDOMElement_Release(pElement);
5415 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Date"), &pElement);
5416 ok(hr == S_OK, "ret %08x\n", hr );
5419 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5421 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Date") );
5422 ok(hr == S_OK, "ret %08x\n", hr );
5424 IXMLDOMElement_Release(pElement);
5428 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time"), &pElement);
5429 ok(hr == S_OK, "ret %08x\n", hr );
5432 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5434 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time") );
5435 ok(hr == S_OK, "ret %08x\n", hr );
5437 IXMLDOMElement_Release(pElement);
5441 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Time_TZ"), &pElement);
5442 ok(hr == S_OK, "ret %08x\n", hr );
5445 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5447 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("Time.tz") );
5448 ok(hr == S_OK, "ret %08x\n", hr );
5450 IXMLDOMElement_Release(pElement);
5454 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I1"), &pElement);
5455 ok(hr == S_OK, "ret %08x\n", hr );
5458 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5460 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I1") );
5461 ok(hr == S_OK, "ret %08x\n", hr );
5463 IXMLDOMElement_Release(pElement);
5467 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I2"), &pElement);
5468 ok(hr == S_OK, "ret %08x\n", hr );
5471 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5473 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I2") );
5474 ok(hr == S_OK, "ret %08x\n", hr );
5476 IXMLDOMElement_Release(pElement);
5480 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_I4"), &pElement);
5481 ok(hr == S_OK, "ret %08x\n", hr );
5484 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5486 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("I4") );
5487 ok(hr == S_OK, "ret %08x\n", hr );
5489 IXMLDOMElement_Release(pElement);
5493 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI1"), &pElement);
5494 ok(hr == S_OK, "ret %08x\n", hr );
5497 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5499 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI1") );
5500 ok(hr == S_OK, "ret %08x\n", hr );
5502 IXMLDOMElement_Release(pElement);
5506 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI2"), &pElement);
5507 ok(hr == S_OK, "ret %08x\n", hr );
5510 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5512 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI2") );
5513 ok(hr == S_OK, "ret %08x\n", hr );
5515 IXMLDOMElement_Release(pElement);
5519 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_UI4"), &pElement);
5520 ok(hr == S_OK, "ret %08x\n", hr );
5523 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5525 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UI4") );
5526 ok(hr == S_OK, "ret %08x\n", hr );
5528 IXMLDOMElement_Release(pElement);
5532 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r4"), &pElement);
5533 ok(hr == S_OK, "ret %08x\n", hr );
5536 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5538 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r4") );
5539 ok(hr == S_OK, "ret %08x\n", hr );
5541 IXMLDOMElement_Release(pElement);
5545 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_r8"), &pElement);
5546 ok(hr == S_OK, "ret %08x\n", hr );
5549 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5551 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("r8") );
5552 ok(hr == S_OK, "ret %08x\n", hr );
5554 IXMLDOMElement_Release(pElement);
5558 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_float"), &pElement);
5559 ok(hr == S_OK, "ret %08x\n", hr );
5562 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5564 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("float") );
5565 ok(hr == S_OK, "ret %08x\n", hr );
5567 IXMLDOMElement_Release(pElement);
5571 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_uuid"), &pElement);
5572 ok(hr == S_OK, "ret %08x\n", hr );
5575 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5577 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("UuId") );
5578 ok(hr == S_OK, "ret %08x\n", hr );
5580 IXMLDOMElement_Release(pElement);
5584 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_hex"), &pElement);
5585 ok(hr == S_OK, "ret %08x\n", hr );
5588 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5590 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.hex") );
5591 ok(hr == S_OK, "ret %08x\n", hr );
5593 IXMLDOMElement_Release(pElement);
5597 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_bin_base64"), &pElement);
5598 ok(hr == S_OK, "ret %08x\n", hr );
5601 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5603 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("bin.base64") );
5604 ok(hr == S_OK, "ret %08x\n", hr );
5606 IXMLDOMElement_Release(pElement);
5609 /* Check changing types */
5610 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing_Change"), &pElement);
5611 ok(hr == S_OK, "ret %08x\n", hr );
5614 IXMLDOMElement_appendChild(pRoot, (IXMLDOMNode*)pElement, NULL);
5616 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("DateTime.tz") );
5617 ok(hr == S_OK, "ret %08x\n", hr );
5619 hr = IXMLDOMElement_put_dataType(pElement, _bstr_("string") );
5620 ok(hr == S_OK, "ret %08x\n", hr );
5622 IXMLDOMElement_Release(pElement);
5625 IXMLDOMElement_Release(pRoot);
5629 IXMLDOMDocument_Release(doc);
5634 static void test_save(void)
5636 IXMLDOMDocument *doc, *doc2;
5637 IXMLDOMElement *root;
5645 doc = create_document(&IID_IXMLDOMDocument);
5648 doc2 = create_document(&IID_IXMLDOMDocument);
5651 IXMLDOMDocument_Release(doc);
5655 /* save to IXMLDOMDocument */
5656 hr = IXMLDOMDocument_createElement(doc, _bstr_("Testing"), &root);
5657 EXPECT_HR(hr, S_OK);
5659 hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode*)root, NULL);
5660 EXPECT_HR(hr, S_OK);
5662 V_VT(&vDoc) = VT_UNKNOWN;
5663 V_UNKNOWN(&vDoc) = (IUnknown*)doc2;
5665 hr = IXMLDOMDocument_save(doc, vDoc);
5666 EXPECT_HR(hr, S_OK);
5668 hr = IXMLDOMDocument_get_xml(doc, &sOrig);
5669 EXPECT_HR(hr, S_OK);
5671 hr = IXMLDOMDocument_get_xml(doc2, &sNew);
5672 EXPECT_HR(hr, S_OK);
5674 ok( !lstrcmpW( sOrig, sNew ), "New document is not the same as origial\n");
5676 SysFreeString(sOrig);
5677 SysFreeString(sNew);
5679 IXMLDOMElement_Release(root);
5680 IXMLDOMDocument_Release(doc2);
5683 V_VT(&file) = VT_BSTR;
5684 V_BSTR(&file) = _bstr_("test.xml");
5686 hr = IXMLDOMDocument_save(doc, file);
5687 EXPECT_HR(hr, S_OK);
5689 IXMLDOMDocument_Release(doc);
5691 hfile = CreateFileA("test.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
5692 ok(hfile != INVALID_HANDLE_VALUE, "Could not open file: %u\n", GetLastError());
5693 if(hfile == INVALID_HANDLE_VALUE) return;
5695 ReadFile(hfile, buffer, sizeof(buffer), &read, NULL);
5696 ok(read != 0, "could not read file\n");
5697 ok(buffer[0] != '<' || buffer[1] != '?', "File contains processing instruction\n");
5700 DeleteFile("test.xml");
5704 static void test_testTransforms(void)
5706 IXMLDOMDocument *doc, *docSS;
5712 doc = create_document(&IID_IXMLDOMDocument);
5715 docSS = create_document(&IID_IXMLDOMDocument);
5718 IXMLDOMDocument_Release(doc);
5722 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc);
5723 ok(hr == S_OK, "ret %08x\n", hr );
5725 hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc);
5726 ok(hr == S_OK, "ret %08x\n", hr );
5728 hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (void**)&pNode );
5729 ok(hr == S_OK, "ret %08x\n", hr );
5734 hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut);
5735 ok(hr == S_OK, "ret %08x\n", hr );
5736 ok( compareIgnoreReturns( bOut, _bstr_(szTransformOutput)), "Stylesheet output not correct\n");
5737 SysFreeString(bOut);
5739 IXMLDOMNode_Release(pNode);
5742 IXMLDOMDocument_Release(docSS);
5743 IXMLDOMDocument_Release(doc);
5748 static void test_Namespaces(void)
5750 IXMLDOMDocument *doc;
5752 IXMLDOMNode *pNode2 = NULL;
5756 static const CHAR szNamespacesXML[] =
5757 "<?xml version=\"1.0\"?>\n"
5758 "<root xmlns:WEB='http://www.winehq.org'>\n"
5759 "<WEB:Site version=\"1.0\" />\n"
5762 doc = create_document(&IID_IXMLDOMDocument);
5765 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szNamespacesXML), &bSucc);
5766 ok(hr == S_OK, "ret %08x\n", hr );
5767 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5769 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root"), &pNode );
5770 ok(hr == S_OK, "ret %08x\n", hr );
5773 hr = IXMLDOMNode_get_firstChild( pNode, &pNode2 );
5774 ok( hr == S_OK, "ret %08x\n", hr );
5775 ok( pNode2 != NULL, "pNode2 == NULL\n");
5777 /* Test get_prefix */
5778 hr = IXMLDOMNode_get_prefix(pNode2, NULL);
5779 ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5780 /* NOTE: Need to test that arg2 gets cleared on Error. */
5782 hr = IXMLDOMNode_get_prefix(pNode2, &str);
5783 ok( hr == S_OK, "ret %08x\n", hr );
5784 ok( !lstrcmpW( str, _bstr_("WEB")), "incorrect prefix string\n");
5787 /* Test get_namespaceURI */
5788 hr = IXMLDOMNode_get_namespaceURI(pNode2, NULL);
5789 ok( hr == E_INVALIDARG, "ret %08x\n", hr );
5790 /* NOTE: Need to test that arg2 gets cleared on Error. */
5792 hr = IXMLDOMNode_get_namespaceURI(pNode2, &str);
5793 ok( hr == S_OK, "ret %08x\n", hr );
5794 ok( !lstrcmpW( str, _bstr_("http://www.winehq.org")), "incorrect namespaceURI string\n");
5797 IXMLDOMNode_Release(pNode2);
5798 IXMLDOMNode_Release(pNode);
5801 IXMLDOMDocument_Release(doc);
5806 static void test_FormattingXML(void)
5808 IXMLDOMDocument *doc;
5809 IXMLDOMElement *pElement;
5813 static const CHAR szLinefeedXML[] = "<?xml version=\"1.0\"?>\n<Root>\n\t<Sub val=\"A\" />\n</Root>";
5814 static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
5816 doc = create_document(&IID_IXMLDOMDocument);
5819 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szLinefeedXML), &bSucc);
5820 ok(hr == S_OK, "ret %08x\n", hr );
5821 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
5823 if(bSucc == VARIANT_TRUE)
5825 hr = IXMLDOMDocument_get_documentElement(doc, &pElement);
5826 ok(hr == S_OK, "ret %08x\n", hr );
5829 hr = IXMLDOMElement_get_xml(pElement, &str);
5830 ok(hr == S_OK, "ret %08x\n", hr );
5831 ok( !lstrcmpW( str, _bstr_(szLinefeedRootXML) ), "incorrect element xml\n");
5834 IXMLDOMElement_Release(pElement);
5838 IXMLDOMDocument_Release(doc);
5843 typedef struct _nodetypedvalue_t {
5846 const char *value; /* value in string format */
5849 static const nodetypedvalue_t get_nodetypedvalue[] = {
5850 { "root/string", VT_BSTR, "Wine" },
5851 { "root/string2", VT_BSTR, "String" },
5852 { "root/number", VT_BSTR, "12.44" },
5853 { "root/number2", VT_BSTR, "-3.71e3" },
5854 { "root/int", VT_I4, "-13" },
5855 { "root/fixed", VT_CY, "7322.9371" },
5856 { "root/bool", VT_BOOL, "-1" },
5857 { "root/datetime", VT_DATE, "40135.14" },
5858 { "root/datetimetz",VT_DATE, "37813.59" },
5859 { "root/date", VT_DATE, "665413" },
5860 { "root/time", VT_DATE, "0.5813889" },
5861 { "root/timetz", VT_DATE, "1.112512" },
5862 { "root/i1", VT_I1, "-13" },
5863 { "root/i2", VT_I2, "31915" },
5864 { "root/i4", VT_I4, "-312232" },
5865 { "root/ui1", VT_UI1, "123" },
5866 { "root/ui2", VT_UI2, "48282" },
5867 { "root/ui4", VT_UI4, "949281" },
5868 { "root/r4", VT_R4, "213124" },
5869 { "root/r8", VT_R8, "0.412" },
5870 { "root/float", VT_R8, "41221.421" },
5871 { "root/uuid", VT_BSTR, "333C7BC4-460F-11D0-BC04-0080C7055a83" },
5872 { "root/binbase64", VT_ARRAY|VT_UI1, "base64 test" },
5873 { "root/binbase64_1", VT_ARRAY|VT_UI1, "base64 test" },
5874 { "root/binbase64_2", VT_ARRAY|VT_UI1, "base64 test" },
5878 static void test_nodeTypedValue(void)
5880 const nodetypedvalue_t *entry = get_nodetypedvalue;
5881 IXMLDOMDocumentType *doctype, *doctype2;
5882 IXMLDOMProcessingInstruction *pi;
5883 IXMLDOMDocumentFragment *frag;
5884 IXMLDOMDocument *doc, *doc2;
5885 IXMLDOMCDATASection *cdata;
5886 IXMLDOMComment *comment;
5892 doc = create_document(&IID_IXMLDOMDocument);
5896 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &b);
5897 ok(hr == S_OK, "ret %08x\n", hr );
5898 ok(b == VARIANT_TRUE, "got %d\n", b);
5900 hr = IXMLDOMDocument_get_nodeValue(doc, NULL);
5901 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5903 V_VT(&value) = VT_BSTR;
5904 V_BSTR(&value) = NULL;
5905 hr = IXMLDOMDocument_get_nodeValue(doc, &value);
5906 ok(hr == S_FALSE, "ret %08x\n", hr );
5907 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
5909 hr = IXMLDOMDocument_get_nodeTypedValue(doc, NULL);
5910 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5912 V_VT(&value) = VT_EMPTY;
5913 hr = IXMLDOMDocument_get_nodeTypedValue(doc, &value);
5914 ok(hr == S_FALSE, "ret %08x\n", hr );
5915 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
5917 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/string"), &node);
5918 ok(hr == S_OK, "ret %08x\n", hr );
5920 V_VT(&value) = VT_BSTR;
5921 V_BSTR(&value) = NULL;
5922 hr = IXMLDOMNode_get_nodeValue(node, &value);
5923 ok(hr == S_FALSE, "ret %08x\n", hr );
5924 ok(V_VT(&value) == VT_NULL, "expect VT_NULL got %d\n", V_VT(&value));
5926 hr = IXMLDOMNode_get_nodeTypedValue(node, NULL);
5927 ok(hr == E_INVALIDARG, "ret %08x\n", hr );
5929 IXMLDOMNode_Release(node);
5931 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("root/binhex"), &node);
5932 ok(hr == S_OK, "ret %08x\n", hr );
5934 BYTE bytes[] = {0xff,0xfc,0xa0,0x12,0x00,0x3c};
5936 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
5937 ok(hr == S_OK, "ret %08x\n", hr );
5938 ok(V_VT(&value) == (VT_ARRAY|VT_UI1), "incorrect type\n");
5939 ok(V_ARRAY(&value)->rgsabound[0].cElements == 6, "incorrect array size\n");
5940 if(V_ARRAY(&value)->rgsabound[0].cElements == 6)
5941 ok(!memcmp(bytes, V_ARRAY(&value)->pvData, sizeof(bytes)), "incorrect value\n");
5942 VariantClear(&value);
5943 IXMLDOMNode_Release(node);
5946 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("foo"), _bstr_("value"), &pi);
5947 ok(hr == S_OK, "ret %08x\n", hr );
5949 V_VT(&value) = VT_NULL;
5950 V_BSTR(&value) = (void*)0xdeadbeef;
5951 hr = IXMLDOMProcessingInstruction_get_nodeTypedValue(pi, &value);
5952 ok(hr == S_OK, "ret %08x\n", hr );
5953 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5954 ok(!lstrcmpW(V_BSTR(&value), _bstr_("value")), "got wrong value\n");
5955 IXMLDOMProcessingInstruction_Release(pi);
5956 VariantClear(&value);
5959 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("[1]*2=3; &gee thats not right!"), &cdata);
5960 ok(hr == S_OK, "ret %08x\n", hr );
5962 V_VT(&value) = VT_NULL;
5963 V_BSTR(&value) = (void*)0xdeadbeef;
5964 hr = IXMLDOMCDATASection_get_nodeTypedValue(cdata, &value);
5965 ok(hr == S_OK, "ret %08x\n", hr );
5966 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5967 ok(!lstrcmpW(V_BSTR(&value), _bstr_("[1]*2=3; &gee thats not right!")), "got wrong value\n");
5968 IXMLDOMCDATASection_Release(cdata);
5969 VariantClear(&value);
5972 hr = IXMLDOMDocument_createComment(doc, _bstr_("comment"), &comment);
5973 ok(hr == S_OK, "ret %08x\n", hr );
5975 V_VT(&value) = VT_NULL;
5976 V_BSTR(&value) = (void*)0xdeadbeef;
5977 hr = IXMLDOMComment_get_nodeTypedValue(comment, &value);
5978 ok(hr == S_OK, "ret %08x\n", hr );
5979 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
5980 ok(!lstrcmpW(V_BSTR(&value), _bstr_("comment")), "got wrong value\n");
5981 IXMLDOMComment_Release(comment);
5982 VariantClear(&value);
5985 hr = IXMLDOMDocument_createDocumentFragment(doc, &frag);
5986 ok(hr == S_OK, "ret %08x\n", hr );
5988 V_VT(&value) = VT_EMPTY;
5989 hr = IXMLDOMDocumentFragment_get_nodeTypedValue(frag, &value);
5990 ok(hr == S_FALSE, "ret %08x\n", hr );
5991 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
5992 IXMLDOMDocumentFragment_Release(frag);
5995 doc2 = create_document(&IID_IXMLDOMDocument);
5998 hr = IXMLDOMDocument_loadXML(doc2, _bstr_(szEmailXML), &b);
5999 ok(hr == S_OK, "ret %08x\n", hr );
6000 ok(b == VARIANT_TRUE, "got %d\n", b);
6002 EXPECT_REF(doc2, 1);
6004 hr = IXMLDOMDocument_get_doctype(doc2, &doctype);
6005 ok(hr == S_OK, "ret %08x\n", hr );
6007 EXPECT_REF(doc2, 1);
6008 todo_wine EXPECT_REF(doctype, 2);
6011 V_VT(&value) = VT_EMPTY;
6012 hr = IXMLDOMDocumentType_get_nodeTypedValue(doctype, &value);
6013 ok(hr == S_FALSE, "ret %08x\n", hr );
6014 ok(V_VT(&value) == VT_NULL, "got %d\n", V_VT(&value));
6017 hr = IXMLDOMDocument_get_doctype(doc2, &doctype2);
6018 ok(hr == S_OK, "ret %08x\n", hr );
6019 ok(doctype != doctype2, "got %p, was %p\n", doctype2, doctype);
6021 IXMLDOMDocumentType_Release(doctype2);
6022 IXMLDOMDocumentType_Release(doctype);
6024 IXMLDOMDocument_Release(doc2);
6028 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_(entry->name), &node);
6029 ok(hr == S_OK, "ret %08x\n", hr );
6031 hr = IXMLDOMNode_get_nodeTypedValue(node, &value);
6032 ok(hr == S_OK, "ret %08x\n", hr );
6033 ok(V_VT(&value) == entry->type, "incorrect type, expected %d, got %d\n", entry->type, V_VT(&value));
6035 if (entry->type == (VT_ARRAY|VT_UI1))
6037 ok(V_ARRAY(&value)->rgsabound[0].cElements == strlen(entry->value),
6038 "incorrect array size, got %d, expected %d\n", V_ARRAY(&value)->rgsabound[0].cElements, strlen(entry->value));
6041 if (entry->type != VT_BSTR)
6043 if (entry->type == VT_DATE ||
6044 entry->type == VT_R8 ||
6045 entry->type == VT_CY)
6047 if (entry->type == VT_DATE)
6049 hr = VariantChangeType(&value, &value, 0, VT_R4);
6050 ok(hr == S_OK, "ret %08x\n", hr );
6052 hr = VariantChangeTypeEx(&value, &value,
6053 MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), SORT_DEFAULT),
6054 VARIANT_NOUSEROVERRIDE, VT_BSTR);
6055 ok(hr == S_OK, "ret %08x\n", hr );
6059 hr = VariantChangeType(&value, &value, 0, VT_BSTR);
6060 ok(hr == S_OK, "ret %08x\n", hr );
6063 /* for byte array from VT_ARRAY|VT_UI1 it's not a WCHAR buffer */
6064 if (entry->type == (VT_ARRAY|VT_UI1))
6066 ok(!memcmp( V_BSTR(&value), entry->value, strlen(entry->value)),
6067 "expected %s", entry->value);
6070 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6071 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6074 ok(lstrcmpW( V_BSTR(&value), _bstr_(entry->value)) == 0,
6075 "expected %s, got %s\n", entry->value, wine_dbgstr_w(V_BSTR(&value)));
6077 VariantClear( &value );
6078 IXMLDOMNode_Release(node);
6083 IXMLDOMDocument_Release(doc);
6087 static void test_TransformWithLoadingLocalFile(void)
6089 IXMLDOMDocument *doc;
6090 IXMLDOMDocument *xsl;
6096 char lpPathBuffer[MAX_PATH];
6099 /* Create a Temp File. */
6100 GetTempPathA(MAX_PATH, lpPathBuffer);
6101 strcat(lpPathBuffer, "customers.xml" );
6103 file = CreateFileA(lpPathBuffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
6104 ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
6105 if(file == INVALID_HANDLE_VALUE)
6108 WriteFile(file, szBasicTransformXML, strlen(szBasicTransformXML), &dwWritten, NULL);
6111 /* Correct path to not include a escape character. */
6112 for(i=0; i < strlen(lpPathBuffer); i++)
6114 if(lpPathBuffer[i] == '\\')
6115 lpPathBuffer[i] = '/';
6118 doc = create_document(&IID_IXMLDOMDocument);
6121 xsl = create_document(&IID_IXMLDOMDocument);
6124 IXMLDOMDocument2_Release(doc);
6128 hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTypeValueXML), &bSucc);
6129 ok(hr == S_OK, "ret %08x\n", hr );
6130 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6131 if(bSucc == VARIANT_TRUE)
6134 BSTR sPart1 = _bstr_(szBasicTransformSSXMLPart1);
6135 BSTR sPart2 = _bstr_(szBasicTransformSSXMLPart2);
6136 BSTR sFileName = _bstr_(lpPathBuffer);
6137 int nLegnth = lstrlenW(sPart1) + lstrlenW(sPart2) + lstrlenW(sFileName) + 1;
6139 sXSL = SysAllocStringLen(NULL, nLegnth);
6140 lstrcpyW(sXSL, sPart1);
6141 lstrcatW(sXSL, sFileName);
6142 lstrcatW(sXSL, sPart2);
6144 hr = IXMLDOMDocument_loadXML(xsl, sXSL, &bSucc);
6145 ok(hr == S_OK, "ret %08x\n", hr );
6146 ok(bSucc == VARIANT_TRUE, "Expected VARIANT_TRUE got VARIANT_FALSE\n");
6147 if(bSucc == VARIANT_TRUE)
6151 hr = IXMLDOMDocument_QueryInterface(xsl, &IID_IXMLDOMNode, (void**)&pNode );
6152 ok(hr == S_OK, "ret %08x\n", hr );
6155 /* This will load the temp file via the XSL */
6156 hr = IXMLDOMDocument_transformNode(doc, pNode, &sResult);
6157 ok(hr == S_OK, "ret %08x\n", hr );
6160 ok( compareIgnoreReturns( sResult, _bstr_(szBasicTransformOutput)), "Stylesheet output not correct\n");
6161 SysFreeString(sResult);
6164 IXMLDOMNode_Release(pNode);
6168 SysFreeString(sXSL);
6171 IXMLDOMDocument_Release(doc);
6172 IXMLDOMDocument_Release(xsl);
6174 DeleteFile(lpPathBuffer);
6178 static void test_put_nodeValue(void)
6180 static const WCHAR jeevesW[] = {'J','e','e','v','e','s',' ','&',' ','W','o','o','s','t','e','r',0};
6181 IXMLDOMDocument *doc;
6183 IXMLDOMEntityReference *entityref;
6184 IXMLDOMAttribute *attr;
6189 doc = create_document(&IID_IXMLDOMDocument);
6192 /* test for unsupported types */
6194 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&node);
6195 ok(hr == S_OK, "ret %08x\n", hr );
6196 V_VT(&data) = VT_BSTR;
6197 V_BSTR(&data) = _bstr_("one two three");
6198 hr = IXMLDOMNode_put_nodeValue(node, data);
6199 ok(hr == E_FAIL, "ret %08x\n", hr );
6200 IXMLDOMNode_Release(node);
6202 /* NODE_DOCUMENT_FRAGMENT */
6203 V_VT(&type) = VT_I1;
6204 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
6205 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
6206 ok(hr == S_OK, "ret %08x\n", hr );
6207 V_VT(&data) = VT_BSTR;
6208 V_BSTR(&data) = _bstr_("one two three");
6209 hr = IXMLDOMNode_put_nodeValue(node, data);
6210 ok(hr == E_FAIL, "ret %08x\n", hr );
6211 IXMLDOMNode_Release(node);
6214 V_VT(&type) = VT_I1;
6215 V_I1(&type) = NODE_ELEMENT;
6216 hr = IXMLDOMDocument_createNode(doc, type, _bstr_("test"), NULL, &node);
6217 ok(hr == S_OK, "ret %08x\n", hr );
6218 V_VT(&data) = VT_BSTR;
6219 V_BSTR(&data) = _bstr_("one two three");
6220 hr = IXMLDOMNode_put_nodeValue(node, data);
6221 ok(hr == E_FAIL, "ret %08x\n", hr );
6222 IXMLDOMNode_Release(node);
6224 /* NODE_ENTITY_REFERENCE */
6225 hr = IXMLDOMDocument_createEntityReference(doc, _bstr_("ref"), &entityref);
6226 ok(hr == S_OK, "ret %08x\n", hr );
6228 V_VT(&data) = VT_BSTR;
6229 V_BSTR(&data) = _bstr_("one two three");
6230 hr = IXMLDOMEntityReference_put_nodeValue(entityref, data);
6231 ok(hr == E_FAIL, "ret %08x\n", hr );
6233 hr = IXMLDOMEntityReference_QueryInterface(entityref, &IID_IXMLDOMNode, (void**)&node);
6234 ok(hr == S_OK, "ret %08x\n", hr );
6235 V_VT(&data) = VT_BSTR;
6236 V_BSTR(&data) = _bstr_("one two three");
6237 hr = IXMLDOMNode_put_nodeValue(node, data);
6238 ok(hr == E_FAIL, "ret %08x\n", hr );
6239 IXMLDOMNode_Release(node);
6240 IXMLDOMEntityReference_Release(entityref);
6242 /* supported types */
6243 hr = IXMLDOMDocument_createTextNode(doc, _bstr_(""), &text);
6244 ok(hr == S_OK, "ret %08x\n", hr );
6245 V_VT(&data) = VT_BSTR;
6246 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
6247 hr = IXMLDOMText_put_nodeValue(text, data);
6248 ok(hr == S_OK, "ret %08x\n", hr );
6249 IXMLDOMText_Release(text);
6251 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
6252 ok(hr == S_OK, "ret %08x\n", hr );
6253 V_VT(&data) = VT_BSTR;
6254 V_BSTR(&data) = _bstr_("Jeeves & Wooster");
6255 hr = IXMLDOMAttribute_put_nodeValue(attr, data);
6256 ok(hr == S_OK, "ret %08x\n", hr );
6257 hr = IXMLDOMAttribute_get_nodeValue(attr, &data);
6258 ok(hr == S_OK, "ret %08x\n", hr );
6259 ok(memcmp(V_BSTR(&data), jeevesW, sizeof(jeevesW)) == 0, "got %s\n",
6260 wine_dbgstr_w(V_BSTR(&data)));
6261 VariantClear(&data);
6262 IXMLDOMAttribute_Release(attr);
6266 IXMLDOMDocument_Release(doc);
6269 static void test_document_IObjectSafety(void)
6271 IXMLDOMDocument *doc;
6272 IObjectSafety *safety;
6275 doc = create_document(&IID_IXMLDOMDocument);
6278 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IObjectSafety, (void**)&safety);
6279 ok(hr == S_OK, "ret %08x\n", hr );
6281 test_IObjectSafety_common(safety);
6283 IObjectSafety_Release(safety);
6285 IXMLDOMDocument_Release(doc);
6288 typedef struct _property_test_t {
6291 const char *property;
6295 static const property_test_t properties_test_data[] = {
6296 { &CLSID_DOMDocument, "CLSID_DOMDocument" , "SelectionLanguage", "XSLPattern" },
6297 { &CLSID_DOMDocument2, "CLSID_DOMDocument2" , "SelectionLanguage", "XSLPattern" },
6298 { &CLSID_DOMDocument30, "CLSID_DOMDocument30", "SelectionLanguage", "XSLPattern" },
6299 { &CLSID_DOMDocument40, "CLSID_DOMDocument40", "SelectionLanguage", "XPath" },
6300 { &CLSID_DOMDocument60, "CLSID_DOMDocument60", "SelectionLanguage", "XPath" },
6304 static void test_default_properties(void)
6306 const property_test_t *entry = properties_test_data;
6307 IXMLDOMDocument2 *doc;
6313 hr = CoCreateInstance(entry->guid, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc);
6316 win_skip("can't create %s instance\n", entry->clsid);
6321 hr = IXMLDOMDocument2_getProperty(doc, _bstr_(entry->property), &var);
6322 ok(hr == S_OK, "got 0x%08x\n", hr);
6323 ok(lstrcmpW(V_BSTR(&var), _bstr_(entry->value)) == 0, "expected %s, for %s\n",
6324 entry->value, entry->clsid);
6327 IXMLDOMDocument2_Release(doc);
6333 static void test_XSLPattern(void)
6335 IXMLDOMDocument2 *doc;
6336 IXMLDOMNodeList *list;
6340 doc = create_document(&IID_IXMLDOMDocument2);
6343 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
6344 ok(b == VARIANT_TRUE, "failed to load XML string\n");
6346 /* switch to XSLPattern */
6347 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
6349 /* XPath doesn't select elements with non-null default namespace with unqualified selectors, XSLPattern does */
6350 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//elem/c"), &list));
6352 ole_check(IXMLDOMNodeList_get_length(list, &len));
6353 /* should select <elem><c> and <elem xmlns='...'><c> but not <elem><foo:c> */
6354 ok(len == 3, "expected 3 entries in list, got %d\n", len);
6355 IXMLDOMNodeList_Release(list);
6357 /* for XSLPattern start index is 0, for XPath it's 1 */
6358 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
6360 ole_check(IXMLDOMNodeList_get_length(list, &len));
6361 ok(len != 0, "expected filled list\n");
6363 expect_list_and_release(list, "E1.E2.D1");
6366 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=1]"), &list));
6368 ole_check(IXMLDOMNodeList_get_length(list, &len));
6369 ok(len != 0, "expected filled list\n");
6371 expect_list_and_release(list, "E2.E2.D1");
6374 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $eq$ 1]"), &list));
6376 ole_check(IXMLDOMNodeList_get_length(list, &len));
6377 ok(len != 0, "expected filled list\n");
6379 expect_list_and_release(list, "E2.E2.D1");
6382 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[end()]"), &list));
6384 ole_check(IXMLDOMNodeList_get_length(list, &len));
6385 ok(len != 0, "expected filled list\n");
6387 expect_list_and_release(list, "E4.E2.D1");
6390 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$not$ end()]"), &list));
6392 ole_check(IXMLDOMNodeList_get_length(list, &len));
6393 ok(len != 0, "expected filled list\n");
6395 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1 E3.E2.D1");
6398 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() != 0]"), &list));
6400 ole_check(IXMLDOMNodeList_get_length(list, &len));
6401 ok(len != 0, "expected filled list\n");
6403 expect_list_and_release(list, "E2.E2.D1 E3.E2.D1 E4.E2.D1");
6404 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $ne$ 0]"), &list));
6406 ole_check(IXMLDOMNodeList_get_length(list, &len));
6407 ok(len != 0, "expected filled list\n");
6409 expect_list_and_release(list, "E2.E2.D1 E3.E2.D1 E4.E2.D1");
6412 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() < 2]"), &list));
6414 ole_check(IXMLDOMNodeList_get_length(list, &len));
6415 ok(len != 0, "expected filled list\n");
6417 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6418 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $lt$ 2]"), &list));
6420 ole_check(IXMLDOMNodeList_get_length(list, &len));
6421 ok(len != 0, "expected filled list\n");
6423 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6426 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() <= 1]"), &list));
6428 ole_check(IXMLDOMNodeList_get_length(list, &len));
6429 ok(len != 0, "expected filled list\n");
6431 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6432 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $le$ 1]"), &list));
6434 ole_check(IXMLDOMNodeList_get_length(list, &len));
6435 ok(len != 0, "expected filled list\n");
6437 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6440 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() > 1]"), &list));
6442 ole_check(IXMLDOMNodeList_get_length(list, &len));
6443 ok(len != 0, "expected filled list\n");
6445 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6446 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $gt$ 1]"), &list));
6448 ole_check(IXMLDOMNodeList_get_length(list, &len));
6449 ok(len != 0, "expected filled list\n");
6451 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6454 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() >= 2]"), &list));
6456 ole_check(IXMLDOMNodeList_get_length(list, &len));
6457 ok(len != 0, "expected filled list\n");
6459 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6460 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index() $ge$ 2]"), &list));
6462 ole_check(IXMLDOMNodeList_get_length(list, &len));
6463 ok(len != 0, "expected filled list\n");
6465 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6468 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ieq$ 'a2 field']"), &list));
6470 ole_check(IXMLDOMNodeList_get_length(list, &len));
6471 ok(len != 0, "expected filled list\n");
6473 expect_list_and_release(list, "E2.E2.D1");
6476 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ine$ 'a2 field']"), &list));
6478 ole_check(IXMLDOMNodeList_get_length(list, &len));
6479 ok(len != 0, "expected filled list\n");
6481 expect_list_and_release(list, "E1.E2.D1 E3.E2.D1 E4.E2.D1");
6484 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ilt$ 'a3 field']"), &list));
6486 ole_check(IXMLDOMNodeList_get_length(list, &len));
6487 ok(len != 0, "expected filled list\n");
6489 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6492 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ile$ 'a2 field']"), &list));
6494 ole_check(IXMLDOMNodeList_get_length(list, &len));
6495 ok(len != 0, "expected filled list\n");
6497 expect_list_and_release(list, "E1.E2.D1 E2.E2.D1");
6500 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $igt$ 'a2 field']"), &list));
6502 ole_check(IXMLDOMNodeList_get_length(list, &len));
6503 ok(len != 0, "expected filled list\n");
6505 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6508 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[a $ige$ 'a3 field']"), &list));
6510 ole_check(IXMLDOMNodeList_get_length(list, &len));
6511 ok(len != 0, "expected filled list\n");
6513 expect_list_and_release(list, "E3.E2.D1 E4.E2.D1");
6516 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$any$ *='B2 field']"), &list));
6518 ole_check(IXMLDOMNodeList_get_length(list, &len));
6519 ok(len != 0, "expected filled list\n");
6521 expect_list_and_release(list, "E2.E2.D1");
6524 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[$all$ *!='B2 field']"), &list));
6526 ole_check(IXMLDOMNodeList_get_length(list, &len));
6527 ok(len != 0, "expected filled list\n");
6529 expect_list_and_release(list, "E1.E2.D1 E3.E2.D1 E4.E2.D1");
6532 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 or end()]"), &list));
6534 ole_check(IXMLDOMNodeList_get_length(list, &len));
6535 ok(len != 0, "expected filled list\n");
6537 expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6538 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 $or$ end()]"), &list));
6540 ole_check(IXMLDOMNodeList_get_length(list, &len));
6541 ok(len != 0, "expected filled list\n");
6543 expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6544 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()=0 || end()]"), &list));
6546 ole_check(IXMLDOMNodeList_get_length(list, &len));
6547 ok(len != 0, "expected filled list\n");
6549 expect_list_and_release(list, "E1.E2.D1 E4.E2.D1");
6552 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 and $not$ end()]"), &list));
6554 ole_check(IXMLDOMNodeList_get_length(list, &len));
6555 ok(len != 0, "expected filled list\n");
6557 expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6558 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 $and$ $not$ end()]"), &list));
6560 ole_check(IXMLDOMNodeList_get_length(list, &len));
6561 ok(len != 0, "expected filled list\n");
6563 expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6564 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[index()>0 && $not$ end()]"), &list));
6566 ole_check(IXMLDOMNodeList_get_length(list, &len));
6567 ok(len != 0, "expected filled list\n");
6569 expect_list_and_release(list, "E2.E2.D1 E3.E2.D1");
6571 /* namespace handling */
6572 /* no registered namespaces */
6573 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
6576 /* prefixes don't need to be registered, you may use them as they are in the doc */
6577 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//bar:x"), &list));
6579 ole_check(IXMLDOMNodeList_get_length(list, &len));
6580 ok(len != 0, "expected filled list\n");
6582 expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
6584 /* prefixes must be explicitly specified in the name */
6585 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:elem"), &list));
6587 ole_check(IXMLDOMNodeList_get_length(list, &len));
6588 ok(len == 0, "expected empty list\n");
6589 IXMLDOMNodeList_Release(list);
6591 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6593 ole_check(IXMLDOMNodeList_get_length(list, &len));
6594 ok(len != 0, "expected filled list\n");
6596 expect_list_and_release(list, "E3.E4.E2.D1");
6598 /* explicitly register prefix foo */
6599 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'")));
6601 /* now we get the same behavior as XPath */
6602 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6604 ole_check(IXMLDOMNodeList_get_length(list, &len));
6605 ok(len != 0, "expected filled list\n");
6607 expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1");
6609 /* set prefix foo to some nonexistent namespace */
6610 ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:foo='urn:nonexistent-foo'")));
6612 /* the registered prefix takes precedence */
6613 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//foo:c"), &list));
6615 ole_check(IXMLDOMNodeList_get_length(list, &len));
6616 ok(len == 0, "expected empty list\n");
6617 IXMLDOMNodeList_Release(list);
6619 IXMLDOMDocument2_Release(doc);
6621 doc = create_document(&IID_IXMLDOMDocument2);
6624 ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szNodeTypesXML), &b));
6625 ok(b == VARIANT_TRUE, "failed to load XML string\n");
6629 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute()"), &list));
6631 ole_check(IXMLDOMNodeList_get_length(list, &len));
6632 ok(len == 0, "expected empty list\n");
6633 IXMLDOMNodeList_Release(list);
6635 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute('depth')"), &list));
6637 ole_check(IXMLDOMNodeList_get_length(list, &len));
6638 ok(len == 0, "expected empty list\n");
6639 IXMLDOMNodeList_Release(list);
6641 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/attribute('depth')"), &list));
6643 ole_check(IXMLDOMNodeList_get_length(list, &len));
6644 ok(len != 0, "expected filled list\n");
6645 expect_list_and_release(list, "A'depth'.E3.D1");
6647 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/attribute()"), &list));
6649 ole_check(IXMLDOMNodeList_get_length(list, &len));
6650 ok(len != 0, "expected filled list\n");
6651 expect_list_and_release(list, "A'id'.E3.E3.D1 A'depth'.E3.E3.D1");
6654 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute(id)"), &list), E_FAIL);
6656 IXMLDOMNodeList_Release(list);
6657 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute('id')"), &list));
6659 ole_check(IXMLDOMNodeList_get_length(list, &len));
6660 ok(len != 0, "expected filled list\n");
6662 expect_list_and_release(list, "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1");
6665 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("comment()"), &list));
6667 ole_check(IXMLDOMNodeList_get_length(list, &len));
6668 ok(len != 0, "expected filled list\n");
6670 expect_list_and_release(list, "C2.D1");
6672 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//comment()"), &list));
6674 ole_check(IXMLDOMNodeList_get_length(list, &len));
6675 ok(len != 0, "expected filled list\n");
6677 expect_list_and_release(list, "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1");
6680 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("element()"), &list));
6682 ole_check(IXMLDOMNodeList_get_length(list, &len));
6683 ok(len != 0, "expected filled list\n");
6685 expect_list_and_release(list, "E3.D1");
6687 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/y/element()"), &list));
6689 ole_check(IXMLDOMNodeList_get_length(list, &len));
6690 ok(len != 0, "expected filled list\n");
6692 expect_list_and_release(list, "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1");
6695 ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element(a)"), &list), E_FAIL);
6697 IXMLDOMNodeList_Release(list);
6698 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element('a')"), &list));
6700 ole_check(IXMLDOMNodeList_get_length(list, &len));
6701 ok(len != 0, "expected filled list\n");
6703 expect_list_and_release(list, "E4.E3.E3.D1 E4.E4.E3.D1");
6706 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("node()"), &list));
6708 ole_check(IXMLDOMNodeList_get_length(list, &len));
6709 ok(len != 0, "expected filled list\n");
6711 expect_list_and_release(list, "P1.D1 C2.D1 E3.D1");
6713 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()"), &list));
6715 ole_check(IXMLDOMNodeList_get_length(list, &len));
6716 ok(len != 0, "expected filled list\n");
6718 expect_list_and_release(list, "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
6721 /* XML_ELEMENT_NODE */
6722 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=1]"), &list));
6724 ole_check(IXMLDOMNodeList_get_length(list, &len));
6725 ok(len != 0, "expected filled list\n");
6727 expect_list_and_release(list, "E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
6729 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=3]"), &list));
6731 ole_check(IXMLDOMNodeList_get_length(list, &len));
6732 ok(len != 0, "expected filled list\n");
6734 expect_list_and_release(list, "T3.E3.E3.D1");
6736 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=7]"), &list));
6738 ole_check(IXMLDOMNodeList_get_length(list, &len));
6739 ok(len != 0, "expected filled list\n");
6741 expect_list_and_release(list, "P1.E3.E3.D1");
6742 /* XML_COMMENT_NODE */
6743 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()[nodeType()=8]"), &list));
6745 ole_check(IXMLDOMNodeList_get_length(list, &len));
6746 ok(len != 0, "expected filled list\n");
6748 expect_list_and_release(list, "C2.E3.E3.D1");
6751 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("pi()"), &list));
6755 ole_check(IXMLDOMNodeList_get_length(list, &len));
6756 ok(len != 0, "expected filled list\n");
6758 expect_list_and_release(list, "P1.D1");
6761 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//y/pi()"), &list));
6763 ole_check(IXMLDOMNodeList_get_length(list, &len));
6764 ok(len != 0, "expected filled list\n");
6766 expect_list_and_release(list, "P1.E4.E3.D1");
6769 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/textnode()"), &list));
6771 ole_check(IXMLDOMNodeList_get_length(list, &len));
6772 ok(len != 0, "expected filled list\n");
6774 expect_list_and_release(list, "T2.E3.D1");
6776 ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/element()/textnode()"), &list));
6778 ole_check(IXMLDOMNodeList_get_length(list, &len));
6779 ok(len != 0, "expected filled list\n");
6781 expect_list_and_release(list, "T3.E3.E3.D1 T3.E4.E3.D1");
6783 IXMLDOMDocument2_Release(doc);
6787 static void test_splitText(void)
6789 IXMLDOMCDATASection *cdata;
6790 IXMLDOMElement *root;
6791 IXMLDOMDocument *doc;
6792 IXMLDOMText *text, *text2;
6795 VARIANT_BOOL success;
6799 doc = create_document(&IID_IXMLDOMDocument);
6802 hr = IXMLDOMDocument_loadXML(doc, _bstr_("<root></root>"), &success);
6803 ok(hr == S_OK, "got 0x%08x\n", hr);
6805 hr = IXMLDOMDocument_get_documentElement(doc, &root);
6806 ok(hr == S_OK, "got 0x%08x\n", hr);
6808 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("beautiful plumage"), &cdata);
6809 ok(hr == S_OK, "got 0x%08x\n", hr);
6811 V_VT(&var) = VT_EMPTY;
6812 hr = IXMLDOMElement_appendChild(root, (IXMLDOMNode*)cdata, NULL);
6813 ok(hr == S_OK, "got 0x%08x\n", hr);
6816 hr = IXMLDOMCDATASection_get_length(cdata, &length);
6817 ok(hr == S_OK, "got 0x%08x\n", hr);
6818 ok(length > 0, "got %d\n", length);
6820 hr = IXMLDOMCDATASection_splitText(cdata, 0, NULL);
6821 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6823 text = (void*)0xdeadbeef;
6824 /* negative offset */
6825 hr = IXMLDOMCDATASection_splitText(cdata, -1, &text);
6826 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6827 ok(text == (void*)0xdeadbeef, "got %p\n", text);
6829 text = (void*)0xdeadbeef;
6830 /* offset outside data */
6831 hr = IXMLDOMCDATASection_splitText(cdata, length + 1, &text);
6832 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6833 ok(text == 0, "got %p\n", text);
6835 text = (void*)0xdeadbeef;
6836 /* offset outside data */
6837 hr = IXMLDOMCDATASection_splitText(cdata, length, &text);
6838 ok(hr == S_FALSE, "got 0x%08x\n", hr);
6839 ok(text == 0, "got %p\n", text);
6841 /* no empty node created */
6842 node = (void*)0xdeadbeef;
6843 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
6844 ok(hr == S_FALSE, "got 0x%08x\n", hr);
6845 ok(node == 0, "got %p\n", text);
6847 hr = IXMLDOMCDATASection_splitText(cdata, 10, &text);
6848 ok(hr == S_OK, "got 0x%08x\n", hr);
6851 hr = IXMLDOMText_get_length(text, &length);
6852 ok(hr == S_OK, "got 0x%08x\n", hr);
6853 ok(length == 7, "got %d\n", length);
6855 hr = IXMLDOMCDATASection_get_nextSibling(cdata, &node);
6856 ok(hr == S_OK, "got 0x%08x\n", hr);
6857 IXMLDOMNode_Release(node);
6859 /* split new text node */
6860 hr = IXMLDOMText_get_length(text, &length);
6861 ok(hr == S_OK, "got 0x%08x\n", hr);
6863 node = (void*)0xdeadbeef;
6864 hr = IXMLDOMText_get_nextSibling(text, &node);
6865 ok(hr == S_FALSE, "got 0x%08x\n", hr);
6866 ok(node == 0, "got %p\n", text);
6868 hr = IXMLDOMText_splitText(text, 0, NULL);
6869 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6871 text2 = (void*)0xdeadbeef;
6872 /* negative offset */
6873 hr = IXMLDOMText_splitText(text, -1, &text2);
6874 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6875 ok(text2 == (void*)0xdeadbeef, "got %p\n", text2);
6877 text2 = (void*)0xdeadbeef;
6878 /* offset outside data */
6879 hr = IXMLDOMText_splitText(text, length + 1, &text2);
6880 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
6881 ok(text2 == 0, "got %p\n", text2);
6883 text2 = (void*)0xdeadbeef;
6884 /* offset outside data */
6885 hr = IXMLDOMText_splitText(text, length, &text2);
6886 ok(hr == S_FALSE, "got 0x%08x\n", hr);
6887 ok(text2 == 0, "got %p\n", text);
6890 hr = IXMLDOMText_splitText(text, 4, &text2);
6891 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
6892 if (text2) IXMLDOMText_Release(text2);
6895 hr = IXMLDOMText_get_nextSibling(text, &node);
6896 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
6897 if (node) IXMLDOMNode_Release(node);
6899 IXMLDOMText_Release(text);
6900 IXMLDOMElement_Release(root);
6901 IXMLDOMCDATASection_Release(cdata);
6905 static void test_getQualifiedItem(void)
6907 IXMLDOMDocument *doc;
6908 IXMLDOMElement *element;
6909 IXMLDOMNode *pr_node, *node;
6910 IXMLDOMNodeList *root_list;
6911 IXMLDOMNamedNodeMap *map;
6917 doc = create_document(&IID_IXMLDOMDocument);
6920 str = SysAllocString( szComplete4 );
6921 hr = IXMLDOMDocument_loadXML( doc, str, &b );
6922 ok( hr == S_OK, "loadXML failed\n");
6923 ok( b == VARIANT_TRUE, "failed to load XML string\n");
6924 SysFreeString( str );
6926 hr = IXMLDOMDocument_get_documentElement(doc, &element);
6927 ok( hr == S_OK, "ret %08x\n", hr);
6929 hr = IXMLDOMElement_get_childNodes(element, &root_list);
6930 ok( hr == S_OK, "ret %08x\n", hr);
6932 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
6933 ok( hr == S_OK, "ret %08x\n", hr);
6934 IXMLDOMNodeList_Release(root_list);
6936 hr = IXMLDOMNode_get_attributes(pr_node, &map);
6937 ok( hr == S_OK, "ret %08x\n", hr);
6938 IXMLDOMNode_Release(pr_node);
6940 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
6941 ok( hr == S_OK, "ret %08x\n", hr);
6942 ok( len == 3, "length %d\n", len);
6944 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, NULL);
6945 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6947 node = (void*)0xdeadbeef;
6948 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, NULL, NULL, &node);
6949 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6950 ok( node == (void*)0xdeadbeef, "got %p\n", node);
6952 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, NULL);
6953 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
6955 hr = IXMLDOMNamedNodeMap_getQualifiedItem(map, _bstr_("id"), NULL, &node);
6956 ok( hr == S_OK, "ret %08x\n", hr);
6957 IXMLDOMNode_Release(node);
6959 IXMLDOMNamedNodeMap_Release( map );
6960 IXMLDOMElement_Release( element );
6961 IXMLDOMDocument_Release( doc );
6965 static void test_removeQualifiedItem(void)
6967 IXMLDOMDocument *doc;
6968 IXMLDOMElement *element;
6969 IXMLDOMNode *pr_node, *node;
6970 IXMLDOMNodeList *root_list;
6971 IXMLDOMNamedNodeMap *map;
6977 doc = create_document(&IID_IXMLDOMDocument);
6980 str = SysAllocString( szComplete4 );
6981 hr = IXMLDOMDocument_loadXML( doc, str, &b );
6982 ok( hr == S_OK, "loadXML failed\n");
6983 ok( b == VARIANT_TRUE, "failed to load XML string\n");
6984 SysFreeString( str );
6986 hr = IXMLDOMDocument_get_documentElement(doc, &element);
6987 ok( hr == S_OK, "ret %08x\n", hr);
6989 hr = IXMLDOMElement_get_childNodes(element, &root_list);
6990 ok( hr == S_OK, "ret %08x\n", hr);
6992 hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node);
6993 ok( hr == S_OK, "ret %08x\n", hr);
6994 IXMLDOMNodeList_Release(root_list);
6996 hr = IXMLDOMNode_get_attributes(pr_node, &map);
6997 ok( hr == S_OK, "ret %08x\n", hr);
6998 IXMLDOMNode_Release(pr_node);
7000 hr = IXMLDOMNamedNodeMap_get_length(map, &len);
7001 ok( hr == S_OK, "ret %08x\n", hr);
7002 ok( len == 3, "length %d\n", len);
7004 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL);
7005 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7007 node = (void*)0xdeadbeef;
7008 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node);
7009 ok( hr == E_INVALIDARG, "ret %08x\n", hr);
7010 ok( node == (void*)0xdeadbeef, "got %p\n", node);
7012 /* out pointer is optional */
7013 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7014 ok( hr == S_OK, "ret %08x\n", hr);
7016 /* already removed */
7017 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL);
7018 ok( hr == S_FALSE, "ret %08x\n", hr);
7020 hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node);
7021 ok( hr == S_OK, "ret %08x\n", hr);
7022 IXMLDOMNode_Release(node);
7024 IXMLDOMNamedNodeMap_Release( map );
7025 IXMLDOMElement_Release( element );
7026 IXMLDOMDocument_Release( doc );
7030 #define check_default_props(doc) _check_default_props(__LINE__, doc)
7031 static inline void _check_default_props(int line, IXMLDOMDocument2* doc)
7038 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7039 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XSLPattern")) == 0, "expected XSLPattern\n");
7042 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7043 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("")) == 0, "expected empty string\n");
7046 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7047 ok_(__FILE__, line)(b == VARIANT_FALSE, "expected FALSE\n");
7049 hr = IXMLDOMDocument2_get_schemas(doc, &var);
7050 ok_(__FILE__, line)(hr == S_FALSE, "got %08x\n", hr);
7054 #define check_set_props(doc) _check_set_props(__LINE__, doc)
7055 static inline void _check_set_props(int line, IXMLDOMDocument2* doc)
7061 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &var));
7062 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("XPath")) == 0, "expected XPath\n");
7065 helper_ole_check(IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionNamespaces"), &var));
7066 ok_(__FILE__, line)(lstrcmpW(V_BSTR(&var), _bstr_("xmlns:wi=\'www.winehq.org\'")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
7069 helper_ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc, &b));
7070 ok_(__FILE__, line)(b == VARIANT_TRUE, "expected TRUE\n");
7072 helper_ole_check(IXMLDOMDocument2_get_schemas(doc, &var));
7073 ok_(__FILE__, line)(V_VT(&var) != VT_NULL, "expected pointer\n");
7077 #define set_props(doc, cache) _set_props(__LINE__, doc, cache)
7078 static inline void _set_props(int line, IXMLDOMDocument2* doc, IXMLDOMSchemaCollection* cache)
7083 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XPath")));
7084 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("xmlns:wi=\'www.winehq.org\'")));
7085 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_TRUE));
7086 V_VT(&var) = VT_DISPATCH;
7087 V_DISPATCH(&var) = NULL;
7088 helper_ole_check(IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&var)));
7089 ok_(__FILE__, line)(V_DISPATCH(&var) != NULL, "expected pointer\n");
7090 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7094 #define unset_props(doc) _unset_props(__LINE__, doc)
7095 static inline void _unset_props(int line, IXMLDOMDocument2* doc)
7100 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
7101 helper_ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), _variantbstr_("")));
7102 helper_ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc, VARIANT_FALSE));
7103 V_VT(&var) = VT_NULL;
7104 helper_ole_check(IXMLDOMDocument2_putref_schemas(doc, var));
7108 static void test_get_ownerDocument(void)
7110 IXMLDOMDocument *doc1, *doc2, *doc3;
7111 IXMLDOMDocument2 *doc, *doc_owner;
7113 IXMLDOMSchemaCollection *cache;
7118 doc = create_document(&IID_IXMLDOMDocument2);
7119 cache = create_cache(&IID_IXMLDOMSchemaCollection);
7122 if (doc) IXMLDOMDocument2_Release(doc);
7123 if (cache) IXMLDOMSchemaCollection_Release(cache);
7129 str = SysAllocString(szComplete4);
7130 ole_check(IXMLDOMDocument_loadXML(doc, str, &b));
7131 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7134 check_default_props(doc);
7136 /* set properties and check that new instances use them */
7137 set_props(doc, cache);
7138 check_set_props(doc);
7140 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7141 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc1));
7143 /* new interface keeps props */
7144 ole_check(IXMLDOMDocument_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7145 ok( doc_owner != doc, "got %p, doc %p\n", doc_owner, doc);
7146 check_set_props(doc_owner);
7147 IXMLDOMDocument2_Release(doc_owner);
7149 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc2));
7150 IXMLDOMNode_Release(node);
7152 ok(doc1 != doc2, "got %p, expected %p. original %p\n", doc2, doc1, doc);
7155 str = SysAllocString(szComplete4);
7156 ole_check(IXMLDOMDocument2_loadXML(doc, str, &b));
7157 ok(b == VARIANT_TRUE, "failed to load XML string\n");
7160 /* properties retained even after reload */
7161 check_set_props(doc);
7163 ole_check(IXMLDOMDocument2_get_firstChild(doc, &node));
7164 ole_check(IXMLDOMNode_get_ownerDocument(node, &doc3));
7165 IXMLDOMNode_Release(node);
7167 ole_check(IXMLDOMDocument_QueryInterface(doc3, &IID_IXMLDOMDocument2, (void**)&doc_owner));
7168 ok(doc3 != doc1 && doc3 != doc2 && doc_owner != doc, "got %p, (%p, %p, %p)\n", doc3, doc, doc1, doc2);
7169 check_set_props(doc_owner);
7171 /* changing properties for one instance changes them for all */
7172 unset_props(doc_owner);
7173 check_default_props(doc_owner);
7174 check_default_props(doc);
7176 IXMLDOMSchemaCollection_Release(cache);
7177 IXMLDOMDocument_Release(doc1);
7178 IXMLDOMDocument_Release(doc2);
7179 IXMLDOMDocument_Release(doc3);
7180 IXMLDOMDocument2_Release(doc);
7181 IXMLDOMDocument2_Release(doc_owner);
7185 static void test_setAttributeNode(void)
7187 IXMLDOMDocument *doc, *doc2;
7188 IXMLDOMElement *elem, *elem2;
7189 IXMLDOMAttribute *attr, *attr2, *ret_attr;
7196 doc = create_document(&IID_IXMLDOMDocument);
7199 str = SysAllocString( szComplete4 );
7200 hr = IXMLDOMDocument2_loadXML( doc, str, &b );
7201 ok( hr == S_OK, "loadXML failed\n");
7202 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7203 SysFreeString( str );
7205 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7206 ok( hr == S_OK, "got 0x%08x\n", hr);
7208 hr = IXMLDOMDocument_get_documentElement(doc, &elem2);
7209 ok( hr == S_OK, "got 0x%08x\n", hr);
7210 ok( elem2 != elem, "got same instance\n");
7212 ret_attr = (void*)0xdeadbeef;
7213 hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr);
7214 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7215 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7217 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7218 ok( hr == S_OK, "got 0x%08x\n", hr);
7220 ref1 = IXMLDOMElement_AddRef(elem);
7221 IXMLDOMElement_Release(elem);
7223 ret_attr = (void*)0xdeadbeef;
7224 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7225 ok( hr == S_OK, "got 0x%08x\n", hr);
7226 ok( ret_attr == NULL, "got %p\n", ret_attr);
7228 /* no reference added */
7229 ref2 = IXMLDOMElement_AddRef(elem);
7230 IXMLDOMElement_Release(elem);
7231 ok(ref2 == ref1, "got %d, expected %d\n", ref2, ref1);
7233 EXPECT_CHILDREN(elem);
7234 EXPECT_CHILDREN(elem2);
7236 IXMLDOMElement_Release(elem2);
7239 hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
7240 ok( hr == S_OK, "got 0x%08x\n", hr);
7241 ok( attr2 != attr, "got same instance %p\n", attr2);
7242 IXMLDOMAttribute_Release(attr2);
7244 /* try to add it another time */
7245 ret_attr = (void*)0xdeadbeef;
7246 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7247 ok( hr == E_FAIL, "got 0x%08x\n", hr);
7248 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7250 IXMLDOMElement_Release(elem);
7252 /* initialy used element is released, attribute still 'has' a container */
7253 hr = IXMLDOMDocument_get_documentElement(doc, &elem);
7254 ok( hr == S_OK, "got 0x%08x\n", hr);
7255 ret_attr = (void*)0xdeadbeef;
7256 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7257 ok( hr == E_FAIL, "got 0x%08x\n", hr);
7258 ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
7259 IXMLDOMElement_Release(elem);
7261 /* add attribute already attached to another document */
7262 doc2 = create_document(&IID_IXMLDOMDocument);
7264 str = SysAllocString( szComplete4 );
7265 hr = IXMLDOMDocument_loadXML( doc2, str, &b );
7266 ok( hr == S_OK, "loadXML failed\n");
7267 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7268 SysFreeString( str );
7270 hr = IXMLDOMDocument_get_documentElement(doc2, &elem);
7271 ok( hr == S_OK, "got 0x%08x\n", hr);
7272 hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL);
7273 ok( hr == E_FAIL, "got 0x%08x\n", hr);
7274 IXMLDOMElement_Release(elem);
7276 IXMLDOMAttribute_Release(attr);
7278 /* create element, add attribute, see if it's copied or linked */
7279 hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
7280 ok( hr == S_OK, "got 0x%08x\n", hr);
7283 hr = IXMLDOMDocument_createAttribute(doc, _bstr_("attr"), &attr);
7284 ok(hr == S_OK, "got 0x%08x\n", hr);
7285 ok(attr != NULL, "got %p\n", attr);
7287 ref1 = IXMLDOMAttribute_AddRef(attr);
7288 IXMLDOMAttribute_Release(attr);
7291 V_BSTR(&v) = _bstr_("attrvalue1");
7292 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
7293 ok( hr == S_OK, "got 0x%08x\n", hr);
7296 hr = IXMLDOMAttribute_get_xml(attr, &str);
7297 ok( hr == S_OK, "got 0x%08x\n", hr);
7298 ok( lstrcmpW(str, _bstr_("attr=\"attrvalue1\"")) == 0,
7299 "got %s\n", wine_dbgstr_w(str));
7302 ret_attr = (void*)0xdeadbeef;
7303 hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
7304 ok(hr == S_OK, "got 0x%08x\n", hr);
7305 ok(ret_attr == NULL, "got %p\n", ret_attr);
7307 /* attribute reference increased */
7308 ref2 = IXMLDOMAttribute_AddRef(attr);
7309 IXMLDOMAttribute_Release(attr);
7310 ok(ref1 == ref2, "got %d, expected %d\n", ref2, ref1);
7312 hr = IXMLDOMElement_get_xml(elem, &str);
7313 ok( hr == S_OK, "got 0x%08x\n", hr);
7314 ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue1\"/>")) == 0,
7315 "got %s\n", wine_dbgstr_w(str));
7319 V_BSTR(&v) = _bstr_("attrvalue2");
7320 hr = IXMLDOMAttribute_put_nodeValue(attr, v);
7321 ok( hr == S_OK, "got 0x%08x\n", hr);
7323 hr = IXMLDOMElement_get_xml(elem, &str);
7324 ok( hr == S_OK, "got 0x%08x\n", hr);
7325 todo_wine ok( lstrcmpW(str, _bstr_("<test attr=\"attrvalue2\"/>")) == 0,
7326 "got %s\n", wine_dbgstr_w(str));
7329 IXMLDOMElement_Release(elem);
7330 IXMLDOMAttribute_Release(attr);
7331 IXMLDOMDocument_Release(doc2);
7332 IXMLDOMDocument_Release(doc);
7335 static void test_put_dataType(void)
7337 IXMLDOMCDATASection *cdata;
7338 IXMLDOMDocument *doc;
7343 doc = create_document(&IID_IXMLDOMDocument);
7346 str = SysAllocString( szComplete4 );
7347 hr = IXMLDOMDocument_loadXML( doc, str, &b );
7348 ok( hr == S_OK, "loadXML failed\n");
7349 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7350 SysFreeString( str );
7352 hr = IXMLDOMDocument_createCDATASection(doc, _bstr_("test"), &cdata);
7353 ok( hr == S_OK, "got 0x%08x\n", hr);
7354 hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("number"));
7355 ok( hr == E_FAIL, "got 0x%08x\n", hr);
7356 hr = IXMLDOMCDATASection_put_dataType(cdata, _bstr_("string"));
7357 ok( hr == E_FAIL, "got 0x%08x\n", hr);
7358 IXMLDOMCDATASection_Release(cdata);
7360 IXMLDOMDocument_Release(doc);
7364 static void test_createNode(void)
7366 IXMLDOMDocument *doc;
7367 IXMLDOMElement *elem;
7374 doc = create_document(&IID_IXMLDOMDocument);
7379 /* reference count tests */
7380 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
7381 ok( hr == S_OK, "got 0x%08x\n", hr);
7383 /* initial reference is 2 */
7385 EXPECT_REF(elem, 2);
7386 ref = IXMLDOMElement_Release(elem);
7387 ok(ref == 1, "got %d\n", ref);
7388 /* it's released already, attempt to release now will crash it */
7391 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
7392 ok( hr == S_OK, "got 0x%08x\n", hr);
7393 todo_wine EXPECT_REF(elem, 2);
7394 IXMLDOMDocument_Release(doc);
7395 todo_wine EXPECT_REF(elem, 2);
7396 IXMLDOMElement_Release(elem);
7398 doc = create_document(&IID_IXMLDOMDocument);
7400 /* NODE_ELEMENT nodes */
7401 /* 1. specified namespace */
7403 V_I4(&v) = NODE_ELEMENT;
7405 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("ns1:test"), _bstr_("http://winehq.org"), &node);
7406 ok( hr == S_OK, "got 0x%08x\n", hr);
7408 hr = IXMLDOMNode_get_prefix(node, &prefix);
7409 ok( hr == S_OK, "got 0x%08x\n", hr);
7410 ok(lstrcmpW(prefix, _bstr_("ns1")) == 0, "wrong prefix\n");
7411 SysFreeString(prefix);
7412 IXMLDOMNode_Release(node);
7414 /* 2. default namespace */
7415 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("test"), _bstr_("http://winehq.org/default"), &node);
7416 ok( hr == S_OK, "got 0x%08x\n", hr);
7417 prefix = (void*)0xdeadbeef;
7418 hr = IXMLDOMNode_get_prefix(node, &prefix);
7419 ok( hr == S_FALSE, "got 0x%08x\n", hr);
7420 ok(prefix == 0, "expected empty prefix, got %p\n", prefix);
7422 hr = IXMLDOMNode_get_xml(node, &str);
7423 ok( hr == S_OK, "got 0x%08x\n", hr);
7424 ok( lstrcmpW(str, _bstr_("<test xmlns=\"http://winehq.org/default\"/>")) == 0,
7425 "got %s\n", wine_dbgstr_w(str));
7428 hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)&elem);
7429 ok( hr == S_OK, "got 0x%08x\n", hr);
7431 V_VT(&var) = VT_BSTR;
7432 hr = IXMLDOMElement_getAttribute(elem, _bstr_("xmlns"), &var);
7433 ok( hr == S_FALSE, "got 0x%08x\n", hr);
7434 ok( V_VT(&var) == VT_NULL, "got %d\n", V_VT(&var));
7437 hr = IXMLDOMElement_get_namespaceURI(elem, &str);
7438 ok( hr == S_OK, "got 0x%08x\n", hr);
7439 ok( lstrcmpW(str, _bstr_("http://winehq.org/default")) == 0, "expected default namespace\n");
7442 IXMLDOMElement_Release(elem);
7443 IXMLDOMNode_Release(node);
7445 IXMLDOMDocument_Release(doc);
7449 static void test_get_prefix(void)
7451 IXMLDOMDocumentFragment *fragment;
7452 IXMLDOMCDATASection *cdata;
7453 IXMLDOMElement *element;
7454 IXMLDOMComment *comment;
7455 IXMLDOMDocument *doc;
7459 doc = create_document(&IID_IXMLDOMDocument);
7462 /* nodes that can't support prefix */
7464 str = (void*)0xdeadbeef;
7465 hr = IXMLDOMDocument_get_prefix(doc, &str);
7466 ok( hr == S_FALSE, "got 0x%08x\n", hr);
7467 ok( str == 0, "got %p\n", str);
7469 hr = IXMLDOMDocument_get_prefix(doc, NULL);
7470 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7473 hr = IXMLDOMDocument_createCDATASection(doc, NULL, &cdata);
7474 ok(hr == S_OK, "got %08x\n", hr );
7476 str = (void*)0xdeadbeef;
7477 hr = IXMLDOMCDATASection_get_prefix(cdata, &str);
7478 ok(hr == S_FALSE, "got %08x\n", hr);
7479 ok( str == 0, "got %p\n", str);
7481 hr = IXMLDOMCDATASection_get_prefix(cdata, NULL);
7482 ok(hr == E_INVALIDARG, "got %08x\n", hr);
7483 IXMLDOMCDATASection_Release(cdata);
7486 hr = IXMLDOMDocument_createComment(doc, NULL, &comment);
7487 ok(hr == S_OK, "got %08x\n", hr );
7489 str = (void*)0xdeadbeef;
7490 hr = IXMLDOMComment_get_prefix(comment, &str);
7491 ok(hr == S_FALSE, "got %08x\n", hr);
7492 ok( str == 0, "got %p\n", str);
7494 hr = IXMLDOMComment_get_prefix(comment, NULL);
7495 ok(hr == E_INVALIDARG, "got %08x\n", hr);
7496 IXMLDOMComment_Release(comment);
7499 hr = IXMLDOMDocument_createDocumentFragment(doc, &fragment);
7500 ok(hr == S_OK, "got %08x\n", hr );
7502 str = (void*)0xdeadbeef;
7503 hr = IXMLDOMDocumentFragment_get_prefix(fragment, &str);
7504 ok(hr == S_FALSE, "got %08x\n", hr);
7505 ok( str == 0, "got %p\n", str);
7507 hr = IXMLDOMDocumentFragment_get_prefix(fragment, NULL);
7508 ok(hr == E_INVALIDARG, "got %08x\n", hr);
7509 IXMLDOMDocumentFragment_Release(fragment);
7512 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &element);
7513 ok( hr == S_OK, "got 0x%08x\n", hr);
7515 hr = IXMLDOMElement_get_prefix(element, NULL);
7516 ok( hr == E_INVALIDARG, "got 0x%08x\n", hr);
7518 str = (void*)0xdeadbeef;
7519 hr = IXMLDOMElement_get_prefix(element, &str);
7520 ok( hr == S_FALSE, "got 0x%08x\n", hr);
7521 ok( str == 0, "got %p\n", str);
7523 IXMLDOMElement_Release(element);
7526 hr = IXMLDOMDocument_createElement(doc, _bstr_("a:elem"), &element);
7527 ok( hr == S_OK, "got 0x%08x\n", hr);
7529 str = (void*)0xdeadbeef;
7530 hr = IXMLDOMElement_get_prefix(element, &str);
7531 ok( hr == S_OK, "got 0x%08x\n", hr);
7532 ok( lstrcmpW(str, _bstr_("a")) == 0, "expected prefix \"a\"\n");
7535 str = (void*)0xdeadbeef;
7536 hr = IXMLDOMElement_get_namespaceURI(element, &str);
7537 ok( hr == S_FALSE, "got 0x%08x\n", hr);
7538 ok( str == 0, "got %p\n", str);
7540 IXMLDOMElement_Release(element);
7542 IXMLDOMDocument_Release(doc);
7546 static void test_selectSingleNode(void)
7548 IXMLDOMDocument *doc;
7549 IXMLDOMNodeList *list;
7556 doc = create_document(&IID_IXMLDOMDocument);
7559 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
7560 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7562 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
7563 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7565 str = SysAllocString( szComplete4 );
7566 hr = IXMLDOMDocument_loadXML( doc, str, &b );
7567 ok( hr == S_OK, "loadXML failed\n");
7568 ok( b == VARIANT_TRUE, "failed to load XML string\n");
7569 SysFreeString( str );
7571 hr = IXMLDOMDocument_selectSingleNode(doc, NULL, NULL);
7572 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7574 hr = IXMLDOMDocument_selectNodes(doc, NULL, NULL);
7575 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7577 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), NULL);
7578 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7580 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), NULL);
7581 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7583 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc"), &node);
7584 ok(hr == S_OK, "got 0x%08x\n", hr);
7585 IXMLDOMNode_Release(node);
7587 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("lc"), &list);
7588 ok(hr == S_OK, "got 0x%08x\n", hr);
7589 IXMLDOMNodeList_Release(list);
7591 list = (void*)0xdeadbeef;
7592 hr = IXMLDOMDocument_selectNodes(doc, NULL, &list);
7593 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7594 ok(list == (void*)0xdeadbeef, "got %p\n", list);
7596 node = (void*)0xdeadbeef;
7597 hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("nonexistent"), &node);
7598 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7599 ok(node == 0, "got %p\n", node);
7601 list = (void*)0xdeadbeef;
7602 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("nonexistent"), &list);
7603 ok(hr == S_OK, "got 0x%08x\n", hr);
7605 hr = IXMLDOMNodeList_get_length(list, &len);
7606 ok(hr == S_OK, "got 0x%08x\n", hr);
7607 ok(len == 0, "got %d\n", len);
7608 IXMLDOMNodeList_Release(list);
7610 IXMLDOMDocument_Release(doc);
7614 static void test_events(void)
7616 IConnectionPointContainer *conn;
7617 IConnectionPoint *point;
7618 IXMLDOMDocument *doc;
7623 doc = create_document(&IID_IXMLDOMDocument);
7626 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&conn);
7627 ok(hr == S_OK, "got 0x%08x\n", hr);
7629 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IDispatch, &point);
7630 ok(hr == S_OK, "got 0x%08x\n", hr);
7631 IConnectionPoint_Release(point);
7632 hr = IConnectionPointContainer_FindConnectionPoint(conn, &IID_IPropertyNotifySink, &point);
7633 ok(hr == S_OK, "got 0x%08x\n", hr);
7634 IConnectionPoint_Release(point);
7635 hr = IConnectionPointContainer_FindConnectionPoint(conn, &DIID_XMLDOMDocumentEvents, &point);
7636 ok(hr == S_OK, "got 0x%08x\n", hr);
7637 IConnectionPoint_Release(point);
7639 IConnectionPointContainer_Release(conn);
7641 /* ready state callback */
7643 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7644 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
7646 event = create_dispevent();
7647 V_VT(&v) = VT_UNKNOWN;
7648 V_UNKNOWN(&v) = (IUnknown*)event;
7650 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7651 ok(hr == S_OK, "got 0x%08x\n", hr);
7652 EXPECT_REF(event, 2);
7654 V_VT(&v) = VT_DISPATCH;
7655 V_DISPATCH(&v) = event;
7657 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7658 ok(hr == S_OK, "got 0x%08x\n", hr);
7659 EXPECT_REF(event, 2);
7661 /* VT_NULL doesn't reset event handler */
7663 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7664 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
7665 EXPECT_REF(event, 2);
7667 V_VT(&v) = VT_DISPATCH;
7668 V_DISPATCH(&v) = NULL;
7670 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7671 ok(hr == S_OK, "got 0x%08x\n", hr);
7672 EXPECT_REF(event, 1);
7674 V_VT(&v) = VT_UNKNOWN;
7675 V_DISPATCH(&v) = NULL;
7676 hr = IXMLDOMDocument_put_onreadystatechange(doc, v);
7677 ok(hr == S_OK, "got 0x%08x\n", hr);
7679 IDispatch_Release(event);
7681 IXMLDOMDocument_Release(doc);
7684 static void test_createProcessingInstruction(void)
7686 static const WCHAR bodyW[] = {'t','e','s','t',0};
7687 IXMLDOMProcessingInstruction *pi;
7688 IXMLDOMDocument *doc;
7692 doc = create_document(&IID_IXMLDOMDocument);
7695 /* test for BSTR handling, pass broken BSTR */
7696 memcpy(&buff[2], bodyW, sizeof(bodyW));
7697 /* just a big length */
7698 *(DWORD*)buff = 0xf0f0;
7699 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("test"), &buff[2], &pi);
7700 ok(hr == S_OK, "got 0x%08x\n", hr);
7702 IXMLDOMProcessingInstruction_Release(pi);
7703 IXMLDOMDocument_Release(doc);
7706 static void test_put_nodeTypedValue(void)
7708 IXMLDOMDocument *doc;
7709 IXMLDOMElement *elem;
7713 doc = create_document(&IID_IXMLDOMDocument);
7716 hr = IXMLDOMDocument_createElement(doc, _bstr_("Element"), &elem);
7717 ok(hr == S_OK, "got 0x%08x\n", hr);
7719 V_VT(&type) = VT_EMPTY;
7720 hr = IXMLDOMElement_get_dataType(elem, &type);
7721 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7722 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
7724 /* set typed value for untyped node */
7725 V_VT(&type) = VT_I1;
7727 hr = IXMLDOMElement_put_nodeTypedValue(elem, type);
7728 ok(hr == S_OK, "got 0x%08x\n", hr);
7730 V_VT(&type) = VT_EMPTY;
7731 hr = IXMLDOMElement_get_dataType(elem, &type);
7732 ok(hr == S_FALSE, "got 0x%08x\n", hr);
7733 ok(V_VT(&type) == VT_NULL, "got %d, expected VT_NULL\n", V_VT(&type));
7735 /* no type info stored */
7736 V_VT(&type) = VT_EMPTY;
7737 hr = IXMLDOMElement_get_nodeTypedValue(elem, &type);
7738 ok(hr == S_OK, "got 0x%08x\n", hr);
7739 ok(V_VT(&type) == VT_BSTR, "got %d, expected VT_BSTR\n", V_VT(&type));
7740 ok(memcmp(V_BSTR(&type), _bstr_("1"), 2*sizeof(WCHAR)) == 0,
7741 "got %s, expected \"1\"\n", wine_dbgstr_w(V_BSTR(&type)));
7742 VariantClear(&type);
7744 IXMLDOMElement_Release(elem);
7745 IXMLDOMDocument_Release(doc);
7749 static void test_get_xml(void)
7751 static const char xmlA[] = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n<a>test</a>\r\n";
7752 IXMLDOMProcessingInstruction *pi;
7754 IXMLDOMDocument *doc;
7760 doc = create_document(&IID_IXMLDOMDocument);
7764 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
7765 ok(hr == S_OK, "got 0x%08x\n", hr);
7766 ok( b == VARIANT_TRUE, "got %d\n", b);
7768 hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
7769 _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
7770 ok(hr == S_OK, "got 0x%08x\n", hr);
7772 hr = IXMLDOMDocument_get_firstChild(doc, &first);
7773 ok(hr == S_OK, "got 0x%08x\n", hr);
7775 V_UNKNOWN(&v) = (IUnknown*)first;
7776 V_VT(&v) = VT_UNKNOWN;
7778 hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
7779 ok(hr == S_OK, "got 0x%08x\n", hr);
7781 IXMLDOMProcessingInstruction_Release(pi);
7782 IXMLDOMNode_Release(first);
7784 hr = IXMLDOMDocument_get_xml(doc, &xml);
7785 ok(hr == S_OK, "got 0x%08x\n", hr);
7787 ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
7788 "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
7791 IXMLDOMDocument_Release(doc);
7795 static void test_xsltemplate(void)
7797 IXSLTemplate *template;
7798 IXSLProcessor *processor;
7799 IXMLDOMDocument *doc, *doc2;
7806 template = create_xsltemplate(&IID_IXSLTemplate);
7807 if (!template) return;
7809 /* works as reset */
7810 hr = IXSLTemplate_putref_stylesheet(template, NULL);
7811 ok(hr == S_OK, "got 0x%08x\n", hr);
7813 doc = create_document(&IID_IXMLDOMDocument);
7816 hr = IXMLDOMDocument_loadXML( doc, _bstr_("<a>test</a>"), &b );
7817 ok(hr == S_OK, "got 0x%08x\n", hr);
7818 ok( b == VARIANT_TRUE, "got %d\n", b);
7820 /* putref with non-xsl document */
7821 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7822 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
7825 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
7826 ok(hr == S_OK, "got 0x%08x\n", hr);
7827 ok( b == VARIANT_TRUE, "got %d\n", b);
7829 /* not a freethreaded document */
7830 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7831 todo_wine ok(hr == E_FAIL, "got 0x%08x\n", hr);
7833 IXMLDOMDocument_Release(doc);
7835 hr = CoCreateInstance(&CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc);
7838 win_skip("failed to create free threaded document instance: 0x%08x\n", hr);
7839 IXSLTemplate_Release(template);
7844 hr = IXMLDOMDocument_loadXML( doc, _bstr_(szTransformSSXML), &b );
7845 ok(hr == S_OK, "got 0x%08x\n", hr);
7846 ok( b == VARIANT_TRUE, "got %d\n", b);
7848 /* freethreaded document */
7849 ref1 = IXMLDOMDocument_AddRef(doc);
7850 IXMLDOMDocument_Release(doc);
7851 hr = IXSLTemplate_putref_stylesheet(template, (IXMLDOMNode*)doc);
7852 ok(hr == S_OK, "got 0x%08x\n", hr);
7853 ref2 = IXMLDOMDocument_AddRef(doc);
7854 IXMLDOMDocument_Release(doc);
7855 ok(ref2 > ref1, "got %d\n", ref2);
7858 hr = IXSLTemplate_createProcessor(template, NULL);
7859 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7861 EXPECT_REF(template, 1);
7862 hr = IXSLTemplate_createProcessor(template, &processor);
7863 ok(hr == S_OK, "got 0x%08x\n", hr);
7864 EXPECT_REF(template, 2);
7866 /* input no set yet */
7869 hr = IXSLProcessor_get_input(processor, &v);
7871 ok(hr == S_OK, "got 0x%08x\n", hr);
7872 ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v));
7875 hr = IXSLProcessor_get_output(processor, NULL);
7876 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7878 /* reset before it was set */
7879 V_VT(&v) = VT_EMPTY;
7880 hr = IXSLProcessor_put_output(processor, v);
7881 ok(hr == S_OK, "got 0x%08x\n", hr);
7883 CreateStreamOnHGlobal(NULL, TRUE, &stream);
7884 EXPECT_REF(stream, 1);
7886 V_VT(&v) = VT_UNKNOWN;
7887 V_UNKNOWN(&v) = (IUnknown*)stream;
7888 hr = IXSLProcessor_put_output(processor, v);
7889 ok(hr == S_OK, "got 0x%08x\n", hr);
7891 /* it seems processor grabs 2 references */
7892 todo_wine EXPECT_REF(stream, 3);
7894 V_VT(&v) = VT_EMPTY;
7895 hr = IXSLProcessor_get_output(processor, &v);
7896 ok(hr == S_OK, "got 0x%08x\n", hr);
7897 ok(V_VT(&v) == VT_UNKNOWN, "got type %d\n", V_VT(&v));
7898 ok(V_UNKNOWN(&v) == (IUnknown*)stream, "got %p\n", V_UNKNOWN(&v));
7900 todo_wine EXPECT_REF(stream, 4);
7903 hr = IXSLProcessor_transform(processor, NULL);
7904 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7906 /* reset and check stream refcount */
7907 V_VT(&v) = VT_EMPTY;
7908 hr = IXSLProcessor_put_output(processor, v);
7909 ok(hr == S_OK, "got 0x%08x\n", hr);
7911 EXPECT_REF(stream, 1);
7913 IStream_Release(stream);
7915 /* no output interface set, check output */
7916 doc2 = create_document(&IID_IXMLDOMDocument);
7919 hr = IXMLDOMDocument_loadXML( doc2, _bstr_("<a>test</a>"), &b );
7920 ok(hr == S_OK, "got 0x%08x\n", hr);
7921 ok( b == VARIANT_TRUE, "got %d\n", b);
7923 V_VT(&v) = VT_UNKNOWN;
7924 V_UNKNOWN(&v) = (IUnknown*)doc2;
7925 hr = IXSLProcessor_put_input(processor, v);
7926 ok(hr == S_OK, "got 0x%08x\n", hr);
7928 hr = IXSLProcessor_transform(processor, &b);
7929 ok(hr == S_OK, "got 0x%08x\n", hr);
7931 V_VT(&v) = VT_EMPTY;
7932 hr = IXSLProcessor_get_output(processor, &v);
7933 ok(hr == S_OK, "got 0x%08x\n", hr);
7934 ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
7935 /* we currently output one '\n' instead of empty string */
7936 todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
7937 IXMLDOMDocument_Release(doc2);
7940 IXSLProcessor_Release(processor);
7942 /* drop reference */
7943 hr = IXSLTemplate_putref_stylesheet(template, NULL);
7944 ok(hr == S_OK, "got 0x%08x\n", hr);
7945 ref2 = IXMLDOMDocument_AddRef(doc);
7946 IXMLDOMDocument_Release(doc);
7947 ok(ref2 == ref1, "got %d\n", ref2);
7949 IXMLDOMDocument_Release(doc);
7950 IXSLTemplate_Release(template);
7954 static void test_insertBefore(void)
7956 IXMLDOMDocument *doc, *doc2;
7957 IXMLDOMAttribute *attr;
7958 IXMLDOMElement *elem1, *elem2, *elem3, *elem4, *elem5;
7959 IXMLDOMNode *node, *newnode;
7964 doc = create_document(&IID_IXMLDOMDocument);
7966 /* insertBefore behaviour for attribute node */
7968 V_I4(&v) = NODE_ATTRIBUTE;
7971 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr"), NULL, (IXMLDOMNode**)&attr);
7972 ok(hr == S_OK, "got 0x%08x\n", hr);
7973 ok(attr != NULL, "got %p\n", attr);
7975 /* attribute to attribute */
7977 V_I4(&v) = NODE_ATTRIBUTE;
7979 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("attr2"), NULL, &newnode);
7980 ok(hr == S_OK, "got 0x%08x\n", hr);
7981 ok(newnode != NULL, "got %p\n", newnode);
7984 node = (void*)0xdeadbeef;
7985 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7986 ok(hr == E_FAIL, "got 0x%08x\n", hr);
7987 ok(node == NULL, "got %p\n", node);
7989 V_VT(&v) = VT_UNKNOWN;
7990 V_UNKNOWN(&v) = (IUnknown*)attr;
7991 node = (void*)0xdeadbeef;
7992 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
7993 todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
7994 ok(node == NULL, "got %p\n", node);
7995 IXMLDOMNode_Release(newnode);
7997 /* cdata to attribute */
7999 V_I4(&v) = NODE_CDATA_SECTION;
8001 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
8002 ok(hr == S_OK, "got 0x%08x\n", hr);
8003 ok(newnode != NULL, "got %p\n", newnode);
8006 node = (void*)0xdeadbeef;
8007 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
8008 ok(hr == E_FAIL, "got 0x%08x\n", hr);
8009 ok(node == NULL, "got %p\n", node);
8010 IXMLDOMNode_Release(newnode);
8012 /* comment to attribute */
8014 V_I4(&v) = NODE_COMMENT;
8016 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
8017 ok(hr == S_OK, "got 0x%08x\n", hr);
8018 ok(newnode != NULL, "got %p\n", newnode);
8021 node = (void*)0xdeadbeef;
8022 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
8023 ok(hr == E_FAIL, "got 0x%08x\n", hr);
8024 ok(node == NULL, "got %p\n", node);
8025 IXMLDOMNode_Release(newnode);
8027 /* element to attribute */
8029 V_I4(&v) = NODE_ELEMENT;
8031 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
8032 ok(hr == S_OK, "got 0x%08x\n", hr);
8033 ok(newnode != NULL, "got %p\n", newnode);
8036 node = (void*)0xdeadbeef;
8037 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
8038 ok(hr == E_FAIL, "got 0x%08x\n", hr);
8039 ok(node == NULL, "got %p\n", node);
8040 IXMLDOMNode_Release(newnode);
8042 /* pi to attribute */
8044 V_I4(&v) = NODE_PROCESSING_INSTRUCTION;
8046 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("cdata"), NULL, &newnode);
8047 ok(hr == S_OK, "got 0x%08x\n", hr);
8048 ok(newnode != NULL, "got %p\n", newnode);
8051 node = (void*)0xdeadbeef;
8052 hr = IXMLDOMAttribute_insertBefore(attr, newnode, v, &node);
8053 ok(hr == E_FAIL, "got 0x%08x\n", hr);
8054 ok(node == NULL, "got %p\n", node);
8055 IXMLDOMNode_Release(newnode);
8056 IXMLDOMAttribute_Release(attr);
8058 /* insertBefore for elements */
8059 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem1);
8060 ok(hr == S_OK, "got 0x%08x\n", hr);
8062 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem2"), &elem2);
8063 ok(hr == S_OK, "got 0x%08x\n", hr);
8065 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem3"), &elem3);
8066 ok(hr == S_OK, "got 0x%08x\n", hr);
8068 EXPECT_NO_CHILDREN(elem1);
8069 EXPECT_NO_CHILDREN(elem2);
8070 EXPECT_NO_CHILDREN(elem3);
8072 todo_wine EXPECT_REF(elem2, 2);
8076 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
8077 ok(hr == S_OK, "got 0x%08x\n", hr);
8078 ok(node == (void*)elem2, "got %p\n", node);
8080 EXPECT_CHILDREN(elem1);
8081 todo_wine EXPECT_REF(elem2, 3);
8082 IXMLDOMNode_Release(node);
8084 /* again for already linked node */
8087 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, &node);
8088 ok(hr == S_OK, "got 0x%08x\n", hr);
8089 ok(node == (void*)elem2, "got %p\n", node);
8091 EXPECT_CHILDREN(elem1);
8093 /* increments each time */
8094 todo_wine EXPECT_REF(elem2, 3);
8095 IXMLDOMNode_Release(node);
8097 /* try to add to another element */
8099 node = (void*)0xdeadbeef;
8100 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem2, v, &node);
8101 ok(hr == S_OK, "got 0x%08x\n", hr);
8102 ok(node == (void*)elem2, "got %p\n", node);
8104 EXPECT_CHILDREN(elem3);
8105 EXPECT_NO_CHILDREN(elem1);
8107 IXMLDOMNode_Release(node);
8109 /* cross document case - try to add as child to a node created with other doc */
8110 doc2 = create_document(&IID_IXMLDOMDocument);
8112 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem4);
8113 ok(hr == S_OK, "got 0x%08x\n", hr);
8114 todo_wine EXPECT_REF(elem4, 2);
8116 /* same name, another instance */
8117 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem4"), &elem5);
8118 ok(hr == S_OK, "got 0x%08x\n", hr);
8119 todo_wine EXPECT_REF(elem5, 2);
8121 todo_wine EXPECT_REF(elem3, 2);
8124 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem4, v, &node);
8125 ok(hr == S_OK, "got 0x%08x\n", hr);
8126 ok(node == (void*)elem4, "got %p\n", node);
8127 todo_wine EXPECT_REF(elem4, 3);
8128 todo_wine EXPECT_REF(elem3, 2);
8129 IXMLDOMNode_Release(node);
8133 hr = IXMLDOMElement_insertBefore(elem3, (IXMLDOMNode*)elem5, v, &node);
8134 ok(hr == S_OK, "got 0x%08x\n", hr);
8135 ok(node == (void*)elem5, "got %p\n", node);
8136 todo_wine EXPECT_REF(elem4, 2);
8137 todo_wine EXPECT_REF(elem5, 3);
8138 IXMLDOMNode_Release(node);
8140 IXMLDOMDocument_Release(doc2);
8142 IXMLDOMElement_Release(elem1);
8143 IXMLDOMElement_Release(elem2);
8144 IXMLDOMElement_Release(elem3);
8145 IXMLDOMElement_Release(elem4);
8146 IXMLDOMElement_Release(elem5);
8148 /* elements with same default namespace */
8150 V_I4(&v) = NODE_ELEMENT;
8152 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
8153 ok(hr == S_OK, "got 0x%08x\n", hr);
8154 ok(elem1 != NULL, "got %p\n", elem1);
8157 V_I4(&v) = NODE_ELEMENT;
8159 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem2);
8160 ok(hr == S_OK, "got 0x%08x\n", hr);
8161 ok(elem2 != NULL, "got %p\n", elem2);
8163 /* check contents so far */
8165 hr = IXMLDOMElement_get_xml(elem1, &p);
8166 ok(hr == S_OK, "got 0x%08x\n", hr);
8167 ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8171 hr = IXMLDOMElement_get_xml(elem2, &p);
8172 ok(hr == S_OK, "got 0x%08x\n", hr);
8173 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8177 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
8178 ok(hr == S_OK, "got 0x%08x\n", hr);
8180 /* get_xml depends on context, for top node it omits child namespace attribute,
8181 but at child level it's still returned */
8183 hr = IXMLDOMElement_get_xml(elem1, &p);
8184 ok(hr == S_OK, "got 0x%08x\n", hr);
8185 todo_wine ok(!lstrcmpW(p, _bstr_("<elem1 xmlns=\"http://winehq.org/default\"><elem2/></elem1>")),
8186 "got %s\n", wine_dbgstr_w(p));
8190 hr = IXMLDOMElement_get_xml(elem2, &p);
8191 ok(hr == S_OK, "got 0x%08x\n", hr);
8192 ok(!lstrcmpW(p, _bstr_("<elem2 xmlns=\"http://winehq.org/default\"/>")), "got %s\n", wine_dbgstr_w(p));
8195 IXMLDOMElement_Release(elem1);
8196 IXMLDOMElement_Release(elem2);
8198 /* child without default namespace added to node with default namespace */
8200 V_I4(&v) = NODE_ELEMENT;
8202 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem1"), _bstr_("http://winehq.org/default"), (IXMLDOMNode**)&elem1);
8203 ok(hr == S_OK, "got 0x%08x\n", hr);
8204 ok(elem1 != NULL, "got %p\n", elem1);
8207 V_I4(&v) = NODE_ELEMENT;
8209 hr = IXMLDOMDocument_createNode(doc, v, _bstr_("elem2"), NULL, (IXMLDOMNode**)&elem2);
8210 ok(hr == S_OK, "got 0x%08x\n", hr);
8211 ok(elem2 != NULL, "got %p\n", elem2);
8213 EXPECT_REF(elem2, 1);
8215 hr = IXMLDOMElement_insertBefore(elem1, (IXMLDOMNode*)elem2, v, NULL);
8216 ok(hr == S_OK, "got 0x%08x\n", hr);
8217 EXPECT_REF(elem2, 1);
8220 hr = IXMLDOMElement_get_xml(elem2, &p);
8221 ok(hr == S_OK, "got 0x%08x\n", hr);
8222 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
8225 hr = IXMLDOMElement_removeChild(elem1, (IXMLDOMNode*)elem2, NULL);
8226 ok(hr == S_OK, "got 0x%08x\n", hr);
8229 hr = IXMLDOMElement_get_xml(elem2, &p);
8230 ok(hr == S_OK, "got 0x%08x\n", hr);
8231 ok(!lstrcmpW(p, _bstr_("<elem2/>")), "got %s\n", wine_dbgstr_w(p));
8234 IXMLDOMElement_Release(elem1);
8235 IXMLDOMElement_Release(elem2);
8236 IXMLDOMDocument_Release(doc);
8239 static void test_appendChild(void)
8241 IXMLDOMDocument *doc, *doc2;
8242 IXMLDOMElement *elem, *elem2;
8245 doc = create_document(&IID_IXMLDOMDocument);
8246 doc2 = create_document(&IID_IXMLDOMDocument);
8248 hr = IXMLDOMDocument_createElement(doc, _bstr_("elem"), &elem);
8249 ok(hr == S_OK, "got 0x%08x\n", hr);
8251 hr = IXMLDOMDocument_createElement(doc2, _bstr_("elem2"), &elem2);
8252 ok(hr == S_OK, "got 0x%08x\n", hr);
8255 todo_wine EXPECT_REF(elem, 2);
8256 EXPECT_REF(doc2, 1);
8257 todo_wine EXPECT_REF(elem2, 2);
8258 EXPECT_NO_CHILDREN(doc);
8259 EXPECT_NO_CHILDREN(doc2);
8261 /* append from another document */
8262 hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, NULL);
8263 ok(hr == S_OK, "got 0x%08x\n", hr);
8266 todo_wine EXPECT_REF(elem, 2);
8267 EXPECT_REF(doc2, 1);
8268 todo_wine EXPECT_REF(elem2, 2);
8269 EXPECT_NO_CHILDREN(doc);
8270 EXPECT_CHILDREN(doc2);
8272 IXMLDOMElement_Release(elem);
8273 IXMLDOMElement_Release(elem2);
8274 IXMLDOMDocument_Release(doc);
8275 IXMLDOMDocument_Release(doc2);
8278 static void test_get_doctype(void)
8280 IXMLDOMDocumentType *doctype;
8281 IXMLDOMDocument *doc;
8284 doc = create_document(&IID_IXMLDOMDocument);
8286 hr = IXMLDOMDocument_get_doctype(doc, NULL);
8287 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8289 doctype = (void*)0xdeadbeef;
8290 hr = IXMLDOMDocument_get_doctype(doc, &doctype);
8291 ok(hr == S_FALSE, "got 0x%08x\n", hr);
8292 ok(doctype == NULL, "got %p\n", doctype);
8294 IXMLDOMDocument_Release(doc);
8297 static void test_get_tagName(void)
8299 IXMLDOMDocument *doc;
8300 IXMLDOMElement *elem, *elem2;
8304 doc = create_document(&IID_IXMLDOMDocument);
8306 hr = IXMLDOMDocument_createElement(doc, _bstr_("element"), &elem);
8307 ok(hr == S_OK, "got 0x%08x\n", hr);
8309 hr = IXMLDOMElement_get_tagName(elem, NULL);
8310 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8313 hr = IXMLDOMElement_get_tagName(elem, &str);
8314 ok(hr == S_OK, "got 0x%08x\n", hr);
8315 ok(!lstrcmpW(str, _bstr_("element")), "got %s\n", wine_dbgstr_w(str));
8318 hr = IXMLDOMDocument_createElement(doc, _bstr_("s:element"), &elem2);
8319 ok(hr == S_OK, "got 0x%08x\n", hr);
8322 hr = IXMLDOMElement_get_tagName(elem2, &str);
8323 ok(hr == S_OK, "got 0x%08x\n", hr);
8324 ok(!lstrcmpW(str, _bstr_("s:element")), "got %s\n", wine_dbgstr_w(str));
8327 IXMLDOMDocument_Release(elem);
8328 IXMLDOMDocument_Release(elem2);
8329 IXMLDOMDocument_Release(doc);
8333 typedef struct _get_datatype_t {
8340 static const get_datatype_t get_datatype[] = {
8341 { NODE_ELEMENT, "element", VT_NULL, S_FALSE },
8342 { NODE_ATTRIBUTE, "attr", VT_NULL, S_FALSE },
8343 { NODE_TEXT, "text", VT_NULL, S_FALSE },
8344 { NODE_CDATA_SECTION , "cdata", VT_NULL, S_FALSE },
8345 { NODE_ENTITY_REFERENCE, "entityref", VT_NULL, S_FALSE },
8346 { NODE_PROCESSING_INSTRUCTION, "pi", VT_NULL, S_FALSE },
8347 { NODE_COMMENT, "comment", VT_NULL, S_FALSE },
8348 { NODE_DOCUMENT_FRAGMENT, "docfrag", VT_NULL, S_FALSE },
8352 static void test_get_dataType(void)
8354 IXMLDOMDocument *doc;
8355 const get_datatype_t *entry = get_datatype;
8357 doc = create_document(&IID_IXMLDOMDocument);
8361 IXMLDOMNode *node = NULL;
8366 V_I4(&var) = entry->type;
8367 hr = IXMLDOMDocument_createNode(doc, var, _bstr_(entry->name), NULL, &node);
8368 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8370 hr = IXMLDOMNode_get_dataType(node, NULL);
8371 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8374 hr = IXMLDOMNode_get_dataType(node, &type);
8375 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
8376 hr, entry->hr, entry->type);
8377 ok(V_VT(&type) == entry->vt, "got %d, expected %d. node type %d\n",
8378 V_VT(&type), entry->vt, entry->type);
8379 VariantClear(&type);
8381 IXMLDOMNode_Release(node);
8386 IXMLDOMDocument_Release(doc);
8390 typedef struct _get_node_typestring_t {
8393 } get_node_typestring_t;
8395 static const get_node_typestring_t get_node_typestring[] = {
8396 { NODE_ELEMENT, "element" },
8397 { NODE_ATTRIBUTE, "attribute" },
8398 { NODE_TEXT, "text" },
8399 { NODE_CDATA_SECTION , "cdatasection" },
8400 { NODE_ENTITY_REFERENCE, "entityreference" },
8401 { NODE_PROCESSING_INSTRUCTION, "processinginstruction" },
8402 { NODE_COMMENT, "comment" },
8403 { NODE_DOCUMENT_FRAGMENT, "documentfragment" },
8407 static void test_get_nodeTypeString(void)
8409 const get_node_typestring_t *entry = get_node_typestring;
8410 IXMLDOMDocument *doc;
8414 doc = create_document(&IID_IXMLDOMDocument);
8416 hr = IXMLDOMDocument_get_nodeTypeString(doc, &str);
8417 ok(hr == S_OK, "got 0x%08x\n", hr);
8418 ok(!lstrcmpW(str, _bstr_("document")), "got string %s\n", wine_dbgstr_w(str));
8423 IXMLDOMNode *node = NULL;
8427 V_I4(&var) = entry->type;
8428 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
8429 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8431 hr = IXMLDOMNode_get_nodeTypeString(node, NULL);
8432 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8434 hr = IXMLDOMNode_get_nodeTypeString(node, &str);
8435 ok(hr == S_OK, "got 0x%08x\n", hr);
8436 ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
8437 wine_dbgstr_w(str), entry->string, entry->type);
8439 IXMLDOMNode_Release(node);
8444 IXMLDOMDocument_Release(doc);
8448 typedef struct _get_attributes_t {
8453 static const get_attributes_t get_attributes[] = {
8454 { NODE_ATTRIBUTE, S_FALSE },
8455 { NODE_TEXT, S_FALSE },
8456 { NODE_CDATA_SECTION , S_FALSE },
8457 { NODE_ENTITY_REFERENCE, S_FALSE },
8458 { NODE_PROCESSING_INSTRUCTION, S_FALSE },
8459 { NODE_COMMENT, S_FALSE },
8460 { NODE_DOCUMENT_FRAGMENT, S_FALSE },
8464 static void test_get_attributes(void)
8466 const get_attributes_t *entry = get_attributes;
8467 IXMLDOMNamedNodeMap *map;
8468 IXMLDOMDocument *doc;
8469 IXMLDOMNode *node, *node2;
8475 doc = create_document(&IID_IXMLDOMDocument);
8477 str = SysAllocString( szComplete4 );
8478 hr = IXMLDOMDocument_loadXML(doc, str, &b);
8481 hr = IXMLDOMDocument_get_attributes(doc, NULL);
8482 ok(hr == E_INVALIDARG, "got %08x\n", hr);
8484 map = (void*)0xdeadbeef;
8485 hr = IXMLDOMDocument_get_attributes(doc, &map);
8486 ok(hr == S_FALSE, "got %08x\n", hr);
8487 ok(map == NULL, "got %p\n", map);
8489 /* first child is <?xml ?> */
8490 hr = IXMLDOMDocument_get_firstChild(doc, &node);
8491 ok(hr == S_OK, "got %08x\n", hr);
8493 hr = IXMLDOMNode_get_attributes(node, &map);
8494 todo_wine ok(hr == S_OK, "got %08x\n", hr);
8498 IXMLDOMNode_Release(node);
8501 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node);
8502 ok(hr == S_OK, "got %08x\n", hr);
8503 ok(node != NULL, "got %p\n", node);
8505 hr = IXMLDOMNode_get_nodeName(node, &str);
8506 ok(hr == S_OK, "got %08x\n", hr);
8507 ok(!lstrcmpW(str, _bstr_("version")), "got %s\n", wine_dbgstr_w(str));
8510 IXMLDOMNamedNodeMap_Release(map);
8513 IXMLDOMNode_Release(node);
8515 /* last child is element */
8517 hr = IXMLDOMDocument_get_lastChild(doc, &node);
8518 ok(hr == S_OK, "got %08x\n", hr);
8521 EXPECT_REF(node, 1);
8522 hr = IXMLDOMNode_get_attributes(node, &map);
8523 ok(hr == S_OK, "got %08x\n", hr);
8524 EXPECT_REF(node, 1);
8528 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
8529 ok(hr == S_OK, "got %08x\n", hr);
8530 EXPECT_REF(node, 1);
8531 EXPECT_REF(node2, 1);
8534 IXMLDOMNode_Release(node2);
8536 /* release node before map release, map still works */
8537 IXMLDOMNode_Release(node);
8540 hr = IXMLDOMNamedNodeMap_get_length(map, &length);
8541 ok(hr == S_OK, "got %08x\n", hr);
8542 ok(length == 1, "got %d\n", length);
8545 hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
8546 ok(hr == S_OK, "got %08x\n", hr);
8547 EXPECT_REF(node2, 1);
8548 IXMLDOMNode_Release(node2);
8550 IXMLDOMNamedNodeMap_Release(map);
8559 V_I4(&var) = entry->type;
8560 hr = IXMLDOMDocument_createNode(doc, var, _bstr_("node"), NULL, &node);
8561 ok(hr == S_OK, "failed to create node, type %d\n", entry->type);
8563 hr = IXMLDOMNode_get_attributes(node, NULL);
8564 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
8566 map = (void*)0xdeadbeef;
8567 hr = IXMLDOMNode_get_attributes(node, &map);
8568 ok(hr == entry->hr, "got 0x%08x, expected 0x%08x. node type %d\n",
8569 hr, entry->hr, entry->type);
8570 ok(map == NULL, "got %p\n", map);
8572 IXMLDOMNode_Release(node);
8577 IXMLDOMDocument_Release(doc);
8581 static void test_selection(void)
8583 IXMLDOMSelection *selection;
8584 IXMLDOMNodeList *list;
8585 IXMLDOMDocument *doc;
8589 doc = create_document(&IID_IXMLDOMDocument);
8591 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b);
8592 EXPECT_HR(hr, S_OK);
8594 hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root"), &list);
8595 EXPECT_HR(hr, S_OK);
8597 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
8598 EXPECT_HR(hr, S_OK);
8599 IXMLDOMSelection_Release(selection);
8601 IXMLDOMNodeList_Release(list);
8603 hr = IXMLDOMDocument_get_childNodes(doc, &list);
8604 EXPECT_HR(hr, S_OK);
8606 hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
8607 EXPECT_HR(hr, E_NOINTERFACE);
8609 IXMLDOMNodeList_Release(list);
8611 IXMLDOMDocument_Release(doc);
8615 static void test_load(void)
8617 IXMLDOMDocument *doc;
8626 /* prepare a file */
8627 hfile = CreateFileA("test.xml", GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
8628 ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file\n");
8629 if(hfile == INVALID_HANDLE_VALUE) return;
8631 ret = WriteFile(hfile, szNonUnicodeXML, sizeof(szNonUnicodeXML)-1, &written, NULL);
8632 ok(ret, "WriteFile failed\n");
8636 doc = create_document(&IID_IXMLDOMDocument);
8638 path = _bstr_("test.xml");
8640 /* load from path: VT_BSTR */
8641 V_VT(&src) = VT_BSTR;
8642 V_BSTR(&src) = path;
8643 hr = IXMLDOMDocument_load(doc, src, &b);
8644 EXPECT_HR(hr, S_OK);
8645 ok(b == VARIANT_TRUE, "got %d\n", b);
8647 /* load from a path: VT_BSTR|VT_BYREF */
8648 V_VT(&src) = VT_BSTR | VT_BYREF;
8649 V_BSTRREF(&src) = &path;
8650 hr = IXMLDOMDocument_load(doc, src, &b);
8651 EXPECT_HR(hr, S_OK);
8652 ok(b == VARIANT_TRUE, "got %d\n", b);
8654 /* load from a path: VT_BSTR|VT_BYREF, null ptr */
8655 V_VT(&src) = VT_BSTR | VT_BYREF;
8656 V_BSTRREF(&src) = NULL;
8657 hr = IXMLDOMDocument_load(doc, src, &b);
8658 EXPECT_HR(hr, E_INVALIDARG);
8659 ok(b == VARIANT_FALSE, "got %d\n", b);
8661 IXMLDOMDocument_Release(doc);
8663 DeleteFileA("test.xml");
8669 IXMLDOMDocument *doc;
8672 hr = CoInitialize( NULL );
8673 ok( hr == S_OK, "failed to init com\n");
8679 hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
8682 win_skip("IXMLDOMDocument is not available (0x%08x)\n", hr);
8686 IXMLDOMDocument_Release(doc);
8689 test_persiststreaminit();
8693 test_getElementsByTagName();
8695 test_get_childNodes();
8696 test_get_firstChild();
8697 test_get_lastChild();
8699 test_replaceChild();
8700 test_removeNamedItem();
8701 test_IXMLDOMDocument2();
8707 test_nodeTypeTests();
8709 test_testTransforms();
8711 test_FormattingXML();
8712 test_nodeTypedValue();
8713 test_TransformWithLoadingLocalFile();
8714 test_put_nodeValue();
8715 test_document_IObjectSafety();
8717 test_getQualifiedItem();
8718 test_removeQualifiedItem();
8719 test_get_ownerDocument();
8720 test_setAttributeNode();
8721 test_put_dataType();
8724 test_default_properties();
8725 test_selectSingleNode();
8727 test_createProcessingInstruction();
8728 test_put_nodeTypedValue();
8730 test_insertBefore();
8734 test_get_dataType();
8735 test_get_nodeTypeString();
8736 test_get_attributes();